summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig32
-rw-r--r--arch/alpha/Kconfig175
-rw-r--r--arch/alpha/Makefile8
-rw-r--r--arch/alpha/include/asm/core_apecs.h534
-rw-r--r--arch/alpha/include/asm/core_lca.h378
-rw-r--r--arch/alpha/include/asm/core_t2.h8
-rw-r--r--arch/alpha/include/asm/dma-mapping.h4
-rw-r--r--arch/alpha/include/asm/dma.h9
-rw-r--r--arch/alpha/include/asm/elf.h4
-rw-r--r--arch/alpha/include/asm/io.h26
-rw-r--r--arch/alpha/include/asm/irq.h10
-rw-r--r--arch/alpha/include/asm/jensen.h363
-rw-r--r--arch/alpha/include/asm/machvec.h9
-rw-r--r--arch/alpha/include/asm/mmu_context.h45
-rw-r--r--arch/alpha/include/asm/special_insns.h5
-rw-r--r--arch/alpha/include/asm/tlbflush.h37
-rw-r--r--arch/alpha/include/asm/uaccess.h80
-rw-r--r--arch/alpha/include/asm/vga.h2
-rw-r--r--arch/alpha/include/uapi/asm/compiler.h18
-rw-r--r--arch/alpha/kernel/Makefile25
-rw-r--r--arch/alpha/kernel/asm-offsets.c21
-rw-r--r--arch/alpha/kernel/bugs.c1
-rw-r--r--arch/alpha/kernel/console.c1
-rw-r--r--arch/alpha/kernel/core_apecs.c420
-rw-r--r--arch/alpha/kernel/core_cia.c6
-rw-r--r--arch/alpha/kernel/core_irongate.c1
-rw-r--r--arch/alpha/kernel/core_lca.c517
-rw-r--r--arch/alpha/kernel/core_marvel.c2
-rw-r--r--arch/alpha/kernel/core_t2.c2
-rw-r--r--arch/alpha/kernel/core_wildfire.c8
-rw-r--r--arch/alpha/kernel/entry.S1
-rw-r--r--arch/alpha/kernel/io.c19
-rw-r--r--arch/alpha/kernel/irq.c1
-rw-r--r--arch/alpha/kernel/irq_i8259.c4
-rw-r--r--arch/alpha/kernel/machvec_impl.h25
-rw-r--r--arch/alpha/kernel/osf_sys.c5
-rw-r--r--arch/alpha/kernel/pci-noop.c113
-rw-r--r--arch/alpha/kernel/pci_impl.h4
-rw-r--r--arch/alpha/kernel/pci_iommu.c2
-rw-r--r--arch/alpha/kernel/perf_event.c2
-rw-r--r--arch/alpha/kernel/proto.h44
-rw-r--r--arch/alpha/kernel/setup.c109
-rw-r--r--arch/alpha/kernel/smc37c669.c6
-rw-r--r--arch/alpha/kernel/smc37c93x.c2
-rw-r--r--arch/alpha/kernel/smp.c1
-rw-r--r--arch/alpha/kernel/srmcons.c2
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c87
-rw-r--r--arch/alpha/kernel/sys_eb64p.c238
-rw-r--r--arch/alpha/kernel/sys_jensen.c237
-rw-r--r--arch/alpha/kernel/sys_mikasa.c57
-rw-r--r--arch/alpha/kernel/sys_nautilus.c8
-rw-r--r--arch/alpha/kernel/sys_noritake.c60
-rw-r--r--arch/alpha/kernel/sys_sable.c294
-rw-r--r--arch/alpha/kernel/sys_sio.c486
-rw-r--r--arch/alpha/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/alpha/kernel/traps.c64
-rw-r--r--arch/alpha/lib/Makefile14
-rw-r--r--arch/alpha/lib/checksum.c2
-rw-r--r--arch/alpha/lib/fpreg.c2
-rw-r--r--arch/alpha/lib/memcpy.c3
-rw-r--r--arch/alpha/lib/stycpy.S11
-rw-r--r--arch/alpha/lib/styncpy.S11
-rw-r--r--arch/alpha/math-emu/math.c7
-rw-r--r--arch/alpha/mm/init.c2
-rw-r--r--arch/arc/Kbuild1
-rw-r--r--arch/arc/Kconfig1
-rw-r--r--arch/arc/boot/dts/Makefile3
-rw-r--r--arch/arc/include/asm/Kbuild2
-rw-r--r--arch/arc/include/asm/fb.h8
-rw-r--r--arch/arc/include/asm/mmu-arcv2.h2
-rw-r--r--arch/arc/include/asm/unistd.h14
-rw-r--r--arch/arc/include/uapi/asm/Kbuild2
-rw-r--r--arch/arc/include/uapi/asm/unistd.h44
-rw-r--r--arch/arc/kernel/Makefile.syscalls3
-rw-r--r--arch/arc/kernel/sys.c5
-rw-r--r--arch/arc/mm/dma.c3
-rw-r--r--arch/arc/mm/mmap.c4
-rw-r--r--arch/arc/net/Makefile6
-rw-r--r--arch/arc/net/bpf_jit.h164
-rw-r--r--arch/arc/net/bpf_jit_arcv2.c3007
-rw-r--r--arch/arc/net/bpf_jit_core.c1425
-rw-r--r--arch/arm/Kbuild2
-rw-r--r--arch/arm/Kconfig32
-rw-r--r--arch/arm/Makefile7
-rw-r--r--arch/arm/boot/Makefile3
-rw-r--r--arch/arm/boot/bootp/Makefile1
-rw-r--r--arch/arm/boot/compressed/Makefile7
-rw-r--r--arch/arm/boot/dts/allwinner/Makefile63
-rw-r--r--arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts218
-rw-r--r--arch/arm/boot/dts/allwinner/sun5i-a13.dtsi4
-rw-r--r--arch/arm/boot/dts/allwinner/sun5i-gr8-chip-pro.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun5i-r8-chip.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun6i-a31-hummingbird.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun6i-a31.dtsi16
-rw-r--r--arch/arm/boot/dts/allwinner/sun6i-a31s-sinovoip-bpi-m2.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-bananapi-m1-plus.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-cubietruck.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-hummingbird.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som-evb-emmc.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb-emmc.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-lime2.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20-wits-pro-a20-dkt.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun7i-a20.dtsi4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a23-a33.dtsi14
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2407pxe03.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2809pxe04.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a33-ga10h-v1.1.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a33.dtsi10
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a83t-bananapi-m3.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a83t-cubietruck-plus.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a83t-tbs-a711.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-a83t.dtsi8
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-m2-zero.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-r1.dts5
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts6
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-beelink-x2.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-duo2.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-m1-plus.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-r1.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-2.dts4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-lite.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc-plus.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-zero-plus2.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-q8-common.dtsi4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-r16-bananapi-m2m.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-r16-parrot.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-r40-oka40i-c.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-s3-pinecube.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi4
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-v40-bananapi-m2-berry.dts2
-rw-r--r--arch/arm/boot/dts/allwinner/sun9i-a80.dtsi4
-rw-r--r--arch/arm/boot/dts/allwinner/sunxi-bananapi-m2-plus.dtsi2
-rw-r--r--arch/arm/boot/dts/allwinner/sunxi-h3-h5-emlid-neutis.dtsi2
-rw-r--r--arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi4
-rw-r--r--arch/arm/boot/dts/arm/arm-realview-eb-bbrevd.dtsi2
-rw-r--r--arch/arm/boot/dts/arm/arm-realview-eb.dtsi48
-rw-r--r--arch/arm/boot/dts/arm/arm-realview-pb1176.dts38
-rw-r--r--arch/arm/boot/dts/arm/arm-realview-pb11mp.dts48
-rw-r--r--arch/arm/boot/dts/arm/arm-realview-pbx.dtsi48
-rw-r--r--arch/arm/boot/dts/arm/integratorap-im-pd1.dts4
-rw-r--r--arch/arm/boot/dts/arm/integratorap.dts14
-rw-r--r--arch/arm/boot/dts/arm/integratorcp.dts14
-rw-r--r--arch/arm/boot/dts/arm/mps2.dtsi48
-rw-r--r--arch/arm/boot/dts/arm/versatile-ab.dts8
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2m-rs1.dtsi8
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2m.dtsi16
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2p-ca15-tc1.dts14
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2p-ca15_a7.dts22
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts12
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts18
-rw-r--r--arch/arm/boot/dts/aspeed/Makefile9
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts1
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts9
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts322
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts13
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts324
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts360
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts581
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts4
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-cloudripper.dts544
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-greatlakes.dts4
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts648
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts265
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts543
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts15
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemitev2.dts2
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts8
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts1623
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-g4.dtsi28
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-g5.dtsi28
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-g6.dtsi36
-rw-r--r--arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi2
-rw-r--r--arch/arm/boot/dts/broadcom/Makefile2
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts29
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts1
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts33
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi34
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2711.dtsi12
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2835-rpi-common.dtsi7
-rw-r--r--arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi23
-rw-r--r--arch/arm/boot/dts/broadcom/bcm283x.dtsi24
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts150
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dts13
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dtsi133
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts156
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac88u.dts65
-rw-r--r--arch/arm/boot/dts/cirrus/ep7211-edb7211.dts2
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts11
-rw-r--r--arch/arm/boot/dts/marvell/armada-370-xp.dtsi1
-rw-r--r--arch/arm/boot/dts/marvell/armada-375.dtsi1
-rw-r--r--arch/arm/boot/dts/marvell/armada-385-atl-x530.dts13
-rw-r--r--arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts35
-rw-r--r--arch/arm/boot/dts/marvell/armada-38x.dtsi1
-rw-r--r--arch/arm/boot/dts/marvell/armada-39x.dtsi1
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-blackarmor-nas220.dts6
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-c200-v1.dts8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-cloudbox.dts8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-d2net.dts2
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-dir665.dts22
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-dns320.dts10
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-dns325.dts10
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-dnskw.dtsi8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-dockstar.dts4
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-dreamplug.dts6
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-goflexnet.dts20
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-ib62x0.dts12
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-iconnect.dts20
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-iomega_ix2_200.dts16
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-l-50.dts20
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-laplug.dts6
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-linkstation.dtsi2
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-linksys-viper.dts10
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi18
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-mplcec4.dts12
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-mv88f6281gtw-ge.dts12
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-netxbig.dtsi8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-ns2-common.dtsi6
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-ns2lite.dts2
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-nsa310.dts20
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-nsa310a.dts18
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-nsa310s.dts8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-nsa320.dts18
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-nsa325.dts18
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-nsa3x0-common.dtsi8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-openblocks_a6.dts4
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-openblocks_a7.dts2
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-pogo_e02.dts4
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-pogoplug-series-4.dts8
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-sheevaplug-esata.dts2
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-sheevaplug.dts4
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-synology.dtsi58
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-t5325.dts4
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-ts219-6281.dts6
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-ts219-6282.dts6
-rw-r--r--arch/arm/boot/dts/marvell/kirkwood-ts419.dtsi6
-rw-r--r--arch/arm/boot/dts/marvell/mvebu-linkstation-gpio-simple.dtsi2
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-lacie-d2-network.dts9
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-lacie-ethernet-disk-mini-v2.dts7
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-linkstation-lschl.dts4
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-lswsgl.dts25
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-maxtor-shared-storage-2.dts7
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-netgear-wnr854t.dts2
-rw-r--r--arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts2
-rw-r--r--arch/arm/boot/dts/mediatek/mt2701-evb.dts2
-rw-r--r--arch/arm/boot/dts/mediatek/mt7623.dtsi18
-rw-r--r--arch/arm/boot/dts/nspire/nspire-classic.dtsi2
-rw-r--r--arch/arm/boot/dts/nspire/nspire-cx.dts2
-rw-r--r--arch/arm/boot/dts/nspire/nspire.dtsi5
-rw-r--r--arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts22
-rw-r--r--arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts22
-rw-r--r--arch/arm/boot/dts/nvidia/tegra20-colibri.dtsi4
-rw-r--r--arch/arm/boot/dts/nvidia/tegra20-paz00.dts43
-rw-r--r--arch/arm/boot/dts/nxp/imx/Makefile5
-rw-r--r--arch/arm/boot/dts/nxp/imx/e60k02.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/imx/e70k02.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi78
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx51-apf51dev.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx51-babbage.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx51-ts4800.dts7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-kp-ddc.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-kp.dtsi10
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-m53evk.dts7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-m53menlo.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-mba53.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-ppd.dts6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-tqma53.dtsi8
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-tx53-x03x.dts14
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-tx53-x13x.dts6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_4.dts5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_4.dts7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_7.dts7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i-ads2.dts12
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts10
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i-ads2.dts12
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi25
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-kp.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-novena.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-var-dt6customboard.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-aristainetos2.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi9
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw52xx.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw53xx.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw54xx.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-icore.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i-ads2.dtsi148
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi58
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-mba6.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-mba6a.dtsi12
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-mba6b.dtsi12
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi9
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-mira.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi9
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi9
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-savageboard.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lcd.dtsi21
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lvds.dtsi20
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-udoo.dtsi25
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sl-evk.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sll.dtsi1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi8
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sx-softing-vining-2000.dts12
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sx.dtsi7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-ccimx6ulsbcpro.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-43.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi14
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts19
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts19
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi424
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi155
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-master.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slave.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slavext.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts566
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7s.dtsi9
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts6
-rw-r--r--arch/arm/boot/dts/qcom/Makefile8
-rw-r--r--arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts412
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8026-samsung-milletwifi.dts573
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8064.dtsi19
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8084.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi46
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi33
-rw-r--r--arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts386
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8226.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8660.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8916-smp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8926-motorola-peregrine.dts121
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8960.dtsi5
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts6
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974-samsung-hlte.dts401
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974.dtsi34
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-htc-m8.dts353
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi818
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts813
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts16
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts44
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts574
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi541
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts44
-rw-r--r--arch/arm/boot/dts/qcom/qcom-sdx55.dtsi10
-rw-r--r--arch/arm/boot/dts/renesas/r7s72100.dtsi8
-rw-r--r--arch/arm/boot/dts/renesas/r8a73a4.dtsi38
-rw-r--r--arch/arm/boot/dts/renesas/r8a7742.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a7743.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a7744.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a7745.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a77470.dtsi45
-rw-r--r--arch/arm/boot/dts/renesas/r8a7790.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a7791.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a7792.dtsi60
-rw-r--r--arch/arm/boot/dts/renesas/r8a7793.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r8a7794.dtsi59
-rw-r--r--arch/arm/boot/dts/renesas/r9a06g032.dtsi20
-rw-r--r--arch/arm/boot/dts/rockchip/rk3036.dtsi1
-rw-r--r--arch/arm/boot/dts/rockchip/rk3066a-mk808.dts8
-rw-r--r--arch/arm/boot/dts/rockchip/rk3066a.dtsi21
-rw-r--r--arch/arm/boot/dts/rockchip/rk3128.dtsi128
-rw-r--r--arch/arm/boot/dts/rockchip/rk3xxx.dtsi7
-rw-r--r--arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts3
-rw-r--r--arch/arm/boot/dts/samsung/exynos3250.dtsi2
-rw-r--r--arch/arm/boot/dts/samsung/exynos4.dtsi3
-rw-r--r--arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts2
-rw-r--r--arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi6
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-origen.dts2
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts12
-rw-r--r--arch/arm/boot/dts/samsung/exynos5250.dtsi3
-rw-r--r--arch/arm/boot/dts/samsung/exynos5420.dtsi3
-rw-r--r--arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts2
-rw-r--r--arch/arm/boot/dts/samsung/s5pv210.dtsi6
-rw-r--r--arch/arm/boot/dts/st/Makefile1
-rw-r--r--arch/arm/boot/dts/st/stih407-family.dtsi6
-rw-r--r--arch/arm/boot/dts/st/stih410.dtsi1
-rw-r--r--arch/arm/boot/dts/st/stih418.dtsi42
-rw-r--r--arch/arm/boot/dts/st/stm32f429.dtsi1
-rw-r--r--arch/arm/boot/dts/st/stm32f746.dtsi17
-rw-r--r--arch/arm/boot/dts/st/stm32f769.dtsi17
-rw-r--r--arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi754
-rw-r--r--arch/arm/boot/dts/st/stm32mp131.dtsi1200
-rw-r--r--arch/arm/boot/dts/st/stm32mp133.dtsi82
-rw-r--r--arch/arm/boot/dts/st/stm32mp135.dtsi11
-rw-r--r--arch/arm/boot/dts/st/stm32mp135f-dhcor-dhsbc.dts377
-rw-r--r--arch/arm/boot/dts/st/stm32mp135f-dk.dts181
-rw-r--r--arch/arm/boot/dts/st/stm32mp13xc.dtsi19
-rw-r--r--arch/arm/boot/dts/st/stm32mp13xf.dtsi19
-rw-r--r--arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi308
-rw-r--r--arch/arm/boot/dts/st/stm32mp151.dtsi2802
-rw-r--r--arch/arm/boot/dts/st/stm32mp153.dtsi52
-rw-r--r--arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts5
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts5
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts5
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-ed1.dts12
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts5
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts13
-rw-r--r--arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi13
-rw-r--r--arch/arm/boot/dts/st/stm32mp15xc.dtsi19
-rw-r--r--arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi13
-rw-r--r--arch/arm/boot/dts/ti/davinci/da850-evm.dts2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi5
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-guardian.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-pdu001.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-pepper.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am33xx.dtsi8
-rw-r--r--arch/arm/boot/dts/ti/omap/am4372.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts1
-rw-r--r--arch/arm/boot/dts/ti/omap/dra76x.dtsi63
-rw-r--r--arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi270
-rw-r--r--arch/arm/boot/dts/ti/omap/omap3-n900.dts2
-rw-r--r--arch/arm/boot/dts/vt8500/vt8500-bv07.dts2
-rw-r--r--arch/arm/boot/dts/vt8500/vt8500.dtsi2
-rw-r--r--arch/arm/boot/dts/vt8500/wm8505-ref.dts2
-rw-r--r--arch/arm/boot/dts/vt8500/wm8505.dtsi2
-rw-r--r--arch/arm/boot/dts/vt8500/wm8650-mid.dts2
-rw-r--r--arch/arm/boot/dts/vt8500/wm8650.dtsi2
-rw-r--r--arch/arm/boot/dts/vt8500/wm8750.dtsi4
-rw-r--r--arch/arm/boot/dts/vt8500/wm8850-w70v2.dts2
-rw-r--r--arch/arm/boot/dts/vt8500/wm8850.dtsi4
-rwxr-xr-xarch/arm/boot/install.sh2
-rw-r--r--arch/arm/common/locomo.c4
-rw-r--r--arch/arm/common/sa1111.c4
-rw-r--r--arch/arm/configs/at91_dt_defconfig1
-rw-r--r--arch/arm/configs/collie_defconfig2
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig9
-rw-r--r--arch/arm/configs/keystone_defconfig2
-rw-r--r--arch/arm/configs/lpc18xx_defconfig2
-rw-r--r--arch/arm/configs/moxart_defconfig2
-rw-r--r--arch/arm/configs/mps2_defconfig2
-rw-r--r--arch/arm/configs/multi_v7_defconfig3
-rw-r--r--arch/arm/configs/omap1_defconfig2
-rw-r--r--arch/arm/configs/shmobile_defconfig3
-rw-r--r--arch/arm/configs/stm32_defconfig2
-rw-r--r--arch/arm/configs/sunxi_defconfig1
-rw-r--r--arch/arm/configs/vexpress_defconfig1
-rw-r--r--arch/arm/crypto/aes-neonbs-glue.c1
-rw-r--r--arch/arm/crypto/crc32-ce-core.S17
-rw-r--r--arch/arm/crypto/crc32-ce-glue.c1
-rw-r--r--arch/arm/crypto/crct10dif-ce-glue.c1
-rw-r--r--arch/arm/crypto/curve25519-glue.c1
-rw-r--r--arch/arm/crypto/poly1305-glue.c1
-rw-r--r--arch/arm/include/asm/assembler.h1
-rw-r--r--arch/arm/include/asm/cacheflush.h2
-rw-r--r--arch/arm/include/asm/cmpxchg.h7
-rw-r--r--arch/arm/include/asm/efi.h13
-rw-r--r--arch/arm/include/asm/fb.h6
-rw-r--r--arch/arm/include/asm/fpu.h15
-rw-r--r--arch/arm/include/asm/glue-cache.h28
-rw-r--r--arch/arm/include/asm/hardware/locomo.h2
-rw-r--r--arch/arm/include/asm/hardware/sa1111.h2
-rw-r--r--arch/arm/include/asm/hugetlb-3level.h4
-rw-r--r--arch/arm/include/asm/hugetlb.h6
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h1
-rw-r--r--arch/arm/include/asm/pgtable-2level.h5
-rw-r--r--arch/arm/include/asm/pgtable-3level-hwdef.h27
-rw-r--r--arch/arm/include/asm/pgtable-3level.h5
-rw-r--r--arch/arm/include/asm/proc-fns.h12
-rw-r--r--arch/arm/include/asm/ptrace.h1
-rw-r--r--arch/arm/include/asm/topology.h6
-rw-r--r--arch/arm/include/asm/uaccess-asm.h58
-rw-r--r--arch/arm/include/asm/uaccess.h45
-rw-r--r--arch/arm/include/asm/unistd.h1
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/asm-offsets.c1
-rw-r--r--arch/arm/kernel/entry-ftrace.S4
-rw-r--r--arch/arm/kernel/ftrace.c17
-rw-r--r--arch/arm/kernel/hw_breakpoint.c43
-rw-r--r--arch/arm/kernel/irq.c1
-rw-r--r--arch/arm/kernel/module.c34
-rw-r--r--arch/arm/kernel/perf_event_v6.c448
-rw-r--r--arch/arm/kernel/perf_event_v7.c2005
-rw-r--r--arch/arm/kernel/perf_event_xscale.c748
-rw-r--r--arch/arm/kernel/sleep.S4
-rw-r--r--arch/arm/kernel/suspend.c8
-rw-r--r--arch/arm/kernel/topology.c2
-rw-r--r--arch/arm/kernel/traps.c1
-rw-r--r--arch/arm/lib/Makefile3
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S20
-rw-r--r--arch/arm/lib/delay-loop.S16
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c4
-rw-r--r--arch/arm/mach-davinci/pm.c2
-rw-r--r--arch/arm/mach-imx/mmdc.c1
-rw-r--r--arch/arm/mach-orion5x/board-d2net.c16
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c63
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c29
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c21
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c25
-rw-r--r--arch/arm/mach-pxa/devices.c73
-rw-r--r--arch/arm/mach-pxa/devices.h5
-rw-r--r--arch/arm/mach-pxa/gumstix.c24
-rw-r--r--arch/arm/mach-pxa/pxa25x.c8
-rw-r--r--arch/arm/mach-pxa/pxa27x.c9
-rw-r--r--arch/arm/mach-pxa/spitz.c279
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c22
-rw-r--r--arch/arm/mach-s3c/Makefile2
-rw-r--r--arch/arm/mach-sa1100/h3600.c47
-rw-r--r--arch/arm/mach-stm32/Kconfig3
-rw-r--r--arch/arm/mach-tegra/board-paz00.c50
-rw-r--r--arch/arm/mach-versatile/Kconfig9
-rw-r--r--arch/arm/mach-versatile/Makefile3
-rw-r--r--arch/arm/mach-versatile/dcscb.c173
-rw-r--r--arch/arm/mach-versatile/dcscb_setup.S33
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/cache-b15-rac.c1
-rw-r--r--arch/arm/mm/cache-fa.S47
-rw-r--r--arch/arm/mm/cache-nop.S61
-rw-r--r--arch/arm/mm/cache-v4.S55
-rw-r--r--arch/arm/mm/cache-v4wb.S49
-rw-r--r--arch/arm/mm/cache-v4wt.S55
-rw-r--r--arch/arm/mm/cache-v6.S51
-rw-r--r--arch/arm/mm/cache-v7.S76
-rw-r--r--arch/arm/mm/cache-v7m.S55
-rw-r--r--arch/arm/mm/cache.c663
-rw-r--r--arch/arm/mm/dma-mapping-nommu.c3
-rw-r--r--arch/arm/mm/dma-mapping.c16
-rw-r--r--arch/arm/mm/fault.c65
-rw-r--r--arch/arm/mm/hugetlbpage.c34
-rw-r--r--arch/arm/mm/init.c45
-rw-r--r--arch/arm/mm/mmap.c5
-rw-r--r--arch/arm/mm/mmu.c7
-rw-r--r--arch/arm/mm/proc-arm1020.S69
-rw-r--r--arch/arm/mm/proc-arm1020e.S70
-rw-r--r--arch/arm/mm/proc-arm1022.S69
-rw-r--r--arch/arm/mm/proc-arm1026.S70
-rw-r--r--arch/arm/mm/proc-arm720.S25
-rw-r--r--arch/arm/mm/proc-arm740.S26
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S34
-rw-r--r--arch/arm/mm/proc-arm920.S76
-rw-r--r--arch/arm/mm/proc-arm922.S69
-rw-r--r--arch/arm/mm/proc-arm925.S66
-rw-r--r--arch/arm/mm/proc-arm926.S75
-rw-r--r--arch/arm/mm/proc-arm940.S69
-rw-r--r--arch/arm/mm/proc-arm946.S65
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S26
-rw-r--r--arch/arm/mm/proc-fa526.S24
-rw-r--r--arch/arm/mm/proc-feroceon.S105
-rw-r--r--arch/arm/mm/proc-macros.S33
-rw-r--r--arch/arm/mm/proc-mohawk.S74
-rw-r--r--arch/arm/mm/proc-sa110.S23
-rw-r--r--arch/arm/mm/proc-sa1100.S31
-rw-r--r--arch/arm/mm/proc-v6.S31
-rw-r--r--arch/arm/mm/proc-v7-2level.S8
-rw-r--r--arch/arm/mm/proc-v7-3level.S8
-rw-r--r--arch/arm/mm/proc-v7.S66
-rw-r--r--arch/arm/mm/proc-v7m.S41
-rw-r--r--arch/arm/mm/proc-xsc3.S75
-rw-r--r--arch/arm/mm/proc-xscale.S125
-rw-r--r--arch/arm/mm/proc.c500
-rw-r--r--arch/arm/mm/tlb-fa.S12
-rw-r--r--arch/arm/mm/tlb-v4.S15
-rw-r--r--arch/arm/mm/tlb-v4wb.S12
-rw-r--r--arch/arm/mm/tlb-v4wbi.S12
-rw-r--r--arch/arm/mm/tlb-v6.S12
-rw-r--r--arch/arm/mm/tlb-v7.S14
-rw-r--r--arch/arm/mm/tlb.c84
-rw-r--r--arch/arm/net/bpf_jit_32.c25
-rw-r--r--arch/arm/plat-orion/Makefile2
-rw-r--r--arch/arm/tools/Makefile2
-rw-r--r--arch/arm/tools/syscall.tbl2
-rw-r--r--arch/arm/vdso/Makefile9
-rw-r--r--arch/arm/xen/p2m.c2
-rw-r--r--arch/arm64/Kconfig61
-rw-r--r--arch/arm64/Kconfig.platforms12
-rw-r--r--arch/arm64/Makefile30
-rw-r--r--arch/arm64/boot/.gitignore1
-rw-r--r--arch/arm64/boot/Makefile6
-rw-r--r--arch/arm64/boot/dts/Makefile1
-rw-r--r--arch/arm64/boot/dts/actions/s700-cubieboard7.dts2
-rw-r--r--arch/arm64/boot/dts/airoha/Makefile2
-rw-r--r--arch/arm64/boot/dts/airoha/en7581-evb.dts26
-rw-r--r--arch/arm64/boot/dts/airoha/en7581.dtsi154
-rw-r--r--arch/arm64/boot/dts/allwinner/Makefile4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi16
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab-early-adopter.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi55
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts183
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts8
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi39
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi126
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi96
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts7
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts327
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts115
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts53
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi12
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts2
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts2
-rw-r--r--arch/arm64/boot/dts/amazon/alpine-v2.dtsi35
-rw-r--r--arch/arm64/boot/dts/amazon/alpine-v3.dtsi12
-rw-r--r--arch/arm64/boot/dts/amd/elba-16core.dtsi2
-rw-r--r--arch/arm64/boot/dts/amd/elba-asic-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/amd/elba-asic.dts2
-rw-r--r--arch/arm64/boot/dts/amd/elba-flash-parts.dtsi2
-rw-r--r--arch/arm64/boot/dts/amd/elba.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/Makefile11
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-a4-a113l2-ba400.dts42
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-a4-common.dtsi66
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi50
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-a5-a113x2-av400.dts42
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi40
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi3
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-t7-reset.h197
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi7
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts45
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-a1.dtsi16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-axg.dtsi24
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi508
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12.dtsi4
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts384
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-bananapi.dtsi14
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-one.dts17
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-two.dts20
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi154
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi36
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts24
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts199
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl.dtsi10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxlx-s905l-p271.dts51
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso108
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-s4.dtsi212
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1.dtsi44
-rw-r--r--arch/arm64/boot/dts/apm/apm-merlin.dts4
-rw-r--r--arch/arm64/boot/dts/apm/apm-mustang.dts4
-rw-r--r--arch/arm64/boot/dts/apm/apm-shadowcat.dtsi14
-rw-r--r--arch/arm64/boot/dts/apm/apm-storm.dtsi15
-rw-r--r--arch/arm64/boot/dts/arm/corstone1000-fvp.dts2
-rw-r--r--arch/arm64/boot/dts/arm/corstone1000.dtsi6
-rw-r--r--arch/arm64/boot/dts/arm/foundation-v8.dtsi6
-rw-r--r--arch/arm64/boot/dts/arm/fvp-base-revc.dts1
-rw-r--r--arch/arm64/boot/dts/arm/juno-base.dtsi5
-rw-r--r--arch/arm64/boot/dts/arm/juno-clocks.dtsi10
-rw-r--r--arch/arm64/boot/dts/arm/juno-motherboard.dtsi13
-rw-r--r--arch/arm64/boot/dts/arm/juno-scmi.dtsi4
-rw-r--r--arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi10
-rw-r--r--arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts8
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi1
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts1
-rw-r--r--arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts2
-rw-r--r--arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts2
-rw-r--r--arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi2
-rw-r--r--arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi2
-rw-r--r--arch/arm64/boot/dts/cavium/thunder-88xx.dtsi22
-rw-r--r--arch/arm64/boot/dts/cavium/thunder2-99xx.dts2
-rw-r--r--arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi3
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433.dtsi5
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850.dtsi34
-rw-r--r--arch/arm64/boot/dts/exynos/exynosautov9.dtsi12
-rw-r--r--arch/arm64/boot/dts/exynos/google/gs101-oriole.dts53
-rw-r--r--arch/arm64/boot/dts/exynos/google/gs101.dtsi933
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile22
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi81
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts18
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts31
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi75
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts20
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi140
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi49
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi72
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi191
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi160
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts1
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi9
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi286
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi91
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-cm41.dtsi68
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi69
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi11
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx.dtsi13
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-evk.dts314
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi78
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi11
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl.dtsi15
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi21
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-iot-gateway.dts218
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs232.dtso72
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs485.dtso76
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rts-cts.dtso41
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts10
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-ucm-som.dtsi679
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi20
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi40
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-yavia.dtsi5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi49
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm.dtsi9
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-ddr3l-evk.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-evk.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi45
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts14
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts49
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts39
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts49
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi15
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-evk-mx8-dlvds-lcd1.dtso77
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-evk.dts136
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dts27
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi46
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-navqp.dts424
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts906
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts43
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi20
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi36
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi38
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso13
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts30
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi93
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi49
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin-mallow.dtsi42
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi47
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi69
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp.dtsi280
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-mek.dts432
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi473
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm.dtsi103
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-mek.dts141
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8ulp-evk.dts84
-rw-r--r--arch/arm64/boot/dts/freescale/imx8ulp.dtsi94
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts407
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts492
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts73
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts61
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi6
-rw-r--r--arch/arm64/boot/dts/freescale/imx93.dtsi140
-rw-r--r--arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts289
-rw-r--r--arch/arm64/boot/dts/freescale/imx95-clock.h187
-rw-r--r--arch/arm64/boot/dts/freescale/imx95-pinfunc.h865
-rw-r--r--arch/arm64/boot/dts/freescale/imx95-power.h47
-rw-r--r--arch/arm64/boot/dts/freescale/imx95.dtsi1192
-rw-r--r--arch/arm64/boot/dts/freescale/mba8mx.dtsi14
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/s32g2.dtsi37
-rw-r--r--arch/arm64/boot/dts/freescale/s32g274a-evb.dts6
-rw-r--r--arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts6
-rw-r--r--arch/arm64/boot/dts/freescale/s32g3.dtsi233
-rw-r--r--arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts45
-rw-r--r--arch/arm64/boot/dts/freescale/tqma8xx.dtsi8
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi3660.dtsi2
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi43
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts7
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220.dtsi2
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05-d02.dts4
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05.dtsi12
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip06.dtsi88
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip07.dtsi84
-rw-r--r--arch/arm64/boot/dts/intel/keembay-soc.dtsi2
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_agilex.dtsi2
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts2
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts2
-rw-r--r--arch/arm64/boot/dts/lg/lg1312-ref.dts2
-rw-r--r--arch/arm64/boot/dts/lg/lg1313-ref.dts2
-rw-r--r--arch/arm64/boot/dts/marvell/Makefile4
-rw-r--r--arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts98
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts8
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-37xx.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-ap80x.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-cf-base.dts178
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-cf-pro.dts375
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-cf.dtsi197
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-crb.dtsi13
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-db.dtsi18
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-sr-som.dtsi160
-rw-r--r--arch/arm64/boot/dts/marvell/cn9131-cf-solidwan.dts637
-rw-r--r--arch/arm64/boot/dts/marvell/cn9131-db.dtsi8
-rw-r--r--arch/arm64/boot/dts/marvell/cn9132-clearfog.dts673
-rw-r--r--arch/arm64/boot/dts/marvell/cn9132-db.dtsi12
-rw-r--r--arch/arm64/boot/dts/marvell/cn9132-sr-cex7.dtsi712
-rw-r--r--arch/arm64/boot/dts/mediatek/Makefile12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt2712-evb.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts8
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts8
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts74
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts15
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7981b.dtsi78
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso28
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-mini.dts493
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso74
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso90
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso16
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7988a.dtsi90
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi9
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi6
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-evb.dts12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-evb.dts6
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14-sku2.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku0.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku1.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts17
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi25
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku32.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi18
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts10
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183.dtsi136
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589824.dts13
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts25
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi103
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi42
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8188.dtsi480
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192.dtsi2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry-dojo-r1.dts114
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi50
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-demo.dts26
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-evb.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195.dtsi2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8365-evk.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8365.dtsi3
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts880
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts34
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts1127
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts88
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8516.dtsi2
-rw-r--r--arch/arm64/boot/dts/microchip/sparx5.dtsi4
-rw-r--r--arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi517
-rw-r--r--arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi128
-rw-r--r--arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts2
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132-norrin.dts4
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132.dtsi2
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-smaug.dts2
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210.dtsi2
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts77
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0005.dts31
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi (renamed from arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi)28
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/Makefile20
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts491
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5018-tplink-archer-ax55-v1.dts128
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5018.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5332.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/ipq6018.dtsi38
-rw-r--r--arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/ipq8074.dtsi57
-rw-r--r--arch/arm64/boot/dts/qcom/ipq9574.dtsi39
-rw-r--r--arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts14
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts26
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts47
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-lg-c50.dts140
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-lg-m216.dts251
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-motorola-common.dtsi161
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-motorola-harpia.dts147
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-motorola-osprey.dts105
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-motorola-surnia.dts83
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-mtp.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi59
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-e5.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-e7.dts7
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi280
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts70
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts14
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi30
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi18
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts62
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953.dtsi44
-rw-r--r--arch/arm64/boot/dts/qcom/msm8956.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8976.dtsi579
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994.dtsi14
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi134
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi67
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998.dtsi80
-rw-r--r--arch/arm64/boot/dts/qcom/pm6125.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm6150.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/pm6150l.dtsi13
-rw-r--r--arch/arm64/boot/dts/qcom/pm6350.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm660.dtsi26
-rw-r--r--arch/arm64/boot/dts/qcom/pm660l.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm7250b.dtsi47
-rw-r--r--arch/arm64/boot/dts/qcom/pm7325.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pm7550ba.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8010.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pm8150.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8150b.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8150l.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8350.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pm8350b.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pm8350c.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pm8450.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8550.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8550b.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8550ve.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8550vs.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/pm8916.dtsi31
-rw-r--r--arch/arm64/boot/dts/qcom/pm8953.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/pm8994.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pm8998.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pmi632.dtsi7
-rw-r--r--arch/arm64/boot/dts/qcom/pmi8950.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/pmm8155au_1.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pmm8155au_2.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pmr735a.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pmr735b.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/pmr735d_a.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pmr735d_b.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pms405.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/pmx75.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/qcm2290.dtsi242
-rw-r--r--arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts159
-rw-r--r--arch/arm64/boot/dts/qcom/qcm6490-idp.dts191
-rw-r--r--arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts961
-rw-r--r--arch/arm64/boot/dts/qcom/qcs404-evb.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/qcs404.dtsi30
-rw-r--r--arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts362
-rw-r--r--arch/arm64/boot/dts/qcom/qcs8550-aim300-aiot.dts315
-rw-r--r--arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi405
-rw-r--r--arch/arm64/boot/dts/qcom/qcs8550.dtsi162
-rw-r--r--arch/arm64/boot/dts/qcom/qdu1000-idp.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/qdu1000.dtsi155
-rw-r--r--arch/arm64/boot/dts/qcom/qrb2210-rb1.dts82
-rw-r--r--arch/arm64/boot/dts/qcom/qrb4210-rb2.dts18
-rw-r--r--arch/arm64/boot/dts/qcom/qrb5165-rb5.dts122
-rw-r--r--arch/arm64/boot/dts/qcom/qru1000-idp.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/sa8155p-adp.dts32
-rw-r--r--arch/arm64/boot/dts/qcom/sa8155p.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts47
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p-ride.dts834
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi814
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p.dtsi1166
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts40
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi9
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi6
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi13
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi10
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi5
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi6
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi15
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts3
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi6
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi9
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180.dtsi39
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-idp.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280.dtsi250
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts75
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x-pmics.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x-primus.dts20
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x.dtsi316
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp-crd.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts263
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp.dtsi271
-rw-r--r--arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts15
-rw-r--r--arch/arm64/boot/dts/qcom/sdm450-lenovo-tbx605f.dts276
-rw-r--r--arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi9
-rw-r--r--arch/arm64/boot/dts/qcom/sdm630.dtsi30
-rw-r--r--arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts35
-rw-r--r--arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts64
-rw-r--r--arch/arm64/boot/dts/qcom/sdm670.dtsi18
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-db845c.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-mtp.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845.dtsi199
-rw-r--r--arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts77
-rw-r--r--arch/arm64/boot/dts/qcom/sdx75-idp.dts45
-rw-r--r--arch/arm64/boot/dts/qcom/sdx75.dtsi587
-rw-r--r--arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sm4450.dtsi48
-rw-r--r--arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sm6115.dtsi46
-rw-r--r--arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts8
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts3
-rw-r--r--arch/arm64/boot/dts/qcom/sm6350.dtsi267
-rw-r--r--arch/arm64/boot/dts/qcom/sm6375-sony-xperia-murray-pdx225.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sm6375.dtsi78
-rw-r--r--arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts417
-rw-r--r--arch/arm64/boot/dts/qcom/sm8150-hdk.dts33
-rw-r--r--arch/arm64/boot/dts/qcom/sm8150.dtsi94
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250-mtp.dts14
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi19
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250.dtsi111
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350-hdk.dts28
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350.dtsi108
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-hdk.dts44
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-qrd.dts8
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450.dtsi248
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-hdk.dts26
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-mtp.dts26
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-qrd.dts134
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts593
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts765
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550.dtsi375
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650-hdk-display-card.dtso141
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650-hdk.dts1355
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650-mtp.dts38
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650-qrd.dts140
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650.dtsi580
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts616
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-crd.dts260
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts929
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi533
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-qcp.dts392
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100.dtsi1890
-rw-r--r--arch/arm64/boot/dts/realtek/rtd129x.dtsi2
-rw-r--r--arch/arm64/boot/dts/realtek/rtd139x.dtsi2
-rw-r--r--arch/arm64/boot/dts/realtek/rtd16xx.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile3
-rw-r--r--arch/arm64/boot/dts/renesas/condor-common.dtsi6
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774a1.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774b1.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774c0.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774e1.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77951.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77960.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77961.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77965.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso214
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77970.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77980-condor.dts8
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77980.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77990.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77995.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779a0.dtsi5
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi6
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0.dtsi5
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts12
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g0.dtsi28
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts31
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779h0.dtsi1274
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g043.dtsi7
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g043u.dtsi9
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g044.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g054.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r9a08g045.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r9a09g011.dtsi7
-rw-r--r--arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi58
-rw-r--r--arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi6
-rw-r--r--arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi29
-rw-r--r--arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi103
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts99
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts293
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3308.dtsi85
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts809
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328-rock64.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328.dtsi41
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-lba3368.dts659
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-r88.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368.dtsi5
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts76
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399pro.dtsi22
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353ps.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353vs.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi5
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v1.1.dts29
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v2.1.dts70
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi678
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts3
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts5
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi531
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts52
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts92
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts726
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi3
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi48
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts16
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts404
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts20
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts781
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso137
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts528
-rw-r--r--arch/arm64/boot/dts/rockchip/rk356x.dtsi54
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts725
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi (renamed from arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi)0
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-base.dtsi2799
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi7
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi8
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi8
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts177
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-extra-pinctrl.dtsi (renamed from arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi)0
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi448
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi558
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts778
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi653
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts66
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts411
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi190
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts29
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts1177
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-ep.dtso25
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-srns.dtso16
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts82
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts65
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi34
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi9
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588.dtsi341
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588j.dtsi143
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts11
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts73
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts685
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts101
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts41
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s.dtsi2505
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts4
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts4
-rw-r--r--arch/arm64/boot/dts/sprd/sc9860.dtsi58
-rw-r--r--arch/arm64/boot/dts/sprd/sc9863a.dtsi2
-rw-r--r--arch/arm64/boot/dts/sprd/sharkl3.dtsi18
-rw-r--r--arch/arm64/boot/dts/sprd/sp9860g-1h10.dts30
-rw-r--r--arch/arm64/boot/dts/sprd/ums512.dtsi14
-rw-r--r--arch/arm64/boot/dts/sprd/ums9620.dtsi14
-rw-r--r--arch/arm64/boot/dts/sprd/whale2.dtsi2
-rw-r--r--arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi182
-rw-r--r--arch/arm64/boot/dts/st/stm32mp251.dtsi781
-rw-r--r--arch/arm64/boot/dts/st/stm32mp253.dtsi71
-rw-r--r--arch/arm64/boot/dts/st/stm32mp255.dtsi33
-rw-r--r--arch/arm64/boot/dts/st/stm32mp257f-ev1.dts111
-rw-r--r--arch/arm64/boot/dts/synaptics/berlin4ct.dtsi2
-rw-r--r--arch/arm64/boot/dts/tesla/fsd.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/Makefile67
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-lp-sk-nand.dtso116
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-main.dtsi49
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi32
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi12
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi22
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-yavia.dtsi8
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi51
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi15
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts37
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso20
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts344
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-main.dtsi55
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi330
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi21
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts18
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a7-sk.dts32
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi1062
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi (renamed from arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi)11
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-j722s-common-thermal.dtsi (renamed from arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi)0
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi (renamed from arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi)18
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-main.dtsi1064
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p.dtsi9
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p5-sk.dts68
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi475
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi32
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-main.dtsi24
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi46
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-sdcard.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-wlan.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac-mii.dtso101
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm-nand.dtso148
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm.dts16
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso50
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-pcie-usb2.dtso87
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts18
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-sk.dts13
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi42
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-main.dtsi92
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi19
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-base-board.dts1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts76
-rw-r--r--arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi86
-rw-r--r--arch/arm64/boot/dts/ti/k3-am69-sk.dts99
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-eth-phy.dtso19
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-rtc.dtso15
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-spi-nor.dtso15
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6xx-phycore-qspi-nor.dtso15
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-main.dtsi10
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi22
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-common-proc-board-infotainment.dtso164
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-main.dtsi10
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi22
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-sk.dts117
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi12
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi14
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-j722s-evm.dts195
-rw-r--r--arch/arm64/boot/dts/ti/k3-j722s-main.dtsi217
-rw-r--r--arch/arm64/boot/dts/ti/k3-j722s.dtsi165
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso79
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso147
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-evm-usxgmii-exp1-exp2.dtso81
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-evm.dts391
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi539
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi23
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4.dtsi11
-rw-r--r--arch/arm64/boot/dts/ti/k3-pinctrl.h3
-rw-r--r--arch/arm64/boot/dts/ti/k3-serdes.h8
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi16
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso19
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso41
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts19
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts8
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts8
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp.dtsi190
-rwxr-xr-xarch/arm64/boot/install.sh2
-rw-r--r--arch/arm64/configs/defconfig49
-rw-r--r--arch/arm64/configs/hardening.config1
-rw-r--r--arch/arm64/crypto/aes-ce.S34
-rw-r--r--arch/arm64/crypto/aes-neon.S20
-rw-r--r--arch/arm64/crypto/aes-neonbs-glue.c1
-rw-r--r--arch/arm64/crypto/crct10dif-ce-glue.c3
-rw-r--r--arch/arm64/crypto/poly1305-glue.c1
-rw-r--r--arch/arm64/include/asm/Kbuild8
-rw-r--r--arch/arm64/include/asm/acpi.h12
-rw-r--r--arch/arm64/include/asm/arch_gicv3.h15
-rw-r--r--arch/arm64/include/asm/arch_timer.h2
-rw-r--r--arch/arm64/include/asm/arm_pmuv3.h2
-rw-r--r--arch/arm64/include/asm/asm-bug.h1
-rw-r--r--arch/arm64/include/asm/asm-extable.h3
-rw-r--r--arch/arm64/include/asm/assembler.h13
-rw-r--r--arch/arm64/include/asm/barrier.h4
-rw-r--r--arch/arm64/include/asm/cacheflush.h2
-rw-r--r--arch/arm64/include/asm/cpucaps.h2
-rw-r--r--arch/arm64/include/asm/cpufeature.h4
-rw-r--r--arch/arm64/include/asm/cputype.h12
-rw-r--r--arch/arm64/include/asm/el2_setup.h15
-rw-r--r--arch/arm64/include/asm/esr.h57
-rw-r--r--arch/arm64/include/asm/fb.h10
-rw-r--r--arch/arm64/include/asm/fpu.h15
-rw-r--r--arch/arm64/include/asm/ftrace.h11
-rw-r--r--arch/arm64/include/asm/hugetlb.h8
-rw-r--r--arch/arm64/include/asm/insn.h8
-rw-r--r--arch/arm64/include/asm/io.h128
-rw-r--r--arch/arm64/include/asm/irqflags.h1
-rw-r--r--arch/arm64/include/asm/jump_label.h28
-rw-r--r--arch/arm64/include/asm/kvm_arm.h7
-rw-r--r--arch/arm64/include/asm/kvm_asm.h10
-rw-r--r--arch/arm64/include/asm/kvm_emulate.h182
-rw-r--r--arch/arm64/include/asm/kvm_host.h248
-rw-r--r--arch/arm64/include/asm/kvm_hyp.h12
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h26
-rw-r--r--arch/arm64/include/asm/kvm_nested.h144
-rw-r--r--arch/arm64/include/asm/kvm_pkvm.h9
-rw-r--r--arch/arm64/include/asm/kvm_ptrauth.h21
-rw-r--r--arch/arm64/include/asm/mmu_context.h4
-rw-r--r--arch/arm64/include/asm/mte.h4
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h2
-rw-r--r--arch/arm64/include/asm/pgtable-prot.h19
-rw-r--r--arch/arm64/include/asm/pgtable.h216
-rw-r--r--arch/arm64/include/asm/ptrace.h35
-rw-r--r--arch/arm64/include/asm/runtime-const.h88
-rw-r--r--arch/arm64/include/asm/seccomp.h13
-rw-r--r--arch/arm64/include/asm/smp.h13
-rw-r--r--arch/arm64/include/asm/sysreg.h45
-rw-r--r--arch/arm64/include/asm/tlbflush.h33
-rw-r--r--arch/arm64/include/asm/topology.h6
-rw-r--r--arch/arm64/include/asm/uaccess.h169
-rw-r--r--arch/arm64/include/asm/unistd.h22
-rw-r--r--arch/arm64/include/asm/unistd32.h937
-rw-r--r--arch/arm64/include/asm/vdso/compat_gettimeofday.h12
-rw-r--r--arch/arm64/include/asm/virt.h12
-rw-r--r--arch/arm64/include/asm/word-at-a-time.h11
-rw-r--r--arch/arm64/include/uapi/asm/Kbuild1
-rw-r--r--arch/arm64/include/uapi/asm/unistd.h25
-rw-r--r--arch/arm64/kernel/Makefile1
-rw-r--r--arch/arm64/kernel/Makefile.syscalls6
-rw-r--r--arch/arm64/kernel/acpi.c139
-rw-r--r--arch/arm64/kernel/acpi_numa.c11
-rw-r--r--arch/arm64/kernel/armv8_deprecated.c5
-rw-r--r--arch/arm64/kernel/asm-offsets.c1
-rw-r--r--arch/arm64/kernel/cpu_errata.c22
-rw-r--r--arch/arm64/kernel/cpufeature.c13
-rw-r--r--arch/arm64/kernel/cpuidle.c74
-rw-r--r--arch/arm64/kernel/debug-monitors.c4
-rw-r--r--arch/arm64/kernel/efi.c3
-rw-r--r--arch/arm64/kernel/fpsimd.c46
-rw-r--r--arch/arm64/kernel/hw_breakpoint.c4
-rw-r--r--arch/arm64/kernel/image-vars.h5
-rw-r--r--arch/arm64/kernel/io.c42
-rw-r--r--arch/arm64/kernel/module.c126
-rw-r--r--arch/arm64/kernel/mte.c12
-rw-r--r--arch/arm64/kernel/patching.c2
-rw-r--r--arch/arm64/kernel/perf_callchain.c118
-rw-r--r--arch/arm64/kernel/pi/Makefile6
-rw-r--r--arch/arm64/kernel/pi/idreg-override.c6
-rw-r--r--arch/arm64/kernel/pi/map_kernel.c2
-rw-r--r--arch/arm64/kernel/probes/kprobes.c7
-rw-r--r--arch/arm64/kernel/proton-pack.c12
-rw-r--r--arch/arm64/kernel/psci.c2
-rw-r--r--arch/arm64/kernel/reloc_test_core.c1
-rw-r--r--arch/arm64/kernel/setup.c11
-rw-r--r--arch/arm64/kernel/signal32.c4
-rw-r--r--arch/arm64/kernel/sigreturn32.S18
-rw-r--r--arch/arm64/kernel/smp.c81
-rw-r--r--arch/arm64/kernel/stacktrace.c120
-rw-r--r--arch/arm64/kernel/sys.c6
-rw-r--r--arch/arm64/kernel/sys32.c17
-rw-r--r--arch/arm64/kernel/syscall.c19
-rw-r--r--arch/arm64/kernel/trace-events-emulation.h2
-rw-r--r--arch/arm64/kernel/traps.c8
-rw-r--r--arch/arm64/kernel/vdso/Makefile12
-rw-r--r--arch/arm64/kernel/vdso32/Makefile4
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S3
-rw-r--r--arch/arm64/kvm/Makefile5
-rw-r--r--arch/arm64/kvm/arm.c373
-rw-r--r--arch/arm64/kvm/emulate-nested.c175
-rw-r--r--arch/arm64/kvm/fpsimd.c95
-rw-r--r--arch/arm64/kvm/guest.c3
-rw-r--r--arch/arm64/kvm/handle_exit.c79
-rw-r--r--arch/arm64/kvm/hyp/Makefile2
-rw-r--r--arch/arm64/kvm/hyp/aarch32.c18
-rw-r--r--arch/arm64/kvm/hyp/entry.S8
-rw-r--r--arch/arm64/kvm/hyp/fpsimd.S6
-rw-r--r--arch/arm64/kvm/hyp/include/hyp/debug-sr.h8
-rw-r--r--arch/arm64/kvm/hyp/include/hyp/switch.h149
-rw-r--r--arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h35
-rw-r--r--arch/arm64/kvm/hyp/include/nvhe/ffa.h2
-rw-r--r--arch/arm64/kvm/hyp/include/nvhe/fixed_config.h10
-rw-r--r--arch/arm64/kvm/hyp/include/nvhe/pkvm.h5
-rw-r--r--arch/arm64/kvm/hyp/nvhe/Makefile19
-rw-r--r--arch/arm64/kvm/hyp/nvhe/debug-sr.c8
-rw-r--r--arch/arm64/kvm/hyp/nvhe/ffa.c193
-rw-r--r--arch/arm64/kvm/hyp/nvhe/gen-hyprel.c6
-rw-r--r--arch/arm64/kvm/hyp/nvhe/host.S6
-rw-r--r--arch/arm64/kvm/hyp/nvhe/hyp-init.S30
-rw-r--r--arch/arm64/kvm/hyp/nvhe/hyp-main.c111
-rw-r--r--arch/arm64/kvm/hyp/nvhe/mem_protect.c8
-rw-r--r--arch/arm64/kvm/hyp/nvhe/pkvm.c13
-rw-r--r--arch/arm64/kvm/hyp/nvhe/psci-relay.c2
-rw-r--r--arch/arm64/kvm/hyp/nvhe/setup.c31
-rw-r--r--arch/arm64/kvm/hyp/nvhe/switch.c42
-rw-r--r--arch/arm64/kvm/hyp/nvhe/sys_regs.c2
-rw-r--r--arch/arm64/kvm/hyp/nvhe/tlb.c115
-rw-r--r--arch/arm64/kvm/hyp/pgtable.c21
-rw-r--r--arch/arm64/kvm/hyp/vgic-v3-sr.c27
-rw-r--r--arch/arm64/kvm/hyp/vhe/switch.c315
-rw-r--r--arch/arm64/kvm/hyp/vhe/sysreg-sr.c4
-rw-r--r--arch/arm64/kvm/hyp/vhe/tlb.c173
-rw-r--r--arch/arm64/kvm/mmio.c12
-rw-r--r--arch/arm64/kvm/mmu.c255
-rw-r--r--arch/arm64/kvm/nested.c1004
-rw-r--r--arch/arm64/kvm/pauth.c206
-rw-r--r--arch/arm64/kvm/pkvm.c2
-rw-r--r--arch/arm64/kvm/pmu-emul.c3
-rw-r--r--arch/arm64/kvm/pmu.c2
-rw-r--r--arch/arm64/kvm/reset.c10
-rw-r--r--arch/arm64/kvm/sys_regs.c658
-rw-r--r--arch/arm64/kvm/vgic/vgic-debug.c82
-rw-r--r--arch/arm64/kvm/vgic/vgic-init.c92
-rw-r--r--arch/arm64/kvm/vgic/vgic-its.c352
-rw-r--r--arch/arm64/kvm/vgic/vgic-mmio-v3.c17
-rw-r--r--arch/arm64/kvm/vgic/vgic-v2.c9
-rw-r--r--arch/arm64/kvm/vgic/vgic-v3.c23
-rw-r--r--arch/arm64/kvm/vgic/vgic.c17
-rw-r--r--arch/arm64/kvm/vgic/vgic.h10
-rw-r--r--arch/arm64/lib/Makefile6
-rw-r--r--arch/arm64/lib/insn.c11
-rw-r--r--arch/arm64/mm/contpte.c29
-rw-r--r--arch/arm64/mm/dma-mapping.c13
-rw-r--r--arch/arm64/mm/fault.c56
-rw-r--r--arch/arm64/mm/hugetlbpage.c20
-rw-r--r--arch/arm64/mm/init.c140
-rw-r--r--arch/arm64/mm/mmu.c104
-rw-r--r--arch/arm64/mm/mteswap.c45
-rw-r--r--arch/arm64/mm/proc.S10
-rw-r--r--arch/arm64/net/bpf_jit.h8
-rw-r--r--arch/arm64/net/bpf_jit_comp.c205
-rw-r--r--arch/arm64/tools/Makefile6
-rw-r--r--arch/arm64/tools/cpucaps1
-rw-r--r--arch/arm64/tools/syscall_32.tbl476
l---------arch/arm64/tools/syscall_64.tbl1
-rw-r--r--arch/arm64/tools/sysreg4
-rw-r--r--arch/csky/Kconfig1
-rw-r--r--arch/csky/abiv1/mmap.c12
-rw-r--r--arch/csky/boot/dts/Makefile4
-rw-r--r--arch/csky/include/asm/Kbuild3
-rw-r--r--arch/csky/include/asm/cmpxchg.h10
-rw-r--r--arch/csky/include/asm/ftrace.h2
-rw-r--r--arch/csky/include/asm/unistd.h3
-rw-r--r--arch/csky/include/uapi/asm/Kbuild2
-rw-r--r--arch/csky/include/uapi/asm/unistd.h14
-rw-r--r--arch/csky/kernel/Makefile.syscalls4
-rw-r--r--arch/csky/kernel/probes/ftrace.c3
-rw-r--r--arch/csky/kernel/syscall.c2
-rw-r--r--arch/csky/kernel/syscall_table.c4
-rw-r--r--arch/csky/kernel/vdso/Makefile8
-rw-r--r--arch/hexagon/include/asm/Kbuild2
-rw-r--r--arch/hexagon/include/asm/syscalls.h6
-rw-r--r--arch/hexagon/include/asm/unistd.h10
-rw-r--r--arch/hexagon/include/uapi/asm/Kbuild2
-rw-r--r--arch/hexagon/include/uapi/asm/unistd.h13
-rw-r--r--arch/hexagon/kernel/Makefile.syscalls3
-rw-r--r--arch/hexagon/kernel/syscalltab.c15
-rw-r--r--arch/loongarch/Kconfig39
-rw-r--r--arch/loongarch/Kconfig.debug1
-rw-r--r--arch/loongarch/Makefile10
-rw-r--r--arch/loongarch/boot/dts/loongson-2k0500-ref.dts4
-rw-r--r--arch/loongarch/boot/dts/loongson-2k0500.dtsi86
-rw-r--r--arch/loongarch/boot/dts/loongson-2k1000-ref.dts8
-rw-r--r--arch/loongarch/boot/dts/loongson-2k1000.dtsi1
-rw-r--r--arch/loongarch/boot/dts/loongson-2k2000-ref.dts2
-rw-r--r--arch/loongarch/boot/dts/loongson-2k2000.dtsi49
-rw-r--r--arch/loongarch/configs/loongson3_defconfig25
-rw-r--r--arch/loongarch/include/asm/Kbuild18
-rw-r--r--arch/loongarch/include/asm/acpi.h1
-rw-r--r--arch/loongarch/include/asm/addrspace.h4
-rw-r--r--arch/loongarch/include/asm/asm-prototypes.h6
-rw-r--r--arch/loongarch/include/asm/asmmacro.h1
-rw-r--r--arch/loongarch/include/asm/fpu.h1
-rw-r--r--arch/loongarch/include/asm/ftrace.h1
-rw-r--r--arch/loongarch/include/asm/hardirq.h9
-rw-r--r--arch/loongarch/include/asm/hw_breakpoint.h4
-rw-r--r--arch/loongarch/include/asm/inst.h5
-rw-r--r--arch/loongarch/include/asm/io.h10
-rw-r--r--arch/loongarch/include/asm/irq.h11
-rw-r--r--arch/loongarch/include/asm/irq_work.h10
-rw-r--r--arch/loongarch/include/asm/kfence.h1
-rw-r--r--arch/loongarch/include/asm/kvm_host.h48
-rw-r--r--arch/loongarch/include/asm/kvm_para.h172
-rw-r--r--arch/loongarch/include/asm/kvm_vcpu.h16
-rw-r--r--arch/loongarch/include/asm/loongarch.h26
-rw-r--r--arch/loongarch/include/asm/numa.h1
-rw-r--r--arch/loongarch/include/asm/paravirt.h35
-rw-r--r--arch/loongarch/include/asm/paravirt_api_clock.h1
-rw-r--r--arch/loongarch/include/asm/perf_event.h3
-rw-r--r--arch/loongarch/include/asm/pgtable-bits.h6
-rw-r--r--arch/loongarch/include/asm/pgtable.h23
-rw-r--r--arch/loongarch/include/asm/setup.h5
-rw-r--r--arch/loongarch/include/asm/smp.h30
-rw-r--r--arch/loongarch/include/asm/stackframe.h13
-rw-r--r--arch/loongarch/include/asm/unistd.h3
-rw-r--r--arch/loongarch/include/asm/uprobes.h4
-rw-r--r--arch/loongarch/include/asm/video.h (renamed from arch/loongarch/include/asm/fb.h)8
-rw-r--r--arch/loongarch/include/uapi/asm/Kbuild2
-rw-r--r--arch/loongarch/include/uapi/asm/kvm.h8
-rw-r--r--arch/loongarch/include/uapi/asm/unistd.h4
-rw-r--r--arch/loongarch/kernel/Makefile1
-rw-r--r--arch/loongarch/kernel/Makefile.syscalls (renamed from arch/s390/lib/expoline/Makefile)2
-rw-r--r--arch/loongarch/kernel/acpi.c22
-rw-r--r--arch/loongarch/kernel/dma.c9
-rw-r--r--arch/loongarch/kernel/ftrace_dyn.c3
-rw-r--r--arch/loongarch/kernel/head.S13
-rw-r--r--arch/loongarch/kernel/hw_breakpoint.c96
-rw-r--r--arch/loongarch/kernel/irq.c24
-rw-r--r--arch/loongarch/kernel/kprobes.c4
-rw-r--r--arch/loongarch/kernel/machine_kexec.c2
-rw-r--r--arch/loongarch/kernel/module.c6
-rw-r--r--arch/loongarch/kernel/paravirt.c302
-rw-r--r--arch/loongarch/kernel/perf_event.c14
-rw-r--r--arch/loongarch/kernel/ptrace.c50
-rw-r--r--arch/loongarch/kernel/relocate.c52
-rw-r--r--arch/loongarch/kernel/setup.c10
-rw-r--r--arch/loongarch/kernel/smp.c78
-rw-r--r--arch/loongarch/kernel/syscall.c27
-rw-r--r--arch/loongarch/kernel/time.c14
-rw-r--r--arch/loongarch/kernel/vmlinux.lds.S18
-rw-r--r--arch/loongarch/kvm/Kconfig1
-rw-r--r--arch/loongarch/kvm/Makefile2
-rw-r--r--arch/loongarch/kvm/exit.c185
-rw-r--r--arch/loongarch/kvm/main.c1
-rw-r--r--arch/loongarch/kvm/mmu.c104
-rw-r--r--arch/loongarch/kvm/tlb.c5
-rw-r--r--arch/loongarch/kvm/trace.h20
-rw-r--r--arch/loongarch/kvm/vcpu.c261
-rw-r--r--arch/loongarch/kvm/vm.c11
-rw-r--r--arch/loongarch/lib/Makefile2
-rw-r--r--arch/loongarch/lib/tishift.S56
-rw-r--r--arch/loongarch/mm/hugetlbpage.c12
-rw-r--r--arch/loongarch/mm/init.c21
-rw-r--r--arch/loongarch/mm/mmap.c3
-rw-r--r--arch/loongarch/mm/tlbex.S9
-rw-r--r--arch/loongarch/net/bpf_jit.c22
-rw-r--r--arch/loongarch/power/platform.c37
-rw-r--r--arch/loongarch/power/suspend.c4
-rw-r--r--arch/loongarch/power/suspend_asm.S8
-rw-r--r--arch/loongarch/vdso/Makefile9
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68k/amiga/config.c11
-rw-r--r--arch/m68k/atari/ataints.c6
-rw-r--r--arch/m68k/configs/amiga_defconfig5
-rw-r--r--arch/m68k/configs/apollo_defconfig5
-rw-r--r--arch/m68k/configs/atari_defconfig5
-rw-r--r--arch/m68k/configs/bvme6000_defconfig5
-rw-r--r--arch/m68k/configs/hp300_defconfig5
-rw-r--r--arch/m68k/configs/mac_defconfig5
-rw-r--r--arch/m68k/configs/multi_defconfig5
-rw-r--r--arch/m68k/configs/mvme147_defconfig5
-rw-r--r--arch/m68k/configs/mvme16x_defconfig5
-rw-r--r--arch/m68k/configs/q40_defconfig5
-rw-r--r--arch/m68k/configs/sun3_defconfig5
-rw-r--r--arch/m68k/configs/sun3x_defconfig5
-rw-r--r--arch/m68k/emu/nfblock.c4
-rw-r--r--arch/m68k/emu/nfcon.c1
-rw-r--r--arch/m68k/include/asm/cmpxchg.h2
-rw-r--r--arch/m68k/include/asm/pgtable.h2
-rw-r--r--arch/m68k/include/asm/thread_info.h9
-rw-r--r--arch/m68k/include/asm/unistd.h1
-rw-r--r--arch/m68k/include/asm/video.h (renamed from arch/m68k/include/asm/fb.h)8
-rw-r--r--arch/m68k/include/uapi/asm/ptrace.h2
-rwxr-xr-xarch/m68k/install.sh2
-rw-r--r--arch/m68k/kernel/entry.S4
-rw-r--r--arch/m68k/kernel/syscalls/syscall.tbl1
-rw-r--r--arch/m68k/mac/misc.c36
-rw-r--r--arch/microblaze/configs/mmu_defconfig2
-rw-r--r--arch/microblaze/kernel/Makefile1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c2
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c2
-rw-r--r--arch/microblaze/kernel/syscalls/syscall.tbl1
-rw-r--r--arch/mips/Kbuild.platforms2
-rw-r--r--arch/mips/Kconfig20
-rw-r--r--arch/mips/Makefile2
-rw-r--r--arch/mips/alchemy/common/platform.c8
-rw-r--r--arch/mips/alchemy/devboards/db1000.c80
-rw-r--r--arch/mips/bcm47xx/prom.c6
-rw-r--r--arch/mips/bcm47xx/setup.c8
-rw-r--r--arch/mips/bcm63xx/prom.c3
-rw-r--r--arch/mips/bcm63xx/setup.c8
-rw-r--r--arch/mips/bmips/dma.c2
-rw-r--r--arch/mips/bmips/setup.c36
-rw-r--r--arch/mips/boot/compressed/Makefile6
-rw-r--r--arch/mips/boot/dts/Makefile2
-rw-r--r--arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi102
-rw-r--r--arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts1
-rw-r--r--arch/mips/boot/dts/mobileye/Makefile1
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi (renamed from arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi)54
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi125
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq5.dtsi22
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq6h-epm6.dts22
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi52
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq6h-pins.dtsi88
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq6h.dtsi98
-rw-r--r--arch/mips/boot/dts/ralink/mt7621.dtsi430
-rw-r--r--arch/mips/boot/dts/realtek/Makefile1
-rw-r--r--arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts73
-rw-r--r--arch/mips/boot/dts/realtek/rtl838x.dtsi1
-rw-r--r--arch/mips/boot/dts/realtek/rtl83xx.dtsi4
-rw-r--r--arch/mips/boot/dts/realtek/rtl930x.dtsi79
-rw-r--r--arch/mips/configs/ci20_defconfig2
-rw-r--r--arch/mips/configs/db1xxx_defconfig1
-rw-r--r--arch/mips/configs/eyeq5_defconfig2
-rw-r--r--arch/mips/configs/eyeq6_defconfig111
-rw-r--r--arch/mips/configs/generic/64r6.config2
-rw-r--r--arch/mips/configs/generic/board-litex.config8
-rw-r--r--arch/mips/configs/generic_defconfig1
-rw-r--r--arch/mips/configs/ip30_defconfig183
-rw-r--r--arch/mips/configs/lemote2f_defconfig54
-rw-r--r--arch/mips/configs/rs90_defconfig2
-rw-r--r--arch/mips/crypto/poly1305-glue.c1
-rw-r--r--arch/mips/dec/setup.c2
-rw-r--r--arch/mips/generic/Makefile1
-rw-r--r--arch/mips/generic/board-realtek.c79
-rw-r--r--arch/mips/include/asm/asm.h3
-rw-r--r--arch/mips/include/asm/bmips.h1
-rw-r--r--arch/mips/include/asm/fpu.h15
-rw-r--r--arch/mips/include/asm/kvm_host.h1
-rw-r--r--arch/mips/include/asm/mach-loongson64/boot_param.h2
-rw-r--r--arch/mips/include/asm/mips-cm.h4
-rw-r--r--arch/mips/include/asm/mips-cps.h39
-rw-r--r--arch/mips/include/asm/mips-gic.h50
-rw-r--r--arch/mips/include/asm/mipsmtregs.h2
-rw-r--r--arch/mips/include/asm/pgtable-32.h2
-rw-r--r--arch/mips/include/asm/pgtable-64.h6
-rw-r--r--arch/mips/include/asm/pgtable.h4
-rw-r--r--arch/mips/include/asm/pm.h22
-rw-r--r--arch/mips/include/asm/r4k-timer.h5
-rw-r--r--arch/mips/include/asm/setup.h6
-rw-r--r--arch/mips/include/asm/sgi/ip22.h3
-rw-r--r--arch/mips/include/asm/smp.h1
-rw-r--r--arch/mips/include/asm/stackframe.h19
-rw-r--r--arch/mips/include/asm/unistd.h1
-rw-r--r--arch/mips/include/asm/video.h (renamed from arch/mips/include/asm/fb.h)12
-rw-r--r--arch/mips/jazz/jazzdma.c2
-rw-r--r--arch/mips/kernel/csrc-r4k.c24
-rw-r--r--arch/mips/kernel/elf.c4
-rw-r--r--arch/mips/kernel/fpu-probe.c9
-rw-r--r--arch/mips/kernel/mips-cm.c37
-rw-r--r--arch/mips/kernel/module.c10
-rw-r--r--arch/mips/kernel/smp-bmips.c22
-rw-r--r--arch/mips/kernel/smp-cps.c5
-rw-r--r--arch/mips/kernel/smp.c2
-rw-r--r--arch/mips/kernel/sync-r4k.c281
-rw-r--r--arch/mips/kernel/syscalls/Makefile2
-rw-r--r--arch/mips/kernel/syscalls/syscall_n32.tbl3
-rw-r--r--arch/mips/kernel/syscalls/syscall_n64.tbl1
-rw-r--r--arch/mips/kernel/syscalls/syscall_o32.tbl5
-rw-r--r--arch/mips/kvm/interrupt.h4
-rw-r--r--arch/mips/kvm/loongson_ipi.c2
-rw-r--r--arch/mips/kvm/mips.c4
-rw-r--r--arch/mips/kvm/mmu.c30
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c20
-rw-r--r--arch/mips/loongson64/Makefile2
-rw-r--r--arch/mips/loongson64/dma.c1
-rw-r--r--arch/mips/loongson64/env.c8
-rw-r--r--arch/mips/loongson64/pm.c88
-rw-r--r--arch/mips/loongson64/reset.c38
-rw-r--r--arch/mips/loongson64/sleeper.S21
-rw-r--r--arch/mips/loongson64/smp.c58
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/mips/mm/dma-noncoherent.c3
-rw-r--r--arch/mips/mm/fault.c4
-rw-r--r--arch/mips/mm/hugetlbpage.c10
-rw-r--r--arch/mips/mm/init.c23
-rw-r--r--arch/mips/mm/mmap.c3
-rw-r--r--arch/mips/mm/tlb-r4k.c2
-rw-r--r--arch/mips/mobileye/Kconfig26
-rw-r--r--arch/mips/mobileye/Platform1
-rw-r--r--arch/mips/net/bpf_jit_comp.c3
-rw-r--r--arch/mips/pci/ops-rc32434.c4
-rw-r--r--arch/mips/pci/pcie-octeon.c6
-rw-r--r--arch/mips/rb532/gpio.c2
-rw-r--r--arch/mips/rb532/prom.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-gio.c4
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-setup.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c15
-rw-r--r--arch/mips/sgi-ip30/ip30-console.c1
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c1
-rw-r--r--arch/mips/vdso/Makefile11
-rw-r--r--arch/nios2/boot/dts/Makefile3
-rwxr-xr-xarch/nios2/boot/install.sh2
-rw-r--r--arch/nios2/include/asm/Kbuild2
-rw-r--r--arch/nios2/include/asm/pgtable.h5
-rw-r--r--arch/nios2/include/asm/unistd.h12
-rw-r--r--arch/nios2/include/uapi/asm/Kbuild2
-rw-r--r--arch/nios2/include/uapi/asm/unistd.h14
-rw-r--r--arch/nios2/kernel/Makefile.syscalls3
-rw-r--r--arch/nios2/kernel/module.c20
-rw-r--r--arch/nios2/kernel/syscall_table.c6
-rw-r--r--arch/nios2/mm/init.c21
-rw-r--r--arch/openrisc/Kconfig9
-rw-r--r--arch/openrisc/include/asm/Kbuild2
-rw-r--r--arch/openrisc/include/asm/fpu.h22
-rw-r--r--arch/openrisc/include/asm/processor.h1
-rw-r--r--arch/openrisc/include/asm/ptrace.h3
-rw-r--r--arch/openrisc/include/asm/syscalls.h4
-rw-r--r--arch/openrisc/include/asm/unistd.h8
-rw-r--r--arch/openrisc/include/uapi/asm/Kbuild2
-rw-r--r--arch/openrisc/include/uapi/asm/elf.h75
-rw-r--r--arch/openrisc/include/uapi/asm/unistd.h15
-rw-r--r--arch/openrisc/kernel/Makefile.syscalls3
-rw-r--r--arch/openrisc/kernel/entry.S15
-rw-r--r--arch/openrisc/kernel/module.c18
-rw-r--r--arch/openrisc/kernel/process.c13
-rw-r--r--arch/openrisc/kernel/ptrace.c18
-rw-r--r--arch/openrisc/kernel/signal.c36
-rw-r--r--arch/openrisc/kernel/sys_call_table.c9
-rw-r--r--arch/openrisc/kernel/traps.c144
-rw-r--r--arch/parisc/Kconfig3
-rw-r--r--arch/parisc/Makefile2
-rw-r--r--arch/parisc/boot/compressed/Makefile4
-rw-r--r--arch/parisc/configs/generic-32bit_defconfig2
-rw-r--r--arch/parisc/include/asm/cacheflush.h15
-rw-r--r--arch/parisc/include/asm/cmpxchg.h22
-rw-r--r--arch/parisc/include/asm/fb.h14
-rw-r--r--arch/parisc/include/asm/page.h1
-rw-r--r--arch/parisc/include/asm/parisc-device.h2
-rw-r--r--arch/parisc/include/asm/pgtable.h27
-rw-r--r--arch/parisc/include/asm/signal.h12
-rw-r--r--arch/parisc/include/asm/unistd.h55
-rw-r--r--arch/parisc/include/asm/vdso.h2
-rw-r--r--arch/parisc/include/asm/video.h16
-rw-r--r--arch/parisc/include/uapi/asm/signal.h10
-rwxr-xr-xarch/parisc/install.sh2
-rw-r--r--arch/parisc/kernel/cache.c419
-rw-r--r--arch/parisc/kernel/drivers.c4
-rw-r--r--arch/parisc/kernel/ftrace.c3
-rw-r--r--arch/parisc/kernel/module.c12
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c2
-rw-r--r--arch/parisc/kernel/smp.c2
-rw-r--r--arch/parisc/kernel/sys_parisc.c6
-rw-r--r--arch/parisc/kernel/sys_parisc32.c9
-rw-r--r--arch/parisc/kernel/syscalls/syscall.tbl7
-rw-r--r--arch/parisc/kernel/unaligned.c2
-rw-r--r--arch/parisc/kernel/vdso32/Makefile25
-rw-r--r--arch/parisc/kernel/vdso32/vdso32.lds.S3
-rw-r--r--arch/parisc/kernel/vdso32/vdso32_generic.c32
-rw-r--r--arch/parisc/kernel/vdso64/Makefile27
-rw-r--r--arch/parisc/kernel/vdso64/vdso64.lds.S2
-rw-r--r--arch/parisc/kernel/vdso64/vdso64_generic.c24
-rw-r--r--arch/parisc/lib/bitops.c52
-rw-r--r--arch/parisc/math-emu/driver.c6
-rw-r--r--arch/parisc/mm/hugetlbpage.c11
-rw-r--r--arch/parisc/mm/init.c23
-rw-r--r--arch/parisc/net/bpf_jit_core.c8
-rw-r--r--arch/parisc/video/Makefile2
-rw-r--r--arch/parisc/video/video-sti.c (renamed from arch/parisc/video/fbdev.c)9
-rw-r--r--arch/powerpc/Kbuild3
-rw-r--r--arch/powerpc/Kconfig31
-rw-r--r--arch/powerpc/Kconfig.debug13
-rw-r--r--arch/powerpc/Makefile16
-rw-r--r--arch/powerpc/boot/4xx.c266
-rw-r--r--arch/powerpc/boot/4xx.h4
-rw-r--r--arch/powerpc/boot/Makefile21
-rw-r--r--arch/powerpc/boot/cuboot-acadia.c171
-rw-r--r--arch/powerpc/boot/cuboot-hotfoot.c139
-rw-r--r--arch/powerpc/boot/cuboot-kilauea.c46
-rw-r--r--arch/powerpc/boot/dcr.h11
-rw-r--r--arch/powerpc/boot/decompress.c2
-rw-r--r--arch/powerpc/boot/dts/Makefile3
-rw-r--r--arch/powerpc/boot/dts/acadia.dts224
-rw-r--r--arch/powerpc/boot/dts/fsl/Makefile3
-rw-r--r--arch/powerpc/boot/dts/fsl/b4si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9131rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132qds.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/c293pcie.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/c293si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi14
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts16
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts16
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb.dtsi16
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010si-post.dtsi16
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020si-post.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021si-post.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022si-post.dtsi7
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020si-post.dtsi17
-rw-r--r--arch/powerpc/boot/dts/fsl/pq3-power.dtsi19
-rw-r--r--arch/powerpc/boot/dts/fsl/t1023si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1024rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/t2081si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/haleakala.dts281
-rw-r--r--arch/powerpc/boot/dts/hotfoot.dts296
-rw-r--r--arch/powerpc/boot/dts/kilauea.dts407
-rw-r--r--arch/powerpc/boot/dts/klondike.dts212
-rw-r--r--arch/powerpc/boot/dts/makalu.dts353
-rw-r--r--arch/powerpc/boot/dts/obs600.dts314
-rw-r--r--arch/powerpc/boot/main.c2
-rw-r--r--arch/powerpc/boot/ppcboot-hotfoot.h119
-rw-r--r--arch/powerpc/boot/ppcboot.h2
-rw-r--r--arch/powerpc/boot/ps3.c2
-rwxr-xr-xarch/powerpc/boot/wrapper22
-rw-r--r--arch/powerpc/configs/40x.config2
-rw-r--r--arch/powerpc/configs/40x/acadia_defconfig61
-rw-r--r--arch/powerpc/configs/40x/kilauea_defconfig69
-rw-r--r--arch/powerpc/configs/40x/klondike_defconfig43
-rw-r--r--arch/powerpc/configs/40x/makalu_defconfig59
-rw-r--r--arch/powerpc/configs/40x/obs600_defconfig69
-rw-r--r--arch/powerpc/configs/40x/walnut_defconfig55
-rw-r--r--arch/powerpc/configs/85xx-hw.config2
-rw-r--r--arch/powerpc/configs/adder875_defconfig2
-rw-r--r--arch/powerpc/configs/ep88xc_defconfig2
-rw-r--r--arch/powerpc/configs/mpc866_ads_defconfig2
-rw-r--r--arch/powerpc/configs/mpc885_ads_defconfig2
-rw-r--r--arch/powerpc/configs/ppc40x_defconfig74
-rw-r--r--arch/powerpc/configs/ppc6xx_defconfig1
-rw-r--r--arch/powerpc/configs/tqm8xx_defconfig2
-rw-r--r--arch/powerpc/crypto/.gitignore2
-rw-r--r--arch/powerpc/crypto/Kconfig11
-rw-r--r--arch/powerpc/crypto/Makefile2
-rw-r--r--arch/powerpc/crypto/curve25519-ppc64le-core.c299
-rw-r--r--arch/powerpc/crypto/curve25519-ppc64le_asm.S671
-rw-r--r--arch/powerpc/include/asm/Kbuild1
-rw-r--r--arch/powerpc/include/asm/book3s/32/pgalloc.h2
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-4k.h15
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h40
-rw-r--r--arch/powerpc/include/asm/book3s/64/hugetlb.h38
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable-4k.h67
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable-64k.h45
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h49
-rw-r--r--arch/powerpc/include/asm/cacheflush.h2
-rw-r--r--arch/powerpc/include/asm/cpu_has_feature.h5
-rw-r--r--arch/powerpc/include/asm/cputable.h7
-rw-r--r--arch/powerpc/include/asm/cputime.h13
-rw-r--r--arch/powerpc/include/asm/eeh.h2
-rw-r--r--arch/powerpc/include/asm/elf.h2
-rw-r--r--arch/powerpc/include/asm/fadump-internal.h36
-rw-r--r--arch/powerpc/include/asm/fadump.h2
-rw-r--r--arch/powerpc/include/asm/feature-fixups.h2
-rw-r--r--arch/powerpc/include/asm/fpu.h28
-rw-r--r--arch/powerpc/include/asm/ftrace.h2
-rw-r--r--arch/powerpc/include/asm/guest-state-buffer.h3
-rw-r--r--arch/powerpc/include/asm/hugetlb.h15
-rw-r--r--arch/powerpc/include/asm/hvcall.h10
-rw-r--r--arch/powerpc/include/asm/hw_irq.h8
-rw-r--r--arch/powerpc/include/asm/interrupt.h10
-rw-r--r--arch/powerpc/include/asm/io.h28
-rw-r--r--arch/powerpc/include/asm/iommu.h16
-rw-r--r--arch/powerpc/include/asm/irq.h2
-rw-r--r--arch/powerpc/include/asm/kasan.h2
-rw-r--r--arch/powerpc/include/asm/kexec.h21
-rw-r--r--arch/powerpc/include/asm/kexec_ranges.h20
-rw-r--r--arch/powerpc/include/asm/kfence.h11
-rw-r--r--arch/powerpc/include/asm/kup.h2
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h1
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h5
-rw-r--r--arch/powerpc/include/asm/kvm_host.h4
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h1
-rw-r--r--arch/powerpc/include/asm/lppaca.h11
-rw-r--r--arch/powerpc/include/asm/mmu.h16
-rw-r--r--arch/powerpc/include/asm/module.h5
-rw-r--r--arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h38
-rw-r--r--arch/powerpc/include/asm/nohash/32/mmu-40x.h68
-rw-r--r--arch/powerpc/include/asm/nohash/32/mmu-8xx.h9
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgtable.h4
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-40x.h73
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-44x.h3
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-85xx.h3
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-8xx.h58
-rw-r--r--arch/powerpc/include/asm/nohash/hugetlb-e500.h39
-rw-r--r--arch/powerpc/include/asm/nohash/mmu-e500.h6
-rw-r--r--arch/powerpc/include/asm/nohash/mmu.h5
-rw-r--r--arch/powerpc/include/asm/nohash/pgalloc.h2
-rw-r--r--arch/powerpc/include/asm/nohash/pgtable.h56
-rw-r--r--arch/powerpc/include/asm/nohash/pte-e500.h63
-rw-r--r--arch/powerpc/include/asm/opal-api.h4
-rw-r--r--arch/powerpc/include/asm/page.h32
-rw-r--r--arch/powerpc/include/asm/percpu.h10
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h3
-rw-r--r--arch/powerpc/include/asm/pgtable-be-types.h10
-rw-r--r--arch/powerpc/include/asm/pgtable-types.h13
-rw-r--r--arch/powerpc/include/asm/pgtable.h3
-rw-r--r--arch/powerpc/include/asm/plpar_wrappers.h28
-rw-r--r--arch/powerpc/include/asm/pmac_feature.h2
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h6
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h2
-rw-r--r--arch/powerpc/include/asm/processor.h15
-rw-r--r--arch/powerpc/include/asm/ps3.h6
-rw-r--r--arch/powerpc/include/asm/ptrace.h2
-rw-r--r--arch/powerpc/include/asm/reg.h29
-rw-r--r--arch/powerpc/include/asm/reg_booke.h113
-rw-r--r--arch/powerpc/include/asm/time.h7
-rw-r--r--arch/powerpc/include/asm/trace.h4
-rw-r--r--arch/powerpc/include/asm/uaccess.h27
-rw-r--r--arch/powerpc/include/asm/udbg.h1
-rw-r--r--arch/powerpc/include/asm/uninorth.h2
-rw-r--r--arch/powerpc/include/asm/unistd.h1
-rw-r--r--arch/powerpc/include/asm/vdso/gettimeofday.h26
-rw-r--r--arch/powerpc/include/asm/video.h (renamed from arch/powerpc/include/asm/fb.h)8
-rw-r--r--arch/powerpc/include/asm/vio.h6
-rw-r--r--arch/powerpc/include/uapi/asm/bootx.h2
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h3
-rw-r--r--arch/powerpc/include/uapi/asm/papr_pdsm.h165
-rw-r--r--arch/powerpc/kernel/Makefile8
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S4
-rw-r--r--arch/powerpc/kernel/cpu_specs.h4
-rw-r--r--arch/powerpc/kernel/cpu_specs_40x.h280
-rw-r--r--arch/powerpc/kernel/dexcr.c124
-rw-r--r--arch/powerpc/kernel/dma-iommu.c2
-rw-r--r--arch/powerpc/kernel/eeh.c27
-rw-r--r--arch/powerpc/kernel/eeh_driver.c13
-rw-r--r--arch/powerpc/kernel/eeh_pe.c15
-rw-r--r--arch/powerpc/kernel/entry_32.S48
-rw-r--r--arch/powerpc/kernel/epapr_hcalls.S2
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S4
-rw-r--r--arch/powerpc/kernel/fadump.c547
-rw-r--r--arch/powerpc/kernel/head_32.h12
-rw-r--r--arch/powerpc/kernel/head_40x.S721
-rw-r--r--arch/powerpc/kernel/head_64.S5
-rw-r--r--arch/powerpc/kernel/head_85xx.S70
-rw-r--r--arch/powerpc/kernel/head_8xx.S14
-rw-r--r--arch/powerpc/kernel/head_book3s_32.S6
-rw-r--r--arch/powerpc/kernel/head_booke.h3
-rw-r--r--arch/powerpc/kernel/iommu.c171
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/kgdb.c4
-rw-r--r--arch/powerpc/kernel/kprobes-ftrace.c3
-rw-r--r--arch/powerpc/kernel/kprobes.c22
-rw-r--r--arch/powerpc/kernel/misc_32.S40
-rw-r--r--arch/powerpc/kernel/misc_64.S4
-rw-r--r--arch/powerpc/kernel/module.c40
-rw-r--r--arch/powerpc/kernel/pci-common.c2
-rw-r--r--arch/powerpc/kernel/pci-hotplug.c35
-rw-r--r--arch/powerpc/kernel/process.c33
-rw-r--r--arch/powerpc/kernel/prom.c35
-rw-r--r--arch/powerpc/kernel/prom_init.c4
-rw-r--r--arch/powerpc/kernel/ptrace/ptrace-tm.c2
-rw-r--r--arch/powerpc/kernel/ptrace/ptrace-view.c7
-rw-r--r--arch/powerpc/kernel/rtas.c4
-rw-r--r--arch/powerpc/kernel/rtas_flash.c1
-rw-r--r--arch/powerpc/kernel/setup-common.c2
-rw-r--r--arch/powerpc/kernel/setup.h2
-rw-r--r--arch/powerpc/kernel/setup_32.c2
-rw-r--r--arch/powerpc/kernel/setup_64.c8
-rw-r--r--arch/powerpc/kernel/smp.c2
-rw-r--r--arch/powerpc/kernel/syscalls/syscall.tbl7
-rw-r--r--arch/powerpc/kernel/sysfs.c4
-rw-r--r--arch/powerpc/kernel/time.c24
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--arch/powerpc/kernel/udbg.c3
-rw-r--r--arch/powerpc/kernel/udbg_16550.c23
-rw-r--r--arch/powerpc/kernel/vdso/Makefile16
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S2
-rw-r--r--arch/powerpc/kexec/Makefile4
-rw-r--r--arch/powerpc/kexec/core_64.c123
-rw-r--r--arch/powerpc/kexec/crash.c195
-rw-r--r--arch/powerpc/kexec/elf_64.c15
-rw-r--r--arch/powerpc/kexec/file_load_64.c388
-rw-r--r--arch/powerpc/kexec/ranges.c312
-rw-r--r--arch/powerpc/kvm/book3s.c9
-rw-r--r--arch/powerpc/kvm/book3s.h1
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c12
-rw-r--r--arch/powerpc/kvm/book3s_64_vio.c18
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c4
-rw-r--r--arch/powerpc/kvm/book3s_hv.c106
-rw-r--r--arch/powerpc/kvm/book3s_hv.h3
-rw-r--r--arch/powerpc/kvm/book3s_hv_nestedv2.c29
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_xics.c2
-rw-r--r--arch/powerpc/kvm/book3s_pr.c8
-rw-r--r--arch/powerpc/kvm/book3s_xive.c2
-rw-r--r--arch/powerpc/kvm/e500_mmu_host.c6
-rw-r--r--arch/powerpc/kvm/powerpc.c6
-rw-r--r--arch/powerpc/kvm/test-guest-state-buffer.c3
-rw-r--r--arch/powerpc/kvm/trace_hv.h29
-rw-r--r--arch/powerpc/lib/Makefile2
-rw-r--r--arch/powerpc/lib/code-patching.c33
-rw-r--r--arch/powerpc/lib/feature-fixups.c8
-rw-r--r--arch/powerpc/lib/test-code-patching.c92
-rw-r--r--arch/powerpc/mm/Makefile2
-rw-r--r--arch/powerpc/mm/book3s32/mmu.c2
-rw-r--r--arch/powerpc/mm/book3s64/Makefile2
-rw-r--r--arch/powerpc/mm/book3s64/hash_utils.c11
-rw-r--r--arch/powerpc/mm/book3s64/hugetlbpage.c10
-rw-r--r--arch/powerpc/mm/book3s64/pgtable.c13
-rw-r--r--arch/powerpc/mm/book3s64/radix_pgtable.c84
-rw-r--r--arch/powerpc/mm/book3s64/slice.c20
-rw-r--r--arch/powerpc/mm/cacheflush.c2
-rw-r--r--arch/powerpc/mm/drmem.c4
-rw-r--r--arch/powerpc/mm/fault.c37
-rw-r--r--arch/powerpc/mm/hugetlbpage.c455
-rw-r--r--arch/powerpc/mm/init-common.c11
-rw-r--r--arch/powerpc/mm/kasan/8xx.c21
-rw-r--r--arch/powerpc/mm/kasan/init_book3e_64.c2
-rw-r--r--arch/powerpc/mm/kasan/init_book3s_64.c2
-rw-r--r--arch/powerpc/mm/mem.c67
-rw-r--r--arch/powerpc/mm/mmu_context.c2
-rw-r--r--arch/powerpc/mm/mmu_decl.h8
-rw-r--r--arch/powerpc/mm/nohash/40x.c161
-rw-r--r--arch/powerpc/mm/nohash/8xx.c43
-rw-r--r--arch/powerpc/mm/nohash/Makefile5
-rw-r--r--arch/powerpc/mm/nohash/book3e_pgtable.c4
-rw-r--r--arch/powerpc/mm/nohash/kaslr_booke.c2
-rw-r--r--arch/powerpc/mm/nohash/kup.c2
-rw-r--r--arch/powerpc/mm/nohash/mmu_context.c5
-rw-r--r--arch/powerpc/mm/nohash/tlb.c407
-rw-r--r--arch/powerpc/mm/nohash/tlb_64e.c314
-rw-r--r--arch/powerpc/mm/nohash/tlb_low.S27
-rw-r--r--arch/powerpc/mm/nohash/tlb_low_64e.S428
-rw-r--r--arch/powerpc/mm/numa.c14
-rw-r--r--arch/powerpc/mm/pgtable.c94
-rw-r--r--arch/powerpc/mm/pgtable_32.c2
-rw-r--r--arch/powerpc/mm/pgtable_64.c6
-rw-r--r--arch/powerpc/mm/ptdump/Makefile2
-rw-r--r--arch/powerpc/mm/ptdump/hashpagetable.c2
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c14
-rw-r--r--arch/powerpc/net/bpf_jit_comp32.c149
-rw-r--r--arch/powerpc/net/bpf_jit_comp64.c207
-rw-r--r--arch/powerpc/perf/core-book3s.c45
-rw-r--r--arch/powerpc/perf/hv-24x7.c10
-rw-r--r--arch/powerpc/perf/power10-pmu.c3
-rw-r--r--arch/powerpc/platforms/40x/Kconfig78
-rw-r--r--arch/powerpc/platforms/40x/Makefile2
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c74
-rw-r--r--arch/powerpc/platforms/44x/Makefile6
-rw-r--r--arch/powerpc/platforms/44x/cpm.c (renamed from arch/powerpc/platforms/4xx/cpm.c)0
-rw-r--r--arch/powerpc/platforms/44x/gpio.c (renamed from arch/powerpc/platforms/4xx/gpio.c)0
-rw-r--r--arch/powerpc/platforms/44x/hsta_msi.c (renamed from arch/powerpc/platforms/4xx/hsta_msi.c)0
-rw-r--r--arch/powerpc/platforms/44x/machine_check.c15
-rw-r--r--arch/powerpc/platforms/44x/pci.c (renamed from arch/powerpc/platforms/4xx/pci.c)100
-rw-r--r--arch/powerpc/platforms/44x/pci.h (renamed from arch/powerpc/platforms/4xx/pci.h)0
-rw-r--r--arch/powerpc/platforms/44x/soc.c (renamed from arch/powerpc/platforms/4xx/soc.c)0
-rw-r--r--arch/powerpc/platforms/44x/uic.c (renamed from arch/powerpc/platforms/4xx/uic.c)0
-rw-r--r--arch/powerpc/platforms/4xx/Makefile7
-rw-r--r--arch/powerpc/platforms/4xx/machine_check.c23
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c2
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_sleep.S6
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c2
-rw-r--r--arch/powerpc/platforms/83xx/suspend-asm.S6
-rw-r--r--arch/powerpc/platforms/85xx/smp.c9
-rw-r--r--arch/powerpc/platforms/85xx/t1042rdb_diu.c1
-rw-r--r--arch/powerpc/platforms/Kconfig1
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype28
-rw-r--r--arch/powerpc/platforms/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/cbe_powerbutton.c1
-rw-r--r--arch/powerpc/platforms/cell/cbe_thermal.c1
-rw-r--r--arch/powerpc/platforms/cell/cpufreq_spudemand.c1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c17
-rw-r--r--arch/powerpc/platforms/cell/smp.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c20
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c2
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c1
-rw-r--r--arch/powerpc/platforms/maple/pci.c2
-rw-r--r--arch/powerpc/platforms/powermac/pic.c2
-rw-r--r--arch/powerpc/platforms/powermac/sleep.S2
-rw-r--r--arch/powerpc/platforms/powernv/opal-fadump.c35
-rw-r--r--arch/powerpc/platforms/powernv/opal.c10
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c6
-rw-r--r--arch/powerpc/platforms/powernv/pci-sriov.c4
-rw-r--r--arch/powerpc/platforms/powernv/vas-window.c2
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c61
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c8
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/ibmebus.c2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c781
-rw-r--r--arch/powerpc/platforms/pseries/kexec.c8
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c6
-rw-r--r--arch/powerpc/platforms/pseries/lparcfg.c49
-rw-r--r--arch/powerpc/platforms/pseries/papr_scm.c44
-rw-r--r--arch/powerpc/platforms/pseries/pci.c27
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c14
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h1
-rw-r--r--arch/powerpc/platforms/pseries/rtas-fadump.c322
-rw-r--r--arch/powerpc/platforms/pseries/rtas-fadump.h29
-rw-r--r--arch/powerpc/platforms/pseries/setup.c5
-rw-r--r--arch/powerpc/platforms/pseries/vas.c24
-rw-r--r--arch/powerpc/platforms/pseries/vio.c16
-rw-r--r--arch/powerpc/purgatory/Makefile3
-rw-r--r--arch/powerpc/sysdev/Kconfig4
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c4
-rw-r--r--arch/powerpc/sysdev/fsl_gtm.c6
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c2
-rw-r--r--arch/powerpc/sysdev/rtc_cmos_setup.c1
-rw-r--r--arch/powerpc/sysdev/xive/common.c4
-rw-r--r--arch/powerpc/sysdev/xive/native.c2
-rw-r--r--arch/powerpc/xmon/Makefile2
-rw-r--r--arch/powerpc/xmon/ppc-dis.c33
-rw-r--r--arch/powerpc/xmon/xmon.c6
-rw-r--r--arch/riscv/Kconfig114
-rw-r--r--arch/riscv/Kconfig.socs22
-rw-r--r--arch/riscv/Makefile76
-rw-r--r--arch/riscv/boot/Makefile2
-rw-r--r--arch/riscv/boot/dts/allwinner/Makefile2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-clockworkpi-v3.14.dts252
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-devterm-v3.14.dts36
-rw-r--r--arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi11
-rw-r--r--arch/riscv/boot/dts/canaan/canaan_kd233.dts7
-rw-r--r--arch/riscv/boot/dts/canaan/k210.dtsi23
-rw-r--r--arch/riscv/boot/dts/canaan/k210_generic.dts5
-rw-r--r--arch/riscv/boot/dts/canaan/sipeed_maix_bit.dts9
-rw-r--r--arch/riscv/boot/dts/canaan/sipeed_maix_dock.dts7
-rw-r--r--arch/riscv/boot/dts/canaan/sipeed_maix_go.dts9
-rw-r--r--arch/riscv/boot/dts/canaan/sipeed_maixduino.dts10
-rw-r--r--arch/riscv/boot/dts/microchip/Makefile1
-rw-r--r--arch/riscv/boot/dts/microchip/mpfs-beaglev-fire-fabric.dtsi82
-rw-r--r--arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts223
-rw-r--r--arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts32
-rw-r--r--arch/riscv/boot/dts/renesas/r9a07g043f.dtsi75
-rw-r--r--arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi16
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts21
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1800b.dtsi9
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1812h.dtsi4
-rw-r--r--arch/riscv/boot/dts/sophgo/cv18xx.dtsi132
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts12
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042.dtsi55
-rw-r--r--arch/riscv/boot/dts/starfive/Makefile2
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100.dtsi2
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-common.dtsi658
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts37
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts65
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi679
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110.dtsi118
-rw-r--r--arch/riscv/boot/dts/thead/th1520.dtsi135
-rwxr-xr-xarch/riscv/boot/install.sh11
-rw-r--r--arch/riscv/configs/defconfig34
-rw-r--r--arch/riscv/configs/nommu_k210_defconfig5
-rw-r--r--arch/riscv/configs/nommu_k210_sdcard_defconfig5
-rw-r--r--arch/riscv/configs/nommu_virt_defconfig4
-rw-r--r--arch/riscv/errata/sifive/errata.c5
-rw-r--r--arch/riscv/include/asm/Kbuild3
-rw-r--r--arch/riscv/include/asm/arch_hweight.h8
-rw-r--r--arch/riscv/include/asm/atomic.h164
-rw-r--r--arch/riscv/include/asm/barrier.h45
-rw-r--r--arch/riscv/include/asm/bitops.h2
-rw-r--r--arch/riscv/include/asm/cache.h2
-rw-r--r--arch/riscv/include/asm/cacheflush.h13
-rw-r--r--arch/riscv/include/asm/cmpxchg.h466
-rw-r--r--arch/riscv/include/asm/cpufeature.h1
-rw-r--r--arch/riscv/include/asm/csr.h5
-rw-r--r--arch/riscv/include/asm/dmi.h24
-rw-r--r--arch/riscv/include/asm/errata_list.h12
-rw-r--r--arch/riscv/include/asm/fpu.h16
-rw-r--r--arch/riscv/include/asm/ftrace.h77
-rw-r--r--arch/riscv/include/asm/hugetlb.h8
-rw-r--r--arch/riscv/include/asm/hwcap.h12
-rw-r--r--arch/riscv/include/asm/hwprobe.h2
-rw-r--r--arch/riscv/include/asm/insn-def.h4
-rw-r--r--arch/riscv/include/asm/insn.h2
-rw-r--r--arch/riscv/include/asm/irqflags.h1
-rw-r--r--arch/riscv/include/asm/jump_label.h4
-rw-r--r--arch/riscv/include/asm/kasan.h4
-rw-r--r--arch/riscv/include/asm/kvm_aia_aplic.h58
-rw-r--r--arch/riscv/include/asm/kvm_aia_imsic.h38
-rw-r--r--arch/riscv/include/asm/kvm_host.h23
-rw-r--r--arch/riscv/include/asm/kvm_vcpu_pmu.h16
-rw-r--r--arch/riscv/include/asm/mmu.h9
-rw-r--r--arch/riscv/include/asm/page.h5
-rw-r--r--arch/riscv/include/asm/patch.h3
-rw-r--r--arch/riscv/include/asm/pgalloc.h32
-rw-r--r--arch/riscv/include/asm/pgtable-64.h22
-rw-r--r--arch/riscv/include/asm/pgtable-bits.h1
-rw-r--r--arch/riscv/include/asm/pgtable.h43
-rw-r--r--arch/riscv/include/asm/processor.h16
-rw-r--r--arch/riscv/include/asm/sbi.h54
-rw-r--r--arch/riscv/include/asm/signal.h12
-rw-r--r--arch/riscv/include/asm/smp.h15
-rw-r--r--arch/riscv/include/asm/suspend.h1
-rw-r--r--arch/riscv/include/asm/switch_to.h23
-rw-r--r--arch/riscv/include/asm/syscall_table.h7
-rw-r--r--arch/riscv/include/asm/tlbflush.h52
-rw-r--r--arch/riscv/include/asm/trace.h54
-rw-r--r--arch/riscv/include/asm/unistd.h13
-rw-r--r--arch/riscv/include/asm/vdso/processor.h8
-rw-r--r--arch/riscv/include/asm/vector.h10
-rw-r--r--arch/riscv/include/uapi/asm/Kbuild2
-rw-r--r--arch/riscv/include/uapi/asm/hwprobe.h14
-rw-r--r--arch/riscv/include/uapi/asm/kvm.h8
-rw-r--r--arch/riscv/include/uapi/asm/unistd.h41
-rw-r--r--arch/riscv/kernel/Makefile1
-rw-r--r--arch/riscv/kernel/Makefile.syscalls4
-rw-r--r--arch/riscv/kernel/asm-offsets.c18
-rw-r--r--arch/riscv/kernel/compat_syscall_table.c6
-rw-r--r--arch/riscv/kernel/compat_vdso/Makefile8
-rw-r--r--arch/riscv/kernel/cpu.c40
-rw-r--r--arch/riscv/kernel/cpu_ops_sbi.c2
-rw-r--r--arch/riscv/kernel/cpu_ops_spinwait.c3
-rw-r--r--arch/riscv/kernel/cpufeature.c336
-rw-r--r--arch/riscv/kernel/elf_kexec.c1
-rw-r--r--arch/riscv/kernel/fpu.S2
-rw-r--r--arch/riscv/kernel/ftrace.c61
-rw-r--r--arch/riscv/kernel/head.S22
-rw-r--r--arch/riscv/kernel/jump_label.c16
-rw-r--r--arch/riscv/kernel/kernel_mode_fpu.c28
-rw-r--r--arch/riscv/kernel/machine_kexec.c10
-rw-r--r--arch/riscv/kernel/mcount-dyn.S171
-rw-r--r--arch/riscv/kernel/module.c12
-rw-r--r--arch/riscv/kernel/paravirt.c6
-rw-r--r--arch/riscv/kernel/patch.c100
-rw-r--r--arch/riscv/kernel/pi/Makefile6
-rw-r--r--arch/riscv/kernel/probes/ftrace.c3
-rw-r--r--arch/riscv/kernel/probes/kprobes.c30
-rw-r--r--arch/riscv/kernel/sbi-ipi.c11
-rw-r--r--arch/riscv/kernel/sbi.c17
-rw-r--r--arch/riscv/kernel/smp.c11
-rw-r--r--arch/riscv/kernel/smpboot.c23
-rw-r--r--arch/riscv/kernel/stacktrace.c25
-rw-r--r--arch/riscv/kernel/suspend.c3
-rw-r--r--arch/riscv/kernel/sys_hwprobe.c23
-rw-r--r--arch/riscv/kernel/sys_riscv.c5
-rw-r--r--arch/riscv/kernel/syscall_table.c6
-rw-r--r--arch/riscv/kernel/traps_misaligned.c106
-rw-r--r--arch/riscv/kernel/vdso/Makefile8
-rw-r--r--arch/riscv/kernel/vector.c5
-rw-r--r--arch/riscv/kvm/Makefile2
-rw-r--r--arch/riscv/kvm/aia.c40
-rw-r--r--arch/riscv/kvm/aia_aplic.c2
-rw-r--r--arch/riscv/kvm/aia_device.c9
-rw-r--r--arch/riscv/kvm/aia_imsic.c2
-rw-r--r--arch/riscv/kvm/main.c18
-rw-r--r--arch/riscv/kvm/mmu.c20
-rw-r--r--arch/riscv/kvm/trace.h67
-rw-r--r--arch/riscv/kvm/vcpu.c95
-rw-r--r--arch/riscv/kvm/vcpu_exit.c6
-rw-r--r--arch/riscv/kvm/vcpu_insn.c15
-rw-r--r--arch/riscv/kvm/vcpu_onereg.c24
-rw-r--r--arch/riscv/kvm/vcpu_pmu.c262
-rw-r--r--arch/riscv/kvm/vcpu_sbi.c7
-rw-r--r--arch/riscv/kvm/vcpu_sbi_hsm.c42
-rw-r--r--arch/riscv/kvm/vcpu_sbi_pmu.c17
-rw-r--r--arch/riscv/kvm/vcpu_sbi_sta.c4
-rw-r--r--arch/riscv/kvm/vm.c1
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/crc32.c294
-rw-r--r--arch/riscv/lib/uaccess.S6
-rw-r--r--arch/riscv/mm/Makefile5
-rw-r--r--arch/riscv/mm/cacheflush.c120
-rw-r--r--arch/riscv/mm/context.c42
-rw-r--r--arch/riscv/mm/dma-noncoherent.c3
-rw-r--r--arch/riscv/mm/fault.c5
-rw-r--r--arch/riscv/mm/hugetlbpage.c12
-rw-r--r--arch/riscv/mm/init.c426
-rw-r--r--arch/riscv/mm/pageattr.c28
-rw-r--r--arch/riscv/mm/ptdump.c3
-rw-r--r--arch/riscv/mm/tlbflush.c75
-rw-r--r--arch/riscv/net/bpf_jit.h57
-rw-r--r--arch/riscv/net/bpf_jit_comp32.c3
-rw-r--r--arch/riscv/net/bpf_jit_comp64.c416
-rw-r--r--arch/riscv/net/bpf_jit_core.c20
-rw-r--r--arch/riscv/purgatory/Makefile8
-rw-r--r--arch/s390/Kconfig82
-rw-r--r--arch/s390/Makefile17
-rw-r--r--arch/s390/appldata/appldata_base.c10
-rw-r--r--arch/s390/boot/Makefile13
-rw-r--r--arch/s390/boot/alternative.c3
-rw-r--r--arch/s390/boot/boot.h18
-rw-r--r--arch/s390/boot/decompressor.c15
-rw-r--r--arch/s390/boot/decompressor.h8
-rwxr-xr-xarch/s390/boot/install.sh2
-rw-r--r--arch/s390/boot/ipl_parm.c7
-rw-r--r--arch/s390/boot/ipl_report.c2
-rw-r--r--arch/s390/boot/kaslr.c2
-rw-r--r--arch/s390/boot/kmsan.c6
-rw-r--r--arch/s390/boot/pgm_check_info.c22
-rw-r--r--arch/s390/boot/physmem_info.c8
-rw-r--r--arch/s390/boot/startup.c321
-rw-r--r--arch/s390/boot/string.c16
-rw-r--r--arch/s390/boot/uv.c8
-rw-r--r--arch/s390/boot/uv.h13
-rw-r--r--arch/s390/boot/vmem.c141
-rw-r--r--arch/s390/boot/vmlinux.lds.S29
-rw-r--r--arch/s390/configs/debug_defconfig50
-rw-r--r--arch/s390/configs/defconfig47
-rw-r--r--arch/s390/configs/zfcpdump_defconfig5
-rw-r--r--arch/s390/crypto/crc32-vx.c1
-rw-r--r--arch/s390/hypfs/hypfs_dbfs.c4
-rw-r--r--arch/s390/hypfs/hypfs_diag.c17
-rw-r--r--arch/s390/include/asm/abs_lowcore.h8
-rw-r--r--arch/s390/include/asm/alternative-asm.h56
-rw-r--r--arch/s390/include/asm/alternative.h155
-rw-r--r--arch/s390/include/asm/ap.h30
-rw-r--r--arch/s390/include/asm/arch_hweight.h76
-rw-r--r--arch/s390/include/asm/asm-prototypes.h1
-rw-r--r--arch/s390/include/asm/atomic_ops.h79
-rw-r--r--arch/s390/include/asm/bitops.h3
-rw-r--r--arch/s390/include/asm/ccwdev.h2
-rw-r--r--arch/s390/include/asm/checksum.h2
-rw-r--r--arch/s390/include/asm/chsc.h15
-rw-r--r--arch/s390/include/asm/cpacf.h112
-rw-r--r--arch/s390/include/asm/cpu_mf.h6
-rw-r--r--arch/s390/include/asm/current.h2
-rw-r--r--arch/s390/include/asm/dat-bits.h170
-rw-r--r--arch/s390/include/asm/diag.h8
-rw-r--r--arch/s390/include/asm/elf.h8
-rw-r--r--arch/s390/include/asm/entry-common.h2
-rw-r--r--arch/s390/include/asm/extmem.h7
-rw-r--r--arch/s390/include/asm/facility.h5
-rw-r--r--arch/s390/include/asm/ftrace.h9
-rw-r--r--arch/s390/include/asm/gmap.h2
-rw-r--r--arch/s390/include/asm/hardirq.h6
-rw-r--r--arch/s390/include/asm/hugetlb.h10
-rw-r--r--arch/s390/include/asm/io.h15
-rw-r--r--arch/s390/include/asm/irqflags.h17
-rw-r--r--arch/s390/include/asm/kmsan.h59
-rw-r--r--arch/s390/include/asm/kvm_host.h10
-rw-r--r--arch/s390/include/asm/lowcore.h35
-rw-r--r--arch/s390/include/asm/mmu.h5
-rw-r--r--arch/s390/include/asm/mmu_context.h9
-rw-r--r--arch/s390/include/asm/nospec-branch.h29
-rw-r--r--arch/s390/include/asm/nospec-insn.h13
-rw-r--r--arch/s390/include/asm/os_info.h29
-rw-r--r--arch/s390/include/asm/page.h57
-rw-r--r--arch/s390/include/asm/pai.h17
-rw-r--r--arch/s390/include/asm/percpu.h2
-rw-r--r--arch/s390/include/asm/pgtable.h84
-rw-r--r--arch/s390/include/asm/physmem_info.h4
-rw-r--r--arch/s390/include/asm/preempt.h30
-rw-r--r--arch/s390/include/asm/processor.h47
-rw-r--r--arch/s390/include/asm/runtime-const.h77
-rw-r--r--arch/s390/include/asm/sclp.h1
-rw-r--r--arch/s390/include/asm/setup.h50
-rw-r--r--arch/s390/include/asm/smp.h5
-rw-r--r--arch/s390/include/asm/softirq_stack.h2
-rw-r--r--arch/s390/include/asm/spinlock.h4
-rw-r--r--arch/s390/include/asm/stacktrace.h13
-rw-r--r--arch/s390/include/asm/string.h20
-rw-r--r--arch/s390/include/asm/thread_info.h3
-rw-r--r--arch/s390/include/asm/timex.h10
-rw-r--r--arch/s390/include/asm/uaccess.h121
-rw-r--r--arch/s390/include/asm/unistd.h1
-rw-r--r--arch/s390/include/asm/uv.h38
-rw-r--r--arch/s390/include/asm/vdso/gettimeofday.h7
-rw-r--r--arch/s390/include/asm/vtime.h18
-rw-r--r--arch/s390/kernel/Makefile6
-rw-r--r--arch/s390/kernel/abs_lowcore.c1
-rw-r--r--arch/s390/kernel/alternative.c82
-rw-r--r--arch/s390/kernel/alternative.h0
-rw-r--r--arch/s390/kernel/asm-offsets.c15
-rw-r--r--arch/s390/kernel/cert_store.c1
-rw-r--r--arch/s390/kernel/crash_dump.c71
-rw-r--r--arch/s390/kernel/debug.c2
-rw-r--r--arch/s390/kernel/diag.c22
-rw-r--r--arch/s390/kernel/dumpstack.c8
-rw-r--r--arch/s390/kernel/early.c45
-rw-r--r--arch/s390/kernel/entry.S282
-rw-r--r--arch/s390/kernel/ftrace.c9
-rw-r--r--arch/s390/kernel/head64.S8
-rw-r--r--arch/s390/kernel/idle.c21
-rw-r--r--arch/s390/kernel/ipl.c328
-rw-r--r--arch/s390/kernel/irq.c20
-rw-r--r--arch/s390/kernel/kprobes.c71
-rw-r--r--arch/s390/kernel/kprobes.h9
-rw-r--r--arch/s390/kernel/kprobes_insn_page.S22
-rw-r--r--arch/s390/kernel/machine_kexec.c6
-rw-r--r--arch/s390/kernel/module.c42
-rw-r--r--arch/s390/kernel/nmi.c32
-rw-r--r--arch/s390/kernel/nospec-branch.c20
-rw-r--r--arch/s390/kernel/nospec-sysfs.c2
-rw-r--r--arch/s390/kernel/os_info.c29
-rw-r--r--arch/s390/kernel/perf_cpum_cf.c16
-rw-r--r--arch/s390/kernel/perf_cpum_cf_events.c11
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c2
-rw-r--r--arch/s390/kernel/perf_event.c34
-rw-r--r--arch/s390/kernel/perf_pai_crypto.c183
-rw-r--r--arch/s390/kernel/perf_pai_ext.c146
-rw-r--r--arch/s390/kernel/process.c11
-rw-r--r--arch/s390/kernel/processor.c20
-rw-r--r--arch/s390/kernel/reipl.S26
-rw-r--r--arch/s390/kernel/setup.c35
-rw-r--r--arch/s390/kernel/smp.c221
-rw-r--r--arch/s390/kernel/stacktrace.c108
-rw-r--r--arch/s390/kernel/sthyi.c95
-rw-r--r--arch/s390/kernel/syscall.c31
-rw-r--r--arch/s390/kernel/syscalls/Makefile4
-rw-r--r--arch/s390/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/s390/kernel/time.c22
-rw-r--r--arch/s390/kernel/topology.c10
-rw-r--r--arch/s390/kernel/traps.c34
-rw-r--r--arch/s390/kernel/unwind_bc.c4
-rw-r--r--arch/s390/kernel/uv.c279
-rw-r--r--arch/s390/kernel/vdso.c13
-rw-r--r--arch/s390/kernel/vdso32/Makefile16
-rw-r--r--arch/s390/kernel/vdso64/Makefile16
-rw-r--r--arch/s390/kernel/vdso64/vdso_user_wrapper.S19
-rw-r--r--arch/s390/kernel/vmcore_info.c2
-rw-r--r--arch/s390/kernel/vmlinux.lds.S43
-rw-r--r--arch/s390/kernel/vtime.c90
-rw-r--r--arch/s390/kvm/gaccess.c163
-rw-r--r--arch/s390/kvm/kvm-s390.c26
-rw-r--r--arch/s390/kvm/kvm-s390.h15
-rw-r--r--arch/s390/kvm/priv.c32
-rw-r--r--arch/s390/kvm/vsie.c29
-rw-r--r--arch/s390/lib/Makefile2
-rw-r--r--arch/s390/lib/expoline.S (renamed from arch/s390/lib/expoline/expoline.S)0
-rw-r--r--arch/s390/lib/spinlock.c8
-rw-r--r--arch/s390/lib/test_kprobes.c1
-rw-r--r--arch/s390/lib/test_modules.c1
-rw-r--r--arch/s390/lib/test_unwind.c3
-rw-r--r--arch/s390/lib/uaccess.c4
-rw-r--r--arch/s390/mm/cmm.c7
-rw-r--r--arch/s390/mm/dump_pagetables.c32
-rw-r--r--arch/s390/mm/fault.c36
-rw-r--r--arch/s390/mm/gmap.c181
-rw-r--r--arch/s390/mm/hugetlbpage.c31
-rw-r--r--arch/s390/mm/init.c33
-rw-r--r--arch/s390/mm/maccess.c4
-rw-r--r--arch/s390/mm/mmap.c9
-rw-r--r--arch/s390/mm/pageattr.c2
-rw-r--r--arch/s390/mm/pgalloc.c8
-rw-r--r--arch/s390/mm/vmem.c5
-rw-r--r--arch/s390/net/bpf_jit_comp.c503
-rw-r--r--arch/s390/pci/pci.c8
-rw-r--r--arch/s390/pci/pci_irq.c112
-rw-r--r--arch/s390/pci/pci_mmio.c4
-rw-r--r--arch/s390/pci/pci_sysfs.c4
-rw-r--r--arch/s390/purgatory/Makefile8
-rw-r--r--arch/s390/tools/relocs.c2
-rw-r--r--arch/sh/Kconfig13
-rw-r--r--arch/sh/boards/board-sh7757lcr.c4
-rw-r--r--arch/sh/boards/board-sh7785lcr.c2
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c2
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c3
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c2
-rw-r--r--arch/sh/boards/mach-highlander/pinmux-r7785rp.c1
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c2
-rw-r--r--arch/sh/boards/mach-migor/setup.c2
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c2
-rw-r--r--arch/sh/boards/mach-sh03/rtc.c2
-rw-r--r--arch/sh/boards/of-generic.c2
-rw-r--r--arch/sh/boot/compressed/Makefile5
-rw-r--r--arch/sh/boot/compressed/cache.c13
-rw-r--r--arch/sh/boot/compressed/misc.c9
-rw-r--r--arch/sh/boot/compressed/misc.h9
-rw-r--r--arch/sh/boot/dts/j2_mimas_v2.dts2
-rw-r--r--arch/sh/configs/apsh4a3a_defconfig1
-rw-r--r--arch/sh/configs/apsh4ad0a_defconfig3
-rw-r--r--arch/sh/configs/edosk7705_defconfig3
-rw-r--r--arch/sh/configs/hp6xx_defconfig1
-rw-r--r--arch/sh/configs/landisk_defconfig1
-rw-r--r--arch/sh/configs/magicpanelr2_defconfig1
-rw-r--r--arch/sh/configs/rsk7264_defconfig1
-rw-r--r--arch/sh/configs/rsk7269_defconfig1
-rw-r--r--arch/sh/configs/sdk7786_defconfig2
-rw-r--r--arch/sh/configs/se7619_defconfig3
-rw-r--r--arch/sh/configs/se7705_defconfig1
-rw-r--r--arch/sh/configs/se7712_defconfig2
-rw-r--r--arch/sh/configs/se7721_defconfig2
-rw-r--r--arch/sh/configs/se7722_defconfig1
-rw-r--r--arch/sh/configs/se7750_defconfig1
-rw-r--r--arch/sh/configs/secureedge5410_defconfig1
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig1
-rw-r--r--arch/sh/configs/sh7724_generic_defconfig1
-rw-r--r--arch/sh/configs/sh7770_generic_defconfig1
-rw-r--r--arch/sh/configs/sh7785lcr_32bit_defconfig1
-rw-r--r--arch/sh/configs/sh7785lcr_defconfig1
-rw-r--r--arch/sh/configs/shmin_defconfig2
-rw-r--r--arch/sh/configs/shx3_defconfig2
-rw-r--r--arch/sh/configs/urquell_defconfig1
-rw-r--r--arch/sh/drivers/dma/dma-api.c143
-rw-r--r--arch/sh/drivers/push-switch.c7
-rw-r--r--arch/sh/include/asm/cacheflush.h12
-rw-r--r--arch/sh/include/asm/dma.h7
-rw-r--r--arch/sh/include/asm/fb.h7
-rw-r--r--arch/sh/include/asm/fpu.h3
-rw-r--r--arch/sh/include/asm/ftrace.h10
-rw-r--r--arch/sh/include/asm/hugetlb.h6
-rw-r--r--arch/sh/include/asm/hw_breakpoint.h2
-rw-r--r--arch/sh/include/asm/setup.h1
-rw-r--r--arch/sh/include/asm/syscalls.h1
-rw-r--r--arch/sh/include/asm/tlb.h4
-rw-r--r--arch/sh/include/asm/unistd.h2
-rw-r--r--arch/sh/kernel/cpu/sh2a/opcode_helper.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c3
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c1
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c3
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c14
-rw-r--r--arch/sh/kernel/dwarf.c2
-rw-r--r--arch/sh/kernel/kprobes.c13
-rw-r--r--arch/sh/kernel/return_address.c2
-rw-r--r--arch/sh/kernel/smp.c6
-rw-r--r--arch/sh/kernel/sys_sh32.c11
-rw-r--r--arch/sh/kernel/syscalls/syscall.tbl4
-rw-r--r--arch/sh/kernel/traps.c10
-rw-r--r--arch/sh/kernel/traps_32.c5
-rw-r--r--arch/sh/kernel/vsyscall/Makefile4
-rw-r--r--arch/sh/lib/checksum.S67
-rw-r--r--arch/sh/math-emu/math.c2
-rw-r--r--arch/sh/mm/Kconfig4
-rw-r--r--arch/sh/mm/cache-sh4.c7
-rw-r--r--arch/sh/mm/cache-shx3.c1
-rw-r--r--arch/sh/mm/cache.c16
-rw-r--r--arch/sh/mm/hugetlbpage.c10
-rw-r--r--arch/sh/mm/init.c28
-rw-r--r--arch/sh/mm/mmap.c5
-rw-r--r--arch/sh/mm/nommu.c2
-rw-r--r--arch/sh/mm/pgtable.c4
-rw-r--r--arch/sh/mm/tlbex_32.c1
-rw-r--r--arch/sparc/Makefile4
-rwxr-xr-xarch/sparc/boot/install.sh2
-rw-r--r--arch/sparc/include/asm/asm-prototypes.h17
-rw-r--r--arch/sparc/include/asm/cmpxchg_32.h20
-rw-r--r--arch/sparc/include/asm/floppy_64.h9
-rw-r--r--arch/sparc/include/asm/oplib_64.h1
-rw-r--r--arch/sparc/include/asm/parport_64.h6
-rw-r--r--arch/sparc/include/asm/pgtable_32.h2
-rw-r--r--arch/sparc/include/asm/pgtable_64.h3
-rw-r--r--arch/sparc/include/asm/smp_64.h2
-rw-r--r--arch/sparc/include/asm/uaccess_32.h6
-rw-r--r--arch/sparc/include/asm/unistd.h2
-rw-r--r--arch/sparc/include/asm/video.h (renamed from arch/sparc/include/asm/fb.h)15
-rw-r--r--arch/sparc/include/asm/vio.h6
-rw-r--r--arch/sparc/include/uapi/asm/termbits.h10
-rw-r--r--arch/sparc/include/uapi/asm/termios.h9
-rw-r--r--arch/sparc/kernel/adi_64.c14
-rw-r--r--arch/sparc/kernel/chmc.c5
-rw-r--r--arch/sparc/kernel/head_32.S15
-rw-r--r--arch/sparc/kernel/irq_64.c10
-rw-r--r--arch/sparc/kernel/kernel.h4
-rw-r--r--arch/sparc/kernel/leon_kernel.c7
-rw-r--r--arch/sparc/kernel/module.c30
-rw-r--r--arch/sparc/kernel/of_device_64.c5
-rw-r--r--arch/sparc/kernel/pci_msi.c5
-rw-r--r--arch/sparc/kernel/pci_sun4v.c6
-rw-r--r--arch/sparc/kernel/prom_64.c4
-rw-r--r--arch/sparc/kernel/setup_64.c3
-rw-r--r--arch/sparc/kernel/smp_64.c14
-rw-r--r--arch/sparc/kernel/sys32.S221
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c3
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c20
-rw-r--r--arch/sparc/kernel/syscalls/syscall.tbl9
-rw-r--r--arch/sparc/kernel/time_64.c1
-rw-r--r--arch/sparc/kernel/traps_64.c10
-rw-r--r--arch/sparc/kernel/uprobes.c2
-rw-r--r--arch/sparc/kernel/vio.c4
-rw-r--r--arch/sparc/lib/atomic32.c45
-rw-r--r--arch/sparc/mm/Makefile2
-rw-r--r--arch/sparc/mm/execmem.c21
-rw-r--r--arch/sparc/mm/hugetlbpage.c21
-rw-r--r--arch/sparc/mm/init_64.c7
-rw-r--r--arch/sparc/mm/srmmu.c40
-rw-r--r--arch/sparc/mm/tlb.c7
-rw-r--r--arch/sparc/net/bpf_jit_comp_32.c8
-rw-r--r--arch/sparc/net/bpf_jit_comp_64.c6
-rw-r--r--arch/sparc/power/hibernate.c1
-rw-r--r--arch/sparc/prom/init_64.c3
-rw-r--r--arch/sparc/prom/misc_64.c2
-rw-r--r--arch/sparc/prom/p1275.c2
-rw-r--r--arch/sparc/prom/tree_64.c2
-rw-r--r--arch/sparc/vdso/Makefile4
-rw-r--r--arch/sparc/vdso/vma.c5
-rw-r--r--arch/sparc/video/Makefile2
-rw-r--r--arch/sparc/video/fbdev.c26
-rw-r--r--arch/sparc/video/video-common.c25
-rw-r--r--arch/um/Kconfig8
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/drivers/Kconfig20
-rw-r--r--arch/um/drivers/Makefile10
-rw-r--r--arch/um/drivers/chan.h3
-rw-r--r--arch/um/drivers/chan_kern.c81
-rw-r--r--arch/um/drivers/chan_user.c20
-rw-r--r--arch/um/drivers/harddog_kern.c1
-rw-r--r--arch/um/drivers/line.c16
-rw-r--r--arch/um/drivers/pcap_kern.c113
-rw-r--r--arch/um/drivers/pcap_user.c137
-rw-r--r--arch/um/drivers/pcap_user.h21
-rw-r--r--arch/um/drivers/port_kern.c14
-rw-r--r--arch/um/drivers/rtc_kern.c5
-rw-r--r--arch/um/drivers/slirp_user.c3
-rw-r--r--arch/um/drivers/ubd_kern.c60
-rw-r--r--arch/um/drivers/ubd_user.c2
-rw-r--r--arch/um/drivers/vector_kern.c25
-rw-r--r--arch/um/drivers/vector_kern.h1
-rw-r--r--arch/um/drivers/virt-pci.c25
-rw-r--r--arch/um/drivers/virtio_uml.c17
-rw-r--r--arch/um/drivers/xterm.c2
-rw-r--r--arch/um/drivers/xterm_kern.c13
-rw-r--r--arch/um/include/asm/Kbuild4
-rw-r--r--arch/um/include/asm/bpf_perf_event.h9
-rw-r--r--arch/um/include/asm/cpufeature.h3
-rw-r--r--arch/um/include/asm/kasan.h1
-rw-r--r--arch/um/include/asm/mmu.h12
-rw-r--r--arch/um/include/asm/mmu_context.h2
-rw-r--r--arch/um/include/asm/pgtable.h32
-rw-r--r--arch/um/include/asm/processor-generic.h1
-rw-r--r--arch/um/include/asm/ptrace-generic.h3
-rw-r--r--arch/um/include/asm/tlbflush.h46
-rw-r--r--arch/um/include/shared/as-layout.h3
-rw-r--r--arch/um/include/shared/common-offsets.h5
-rw-r--r--arch/um/include/shared/kern_util.h4
-rw-r--r--arch/um/include/shared/os.h33
-rw-r--r--arch/um/include/shared/skas/mm_id.h4
-rw-r--r--arch/um/include/shared/skas/skas.h2
-rw-r--r--arch/um/include/shared/skas/stub-data.h36
-rw-r--r--arch/um/include/shared/timetravel.h9
-rw-r--r--arch/um/include/shared/um_malloc.h5
-rw-r--r--arch/um/include/shared/user.h8
-rw-r--r--arch/um/kernel/Makefile2
-rw-r--r--arch/um/kernel/exec.c9
-rw-r--r--arch/um/kernel/irq.c80
-rw-r--r--arch/um/kernel/kmsg_dump.c2
-rw-r--r--arch/um/kernel/ksyms.c2
-rw-r--r--arch/um/kernel/mem.c3
-rw-r--r--arch/um/kernel/physmem.c3
-rw-r--r--arch/um/kernel/process.c115
-rw-r--r--arch/um/kernel/ptrace.c3
-rw-r--r--arch/um/kernel/reboot.c16
-rw-r--r--arch/um/kernel/skas/Makefile9
-rw-r--r--arch/um/kernel/skas/clone.c48
-rw-r--r--arch/um/kernel/skas/mmu.c55
-rw-r--r--arch/um/kernel/skas/process.c23
-rw-r--r--arch/um/kernel/skas/stub.c69
-rw-r--r--arch/um/kernel/time.c194
-rw-r--r--arch/um/kernel/tlb.c552
-rw-r--r--arch/um/kernel/trap.c15
-rw-r--r--arch/um/kernel/um_arch.c4
-rw-r--r--arch/um/kernel/um_arch.h2
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c2
-rw-r--r--arch/um/os-Linux/elf_aux.c1
-rw-r--r--arch/um/os-Linux/file.c94
-rw-r--r--arch/um/os-Linux/internal.h20
-rw-r--r--arch/um/os-Linux/main.c8
-rw-r--r--arch/um/os-Linux/mem.c2
-rw-r--r--arch/um/os-Linux/signal.c122
-rw-r--r--arch/um/os-Linux/skas/mem.c246
-rw-r--r--arch/um/os-Linux/skas/process.c125
-rw-r--r--arch/um/os-Linux/start_up.c5
-rw-r--r--arch/x86/Kconfig96
-rw-r--r--arch/x86/Kconfig.assembler12
-rw-r--r--arch/x86/Kconfig.debug5
-rw-r--r--arch/x86/Makefile22
-rw-r--r--arch/x86/Makefile.um1
-rw-r--r--arch/x86/boot/Makefile18
-rw-r--r--arch/x86/boot/compressed/Makefile15
-rw-r--r--arch/x86/boot/compressed/head_64.S5
-rw-r--r--arch/x86/boot/compressed/kaslr.c43
-rw-r--r--arch/x86/boot/compressed/misc.c5
-rw-r--r--arch/x86/boot/compressed/sev.c263
-rw-r--r--arch/x86/boot/cpucheck.c2
-rwxr-xr-xarch/x86/boot/install.sh2
-rw-r--r--arch/x86/boot/main.c42
-rw-r--r--arch/x86/boot/printf.c3
-rw-r--r--arch/x86/coco/Makefile1
-rw-r--r--arch/x86/coco/core.c1
-rw-r--r--arch/x86/coco/sev/Makefile15
-rw-r--r--arch/x86/coco/sev/core.c (renamed from arch/x86/kernel/sev.c)463
-rw-r--r--arch/x86/coco/sev/shared.c (renamed from arch/x86/kernel/sev-shared.c)460
-rw-r--r--arch/x86/coco/tdx/tdx.c121
-rw-r--r--arch/x86/configs/hardening.config3
-rw-r--r--arch/x86/crypto/Kconfig1
-rw-r--r--arch/x86/crypto/Makefile7
-rw-r--r--arch/x86/crypto/aes-gcm-aesni-x86_64.S1128
-rw-r--r--arch/x86/crypto/aes-gcm-avx10-x86_64.S1222
-rw-r--r--arch/x86/crypto/aes-xts-avx-x86_64.S845
-rw-r--r--arch/x86/crypto/aesni-intel_asm.S1970
-rw-r--r--arch/x86/crypto/aesni-intel_avx-x86_64.S2804
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c1587
-rw-r--r--arch/x86/crypto/crc32-pclmul_glue.c1
-rw-r--r--arch/x86/crypto/curve25519-x86_64.c1
-rw-r--r--arch/x86/crypto/nh-avx2-x86_64.S1
-rw-r--r--arch/x86/crypto/poly1305_glue.c4
-rw-r--r--arch/x86/crypto/sha256-avx2-asm.S1
-rw-r--r--arch/x86/crypto/sha256_ni_asm.S253
-rw-r--r--arch/x86/crypto/sha512-avx2-asm.S1
-rw-r--r--arch/x86/crypto/twofish_glue_3way.c9
-rw-r--r--arch/x86/entry/Makefile2
-rw-r--r--arch/x86/entry/entry_64_compat.S15
-rw-r--r--arch/x86/entry/entry_fred.c2
-rw-r--r--arch/x86/entry/syscall_32.c10
-rw-r--r--arch/x86/entry/syscall_64.c9
-rw-r--r--arch/x86/entry/syscall_x32.c7
-rw-r--r--arch/x86/entry/syscalls/syscall_32.tbl10
-rw-r--r--arch/x86/entry/syscalls/syscall_64.tbl11
-rw-r--r--arch/x86/entry/thunk.S (renamed from arch/x86/entry/thunk_64.S)0
-rw-r--r--arch/x86/entry/thunk_32.S18
-rw-r--r--arch/x86/entry/vdso/Makefile31
-rw-r--r--arch/x86/entry/vdso/vdso.lds.S2
-rw-r--r--arch/x86/entry/vdso/vgetrandom-chacha.S178
-rw-r--r--arch/x86/entry/vdso/vgetrandom.c17
-rw-r--r--arch/x86/events/amd/core.c65
-rw-r--r--arch/x86/events/amd/lbr.c13
-rw-r--r--arch/x86/events/amd/uncore.c36
-rw-r--r--arch/x86/events/core.c113
-rw-r--r--arch/x86/events/intel/core.c651
-rw-r--r--arch/x86/events/intel/cstate.c190
-rw-r--r--arch/x86/events/intel/ds.c180
-rw-r--r--arch/x86/events/intel/knc.c2
-rw-r--r--arch/x86/events/intel/lbr.c3
-rw-r--r--arch/x86/events/intel/p4.c10
-rw-r--r--arch/x86/events/intel/p6.c2
-rw-r--r--arch/x86/events/intel/pt.c16
-rw-r--r--arch/x86/events/intel/pt.h4
-rw-r--r--arch/x86/events/intel/uncore.c198
-rw-r--r--arch/x86/events/intel/uncore.h8
-rw-r--r--arch/x86/events/intel/uncore_discovery.c306
-rw-r--r--arch/x86/events/intel/uncore_discovery.h22
-rw-r--r--arch/x86/events/intel/uncore_nhmex.c3
-rw-r--r--arch/x86/events/intel/uncore_snbep.c139
-rw-r--r--arch/x86/events/msr.c132
-rw-r--r--arch/x86/events/perf_event.h111
-rw-r--r--arch/x86/events/rapl.c106
-rw-r--r--arch/x86/events/zhaoxin/core.c12
-rw-r--r--arch/x86/hyperv/hv_vtl.c1
-rw-r--r--arch/x86/hyperv/ivm.c22
-rw-r--r--arch/x86/include/asm/acpi.h9
-rw-r--r--arch/x86/include/asm/alternative.h255
-rw-r--r--arch/x86/include/asm/amd_nb.h4
-rw-r--r--arch/x86/include/asm/apic.h8
-rw-r--r--arch/x86/include/asm/asm.h3
-rw-r--r--arch/x86/include/asm/atomic.h12
-rw-r--r--arch/x86/include/asm/atomic64_32.h81
-rw-r--r--arch/x86/include/asm/atomic64_64.h12
-rw-r--r--arch/x86/include/asm/barrier.h24
-rw-r--r--arch/x86/include/asm/bitops.h10
-rw-r--r--arch/x86/include/asm/boot.h5
-rw-r--r--arch/x86/include/asm/cfi.h2
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h203
-rw-r--r--arch/x86/include/asm/cmpxchg_64.h8
-rw-r--r--arch/x86/include/asm/cpu_device_id.h112
-rw-r--r--arch/x86/include/asm/cpufeature.h16
-rw-r--r--arch/x86/include/asm/cpufeatures.h803
-rw-r--r--arch/x86/include/asm/efi.h23
-rw-r--r--arch/x86/include/asm/entry-common.h15
-rw-r--r--arch/x86/include/asm/extable_fixup_types.h2
-rw-r--r--arch/x86/include/asm/fb.h19
-rw-r--r--arch/x86/include/asm/fpu.h13
-rw-r--r--arch/x86/include/asm/fpu/api.h3
-rw-r--r--arch/x86/include/asm/fpu/types.h6
-rw-r--r--arch/x86/include/asm/ftrace.h2
-rw-r--r--arch/x86/include/asm/hardirq.h6
-rw-r--r--arch/x86/include/asm/ia32.h11
-rw-r--r--arch/x86/include/asm/ia32_unistd.h12
-rw-r--r--arch/x86/include/asm/idtentry.h6
-rw-r--r--arch/x86/include/asm/inat.h17
-rw-r--r--arch/x86/include/asm/init.h3
-rw-r--r--arch/x86/include/asm/insn.h32
-rw-r--r--arch/x86/include/asm/intel-family.h84
-rw-r--r--arch/x86/include/asm/intel_ds.h1
-rw-r--r--arch/x86/include/asm/intel_pconfig.h65
-rw-r--r--arch/x86/include/asm/io.h18
-rw-r--r--arch/x86/include/asm/irq_remapping.h7
-rw-r--r--arch/x86/include/asm/irq_stack.h2
-rw-r--r--arch/x86/include/asm/irq_vectors.h8
-rw-r--r--arch/x86/include/asm/irqflags.h20
-rw-r--r--arch/x86/include/asm/kexec.h13
-rw-r--r--arch/x86/include/asm/kvm-x86-ops.h9
-rw-r--r--arch/x86/include/asm/kvm-x86-pmu-ops.h3
-rw-r--r--arch/x86/include/asm/kvm_host.h154
-rw-r--r--arch/x86/include/asm/mce.h5
-rw-r--r--arch/x86/include/asm/mpspec.h6
-rw-r--r--arch/x86/include/asm/msr-index.h20
-rw-r--r--arch/x86/include/asm/page_64.h2
-rw-r--r--arch/x86/include/asm/page_types.h8
-rw-r--r--arch/x86/include/asm/percpu.h616
-rw-r--r--arch/x86/include/asm/perf_event.h8
-rw-r--r--arch/x86/include/asm/pgtable.h25
-rw-r--r--arch/x86/include/asm/pgtable_64.h1
-rw-r--r--arch/x86/include/asm/pgtable_types.h3
-rw-r--r--arch/x86/include/asm/posted_intr.h118
-rw-r--r--arch/x86/include/asm/processor.h44
-rw-r--r--arch/x86/include/asm/prom.h9
-rw-r--r--arch/x86/include/asm/qspinlock.h13
-rw-r--r--arch/x86/include/asm/qspinlock_paravirt.h7
-rw-r--r--arch/x86/include/asm/runtime-const.h61
-rw-r--r--arch/x86/include/asm/seccomp.h2
-rw-r--r--arch/x86/include/asm/set_memory.h3
-rw-r--r--arch/x86/include/asm/setup.h8
-rw-r--r--arch/x86/include/asm/sev-common.h51
-rw-r--r--arch/x86/include/asm/sev.h188
-rw-r--r--arch/x86/include/asm/shstk.h4
-rw-r--r--arch/x86/include/asm/smp.h1
-rw-r--r--arch/x86/include/asm/sparsemem.h2
-rw-r--r--arch/x86/include/asm/special_insns.h8
-rw-r--r--arch/x86/include/asm/string_64.h45
-rw-r--r--arch/x86/include/asm/svm.h9
-rw-r--r--arch/x86/include/asm/text-patching.h2
-rw-r--r--arch/x86/include/asm/tsc.h3
-rw-r--r--arch/x86/include/asm/uaccess.h6
-rw-r--r--arch/x86/include/asm/unistd.h1
-rw-r--r--arch/x86/include/asm/vdso/getrandom.h55
-rw-r--r--arch/x86/include/asm/vdso/gettimeofday.h43
-rw-r--r--arch/x86/include/asm/vdso/vsyscall.h3
-rw-r--r--arch/x86/include/asm/vgtod.h5
-rw-r--r--arch/x86/include/asm/video.h21
-rw-r--r--arch/x86/include/asm/vm86.h2
-rw-r--r--arch/x86/include/asm/vmware.h336
-rw-r--r--arch/x86/include/asm/vmx.h13
-rw-r--r--arch/x86/include/asm/vmxfeatures.h110
-rw-r--r--arch/x86/include/asm/vvar.h16
-rw-r--r--arch/x86/include/asm/word-at-a-time.h57
-rw-r--r--arch/x86/include/asm/x86_init.h14
-rw-r--r--arch/x86/include/uapi/asm/kvm.h71
-rw-r--r--arch/x86/include/uapi/asm/svm.h1
-rw-r--r--arch/x86/kernel/Makefile10
-rw-r--r--arch/x86/kernel/acpi/Makefile1
-rw-r--r--arch/x86/kernel/acpi/boot.c86
-rw-r--r--arch/x86/kernel/acpi/madt_playdead.S28
-rw-r--r--arch/x86/kernel/acpi/madt_wakeup.c292
-rw-r--r--arch/x86/kernel/alternative.c161
-rw-r--r--arch/x86/kernel/amd_gart_64.c2
-rw-r--r--arch/x86/kernel/amd_nb.c54
-rw-r--r--arch/x86/kernel/apic/apic.c46
-rw-r--r--arch/x86/kernel/apic/msi.c5
-rw-r--r--arch/x86/kernel/apic/vector.c14
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c7
-rw-r--r--arch/x86/kernel/callthunks.c9
-rw-r--r--arch/x86/kernel/cpu/Makefile4
-rw-r--r--arch/x86/kernel/cpu/amd.c23
-rw-r--r--arch/x86/kernel/cpu/aperfmperf.c18
-rw-r--r--arch/x86/kernel/cpu/bugs.c46
-rw-r--r--arch/x86/kernel/cpu/common.c181
-rw-r--r--arch/x86/kernel/cpu/cpu.h2
-rw-r--r--arch/x86/kernel/cpu/cpuid-deps.c3
-rw-r--r--arch/x86/kernel/cpu/intel.c212
-rw-r--r--arch/x86/kernel/cpu/intel_epb.c12
-rw-r--r--arch/x86/kernel/cpu/intel_pconfig.c84
-rw-r--r--arch/x86/kernel/cpu/match.c9
-rw-r--r--arch/x86/kernel/cpu/mce/core.c31
-rw-r--r--arch/x86/kernel/cpu/mce/genpool.c40
-rw-r--r--arch/x86/kernel/cpu/mce/inject.c9
-rw-r--r--arch/x86/kernel/cpu/mce/intel.c21
-rw-r--r--arch/x86/kernel/cpu/mce/severity.c27
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c4
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c5
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c5
-rw-r--r--arch/x86/kernel/cpu/mkcapflags.sh3
-rw-r--r--arch/x86/kernel/cpu/resctrl/core.c371
-rw-r--r--arch/x86/kernel/cpu/resctrl/ctrlmondata.c127
-rw-r--r--arch/x86/kernel/cpu/resctrl/internal.h111
-rw-r--r--arch/x86/kernel/cpu/resctrl/monitor.c262
-rw-r--r--arch/x86/kernel/cpu/resctrl/pseudo_lock.c66
-rw-r--r--arch/x86/kernel/cpu/resctrl/rdtgroup.c298
-rw-r--r--arch/x86/kernel/cpu/resctrl/trace.h (renamed from arch/x86/kernel/cpu/resctrl/pseudo_lock_event.h)24
-rw-r--r--arch/x86/kernel/cpu/scattered.c1
-rw-r--r--arch/x86/kernel/cpu/sgx/driver.c2
-rw-r--r--arch/x86/kernel/cpu/sgx/main.c1
-rw-r--r--arch/x86/kernel/cpu/topology.c53
-rw-r--r--arch/x86/kernel/cpu/topology_amd.c37
-rw-r--r--arch/x86/kernel/cpu/topology_ext.c15
-rw-r--r--arch/x86/kernel/cpu/vmware.c225
-rw-r--r--arch/x86/kernel/crash.c44
-rw-r--r--arch/x86/kernel/devicetree.c26
-rw-r--r--arch/x86/kernel/dumpstack.c4
-rw-r--r--arch/x86/kernel/e820.c9
-rw-r--r--arch/x86/kernel/early-quirks.c85
-rw-r--r--arch/x86/kernel/fpu/core.c4
-rw-r--r--arch/x86/kernel/fpu/xstate.c5
-rw-r--r--arch/x86/kernel/fpu/xstate.h16
-rw-r--r--arch/x86/kernel/ftrace.c16
-rw-r--r--arch/x86/kernel/head_32.S13
-rw-r--r--arch/x86/kernel/head_64.S4
-rw-r--r--arch/x86/kernel/idt.c3
-rw-r--r--arch/x86/kernel/irq.c172
-rw-r--r--arch/x86/kernel/irq_64.c1
-rw-r--r--arch/x86/kernel/itmt.c2
-rw-r--r--arch/x86/kernel/kprobes/core.c4
-rw-r--r--arch/x86/kernel/kprobes/ftrace.c3
-rw-r--r--arch/x86/kernel/kvm.c2
-rw-r--r--arch/x86/kernel/machine_kexec_64.c11
-rw-r--r--arch/x86/kernel/module.c51
-rw-r--r--arch/x86/kernel/process.c7
-rw-r--r--arch/x86/kernel/reboot.c18
-rw-r--r--arch/x86/kernel/relocate_kernel_64.S27
-rw-r--r--arch/x86/kernel/rtc.c1
-rw-r--r--arch/x86/kernel/setup.c45
-rw-r--r--arch/x86/kernel/shstk.c20
-rw-r--r--arch/x86/kernel/signal_32.c2
-rw-r--r--arch/x86/kernel/signal_64.c6
-rw-r--r--arch/x86/kernel/smpboot.c28
-rw-r--r--arch/x86/kernel/sys_x86_64.c42
-rw-r--r--arch/x86/kernel/time.c20
-rw-r--r--arch/x86/kernel/topology.c43
-rw-r--r--arch/x86/kernel/tsc.c100
-rw-r--r--arch/x86/kernel/tsc_msr.c14
-rw-r--r--arch/x86/kernel/tsc_sync.c6
-rw-r--r--arch/x86/kernel/uprobes.c124
-rw-r--r--arch/x86/kernel/vmlinux.lds.S13
-rw-r--r--arch/x86/kernel/x86_init.c8
-rw-r--r--arch/x86/kvm/Kconfig22
-rw-r--r--arch/x86/kvm/Makefile9
-rw-r--r--arch/x86/kvm/cpuid.c57
-rw-r--r--arch/x86/kvm/cpuid.h18
-rw-r--r--arch/x86/kvm/emulate.c73
-rw-r--r--arch/x86/kvm/hyperv.c9
-rw-r--r--arch/x86/kvm/irq.c2
-rw-r--r--arch/x86/kvm/irq.h1
-rw-r--r--arch/x86/kvm/irq_comm.c7
-rw-r--r--arch/x86/kvm/kvm_cache_regs.h10
-rw-r--r--arch/x86/kvm/kvm_emulate.h2
-rw-r--r--arch/x86/kvm/lapic.c87
-rw-r--r--arch/x86/kvm/lapic.h7
-rw-r--r--arch/x86/kvm/mmu.h47
-rw-r--r--arch/x86/kvm/mmu/mmu.c531
-rw-r--r--arch/x86/kvm/mmu/mmu_internal.h52
-rw-r--r--arch/x86/kvm/mmu/mmutrace.h2
-rw-r--r--arch/x86/kvm/mmu/page_track.c2
-rw-r--r--arch/x86/kvm/mmu/paging_tmpl.h29
-rw-r--r--arch/x86/kvm/mmu/spte.c86
-rw-r--r--arch/x86/kvm/mmu/spte.h43
-rw-r--r--arch/x86/kvm/mmu/tdp_iter.h2
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.c261
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.h3
-rw-r--r--arch/x86/kvm/mtrr.c644
-rw-r--r--arch/x86/kvm/pmu.c73
-rw-r--r--arch/x86/kvm/pmu.h10
-rw-r--r--arch/x86/kvm/smm.c44
-rw-r--r--arch/x86/kvm/svm/nested.c2
-rw-r--r--arch/x86/kvm/svm/pmu.c11
-rw-r--r--arch/x86/kvm/svm/sev.c1922
-rw-r--r--arch/x86/kvm/svm/svm.c181
-rw-r--r--arch/x86/kvm/svm/svm.h124
-rw-r--r--arch/x86/kvm/trace.h61
-rw-r--r--arch/x86/kvm/vmx/main.c164
-rw-r--r--arch/x86/kvm/vmx/nested.c90
-rw-r--r--arch/x86/kvm/vmx/pmu_intel.c52
-rw-r--r--arch/x86/kvm/vmx/posted_intr.c4
-rw-r--r--arch/x86/kvm/vmx/posted_intr.h101
-rw-r--r--arch/x86/kvm/vmx/vmcs.h5
-rw-r--r--arch/x86/kvm/vmx/vmcs12.h14
-rw-r--r--arch/x86/kvm/vmx/vmx.c651
-rw-r--r--arch/x86/kvm/vmx/vmx.h11
-rw-r--r--arch/x86/kvm/vmx/x86_ops.h120
-rw-r--r--arch/x86/kvm/x86.c841
-rw-r--r--arch/x86/kvm/x86.h27
-rw-r--r--arch/x86/kvm/xen.c6
-rw-r--r--arch/x86/lib/Makefile1
-rw-r--r--arch/x86/lib/cmdline.c8
-rw-r--r--arch/x86/lib/copy_mc.c21
-rw-r--r--arch/x86/lib/getuser.S65
-rw-r--r--arch/x86/lib/insn.c29
-rw-r--r--arch/x86/lib/iomap_copy_64.S15
-rw-r--r--arch/x86/lib/iomem.c5
-rw-r--r--arch/x86/lib/x86-opcode-map.txt315
-rw-r--r--arch/x86/math-emu/fpu_etc.c9
-rw-r--r--arch/x86/math-emu/fpu_trig.c6
-rw-r--r--arch/x86/math-emu/reg_constant.c7
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/mm/extable.c9
-rw-r--r--arch/x86/mm/fault.c31
-rw-r--r--arch/x86/mm/hugetlbpage.c35
-rw-r--r--arch/x86/mm/ident_map.c73
-rw-r--r--arch/x86/mm/init.c92
-rw-r--r--arch/x86/mm/init_64.c30
-rw-r--r--arch/x86/mm/mem_encrypt_amd.c16
-rw-r--r--arch/x86/mm/mmap.c4
-rw-r--r--arch/x86/mm/numa.c10
-rw-r--r--arch/x86/mm/numa_32.c1
-rw-r--r--arch/x86/mm/pat/memtype.c26
-rw-r--r--arch/x86/mm/pat/set_memory.c139
-rw-r--r--arch/x86/mm/pgtable.c6
-rw-r--r--arch/x86/net/bpf_jit_comp.c117
-rw-r--r--arch/x86/net/bpf_jit_comp32.c3
-rw-r--r--arch/x86/pci/ce4100.c6
-rw-r--r--arch/x86/pci/intel_mid_pci.c8
-rw-r--r--arch/x86/pci/mmconfig-shared.c40
-rw-r--r--arch/x86/pci/olpc.c3
-rw-r--r--arch/x86/pci/xen.c4
-rw-r--r--arch/x86/platform/atom/punit_atom_debug.c11
-rw-r--r--arch/x86/platform/ce4100/ce4100.c1
-rw-r--r--arch/x86/platform/efi/Makefile1
-rw-r--r--arch/x86/platform/efi/efi.c2
-rw-r--r--arch/x86/platform/efi/fake_mem.c197
-rw-r--r--arch/x86/platform/efi/memmap.c13
-rw-r--r--arch/x86/platform/intel-mid/intel-mid.c6
-rw-r--r--arch/x86/platform/intel/iosf_mbi.c4
-rw-r--r--arch/x86/platform/iris/iris.c5
-rw-r--r--arch/x86/platform/olpc/olpc-xo1-pm.c7
-rw-r--r--arch/x86/platform/olpc/olpc-xo1-sci.c5
-rw-r--r--arch/x86/purgatory/Makefile12
-rw-r--r--arch/x86/realmode/rm/Makefile11
-rw-r--r--arch/x86/tools/gen-insn-attr-x86.awk15
-rw-r--r--arch/x86/tools/relocs.c371
-rw-r--r--arch/x86/um/Makefile5
-rw-r--r--arch/x86/um/asm/mm_context.h70
-rw-r--r--arch/x86/um/asm/ptrace.h6
-rw-r--r--arch/x86/um/bugs_32.c1
-rw-r--r--arch/x86/um/bugs_64.c1
-rw-r--r--arch/x86/um/elfcore.c1
-rw-r--r--arch/x86/um/fault.c1
-rw-r--r--arch/x86/um/ldt.c380
-rw-r--r--arch/x86/um/os-Linux/mcontext.c1
-rw-r--r--arch/x86/um/os-Linux/registers.c2
-rw-r--r--arch/x86/um/os-Linux/tls.c1
-rw-r--r--arch/x86/um/ptrace_32.c2
-rw-r--r--arch/x86/um/shared/sysdep/archsetjmp.h7
-rw-r--r--arch/x86/um/shared/sysdep/kernel-offsets.h3
-rw-r--r--arch/x86/um/shared/sysdep/stub.h2
-rw-r--r--arch/x86/um/shared/sysdep/stub_32.h45
-rw-r--r--arch/x86/um/shared/sysdep/stub_64.h41
-rw-r--r--arch/x86/um/signal.c14
-rw-r--r--arch/x86/um/stub_32.S56
-rw-r--r--arch/x86/um/stub_64.S50
-rw-r--r--arch/x86/um/sys_call_table_32.c10
-rw-r--r--arch/x86/um/sys_call_table_64.c11
-rw-r--r--arch/x86/um/tls_32.c20
-rw-r--r--arch/x86/um/user-offsets.c3
-rw-r--r--arch/x86/um/vdso/Makefile9
-rw-r--r--arch/x86/um/vdso/um_vdso.c10
-rw-r--r--arch/x86/video/Makefile3
-rw-r--r--arch/x86/video/video-common.c (renamed from arch/x86/video/fbdev.c)21
-rw-r--r--arch/x86/virt/svm/sev.c44
-rw-r--r--arch/x86/virt/vmx/tdx/tdx.c9
-rw-r--r--arch/x86/xen/apic.c2
-rw-r--r--arch/x86/xen/debugfs.c2
-rw-r--r--arch/x86/xen/debugfs.h7
-rw-r--r--arch/x86/xen/enlighten.c38
-rw-r--r--arch/x86/xen/enlighten_hvm.c2
-rw-r--r--arch/x86/xen/enlighten_pv.c4
-rw-r--r--arch/x86/xen/mmu.c3
-rw-r--r--arch/x86/xen/mmu.h28
-rw-r--r--arch/x86/xen/mmu_hvm.c2
-rw-r--r--arch/x86/xen/mmu_pv.c15
-rw-r--r--arch/x86/xen/multicalls.c128
-rw-r--r--arch/x86/xen/multicalls.h69
-rw-r--r--arch/x86/xen/p2m.c17
-rw-r--r--arch/x86/xen/pmu.c1
-rw-r--r--arch/x86/xen/pmu.h22
-rw-r--r--arch/x86/xen/setup.c6
-rw-r--r--arch/x86/xen/smp.c1
-rw-r--r--arch/x86/xen/smp.h51
-rw-r--r--arch/x86/xen/smp_hvm.c2
-rw-r--r--arch/x86/xen/smp_pv.c3
-rw-r--r--arch/x86/xen/spinlock.c20
-rw-r--r--arch/x86/xen/suspend.c2
-rw-r--r--arch/x86/xen/time.c2
-rw-r--r--arch/x86/xen/xen-head.S2
-rw-r--r--arch/x86/xen/xen-ops.h148
-rw-r--r--arch/xtensa/boot/dts/Makefile3
-rw-r--r--arch/xtensa/include/asm/current.h2
-rw-r--r--arch/xtensa/include/asm/pgtable.h6
-rw-r--r--arch/xtensa/include/asm/thread_info.h2
-rw-r--r--arch/xtensa/include/asm/unistd.h1
-rw-r--r--arch/xtensa/kernel/syscalls/syscall.tbl1
-rw-r--r--arch/xtensa/mm/cache.c6
-rw-r--r--arch/xtensa/mm/tlb.c17
-rw-r--r--arch/xtensa/platforms/iss/simdisk.c5
3144 files changed, 137640 insertions, 59719 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 30f7930275d8..975dd22a2dbd 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -60,10 +60,10 @@ config GENERIC_ENTRY
config KPROBES
bool "Kprobes"
- depends on MODULES
depends on HAVE_KPROBES
select KALLSYMS
- select TASKS_RCU if PREEMPTION
+ select EXECMEM
+ select NEED_TASKS_RCU
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
@@ -112,7 +112,7 @@ config STATIC_CALL_SELFTEST
config OPTPROBES
def_bool y
depends on KPROBES && HAVE_OPTPROBES
- select TASKS_RCU if PREEMPTION
+ select NEED_TASKS_RCU
config KPROBES_ON_FTRACE
def_bool y
@@ -510,6 +510,15 @@ config MMU_LAZY_TLB_SHOOTDOWN
config ARCH_HAVE_NMI_SAFE_CMPXCHG
bool
+config ARCH_HAVE_EXTRA_ELF_NOTES
+ bool
+ help
+ An architecture should select this in order to enable adding an
+ arch-specific ELF note section to core files. It must provide two
+ functions: elf_coredump_extra_notes_size() and
+ elf_coredump_extra_notes_write() which are invoked by the ELF core
+ dumper.
+
config ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
bool
@@ -968,6 +977,14 @@ config ARCH_WANTS_MODULES_DATA_IN_VMALLOC
For architectures like powerpc/32 which have constraints on module
allocation and need to allocate module data outside of module area.
+config ARCH_WANTS_EXECMEM_LATE
+ bool
+ help
+ For architectures that do not allocate executable memory early on
+ boot, but rather require its initialization late when there is
+ enough entropy for module space randomization, for instance
+ arm64.
+
config HAVE_IRQ_EXIT_ON_IRQ_STACK
bool
help
@@ -1577,6 +1594,12 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
address translations. Page table walkers that clear the accessed bit
may use this capability to reduce their search space.
+config ARCH_HAS_KERNEL_FPU_SUPPORT
+ bool
+ help
+ Architectures that select this option can run floating-point code in
+ the kernel, as described in Documentation/core-api/floating-point.rst.
+
source "kernel/gcov/Kconfig"
source "scripts/gcc-plugins/Kconfig"
@@ -1617,4 +1640,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT
# strict alignment always, even with -falign-functions.
def_bool CC_HAS_MIN_FUNCTION_ALIGNMENT || CC_IS_CLANG
+config ARCH_NEED_CMPXCHG_1_EMU
+ bool
+
endmenu
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 3afd042150f8..50ff06d5b799 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -10,7 +10,7 @@ config ALPHA
select ARCH_NO_SG_CHAIN
select ARCH_USE_CMPXCHG_LOCKREF
select DMA_OPS if PCI
- select FORCE_PCI if !ALPHA_JENSEN
+ select FORCE_PCI
select PCI_DOMAINS if PCI
select PCI_SYSCALL if PCI
select HAVE_ASM_MODVERSIONS
@@ -90,22 +90,11 @@ choice
<http://www.alphalinux.org/>. In summary:
Alcor/Alpha-XLT AS 600, AS 500, XL-300, XL-366
- Alpha-XL XL-233, XL-266
- AlphaBook1 Alpha laptop
- Avanti AS 200, AS 205, AS 250, AS 255, AS 300, AS 400
- Cabriolet AlphaPC64, AlphaPCI64
DP264 DP264 / DS20 / ES40 / DS10 / DS10L
- EB164 EB164 21164 evaluation board
- EB64+ EB64+ 21064 evaluation board
- EB66 EB66 21066 evaluation board
- EB66+ EB66+ 21066 evaluation board
- Jensen DECpc 150, DEC 2000 models 300, 500
LX164 AlphaPC164-LX
- Lynx AS 2100A
Miata Personal Workstation 433/500/600 a/au
Marvel AlphaServer ES47 / ES80 / GS1280
Mikasa AS 1000
- Noname AXPpci33, UDB (Multia)
Noritake AS 1000A, AS 600A, AS 800
PC164 AlphaPC164
Rawhide AS 1200, AS 4000, AS 4100
@@ -137,27 +126,6 @@ config ALPHA_ALCOR
all the work required to support an external Bcache and to maintain
memory coherence when a PCI device DMAs into (or out of) memory.
-config ALPHA_XL
- bool "Alpha-XL"
- help
- XL-233 and XL-266-based Alpha systems.
-
-config ALPHA_BOOK1
- bool "AlphaBook1"
- help
- Dec AlphaBook1/Burns Alpha-based laptops.
-
-config ALPHA_AVANTI_CH
- bool "Avanti"
-
-config ALPHA_CABRIOLET
- bool "Cabriolet"
- help
- Cabriolet AlphaPC64, AlphaPCI64 systems. Derived from EB64+ but now
- baby-AT with Flash boot ROM, no on-board SCSI or Ethernet. 3 ISA
- slots, 4 PCI slots (one pair are on a shared slot), uses plug-in
- Bcache SIMMs. Requires power supply with 3.3V output.
-
config ALPHA_DP264
bool "DP264"
help
@@ -165,62 +133,18 @@ config ALPHA_DP264
API Networks: 264DP, UP2000(+), CS20;
Compaq: DS10(E,L), XP900, XP1000, DS20(E), ES40.
-config ALPHA_EB164
- bool "EB164"
- help
- EB164 21164 evaluation board from DEC. Uses 21164 and ALCOR. Has
- ISA and PCI expansion (3 ISA slots, 2 64-bit PCI slots (one is
- shared with an ISA slot) and 2 32-bit PCI slots. Uses plus-in
- Bcache SIMMs. I/O sub-system provides SuperI/O (2S, 1P, FD), KBD,
- MOUSE (PS2 style), RTC/NVRAM. Boot ROM is Flash. PC-AT-sized
- motherboard. Requires power supply with 3.3V output.
-
-config ALPHA_EB64P_CH
- bool "EB64+"
-
-config ALPHA_EB66
- bool "EB66"
- help
- A Digital DS group board. Uses 21066 or 21066A. I/O sub-system is
- identical to EB64+. Baby PC-AT size. Runs from standard PC power
- supply. The EB66 schematic was published as a marketing poster
- advertising the 21066 as "the first microprocessor in the world with
- embedded PCI".
-
-config ALPHA_EB66P
- bool "EB66+"
- help
- Later variant of the EB66 board.
-
config ALPHA_EIGER
bool "Eiger"
help
Apparently an obscure OEM single-board computer based on the
Typhoon/Tsunami chipset family. Information on it is scanty.
-config ALPHA_JENSEN
- bool "Jensen"
- select HAVE_EISA
- help
- DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
- of the first-generation Alpha systems. A number of these systems
- seem to be available on the second- hand market. The Jensen is a
- floor-standing tower system which originally used a 150MHz 21064 It
- used programmable logic to interface a 486 EISA I/O bridge to the
- CPU.
-
config ALPHA_LX164
bool "LX164"
help
A technical overview of this board is available at
<http://www.unix-ag.org/Linux-Alpha/Architectures/LX164.html>.
-config ALPHA_LYNX
- bool "Lynx"
- select HAVE_EISA
- help
- AlphaServer 2100A-based systems.
-
config ALPHA_MARVEL
bool "Marvel"
help
@@ -243,9 +167,6 @@ config ALPHA_NAUTILUS
help
Alpha systems based on the AMD 751 & ALI 1543C chipsets.
-config ALPHA_NONAME_CH
- bool "Noname"
-
config ALPHA_NORITAKE
bool "Noritake"
select HAVE_EISA
@@ -256,9 +177,6 @@ config ALPHA_NORITAKE
config ALPHA_PC164
bool "PC164"
-config ALPHA_P2K
- bool "Platform2000"
-
config ALPHA_RAWHIDE
bool "Rawhide"
select HAVE_EISA
@@ -322,84 +240,18 @@ config ISA_DMA_API
bool
default y
-config ALPHA_NONAME
- bool
- depends on ALPHA_BOOK1 || ALPHA_NONAME_CH
- default y
- help
- The AXPpci33 (aka NoName), is based on the EB66 (includes the Multia
- UDB). This design was produced by Digital's Technical OEM (TOEM)
- group. It uses the 21066 processor running at 166MHz or 233MHz. It
- is a baby-AT size, and runs from a standard PC power supply. It has
- 5 ISA slots and 3 PCI slots (one pair are a shared slot). There are
- 2 versions, with either PS/2 or large DIN connectors for the
- keyboard.
-
-config ALPHA_EV4
- bool
- depends on ALPHA_JENSEN || (ALPHA_SABLE && !ALPHA_GAMMA) || ALPHA_LYNX || ALPHA_NORITAKE && !ALPHA_PRIMO || ALPHA_MIKASA && !ALPHA_PRIMO || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL || ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
- default y if !ALPHA_LYNX
- default y if !ALPHA_EV5
-
-config ALPHA_LCA
- bool
- depends on ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
- default y
-
-config ALPHA_APECS
- bool
- depends on !ALPHA_PRIMO && (ALPHA_NORITAKE || ALPHA_MIKASA) || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL
- default y
-
-config ALPHA_EB64P
- bool
- depends on ALPHA_CABRIOLET || ALPHA_EB64P_CH
- default y
- help
- Uses 21064 or 21064A and APECs. Has ISA and PCI expansion (3 ISA,
- 2 PCI, one pair are on a shared slot). Supports 36-bit DRAM SIMs.
- ISA bus generated by Intel SaturnI/O PCI-ISA bridge. On-board SCSI
- (NCR 810 on PCI) Ethernet (Digital 21040), KBD, MOUSE (PS2 style),
- SuperI/O (2S, 1P, FD), RTC/NVRAM. Boot ROM is EPROM. PC-AT size.
- Runs from standard PC power supply.
-
-config ALPHA_EV5
- bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_LYNX
- default y if ALPHA_RX164 || ALPHA_RAWHIDE || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_SABLE && ALPHA_GAMMA || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
-
config ALPHA_CIA
bool
- depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
+ depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE || ALPHA_MIKASA || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_ALCOR
default y
config ALPHA_EV56
- bool "EV56 CPU (speed >= 366MHz)?" if ALPHA_ALCOR
- default y if ALPHA_RX164 || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_PC164 || ALPHA_TAKARA
-
-config ALPHA_EV56
- prompt "EV56 CPU (speed >= 333MHz)?"
- depends on ALPHA_NORITAKE || ALPHA_PRIMO
-
-config ALPHA_EV56
- prompt "EV56 CPU (speed >= 400MHz)?"
- depends on ALPHA_RAWHIDE
-
-config ALPHA_PRIMO
- bool "EV5 CPU daughtercard (model 5/xxx)?"
- depends on ALPHA_NORITAKE || ALPHA_MIKASA
- help
- Say Y if you have an AS 1000 5/xxx or an AS 1000A 5/xxx.
-
-config ALPHA_GAMMA
- bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_SABLE
- depends on ALPHA_SABLE || ALPHA_LYNX
- default ALPHA_LYNX
- help
- Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
+ bool
+ default y if ALPHA_ALCOR || ALPHA_RX164 || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_NORITAKE || ALPHA_MIKASA || ALPHA_RAWHIDE || ALPHA_SABLE
config ALPHA_T2
bool
- depends on ALPHA_SABLE || ALPHA_LYNX
+ depends on ALPHA_SABLE
default y
config ALPHA_PYXIS
@@ -443,15 +295,6 @@ config GENERIC_HWEIGHT
bool
default y if !ALPHA_EV67
-config ALPHA_AVANTI
- bool
- depends on ALPHA_XL || ALPHA_AVANTI_CH
- default y
- help
- Avanti AS 200, AS 205, AS 250, AS 255, AS 300, and AS 400-based
- Alphas. Info at
- <http://www.unix-ag.org/Linux-Alpha/Architectures/Avanti.html>.
-
config ALPHA_BROKEN_IRQ_MASK
bool
depends on ALPHA_GENERIC || ALPHA_PC164
@@ -481,9 +324,9 @@ config ALPHA_QEMU
config ALPHA_SRM
- bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
+ bool "Use SRM as bootloader" if ALPHA_PC164 || ALPHA_TAKARA || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS
depends on TTY
- default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
+ default y if ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
help
There are two different types of booting firmware on Alphas: SRM,
which is command line driven, and ARC, which uses menus and arrow
@@ -509,7 +352,7 @@ config ARCH_MAY_HAVE_PC_FDC
config SMP
bool "Symmetric multi-processing support"
- depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
+ depends on ALPHA_SABLE || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, say N. If you have a system with more
@@ -545,7 +388,7 @@ config ARCH_SPARSEMEM_ENABLE
config ALPHA_WTINT
bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
default y if ALPHA_QEMU
- default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
+ default n if ALPHA_EV56
default n if !ALPHA_SRM && !ALPHA_GENERIC
default y if SMP
help
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 45158024085e..35445ff2e489 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -15,18 +15,14 @@ CHECKFLAGS += -D__alpha__
cflags-y := -pipe -mno-fp-regs -ffixed-8
cflags-y += $(call cc-option, -fno-jump-tables)
-cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
-cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
cpuflags-$(CONFIG_ALPHA_EV56) := -mcpu=ev56
cpuflags-$(CONFIG_ALPHA_POLARIS) := -mcpu=pca56
cpuflags-$(CONFIG_ALPHA_SX164) := -mcpu=pca56
cpuflags-$(CONFIG_ALPHA_EV6) := -mcpu=ev6
cpuflags-$(CONFIG_ALPHA_EV67) := -mcpu=ev67
# If GENERIC, make sure to turn off any instruction set extensions that
-# the host compiler might have on by default. Given that EV4 and EV5
-# have the same instruction set, prefer EV5 because an EV5 schedule is
-# more likely to keep an EV4 processor busy than vice-versa.
-cpuflags-$(CONFIG_ALPHA_GENERIC) := -mcpu=ev5
+# the host compiler might have on by default.
+cpuflags-$(CONFIG_ALPHA_GENERIC) := -mcpu=ev56 -mtune=ev6
cflags-y += $(cpuflags-y)
diff --git a/arch/alpha/include/asm/core_apecs.h b/arch/alpha/include/asm/core_apecs.h
deleted file mode 100644
index 69a2fc62c9c3..000000000000
--- a/arch/alpha/include/asm/core_apecs.h
+++ /dev/null
@@ -1,534 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ALPHA_APECS__H__
-#define __ALPHA_APECS__H__
-
-#include <linux/types.h>
-#include <asm/compiler.h>
-
-/*
- * APECS is the internal name for the 2107x chipset which provides
- * memory controller and PCI access for the 21064 chip based systems.
- *
- * This file is based on:
- *
- * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets
- * Data Sheet
- *
- * EC-N0648-72
- *
- *
- * david.rusling@reo.mts.dec.com Initial Version.
- *
- */
-
-/*
- An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
- that get passed through the PCI<->ISA bridge chip. So we've gotta use
- both windows to max out the physical memory we can DMA to. Sigh...
-
- If we try a window at 0 for 1GB as a work-around, we run into conflicts
- with ISA/PCI bus memory which can't be relocated, like VGA aperture and
- BIOS ROMs. So we must put the windows high enough to avoid these areas.
-
- We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1,
- and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1.
- Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually
- be used for that range (via virt_to_bus()).
-
- Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb,
- to keep virt_to_bus() from returning an address in the first window, for
- a data area that goes beyond the 64Mb first DMA window. Sigh...
- The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but
- we can't just use that here, because of header file looping... :-(
-
- Window 1 will be used for all DMA from the ISA bus; yes, that does
- limit what memory an ISA floppy or sound card or Ethernet can touch, but
- it's also a known limitation on other platforms as well. We use the
- same technique that is used on INTEL platforms with similar limitation:
- set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init().
- We trust that any ISA bus device drivers will *always* ask for DMAable
- memory explicitly via kmalloc()/get_free_pages() flags arguments.
-
- Note that most PCI bus devices' drivers do *not* explicitly ask for
- DMAable memory; they count on being able to DMA to any memory they
- get from kmalloc()/get_free_pages(). They will also use window 1 for
- any physical memory accesses below 64Mb; the rest will be handled by
- window 2, maxing out at 1Gb of memory. I trust this is enough... :-)
-
- We hope that the area before the first window is large enough so that
- there will be no overlap at the top end (64Mb). We *must* locate the
- PCI cards' memory just below window 1, so that there's still the
- possibility of being able to access it via SPARSE space. This is
- important for cards such as the Matrox Millennium, whose Xserver
- wants to access memory-mapped registers in byte and short lengths.
-
- Note that the XL is treated differently from the AVANTI, even though
- for most other things they are identical. It didn't seem reasonable to
- make the AVANTI support pay for the limitations of the XL. It is true,
- however, that an XL kernel will run on an AVANTI without problems.
-
- %%% All of this should be obviated by the ability to route
- everything through the iommu.
-*/
-
-/*
- * 21071-DA Control and Status registers.
- * These are used for PCI memory access.
- */
-#define APECS_IOC_DCSR (IDENT_ADDR + 0x1A0000000UL)
-#define APECS_IOC_PEAR (IDENT_ADDR + 0x1A0000020UL)
-#define APECS_IOC_SEAR (IDENT_ADDR + 0x1A0000040UL)
-#define APECS_IOC_DR1 (IDENT_ADDR + 0x1A0000060UL)
-#define APECS_IOC_DR2 (IDENT_ADDR + 0x1A0000080UL)
-#define APECS_IOC_DR3 (IDENT_ADDR + 0x1A00000A0UL)
-
-#define APECS_IOC_TB1R (IDENT_ADDR + 0x1A00000C0UL)
-#define APECS_IOC_TB2R (IDENT_ADDR + 0x1A00000E0UL)
-
-#define APECS_IOC_PB1R (IDENT_ADDR + 0x1A0000100UL)
-#define APECS_IOC_PB2R (IDENT_ADDR + 0x1A0000120UL)
-
-#define APECS_IOC_PM1R (IDENT_ADDR + 0x1A0000140UL)
-#define APECS_IOC_PM2R (IDENT_ADDR + 0x1A0000160UL)
-
-#define APECS_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL)
-#define APECS_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL)
-#define APECS_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL)
-
-#define APECS_IOC_PMLT (IDENT_ADDR + 0x1A00001E0UL)
-
-#define APECS_IOC_TLBTAG0 (IDENT_ADDR + 0x1A0000200UL)
-#define APECS_IOC_TLBTAG1 (IDENT_ADDR + 0x1A0000220UL)
-#define APECS_IOC_TLBTAG2 (IDENT_ADDR + 0x1A0000240UL)
-#define APECS_IOC_TLBTAG3 (IDENT_ADDR + 0x1A0000260UL)
-#define APECS_IOC_TLBTAG4 (IDENT_ADDR + 0x1A0000280UL)
-#define APECS_IOC_TLBTAG5 (IDENT_ADDR + 0x1A00002A0UL)
-#define APECS_IOC_TLBTAG6 (IDENT_ADDR + 0x1A00002C0UL)
-#define APECS_IOC_TLBTAG7 (IDENT_ADDR + 0x1A00002E0UL)
-
-#define APECS_IOC_TLBDATA0 (IDENT_ADDR + 0x1A0000300UL)
-#define APECS_IOC_TLBDATA1 (IDENT_ADDR + 0x1A0000320UL)
-#define APECS_IOC_TLBDATA2 (IDENT_ADDR + 0x1A0000340UL)
-#define APECS_IOC_TLBDATA3 (IDENT_ADDR + 0x1A0000360UL)
-#define APECS_IOC_TLBDATA4 (IDENT_ADDR + 0x1A0000380UL)
-#define APECS_IOC_TLBDATA5 (IDENT_ADDR + 0x1A00003A0UL)
-#define APECS_IOC_TLBDATA6 (IDENT_ADDR + 0x1A00003C0UL)
-#define APECS_IOC_TLBDATA7 (IDENT_ADDR + 0x1A00003E0UL)
-
-#define APECS_IOC_TBIA (IDENT_ADDR + 0x1A0000400UL)
-
-
-/*
- * 21071-CA Control and Status registers.
- * These are used to program memory timing,
- * configure memory and initialise the B-Cache.
- */
-#define APECS_MEM_GCR (IDENT_ADDR + 0x180000000UL)
-#define APECS_MEM_EDSR (IDENT_ADDR + 0x180000040UL)
-#define APECS_MEM_TAR (IDENT_ADDR + 0x180000060UL)
-#define APECS_MEM_ELAR (IDENT_ADDR + 0x180000080UL)
-#define APECS_MEM_EHAR (IDENT_ADDR + 0x1800000a0UL)
-#define APECS_MEM_SFT_RST (IDENT_ADDR + 0x1800000c0UL)
-#define APECS_MEM_LDxLAR (IDENT_ADDR + 0x1800000e0UL)
-#define APECS_MEM_LDxHAR (IDENT_ADDR + 0x180000100UL)
-#define APECS_MEM_GTR (IDENT_ADDR + 0x180000200UL)
-#define APECS_MEM_RTR (IDENT_ADDR + 0x180000220UL)
-#define APECS_MEM_VFPR (IDENT_ADDR + 0x180000240UL)
-#define APECS_MEM_PDLDR (IDENT_ADDR + 0x180000260UL)
-#define APECS_MEM_PDhDR (IDENT_ADDR + 0x180000280UL)
-
-/* Bank x Base Address Register */
-#define APECS_MEM_B0BAR (IDENT_ADDR + 0x180000800UL)
-#define APECS_MEM_B1BAR (IDENT_ADDR + 0x180000820UL)
-#define APECS_MEM_B2BAR (IDENT_ADDR + 0x180000840UL)
-#define APECS_MEM_B3BAR (IDENT_ADDR + 0x180000860UL)
-#define APECS_MEM_B4BAR (IDENT_ADDR + 0x180000880UL)
-#define APECS_MEM_B5BAR (IDENT_ADDR + 0x1800008A0UL)
-#define APECS_MEM_B6BAR (IDENT_ADDR + 0x1800008C0UL)
-#define APECS_MEM_B7BAR (IDENT_ADDR + 0x1800008E0UL)
-#define APECS_MEM_B8BAR (IDENT_ADDR + 0x180000900UL)
-
-/* Bank x Configuration Register */
-#define APECS_MEM_B0BCR (IDENT_ADDR + 0x180000A00UL)
-#define APECS_MEM_B1BCR (IDENT_ADDR + 0x180000A20UL)
-#define APECS_MEM_B2BCR (IDENT_ADDR + 0x180000A40UL)
-#define APECS_MEM_B3BCR (IDENT_ADDR + 0x180000A60UL)
-#define APECS_MEM_B4BCR (IDENT_ADDR + 0x180000A80UL)
-#define APECS_MEM_B5BCR (IDENT_ADDR + 0x180000AA0UL)
-#define APECS_MEM_B6BCR (IDENT_ADDR + 0x180000AC0UL)
-#define APECS_MEM_B7BCR (IDENT_ADDR + 0x180000AE0UL)
-#define APECS_MEM_B8BCR (IDENT_ADDR + 0x180000B00UL)
-
-/* Bank x Timing Register A */
-#define APECS_MEM_B0TRA (IDENT_ADDR + 0x180000C00UL)
-#define APECS_MEM_B1TRA (IDENT_ADDR + 0x180000C20UL)
-#define APECS_MEM_B2TRA (IDENT_ADDR + 0x180000C40UL)
-#define APECS_MEM_B3TRA (IDENT_ADDR + 0x180000C60UL)
-#define APECS_MEM_B4TRA (IDENT_ADDR + 0x180000C80UL)
-#define APECS_MEM_B5TRA (IDENT_ADDR + 0x180000CA0UL)
-#define APECS_MEM_B6TRA (IDENT_ADDR + 0x180000CC0UL)
-#define APECS_MEM_B7TRA (IDENT_ADDR + 0x180000CE0UL)
-#define APECS_MEM_B8TRA (IDENT_ADDR + 0x180000D00UL)
-
-/* Bank x Timing Register B */
-#define APECS_MEM_B0TRB (IDENT_ADDR + 0x180000E00UL)
-#define APECS_MEM_B1TRB (IDENT_ADDR + 0x180000E20UL)
-#define APECS_MEM_B2TRB (IDENT_ADDR + 0x180000E40UL)
-#define APECS_MEM_B3TRB (IDENT_ADDR + 0x180000E60UL)
-#define APECS_MEM_B4TRB (IDENT_ADDR + 0x180000E80UL)
-#define APECS_MEM_B5TRB (IDENT_ADDR + 0x180000EA0UL)
-#define APECS_MEM_B6TRB (IDENT_ADDR + 0x180000EC0UL)
-#define APECS_MEM_B7TRB (IDENT_ADDR + 0x180000EE0UL)
-#define APECS_MEM_B8TRB (IDENT_ADDR + 0x180000F00UL)
-
-
-/*
- * Memory spaces:
- */
-#define APECS_IACK_SC (IDENT_ADDR + 0x1b0000000UL)
-#define APECS_CONF (IDENT_ADDR + 0x1e0000000UL)
-#define APECS_IO (IDENT_ADDR + 0x1c0000000UL)
-#define APECS_SPARSE_MEM (IDENT_ADDR + 0x200000000UL)
-#define APECS_DENSE_MEM (IDENT_ADDR + 0x300000000UL)
-
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define APECS_IOC_STAT0_CMD 0xf
-#define APECS_IOC_STAT0_ERR (1<<4)
-#define APECS_IOC_STAT0_LOST (1<<5)
-#define APECS_IOC_STAT0_THIT (1<<6)
-#define APECS_IOC_STAT0_TREF (1<<7)
-#define APECS_IOC_STAT0_CODE_SHIFT 8
-#define APECS_IOC_STAT0_CODE_MASK 0x7
-#define APECS_IOC_STAT0_P_NBR_SHIFT 13
-#define APECS_IOC_STAT0_P_NBR_MASK 0x7ffff
-
-#define APECS_HAE_ADDRESS APECS_IOC_HAXR1
-
-
-/*
- * Data structure for handling APECS machine checks:
- */
-
-struct el_apecs_mikasa_sysdata_mcheck
-{
- unsigned long coma_gcr;
- unsigned long coma_edsr;
- unsigned long coma_ter;
- unsigned long coma_elar;
- unsigned long coma_ehar;
- unsigned long coma_ldlr;
- unsigned long coma_ldhr;
- unsigned long coma_base0;
- unsigned long coma_base1;
- unsigned long coma_base2;
- unsigned long coma_base3;
- unsigned long coma_cnfg0;
- unsigned long coma_cnfg1;
- unsigned long coma_cnfg2;
- unsigned long coma_cnfg3;
- unsigned long epic_dcsr;
- unsigned long epic_pear;
- unsigned long epic_sear;
- unsigned long epic_tbr1;
- unsigned long epic_tbr2;
- unsigned long epic_pbr1;
- unsigned long epic_pbr2;
- unsigned long epic_pmr1;
- unsigned long epic_pmr2;
- unsigned long epic_harx1;
- unsigned long epic_harx2;
- unsigned long epic_pmlt;
- unsigned long epic_tag0;
- unsigned long epic_tag1;
- unsigned long epic_tag2;
- unsigned long epic_tag3;
- unsigned long epic_tag4;
- unsigned long epic_tag5;
- unsigned long epic_tag6;
- unsigned long epic_tag7;
- unsigned long epic_data0;
- unsigned long epic_data1;
- unsigned long epic_data2;
- unsigned long epic_data3;
- unsigned long epic_data4;
- unsigned long epic_data5;
- unsigned long epic_data6;
- unsigned long epic_data7;
-
- unsigned long pceb_vid;
- unsigned long pceb_did;
- unsigned long pceb_revision;
- unsigned long pceb_command;
- unsigned long pceb_status;
- unsigned long pceb_latency;
- unsigned long pceb_control;
- unsigned long pceb_arbcon;
- unsigned long pceb_arbpri;
-
- unsigned long esc_id;
- unsigned long esc_revision;
- unsigned long esc_int0;
- unsigned long esc_int1;
- unsigned long esc_elcr0;
- unsigned long esc_elcr1;
- unsigned long esc_last_eisa;
- unsigned long esc_nmi_stat;
-
- unsigned long pci_ir;
- unsigned long pci_imr;
- unsigned long svr_mgr;
-};
-
-/* This for the normal APECS machines. */
-struct el_apecs_sysdata_mcheck
-{
- unsigned long coma_gcr;
- unsigned long coma_edsr;
- unsigned long coma_ter;
- unsigned long coma_elar;
- unsigned long coma_ehar;
- unsigned long coma_ldlr;
- unsigned long coma_ldhr;
- unsigned long coma_base0;
- unsigned long coma_base1;
- unsigned long coma_base2;
- unsigned long coma_cnfg0;
- unsigned long coma_cnfg1;
- unsigned long coma_cnfg2;
- unsigned long epic_dcsr;
- unsigned long epic_pear;
- unsigned long epic_sear;
- unsigned long epic_tbr1;
- unsigned long epic_tbr2;
- unsigned long epic_pbr1;
- unsigned long epic_pbr2;
- unsigned long epic_pmr1;
- unsigned long epic_pmr2;
- unsigned long epic_harx1;
- unsigned long epic_harx2;
- unsigned long epic_pmlt;
- unsigned long epic_tag0;
- unsigned long epic_tag1;
- unsigned long epic_tag2;
- unsigned long epic_tag3;
- unsigned long epic_tag4;
- unsigned long epic_tag5;
- unsigned long epic_tag6;
- unsigned long epic_tag7;
- unsigned long epic_data0;
- unsigned long epic_data1;
- unsigned long epic_data2;
- unsigned long epic_data3;
- unsigned long epic_data4;
- unsigned long epic_data5;
- unsigned long epic_data6;
- unsigned long epic_data7;
-};
-
-struct el_apecs_procdata
-{
- unsigned long paltemp[32]; /* PAL TEMP REGS. */
- /* EV4-specific fields */
- unsigned long exc_addr; /* Address of excepting instruction. */
- unsigned long exc_sum; /* Summary of arithmetic traps. */
- unsigned long exc_mask; /* Exception mask (from exc_sum). */
- unsigned long iccsr; /* IBox hardware enables. */
- unsigned long pal_base; /* Base address for PALcode. */
- unsigned long hier; /* Hardware Interrupt Enable. */
- unsigned long hirr; /* Hardware Interrupt Request. */
- unsigned long csr; /* D-stream fault info. */
- unsigned long dc_stat; /* D-cache status (ECC/Parity Err). */
- unsigned long dc_addr; /* EV3 Phys Addr for ECC/DPERR. */
- unsigned long abox_ctl; /* ABox Control Register. */
- unsigned long biu_stat; /* BIU Status. */
- unsigned long biu_addr; /* BUI Address. */
- unsigned long biu_ctl; /* BIU Control. */
- unsigned long fill_syndrome;/* For correcting ECC errors. */
- unsigned long fill_addr; /* Cache block which was being read */
- unsigned long va; /* Effective VA of fault or miss. */
- unsigned long bc_tag; /* Backup Cache Tag Probe Results.*/
-};
-
-
-#ifdef __KERNEL__
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __IO_EXTERN_INLINE
-#endif
-
-/*
- * I/O functions:
- *
- * Unlike Jensen, the APECS machines have no concept of local
- * I/O---everything goes over the PCI bus.
- *
- * There is plenty room for optimization here. In particular,
- * the Alpha's insb/insw/extb/extw should be useful in moving
- * data to/from the right byte-lanes.
- */
-
-#define vip volatile int __force *
-#define vuip volatile unsigned int __force *
-#define vulp volatile unsigned long __force *
-
-#define APECS_SET_HAE \
- do { \
- if (addr >= (1UL << 24)) { \
- unsigned long msb = addr & 0xf8000000; \
- addr -= msb; \
- set_hae(msb); \
- } \
- } while (0)
-
-__EXTERN_INLINE u8 apecs_ioread8(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long result, base_and_type;
-
- if (addr >= APECS_DENSE_MEM) {
- addr -= APECS_DENSE_MEM;
- APECS_SET_HAE;
- base_and_type = APECS_SPARSE_MEM + 0x00;
- } else {
- addr -= APECS_IO;
- base_and_type = APECS_IO + 0x00;
- }
-
- result = *(vip) ((addr << 5) + base_and_type);
- return __kernel_extbl(result, addr & 3);
-}
-
-__EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long w, base_and_type;
-
- if (addr >= APECS_DENSE_MEM) {
- addr -= APECS_DENSE_MEM;
- APECS_SET_HAE;
- base_and_type = APECS_SPARSE_MEM + 0x00;
- } else {
- addr -= APECS_IO;
- base_and_type = APECS_IO + 0x00;
- }
-
- w = __kernel_insbl(b, addr & 3);
- *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u16 apecs_ioread16(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long result, base_and_type;
-
- if (addr >= APECS_DENSE_MEM) {
- addr -= APECS_DENSE_MEM;
- APECS_SET_HAE;
- base_and_type = APECS_SPARSE_MEM + 0x08;
- } else {
- addr -= APECS_IO;
- base_and_type = APECS_IO + 0x08;
- }
-
- result = *(vip) ((addr << 5) + base_and_type);
- return __kernel_extwl(result, addr & 3);
-}
-
-__EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long w, base_and_type;
-
- if (addr >= APECS_DENSE_MEM) {
- addr -= APECS_DENSE_MEM;
- APECS_SET_HAE;
- base_and_type = APECS_SPARSE_MEM + 0x08;
- } else {
- addr -= APECS_IO;
- base_and_type = APECS_IO + 0x08;
- }
-
- w = __kernel_inswl(b, addr & 3);
- *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u32 apecs_ioread32(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < APECS_DENSE_MEM)
- addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
- return *(vuip)addr;
-}
-
-__EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < APECS_DENSE_MEM)
- addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
- *(vuip)addr = b;
-}
-
-__EXTERN_INLINE u64 apecs_ioread64(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < APECS_DENSE_MEM)
- addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
- return *(vulp)addr;
-}
-
-__EXTERN_INLINE void apecs_iowrite64(u64 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < APECS_DENSE_MEM)
- addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
- *(vulp)addr = b;
-}
-
-__EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
-{
- return (void __iomem *)(addr + APECS_IO);
-}
-
-__EXTERN_INLINE void __iomem *apecs_ioremap(unsigned long addr,
- unsigned long size)
-{
- return (void __iomem *)(addr + APECS_DENSE_MEM);
-}
-
-__EXTERN_INLINE int apecs_is_ioaddr(unsigned long addr)
-{
- return addr >= IDENT_ADDR + 0x180000000UL;
-}
-
-__EXTERN_INLINE int apecs_is_mmio(const volatile void __iomem *addr)
-{
- return (unsigned long)addr >= APECS_DENSE_MEM;
-}
-
-#undef APECS_SET_HAE
-
-#undef vip
-#undef vuip
-#undef vulp
-
-#undef __IO_PREFIX
-#define __IO_PREFIX apecs
-#define apecs_trivial_io_bw 0
-#define apecs_trivial_io_lq 0
-#define apecs_trivial_rw_bw 2
-#define apecs_trivial_rw_lq 1
-#define apecs_trivial_iounmap 1
-#include <asm/io_trivial.h>
-
-#ifdef __IO_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __IO_EXTERN_INLINE
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __ALPHA_APECS__H__ */
diff --git a/arch/alpha/include/asm/core_lca.h b/arch/alpha/include/asm/core_lca.h
deleted file mode 100644
index d8c3e72ef8f6..000000000000
--- a/arch/alpha/include/asm/core_lca.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ALPHA_LCA__H__
-#define __ALPHA_LCA__H__
-
-#include <asm/compiler.h>
-#include <asm/mce.h>
-
-/*
- * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
- * for example).
- *
- * This file is based on:
- *
- * DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
- * Hardware Reference Manual; Digital Equipment Corp.; May 1994;
- * Maynard, MA; Order Number: EC-N2681-71.
- */
-
-/*
- * NOTE: The LCA uses a Host Address Extension (HAE) register to access
- * PCI addresses that are beyond the first 27 bits of address
- * space. Updating the HAE requires an external cycle (and
- * a memory barrier), which tends to be slow. Instead of updating
- * it on each sparse memory access, we keep the current HAE value
- * cached in variable cache_hae. Only if the cached HAE differs
- * from the desired HAE value do we actually updated HAE register.
- * The HAE register is preserved by the interrupt handler entry/exit
- * code, so this scheme works even in the presence of interrupts.
- *
- * Dense memory space doesn't require the HAE, but is restricted to
- * aligned 32 and 64 bit accesses. Special Cycle and Interrupt
- * Acknowledge cycles may also require the use of the HAE. The LCA
- * limits I/O address space to the bottom 24 bits of address space,
- * but this easily covers the 16 bit ISA I/O address space.
- */
-
-/*
- * NOTE 2! The memory operations do not set any memory barriers, as
- * it's not needed for cases like a frame buffer that is essentially
- * memory-like. You need to do them by hand if the operations depend
- * on ordering.
- *
- * Similarly, the port I/O operations do a "mb" only after a write
- * operation: if an mb is needed before (as in the case of doing
- * memory mapped I/O first, and then a port I/O operation to the same
- * device), it needs to be done by hand.
- *
- * After the above has bitten me 100 times, I'll give up and just do
- * the mb all the time, but right now I'm hoping this will work out.
- * Avoiding mb's may potentially be a noticeable speed improvement,
- * but I can't honestly say I've tested it.
- *
- * Handling interrupts that need to do mb's to synchronize to
- * non-interrupts is another fun race area. Don't do it (because if
- * you do, I'll have to do *everything* with interrupts disabled,
- * ugh).
- */
-
-/*
- * Memory Controller registers:
- */
-#define LCA_MEM_BCR0 (IDENT_ADDR + 0x120000000UL)
-#define LCA_MEM_BCR1 (IDENT_ADDR + 0x120000008UL)
-#define LCA_MEM_BCR2 (IDENT_ADDR + 0x120000010UL)
-#define LCA_MEM_BCR3 (IDENT_ADDR + 0x120000018UL)
-#define LCA_MEM_BMR0 (IDENT_ADDR + 0x120000020UL)
-#define LCA_MEM_BMR1 (IDENT_ADDR + 0x120000028UL)
-#define LCA_MEM_BMR2 (IDENT_ADDR + 0x120000030UL)
-#define LCA_MEM_BMR3 (IDENT_ADDR + 0x120000038UL)
-#define LCA_MEM_BTR0 (IDENT_ADDR + 0x120000040UL)
-#define LCA_MEM_BTR1 (IDENT_ADDR + 0x120000048UL)
-#define LCA_MEM_BTR2 (IDENT_ADDR + 0x120000050UL)
-#define LCA_MEM_BTR3 (IDENT_ADDR + 0x120000058UL)
-#define LCA_MEM_GTR (IDENT_ADDR + 0x120000060UL)
-#define LCA_MEM_ESR (IDENT_ADDR + 0x120000068UL)
-#define LCA_MEM_EAR (IDENT_ADDR + 0x120000070UL)
-#define LCA_MEM_CAR (IDENT_ADDR + 0x120000078UL)
-#define LCA_MEM_VGR (IDENT_ADDR + 0x120000080UL)
-#define LCA_MEM_PLM (IDENT_ADDR + 0x120000088UL)
-#define LCA_MEM_FOR (IDENT_ADDR + 0x120000090UL)
-
-/*
- * I/O Controller registers:
- */
-#define LCA_IOC_HAE (IDENT_ADDR + 0x180000000UL)
-#define LCA_IOC_CONF (IDENT_ADDR + 0x180000020UL)
-#define LCA_IOC_STAT0 (IDENT_ADDR + 0x180000040UL)
-#define LCA_IOC_STAT1 (IDENT_ADDR + 0x180000060UL)
-#define LCA_IOC_TBIA (IDENT_ADDR + 0x180000080UL)
-#define LCA_IOC_TB_ENA (IDENT_ADDR + 0x1800000a0UL)
-#define LCA_IOC_SFT_RST (IDENT_ADDR + 0x1800000c0UL)
-#define LCA_IOC_PAR_DIS (IDENT_ADDR + 0x1800000e0UL)
-#define LCA_IOC_W_BASE0 (IDENT_ADDR + 0x180000100UL)
-#define LCA_IOC_W_BASE1 (IDENT_ADDR + 0x180000120UL)
-#define LCA_IOC_W_MASK0 (IDENT_ADDR + 0x180000140UL)
-#define LCA_IOC_W_MASK1 (IDENT_ADDR + 0x180000160UL)
-#define LCA_IOC_T_BASE0 (IDENT_ADDR + 0x180000180UL)
-#define LCA_IOC_T_BASE1 (IDENT_ADDR + 0x1800001a0UL)
-#define LCA_IOC_TB_TAG0 (IDENT_ADDR + 0x188000000UL)
-#define LCA_IOC_TB_TAG1 (IDENT_ADDR + 0x188000020UL)
-#define LCA_IOC_TB_TAG2 (IDENT_ADDR + 0x188000040UL)
-#define LCA_IOC_TB_TAG3 (IDENT_ADDR + 0x188000060UL)
-#define LCA_IOC_TB_TAG4 (IDENT_ADDR + 0x188000070UL)
-#define LCA_IOC_TB_TAG5 (IDENT_ADDR + 0x1880000a0UL)
-#define LCA_IOC_TB_TAG6 (IDENT_ADDR + 0x1880000c0UL)
-#define LCA_IOC_TB_TAG7 (IDENT_ADDR + 0x1880000e0UL)
-
-/*
- * Memory spaces:
- */
-#define LCA_IACK_SC (IDENT_ADDR + 0x1a0000000UL)
-#define LCA_CONF (IDENT_ADDR + 0x1e0000000UL)
-#define LCA_IO (IDENT_ADDR + 0x1c0000000UL)
-#define LCA_SPARSE_MEM (IDENT_ADDR + 0x200000000UL)
-#define LCA_DENSE_MEM (IDENT_ADDR + 0x300000000UL)
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define LCA_IOC_STAT0_CMD 0xf
-#define LCA_IOC_STAT0_ERR (1<<4)
-#define LCA_IOC_STAT0_LOST (1<<5)
-#define LCA_IOC_STAT0_THIT (1<<6)
-#define LCA_IOC_STAT0_TREF (1<<7)
-#define LCA_IOC_STAT0_CODE_SHIFT 8
-#define LCA_IOC_STAT0_CODE_MASK 0x7
-#define LCA_IOC_STAT0_P_NBR_SHIFT 13
-#define LCA_IOC_STAT0_P_NBR_MASK 0x7ffff
-
-#define LCA_HAE_ADDRESS LCA_IOC_HAE
-
-/* LCA PMR Power Management register defines */
-#define LCA_PMR_ADDR (IDENT_ADDR + 0x120000098UL)
-#define LCA_PMR_PDIV 0x7 /* Primary clock divisor */
-#define LCA_PMR_ODIV 0x38 /* Override clock divisor */
-#define LCA_PMR_INTO 0x40 /* Interrupt override */
-#define LCA_PMR_DMAO 0x80 /* DMA override */
-#define LCA_PMR_OCCEB 0xffff0000L /* Override cycle counter - even bits */
-#define LCA_PMR_OCCOB 0xffff000000000000L /* Override cycle counter - even bits */
-#define LCA_PMR_PRIMARY_MASK 0xfffffffffffffff8L
-
-/* LCA PMR Macros */
-
-#define LCA_READ_PMR (*(volatile unsigned long *)LCA_PMR_ADDR)
-#define LCA_WRITE_PMR(d) (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))
-
-#define LCA_GET_PRIMARY(r) ((r) & LCA_PMR_PDIV)
-#define LCA_GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
-#define LCA_SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK)|(c)))
-
-/* LCA PMR Divisor values */
-#define LCA_PMR_DIV_1 0x0
-#define LCA_PMR_DIV_1_5 0x1
-#define LCA_PMR_DIV_2 0x2
-#define LCA_PMR_DIV_4 0x3
-#define LCA_PMR_DIV_8 0x4
-#define LCA_PMR_DIV_16 0x5
-#define LCA_PMR_DIV_MIN DIV_1
-#define LCA_PMR_DIV_MAX DIV_16
-
-
-/*
- * Data structure for handling LCA machine checks. Correctable errors
- * result in a short logout frame, uncorrectable ones in a long one.
- */
-struct el_lca_mcheck_short {
- struct el_common h; /* common logout header */
- unsigned long esr; /* error-status register */
- unsigned long ear; /* error-address register */
- unsigned long dc_stat; /* dcache status register */
- unsigned long ioc_stat0; /* I/O controller status register 0 */
- unsigned long ioc_stat1; /* I/O controller status register 1 */
-};
-
-struct el_lca_mcheck_long {
- struct el_common h; /* common logout header */
- unsigned long pt[31]; /* PAL temps */
- unsigned long exc_addr; /* exception address */
- unsigned long pad1[3];
- unsigned long pal_base; /* PALcode base address */
- unsigned long hier; /* hw interrupt enable */
- unsigned long hirr; /* hw interrupt request */
- unsigned long mm_csr; /* MMU control & status */
- unsigned long dc_stat; /* data cache status */
- unsigned long dc_addr; /* data cache addr register */
- unsigned long abox_ctl; /* address box control register */
- unsigned long esr; /* error status register */
- unsigned long ear; /* error address register */
- unsigned long car; /* cache control register */
- unsigned long ioc_stat0; /* I/O controller status register 0 */
- unsigned long ioc_stat1; /* I/O controller status register 1 */
- unsigned long va; /* virtual address register */
-};
-
-union el_lca {
- struct el_common * c;
- struct el_lca_mcheck_long * l;
- struct el_lca_mcheck_short * s;
-};
-
-#ifdef __KERNEL__
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __IO_EXTERN_INLINE
-#endif
-
-/*
- * I/O functions:
- *
- * Unlike Jensen, the Noname machines have no concept of local
- * I/O---everything goes over the PCI bus.
- *
- * There is plenty room for optimization here. In particular,
- * the Alpha's insb/insw/extb/extw should be useful in moving
- * data to/from the right byte-lanes.
- */
-
-#define vip volatile int __force *
-#define vuip volatile unsigned int __force *
-#define vulp volatile unsigned long __force *
-
-#define LCA_SET_HAE \
- do { \
- if (addr >= (1UL << 24)) { \
- unsigned long msb = addr & 0xf8000000; \
- addr -= msb; \
- set_hae(msb); \
- } \
- } while (0)
-
-
-__EXTERN_INLINE u8 lca_ioread8(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long result, base_and_type;
-
- if (addr >= LCA_DENSE_MEM) {
- addr -= LCA_DENSE_MEM;
- LCA_SET_HAE;
- base_and_type = LCA_SPARSE_MEM + 0x00;
- } else {
- addr -= LCA_IO;
- base_and_type = LCA_IO + 0x00;
- }
-
- result = *(vip) ((addr << 5) + base_and_type);
- return __kernel_extbl(result, addr & 3);
-}
-
-__EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long w, base_and_type;
-
- if (addr >= LCA_DENSE_MEM) {
- addr -= LCA_DENSE_MEM;
- LCA_SET_HAE;
- base_and_type = LCA_SPARSE_MEM + 0x00;
- } else {
- addr -= LCA_IO;
- base_and_type = LCA_IO + 0x00;
- }
-
- w = __kernel_insbl(b, addr & 3);
- *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u16 lca_ioread16(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long result, base_and_type;
-
- if (addr >= LCA_DENSE_MEM) {
- addr -= LCA_DENSE_MEM;
- LCA_SET_HAE;
- base_and_type = LCA_SPARSE_MEM + 0x08;
- } else {
- addr -= LCA_IO;
- base_and_type = LCA_IO + 0x08;
- }
-
- result = *(vip) ((addr << 5) + base_and_type);
- return __kernel_extwl(result, addr & 3);
-}
-
-__EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long w, base_and_type;
-
- if (addr >= LCA_DENSE_MEM) {
- addr -= LCA_DENSE_MEM;
- LCA_SET_HAE;
- base_and_type = LCA_SPARSE_MEM + 0x08;
- } else {
- addr -= LCA_IO;
- base_and_type = LCA_IO + 0x08;
- }
-
- w = __kernel_inswl(b, addr & 3);
- *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u32 lca_ioread32(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < LCA_DENSE_MEM)
- addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
- return *(vuip)addr;
-}
-
-__EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < LCA_DENSE_MEM)
- addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
- *(vuip)addr = b;
-}
-
-__EXTERN_INLINE u64 lca_ioread64(const void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < LCA_DENSE_MEM)
- addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
- return *(vulp)addr;
-}
-
-__EXTERN_INLINE void lca_iowrite64(u64 b, void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- if (addr < LCA_DENSE_MEM)
- addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
- *(vulp)addr = b;
-}
-
-__EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
-{
- return (void __iomem *)(addr + LCA_IO);
-}
-
-__EXTERN_INLINE void __iomem *lca_ioremap(unsigned long addr,
- unsigned long size)
-{
- return (void __iomem *)(addr + LCA_DENSE_MEM);
-}
-
-__EXTERN_INLINE int lca_is_ioaddr(unsigned long addr)
-{
- return addr >= IDENT_ADDR + 0x120000000UL;
-}
-
-__EXTERN_INLINE int lca_is_mmio(const volatile void __iomem *addr)
-{
- return (unsigned long)addr >= LCA_DENSE_MEM;
-}
-
-#undef vip
-#undef vuip
-#undef vulp
-
-#undef __IO_PREFIX
-#define __IO_PREFIX lca
-#define lca_trivial_rw_bw 2
-#define lca_trivial_rw_lq 1
-#define lca_trivial_io_bw 0
-#define lca_trivial_io_lq 0
-#define lca_trivial_iounmap 1
-#include <asm/io_trivial.h>
-
-#ifdef __IO_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __IO_EXTERN_INLINE
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __ALPHA_LCA__H__ */
diff --git a/arch/alpha/include/asm/core_t2.h b/arch/alpha/include/asm/core_t2.h
index ab956b1625b5..ca9b091d9c5f 100644
--- a/arch/alpha/include/asm/core_t2.h
+++ b/arch/alpha/include/asm/core_t2.h
@@ -25,16 +25,8 @@
#define T2_MEM_R1_MASK 0x07ffffff /* Mem sparse region 1 mask is 27 bits */
/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
-/* All LYNX machines, EV4 or EV5, use the GAMMA bias also */
#define _GAMMA_BIAS 0x8000000000UL
-
-#if defined(CONFIG_ALPHA_GENERIC)
-#define GAMMA_BIAS alpha_mv.sys.t2.gamma_bias
-#elif defined(CONFIG_ALPHA_GAMMA)
#define GAMMA_BIAS _GAMMA_BIAS
-#else
-#define GAMMA_BIAS 0
-#endif
/*
* Memory spaces:
diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h
index 6ce7e2041685..ad5a59b035cb 100644
--- a/arch/alpha/include/asm/dma-mapping.h
+++ b/arch/alpha/include/asm/dma-mapping.h
@@ -6,11 +6,7 @@ extern const struct dma_map_ops alpha_pci_ops;
static inline const struct dma_map_ops *get_arch_dma_ops(void)
{
-#ifdef CONFIG_ALPHA_JENSEN
- return NULL;
-#else
return &alpha_pci_ops;
-#endif
}
#endif /* _ALPHA_DMA_MAPPING_H */
diff --git a/arch/alpha/include/asm/dma.h b/arch/alpha/include/asm/dma.h
index a04d76b96089..3a88812b7165 100644
--- a/arch/alpha/include/asm/dma.h
+++ b/arch/alpha/include/asm/dma.h
@@ -82,11 +82,6 @@
just a wiring limit.
*/
-/* The maximum address for ISA DMA transfer on Alpha XL, due to an
- hardware SIO limitation, is 64MB.
-*/
-#define ALPHA_XL_MAX_ISA_DMA_ADDRESS 0x04000000UL
-
/* The maximum address for ISA DMA transfer on RUFFIAN,
due to an hardware SIO limitation, is 16MB.
*/
@@ -107,9 +102,7 @@
#ifdef CONFIG_ALPHA_GENERIC
# define MAX_ISA_DMA_ADDRESS (alpha_mv.max_isa_dma_address)
#else
-# if defined(CONFIG_ALPHA_XL)
-# define MAX_ISA_DMA_ADDRESS ALPHA_XL_MAX_ISA_DMA_ADDRESS
-# elif defined(CONFIG_ALPHA_RUFFIAN)
+# if defined(CONFIG_ALPHA_RUFFIAN)
# define MAX_ISA_DMA_ADDRESS ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_SABLE)
# define MAX_ISA_DMA_ADDRESS ALPHA_SABLE_MAX_ISA_DMA_ADDRESS
diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
index e6da23f1da83..4d7c46f50382 100644
--- a/arch/alpha/include/asm/elf.h
+++ b/arch/alpha/include/asm/elf.h
@@ -133,9 +133,7 @@ extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
#define ELF_PLATFORM \
({ \
enum implver_enum i_ = implver(); \
- ( i_ == IMPLVER_EV4 ? "ev4" \
- : i_ == IMPLVER_EV5 \
- ? (amask(AMASK_BWX) ? "ev5" : "ev56") \
+ ( i_ == IMPLVER_EV5 ? "ev56" \
: amask (AMASK_CIX) ? "ev6" : "ev67"); \
})
diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
index 4f47a5003fe8..2bb8cbeedf91 100644
--- a/arch/alpha/include/asm/io.h
+++ b/arch/alpha/include/asm/io.h
@@ -203,16 +203,10 @@ static inline int generic_is_mmio(const volatile void __iomem *a)
#else
-#if defined(CONFIG_ALPHA_APECS)
-# include <asm/core_apecs.h>
-#elif defined(CONFIG_ALPHA_CIA)
+#if defined(CONFIG_ALPHA_CIA)
# include <asm/core_cia.h>
#elif defined(CONFIG_ALPHA_IRONGATE)
# include <asm/core_irongate.h>
-#elif defined(CONFIG_ALPHA_JENSEN)
-# include <asm/jensen.h>
-#elif defined(CONFIG_ALPHA_LCA)
-# include <asm/core_lca.h>
#elif defined(CONFIG_ALPHA_MARVEL)
# include <asm/core_marvel.h>
#elif defined(CONFIG_ALPHA_MCPCIA)
@@ -631,23 +625,7 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
#define outsw outsw
#define outsl outsl
-/*
- * The Alpha Jensen hardware for some rather strange reason puts
- * the RTC clock at 0x170 instead of 0x70. Probably due to some
- * misguided idea about using 0x70 for NMI stuff.
- *
- * These defines will override the defaults when doing RTC queries
- */
-
-#ifdef CONFIG_ALPHA_GENERIC
-# define RTC_PORT(x) ((x) + alpha_mv.rtc_port)
-#else
-# ifdef CONFIG_ALPHA_JENSEN
-# define RTC_PORT(x) (0x170+(x))
-# else
-# define RTC_PORT(x) (0x70 + (x))
-# endif
-#endif
+#define RTC_PORT(x) (0x70 + (x))
#define RTC_ALWAYS_BCD 0
/*
diff --git a/arch/alpha/include/asm/irq.h b/arch/alpha/include/asm/irq.h
index 432402c8e47f..d83b26b6660f 100644
--- a/arch/alpha/include/asm/irq.h
+++ b/arch/alpha/include/asm/irq.h
@@ -31,16 +31,11 @@
# define NR_IRQS (32768 + 16) /* marvel - 32 pids */
# endif
-#elif defined(CONFIG_ALPHA_CABRIOLET) || \
- defined(CONFIG_ALPHA_EB66P) || \
- defined(CONFIG_ALPHA_EB164) || \
- defined(CONFIG_ALPHA_PC164) || \
+#elif defined(CONFIG_ALPHA_PC164) || \
defined(CONFIG_ALPHA_LX164)
# define NR_IRQS 35
-#elif defined(CONFIG_ALPHA_EB66) || \
- defined(CONFIG_ALPHA_EB64P) || \
- defined(CONFIG_ALPHA_MIKASA)
+#elif defined(CONFIG_ALPHA_MIKASA)
# define NR_IRQS 32
#elif defined(CONFIG_ALPHA_ALCOR) || \
@@ -55,7 +50,6 @@
# define NR_IRQS 40
#elif defined(CONFIG_ALPHA_DP264) || \
- defined(CONFIG_ALPHA_LYNX) || \
defined(CONFIG_ALPHA_SHARK)
# define NR_IRQS 64
diff --git a/arch/alpha/include/asm/jensen.h b/arch/alpha/include/asm/jensen.h
deleted file mode 100644
index 66eb049eb421..000000000000
--- a/arch/alpha/include/asm/jensen.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ALPHA_JENSEN_H
-#define __ALPHA_JENSEN_H
-
-#include <asm/compiler.h>
-
-/*
- * Defines for the AlphaPC EISA IO and memory address space.
- */
-
-/*
- * NOTE! The memory operations do not set any memory barriers, as it's
- * not needed for cases like a frame buffer that is essentially memory-like.
- * You need to do them by hand if the operations depend on ordering.
- *
- * Similarly, the port IO operations do a "mb" only after a write operation:
- * if an mb is needed before (as in the case of doing memory mapped IO
- * first, and then a port IO operation to the same device), it needs to be
- * done by hand.
- *
- * After the above has bitten me 100 times, I'll give up and just do the
- * mb all the time, but right now I'm hoping this will work out. Avoiding
- * mb's may potentially be a noticeable speed improvement, but I can't
- * honestly say I've tested it.
- *
- * Handling interrupts that need to do mb's to synchronize to non-interrupts
- * is another fun race area. Don't do it (because if you do, I'll have to
- * do *everything* with interrupts disabled, ugh).
- */
-
-/*
- * EISA Interrupt Acknowledge address
- */
-#define EISA_INTA (IDENT_ADDR + 0x100000000UL)
-
-/*
- * FEPROM addresses
- */
-#define EISA_FEPROM0 (IDENT_ADDR + 0x180000000UL)
-#define EISA_FEPROM1 (IDENT_ADDR + 0x1A0000000UL)
-
-/*
- * VL82C106 base address
- */
-#define EISA_VL82C106 (IDENT_ADDR + 0x1C0000000UL)
-
-/*
- * EISA "Host Address Extension" address (bits 25-31 of the EISA address)
- */
-#define EISA_HAE (IDENT_ADDR + 0x1D0000000UL)
-
-/*
- * "SYSCTL" register address
- */
-#define EISA_SYSCTL (IDENT_ADDR + 0x1E0000000UL)
-
-/*
- * "spare" register address
- */
-#define EISA_SPARE (IDENT_ADDR + 0x1F0000000UL)
-
-/*
- * EISA memory address offset
- */
-#define EISA_MEM (IDENT_ADDR + 0x200000000UL)
-
-/*
- * EISA IO address offset
- */
-#define EISA_IO (IDENT_ADDR + 0x300000000UL)
-
-
-#ifdef __KERNEL__
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __IO_EXTERN_INLINE
-#endif
-
-/*
- * Handle the "host address register". This needs to be set
- * to the high 7 bits of the EISA address. This is also needed
- * for EISA IO addresses, which are only 16 bits wide (the
- * hae needs to be set to 0).
- *
- * HAE isn't needed for the local IO operations, though.
- */
-
-#define JENSEN_HAE_ADDRESS EISA_HAE
-#define JENSEN_HAE_MASK 0x1ffffff
-
-__EXTERN_INLINE void jensen_set_hae(unsigned long addr)
-{
- /* hae on the Jensen is bits 31:25 shifted right */
- addr >>= 25;
- if (addr != alpha_mv.hae_cache)
- set_hae(addr);
-}
-
-#define vuip volatile unsigned int *
-#define vulp volatile unsigned long *
-
-/*
- * IO functions
- *
- * The "local" functions are those that don't go out to the EISA bus,
- * but instead act on the VL82C106 chip directly.. This is mainly the
- * keyboard, RTC, printer and first two serial lines..
- *
- * The local stuff makes for some complications, but it seems to be
- * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
- * convinced that I need one of the newer machines.
- */
-
-__EXTERN_INLINE unsigned int jensen_local_inb(unsigned long addr)
-{
- return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
-}
-
-__EXTERN_INLINE void jensen_local_outb(u8 b, unsigned long addr)
-{
- *(vuip)((addr << 9) + EISA_VL82C106) = b;
- mb();
-}
-
-__EXTERN_INLINE unsigned int jensen_bus_inb(unsigned long addr)
-{
- long result;
-
- jensen_set_hae(0);
- result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
- return __kernel_extbl(result, addr & 3);
-}
-
-__EXTERN_INLINE void jensen_bus_outb(u8 b, unsigned long addr)
-{
- jensen_set_hae(0);
- *(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
- mb();
-}
-
-/*
- * It seems gcc is not very good at optimizing away logical
- * operations that result in operations across inline functions.
- * Which is why this is a macro.
- */
-
-#define jensen_is_local(addr) ( \
-/* keyboard */ (addr == 0x60 || addr == 0x64) || \
-/* RTC */ (addr == 0x170 || addr == 0x171) || \
-/* mb COM2 */ (addr >= 0x2f8 && addr <= 0x2ff) || \
-/* mb LPT1 */ (addr >= 0x3bc && addr <= 0x3be) || \
-/* mb COM2 */ (addr >= 0x3f8 && addr <= 0x3ff))
-
-__EXTERN_INLINE u8 jensen_inb(unsigned long addr)
-{
- if (jensen_is_local(addr))
- return jensen_local_inb(addr);
- else
- return jensen_bus_inb(addr);
-}
-
-__EXTERN_INLINE void jensen_outb(u8 b, unsigned long addr)
-{
- if (jensen_is_local(addr))
- jensen_local_outb(b, addr);
- else
- jensen_bus_outb(b, addr);
-}
-
-__EXTERN_INLINE u16 jensen_inw(unsigned long addr)
-{
- long result;
-
- jensen_set_hae(0);
- result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
- result >>= (addr & 3) * 8;
- return 0xffffUL & result;
-}
-
-__EXTERN_INLINE u32 jensen_inl(unsigned long addr)
-{
- jensen_set_hae(0);
- return *(vuip) ((addr << 7) + EISA_IO + 0x60);
-}
-
-__EXTERN_INLINE u64 jensen_inq(unsigned long addr)
-{
- jensen_set_hae(0);
- return *(vulp) ((addr << 7) + EISA_IO + 0x60);
-}
-
-__EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
-{
- jensen_set_hae(0);
- *(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
- mb();
-}
-
-__EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
-{
- jensen_set_hae(0);
- *(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
- mb();
-}
-
-__EXTERN_INLINE void jensen_outq(u64 b, unsigned long addr)
-{
- jensen_set_hae(0);
- *(vulp) ((addr << 7) + EISA_IO + 0x60) = b;
- mb();
-}
-
-/*
- * Memory functions.
- */
-
-__EXTERN_INLINE u8 jensen_readb(const volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- long result;
-
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
- result >>= (addr & 3) * 8;
- return 0xffUL & result;
-}
-
-__EXTERN_INLINE u16 jensen_readw(const volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- long result;
-
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
- result >>= (addr & 3) * 8;
- return 0xffffUL & result;
-}
-
-__EXTERN_INLINE u32 jensen_readl(const volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
-}
-
-__EXTERN_INLINE u64 jensen_readq(const volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- unsigned long r0, r1;
-
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- addr = (addr << 7) + EISA_MEM + 0x60;
- r0 = *(vuip) (addr);
- r1 = *(vuip) (addr + (4 << 7));
- return r1 << 32 | r0;
-}
-
-__EXTERN_INLINE void jensen_writeb(u8 b, volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- *(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
-}
-
-__EXTERN_INLINE void jensen_writew(u16 b, volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- *(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
-}
-
-__EXTERN_INLINE void jensen_writel(u32 b, volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- *(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
-}
-
-__EXTERN_INLINE void jensen_writeq(u64 b, volatile void __iomem *xaddr)
-{
- unsigned long addr = (unsigned long) xaddr;
- jensen_set_hae(addr);
- addr &= JENSEN_HAE_MASK;
- addr = (addr << 7) + EISA_MEM + 0x60;
- *(vuip) (addr) = b;
- *(vuip) (addr + (4 << 7)) = b >> 32;
-}
-
-__EXTERN_INLINE void __iomem *jensen_ioportmap(unsigned long addr)
-{
- return (void __iomem *)addr;
-}
-
-__EXTERN_INLINE void __iomem *jensen_ioremap(unsigned long addr,
- unsigned long size)
-{
- return (void __iomem *)(addr + 0x100000000ul);
-}
-
-__EXTERN_INLINE int jensen_is_ioaddr(unsigned long addr)
-{
- return (long)addr >= 0;
-}
-
-__EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
-{
- return (unsigned long)addr >= 0x100000000ul;
-}
-
-/* New-style ioread interface. All the routines are so ugly for Jensen
- that it doesn't make sense to merge them. */
-
-#define IOPORT(OS, NS) \
-__EXTERN_INLINE u##NS jensen_ioread##NS(const void __iomem *xaddr) \
-{ \
- if (jensen_is_mmio(xaddr)) \
- return jensen_read##OS(xaddr - 0x100000000ul); \
- else \
- return jensen_in##OS((unsigned long)xaddr); \
-} \
-__EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr) \
-{ \
- if (jensen_is_mmio(xaddr)) \
- jensen_write##OS(b, xaddr - 0x100000000ul); \
- else \
- jensen_out##OS(b, (unsigned long)xaddr); \
-}
-
-IOPORT(b, 8)
-IOPORT(w, 16)
-IOPORT(l, 32)
-IOPORT(q, 64)
-
-#undef IOPORT
-
-#undef vuip
-#undef vulp
-
-#undef __IO_PREFIX
-#define __IO_PREFIX jensen
-#define jensen_trivial_rw_bw 0
-#define jensen_trivial_rw_lq 0
-#define jensen_trivial_io_bw 0
-#define jensen_trivial_io_lq 0
-#define jensen_trivial_iounmap 1
-#include <asm/io_trivial.h>
-
-#ifdef __IO_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __IO_EXTERN_INLINE
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __ALPHA_JENSEN_H */
diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
index 8623f995d34c..490fc880bb3f 100644
--- a/arch/alpha/include/asm/machvec.h
+++ b/arch/alpha/include/asm/machvec.h
@@ -72,15 +72,6 @@ struct alpha_machine_vector
int (*mv_is_ioaddr)(unsigned long);
int (*mv_is_mmio)(const volatile void __iomem *);
- void (*mv_switch_mm)(struct mm_struct *, struct mm_struct *,
- struct task_struct *);
- void (*mv_activate_mm)(struct mm_struct *, struct mm_struct *);
-
- void (*mv_flush_tlb_current)(struct mm_struct *);
- void (*mv_flush_tlb_current_page)(struct mm_struct * mm,
- struct vm_area_struct *vma,
- unsigned long addr);
-
void (*update_irq_hw)(unsigned long, unsigned long, int);
void (*ack_irq)(unsigned long);
void (*device_interrupt)(unsigned long vector);
diff --git a/arch/alpha/include/asm/mmu_context.h b/arch/alpha/include/asm/mmu_context.h
index 29a3e3a1f02b..eee8fe836a59 100644
--- a/arch/alpha/include/asm/mmu_context.h
+++ b/arch/alpha/include/asm/mmu_context.h
@@ -71,9 +71,7 @@ __reload_thread(struct pcb_struct *pcb)
#ifdef CONFIG_ALPHA_GENERIC
# define MAX_ASN (alpha_mv.max_asn)
#else
-# ifdef CONFIG_ALPHA_EV4
-# define MAX_ASN EV4_MAX_ASN
-# elif defined(CONFIG_ALPHA_EV5)
+# if defined(CONFIG_ALPHA_EV56)
# define MAX_ASN EV5_MAX_ASN
# else
# define MAX_ASN EV6_MAX_ASN
@@ -162,26 +160,6 @@ ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
task_thread_info(next)->pcb.asn = mmc & HARDWARE_ASN_MASK;
}
-__EXTERN_INLINE void
-ev4_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
- struct task_struct *next)
-{
- /* As described, ASN's are broken for TLB usage. But we can
- optimize for switching between threads -- if the mm is
- unchanged from current we needn't flush. */
- /* ??? May not be needed because EV4 PALcode recognizes that
- ASN's are broken and does a tbiap itself on swpctx, under
- the "Must set ASN or flush" rule. At least this is true
- for a 1992 SRM, reports Joseph Martin (jmartin@hlo.dec.com).
- I'm going to leave this here anyway, just to Be Sure. -- r~ */
- if (prev_mm != next_mm)
- tbiap();
-
- /* Do continue to allocate ASNs, because we can still use them
- to avoid flushing the icache. */
- ev5_switch_mm(prev_mm, next_mm, next);
-}
-
extern void __load_new_mm_context(struct mm_struct *);
asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
long cause, struct pt_regs *regs);
@@ -209,25 +187,8 @@ ev5_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
__load_new_mm_context(next_mm);
}
-__EXTERN_INLINE void
-ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
-{
- __load_new_mm_context(next_mm);
- tbiap();
-}
-
-#ifdef CONFIG_ALPHA_GENERIC
-# define switch_mm(a,b,c) alpha_mv.mv_switch_mm((a),(b),(c))
-# define activate_mm(x,y) alpha_mv.mv_activate_mm((x),(y))
-#else
-# ifdef CONFIG_ALPHA_EV4
-# define switch_mm(a,b,c) ev4_switch_mm((a),(b),(c))
-# define activate_mm(x,y) ev4_activate_mm((x),(y))
-# else
-# define switch_mm(a,b,c) ev5_switch_mm((a),(b),(c))
-# define activate_mm(x,y) ev5_activate_mm((x),(y))
-# endif
-#endif
+#define switch_mm(a,b,c) ev5_switch_mm((a),(b),(c))
+#define activate_mm(x,y) ev5_activate_mm((x),(y))
#define init_new_context init_new_context
static inline int
diff --git a/arch/alpha/include/asm/special_insns.h b/arch/alpha/include/asm/special_insns.h
index ca2c5c30b22e..798d0bdb11f9 100644
--- a/arch/alpha/include/asm/special_insns.h
+++ b/arch/alpha/include/asm/special_insns.h
@@ -15,10 +15,7 @@ enum implver_enum {
(enum implver_enum) __implver; })
#else
/* Try to eliminate some dead code. */
-#ifdef CONFIG_ALPHA_EV4
-#define implver() IMPLVER_EV4
-#endif
-#ifdef CONFIG_ALPHA_EV5
+#ifdef CONFIG_ALPHA_EV56
#define implver() IMPLVER_EV5
#endif
#if defined(CONFIG_ALPHA_EV6)
diff --git a/arch/alpha/include/asm/tlbflush.h b/arch/alpha/include/asm/tlbflush.h
index 94dc37cf873a..ba4b359d6c39 100644
--- a/arch/alpha/include/asm/tlbflush.h
+++ b/arch/alpha/include/asm/tlbflush.h
@@ -14,16 +14,6 @@
extern void __load_new_mm_context(struct mm_struct *);
-/* Use a few helper functions to hide the ugly broken ASN
- numbers on early Alphas (ev4 and ev45). */
-
-__EXTERN_INLINE void
-ev4_flush_tlb_current(struct mm_struct *mm)
-{
- __load_new_mm_context(mm);
- tbiap();
-}
-
__EXTERN_INLINE void
ev5_flush_tlb_current(struct mm_struct *mm)
{
@@ -35,19 +25,6 @@ ev5_flush_tlb_current(struct mm_struct *mm)
specific icache page. */
__EXTERN_INLINE void
-ev4_flush_tlb_current_page(struct mm_struct * mm,
- struct vm_area_struct *vma,
- unsigned long addr)
-{
- int tbi_flag = 2;
- if (vma->vm_flags & VM_EXEC) {
- __load_new_mm_context(mm);
- tbi_flag = 3;
- }
- tbi(tbi_flag, addr);
-}
-
-__EXTERN_INLINE void
ev5_flush_tlb_current_page(struct mm_struct * mm,
struct vm_area_struct *vma,
unsigned long addr)
@@ -59,18 +36,8 @@ ev5_flush_tlb_current_page(struct mm_struct * mm,
}
-#ifdef CONFIG_ALPHA_GENERIC
-# define flush_tlb_current alpha_mv.mv_flush_tlb_current
-# define flush_tlb_current_page alpha_mv.mv_flush_tlb_current_page
-#else
-# ifdef CONFIG_ALPHA_EV4
-# define flush_tlb_current ev4_flush_tlb_current
-# define flush_tlb_current_page ev4_flush_tlb_current_page
-# else
-# define flush_tlb_current ev5_flush_tlb_current
-# define flush_tlb_current_page ev5_flush_tlb_current_page
-# endif
-#endif
+#define flush_tlb_current ev5_flush_tlb_current
+#define flush_tlb_current_page ev5_flush_tlb_current_page
#ifdef __MMU_EXTERN_INLINE
#undef __EXTERN_INLINE
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h
index c32c2584c0b7..ef295cbb797c 100644
--- a/arch/alpha/include/asm/uaccess.h
+++ b/arch/alpha/include/asm/uaccess.h
@@ -96,9 +96,6 @@ struct __large_struct { unsigned long buf[100]; };
: "=r"(__gu_val), "=r"(__gu_err) \
: "m"(__m(addr)), "1"(__gu_err))
-#ifdef __alpha_bwx__
-/* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */
-
#define __get_user_16(addr) \
__asm__("1: ldwu %0,%2\n" \
"2:\n" \
@@ -112,33 +109,6 @@ struct __large_struct { unsigned long buf[100]; };
EXC(1b,2b,%0,%1) \
: "=r"(__gu_val), "=r"(__gu_err) \
: "m"(__m(addr)), "1"(__gu_err))
-#else
-/* Unfortunately, we can't get an unaligned access trap for the sub-word
- load, so we have to do a general unaligned operation. */
-
-#define __get_user_16(addr) \
-{ \
- long __gu_tmp; \
- __asm__("1: ldq_u %0,0(%3)\n" \
- "2: ldq_u %1,1(%3)\n" \
- " extwl %0,%3,%0\n" \
- " extwh %1,%3,%1\n" \
- " or %0,%1,%0\n" \
- "3:\n" \
- EXC(1b,3b,%0,%2) \
- EXC(2b,3b,%0,%2) \
- : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \
- : "r"(addr), "2"(__gu_err)); \
-}
-
-#define __get_user_8(addr) \
- __asm__("1: ldq_u %0,0(%2)\n" \
- " extbl %0,%2,%0\n" \
- "2:\n" \
- EXC(1b,2b,%0,%1) \
- : "=&r"(__gu_val), "=r"(__gu_err) \
- : "r"(addr), "1"(__gu_err))
-#endif
extern void __put_user_unknown(void);
@@ -192,9 +162,6 @@ __asm__ __volatile__("1: stl %r2,%1\n" \
: "=r"(__pu_err) \
: "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
-#ifdef __alpha_bwx__
-/* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */
-
#define __put_user_16(x, addr) \
__asm__ __volatile__("1: stw %r2,%1\n" \
"2:\n" \
@@ -208,53 +175,6 @@ __asm__ __volatile__("1: stb %r2,%1\n" \
EXC(1b,2b,$31,%0) \
: "=r"(__pu_err) \
: "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
-#else
-/* Unfortunately, we can't get an unaligned access trap for the sub-word
- write, so we have to do a general unaligned operation. */
-
-#define __put_user_16(x, addr) \
-{ \
- long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4; \
- __asm__ __volatile__( \
- "1: ldq_u %2,1(%5)\n" \
- "2: ldq_u %1,0(%5)\n" \
- " inswh %6,%5,%4\n" \
- " inswl %6,%5,%3\n" \
- " mskwh %2,%5,%2\n" \
- " mskwl %1,%5,%1\n" \
- " or %2,%4,%2\n" \
- " or %1,%3,%1\n" \
- "3: stq_u %2,1(%5)\n" \
- "4: stq_u %1,0(%5)\n" \
- "5:\n" \
- EXC(1b,5b,$31,%0) \
- EXC(2b,5b,$31,%0) \
- EXC(3b,5b,$31,%0) \
- EXC(4b,5b,$31,%0) \
- : "=r"(__pu_err), "=&r"(__pu_tmp1), \
- "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \
- "=&r"(__pu_tmp4) \
- : "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); \
-}
-
-#define __put_user_8(x, addr) \
-{ \
- long __pu_tmp1, __pu_tmp2; \
- __asm__ __volatile__( \
- "1: ldq_u %1,0(%4)\n" \
- " insbl %3,%4,%2\n" \
- " mskbl %1,%4,%1\n" \
- " or %1,%2,%1\n" \
- "2: stq_u %1,0(%4)\n" \
- "3:\n" \
- EXC(1b,3b,$31,%0) \
- EXC(2b,3b,$31,%0) \
- : "=r"(__pu_err), \
- "=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \
- : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \
-}
-#endif
-
/*
* Complex access routines
diff --git a/arch/alpha/include/asm/vga.h b/arch/alpha/include/asm/vga.h
index 4c347a8454c7..919931cb5b63 100644
--- a/arch/alpha/include/asm/vga.h
+++ b/arch/alpha/include/asm/vga.h
@@ -13,6 +13,7 @@
#define VT_BUF_HAVE_RW
#define VT_BUF_HAVE_MEMSETW
#define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
static inline void scr_writew(u16 val, volatile u16 *addr)
{
@@ -40,6 +41,7 @@ static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
/* Do not trust that the usage will be correct; analyze the arguments. */
extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
+extern void scr_memmovew(u16 *d, const u16 *s, unsigned int count);
/* ??? These are currently only used for downloading character sets. As
such, they don't need memory barriers. Is this all they are intended
diff --git a/arch/alpha/include/uapi/asm/compiler.h b/arch/alpha/include/uapi/asm/compiler.h
index 0e00c0e13374..8c03740966b4 100644
--- a/arch/alpha/include/uapi/asm/compiler.h
+++ b/arch/alpha/include/uapi/asm/compiler.h
@@ -95,24 +95,6 @@
#define __kernel_ldwu(mem) (mem)
#define __kernel_stb(val,mem) ((mem) = (val))
#define __kernel_stw(val,mem) ((mem) = (val))
-#else
-#define __kernel_ldbu(mem) \
- ({ unsigned char __kir; \
- __asm__(".arch ev56; \
- ldbu %0,%1" : "=r"(__kir) : "m"(mem)); \
- __kir; })
-#define __kernel_ldwu(mem) \
- ({ unsigned short __kir; \
- __asm__(".arch ev56; \
- ldwu %0,%1" : "=r"(__kir) : "m"(mem)); \
- __kir; })
-#define __kernel_stb(val,mem) \
- __asm__(".arch ev56; \
- stb %1,%0" : "=m"(mem) : "r"(val))
-#define __kernel_stw(val,mem) \
- __asm__(".arch ev56; \
- stw %1,%0" : "=m"(mem) : "r"(val))
#endif
-
#endif /* _UAPI__ALPHA_COMPILER_H */
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index fb4efec7cbc7..b6c862dff1f6 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -22,14 +22,14 @@ obj-$(CONFIG_AUDIT) += audit.o
ifdef CONFIG_ALPHA_GENERIC
-obj-y += core_apecs.o core_cia.o core_irongate.o core_lca.o \
+obj-y += core_cia.o core_irongate.o \
core_mcpcia.o core_polaris.o core_t2.o \
core_tsunami.o
-obj-y += sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
- sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+obj-y += sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eiger.o \
+ sys_miata.o sys_mikasa.o sys_nautilus.o \
sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
- sys_sable.o sys_sio.o sys_sx164.o sys_takara.o
+ sys_sable.o sys_sx164.o sys_takara.o
ifndef CONFIG_ALPHA_LEGACY_START_ADDRESS
obj-y += core_marvel.o core_titan.o core_wildfire.o
@@ -48,10 +48,8 @@ else
obj-$(CONFIG_ALPHA_SRM) += srmcons.o
# Core logic support
-obj-$(CONFIG_ALPHA_APECS) += core_apecs.o
obj-$(CONFIG_ALPHA_CIA) += core_cia.o
obj-$(CONFIG_ALPHA_IRONGATE) += core_irongate.o
-obj-$(CONFIG_ALPHA_LCA) += core_lca.o
obj-$(CONFIG_ALPHA_MARVEL) += core_marvel.o gct.o
obj-$(CONFIG_ALPHA_MCPCIA) += core_mcpcia.o
obj-$(CONFIG_ALPHA_POLARIS) += core_polaris.o
@@ -62,12 +60,6 @@ obj-$(CONFIG_ALPHA_WILDFIRE) += core_wildfire.o
# Board support
obj-$(CONFIG_ALPHA_ALCOR) += sys_alcor.o irq_i8259.o irq_srm.o
-obj-$(CONFIG_ALPHA_CABRIOLET) += sys_cabriolet.o irq_i8259.o irq_srm.o \
- pc873xx.o
-obj-$(CONFIG_ALPHA_EB164) += sys_cabriolet.o irq_i8259.o irq_srm.o \
- pc873xx.o
-obj-$(CONFIG_ALPHA_EB66P) += sys_cabriolet.o irq_i8259.o irq_srm.o \
- pc873xx.o
obj-$(CONFIG_ALPHA_LX164) += sys_cabriolet.o irq_i8259.o irq_srm.o \
smc37c93x.o
obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \
@@ -75,10 +67,7 @@ obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \
obj-$(CONFIG_ALPHA_DP264) += sys_dp264.o irq_i8259.o es1888.o smc37c669.o
obj-$(CONFIG_ALPHA_SHARK) += sys_dp264.o irq_i8259.o es1888.o smc37c669.o
obj-$(CONFIG_ALPHA_TITAN) += sys_titan.o irq_i8259.o smc37c669.o
-obj-$(CONFIG_ALPHA_EB64P) += sys_eb64p.o irq_i8259.o
-obj-$(CONFIG_ALPHA_EB66) += sys_eb64p.o irq_i8259.o
obj-$(CONFIG_ALPHA_EIGER) += sys_eiger.o irq_i8259.o
-obj-$(CONFIG_ALPHA_JENSEN) += sys_jensen.o pci-noop.o irq_i8259.o
obj-$(CONFIG_ALPHA_MARVEL) += sys_marvel.o
obj-$(CONFIG_ALPHA_MIATA) += sys_miata.o irq_pyxis.o irq_i8259.o \
es1888.o smc37c669.o
@@ -89,12 +78,6 @@ obj-$(CONFIG_ALPHA_RAWHIDE) += sys_rawhide.o irq_i8259.o
obj-$(CONFIG_ALPHA_RUFFIAN) += sys_ruffian.o irq_pyxis.o irq_i8259.o
obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o irq_i8259.o
obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o
-obj-$(CONFIG_ALPHA_LYNX) += sys_sable.o
-obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
obj-$(CONFIG_ALPHA_SX164) += sys_sx164.o irq_pyxis.o irq_i8259.o \
irq_srm.o smc37c669.o
obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o pc873xx.o
diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c
index bf1eedd27cf7..4cfeae42c79a 100644
--- a/arch/alpha/kernel/asm-offsets.c
+++ b/arch/alpha/kernel/asm-offsets.c
@@ -10,35 +10,16 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/kbuild.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
static void __used foo(void)
{
- DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_FP, offsetof(struct thread_info, fp));
DEFINE(TI_STATUS, offsetof(struct thread_info, status));
BLANK();
- DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
- DEFINE(TASK_CRED, offsetof(struct task_struct, cred));
- DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
- DEFINE(TASK_GROUP_LEADER, offsetof(struct task_struct, group_leader));
- DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
- BLANK();
-
- DEFINE(CRED_UID, offsetof(struct cred, uid));
- DEFINE(CRED_EUID, offsetof(struct cred, euid));
- DEFINE(CRED_GID, offsetof(struct cred, gid));
- DEFINE(CRED_EGID, offsetof(struct cred, egid));
- BLANK();
-
DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
- DEFINE(PT_PTRACED, PT_PTRACED);
- DEFINE(CLONE_VM, CLONE_VM);
- DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
- DEFINE(SIGCHLD, SIGCHLD);
BLANK();
DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
diff --git a/arch/alpha/kernel/bugs.c b/arch/alpha/kernel/bugs.c
index 08cc10d7fa17..e8c51089325f 100644
--- a/arch/alpha/kernel/bugs.c
+++ b/arch/alpha/kernel/bugs.c
@@ -1,6 +1,7 @@
#include <asm/hwrpb.h>
#include <linux/device.h>
+#include <linux/cpu.h>
#ifdef CONFIG_SYSFS
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
index 5476279329a6..4193f76e9633 100644
--- a/arch/alpha/kernel/console.c
+++ b/arch/alpha/kernel/console.c
@@ -15,6 +15,7 @@
#include <asm/machvec.h>
#include "pci_impl.h"
+#include "proto.h"
#ifdef CONFIG_VGA_HOSE
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
deleted file mode 100644
index 6df765ff2b10..000000000000
--- a/arch/alpha/kernel/core_apecs.c
+++ /dev/null
@@ -1,420 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/alpha/kernel/core_apecs.c
- *
- * Rewritten for Apecs from the lca.c from:
- *
- * Written by David Mosberger (davidm@cs.arizona.edu) with some code
- * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
- * bios code.
- *
- * Code common to all APECS core logic chips.
- */
-
-#define __EXTERN_INLINE inline
-#include <asm/io.h>
-#include <asm/core_apecs.h>
-#undef __EXTERN_INLINE
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/ptrace.h>
-#include <asm/smp.h>
-#include <asm/mce.h>
-
-#include "proto.h"
-#include "pci_impl.h"
-
-/*
- * NOTE: Herein lie back-to-back mb instructions. They are magic.
- * One plausible explanation is that the i/o controller does not properly
- * handle the system transaction. Another involves timing. Ho hum.
- */
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#define DEBUG_CONFIG 0
-
-#if DEBUG_CONFIG
-# define DBGC(args) printk args
-#else
-# define DBGC(args)
-#endif
-
-#define vuip volatile unsigned int *
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the APECS_HAXR2 register
- * accordingly. It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
- * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * 31:11 Device select bit.
- * 10:8 Function number
- * 7:2 Register number
- *
- * Type 1:
- *
- * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
- * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * 31:24 reserved
- * 23:16 bus number (8 bits = 128 possible buses)
- * 15:11 Device number (5 bits)
- * 10:8 function number
- * 7:2 register number
- *
- * Notes:
- * The function number selects which function of a multi-function device
- * (e.g., SCSI and Ethernet).
- *
- * The register selects a DWORD (32 bit) register offset. Hence it
- * doesn't get shifted by 2 bits as we want to "drop" the bottom two
- * bits.
- */
-
-static int
-mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
- unsigned long *pci_addr, unsigned char *type1)
-{
- unsigned long addr;
- u8 bus = pbus->number;
-
- DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
- " pci_addr=0x%p, type1=0x%p)\n",
- bus, device_fn, where, pci_addr, type1));
-
- if (bus == 0) {
- int device = device_fn >> 3;
-
- /* type 0 configuration cycle: */
-
- if (device > 20) {
- DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
- device));
- return -1;
- }
-
- *type1 = 0;
- addr = (device_fn << 8) | (where);
- } else {
- /* type 1 configuration cycle: */
- *type1 = 1;
- addr = (bus << 16) | (device_fn << 8) | (where);
- }
- *pci_addr = addr;
- DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
- return 0;
-}
-
-static unsigned int
-conf_read(unsigned long addr, unsigned char type1)
-{
- unsigned long flags;
- unsigned int stat0, value;
- unsigned int haxr2 = 0;
-
- local_irq_save(flags); /* avoid getting hit by machine check */
-
- DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
-
- /* Reset status register to avoid losing errors. */
- stat0 = *(vuip)APECS_IOC_DCSR;
- *(vuip)APECS_IOC_DCSR = stat0;
- mb();
- DBGC(("conf_read: APECS DCSR was 0x%x\n", stat0));
-
- /* If Type1 access, must set HAE #2. */
- if (type1) {
- haxr2 = *(vuip)APECS_IOC_HAXR2;
- mb();
- *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
- DBGC(("conf_read: TYPE1 access\n"));
- }
-
- draina();
- mcheck_expected(0) = 1;
- mcheck_taken(0) = 0;
- mb();
-
- /* Access configuration space. */
-
- /* Some SRMs step on these registers during a machine check. */
- asm volatile("ldl %0,%1; mb; mb" : "=r"(value) : "m"(*(vuip)addr)
- : "$9", "$10", "$11", "$12", "$13", "$14", "memory");
-
- if (mcheck_taken(0)) {
- mcheck_taken(0) = 0;
- value = 0xffffffffU;
- mb();
- }
- mcheck_expected(0) = 0;
- mb();
-
-#if 1
- /*
- * david.rusling@reo.mts.dec.com. This code is needed for the
- * EB64+ as it does not generate a machine check (why I don't
- * know). When we build kernels for one particular platform
- * then we can make this conditional on the type.
- */
- draina();
-
- /* Now look for any errors. */
- stat0 = *(vuip)APECS_IOC_DCSR;
- DBGC(("conf_read: APECS DCSR after read 0x%x\n", stat0));
-
- /* Is any error bit set? */
- if (stat0 & 0xffe0U) {
- /* If not NDEV, print status. */
- if (!(stat0 & 0x0800)) {
- printk("apecs.c:conf_read: got stat0=%x\n", stat0);
- }
-
- /* Reset error status. */
- *(vuip)APECS_IOC_DCSR = stat0;
- mb();
- wrmces(0x7); /* reset machine check */
- value = 0xffffffff;
- }
-#endif
-
- /* If Type1 access, must reset HAE #2 so normal IO space ops work. */
- if (type1) {
- *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
- mb();
- }
- local_irq_restore(flags);
-
- return value;
-}
-
-static void
-conf_write(unsigned long addr, unsigned int value, unsigned char type1)
-{
- unsigned long flags;
- unsigned int stat0;
- unsigned int haxr2 = 0;
-
- local_irq_save(flags); /* avoid getting hit by machine check */
-
- /* Reset status register to avoid losing errors. */
- stat0 = *(vuip)APECS_IOC_DCSR;
- *(vuip)APECS_IOC_DCSR = stat0;
- mb();
-
- /* If Type1 access, must set HAE #2. */
- if (type1) {
- haxr2 = *(vuip)APECS_IOC_HAXR2;
- mb();
- *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
- }
-
- draina();
- mcheck_expected(0) = 1;
- mb();
-
- /* Access configuration space. */
- *(vuip)addr = value;
- mb();
- mb(); /* magic */
- mcheck_expected(0) = 0;
- mb();
-
-#if 1
- /*
- * david.rusling@reo.mts.dec.com. This code is needed for the
- * EB64+ as it does not generate a machine check (why I don't
- * know). When we build kernels for one particular platform
- * then we can make this conditional on the type.
- */
- draina();
-
- /* Now look for any errors. */
- stat0 = *(vuip)APECS_IOC_DCSR;
-
- /* Is any error bit set? */
- if (stat0 & 0xffe0U) {
- /* If not NDEV, print status. */
- if (!(stat0 & 0x0800)) {
- printk("apecs.c:conf_write: got stat0=%x\n", stat0);
- }
-
- /* Reset error status. */
- *(vuip)APECS_IOC_DCSR = stat0;
- mb();
- wrmces(0x7); /* reset machine check */
- }
-#endif
-
- /* If Type1 access, must reset HAE #2 so normal IO space ops work. */
- if (type1) {
- *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
- mb();
- }
- local_irq_restore(flags);
-}
-
-static int
-apecs_read_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *value)
-{
- unsigned long addr, pci_addr;
- unsigned char type1;
- long mask;
- int shift;
-
- if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- mask = (size - 1) * 8;
- shift = (where & 3) * 8;
- addr = (pci_addr << 5) + mask + APECS_CONF;
- *value = conf_read(addr, type1) >> (shift);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-apecs_write_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 value)
-{
- unsigned long addr, pci_addr;
- unsigned char type1;
- long mask;
-
- if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- mask = (size - 1) * 8;
- addr = (pci_addr << 5) + mask + APECS_CONF;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops apecs_pci_ops =
-{
- .read = apecs_read_config,
- .write = apecs_write_config,
-};
-
-void
-apecs_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
-{
- wmb();
- *(vip)APECS_IOC_TBIA = 0;
- mb();
-}
-
-void __init
-apecs_init_arch(void)
-{
- struct pci_controller *hose;
-
- /*
- * Create our single hose.
- */
-
- pci_isa_hose = hose = alloc_pci_controller();
- hose->io_space = &ioport_resource;
- hose->mem_space = &iomem_resource;
- hose->index = 0;
-
- hose->sparse_mem_base = APECS_SPARSE_MEM - IDENT_ADDR;
- hose->dense_mem_base = APECS_DENSE_MEM - IDENT_ADDR;
- hose->sparse_io_base = APECS_IO - IDENT_ADDR;
- hose->dense_io_base = 0;
-
- /*
- * Set up the PCI to main memory translation windows.
- *
- * Window 1 is direct access 1GB at 1GB
- * Window 2 is scatter-gather 8MB at 8MB (for isa)
- */
- hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
- SMP_CACHE_BYTES);
- hose->sg_pci = NULL;
- __direct_map_base = 0x40000000;
- __direct_map_size = 0x40000000;
-
- *(vuip)APECS_IOC_PB1R = __direct_map_base | 0x00080000;
- *(vuip)APECS_IOC_PM1R = (__direct_map_size - 1) & 0xfff00000U;
- *(vuip)APECS_IOC_TB1R = 0;
-
- *(vuip)APECS_IOC_PB2R = hose->sg_isa->dma_base | 0x000c0000;
- *(vuip)APECS_IOC_PM2R = (hose->sg_isa->size - 1) & 0xfff00000;
- *(vuip)APECS_IOC_TB2R = virt_to_phys(hose->sg_isa->ptes) >> 1;
-
- apecs_pci_tbi(hose, 0, -1);
-
- /*
- * Finally, clear the HAXR2 register, which gets used
- * for PCI Config Space accesses. That is the way
- * we want to use it, and we do not want to depend on
- * what ARC or SRM might have left behind...
- */
- *(vuip)APECS_IOC_HAXR2 = 0;
- mb();
-}
-
-void
-apecs_pci_clr_err(void)
-{
- unsigned int jd;
-
- jd = *(vuip)APECS_IOC_DCSR;
- if (jd & 0xffe0L) {
- *(vuip)APECS_IOC_SEAR;
- *(vuip)APECS_IOC_DCSR = jd | 0xffe1L;
- mb();
- *(vuip)APECS_IOC_DCSR;
- }
- *(vuip)APECS_IOC_TBIA = (unsigned int)APECS_IOC_TBIA;
- mb();
- *(vuip)APECS_IOC_TBIA;
-}
-
-void
-apecs_machine_check(unsigned long vector, unsigned long la_ptr)
-{
- struct el_common *mchk_header;
- struct el_apecs_procdata *mchk_procdata;
- struct el_apecs_sysdata_mcheck *mchk_sysdata;
-
- mchk_header = (struct el_common *)la_ptr;
-
- mchk_procdata = (struct el_apecs_procdata *)
- (la_ptr + mchk_header->proc_offset
- - sizeof(mchk_procdata->paltemp));
-
- mchk_sysdata = (struct el_apecs_sysdata_mcheck *)
- (la_ptr + mchk_header->sys_offset);
-
-
- /* Clear the error before any reporting. */
- mb();
- mb(); /* magic */
- draina();
- apecs_pci_clr_err();
- wrmces(0x7); /* reset machine check pending flag */
- mb();
-
- process_mcheck_info(vector, la_ptr, "APECS",
- (mcheck_expected(0)
- && (mchk_sysdata->epic_dcsr & 0x0c00UL)));
-}
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 12926e9538b8..ca3d9c732b61 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -280,7 +280,7 @@ cia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
#define CIA_BROKEN_TBIA_SIZE 1024
/* Always called with interrupts disabled */
-void
+static void
cia_pci_tbi_try2(struct pci_controller *hose,
dma_addr_t start, dma_addr_t end)
{
@@ -576,7 +576,7 @@ struct
} window[4];
} saved_config __attribute((common));
-void
+static void
cia_save_srm_settings(int is_pyxis)
{
int i;
@@ -602,7 +602,7 @@ cia_save_srm_settings(int is_pyxis)
mb();
}
-void
+static void
cia_restore_srm_settings(void)
{
int i;
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
index 6b8ed12936b6..05dc4c1b9074 100644
--- a/arch/alpha/kernel/core_irongate.c
+++ b/arch/alpha/kernel/core_irongate.c
@@ -226,7 +226,6 @@ albacore_init_arch(void)
if (memtop > pci_mem) {
#ifdef CONFIG_BLK_DEV_INITRD
extern unsigned long initrd_start, initrd_end;
- extern void *move_initrd(unsigned long);
/* Move the initrd out of the way. */
if (initrd_end && __pa(initrd_end) > pci_mem) {
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
deleted file mode 100644
index 57e0750419f2..000000000000
--- a/arch/alpha/kernel/core_lca.c
+++ /dev/null
@@ -1,517 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/alpha/kernel/core_lca.c
- *
- * Written by David Mosberger (davidm@cs.arizona.edu) with some code
- * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
- * bios code.
- *
- * Code common to all LCA core logic chips.
- */
-
-#define __EXTERN_INLINE inline
-#include <asm/io.h>
-#include <asm/core_lca.h>
-#undef __EXTERN_INLINE
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-
-#include <asm/ptrace.h>
-#include <asm/irq_regs.h>
-#include <asm/smp.h>
-
-#include "proto.h"
-#include "pci_impl.h"
-
-
-/*
- * BIOS32-style PCI interface:
- */
-
-/*
- * Machine check reasons. Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR 0x0080
-#define MCHK_K_TCPERR 0x0082
-#define MCHK_K_HERR 0x0084
-#define MCHK_K_ECC_C 0x0086
-#define MCHK_K_ECC_NC 0x0088
-#define MCHK_K_UNKNOWN 0x008A
-#define MCHK_K_CACKSOFT 0x008C
-#define MCHK_K_BUGCHECK 0x008E
-#define MCHK_K_OS_BUGCHECK 0x0090
-#define MCHK_K_DCPERR 0x0092
-#define MCHK_K_ICPERR 0x0094
-
-
-/*
- * Platform-specific machine-check reasons:
- */
-#define MCHK_K_SIO_SERR 0x204 /* all platforms so far */
-#define MCHK_K_SIO_IOCHK 0x206 /* all platforms so far */
-#define MCHK_K_DCSR 0x208 /* all but Noname */
-
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the LCA_IOC_CONF register
- * accordingly. It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
- * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * 31:11 Device select bit.
- * 10:8 Function number
- * 7:2 Register number
- *
- * Type 1:
- *
- * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
- * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * 31:24 reserved
- * 23:16 bus number (8 bits = 128 possible buses)
- * 15:11 Device number (5 bits)
- * 10:8 function number
- * 7:2 register number
- *
- * Notes:
- * The function number selects which function of a multi-function device
- * (e.g., SCSI and Ethernet).
- *
- * The register selects a DWORD (32 bit) register offset. Hence it
- * doesn't get shifted by 2 bits as we want to "drop" the bottom two
- * bits.
- */
-
-static int
-mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
- unsigned long *pci_addr)
-{
- unsigned long addr;
- u8 bus = pbus->number;
-
- if (bus == 0) {
- int device = device_fn >> 3;
- int func = device_fn & 0x7;
-
- /* Type 0 configuration cycle. */
-
- if (device > 12) {
- return -1;
- }
-
- *(vulp)LCA_IOC_CONF = 0;
- addr = (1 << (11 + device)) | (func << 8) | where;
- } else {
- /* Type 1 configuration cycle. */
- *(vulp)LCA_IOC_CONF = 1;
- addr = (bus << 16) | (device_fn << 8) | where;
- }
- *pci_addr = addr;
- return 0;
-}
-
-static unsigned int
-conf_read(unsigned long addr)
-{
- unsigned long flags, code, stat0;
- unsigned int value;
-
- local_irq_save(flags);
-
- /* Reset status register to avoid losing errors. */
- stat0 = *(vulp)LCA_IOC_STAT0;
- *(vulp)LCA_IOC_STAT0 = stat0;
- mb();
-
- /* Access configuration space. */
- value = *(vuip)addr;
- draina();
-
- stat0 = *(vulp)LCA_IOC_STAT0;
- if (stat0 & LCA_IOC_STAT0_ERR) {
- code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
- & LCA_IOC_STAT0_CODE_MASK);
- if (code != 1) {
- printk("lca.c:conf_read: got stat0=%lx\n", stat0);
- }
-
- /* Reset error status. */
- *(vulp)LCA_IOC_STAT0 = stat0;
- mb();
-
- /* Reset machine check. */
- wrmces(0x7);
-
- value = 0xffffffff;
- }
- local_irq_restore(flags);
- return value;
-}
-
-static void
-conf_write(unsigned long addr, unsigned int value)
-{
- unsigned long flags, code, stat0;
-
- local_irq_save(flags); /* avoid getting hit by machine check */
-
- /* Reset status register to avoid losing errors. */
- stat0 = *(vulp)LCA_IOC_STAT0;
- *(vulp)LCA_IOC_STAT0 = stat0;
- mb();
-
- /* Access configuration space. */
- *(vuip)addr = value;
- draina();
-
- stat0 = *(vulp)LCA_IOC_STAT0;
- if (stat0 & LCA_IOC_STAT0_ERR) {
- code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
- & LCA_IOC_STAT0_CODE_MASK);
- if (code != 1) {
- printk("lca.c:conf_write: got stat0=%lx\n", stat0);
- }
-
- /* Reset error status. */
- *(vulp)LCA_IOC_STAT0 = stat0;
- mb();
-
- /* Reset machine check. */
- wrmces(0x7);
- }
- local_irq_restore(flags);
-}
-
-static int
-lca_read_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *value)
-{
- unsigned long addr, pci_addr;
- long mask;
- int shift;
-
- if (mk_conf_addr(bus, devfn, where, &pci_addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- shift = (where & 3) * 8;
- mask = (size - 1) * 8;
- addr = (pci_addr << 5) + mask + LCA_CONF;
- *value = conf_read(addr) >> (shift);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-lca_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
- u32 value)
-{
- unsigned long addr, pci_addr;
- long mask;
-
- if (mk_conf_addr(bus, devfn, where, &pci_addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- mask = (size - 1) * 8;
- addr = (pci_addr << 5) + mask + LCA_CONF;
- conf_write(addr, value << ((where & 3) * 8));
- return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops lca_pci_ops =
-{
- .read = lca_read_config,
- .write = lca_write_config,
-};
-
-void
-lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
-{
- wmb();
- *(vulp)LCA_IOC_TBIA = 0;
- mb();
-}
-
-void __init
-lca_init_arch(void)
-{
- struct pci_controller *hose;
-
- /*
- * Create our single hose.
- */
-
- pci_isa_hose = hose = alloc_pci_controller();
- hose->io_space = &ioport_resource;
- hose->mem_space = &iomem_resource;
- hose->index = 0;
-
- hose->sparse_mem_base = LCA_SPARSE_MEM - IDENT_ADDR;
- hose->dense_mem_base = LCA_DENSE_MEM - IDENT_ADDR;
- hose->sparse_io_base = LCA_IO - IDENT_ADDR;
- hose->dense_io_base = 0;
-
- /*
- * Set up the PCI to main memory translation windows.
- *
- * Mimic the SRM settings for the direct-map window.
- * Window 0 is scatter-gather 8MB at 8MB (for isa).
- * Window 1 is direct access 1GB at 1GB.
- *
- * Note that we do not try to save any of the DMA window CSRs
- * before setting them, since we cannot read those CSRs on LCA.
- */
- hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
- SMP_CACHE_BYTES);
- hose->sg_pci = NULL;
- __direct_map_base = 0x40000000;
- __direct_map_size = 0x40000000;
-
- *(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32);
- *(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000;
- *(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes);
-
- *(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32);
- *(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000;
- *(vulp)LCA_IOC_T_BASE1 = 0;
-
- *(vulp)LCA_IOC_TB_ENA = 0x80;
-
- lca_pci_tbi(hose, 0, -1);
-
- /*
- * Disable PCI parity for now. The NCR53c810 chip has
- * troubles meeting the PCI spec which results in
- * data parity errors.
- */
- *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
-
- /*
- * Finally, set up for restoring the correct HAE if using SRM.
- * Again, since we cannot read many of the CSRs on the LCA,
- * one of which happens to be the HAE, we save the value that
- * the SRM will expect...
- */
- if (alpha_using_srm)
- srm_hae = 0x80000000UL;
-}
-
-/*
- * Constants used during machine-check handling. I suppose these
- * could be moved into lca.h but I don't see much reason why anybody
- * else would want to use them.
- */
-
-#define ESR_EAV (1UL<< 0) /* error address valid */
-#define ESR_CEE (1UL<< 1) /* correctable error */
-#define ESR_UEE (1UL<< 2) /* uncorrectable error */
-#define ESR_WRE (1UL<< 3) /* write-error */
-#define ESR_SOR (1UL<< 4) /* error source */
-#define ESR_CTE (1UL<< 7) /* cache-tag error */
-#define ESR_MSE (1UL<< 9) /* multiple soft errors */
-#define ESR_MHE (1UL<<10) /* multiple hard errors */
-#define ESR_NXM (1UL<<12) /* non-existent memory */
-
-#define IOC_ERR ( 1<<4) /* ioc logs an error */
-#define IOC_CMD_SHIFT 0
-#define IOC_CMD (0xf<<IOC_CMD_SHIFT)
-#define IOC_CODE_SHIFT 8
-#define IOC_CODE (0xf<<IOC_CODE_SHIFT)
-#define IOC_LOST ( 1<<5)
-#define IOC_P_NBR ((__u32) ~((1<<13) - 1))
-
-static void
-mem_error(unsigned long esr, unsigned long ear)
-{
- printk(" %s %s error to %s occurred at address %x\n",
- ((esr & ESR_CEE) ? "Correctable" :
- (esr & ESR_UEE) ? "Uncorrectable" : "A"),
- (esr & ESR_WRE) ? "write" : "read",
- (esr & ESR_SOR) ? "memory" : "b-cache",
- (unsigned) (ear & 0x1ffffff8));
- if (esr & ESR_CTE) {
- printk(" A b-cache tag parity error was detected.\n");
- }
- if (esr & ESR_MSE) {
- printk(" Several other correctable errors occurred.\n");
- }
- if (esr & ESR_MHE) {
- printk(" Several other uncorrectable errors occurred.\n");
- }
- if (esr & ESR_NXM) {
- printk(" Attempted to access non-existent memory.\n");
- }
-}
-
-static void
-ioc_error(__u32 stat0, __u32 stat1)
-{
- static const char * const pci_cmd[] = {
- "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
- "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3",
- "Rsvd4", "Configuration Read", "Configuration Write",
- "Memory Read Multiple", "Dual Address", "Memory Read Line",
- "Memory Write and Invalidate"
- };
- static const char * const err_name[] = {
- "exceeded retry limit", "no device", "bad data parity",
- "target abort", "bad address parity", "page table read error",
- "invalid page", "data error"
- };
- unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
- unsigned cmd = (stat0 & IOC_CMD) >> IOC_CMD_SHIFT;
-
- printk(" %s initiated PCI %s cycle to address %x"
- " failed due to %s.\n",
- code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
-
- if (code == 5 || code == 6) {
- printk(" (Error occurred at PCI memory address %x.)\n",
- (stat0 & ~IOC_P_NBR));
- }
- if (stat0 & IOC_LOST) {
- printk(" Other PCI errors occurred simultaneously.\n");
- }
-}
-
-void
-lca_machine_check(unsigned long vector, unsigned long la_ptr)
-{
- const char * reason;
- union el_lca el;
-
- el.c = (struct el_common *) la_ptr;
-
- wrmces(rdmces()); /* reset machine check pending flag */
-
- printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n",
- vector, get_irq_regs()->pc, (unsigned int) el.c->code);
-
- /*
- * The first quadword after the common header always seems to
- * be the machine check reason---don't know why this isn't
- * part of the common header instead. In the case of a long
- * logout frame, the upper 32 bits is the machine check
- * revision level, which we ignore for now.
- */
- switch ((unsigned int) el.c->code) {
- case MCHK_K_TPERR: reason = "tag parity error"; break;
- case MCHK_K_TCPERR: reason = "tag control parity error"; break;
- case MCHK_K_HERR: reason = "access to non-existent memory"; break;
- case MCHK_K_ECC_C: reason = "correctable ECC error"; break;
- case MCHK_K_ECC_NC: reason = "non-correctable ECC error"; break;
- case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break;
- case MCHK_K_BUGCHECK: reason = "illegal exception in PAL mode"; break;
- case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
- case MCHK_K_DCPERR: reason = "d-cache parity error"; break;
- case MCHK_K_ICPERR: reason = "i-cache parity error"; break;
- case MCHK_K_SIO_SERR: reason = "SIO SERR occurred on PCI bus"; break;
- case MCHK_K_SIO_IOCHK: reason = "SIO IOCHK occurred on ISA bus"; break;
- case MCHK_K_DCSR: reason = "MCHK_K_DCSR"; break;
- case MCHK_K_UNKNOWN:
- default: reason = "unknown"; break;
- }
-
- switch (el.c->size) {
- case sizeof(struct el_lca_mcheck_short):
- printk(KERN_CRIT
- " Reason: %s (short frame%s, dc_stat=%#lx):\n",
- reason, el.c->retry ? ", retryable" : "",
- el.s->dc_stat);
- if (el.s->esr & ESR_EAV) {
- mem_error(el.s->esr, el.s->ear);
- }
- if (el.s->ioc_stat0 & IOC_ERR) {
- ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
- }
- break;
-
- case sizeof(struct el_lca_mcheck_long):
- printk(KERN_CRIT " Reason: %s (long frame%s):\n",
- reason, el.c->retry ? ", retryable" : "");
- printk(KERN_CRIT
- " reason: %#lx exc_addr: %#lx dc_stat: %#lx\n",
- el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
- printk(KERN_CRIT " car: %#lx\n", el.l->car);
- if (el.l->esr & ESR_EAV) {
- mem_error(el.l->esr, el.l->ear);
- }
- if (el.l->ioc_stat0 & IOC_ERR) {
- ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
- }
- break;
-
- default:
- printk(KERN_CRIT " Unknown errorlog size %d\n", el.c->size);
- }
-
- /* Dump the logout area to give all info. */
-#ifdef CONFIG_VERBOSE_MCHECK
- if (alpha_verbose_mcheck > 1) {
- unsigned long * ptr = (unsigned long *) la_ptr;
- long i;
- for (i = 0; i < el.c->size / sizeof(long); i += 2) {
- printk(KERN_CRIT " +%8lx %016lx %016lx\n",
- i*sizeof(long), ptr[i], ptr[i+1]);
- }
- }
-#endif /* CONFIG_VERBOSE_MCHECK */
-}
-
-/*
- * The following routines are needed to support the SPEED changing
- * necessary to successfully manage the thermal problem on the AlphaBook1.
- */
-
-void
-lca_clock_print(void)
-{
- long pmr_reg;
-
- pmr_reg = LCA_READ_PMR;
-
- printk("Status of clock control:\n");
- printk("\tPrimary clock divisor\t0x%lx\n", LCA_GET_PRIMARY(pmr_reg));
- printk("\tOverride clock divisor\t0x%lx\n", LCA_GET_OVERRIDE(pmr_reg));
- printk("\tInterrupt override is %s\n",
- (pmr_reg & LCA_PMR_INTO) ? "on" : "off");
- printk("\tDMA override is %s\n",
- (pmr_reg & LCA_PMR_DMAO) ? "on" : "off");
-
-}
-
-int
-lca_get_clock(void)
-{
- long pmr_reg;
-
- pmr_reg = LCA_READ_PMR;
- return(LCA_GET_PRIMARY(pmr_reg));
-
-}
-
-void
-lca_clock_fiddle(int divisor)
-{
- long pmr_reg;
-
- pmr_reg = LCA_READ_PMR;
- LCA_SET_PRIMARY_CLOCK(pmr_reg, divisor);
- /* lca_norm_clock = divisor; */
- LCA_WRITE_PMR(pmr_reg);
- mb();
-}
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index e9348aec4649..b22248044bf0 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -355,7 +355,7 @@ marvel_init_io7(struct io7 *io7)
}
}
-void __init
+static void __init
marvel_io7_present(gct6_node *node)
{
int pe;
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
index 98d5b6ff8a76..3d72d90624f1 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -10,7 +10,7 @@
* Code common to all T2 core logic chips.
*/
-#define __EXTERN_INLINE
+#define __EXTERN_INLINE inline
#include <asm/io.h>
#include <asm/core_t2.h>
#undef __EXTERN_INLINE
diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c
index 3a804b67f9da..8dd08c5e4270 100644
--- a/arch/alpha/kernel/core_wildfire.c
+++ b/arch/alpha/kernel/core_wildfire.c
@@ -59,7 +59,7 @@ unsigned long wildfire_pca_mask;
unsigned long wildfire_cpu_mask;
unsigned long wildfire_mem_mask;
-void __init
+static void __init
wildfire_init_hose(int qbbno, int hoseno)
{
struct pci_controller *hose;
@@ -137,7 +137,7 @@ wildfire_init_hose(int qbbno, int hoseno)
wildfire_pci_tbi(hose, 0, 0); /* Flush TLB at the end. */
}
-void __init
+static void __init
wildfire_init_pca(int qbbno, int pcano)
{
@@ -154,7 +154,7 @@ wildfire_init_pca(int qbbno, int pcano)
wildfire_init_hose(qbbno, (pcano << 1) + 1);
}
-void __init
+static void __init
wildfire_init_qbb(int qbbno)
{
int pcano;
@@ -176,7 +176,7 @@ wildfire_init_qbb(int qbbno)
}
}
-void __init
+static void __init
wildfire_hardware_probe(void)
{
unsigned long temp;
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index eb51f93a70c8..dd26062d75b3 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -811,6 +811,7 @@ alpha_\name:
fork_like fork
fork_like vfork
fork_like clone
+fork_like clone3
.macro sigreturn_like name
.align 4
diff --git a/arch/alpha/kernel/io.c b/arch/alpha/kernel/io.c
index eda09778268f..c28035d6d1e6 100644
--- a/arch/alpha/kernel/io.c
+++ b/arch/alpha/kernel/io.c
@@ -647,6 +647,10 @@ void _memset_c_io(volatile void __iomem *to, unsigned long c, long count)
EXPORT_SYMBOL(_memset_c_io);
+#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE)
+
+#include <asm/vga.h>
+
/* A version of memcpy used by the vga console routines to move data around
arbitrarily between screen and main memory. */
@@ -681,6 +685,21 @@ scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
EXPORT_SYMBOL(scr_memcpyw);
+void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
+{
+ if (d < s)
+ scr_memcpyw(d, s, count);
+ else {
+ count /= 2;
+ d += count;
+ s += count;
+ while (count--)
+ scr_writew(scr_readw(--s), --d);
+ }
+}
+EXPORT_SYMBOL(scr_memmovew);
+#endif
+
void __iomem *ioport_map(unsigned long port, unsigned int size)
{
return IO_CONCAT(__IO_PREFIX,ioportmap) (port);
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 15f2effd6baf..c67047c5d830 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -28,6 +28,7 @@
#include <asm/io.h>
#include <linux/uaccess.h>
+#include "irq_impl.h"
volatile unsigned long irq_err_count;
DEFINE_PER_CPU(unsigned long, irq_pmi_count);
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index 1dcf0d9038fd..29c6c477ac35 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -98,10 +98,6 @@ init_i8259a_irqs(void)
#if defined(CONFIG_ALPHA_GENERIC)
# define IACK_SC alpha_mv.iack_sc
-#elif defined(CONFIG_ALPHA_APECS)
-# define IACK_SC APECS_IACK_SC
-#elif defined(CONFIG_ALPHA_LCA)
-# define IACK_SC LCA_IACK_SC
#elif defined(CONFIG_ALPHA_CIA)
# define IACK_SC CIA_IACK_SC
#elif defined(CONFIG_ALPHA_PYXIS)
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index c2ebcb39e589..129ae36b8e6d 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -44,33 +44,14 @@
#define DO_DEFAULT_RTC .rtc_port = 0x70
-#define DO_EV4_MMU \
- .max_asn = EV4_MAX_ASN, \
- .mv_switch_mm = ev4_switch_mm, \
- .mv_activate_mm = ev4_activate_mm, \
- .mv_flush_tlb_current = ev4_flush_tlb_current, \
- .mv_flush_tlb_current_page = ev4_flush_tlb_current_page
-
#define DO_EV5_MMU \
- .max_asn = EV5_MAX_ASN, \
- .mv_switch_mm = ev5_switch_mm, \
- .mv_activate_mm = ev5_activate_mm, \
- .mv_flush_tlb_current = ev5_flush_tlb_current, \
- .mv_flush_tlb_current_page = ev5_flush_tlb_current_page
+ .max_asn = EV5_MAX_ASN \
#define DO_EV6_MMU \
- .max_asn = EV6_MAX_ASN, \
- .mv_switch_mm = ev5_switch_mm, \
- .mv_activate_mm = ev5_activate_mm, \
- .mv_flush_tlb_current = ev5_flush_tlb_current, \
- .mv_flush_tlb_current_page = ev5_flush_tlb_current_page
+ .max_asn = EV6_MAX_ASN \
#define DO_EV7_MMU \
- .max_asn = EV6_MAX_ASN, \
- .mv_switch_mm = ev5_switch_mm, \
- .mv_activate_mm = ev5_activate_mm, \
- .mv_flush_tlb_current = ev5_flush_tlb_current, \
- .mv_flush_tlb_current_page = ev5_flush_tlb_current_page
+ .max_asn = EV6_MAX_ASN \
#define IO_LITE(UP,low) \
.hae_register = (unsigned long *) CAT(UP,_HAE_ADDRESS), \
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 5db88b627439..e5f881bc8288 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1218,14 +1218,11 @@ static unsigned long
arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
unsigned long limit)
{
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
- info.flags = 0;
info.length = len;
info.low_limit = addr;
info.high_limit = limit;
- info.align_mask = 0;
- info.align_offset = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
deleted file mode 100644
index ae82061edae9..000000000000
--- a/arch/alpha/kernel/pci-noop.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/alpha/kernel/pci-noop.c
- *
- * Stub PCI interfaces for Jensen-specific kernels.
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/gfp.h>
-#include <linux/capability.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/syscalls.h>
-
-#include "proto.h"
-
-
-/*
- * The PCI controller list.
- */
-
-struct pci_controller *hose_head, **hose_tail = &hose_head;
-struct pci_controller *pci_isa_hose;
-
-
-struct pci_controller * __init
-alloc_pci_controller(void)
-{
- struct pci_controller *hose;
-
- hose = memblock_alloc(sizeof(*hose), SMP_CACHE_BYTES);
- if (!hose)
- panic("%s: Failed to allocate %zu bytes\n", __func__,
- sizeof(*hose));
-
- *hose_tail = hose;
- hose_tail = &hose->next;
-
- return hose;
-}
-
-struct resource * __init
-alloc_resource(void)
-{
- void *ptr = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
-
- if (!ptr)
- panic("%s: Failed to allocate %zu bytes\n", __func__,
- sizeof(struct resource));
-
- return ptr;
-}
-
-SYSCALL_DEFINE3(pciconfig_iobase, long, which, unsigned long, bus,
- unsigned long, dfn)
-{
- struct pci_controller *hose;
-
- /* from hose or from bus.devfn */
- if (which & IOBASE_FROM_HOSE) {
- for (hose = hose_head; hose; hose = hose->next)
- if (hose->index == bus)
- break;
- if (!hose)
- return -ENODEV;
- } else {
- /* Special hook for ISA access. */
- if (bus == 0 && dfn == 0)
- hose = pci_isa_hose;
- else
- return -ENODEV;
- }
-
- switch (which & ~IOBASE_FROM_HOSE) {
- case IOBASE_HOSE:
- return hose->index;
- case IOBASE_SPARSE_MEM:
- return hose->sparse_mem_base;
- case IOBASE_DENSE_MEM:
- return hose->dense_mem_base;
- case IOBASE_SPARSE_IO:
- return hose->sparse_io_base;
- case IOBASE_DENSE_IO:
- return hose->dense_io_base;
- case IOBASE_ROOT_BUS:
- return hose->bus->number;
- }
-
- return -EOPNOTSUPP;
-}
-
-SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
- unsigned long, off, unsigned long, len, void __user *, buf)
-{
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- else
- return -ENODEV;
-}
-
-SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
- unsigned long, off, unsigned long, len, void __user *, buf)
-{
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- else
- return -ENODEV;
-}
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index 18043af45e2b..a16325ce21c4 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -143,9 +143,7 @@ struct pci_iommu_arena
unsigned int align_entry;
};
-#if defined(CONFIG_ALPHA_SRM) && \
- (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA) || \
- defined(CONFIG_ALPHA_AVANTI))
+#if defined(CONFIG_ALPHA_SRM) && defined(CONFIG_ALPHA_CIA)
# define NEED_SRM_SAVE_RESTORE
#else
# undef NEED_SRM_SAVE_RESTORE
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index c81183935e97..7fcf3e9b7103 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -929,7 +929,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,
+ .alloc_pages_op = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
};
EXPORT_SYMBOL(alpha_pci_ops);
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c
index ccdb508c1516..1f0eb4f25c0f 100644
--- a/arch/alpha/kernel/perf_event.c
+++ b/arch/alpha/kernel/perf_event.c
@@ -870,7 +870,7 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,
/*
* Init call to initialise performance events at kernel startup.
*/
-int __init init_hw_perf_events(void)
+static int __init init_hw_perf_events(void)
{
pr_info("Performance events: ");
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 2c89c1c55712..a8bc3ead776b 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -15,13 +15,7 @@ struct pt_regs;
struct task_struct;
struct pci_dev;
struct pci_controller;
-
-/* core_apecs.c */
-extern struct pci_ops apecs_pci_ops;
-extern void apecs_init_arch(void);
-extern void apecs_pci_clr_err(void);
-extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr);
-extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
+struct pci_bus;
/* core_cia.c */
extern struct pci_ops cia_pci_ops;
@@ -38,12 +32,6 @@ extern int irongate_pci_clr_err(void);
extern void irongate_init_arch(void);
#define irongate_pci_tbi ((void *)0)
-/* core_lca.c */
-extern struct pci_ops lca_pci_ops;
-extern void lca_init_arch(void);
-extern void lca_machine_check(unsigned long vector, unsigned long la_ptr);
-extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
-
/* core_marvel.c */
extern struct pci_ops marvel_pci_ops;
extern void marvel_init_arch(void);
@@ -114,6 +102,9 @@ extern int boot_cpuid;
#ifdef CONFIG_VERBOSE_MCHECK
extern unsigned long alpha_verbose_mcheck;
#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+extern void * __init move_initrd(unsigned long);
+#endif
extern struct screen_info vgacon_screen_info;
/* srmcons.c */
@@ -128,6 +119,7 @@ extern void unregister_srm_console(void);
/* smp.c */
extern void setup_smp(void);
extern void handle_ipi(struct pt_regs *);
+extern void __init smp_callin(void);
/* bios32.c */
/* extern void reset_for_srm(void); */
@@ -139,13 +131,13 @@ extern void common_init_rtc(void);
extern unsigned long est_cycle_freq;
/* smc37c93x.c */
-extern void SMC93x_Init(void);
+extern int __init SMC93x_Init(void);
/* smc37c669.c */
-extern void SMC669_Init(int);
+extern void __init SMC669_Init(int);
/* es1888.c */
-extern void es1888_init(void);
+extern void __init es1888_init(void);
/* ../lib/fpreg.c */
extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
@@ -166,19 +158,37 @@ extern void entSys(void);
extern void entUna(void);
extern void entDbg(void);
+/* pci.c */
+extern void pcibios_claim_one_bus(struct pci_bus *);
+
/* ptrace.c */
extern int ptrace_set_bpt (struct task_struct *child);
extern int ptrace_cancel_bpt (struct task_struct *child);
+extern void syscall_trace_leave(void);
+extern unsigned long syscall_trace_enter(void);
+
+/* signal.c */
+struct sigcontext;
+extern void do_sigreturn(struct sigcontext __user *);
+struct rt_sigframe;
+extern void do_rt_sigreturn(struct rt_sigframe __user *);
+extern void do_work_pending(struct pt_regs *, unsigned long, unsigned long, unsigned long);
/* traps.c */
extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15);
extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *);
+extern void do_entInt(unsigned long, unsigned long, unsigned long, struct pt_regs *);
+extern void do_entArith(unsigned long, unsigned long, struct pt_regs *);
+extern void do_entIF(unsigned long, struct pt_regs *);
+extern void do_entDbg(struct pt_regs *);
+struct allregs;
+extern void do_entUna(void *, unsigned long, unsigned long, struct allregs *);
+extern void do_entUnaUser(void __user *, unsigned long, unsigned long, struct pt_regs *);
/* sys_titan.c */
extern void titan_dispatch_irqs(u64);
/* ../mm/init.c */
-extern void switch_to_system_map(void);
extern void srm_paging_stop(void);
static inline int
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 0738f9396f95..bebdffafaee8 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -171,35 +171,22 @@ EXPORT_SYMBOL(__direct_map_size);
asm(".weak "#X)
WEAK(alcor_mv);
-WEAK(alphabook1_mv);
-WEAK(avanti_mv);
-WEAK(cabriolet_mv);
WEAK(clipper_mv);
WEAK(dp264_mv);
WEAK(eb164_mv);
-WEAK(eb64p_mv);
-WEAK(eb66_mv);
-WEAK(eb66p_mv);
WEAK(eiger_mv);
-WEAK(jensen_mv);
WEAK(lx164_mv);
-WEAK(lynx_mv);
WEAK(marvel_ev7_mv);
WEAK(miata_mv);
-WEAK(mikasa_mv);
WEAK(mikasa_primo_mv);
WEAK(monet_mv);
WEAK(nautilus_mv);
-WEAK(noname_mv);
-WEAK(noritake_mv);
WEAK(noritake_primo_mv);
-WEAK(p2k_mv);
WEAK(pc164_mv);
WEAK(privateer_mv);
WEAK(rawhide_mv);
WEAK(ruffian_mv);
WEAK(rx164_mv);
-WEAK(sable_mv);
WEAK(sable_gamma_mv);
WEAK(shark_mv);
WEAK(sx164_mv);
@@ -207,7 +194,6 @@ WEAK(takara_mv);
WEAK(titan_mv);
WEAK(webbrick_mv);
WEAK(wildfire_mv);
-WEAK(xl_mv);
WEAK(xlt_mv);
#undef WEAK
@@ -224,7 +210,7 @@ static void __init
reserve_std_resources(void)
{
static struct resource standard_io_resources[] = {
- { .name = "rtc", .start = -1, .end = -1 },
+ { .name = "rtc", .start = 0x70, .end = 0x7f},
{ .name = "dma1", .start = 0x00, .end = 0x1f },
{ .name = "pic1", .start = 0x20, .end = 0x3f },
{ .name = "timer", .start = 0x40, .end = 0x5f },
@@ -246,10 +232,6 @@ reserve_std_resources(void)
}
}
- /* Fix up for the Jensen's queer RTC placement. */
- standard_io_resources[0].start = RTC_PORT(0);
- standard_io_resources[0].end = RTC_PORT(0) + 0x0f;
-
for (i = 0; i < ARRAY_SIZE(standard_io_resources); ++i)
request_resource(io, standard_io_resources+i);
}
@@ -486,14 +468,7 @@ setup_arch(char **cmdline_p)
/*
* Locate the command line.
*/
- /* Hack for Jensen... since we're restricted to 8 or 16 chars for
- boot flags depending on the boot mode, we need some shorthand.
- This should do for installation. */
- if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
- strscpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof(command_line));
- } else {
- strscpy(command_line, COMMAND_LINE, sizeof(command_line));
- }
+ strscpy(command_line, COMMAND_LINE, sizeof(command_line));
strcpy(boot_command_line, command_line);
*cmdline_p = command_line;
@@ -706,12 +681,6 @@ static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
static char alcor_names[][16] = {"Alcor", "Maverick", "Bret"};
static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
-static char eb64p_names[][16] = {"EB64+", "Cabriolet", "AlphaPCI64"};
-static int eb64p_indices[] = {0,0,1,2};
-
-static char eb66_names[][8] = {"EB66", "EB66+"};
-static int eb66_indices[] = {0,0,1};
-
static char marvel_names[][16] = {
"Marvel/EV7"
};
@@ -745,26 +714,26 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
NULL, /* Ruby */
NULL, /* Flamingo */
NULL, /* Mannequin */
- &jensen_mv,
+ NULL, /* Jensens */
NULL, /* Pelican */
NULL, /* Morgan */
NULL, /* Sable -- see below. */
NULL, /* Medulla */
- &noname_mv,
+ NULL, /* Noname */
NULL, /* Turbolaser */
- &avanti_mv,
+ NULL, /* Avanti */
NULL, /* Mustang */
NULL, /* Alcor, Bret, Maverick. HWRPB inaccurate? */
NULL, /* Tradewind */
NULL, /* Mikasa -- see below. */
NULL, /* EB64 */
- NULL, /* EB66 -- see variation. */
- NULL, /* EB64+ -- see variation. */
- &alphabook1_mv,
+ NULL, /* EB66 */
+ NULL, /* EB64+ */
+ NULL, /* Alphabook1 */
&rawhide_mv,
NULL, /* K2 */
- &lynx_mv, /* Lynx */
- &xl_mv,
+ NULL, /* Lynx */
+ NULL, /* XL */
NULL, /* EB164 -- see variation. */
NULL, /* Noritake -- see below. */
NULL, /* Cortex */
@@ -803,19 +772,6 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
&eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv, &rx164_mv
};
- static struct alpha_machine_vector *eb64p_vecs[] __initdata =
- {
- &eb64p_mv,
- &cabriolet_mv,
- &cabriolet_mv /* AlphaPCI64 */
- };
-
- static struct alpha_machine_vector *eb66_vecs[] __initdata =
- {
- &eb66_mv,
- &eb66p_mv
- };
-
static struct alpha_machine_vector *marvel_vecs[] __initdata =
{
&marvel_ev7_mv,
@@ -883,14 +839,6 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
if (vec == &eb164_mv && cpu == EV56_CPU)
vec = &pc164_mv;
break;
- case ST_DEC_EB64P:
- if (member < ARRAY_SIZE(eb64p_indices))
- vec = eb64p_vecs[eb64p_indices[member]];
- break;
- case ST_DEC_EB66:
- if (member < ARRAY_SIZE(eb66_indices))
- vec = eb66_vecs[eb66_indices[member]];
- break;
case ST_DEC_MARVEL:
if (member < ARRAY_SIZE(marvel_indices))
vec = marvel_vecs[marvel_indices[member]];
@@ -905,22 +853,13 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
vec = tsunami_vecs[tsunami_indices[member]];
break;
case ST_DEC_1000:
- if (cpu == EV5_CPU || cpu == EV56_CPU)
- vec = &mikasa_primo_mv;
- else
- vec = &mikasa_mv;
+ vec = &mikasa_primo_mv;
break;
case ST_DEC_NORITAKE:
- if (cpu == EV5_CPU || cpu == EV56_CPU)
- vec = &noritake_primo_mv;
- else
- vec = &noritake_mv;
+ vec = &noritake_primo_mv;
break;
case ST_DEC_2100_A500:
- if (cpu == EV5_CPU || cpu == EV56_CPU)
- vec = &sable_gamma_mv;
- else
- vec = &sable_mv;
+ vec = &sable_gamma_mv;
break;
}
}
@@ -933,41 +872,27 @@ get_sysvec_byname(const char *name)
static struct alpha_machine_vector *all_vecs[] __initdata =
{
&alcor_mv,
- &alphabook1_mv,
- &avanti_mv,
- &cabriolet_mv,
&clipper_mv,
&dp264_mv,
&eb164_mv,
- &eb64p_mv,
- &eb66_mv,
- &eb66p_mv,
&eiger_mv,
- &jensen_mv,
&lx164_mv,
- &lynx_mv,
&miata_mv,
- &mikasa_mv,
&mikasa_primo_mv,
&monet_mv,
&nautilus_mv,
- &noname_mv,
- &noritake_mv,
&noritake_primo_mv,
- &p2k_mv,
&pc164_mv,
&privateer_mv,
&rawhide_mv,
&ruffian_mv,
&rx164_mv,
- &sable_mv,
&sable_gamma_mv,
&shark_mv,
&sx164_mv,
&takara_mv,
&webbrick_mv,
&wildfire_mv,
- &xl_mv,
&xlt_mv
};
@@ -1029,14 +954,6 @@ get_sysnames(unsigned long type, unsigned long variation, unsigned long cpu,
if (member < ARRAY_SIZE(alcor_indices))
*variation_name = alcor_names[alcor_indices[member]];
break;
- case ST_DEC_EB64P:
- if (member < ARRAY_SIZE(eb64p_indices))
- *variation_name = eb64p_names[eb64p_indices[member]];
- break;
- case ST_DEC_EB66:
- if (member < ARRAY_SIZE(eb66_indices))
- *variation_name = eb66_names[eb66_indices[member]];
- break;
case ST_DEC_MARVEL:
if (member < ARRAY_SIZE(marvel_indices))
*variation_name = marvel_names[marvel_indices[member]];
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
index bbbd34586de0..a5a6ed97a6ce 100644
--- a/arch/alpha/kernel/smc37c669.c
+++ b/arch/alpha/kernel/smc37c669.c
@@ -11,6 +11,8 @@
#include <asm/hwrpb.h>
#include <asm/io.h>
+#include "proto.h"
+
#if 0
# define DBG_DEVS(args) printk args
#else
@@ -2430,13 +2432,15 @@ int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *
}
#endif
-void __init
+#if SMC_DEBUG
+static void __init
SMC37c669_dump_registers(void)
{
int i;
for (i = 0; i <= 0x29; i++)
printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
}
+#endif
/*+
* ============================================================================
* = SMC_init - SMC37c669 Super I/O controller initialization =
diff --git a/arch/alpha/kernel/smc37c93x.c b/arch/alpha/kernel/smc37c93x.c
index 71cd7aca38ce..8028273f0d16 100644
--- a/arch/alpha/kernel/smc37c93x.c
+++ b/arch/alpha/kernel/smc37c93x.c
@@ -12,6 +12,8 @@
#include <asm/hwrpb.h>
#include <asm/io.h>
+#include "proto.h"
+
#define SMC_DEBUG 0
#if SMC_DEBUG
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 8e9dd63b220c..ed06367ece57 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -38,6 +38,7 @@
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
#include "proto.h"
#include "irq_impl.h"
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index feaf89f6936b..3e61073f4b30 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -21,6 +21,8 @@
#include <asm/console.h>
#include <linux/uaccess.h>
+#include "proto.h"
+
static DEFINE_SPINLOCK(srmcons_callback_lock);
static int srm_is_registered_console = 0;
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index 47459b73cdb7..54e75d4fdbe3 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -6,8 +6,7 @@
* Copyright (C) 1996 Jay A Estabrook
* Copyright (C) 1998, 1999, 2000 Richard Henderson
*
- * Code supporting the Cabriolet (AlphaPC64), EB66+, and EB164,
- * PC164 and LX164.
+ * Code supporting the PC164 and LX164.
*/
#include <linux/kernel.h>
@@ -23,9 +22,7 @@
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
-#include <asm/core_apecs.h>
#include <asm/core_cia.h>
-#include <asm/core_lca.h>
#include <asm/tlbflush.h>
#include "proto.h"
@@ -233,13 +230,6 @@ cabriolet_enable_ide(void)
}
static inline void __init
-cabriolet_init_pci(void)
-{
- common_init_pci();
- cabriolet_enable_ide();
-}
-
-static inline void __init
cia_cab_init_pci(void)
{
cia_init_pci();
@@ -317,81 +307,6 @@ alphapc164_init_pci(void)
* The System Vector
*/
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
-struct alpha_machine_vector cabriolet_mv __initmv = {
- .vector_name = "Cabriolet",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_APECS_IO,
- .machine_check = apecs_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 35,
- .device_interrupt = cabriolet_device_interrupt,
-
- .init_arch = apecs_init_arch,
- .init_irq = cabriolet_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = cabriolet_init_pci,
- .pci_map_irq = cabriolet_map_irq,
- .pci_swizzle = common_swizzle,
-};
-#ifndef CONFIG_ALPHA_EB64P
-ALIAS_MV(cabriolet)
-#endif
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB164)
-struct alpha_machine_vector eb164_mv __initmv = {
- .vector_name = "EB164",
- DO_EV5_MMU,
- DO_DEFAULT_RTC,
- DO_CIA_IO,
- .machine_check = cia_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = CIA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 35,
- .device_interrupt = cabriolet_device_interrupt,
-
- .init_arch = cia_init_arch,
- .init_irq = cabriolet_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = cia_cab_init_pci,
- .kill_arch = cia_kill_arch,
- .pci_map_irq = cabriolet_map_irq,
- .pci_swizzle = common_swizzle,
-};
-ALIAS_MV(eb164)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66P)
-struct alpha_machine_vector eb66p_mv __initmv = {
- .vector_name = "EB66+",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_LCA_IO,
- .machine_check = lca_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 35,
- .device_interrupt = cabriolet_device_interrupt,
-
- .init_arch = lca_init_arch,
- .init_irq = cabriolet_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = cabriolet_init_pci,
- .pci_map_irq = eb66p_map_irq,
- .pci_swizzle = common_swizzle,
-};
-ALIAS_MV(eb66p)
-#endif
-
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LX164)
struct alpha_machine_vector lx164_mv __initmv = {
.vector_name = "LX164",
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
deleted file mode 100644
index 3c43fd347526..000000000000
--- a/arch/alpha/kernel/sys_eb64p.c
+++ /dev/null
@@ -1,238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/alpha/kernel/sys_eb64p.c
- *
- * Copyright (C) 1995 David A Rusling
- * Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998, 1999 Richard Henderson
- *
- * Code supporting the EB64+ and EB66.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <asm/ptrace.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/io.h>
-#include <asm/core_apecs.h>
-#include <asm/core_lca.h>
-#include <asm/hwrpb.h>
-#include <asm/tlbflush.h>
-
-#include "proto.h"
-#include "irq_impl.h"
-#include "pci_impl.h"
-#include "machvec_impl.h"
-
-
-/* Note mask bit is true for DISABLED irqs. */
-static unsigned int cached_irq_mask = -1;
-
-static inline void
-eb64p_update_irq_hw(unsigned int irq, unsigned long mask)
-{
- outb(mask >> (irq >= 24 ? 24 : 16), (irq >= 24 ? 0x27 : 0x26));
-}
-
-static inline void
-eb64p_enable_irq(struct irq_data *d)
-{
- eb64p_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq));
-}
-
-static void
-eb64p_disable_irq(struct irq_data *d)
-{
- eb64p_update_irq_hw(d->irq, cached_irq_mask |= 1 << d->irq);
-}
-
-static struct irq_chip eb64p_irq_type = {
- .name = "EB64P",
- .irq_unmask = eb64p_enable_irq,
- .irq_mask = eb64p_disable_irq,
- .irq_mask_ack = eb64p_disable_irq,
-};
-
-static void
-eb64p_device_interrupt(unsigned long vector)
-{
- unsigned long pld;
- unsigned int i;
-
- /* Read the interrupt summary registers */
- pld = inb(0x26) | (inb(0x27) << 8);
-
- /*
- * Now, for every possible bit set, work through
- * them and call the appropriate interrupt handler.
- */
- while (pld) {
- i = ffz(~pld);
- pld &= pld - 1; /* clear least bit set */
-
- if (i == 5) {
- isa_device_interrupt(vector);
- } else {
- handle_irq(16 + i);
- }
- }
-}
-
-static void __init
-eb64p_init_irq(void)
-{
- long i;
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
- /*
- * CABRIO SRM may not set variation correctly, so here we test
- * the high word of the interrupt summary register for the RAZ
- * bits, and hope that a true EB64+ would read all ones...
- */
- if (inw(0x806) != 0xffff) {
- extern struct alpha_machine_vector cabriolet_mv;
-
- printk("Detected Cabriolet: correcting HWRPB.\n");
-
- hwrpb->sys_variation |= 2L << 10;
- hwrpb_update_checksum(hwrpb);
-
- alpha_mv = cabriolet_mv;
- alpha_mv.init_irq();
- return;
- }
-#endif /* GENERIC */
-
- outb(0xff, 0x26);
- outb(0xff, 0x27);
-
- init_i8259a_irqs();
-
- for (i = 16; i < 32; ++i) {
- irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
- irq_set_status_flags(i, IRQ_LEVEL);
- }
-
- common_init_isa_dma();
- if (request_irq(16 + 5, no_action, 0, "isa-cascade", NULL))
- pr_err("Failed to register isa-cascade interrupt\n");
-}
-
-/*
- * PCI Fixup configuration.
- *
- * There are two 8 bit external summary registers as follows:
- *
- * Summary @ 0x26:
- * Bit Meaning
- * 0 Interrupt Line A from slot 0
- * 1 Interrupt Line A from slot 1
- * 2 Interrupt Line B from slot 0
- * 3 Interrupt Line B from slot 1
- * 4 Interrupt Line C from slot 0
- * 5 Interrupt line from the two ISA PICs
- * 6 Tulip
- * 7 NCR SCSI
- *
- * Summary @ 0x27
- * Bit Meaning
- * 0 Interrupt Line C from slot 1
- * 1 Interrupt Line D from slot 0
- * 2 Interrupt Line D from slot 1
- * 3 RAZ
- * 4 RAZ
- * 5 RAZ
- * 6 RAZ
- * 7 RAZ
- *
- * The device to slot mapping looks like:
- *
- * Slot Device
- * 5 NCR SCSI controller
- * 6 PCI on board slot 0
- * 7 PCI on board slot 1
- * 8 Intel SIO PCI-ISA bridge chip
- * 9 Tulip - DECchip 21040 Ethernet controller
- *
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and
- * above for PCI interrupts. The IRQ relates to which bit the interrupt
- * comes in on. This makes interrupt processing much easier.
- */
-
-static int
-eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- static char irq_tab[5][5] = {
- /*INT INTA INTB INTC INTD */
- {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */
- {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */
- {16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */
- { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
- {16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 9, TULIP */
- };
- const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
- return COMMON_TABLE_LOOKUP;
-}
-
-
-/*
- * The System Vector
- */
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB64P)
-struct alpha_machine_vector eb64p_mv __initmv = {
- .vector_name = "EB64+",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_APECS_IO,
- .machine_check = apecs_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 32,
- .device_interrupt = eb64p_device_interrupt,
-
- .init_arch = apecs_init_arch,
- .init_irq = eb64p_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = common_init_pci,
- .kill_arch = NULL,
- .pci_map_irq = eb64p_map_irq,
- .pci_swizzle = common_swizzle,
-};
-ALIAS_MV(eb64p)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66)
-struct alpha_machine_vector eb66_mv __initmv = {
- .vector_name = "EB66",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_LCA_IO,
- .machine_check = lca_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 32,
- .device_interrupt = eb64p_device_interrupt,
-
- .init_arch = lca_init_arch,
- .init_irq = eb64p_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = common_init_pci,
- .pci_map_irq = eb64p_map_irq,
- .pci_swizzle = common_swizzle,
-};
-ALIAS_MV(eb66)
-#endif
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
deleted file mode 100644
index 5c9c88428124..000000000000
--- a/arch/alpha/kernel/sys_jensen.c
+++ /dev/null
@@ -1,237 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/alpha/kernel/sys_jensen.c
- *
- * Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 1998, 1999 Richard Henderson
- *
- * Code supporting the Jensen.
- */
-#define __EXTERN_INLINE
-#include <asm/io.h>
-#include <asm/jensen.h>
-#undef __EXTERN_INLINE
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/ptrace.h>
-
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
-
-#include "proto.h"
-#include "irq_impl.h"
-#include "pci_impl.h"
-#include "machvec_impl.h"
-
-
-/*
- * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
- * 0x9X0 for the local motherboard interrupts.
- *
- * Note especially that those local interrupts CANNOT be masked,
- * which causes much of the pain below...
- *
- * 0x660 - NMI
- *
- * 0x800 - IRQ0 interval timer (not used, as we use the RTC timer)
- * 0x810 - IRQ1 line printer (duh..)
- * 0x860 - IRQ6 floppy disk
- *
- * 0x900 - COM1
- * 0x920 - COM2
- * 0x980 - keyboard
- * 0x990 - mouse
- *
- * PCI-based systems are more sane: they don't have the local
- * interrupts at all, and have only normal PCI interrupts from
- * devices. Happily it's easy enough to do a sane mapping from the
- * Jensen.
- *
- * Note that this means that we may have to do a hardware
- * "local_op" to a different interrupt than we report to the rest of the
- * world.
- */
-
-static void
-jensen_local_enable(struct irq_data *d)
-{
- /* the parport is really hw IRQ 1, silly Jensen. */
- if (d->irq == 7)
- i8259a_enable_irq(d);
-}
-
-static void
-jensen_local_disable(struct irq_data *d)
-{
- /* the parport is really hw IRQ 1, silly Jensen. */
- if (d->irq == 7)
- i8259a_disable_irq(d);
-}
-
-static void
-jensen_local_mask_ack(struct irq_data *d)
-{
- /* the parport is really hw IRQ 1, silly Jensen. */
- if (d->irq == 7)
- i8259a_mask_and_ack_irq(d);
-}
-
-static struct irq_chip jensen_local_irq_type = {
- .name = "LOCAL",
- .irq_unmask = jensen_local_enable,
- .irq_mask = jensen_local_disable,
- .irq_mask_ack = jensen_local_mask_ack,
-};
-
-static void
-jensen_device_interrupt(unsigned long vector)
-{
- int irq;
-
- switch (vector) {
- case 0x660:
- printk("Whee.. NMI received. Probable hardware error\n");
- printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
- return;
-
- /* local device interrupts: */
- case 0x900: irq = 4; break; /* com1 -> irq 4 */
- case 0x920: irq = 3; break; /* com2 -> irq 3 */
- case 0x980: irq = 1; break; /* kbd -> irq 1 */
- case 0x990: irq = 9; break; /* mouse -> irq 9 */
-
- default:
- if (vector > 0x900) {
- printk("Unknown local interrupt %lx\n", vector);
- return;
- }
-
- irq = (vector - 0x800) >> 4;
- if (irq == 1)
- irq = 7;
- break;
- }
-
- /* If there is no handler yet... */
- if (!irq_has_action(irq)) {
- /* If it is a local interrupt that cannot be masked... */
- if (vector >= 0x900)
- {
- /* Clear keyboard/mouse state */
- inb(0x64);
- inb(0x60);
- /* Reset serial ports */
- inb(0x3fa);
- inb(0x2fa);
- outb(0x0c, 0x3fc);
- outb(0x0c, 0x2fc);
- /* Clear NMI */
- outb(0,0x61);
- outb(0,0x461);
- }
- }
-
-#if 0
- /* A useful bit of code to find out if an interrupt is going wild. */
- {
- static unsigned int last_msg = 0, last_cc = 0;
- static int last_irq = -1, count = 0;
- unsigned int cc;
-
- __asm __volatile("rpcc %0" : "=r"(cc));
- ++count;
-#define JENSEN_CYCLES_PER_SEC (150000000)
- if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) ||
- irq != last_irq) {
- printk(KERN_CRIT " irq %d count %d cc %u @ %lx\n",
- irq, count, cc-last_cc, get_irq_regs()->pc);
- count = 0;
- last_msg = cc;
- last_irq = irq;
- }
- last_cc = cc;
- }
-#endif
-
- handle_irq(irq);
-}
-
-static void __init
-jensen_init_irq(void)
-{
- init_i8259a_irqs();
-
- irq_set_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq);
- irq_set_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq);
- irq_set_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq);
- irq_set_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq);
- irq_set_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq);
-
- common_init_isa_dma();
-}
-
-static void __init
-jensen_init_arch(void)
-{
- struct pci_controller *hose;
-#ifdef CONFIG_PCI
- static struct pci_dev fake_isa_bridge = { .dma_mask = 0xffffffffUL, };
-
- isa_bridge = &fake_isa_bridge;
-#endif
-
- /* Create a hose so that we can report i/o base addresses to
- userland. */
-
- pci_isa_hose = hose = alloc_pci_controller();
- hose->io_space = &ioport_resource;
- hose->mem_space = &iomem_resource;
- hose->index = 0;
-
- hose->sparse_mem_base = EISA_MEM - IDENT_ADDR;
- hose->dense_mem_base = 0;
- hose->sparse_io_base = EISA_IO - IDENT_ADDR;
- hose->dense_io_base = 0;
-
- hose->sg_isa = hose->sg_pci = NULL;
- __direct_map_base = 0;
- __direct_map_size = 0xffffffff;
-}
-
-static void
-jensen_machine_check(unsigned long vector, unsigned long la)
-{
- printk(KERN_CRIT "Machine check\n");
-}
-
-/*
- * The System Vector
- */
-
-struct alpha_machine_vector jensen_mv __initmv = {
- .vector_name = "Jensen",
- DO_EV4_MMU,
- IO_LITE(JENSEN,jensen),
- .machine_check = jensen_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .rtc_port = 0x170,
-
- .nr_irqs = 16,
- .device_interrupt = jensen_device_interrupt,
-
- .init_arch = jensen_init_arch,
- .init_irq = jensen_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = NULL,
- .kill_arch = NULL,
-};
-ALIAS_MV(jensen)
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index 7690dfd57cb6..557802398231 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -23,7 +23,6 @@
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
-#include <asm/core_apecs.h>
#include <asm/core_cia.h>
#include <asm/tlbflush.h>
@@ -164,64 +163,9 @@ mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
}
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-static void
-mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
-{
-#define MCHK_NO_DEVSEL 0x205U
-#define MCHK_NO_TABT 0x204U
-
- struct el_common *mchk_header;
- unsigned int code;
-
- mchk_header = (struct el_common *)la_ptr;
-
- /* Clear the error before any reporting. */
- mb();
- mb(); /* magic */
- draina();
- apecs_pci_clr_err();
- wrmces(0x7);
- mb();
-
- code = mchk_header->code;
- process_mcheck_info(vector, la_ptr, "MIKASA APECS",
- (mcheck_expected(0)
- && (code == MCHK_NO_DEVSEL
- || code == MCHK_NO_TABT)));
-}
-#endif
-
-
/*
* The System Vector
*/
-
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-struct alpha_machine_vector mikasa_mv __initmv = {
- .vector_name = "Mikasa",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_APECS_IO,
- .machine_check = mikasa_apecs_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 32,
- .device_interrupt = mikasa_device_interrupt,
-
- .init_arch = apecs_init_arch,
- .init_irq = mikasa_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = common_init_pci,
- .pci_map_irq = mikasa_map_irq,
- .pci_swizzle = common_swizzle,
-};
-ALIAS_MV(mikasa)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
struct alpha_machine_vector mikasa_primo_mv __initmv = {
.vector_name = "Mikasa-Primo",
DO_EV5_MMU,
@@ -244,4 +188,3 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = {
.pci_swizzle = common_swizzle,
};
ALIAS_MV(mikasa_primo)
-#endif
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
index 96fd6ff3fe81..13b79960b4b9 100644
--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -78,7 +78,7 @@ nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq;
}
-void
+static void
nautilus_kill_arch(int mode)
{
struct pci_bus *bus = pci_isa_hose->bus;
@@ -127,7 +127,7 @@ naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
/* Machine checks can come from two sources - those on the CPU and those
in the system. They are analysed separately but all starts here. */
-void
+static void
nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
{
char *mchk_class;
@@ -184,8 +184,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
mb();
}
-extern void pcibios_claim_one_bus(struct pci_bus *);
-
static struct resource irongate_mem = {
.name = "Irongate PCI MEM",
.flags = IORESOURCE_MEM,
@@ -197,7 +195,7 @@ static struct resource busn_resource = {
.flags = IORESOURCE_BUS,
};
-void __init
+static void __init
nautilus_init_pci(void)
{
struct pci_controller *hose = hose_head;
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 47f3ce4f719a..eed3f16561c0 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -24,7 +24,6 @@
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
-#include <asm/core_apecs.h>
#include <asm/core_cia.h>
#include <asm/tlbflush.h>
@@ -253,64 +252,6 @@ noritake_swizzle(struct pci_dev *dev, u8 *pinp)
return slot;
}
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-static void
-noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
-{
-#define MCHK_NO_DEVSEL 0x205U
-#define MCHK_NO_TABT 0x204U
-
- struct el_common *mchk_header;
- unsigned int code;
-
- mchk_header = (struct el_common *)la_ptr;
-
- /* Clear the error before any reporting. */
- mb();
- mb(); /* magic */
- draina();
- apecs_pci_clr_err();
- wrmces(0x7);
- mb();
-
- code = mchk_header->code;
- process_mcheck_info(vector, la_ptr, "NORITAKE APECS",
- (mcheck_expected(0)
- && (code == MCHK_NO_DEVSEL
- || code == MCHK_NO_TABT)));
-}
-#endif
-
-
-/*
- * The System Vectors
- */
-
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-struct alpha_machine_vector noritake_mv __initmv = {
- .vector_name = "Noritake",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_APECS_IO,
- .machine_check = noritake_apecs_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = EISA_DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 48,
- .device_interrupt = noritake_device_interrupt,
-
- .init_arch = apecs_init_arch,
- .init_irq = noritake_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = common_init_pci,
- .pci_map_irq = noritake_map_irq,
- .pci_swizzle = noritake_swizzle,
-};
-ALIAS_MV(noritake)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
struct alpha_machine_vector noritake_primo_mv __initmv = {
.vector_name = "Noritake-Primo",
DO_EV5_MMU,
@@ -333,4 +274,3 @@ struct alpha_machine_vector noritake_primo_mv __initmv = {
.pci_swizzle = noritake_swizzle,
};
ALIAS_MV(noritake_primo)
-#endif
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index 930005b2f630..49f5c75134ec 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -212,232 +212,6 @@ sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
}
#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) */
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
-
-/***********************************************************************/
-/* LYNX hardware specifics
- */
-/*
- * For LYNX, which is also baroque, we manage 64 IRQs, via a custom IC.
- *
- * Bit Meaning Kernel IRQ
- *------------------------------------------
- * 0
- * 1
- * 2
- * 3 mouse 12
- * 4
- * 5
- * 6 keyboard 1
- * 7 floppy 6
- * 8 COM2 3
- * 9 parallel port 7
- *10 EISA irq 3 -
- *11 EISA irq 4 -
- *12 EISA irq 5 5
- *13 EISA irq 6 -
- *14 EISA irq 7 -
- *15 COM1 4
- *16 EISA irq 9 9
- *17 EISA irq 10 10
- *18 EISA irq 11 11
- *19 EISA irq 12 -
- *20
- *21 EISA irq 14 14
- *22 EISA irq 15 15
- *23 IIC -
- *24 VGA (builtin) -
- *25
- *26
- *27
- *28 NCR810 (builtin) 28
- *29
- *30
- *31
- *32 PCI 0 slot 4 A primary bus 32
- *33 PCI 0 slot 4 B primary bus 33
- *34 PCI 0 slot 4 C primary bus 34
- *35 PCI 0 slot 4 D primary bus
- *36 PCI 0 slot 5 A primary bus
- *37 PCI 0 slot 5 B primary bus
- *38 PCI 0 slot 5 C primary bus
- *39 PCI 0 slot 5 D primary bus
- *40 PCI 0 slot 6 A primary bus
- *41 PCI 0 slot 6 B primary bus
- *42 PCI 0 slot 6 C primary bus
- *43 PCI 0 slot 6 D primary bus
- *44 PCI 0 slot 7 A primary bus
- *45 PCI 0 slot 7 B primary bus
- *46 PCI 0 slot 7 C primary bus
- *47 PCI 0 slot 7 D primary bus
- *48 PCI 0 slot 0 A secondary bus
- *49 PCI 0 slot 0 B secondary bus
- *50 PCI 0 slot 0 C secondary bus
- *51 PCI 0 slot 0 D secondary bus
- *52 PCI 0 slot 1 A secondary bus
- *53 PCI 0 slot 1 B secondary bus
- *54 PCI 0 slot 1 C secondary bus
- *55 PCI 0 slot 1 D secondary bus
- *56 PCI 0 slot 2 A secondary bus
- *57 PCI 0 slot 2 B secondary bus
- *58 PCI 0 slot 2 C secondary bus
- *59 PCI 0 slot 2 D secondary bus
- *60 PCI 0 slot 3 A secondary bus
- *61 PCI 0 slot 3 B secondary bus
- *62 PCI 0 slot 3 C secondary bus
- *63 PCI 0 slot 3 D secondary bus
- */
-
-static void
-lynx_update_irq_hw(unsigned long bit, unsigned long mask)
-{
- /*
- * Write the AIR register on the T3/T4 with the
- * address of the IC mask register (offset 0x40)
- */
- *(vulp)T2_AIR = 0x40;
- mb();
- *(vulp)T2_AIR; /* re-read to force write */
- mb();
- *(vulp)T2_DIR = mask;
- mb();
- mb();
-}
-
-static void
-lynx_ack_irq_hw(unsigned long bit)
-{
- *(vulp)T2_VAR = (u_long) bit;
- mb();
- mb();
-}
-
-static irq_swizzle_t lynx_irq_swizzle = {
- { /* irq_to_mask */
- -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */
- -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */
- -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo */
- -1, -1, -1, -1, 28, -1, -1, -1, /* pseudo */
- 32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */
- 40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */
- 48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */
- 56, 57, 58, 59, 60, 61, 62, 63 /* mask 56-63 */
- },
- { /* mask_to_irq */
- -1, -1, -1, 12, -1, -1, 1, 6, /* mask 0-7 */
- 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */
- 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */
- -1, -1, -1, -1, 28, -1, -1, -1, /* mask 24-31 */
- 32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */
- 40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */
- 48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */
- 56, 57, 58, 59, 60, 61, 62, 63 /* mask 56-63 */
- },
- -1,
- lynx_update_irq_hw,
- lynx_ack_irq_hw
-};
-
-static void __init
-lynx_init_irq(void)
-{
- sable_lynx_irq_swizzle = &lynx_irq_swizzle;
- sable_lynx_init_irq(64);
-}
-
-/*
- * PCI Fixup configuration for ALPHA LYNX (2100A)
- *
- * The device to slot mapping looks like:
- *
- * Slot Device
- * 0 none
- * 1 none
- * 2 PCI-EISA bridge
- * 3 PCI-PCI bridge
- * 4 NCR 810 (Demi-Lynx only)
- * 5 none
- * 6 PCI on board slot 4
- * 7 PCI on board slot 5
- * 8 PCI on board slot 6
- * 9 PCI on board slot 7
- *
- * And behind the PPB we have:
- *
- * 11 PCI on board slot 0
- * 12 PCI on board slot 1
- * 13 PCI on board slot 2
- * 14 PCI on board slot 3
- */
-/*
- * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
- * with the values in the irq swizzling tables above.
- */
-
-static int
-lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- static char irq_tab[19][5] = {
- /*INT INTA INTB INTC INTD */
- { -1, -1, -1, -1, -1}, /* IdSel 13, PCEB */
- { -1, -1, -1, -1, -1}, /* IdSel 14, PPB */
- { 28, 28, 28, 28, 28}, /* IdSel 15, NCR demi */
- { -1, -1, -1, -1, -1}, /* IdSel 16, none */
- { 32, 32, 33, 34, 35}, /* IdSel 17, slot 4 */
- { 36, 36, 37, 38, 39}, /* IdSel 18, slot 5 */
- { 40, 40, 41, 42, 43}, /* IdSel 19, slot 6 */
- { 44, 44, 45, 46, 47}, /* IdSel 20, slot 7 */
- { -1, -1, -1, -1, -1}, /* IdSel 22, none */
- /* The following are actually behind the PPB. */
- { -1, -1, -1, -1, -1}, /* IdSel 16 none */
- { 28, 28, 28, 28, 28}, /* IdSel 17 NCR lynx */
- { -1, -1, -1, -1, -1}, /* IdSel 18 none */
- { -1, -1, -1, -1, -1}, /* IdSel 19 none */
- { -1, -1, -1, -1, -1}, /* IdSel 20 none */
- { -1, -1, -1, -1, -1}, /* IdSel 21 none */
- { 48, 48, 49, 50, 51}, /* IdSel 22 slot 0 */
- { 52, 52, 53, 54, 55}, /* IdSel 23 slot 1 */
- { 56, 56, 57, 58, 59}, /* IdSel 24 slot 2 */
- { 60, 60, 61, 62, 63} /* IdSel 25 slot 3 */
- };
- const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5;
- return COMMON_TABLE_LOOKUP;
-}
-
-static u8
-lynx_swizzle(struct pci_dev *dev, u8 *pinp)
-{
- int slot, pin = *pinp;
-
- if (dev->bus->number == 0) {
- slot = PCI_SLOT(dev->devfn);
- }
- /* Check for the built-in bridge */
- else if (PCI_SLOT(dev->bus->self->devfn) == 3) {
- slot = PCI_SLOT(dev->devfn) + 11;
- }
- else
- {
- /* Must be a card-based bridge. */
- do {
- if (PCI_SLOT(dev->bus->self->devfn) == 3) {
- slot = PCI_SLOT(dev->devfn) + 11;
- break;
- }
- pin = pci_swizzle_interrupt_pin(dev, pin);
-
- /* Move up the chain of bridges. */
- dev = dev->bus->self;
- /* Slot of the next bridge. */
- slot = PCI_SLOT(dev->devfn);
- } while (dev->bus->self);
- }
- *pinp = pin;
- return slot;
-}
-
-#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) */
-
/***********************************************************************/
/* GENERIC irq routines */
@@ -539,40 +313,7 @@ sable_lynx_init_pci(void)
* these games with GAMMA_BIAS.
*/
-#if defined(CONFIG_ALPHA_GENERIC) || \
- (defined(CONFIG_ALPHA_SABLE) && !defined(CONFIG_ALPHA_GAMMA))
-#undef GAMMA_BIAS
-#define GAMMA_BIAS 0
-struct alpha_machine_vector sable_mv __initmv = {
- .vector_name = "Sable",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_T2_IO,
- .machine_check = t2_machine_check,
- .max_isa_dma_address = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
- .min_io_address = EISA_DEFAULT_IO_BASE,
- .min_mem_address = T2_DEFAULT_MEM_BASE,
-
- .nr_irqs = 40,
- .device_interrupt = sable_lynx_srm_device_interrupt,
-
- .init_arch = t2_init_arch,
- .init_irq = sable_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = sable_lynx_init_pci,
- .kill_arch = t2_kill_arch,
- .pci_map_irq = sable_map_irq,
- .pci_swizzle = common_swizzle,
-
- .sys = { .t2 = {
- .gamma_bias = 0
- } }
-};
-ALIAS_MV(sable)
-#endif /* GENERIC || (SABLE && !GAMMA) */
-
-#if defined(CONFIG_ALPHA_GENERIC) || \
- (defined(CONFIG_ALPHA_SABLE) && defined(CONFIG_ALPHA_GAMMA))
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)
#undef GAMMA_BIAS
#define GAMMA_BIAS _GAMMA_BIAS
struct alpha_machine_vector sable_gamma_mv __initmv = {
@@ -601,35 +342,4 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
} }
};
ALIAS_MV(sable_gamma)
-#endif /* GENERIC || (SABLE && GAMMA) */
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
-#undef GAMMA_BIAS
-#define GAMMA_BIAS _GAMMA_BIAS
-struct alpha_machine_vector lynx_mv __initmv = {
- .vector_name = "Lynx",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_T2_IO,
- .machine_check = t2_machine_check,
- .max_isa_dma_address = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
- .min_io_address = EISA_DEFAULT_IO_BASE,
- .min_mem_address = T2_DEFAULT_MEM_BASE,
-
- .nr_irqs = 64,
- .device_interrupt = sable_lynx_srm_device_interrupt,
-
- .init_arch = t2_init_arch,
- .init_irq = lynx_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = sable_lynx_init_pci,
- .kill_arch = t2_kill_arch,
- .pci_map_irq = lynx_map_irq,
- .pci_swizzle = lynx_swizzle,
-
- .sys = { .t2 = {
- .gamma_bias = _GAMMA_BIAS
- } }
-};
-ALIAS_MV(lynx)
-#endif /* GENERIC || LYNX */
+#endif /* GENERIC || SABLE */
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
deleted file mode 100644
index 086488ed83a7..000000000000
--- a/arch/alpha/kernel/sys_sio.c
+++ /dev/null
@@ -1,486 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/alpha/kernel/sys_sio.c
- *
- * Copyright (C) 1995 David A Rusling
- * Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998, 1999 Richard Henderson
- *
- * Code for all boards that route the PCI interrupts through the SIO
- * PCI/ISA bridge. This includes Noname (AXPpci33), Multia (UDB),
- * Kenetics's Platform 2000, Avanti (AlphaStation), XL, and AlphaBook1.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/screen_info.h>
-
-#include <asm/compiler.h>
-#include <asm/ptrace.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/io.h>
-#include <asm/core_apecs.h>
-#include <asm/core_lca.h>
-#include <asm/tlbflush.h>
-
-#include "proto.h"
-#include "irq_impl.h"
-#include "pci_impl.h"
-#include "machvec_impl.h"
-#include "pc873xx.h"
-
-#if defined(ALPHA_RESTORE_SRM_SETUP)
-/* Save LCA configuration data as the console had it set up. */
-struct
-{
- unsigned int orig_route_tab; /* for SAVE/RESTORE */
-} saved_config __attribute((common));
-#endif
-
-
-static void __init
-sio_init_irq(void)
-{
- if (alpha_using_srm)
- alpha_mv.device_interrupt = srm_device_interrupt;
-
- init_i8259a_irqs();
- common_init_isa_dma();
-}
-
-static inline void __init
-alphabook1_init_arch(void)
-{
-#ifdef CONFIG_VGA_CONSOLE
- /* The AlphaBook1 has LCD video fixed at 800x600,
- 37 rows and 100 cols. */
- vgacon_screen_info.orig_y = 37;
- vgacon_screen_info.orig_video_cols = 100;
- vgacon_screen_info.orig_video_lines = 37;
-#endif
-
- lca_init_arch();
-}
-
-
-/*
- * sio_route_tab selects irq routing in PCI/ISA bridge so that:
- * PIRQ0 -> irq 15
- * PIRQ1 -> irq 9
- * PIRQ2 -> irq 10
- * PIRQ3 -> irq 11
- *
- * This probably ought to be configurable via MILO. For
- * example, sound boards seem to like using IRQ 9.
- *
- * This is NOT how we should do it. PIRQ0-X should have
- * their own IRQs, the way intel uses the IO-APIC IRQs.
- */
-
-static void __init
-sio_pci_route(void)
-{
- unsigned int orig_route_tab;
-
- /* First, ALWAYS read and print the original setting. */
- pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
- &orig_route_tab);
- printk("%s: PIRQ original 0x%x new 0x%x\n", __func__,
- orig_route_tab, alpha_mv.sys.sio.route_tab);
-
-#if defined(ALPHA_RESTORE_SRM_SETUP)
- saved_config.orig_route_tab = orig_route_tab;
-#endif
-
- /* Now override with desired setting. */
- pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
- alpha_mv.sys.sio.route_tab);
-}
-
-static bool sio_pci_dev_irq_needs_level(const struct pci_dev *dev)
-{
- if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
- (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
- return false;
-
- return true;
-}
-
-static unsigned int __init
-sio_collect_irq_levels(void)
-{
- unsigned int level_bits = 0;
- struct pci_dev *dev = NULL;
-
- /* Iterate through the devices, collecting IRQ levels. */
- for_each_pci_dev(dev) {
- if (!sio_pci_dev_irq_needs_level(dev))
- continue;
-
- if (dev->irq)
- level_bits |= (1 << dev->irq);
- }
- return level_bits;
-}
-
-static void __sio_fixup_irq_levels(unsigned int level_bits, bool reset)
-{
- unsigned int old_level_bits;
-
- /*
- * Now, make all PCI interrupts level sensitive. Notice:
- * these registers must be accessed byte-wise. inw()/outw()
- * don't work.
- *
- * Make sure to turn off any level bits set for IRQs 9,10,11,15,
- * so that the only bits getting set are for devices actually found.
- * Note that we do preserve the remainder of the bits, which we hope
- * will be set correctly by ARC/SRM.
- *
- * Note: we at least preserve any level-set bits on AlphaBook1
- */
- old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
-
- if (reset)
- old_level_bits &= 0x71ff;
-
- level_bits |= old_level_bits;
-
- outb((level_bits >> 0) & 0xff, 0x4d0);
- outb((level_bits >> 8) & 0xff, 0x4d1);
-}
-
-static inline void
-sio_fixup_irq_levels(unsigned int level_bits)
-{
- __sio_fixup_irq_levels(level_bits, true);
-}
-
-static inline int
-noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- /*
- * The Noname board has 5 PCI slots with each of the 4
- * interrupt pins routed to different pins on the PCI/ISA
- * bridge (PIRQ0-PIRQ3). The table below is based on
- * information available at:
- *
- * http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
- *
- * I have no information on the Avanti interrupt routing, but
- * the routing seems to be identical to the Noname except
- * that the Avanti has an additional slot whose routing I'm
- * unsure of.
- *
- * pirq_tab[0] is a fake entry to deal with old PCI boards
- * that have the interrupt pin number hardwired to 0 (meaning
- * that they use the default INTA line, if they are interrupt
- * driven at all).
- */
- static char irq_tab[][5] = {
- /*INT A B C D */
- { 3, 3, 3, 3, 3}, /* idsel 6 (53c810) */
- {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
- { 2, 2, -1, -1, -1}, /* idsel 8 (Hack: slot closest ISA) */
- {-1, -1, -1, -1, -1}, /* idsel 9 (unused) */
- {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
- { 0, 0, 2, 1, 0}, /* idsel 11 KN25_PCI_SLOT0 */
- { 1, 1, 0, 2, 1}, /* idsel 12 KN25_PCI_SLOT1 */
- { 2, 2, 1, 0, 2}, /* idsel 13 KN25_PCI_SLOT2 */
- { 0, 0, 0, 0, 0}, /* idsel 14 AS255 TULIP */
- };
- const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
- int irq = COMMON_TABLE_LOOKUP, tmp;
- tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
-
- irq = irq >= 0 ? tmp : -1;
-
- /* Fixup IRQ level if an actual IRQ mapping is detected */
- if (sio_pci_dev_irq_needs_level(dev) && irq >= 0)
- __sio_fixup_irq_levels(1 << irq, false);
-
- return irq;
-}
-
-static inline int
-p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- static char irq_tab[][5] = {
- /*INT A B C D */
- { 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */
- {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
- { 1, 1, 2, 3, 0}, /* idsel 8 (slot A) */
- { 2, 2, 3, 0, 1}, /* idsel 9 (slot B) */
- {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
- {-1, -1, -1, -1, -1}, /* idsel 11 (unused) */
- { 3, 3, -1, -1, -1}, /* idsel 12 (CMD0646) */
- };
- const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
- int irq = COMMON_TABLE_LOOKUP, tmp;
- tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
- return irq >= 0 ? tmp : -1;
-}
-
-static inline void __init
-noname_init_pci(void)
-{
- common_init_pci();
- sio_pci_route();
- sio_fixup_irq_levels(sio_collect_irq_levels());
-
- if (pc873xx_probe() == -1) {
- printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
- } else {
- printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
- pc873xx_get_model(), pc873xx_get_base());
-
- /* Enabling things in the Super IO chip doesn't actually
- * configure and enable things, the legacy drivers still
- * need to do the actual configuration and enabling.
- * This only unblocks them.
- */
-
-#if !defined(CONFIG_ALPHA_AVANTI)
- /* Don't bother on the Avanti family.
- * None of them had on-board IDE.
- */
- pc873xx_enable_ide();
-#endif
- pc873xx_enable_epp19();
- }
-}
-
-static inline void __init
-alphabook1_init_pci(void)
-{
- struct pci_dev *dev;
- unsigned char orig, config;
-
- common_init_pci();
- sio_pci_route();
-
- /*
- * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
- * is sensitive to PCI bus bursts, so we must DISABLE
- * burst mode for the NCR 8xx SCSI... :-(
- *
- * Note that the NCR810 SCSI driver must preserve the
- * setting of the bit in order for this to work. At the
- * moment (2.0.29), ncr53c8xx.c does NOT do this, but
- * 53c7,8xx.c DOES.
- */
-
- dev = NULL;
- while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
- if (dev->device == PCI_DEVICE_ID_NCR_53C810
- || dev->device == PCI_DEVICE_ID_NCR_53C815
- || dev->device == PCI_DEVICE_ID_NCR_53C820
- || dev->device == PCI_DEVICE_ID_NCR_53C825) {
- unsigned long io_port;
- unsigned char ctest4;
-
- io_port = dev->resource[0].start;
- ctest4 = inb(io_port+0x21);
- if (!(ctest4 & 0x80)) {
- printk("AlphaBook1 NCR init: setting"
- " burst disable\n");
- outb(ctest4 | 0x80, io_port+0x21);
- }
- }
- }
-
- /* Do not set *ANY* level triggers for AlphaBook1. */
- sio_fixup_irq_levels(0);
-
- /* Make sure that register PR1 indicates 1Mb mem */
- outb(0x0f, 0x3ce); orig = inb(0x3cf); /* read PR5 */
- outb(0x0f, 0x3ce); outb(0x05, 0x3cf); /* unlock PR0-4 */
- outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
- if ((config & 0xc0) != 0xc0) {
- printk("AlphaBook1 VGA init: setting 1Mb memory\n");
- config |= 0xc0;
- outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
- }
- outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
-}
-
-void
-sio_kill_arch(int mode)
-{
-#if defined(ALPHA_RESTORE_SRM_SETUP)
- /* Since we cannot read the PCI DMA Window CSRs, we
- * cannot restore them here.
- *
- * However, we CAN read the PIRQ route register, so restore it
- * now...
- */
- pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
- saved_config.orig_route_tab);
-#endif
-}
-
-
-/*
- * The System Vectors
- */
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1)
-struct alpha_machine_vector alphabook1_mv __initmv = {
- .vector_name = "AlphaBook1",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_LCA_IO,
- .machine_check = lca_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 16,
- .device_interrupt = isa_device_interrupt,
-
- .init_arch = alphabook1_init_arch,
- .init_irq = sio_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = alphabook1_init_pci,
- .kill_arch = sio_kill_arch,
- .pci_map_irq = noname_map_irq,
- .pci_swizzle = common_swizzle,
-
- .sys = { .sio = {
- /* NCR810 SCSI is 14, PCMCIA controller is 15. */
- .route_tab = 0x0e0f0a0a,
- }}
-};
-ALIAS_MV(alphabook1)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI)
-struct alpha_machine_vector avanti_mv __initmv = {
- .vector_name = "Avanti",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_APECS_IO,
- .machine_check = apecs_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 16,
- .device_interrupt = isa_device_interrupt,
-
- .init_arch = apecs_init_arch,
- .init_irq = sio_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = noname_init_pci,
- .kill_arch = sio_kill_arch,
- .pci_map_irq = noname_map_irq,
- .pci_swizzle = common_swizzle,
-
- .sys = { .sio = {
- .route_tab = 0x0b0a050f, /* leave 14 for IDE, 9 for SND */
- }}
-};
-ALIAS_MV(avanti)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME)
-struct alpha_machine_vector noname_mv __initmv = {
- .vector_name = "Noname",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_LCA_IO,
- .machine_check = lca_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 16,
- .device_interrupt = srm_device_interrupt,
-
- .init_arch = lca_init_arch,
- .init_irq = sio_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = noname_init_pci,
- .kill_arch = sio_kill_arch,
- .pci_map_irq = noname_map_irq,
- .pci_swizzle = common_swizzle,
-
- .sys = { .sio = {
- /* For UDB, the only available PCI slot must not map to IRQ 9,
- since that's the builtin MSS sound chip. That PCI slot
- will map to PIRQ1 (for INTA at least), so we give it IRQ 15
- instead.
-
- Unfortunately we have to do this for NONAME as well, since
- they are co-indicated when the platform type "Noname" is
- selected... :-( */
-
- .route_tab = 0x0b0a0f0d,
- }}
-};
-ALIAS_MV(noname)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K)
-struct alpha_machine_vector p2k_mv __initmv = {
- .vector_name = "Platform2000",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_LCA_IO,
- .machine_check = lca_machine_check,
- .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
- .nr_irqs = 16,
- .device_interrupt = srm_device_interrupt,
-
- .init_arch = lca_init_arch,
- .init_irq = sio_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = noname_init_pci,
- .kill_arch = sio_kill_arch,
- .pci_map_irq = p2k_map_irq,
- .pci_swizzle = common_swizzle,
-
- .sys = { .sio = {
- .route_tab = 0x0b0a090f,
- }}
-};
-ALIAS_MV(p2k)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL)
-struct alpha_machine_vector xl_mv __initmv = {
- .vector_name = "XL",
- DO_EV4_MMU,
- DO_DEFAULT_RTC,
- DO_APECS_IO,
- .machine_check = apecs_machine_check,
- .max_isa_dma_address = ALPHA_XL_MAX_ISA_DMA_ADDRESS,
- .min_io_address = DEFAULT_IO_BASE,
- .min_mem_address = XL_DEFAULT_MEM_BASE,
-
- .nr_irqs = 16,
- .device_interrupt = isa_device_interrupt,
-
- .init_arch = apecs_init_arch,
- .init_irq = sio_init_irq,
- .init_rtc = common_init_rtc,
- .init_pci = noname_init_pci,
- .kill_arch = sio_kill_arch,
- .pci_map_irq = noname_map_irq,
- .pci_swizzle = common_swizzle,
-
- .sys = { .sio = {
- .route_tab = 0x0b0a090f,
- }}
-};
-ALIAS_MV(xl)
-#endif
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 8ff110826ce2..74720667fe09 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -474,7 +474,7 @@
542 common fsmount sys_fsmount
543 common fspick sys_fspick
544 common pidfd_open sys_pidfd_open
-# 545 reserved for clone3
+545 common clone3 alpha_clone3
546 common close_range sys_close_range
547 common openat2 sys_openat2
548 common pidfd_getfd sys_pidfd_getfd
@@ -501,3 +501,4 @@
569 common lsm_get_self_attr sys_lsm_get_self_attr
570 common lsm_set_self_attr sys_lsm_set_self_attr
571 common lsm_list_modules sys_lsm_list_modules
+572 common mseal sys_mseal
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 7fc72aeb7398..6afae65e9a8b 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -30,39 +30,6 @@
#include "proto.h"
-/* Work-around for some SRMs which mishandle opDEC faults. */
-
-static int opDEC_fix;
-
-static void
-opDEC_check(void)
-{
- __asm__ __volatile__ (
- /* Load the address of... */
- " br $16, 1f\n"
- /* A stub instruction fault handler. Just add 4 to the
- pc and continue. */
- " ldq $16, 8($sp)\n"
- " addq $16, 4, $16\n"
- " stq $16, 8($sp)\n"
- " call_pal %[rti]\n"
- /* Install the instruction fault handler. */
- "1: lda $17, 3\n"
- " call_pal %[wrent]\n"
- /* With that in place, the fault from the round-to-minf fp
- insn will arrive either at the "lda 4" insn (bad) or one
- past that (good). This places the correct fixup in %0. */
- " lda %[fix], 0\n"
- " cvttq/svm $f31,$f31\n"
- " lda %[fix], 4"
- : [fix] "=r" (opDEC_fix)
- : [rti] "n" (PAL_rti), [wrent] "n" (PAL_wrent)
- : "$0", "$1", "$16", "$17", "$22", "$23", "$24", "$25");
-
- if (opDEC_fix)
- printk("opDEC fixup enabled.\n");
-}
-
void
dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
{
@@ -353,32 +320,6 @@ do_entIF(unsigned long type, struct pt_regs *regs)
return;
case 4: /* opDEC */
- if (implver() == IMPLVER_EV4) {
- long si_code;
-
- /* The some versions of SRM do not handle
- the opDEC properly - they return the PC of the
- opDEC fault, not the instruction after as the
- Alpha architecture requires. Here we fix it up.
- We do this by intentionally causing an opDEC
- fault during the boot sequence and testing if
- we get the correct PC. If not, we set a flag
- to correct it every time through. */
- regs->pc += opDEC_fix;
-
- /* EV4 does not implement anything except normal
- rounding. Everything else will come here as
- an illegal instruction. Emulate them. */
- si_code = alpha_fp_emul(regs->pc - 4);
- if (si_code == 0)
- return;
- if (si_code > 0) {
- send_sig_fault_trapno(SIGFPE, si_code,
- (void __user *) regs->pc,
- 0, current);
- return;
- }
- }
break;
case 5: /* illoc */
@@ -979,11 +920,6 @@ trap_init(void)
register unsigned long gptr __asm__("$29");
wrkgp(gptr);
- /* Hack for Multia (UDB) and JENSEN: some of their SRMs have
- a bug in the handling of the opDEC fault. Fix it up if so. */
- if (implver() == IMPLVER_EV4)
- opDEC_check();
-
wrent(entArith, 1);
wrent(entMM, 2);
wrent(entIF, 3);
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index 6a779b9018fd..84046e730e6d 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -44,17 +44,3 @@ AFLAGS___remlu.o = -DREM -DINTSIZE
$(addprefix $(obj)/,__divqu.o __remqu.o __divlu.o __remlu.o): \
$(src)/$(ev6-y)divide.S FORCE
$(call if_changed_rule,as_o_S)
-
-# There are direct branches between {str*cpy,str*cat} and stx*cpy.
-# Ensure the branches are within range by merging these objects.
-
-LDFLAGS_stycpy.o := -r
-LDFLAGS_styncpy.o := -r
-
-$(obj)/stycpy.o: $(obj)/strcpy.o $(obj)/$(ev67-y)strcat.o \
- $(obj)/$(ev6-y)stxcpy.o FORCE
- $(call if_changed,ld)
-
-$(obj)/styncpy.o: $(obj)/strncpy.o $(obj)/$(ev67-y)strncat.o \
- $(obj)/$(ev6-y)stxncpy.o FORCE
- $(call if_changed,ld)
diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c
index 3f35c3ed6948..27b2a9edf3cc 100644
--- a/arch/alpha/lib/checksum.c
+++ b/arch/alpha/lib/checksum.c
@@ -12,8 +12,10 @@
#include <linux/module.h>
#include <linux/string.h>
+#include <net/checksum.h>
#include <asm/byteorder.h>
+#include <asm/checksum.h>
static inline unsigned short from64to16(unsigned long x)
{
diff --git a/arch/alpha/lib/fpreg.c b/arch/alpha/lib/fpreg.c
index 7c08b225261c..9a238e7536ae 100644
--- a/arch/alpha/lib/fpreg.c
+++ b/arch/alpha/lib/fpreg.c
@@ -8,7 +8,9 @@
#include <linux/compiler.h>
#include <linux/export.h>
#include <linux/preempt.h>
+#include <asm/fpu.h>
#include <asm/thread_info.h>
+#include <asm/fpu.h>
#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
#define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
diff --git a/arch/alpha/lib/memcpy.c b/arch/alpha/lib/memcpy.c
index cbac3dc6d963..78b6850a9d53 100644
--- a/arch/alpha/lib/memcpy.c
+++ b/arch/alpha/lib/memcpy.c
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/export.h>
+#include <linux/string.h>
/*
* This should be done in one go with ldq_u*2/mask/stq_u. Do it
@@ -150,6 +151,8 @@ static inline void __memcpy_aligned_dn (unsigned long d, unsigned long s,
DO_REST_ALIGNED_DN(d,s,n);
}
+#undef memcpy
+
void * memcpy(void * dest, const void *src, size_t n)
{
if (!(((unsigned long) dest ^ (unsigned long) src) & 7)) {
diff --git a/arch/alpha/lib/stycpy.S b/arch/alpha/lib/stycpy.S
new file mode 100644
index 000000000000..32ecd9c5f90d
--- /dev/null
+++ b/arch/alpha/lib/stycpy.S
@@ -0,0 +1,11 @@
+#include "strcpy.S"
+#ifdef CONFIG_ALPHA_EV67
+#include "ev67-strcat.S"
+#else
+#include "strcat.S"
+#endif
+#ifdef CONFIG_ALPHA_EV6
+#include "ev6-stxcpy.S"
+#else
+#include "stxcpy.S"
+#endif
diff --git a/arch/alpha/lib/styncpy.S b/arch/alpha/lib/styncpy.S
new file mode 100644
index 000000000000..72fc2754eb57
--- /dev/null
+++ b/arch/alpha/lib/styncpy.S
@@ -0,0 +1,11 @@
+#include "strncpy.S"
+#ifdef CONFIG_ALPHA_EV67
+#include "ev67-strncat.S"
+#else
+#include "strncat.S"
+#endif
+#ifdef CONFIG_ALPHA_EV6
+#include "ev6-stxncpy.S"
+#else
+#include "stxncpy.S"
+#endif
diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c
index 4212258f3cfd..68d420bfd3c0 100644
--- a/arch/alpha/math-emu/math.c
+++ b/arch/alpha/math-emu/math.c
@@ -4,6 +4,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/ptrace.h>
+#include <asm/fpu.h>
#include <linux/uaccess.h>
@@ -45,12 +46,6 @@
#define MISC_TRAPB 0x0000
#define MISC_EXCB 0x0400
-extern unsigned long alpha_read_fp_reg (unsigned long reg);
-extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
-extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
-extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
-
-
#ifdef MODULE
MODULE_DESCRIPTION("FP Software completion module");
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index a155180d7a83..4fe618446e4c 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -33,7 +33,7 @@
#include <asm/setup.h>
#include <asm/sections.h>
-extern void die_if_kernel(char *,struct pt_regs *,long);
+#include "../kernel/proto.h"
static struct pcb_struct original_pcb;
diff --git a/arch/arc/Kbuild b/arch/arc/Kbuild
index b94102fff68b..20ea7dd482d4 100644
--- a/arch/arc/Kbuild
+++ b/arch/arc/Kbuild
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += kernel/
obj-y += mm/
+obj-y += net/
# for cleaning
subdir- += boot
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 4092bec198be..fd0b0a0d4686 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -51,6 +51,7 @@ config ARC
select PCI_SYSCALL if PCI
select HAVE_ARCH_JUMP_LABEL if ISA_ARCV2 && !CPU_ENDIAN_BE32
select TRACE_IRQFLAGS_SUPPORT
+ select HAVE_EBPF_JIT if ISA_ARCV2
config LOCKDEP_SUPPORT
def_bool y
diff --git a/arch/arc/boot/dts/Makefile b/arch/arc/boot/dts/Makefile
index 4237aa5de3a3..48704dfdf75c 100644
--- a/arch/arc/boot/dts/Makefile
+++ b/arch/arc/boot/dts/Makefile
@@ -10,8 +10,7 @@ obj-y += $(builtindtb-y).dtb.o
dtb-y := $(builtindtb-y).dtb
# for CONFIG_OF_ALL_DTBS test
-dtstree := $(srctree)/$(src)
-dtb- := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+dtb- := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts))
# board-specific dtc flags
DTC_FLAGS_hsdk += --pad 20
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 3c1afa524b9c..49285a3ce239 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
+
generic-y += extable.h
generic-y += kvm_para.h
generic-y += mcs_spinlock.h
diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h
deleted file mode 100644
index 9c2383d29cbb..000000000000
--- a/arch/arc/include/asm/fb.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/arc/include/asm/mmu-arcv2.h b/arch/arc/include/asm/mmu-arcv2.h
index ed9036d4ede3..d85dc0721907 100644
--- a/arch/arc/include/asm/mmu-arcv2.h
+++ b/arch/arc/include/asm/mmu-arcv2.h
@@ -9,6 +9,8 @@
#ifndef _ASM_ARC_MMU_ARCV2_H
#define _ASM_ARC_MMU_ARCV2_H
+#include <soc/arc/aux.h>
+
/*
* TLB Management regs
*/
diff --git a/arch/arc/include/asm/unistd.h b/arch/arc/include/asm/unistd.h
new file mode 100644
index 000000000000..211c230d88d6
--- /dev/null
+++ b/arch/arc/include/asm/unistd.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_ARC_UNISTD_H
+#define _ASM_ARC_UNISTD_H
+
+#include <uapi/asm/unistd.h>
+
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_FORK
+
+#define NR_syscalls __NR_syscalls
+
+#endif
diff --git a/arch/arc/include/uapi/asm/Kbuild b/arch/arc/include/uapi/asm/Kbuild
index e78470141932..2501e82a1a0a 100644
--- a/arch/arc/include/uapi/asm/Kbuild
+++ b/arch/arc/include/uapi/asm/Kbuild
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
+
generic-y += ucontext.h
diff --git a/arch/arc/include/uapi/asm/unistd.h b/arch/arc/include/uapi/asm/unistd.h
index fa2713ae6bea..cb2905c7c5da 100644
--- a/arch/arc/include/uapi/asm/unistd.h
+++ b/arch/arc/include/uapi/asm/unistd.h
@@ -7,46 +7,4 @@
* published by the Free Software Foundation.
*/
-/******** no-legacy-syscalls-ABI *******/
-
-/*
- * Non-typical guard macro to enable inclusion twice in ARCH sys.c
- * That is how the Generic syscall wrapper generator works
- */
-#if !defined(_UAPI_ASM_ARC_UNISTD_H) || defined(__SYSCALL)
-#define _UAPI_ASM_ARC_UNISTD_H
-
-#define __ARCH_WANT_RENAMEAT
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_SYS_EXECVE
-#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_SYS_VFORK
-#define __ARCH_WANT_SYS_FORK
-#define __ARCH_WANT_TIME32_SYSCALLS
-
-#define sys_mmap2 sys_mmap_pgoff
-
-#include <asm-generic/unistd.h>
-
-#define NR_syscalls __NR_syscalls
-
-/* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
-#define __NR_sysfs (__NR_arch_specific_syscall + 3)
-
-/* ARC specific syscall */
-#define __NR_cacheflush (__NR_arch_specific_syscall + 0)
-#define __NR_arc_settls (__NR_arch_specific_syscall + 1)
-#define __NR_arc_gettls (__NR_arch_specific_syscall + 2)
-#define __NR_arc_usr_cmpxchg (__NR_arch_specific_syscall + 4)
-
-__SYSCALL(__NR_cacheflush, sys_cacheflush)
-__SYSCALL(__NR_arc_settls, sys_arc_settls)
-__SYSCALL(__NR_arc_gettls, sys_arc_gettls)
-__SYSCALL(__NR_arc_usr_cmpxchg, sys_arc_usr_cmpxchg)
-__SYSCALL(__NR_sysfs, sys_sysfs)
-
-#undef __SYSCALL
-
-#endif
+#include <asm/unistd_32.h>
diff --git a/arch/arc/kernel/Makefile.syscalls b/arch/arc/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..391d30ab7a83
--- /dev/null
+++ b/arch/arc/kernel/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += arc time32 renameat stat64 rlimit
diff --git a/arch/arc/kernel/sys.c b/arch/arc/kernel/sys.c
index 1069446bdc58..36a2a95c083b 100644
--- a/arch/arc/kernel/sys.c
+++ b/arch/arc/kernel/sys.c
@@ -8,11 +8,12 @@
#define sys_clone sys_clone_wrapper
#define sys_clone3 sys_clone3_wrapper
+#define sys_mmap2 sys_mmap_pgoff
-#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
void *sys_call_table[NR_syscalls] = {
[0 ... NR_syscalls-1] = sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 197707bc7658..6b85e94f3275 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -90,8 +90,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
/*
* Plug in direct dma map ops.
*/
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
{
/*
* IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
index 3c1c7ae73292..69a915297155 100644
--- a/arch/arc/mm/mmap.c
+++ b/arch/arc/mm/mmap.c
@@ -27,7 +27,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/*
* We enforce the MAP_FIXED case.
@@ -51,11 +51,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- info.flags = 0;
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
- info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
}
diff --git a/arch/arc/net/Makefile b/arch/arc/net/Makefile
new file mode 100644
index 000000000000..ea5790952e9a
--- /dev/null
+++ b/arch/arc/net/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+ifeq ($(CONFIG_ISA_ARCV2),y)
+ obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o
+ obj-$(CONFIG_BPF_JIT) += bpf_jit_arcv2.o
+endif
diff --git a/arch/arc/net/bpf_jit.h b/arch/arc/net/bpf_jit.h
new file mode 100644
index 000000000000..495f3023e4c1
--- /dev/null
+++ b/arch/arc/net/bpf_jit.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The interface that a back-end should provide to bpf_jit_core.c.
+ *
+ * Copyright (c) 2024 Synopsys Inc.
+ * Author: Shahab Vahedi <shahab@synopsys.com>
+ */
+
+#ifndef _ARC_BPF_JIT_H
+#define _ARC_BPF_JIT_H
+
+#include <linux/bpf.h>
+#include <linux/filter.h>
+
+/* Print debug info and assert. */
+//#define ARC_BPF_JIT_DEBUG
+
+/* Determine the address type of the target. */
+#ifdef CONFIG_ISA_ARCV2
+#define ARC_ADDR u32
+#endif
+
+/*
+ * For the translation of some BPF instructions, a temporary register
+ * might be needed for some interim data.
+ */
+#define JIT_REG_TMP MAX_BPF_JIT_REG
+
+/*
+ * Buffer access: If buffer "b" is not NULL, advance by "n" bytes.
+ *
+ * This macro must be used in any place that potentially requires a
+ * "buf + len". This way, we make sure that the "buf" argument for
+ * the underlying "arc_*(buf, ...)" ends up as NULL instead of something
+ * like "0+4" or "0+8", etc. Those "arc_*()" functions check their "buf"
+ * value to decide if instructions should be emitted or not.
+ */
+#define BUF(b, n) (((b) != NULL) ? ((b) + (n)) : (b))
+
+/************** Functions that the back-end must provide **************/
+/* Extension for 32-bit operations. */
+u8 zext(u8 *buf, u8 rd);
+/***** Moves *****/
+u8 mov_r32(u8 *buf, u8 rd, u8 rs, u8 sign_ext);
+u8 mov_r32_i32(u8 *buf, u8 reg, s32 imm);
+u8 mov_r64(u8 *buf, u8 rd, u8 rs, u8 sign_ext);
+u8 mov_r64_i32(u8 *buf, u8 reg, s32 imm);
+u8 mov_r64_i64(u8 *buf, u8 reg, u32 lo, u32 hi);
+/***** Loads and stores *****/
+u8 load_r(u8 *buf, u8 rd, u8 rs, s16 off, u8 size, bool sign_ext);
+u8 store_r(u8 *buf, u8 rd, u8 rs, s16 off, u8 size);
+u8 store_i(u8 *buf, s32 imm, u8 rd, s16 off, u8 size);
+/***** Addition *****/
+u8 add_r32(u8 *buf, u8 rd, u8 rs);
+u8 add_r32_i32(u8 *buf, u8 rd, s32 imm);
+u8 add_r64(u8 *buf, u8 rd, u8 rs);
+u8 add_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Subtraction *****/
+u8 sub_r32(u8 *buf, u8 rd, u8 rs);
+u8 sub_r32_i32(u8 *buf, u8 rd, s32 imm);
+u8 sub_r64(u8 *buf, u8 rd, u8 rs);
+u8 sub_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Multiplication *****/
+u8 mul_r32(u8 *buf, u8 rd, u8 rs);
+u8 mul_r32_i32(u8 *buf, u8 rd, s32 imm);
+u8 mul_r64(u8 *buf, u8 rd, u8 rs);
+u8 mul_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Division *****/
+u8 div_r32(u8 *buf, u8 rd, u8 rs, bool sign_ext);
+u8 div_r32_i32(u8 *buf, u8 rd, s32 imm, bool sign_ext);
+/***** Remainder *****/
+u8 mod_r32(u8 *buf, u8 rd, u8 rs, bool sign_ext);
+u8 mod_r32_i32(u8 *buf, u8 rd, s32 imm, bool sign_ext);
+/***** Bitwise AND *****/
+u8 and_r32(u8 *buf, u8 rd, u8 rs);
+u8 and_r32_i32(u8 *buf, u8 rd, s32 imm);
+u8 and_r64(u8 *buf, u8 rd, u8 rs);
+u8 and_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Bitwise OR *****/
+u8 or_r32(u8 *buf, u8 rd, u8 rs);
+u8 or_r32_i32(u8 *buf, u8 rd, s32 imm);
+u8 or_r64(u8 *buf, u8 rd, u8 rs);
+u8 or_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Bitwise XOR *****/
+u8 xor_r32(u8 *buf, u8 rd, u8 rs);
+u8 xor_r32_i32(u8 *buf, u8 rd, s32 imm);
+u8 xor_r64(u8 *buf, u8 rd, u8 rs);
+u8 xor_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Bitwise Negate *****/
+u8 neg_r32(u8 *buf, u8 r);
+u8 neg_r64(u8 *buf, u8 r);
+/***** Bitwise left shift *****/
+u8 lsh_r32(u8 *buf, u8 rd, u8 rs);
+u8 lsh_r32_i32(u8 *buf, u8 rd, u8 imm);
+u8 lsh_r64(u8 *buf, u8 rd, u8 rs);
+u8 lsh_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Bitwise right shift (logical) *****/
+u8 rsh_r32(u8 *buf, u8 rd, u8 rs);
+u8 rsh_r32_i32(u8 *buf, u8 rd, u8 imm);
+u8 rsh_r64(u8 *buf, u8 rd, u8 rs);
+u8 rsh_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Bitwise right shift (arithmetic) *****/
+u8 arsh_r32(u8 *buf, u8 rd, u8 rs);
+u8 arsh_r32_i32(u8 *buf, u8 rd, u8 imm);
+u8 arsh_r64(u8 *buf, u8 rd, u8 rs);
+u8 arsh_r64_i32(u8 *buf, u8 rd, s32 imm);
+/***** Frame related *****/
+u32 mask_for_used_regs(u8 bpf_reg, bool is_call);
+u8 arc_prologue(u8 *buf, u32 usage, u16 frame_size);
+u8 arc_epilogue(u8 *buf, u32 usage, u16 frame_size);
+/***** Jumps *****/
+/*
+ * Different sorts of conditions (ARC enum as opposed to BPF_*).
+ *
+ * Do not change the order of enums here. ARC_CC_SLE+1 is used
+ * to determine the number of JCCs.
+ */
+enum ARC_CC {
+ ARC_CC_UGT = 0, /* unsigned > */
+ ARC_CC_UGE, /* unsigned >= */
+ ARC_CC_ULT, /* unsigned < */
+ ARC_CC_ULE, /* unsigned <= */
+ ARC_CC_SGT, /* signed > */
+ ARC_CC_SGE, /* signed >= */
+ ARC_CC_SLT, /* signed < */
+ ARC_CC_SLE, /* signed <= */
+ ARC_CC_AL, /* always */
+ ARC_CC_EQ, /* == */
+ ARC_CC_NE, /* != */
+ ARC_CC_SET, /* test */
+ ARC_CC_LAST
+};
+
+/*
+ * A few notes:
+ *
+ * - check_jmp_*() are prerequisites before calling the gen_jmp_*().
+ * They return "true" if the jump is possible and "false" otherwise.
+ *
+ * - The notion of "*_off" is to emphasize that these parameters are
+ * merely offsets in the JIT stream and not absolute addresses. One
+ * can look at them as addresses if the JIT code would start from
+ * address 0x0000_0000. Nonetheless, since the buffer address for the
+ * JIT is on a word-aligned address, this works and actually makes
+ * things simpler (offsets are in the range of u32 which is more than
+ * enough).
+ */
+bool check_jmp_32(u32 curr_off, u32 targ_off, u8 cond);
+bool check_jmp_64(u32 curr_off, u32 targ_off, u8 cond);
+u8 gen_jmp_32(u8 *buf, u8 rd, u8 rs, u8 cond, u32 c_off, u32 t_off);
+u8 gen_jmp_64(u8 *buf, u8 rd, u8 rs, u8 cond, u32 c_off, u32 t_off);
+/***** Miscellaneous *****/
+u8 gen_func_call(u8 *buf, ARC_ADDR func_addr, bool external_func);
+u8 arc_to_bpf_return(u8 *buf);
+/*
+ * - Perform byte swaps on "rd" based on the "size".
+ * - If "force" is set, do it unconditionally. Otherwise, consider the
+ * desired "endian"ness and the host endianness.
+ * - For data "size"s up to 32 bits, perform a zero-extension if asked
+ * by the "do_zext" boolean.
+ */
+u8 gen_swap(u8 *buf, u8 rd, u8 size, u8 endian, bool force, bool do_zext);
+
+#endif /* _ARC_BPF_JIT_H */
diff --git a/arch/arc/net/bpf_jit_arcv2.c b/arch/arc/net/bpf_jit_arcv2.c
new file mode 100644
index 000000000000..4458e409ca0a
--- /dev/null
+++ b/arch/arc/net/bpf_jit_arcv2.c
@@ -0,0 +1,3007 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The ARCv2 backend of Just-In-Time compiler for eBPF bytecode.
+ *
+ * Copyright (c) 2024 Synopsys Inc.
+ * Author: Shahab Vahedi <shahab@synopsys.com>
+ */
+#include <linux/bug.h>
+#include "bpf_jit.h"
+
+/* ARC core registers. */
+enum {
+ ARC_R_0, ARC_R_1, ARC_R_2, ARC_R_3, ARC_R_4, ARC_R_5,
+ ARC_R_6, ARC_R_7, ARC_R_8, ARC_R_9, ARC_R_10, ARC_R_11,
+ ARC_R_12, ARC_R_13, ARC_R_14, ARC_R_15, ARC_R_16, ARC_R_17,
+ ARC_R_18, ARC_R_19, ARC_R_20, ARC_R_21, ARC_R_22, ARC_R_23,
+ ARC_R_24, ARC_R_25, ARC_R_26, ARC_R_FP, ARC_R_SP, ARC_R_ILINK,
+ ARC_R_30, ARC_R_BLINK,
+ /*
+ * Having ARC_R_IMM encoded as source register means there is an
+ * immediate that must be interpreted from the next 4 bytes. If
+ * encoded as the destination register though, it implies that the
+ * output of the operation is not assigned to any register. The
+ * latter is helpful if we only care about updating the CPU status
+ * flags.
+ */
+ ARC_R_IMM = 62
+};
+
+/*
+ * Remarks about the rationale behind the chosen mapping:
+ *
+ * - BPF_REG_{1,2,3,4} are the argument registers and must be mapped to
+ * argument registers in ARCv2 ABI: r0-r7. The r7 registers is the last
+ * argument register in the ABI. Therefore BPF_REG_5, as the fifth
+ * argument, must be pushed onto the stack. This is a must for calling
+ * in-kernel functions.
+ *
+ * - In ARCv2 ABI, the return value is in r0 for 32-bit results and (r1,r0)
+ * for 64-bit results. However, because they're already used for BPF_REG_1,
+ * the next available scratch registers, r8 and r9, are the best candidates
+ * for BPF_REG_0. After a "call" to a(n) (in-kernel) function, the result
+ * is "mov"ed to these registers. At a BPF_EXIT, their value is "mov"ed to
+ * (r1,r0).
+ * It is worth mentioning that scratch registers are the best choice for
+ * BPF_REG_0, because it is very popular in BPF instruction encoding.
+ *
+ * - JIT_REG_TMP is an artifact needed to translate some BPF instructions.
+ * Its life span is one single BPF instruction. Since during the
+ * analyze_reg_usage(), it is not known if temporary registers are used,
+ * it is mapped to ARC's scratch registers: r10 and r11. Therefore, they
+ * don't matter in analysing phase and don't need saving. This temporary
+ * register is added as yet another index in the bpf2arc array, so it will
+ * unfold like the rest of registers during the code generation process.
+ *
+ * - Mapping of callee-saved BPF registers, BPF_REG_{6,7,8,9}, starts from
+ * (r15,r14) register pair. The (r13,r12) is not a good choice, because
+ * in ARCv2 ABI, r12 is not a callee-saved register and this can cause
+ * problem when calling an in-kernel function. Theoretically, the mapping
+ * could start from (r14,r13), but it is not a conventional ARCv2 register
+ * pair. To have a future proof design, I opted for this arrangement.
+ * If/when we decide to add ARCv2 instructions that do use register pairs,
+ * the mapping, hopefully, doesn't need to be revisited.
+ */
+static const u8 bpf2arc[][2] = {
+ /* Return value from in-kernel function, and exit value from eBPF */
+ [BPF_REG_0] = {ARC_R_8, ARC_R_9},
+ /* Arguments from eBPF program to in-kernel function */
+ [BPF_REG_1] = {ARC_R_0, ARC_R_1},
+ [BPF_REG_2] = {ARC_R_2, ARC_R_3},
+ [BPF_REG_3] = {ARC_R_4, ARC_R_5},
+ [BPF_REG_4] = {ARC_R_6, ARC_R_7},
+ /* Remaining arguments, to be passed on the stack per 32-bit ABI */
+ [BPF_REG_5] = {ARC_R_22, ARC_R_23},
+ /* Callee-saved registers that in-kernel function will preserve */
+ [BPF_REG_6] = {ARC_R_14, ARC_R_15},
+ [BPF_REG_7] = {ARC_R_16, ARC_R_17},
+ [BPF_REG_8] = {ARC_R_18, ARC_R_19},
+ [BPF_REG_9] = {ARC_R_20, ARC_R_21},
+ /* Read-only frame pointer to access the eBPF stack. 32-bit only. */
+ [BPF_REG_FP] = {ARC_R_FP, },
+ /* Register for blinding constants */
+ [BPF_REG_AX] = {ARC_R_24, ARC_R_25},
+ /* Temporary registers for internal use */
+ [JIT_REG_TMP] = {ARC_R_10, ARC_R_11}
+};
+
+#define ARC_CALLEE_SAVED_REG_FIRST ARC_R_13
+#define ARC_CALLEE_SAVED_REG_LAST ARC_R_25
+
+#define REG_LO(r) (bpf2arc[(r)][0])
+#define REG_HI(r) (bpf2arc[(r)][1])
+
+/*
+ * To comply with ARCv2 ABI, BPF's arg5 must be put on stack. After which,
+ * the stack needs to be restored by ARG5_SIZE.
+ */
+#define ARG5_SIZE 8
+
+/* Instruction lengths in bytes. */
+enum {
+ INSN_len_normal = 4, /* Normal instructions length. */
+ INSN_len_imm = 4 /* Length of an extra 32-bit immediate. */
+};
+
+/* ZZ defines the size of operation in encodings that it is used. */
+enum {
+ ZZ_1_byte = 1,
+ ZZ_2_byte = 2,
+ ZZ_4_byte = 0,
+ ZZ_8_byte = 3
+};
+
+/*
+ * AA is mostly about address write back mode. It determines if the
+ * address in question should be updated before usage or after:
+ * addr += offset; data = *addr;
+ * data = *addr; addr += offset;
+ *
+ * In "scaling" mode, the effective address will become the sum
+ * of "address" + "index"*"size". The "size" is specified by the
+ * "ZZ" field. There is no write back when AA is set for scaling:
+ * data = *(addr + offset<<zz)
+ */
+enum {
+ AA_none = 0,
+ AA_pre = 1, /* in assembly known as "a/aw". */
+ AA_post = 2, /* in assembly known as "ab". */
+ AA_scale = 3 /* in assembly known as "as". */
+};
+
+/* X flag determines the mode of extension. */
+enum {
+ X_zero = 0,
+ X_sign = 1
+};
+
+/* Condition codes. */
+enum {
+ CC_always = 0, /* condition is true all the time */
+ CC_equal = 1, /* if status32.z flag is set */
+ CC_unequal = 2, /* if status32.z flag is clear */
+ CC_positive = 3, /* if status32.n flag is clear */
+ CC_negative = 4, /* if status32.n flag is set */
+ CC_less_u = 5, /* less than (unsigned) */
+ CC_less_eq_u = 14, /* less than or equal (unsigned) */
+ CC_great_eq_u = 6, /* greater than or equal (unsigned) */
+ CC_great_u = 13, /* greater than (unsigned) */
+ CC_less_s = 11, /* less than (signed) */
+ CC_less_eq_s = 12, /* less than or equal (signed) */
+ CC_great_eq_s = 10, /* greater than or equal (signed) */
+ CC_great_s = 9 /* greater than (signed) */
+};
+
+#define IN_U6_RANGE(x) ((x) <= (0x40 - 1) && (x) >= 0)
+#define IN_S9_RANGE(x) ((x) <= (0x100 - 1) && (x) >= -0x100)
+#define IN_S12_RANGE(x) ((x) <= (0x800 - 1) && (x) >= -0x800)
+#define IN_S21_RANGE(x) ((x) <= (0x100000 - 1) && (x) >= -0x100000)
+#define IN_S25_RANGE(x) ((x) <= (0x1000000 - 1) && (x) >= -0x1000000)
+
+/* Operands in most of the encodings. */
+#define OP_A(x) ((x) & 0x03f)
+#define OP_B(x) ((((x) & 0x07) << 24) | (((x) & 0x38) << 9))
+#define OP_C(x) (((x) & 0x03f) << 6)
+#define OP_IMM (OP_C(ARC_R_IMM))
+#define COND(x) (OP_A((x) & 31))
+#define FLAG(x) (((x) & 1) << 15)
+
+/*
+ * The 4-byte encoding of "mov b,c":
+ *
+ * 0010_0bbb 0000_1010 0BBB_cccc cc00_0000
+ *
+ * b: BBBbbb destination register
+ * c: cccccc source register
+ */
+#define OPC_MOV 0x200a0000
+
+/*
+ * The 4-byte encoding of "mov b,s12" (used for moving small immediates):
+ *
+ * 0010_0bbb 1000_1010 0BBB_ssss ssSS_SSSS
+ *
+ * b: BBBbbb destination register
+ * s: SSSSSSssssss source immediate (signed)
+ */
+#define OPC_MOVI 0x208a0000
+#define MOVI_S12(x) ((((x) & 0xfc0) >> 6) | (((x) & 0x3f) << 6))
+
+/*
+ * The 4-byte encoding of "mov[.qq] b,u6", used for conditional
+ * moving of even smaller immediates:
+ *
+ * 0010_0bbb 1100_1010 0BBB_cccc cciq_qqqq
+ *
+ * qq: qqqqq condition code
+ * i: If set, c is considered a 6-bit immediate, else a reg.
+ *
+ * b: BBBbbb destination register
+ * c: cccccc source
+ */
+#define OPC_MOV_CC 0x20ca0000
+#define MOV_CC_I BIT(5)
+#define OPC_MOVU_CC (OPC_MOV_CC | MOV_CC_I)
+
+/*
+ * The 4-byte encoding of "sexb b,c" (8-bit sign extension):
+ *
+ * 0010_0bbb 0010_1111 0BBB_cccc cc00_0101
+ *
+ * b: BBBbbb destination register
+ * c: cccccc source register
+ */
+#define OPC_SEXB 0x202f0005
+
+/*
+ * The 4-byte encoding of "sexh b,c" (16-bit sign extension):
+ *
+ * 0010_0bbb 0010_1111 0BBB_cccc cc00_0110
+ *
+ * b: BBBbbb destination register
+ * c: cccccc source register
+ */
+#define OPC_SEXH 0x202f0006
+
+/*
+ * The 4-byte encoding of "ld[zz][.x][.aa] c,[b,s9]":
+ *
+ * 0001_0bbb ssss_ssss SBBB_0aaz zxcc_cccc
+ *
+ * zz: size mode
+ * aa: address write back mode
+ * x: extension mode
+ *
+ * s9: S_ssss_ssss 9-bit signed number
+ * b: BBBbbb source reg for address
+ * c: cccccc destination register
+ */
+#define OPC_LOAD 0x10000000
+#define LOAD_X(x) ((x) << 6)
+#define LOAD_ZZ(x) ((x) << 7)
+#define LOAD_AA(x) ((x) << 9)
+#define LOAD_S9(x) ((((x) & 0x0ff) << 16) | (((x) & 0x100) << 7))
+#define LOAD_C(x) ((x) & 0x03f)
+/* Unsigned and signed loads. */
+#define OPC_LDU (OPC_LOAD | LOAD_X(X_zero))
+#define OPC_LDS (OPC_LOAD | LOAD_X(X_sign))
+/* 32-bit load. */
+#define OPC_LD32 (OPC_LDU | LOAD_ZZ(ZZ_4_byte))
+/* "pop reg" is merely a "ld.ab reg,[sp,4]". */
+#define OPC_POP \
+ (OPC_LD32 | LOAD_AA(AA_post) | LOAD_S9(4) | OP_B(ARC_R_SP))
+
+/*
+ * The 4-byte encoding of "st[zz][.aa] c,[b,s9]":
+ *
+ * 0001_1bbb ssss_ssss SBBB_cccc cc0a_azz0
+ *
+ * zz: zz size mode
+ * aa: aa address write back mode
+ *
+ * s9: S_ssss_ssss 9-bit signed number
+ * b: BBBbbb source reg for address
+ * c: cccccc source reg to be stored
+ */
+#define OPC_STORE 0x18000000
+#define STORE_ZZ(x) ((x) << 1)
+#define STORE_AA(x) ((x) << 3)
+#define STORE_S9(x) ((((x) & 0x0ff) << 16) | (((x) & 0x100) << 7))
+/* 32-bit store. */
+#define OPC_ST32 (OPC_STORE | STORE_ZZ(ZZ_4_byte))
+/* "push reg" is merely a "st.aw reg,[sp,-4]". */
+#define OPC_PUSH \
+ (OPC_ST32 | STORE_AA(AA_pre) | STORE_S9(-4) | OP_B(ARC_R_SP))
+
+/*
+ * The 4-byte encoding of "add a,b,c":
+ *
+ * 0010_0bbb 0i00_0000 fBBB_cccc ccaa_aaaa
+ *
+ * f: indicates if flags (carry, etc.) should be updated
+ * i: If set, c is considered a 6-bit immediate, else a reg.
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_ADD 0x20000000
+/* Addition with updating the pertinent flags in "status32" register. */
+#define OPC_ADDF (OPC_ADD | FLAG(1))
+#define ADDI BIT(22)
+#define ADDI_U6(x) OP_C(x)
+#define OPC_ADDI (OPC_ADD | ADDI)
+#define OPC_ADDIF (OPC_ADDI | FLAG(1))
+#define OPC_ADD_I (OPC_ADD | OP_IMM)
+
+/*
+ * The 4-byte encoding of "adc a,b,c" (addition with carry):
+ *
+ * 0010_0bbb 0i00_0001 0BBB_cccc ccaa_aaaa
+ *
+ * i: if set, c is considered a 6-bit immediate, else a reg.
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_ADC 0x20010000
+#define ADCI BIT(22)
+#define ADCI_U6(x) OP_C(x)
+#define OPC_ADCI (OPC_ADC | ADCI)
+
+/*
+ * The 4-byte encoding of "sub a,b,c":
+ *
+ * 0010_0bbb 0i00_0010 fBBB_cccc ccaa_aaaa
+ *
+ * f: indicates if flags (carry, etc.) should be updated
+ * i: if set, c is considered a 6-bit immediate, else a reg.
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_SUB 0x20020000
+/* Subtraction with updating the pertinent flags in "status32" register. */
+#define OPC_SUBF (OPC_SUB | FLAG(1))
+#define SUBI BIT(22)
+#define SUBI_U6(x) OP_C(x)
+#define OPC_SUBI (OPC_SUB | SUBI)
+#define OPC_SUB_I (OPC_SUB | OP_IMM)
+
+/*
+ * The 4-byte encoding of "sbc a,b,c" (subtraction with carry):
+ *
+ * 0010_0bbb 0000_0011 fBBB_cccc ccaa_aaaa
+ *
+ * f: indicates if flags (carry, etc.) should be updated
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_SBC 0x20030000
+
+/*
+ * The 4-byte encoding of "cmp[.qq] b,c":
+ *
+ * 0010_0bbb 1100_1100 1BBB_cccc cc0q_qqqq
+ *
+ * qq: qqqqq condition code
+ *
+ * b: BBBbbb the 1st operand
+ * c: cccccc the 2nd operand
+ */
+#define OPC_CMP 0x20cc8000
+
+/*
+ * The 4-byte encoding of "neg a,b":
+ *
+ * 0010_0bbb 0100_1110 0BBB_0000 00aa_aaaa
+ *
+ * a: aaaaaa result
+ * b: BBBbbb input
+ */
+#define OPC_NEG 0x204e0000
+
+/*
+ * The 4-byte encoding of "mpy a,b,c".
+ * mpy is the signed 32-bit multiplication with the lower 32-bit
+ * of the product as the result.
+ *
+ * 0010_0bbb 0001_1010 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_MPY 0x201a0000
+#define OPC_MPYI (OPC_MPY | OP_IMM)
+
+/*
+ * The 4-byte encoding of "mpydu a,b,c".
+ * mpydu is the unsigned 32-bit multiplication with the lower 32-bit of
+ * the product in register "a" and the higher 32-bit in register "a+1".
+ *
+ * 0010_1bbb 0001_1001 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa 64-bit result in registers (R_a+1,R_a)
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_MPYDU 0x28190000
+#define OPC_MPYDUI (OPC_MPYDU | OP_IMM)
+
+/*
+ * The 4-byte encoding of "divu a,b,c" (unsigned division):
+ *
+ * 0010_1bbb 0000_0101 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result (quotient)
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand (divisor)
+ */
+#define OPC_DIVU 0x28050000
+#define OPC_DIVUI (OPC_DIVU | OP_IMM)
+
+/*
+ * The 4-byte encoding of "div a,b,c" (signed division):
+ *
+ * 0010_1bbb 0000_0100 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result (quotient)
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand (divisor)
+ */
+#define OPC_DIVS 0x28040000
+#define OPC_DIVSI (OPC_DIVS | OP_IMM)
+
+/*
+ * The 4-byte encoding of "remu a,b,c" (unsigned remainder):
+ *
+ * 0010_1bbb 0000_1001 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result (remainder)
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand (divisor)
+ */
+#define OPC_REMU 0x28090000
+#define OPC_REMUI (OPC_REMU | OP_IMM)
+
+/*
+ * The 4-byte encoding of "rem a,b,c" (signed remainder):
+ *
+ * 0010_1bbb 0000_1000 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result (remainder)
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand (divisor)
+ */
+#define OPC_REMS 0x28080000
+#define OPC_REMSI (OPC_REMS | OP_IMM)
+
+/*
+ * The 4-byte encoding of "and a,b,c":
+ *
+ * 0010_0bbb 0000_0100 fBBB_cccc ccaa_aaaa
+ *
+ * f: indicates if zero and negative flags should be updated
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_AND 0x20040000
+#define OPC_ANDI (OPC_AND | OP_IMM)
+
+/*
+ * The 4-byte encoding of "tst[.qq] b,c".
+ * Checks if the two input operands have any bit set at the same
+ * position.
+ *
+ * 0010_0bbb 1100_1011 1BBB_cccc cc0q_qqqq
+ *
+ * qq: qqqqq condition code
+ *
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_TST 0x20cb8000
+
+/*
+ * The 4-byte encoding of "or a,b,c":
+ *
+ * 0010_0bbb 0000_0101 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_OR 0x20050000
+#define OPC_ORI (OPC_OR | OP_IMM)
+
+/*
+ * The 4-byte encoding of "xor a,b,c":
+ *
+ * 0010_0bbb 0000_0111 0BBB_cccc ccaa_aaaa
+ *
+ * a: aaaaaa result
+ * b: BBBbbb the 1st input operand
+ * c: cccccc the 2nd input operand
+ */
+#define OPC_XOR 0x20070000
+#define OPC_XORI (OPC_XOR | OP_IMM)
+
+/*
+ * The 4-byte encoding of "not b,c":
+ *
+ * 0010_0bbb 0010_1111 0BBB_cccc cc00_1010
+ *
+ * b: BBBbbb result
+ * c: cccccc input
+ */
+#define OPC_NOT 0x202f000a
+
+/*
+ * The 4-byte encoding of "btst b,u6":
+ *
+ * 0010_0bbb 0101_0001 1BBB_uuuu uu00_0000
+ *
+ * b: BBBbbb input number to check
+ * u6: uuuuuu 6-bit unsigned number specifying bit position to check
+ */
+#define OPC_BTSTU6 0x20518000
+#define BTST_U6(x) (OP_C((x) & 63))
+
+/*
+ * The 4-byte encoding of "asl[.qq] b,b,c" (arithmetic shift left):
+ *
+ * 0010_1bbb 0i00_0000 0BBB_cccc ccaa_aaaa
+ *
+ * i: if set, c is considered a 5-bit immediate, else a reg.
+ *
+ * b: BBBbbb result and the first operand (number to be shifted)
+ * c: cccccc amount to be shifted
+ */
+#define OPC_ASL 0x28000000
+#define ASL_I BIT(22)
+#define ASLI_U6(x) OP_C((x) & 31)
+#define OPC_ASLI (OPC_ASL | ASL_I)
+
+/*
+ * The 4-byte encoding of "asr a,b,c" (arithmetic shift right):
+ *
+ * 0010_1bbb 0i00_0010 0BBB_cccc ccaa_aaaa
+ *
+ * i: if set, c is considered a 6-bit immediate, else a reg.
+ *
+ * a: aaaaaa result
+ * b: BBBbbb first input: number to be shifted
+ * c: cccccc second input: amount to be shifted
+ */
+#define OPC_ASR 0x28020000
+#define ASR_I ASL_I
+#define ASRI_U6(x) ASLI_U6(x)
+#define OPC_ASRI (OPC_ASR | ASR_I)
+
+/*
+ * The 4-byte encoding of "lsr a,b,c" (logical shift right):
+ *
+ * 0010_1bbb 0i00_0001 0BBB_cccc ccaa_aaaa
+ *
+ * i: if set, c is considered a 6-bit immediate, else a reg.
+ *
+ * a: aaaaaa result
+ * b: BBBbbb first input: number to be shifted
+ * c: cccccc second input: amount to be shifted
+ */
+#define OPC_LSR 0x28010000
+#define LSR_I ASL_I
+#define LSRI_U6(x) ASLI_U6(x)
+#define OPC_LSRI (OPC_LSR | LSR_I)
+
+/*
+ * The 4-byte encoding of "swape b,c":
+ *
+ * 0010_1bbb 0010_1111 0bbb_cccc cc00_1001
+ *
+ * b: BBBbbb destination register
+ * c: cccccc source register
+ */
+#define OPC_SWAPE 0x282f0009
+
+/*
+ * Encoding for jump to an address in register:
+ * j reg_c
+ *
+ * 0010_0000 1110_0000 0000_cccc cc00_0000
+ *
+ * c: cccccc register holding the destination address
+ */
+#define OPC_JMP 0x20e00000
+/* Jump to "branch-and-link" register, which effectively is a "return". */
+#define OPC_J_BLINK (OPC_JMP | OP_C(ARC_R_BLINK))
+
+/*
+ * Encoding for jump-and-link to an address in register:
+ * jl reg_c
+ *
+ * 0010_0000 0010_0010 0000_cccc cc00_0000
+ *
+ * c: cccccc register holding the destination address
+ */
+#define OPC_JL 0x20220000
+
+/*
+ * Encoding for (conditional) branch to an offset from the current location
+ * that is word aligned: (PC & 0xffff_fffc) + s21
+ * B[qq] s21
+ *
+ * 0000_0sss ssss_sss0 SSSS_SSSS SS0q_qqqq
+ *
+ * qq: qqqqq condition code
+ * s21: SSSS SSSS_SSss ssss_ssss The displacement (21-bit signed)
+ *
+ * The displacement is supposed to be 16-bit (2-byte) aligned. Therefore,
+ * it should be a multiple of 2. Hence, there is an implied '0' bit at its
+ * LSB: S_SSSS SSSS_Ssss ssss_sss0
+ */
+#define OPC_BCC 0x00000000
+#define BCC_S21(d) ((((d) & 0x7fe) << 16) | (((d) & 0x1ff800) >> 5))
+
+/*
+ * Encoding for unconditional branch to an offset from the current location
+ * that is word aligned: (PC & 0xffff_fffc) + s25
+ * B s25
+ *
+ * 0000_0sss ssss_sss1 SSSS_SSSS SS00_TTTT
+ *
+ * s25: TTTT SSSS SSSS_SSss ssss_ssss The displacement (25-bit signed)
+ *
+ * The displacement is supposed to be 16-bit (2-byte) aligned. Therefore,
+ * it should be a multiple of 2. Hence, there is an implied '0' bit at its
+ * LSB: T TTTS_SSSS SSSS_Ssss ssss_sss0
+ */
+#define OPC_B 0x00010000
+#define B_S25(d) ((((d) & 0x1e00000) >> 21) | BCC_S21(d))
+
+static inline void emit_2_bytes(u8 *buf, u16 bytes)
+{
+ *((u16 *)buf) = bytes;
+}
+
+static inline void emit_4_bytes(u8 *buf, u32 bytes)
+{
+ emit_2_bytes(buf, bytes >> 16);
+ emit_2_bytes(buf + 2, bytes & 0xffff);
+}
+
+static inline u8 bpf_to_arc_size(u8 size)
+{
+ switch (size) {
+ case BPF_B:
+ return ZZ_1_byte;
+ case BPF_H:
+ return ZZ_2_byte;
+ case BPF_W:
+ return ZZ_4_byte;
+ case BPF_DW:
+ return ZZ_8_byte;
+ default:
+ return ZZ_4_byte;
+ }
+}
+
+/************** Encoders (Deal with ARC regs) ************/
+
+/* Move an immediate to register with a 4-byte instruction. */
+static u8 arc_movi_r(u8 *buf, u8 reg, s16 imm)
+{
+ const u32 insn = OPC_MOVI | OP_B(reg) | MOVI_S12(imm);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* rd <- rs */
+static u8 arc_mov_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_MOV | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* The emitted code may have different sizes based on "imm". */
+static u8 arc_mov_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_MOV | OP_B(rd) | OP_IMM;
+
+ if (IN_S12_RANGE(imm))
+ return arc_movi_r(buf, rd, imm);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* The emitted code will always have the same size (8). */
+static u8 arc_mov_i_fixed(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_MOV | OP_B(rd) | OP_IMM;
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* Conditional move. */
+static u8 arc_mov_cc_r(u8 *buf, u8 cc, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_MOV_CC | OP_B(rd) | OP_C(rs) | COND(cc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* Conditional move of a small immediate to rd. */
+static u8 arc_movu_cc_r(u8 *buf, u8 cc, u8 rd, u8 imm)
+{
+ const u32 insn = OPC_MOVU_CC | OP_B(rd) | OP_C(imm) | COND(cc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* Sign extension from a byte. */
+static u8 arc_sexb_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_SEXB | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* Sign extension from two bytes. */
+static u8 arc_sexh_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_SEXH | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* st reg, [reg_mem, off] */
+static u8 arc_st_r(u8 *buf, u8 reg, u8 reg_mem, s16 off, u8 zz)
+{
+ const u32 insn = OPC_STORE | STORE_ZZ(zz) | OP_C(reg) |
+ OP_B(reg_mem) | STORE_S9(off);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* st.aw reg, [sp, -4] */
+static u8 arc_push_r(u8 *buf, u8 reg)
+{
+ const u32 insn = OPC_PUSH | OP_C(reg);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* ld reg, [reg_mem, off] (unsigned) */
+static u8 arc_ld_r(u8 *buf, u8 reg, u8 reg_mem, s16 off, u8 zz)
+{
+ const u32 insn = OPC_LDU | LOAD_ZZ(zz) | LOAD_C(reg) |
+ OP_B(reg_mem) | LOAD_S9(off);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* ld.x reg, [reg_mem, off] (sign extend) */
+static u8 arc_ldx_r(u8 *buf, u8 reg, u8 reg_mem, s16 off, u8 zz)
+{
+ const u32 insn = OPC_LDS | LOAD_ZZ(zz) | LOAD_C(reg) |
+ OP_B(reg_mem) | LOAD_S9(off);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* ld.ab reg,[sp,4] */
+static u8 arc_pop_r(u8 *buf, u8 reg)
+{
+ const u32 insn = OPC_POP | LOAD_C(reg);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* add Ra,Ra,Rc */
+static u8 arc_add_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_ADD | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* add.f Ra,Ra,Rc */
+static u8 arc_addf_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_ADDF | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* add.f Ra,Ra,u6 */
+static u8 arc_addif_r(u8 *buf, u8 ra, u8 u6)
+{
+ const u32 insn = OPC_ADDIF | OP_A(ra) | OP_B(ra) | ADDI_U6(u6);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* add Ra,Ra,u6 */
+static u8 arc_addi_r(u8 *buf, u8 ra, u8 u6)
+{
+ const u32 insn = OPC_ADDI | OP_A(ra) | OP_B(ra) | ADDI_U6(u6);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* add Ra,Rb,imm */
+static u8 arc_add_i(u8 *buf, u8 ra, u8 rb, s32 imm)
+{
+ const u32 insn = OPC_ADD_I | OP_A(ra) | OP_B(rb);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* adc Ra,Ra,Rc */
+static u8 arc_adc_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_ADC | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* adc Ra,Ra,u6 */
+static u8 arc_adci_r(u8 *buf, u8 ra, u8 u6)
+{
+ const u32 insn = OPC_ADCI | OP_A(ra) | OP_B(ra) | ADCI_U6(u6);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* sub Ra,Ra,Rc */
+static u8 arc_sub_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_SUB | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* sub.f Ra,Ra,Rc */
+static u8 arc_subf_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_SUBF | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* sub Ra,Ra,u6 */
+static u8 arc_subi_r(u8 *buf, u8 ra, u8 u6)
+{
+ const u32 insn = OPC_SUBI | OP_A(ra) | OP_B(ra) | SUBI_U6(u6);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* sub Ra,Ra,imm */
+static u8 arc_sub_i(u8 *buf, u8 ra, s32 imm)
+{
+ const u32 insn = OPC_SUB_I | OP_A(ra) | OP_B(ra);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* sbc Ra,Ra,Rc */
+static u8 arc_sbc_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_SBC | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* cmp Rb,Rc */
+static u8 arc_cmp_r(u8 *buf, u8 rb, u8 rc)
+{
+ const u32 insn = OPC_CMP | OP_B(rb) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/*
+ * cmp.z Rb,Rc
+ *
+ * This "cmp.z" variant of compare instruction is used on lower
+ * 32-bits of register pairs after "cmp"ing their upper parts. If the
+ * upper parts are equal (z), then this one will proceed to check the
+ * rest.
+ */
+static u8 arc_cmpz_r(u8 *buf, u8 rb, u8 rc)
+{
+ const u32 insn = OPC_CMP | OP_B(rb) | OP_C(rc) | CC_equal;
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* neg Ra,Rb */
+static u8 arc_neg_r(u8 *buf, u8 ra, u8 rb)
+{
+ const u32 insn = OPC_NEG | OP_A(ra) | OP_B(rb);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* mpy Ra,Rb,Rc */
+static u8 arc_mpy_r(u8 *buf, u8 ra, u8 rb, u8 rc)
+{
+ const u32 insn = OPC_MPY | OP_A(ra) | OP_B(rb) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* mpy Ra,Rb,imm */
+static u8 arc_mpy_i(u8 *buf, u8 ra, u8 rb, s32 imm)
+{
+ const u32 insn = OPC_MPYI | OP_A(ra) | OP_B(rb);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* mpydu Ra,Ra,Rc */
+static u8 arc_mpydu_r(u8 *buf, u8 ra, u8 rc)
+{
+ const u32 insn = OPC_MPYDU | OP_A(ra) | OP_B(ra) | OP_C(rc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* mpydu Ra,Ra,imm */
+static u8 arc_mpydu_i(u8 *buf, u8 ra, s32 imm)
+{
+ const u32 insn = OPC_MPYDUI | OP_A(ra) | OP_B(ra);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* divu Rd,Rd,Rs */
+static u8 arc_divu_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_DIVU | OP_A(rd) | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* divu Rd,Rd,imm */
+static u8 arc_divu_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_DIVUI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* div Rd,Rd,Rs */
+static u8 arc_divs_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_DIVS | OP_A(rd) | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* div Rd,Rd,imm */
+static u8 arc_divs_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_DIVSI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* remu Rd,Rd,Rs */
+static u8 arc_remu_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_REMU | OP_A(rd) | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* remu Rd,Rd,imm */
+static u8 arc_remu_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_REMUI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* rem Rd,Rd,Rs */
+static u8 arc_rems_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_REMS | OP_A(rd) | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* rem Rd,Rd,imm */
+static u8 arc_rems_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_REMSI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* and Rd,Rd,Rs */
+static u8 arc_and_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_AND | OP_A(rd) | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/* and Rd,Rd,limm */
+static u8 arc_and_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_ANDI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+/* tst Rd,Rs */
+static u8 arc_tst_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_TST | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/*
+ * This particular version, "tst.z ...", is meant to be used after a
+ * "tst" on the low 32-bit of register pairs. If that "tst" is not
+ * zero, then we don't need to test the upper 32-bits lest it sets
+ * the zero flag.
+ */
+static u8 arc_tstz_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_TST | OP_B(rd) | OP_C(rs) | CC_equal;
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_or_r(u8 *buf, u8 rd, u8 rs1, u8 rs2)
+{
+ const u32 insn = OPC_OR | OP_A(rd) | OP_B(rs1) | OP_C(rs2);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_or_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_ORI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+static u8 arc_xor_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_XOR | OP_A(rd) | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_xor_i(u8 *buf, u8 rd, s32 imm)
+{
+ const u32 insn = OPC_XORI | OP_A(rd) | OP_B(rd);
+
+ if (buf) {
+ emit_4_bytes(buf, insn);
+ emit_4_bytes(buf + INSN_len_normal, imm);
+ }
+ return INSN_len_normal + INSN_len_imm;
+}
+
+static u8 arc_not_r(u8 *buf, u8 rd, u8 rs)
+{
+ const u32 insn = OPC_NOT | OP_B(rd) | OP_C(rs);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_btst_i(u8 *buf, u8 rs, u8 imm)
+{
+ const u32 insn = OPC_BTSTU6 | OP_B(rs) | BTST_U6(imm);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_asl_r(u8 *buf, u8 rd, u8 rs1, u8 rs2)
+{
+ const u32 insn = OPC_ASL | OP_A(rd) | OP_B(rs1) | OP_C(rs2);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_asli_r(u8 *buf, u8 rd, u8 rs, u8 imm)
+{
+ const u32 insn = OPC_ASLI | OP_A(rd) | OP_B(rs) | ASLI_U6(imm);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_asr_r(u8 *buf, u8 rd, u8 rs1, u8 rs2)
+{
+ const u32 insn = OPC_ASR | OP_A(rd) | OP_B(rs1) | OP_C(rs2);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_asri_r(u8 *buf, u8 rd, u8 rs, u8 imm)
+{
+ const u32 insn = OPC_ASRI | OP_A(rd) | OP_B(rs) | ASRI_U6(imm);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_lsr_r(u8 *buf, u8 rd, u8 rs1, u8 rs2)
+{
+ const u32 insn = OPC_LSR | OP_A(rd) | OP_B(rs1) | OP_C(rs2);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_lsri_r(u8 *buf, u8 rd, u8 rs, u8 imm)
+{
+ const u32 insn = OPC_LSRI | OP_A(rd) | OP_B(rs) | LSRI_U6(imm);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_swape_r(u8 *buf, u8 r)
+{
+ const u32 insn = OPC_SWAPE | OP_B(r) | OP_C(r);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+static u8 arc_jmp_return(u8 *buf)
+{
+ if (buf)
+ emit_4_bytes(buf, OPC_J_BLINK);
+ return INSN_len_normal;
+}
+
+static u8 arc_jl(u8 *buf, u8 reg)
+{
+ const u32 insn = OPC_JL | OP_C(reg);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/*
+ * Conditional jump to an address that is max 21 bits away (signed).
+ *
+ * b<cc> s21
+ */
+static u8 arc_bcc(u8 *buf, u8 cc, int offset)
+{
+ const u32 insn = OPC_BCC | BCC_S21(offset) | COND(cc);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/*
+ * Unconditional jump to an address that is max 25 bits away (signed).
+ *
+ * b s25
+ */
+static u8 arc_b(u8 *buf, s32 offset)
+{
+ const u32 insn = OPC_B | B_S25(offset);
+
+ if (buf)
+ emit_4_bytes(buf, insn);
+ return INSN_len_normal;
+}
+
+/************* Packers (Deal with BPF_REGs) **************/
+
+u8 zext(u8 *buf, u8 rd)
+{
+ if (rd != BPF_REG_FP)
+ return arc_movi_r(buf, REG_HI(rd), 0);
+ else
+ return 0;
+}
+
+u8 mov_r32(u8 *buf, u8 rd, u8 rs, u8 sign_ext)
+{
+ u8 len = 0;
+
+ if (sign_ext) {
+ if (sign_ext == 8)
+ len = arc_sexb_r(buf, REG_LO(rd), REG_LO(rs));
+ else if (sign_ext == 16)
+ len = arc_sexh_r(buf, REG_LO(rd), REG_LO(rs));
+ else if (sign_ext == 32 && rd != rs)
+ len = arc_mov_r(buf, REG_LO(rd), REG_LO(rs));
+
+ return len;
+ }
+
+ /* Unsigned move. */
+
+ if (rd != rs)
+ len = arc_mov_r(buf, REG_LO(rd), REG_LO(rs));
+
+ return len;
+}
+
+u8 mov_r32_i32(u8 *buf, u8 reg, s32 imm)
+{
+ return arc_mov_i(buf, REG_LO(reg), imm);
+}
+
+u8 mov_r64(u8 *buf, u8 rd, u8 rs, u8 sign_ext)
+{
+ u8 len = 0;
+
+ if (sign_ext) {
+ /* First handle the low 32-bit part. */
+ len = mov_r32(buf, rd, rs, sign_ext);
+
+ /* Now propagate the sign bit of LO to HI. */
+ if (sign_ext == 8 || sign_ext == 16 || sign_ext == 32) {
+ len += arc_asri_r(BUF(buf, len),
+ REG_HI(rd), REG_LO(rd), 31);
+ }
+
+ return len;
+ }
+
+ /* Unsigned move. */
+
+ if (rd == rs)
+ return 0;
+
+ len = arc_mov_r(buf, REG_LO(rd), REG_LO(rs));
+
+ if (rs != BPF_REG_FP)
+ len += arc_mov_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ /* BPF_REG_FP is mapped to 32-bit "fp" register. */
+ else
+ len += arc_movi_r(BUF(buf, len), REG_HI(rd), 0);
+
+ return len;
+}
+
+/* Sign extend the 32-bit immediate into 64-bit register pair. */
+u8 mov_r64_i32(u8 *buf, u8 reg, s32 imm)
+{
+ u8 len = 0;
+
+ len = arc_mov_i(buf, REG_LO(reg), imm);
+
+ /* BPF_REG_FP is mapped to 32-bit "fp" register. */
+ if (reg != BPF_REG_FP) {
+ if (imm >= 0)
+ len += arc_movi_r(BUF(buf, len), REG_HI(reg), 0);
+ else
+ len += arc_movi_r(BUF(buf, len), REG_HI(reg), -1);
+ }
+
+ return len;
+}
+
+/*
+ * This is merely used for translation of "LD R, IMM64" instructions
+ * of the BPF. These sort of instructions are sometimes used for
+ * relocations. If during the normal pass, the relocation value is
+ * not known, the BPF instruction may look something like:
+ *
+ * LD R <- 0x0000_0001_0000_0001
+ *
+ * Which will nicely translate to two 4-byte ARC instructions:
+ *
+ * mov R_lo, 1 # imm is small enough to be s12
+ * mov R_hi, 1 # same
+ *
+ * However, during the extra pass, the IMM64 will have changed
+ * to the resolved address and looks something like:
+ *
+ * LD R <- 0x0000_0000_1234_5678
+ *
+ * Now, the translated code will require 12 bytes:
+ *
+ * mov R_lo, 0x12345678 # this is an 8-byte instruction
+ * mov R_hi, 0 # still 4 bytes
+ *
+ * Which in practice will result in overwriting the following
+ * instruction. To avoid such cases, we will always emit codes
+ * with fixed sizes.
+ */
+u8 mov_r64_i64(u8 *buf, u8 reg, u32 lo, u32 hi)
+{
+ u8 len;
+
+ len = arc_mov_i_fixed(buf, REG_LO(reg), lo);
+ len += arc_mov_i_fixed(BUF(buf, len), REG_HI(reg), hi);
+
+ return len;
+}
+
+/*
+ * If the "off"set is too big (doesn't encode as S9) for:
+ *
+ * {ld,st} r, [rm, off]
+ *
+ * Then emit:
+ *
+ * add r10, REG_LO(rm), off
+ *
+ * and make sure that r10 becomes the effective address:
+ *
+ * {ld,st} r, [r10, 0]
+ */
+static u8 adjust_mem_access(u8 *buf, s16 *off, u8 size,
+ u8 rm, u8 *arc_reg_mem)
+{
+ u8 len = 0;
+ *arc_reg_mem = REG_LO(rm);
+
+ if (!IN_S9_RANGE(*off) ||
+ (size == BPF_DW && !IN_S9_RANGE(*off + 4))) {
+ len += arc_add_i(BUF(buf, len),
+ REG_LO(JIT_REG_TMP), REG_LO(rm), (u32)(*off));
+ *arc_reg_mem = REG_LO(JIT_REG_TMP);
+ *off = 0;
+ }
+
+ return len;
+}
+
+/* store rs, [rd, off] */
+u8 store_r(u8 *buf, u8 rs, u8 rd, s16 off, u8 size)
+{
+ u8 len, arc_reg_mem;
+
+ len = adjust_mem_access(buf, &off, size, rd, &arc_reg_mem);
+
+ if (size == BPF_DW) {
+ len += arc_st_r(BUF(buf, len), REG_LO(rs), arc_reg_mem,
+ off, ZZ_4_byte);
+ len += arc_st_r(BUF(buf, len), REG_HI(rs), arc_reg_mem,
+ off + 4, ZZ_4_byte);
+ } else {
+ u8 zz = bpf_to_arc_size(size);
+
+ len += arc_st_r(BUF(buf, len), REG_LO(rs), arc_reg_mem,
+ off, zz);
+ }
+
+ return len;
+}
+
+/*
+ * For {8,16,32}-bit stores:
+ * mov r21, imm
+ * st r21, [...]
+ * For 64-bit stores:
+ * mov r21, imm
+ * st r21, [...]
+ * mov r21, {0,-1}
+ * st r21, [...+4]
+ */
+u8 store_i(u8 *buf, s32 imm, u8 rd, s16 off, u8 size)
+{
+ u8 len, arc_reg_mem;
+ /* REG_LO(JIT_REG_TMP) might be used by "adjust_mem_access()". */
+ const u8 arc_rs = REG_HI(JIT_REG_TMP);
+
+ len = adjust_mem_access(buf, &off, size, rd, &arc_reg_mem);
+
+ if (size == BPF_DW) {
+ len += arc_mov_i(BUF(buf, len), arc_rs, imm);
+ len += arc_st_r(BUF(buf, len), arc_rs, arc_reg_mem,
+ off, ZZ_4_byte);
+ imm = (imm >= 0 ? 0 : -1);
+ len += arc_mov_i(BUF(buf, len), arc_rs, imm);
+ len += arc_st_r(BUF(buf, len), arc_rs, arc_reg_mem,
+ off + 4, ZZ_4_byte);
+ } else {
+ u8 zz = bpf_to_arc_size(size);
+
+ len += arc_mov_i(BUF(buf, len), arc_rs, imm);
+ len += arc_st_r(BUF(buf, len), arc_rs, arc_reg_mem, off, zz);
+ }
+
+ return len;
+}
+
+/*
+ * For the calling convention of a little endian machine, the LO part
+ * must be on top of the stack.
+ */
+static u8 push_r64(u8 *buf, u8 reg)
+{
+ u8 len = 0;
+
+#ifdef __LITTLE_ENDIAN
+ /* BPF_REG_FP is mapped to 32-bit "fp" register. */
+ if (reg != BPF_REG_FP)
+ len += arc_push_r(BUF(buf, len), REG_HI(reg));
+ len += arc_push_r(BUF(buf, len), REG_LO(reg));
+#else
+ len += arc_push_r(BUF(buf, len), REG_LO(reg));
+ if (reg != BPF_REG_FP)
+ len += arc_push_r(BUF(buf, len), REG_HI(reg));
+#endif
+
+ return len;
+}
+
+/* load rd, [rs, off] */
+u8 load_r(u8 *buf, u8 rd, u8 rs, s16 off, u8 size, bool sign_ext)
+{
+ u8 len, arc_reg_mem;
+
+ len = adjust_mem_access(buf, &off, size, rs, &arc_reg_mem);
+
+ if (size == BPF_B || size == BPF_H || size == BPF_W) {
+ const u8 zz = bpf_to_arc_size(size);
+
+ /* Use LD.X only if the data size is less than 32-bit. */
+ if (sign_ext && (zz == ZZ_1_byte || zz == ZZ_2_byte)) {
+ len += arc_ldx_r(BUF(buf, len), REG_LO(rd),
+ arc_reg_mem, off, zz);
+ } else {
+ len += arc_ld_r(BUF(buf, len), REG_LO(rd),
+ arc_reg_mem, off, zz);
+ }
+
+ if (sign_ext) {
+ /* Propagate the sign bit to the higher reg. */
+ len += arc_asri_r(BUF(buf, len),
+ REG_HI(rd), REG_LO(rd), 31);
+ } else {
+ len += arc_movi_r(BUF(buf, len), REG_HI(rd), 0);
+ }
+ } else if (size == BPF_DW) {
+ /*
+ * We are about to issue 2 consecutive loads:
+ *
+ * ld rx, [rb, off+0]
+ * ld ry, [rb, off+4]
+ *
+ * If "rx" and "rb" are the same registers, then the order
+ * should change to guarantee that "rb" remains intact
+ * during these 2 operations:
+ *
+ * ld ry, [rb, off+4]
+ * ld rx, [rb, off+0]
+ */
+ if (REG_LO(rd) != arc_reg_mem) {
+ len += arc_ld_r(BUF(buf, len), REG_LO(rd), arc_reg_mem,
+ off, ZZ_4_byte);
+ len += arc_ld_r(BUF(buf, len), REG_HI(rd), arc_reg_mem,
+ off + 4, ZZ_4_byte);
+ } else {
+ len += arc_ld_r(BUF(buf, len), REG_HI(rd), arc_reg_mem,
+ off + 4, ZZ_4_byte);
+ len += arc_ld_r(BUF(buf, len), REG_LO(rd), arc_reg_mem,
+ off, ZZ_4_byte);
+ }
+ }
+
+ return len;
+}
+
+u8 add_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_add_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 add_r32_i32(u8 *buf, u8 rd, s32 imm)
+{
+ if (IN_U6_RANGE(imm))
+ return arc_addi_r(buf, REG_LO(rd), imm);
+ else
+ return arc_add_i(buf, REG_LO(rd), REG_LO(rd), imm);
+}
+
+u8 add_r64(u8 *buf, u8 rd, u8 rs)
+{
+ u8 len;
+
+ len = arc_addf_r(buf, REG_LO(rd), REG_LO(rs));
+ len += arc_adc_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ return len;
+}
+
+u8 add_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ u8 len;
+
+ if (IN_U6_RANGE(imm)) {
+ len = arc_addif_r(buf, REG_LO(rd), imm);
+ len += arc_adci_r(BUF(buf, len), REG_HI(rd), 0);
+ } else {
+ len = mov_r64_i32(buf, JIT_REG_TMP, imm);
+ len += add_r64(BUF(buf, len), rd, JIT_REG_TMP);
+ }
+ return len;
+}
+
+u8 sub_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_sub_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 sub_r32_i32(u8 *buf, u8 rd, s32 imm)
+{
+ if (IN_U6_RANGE(imm))
+ return arc_subi_r(buf, REG_LO(rd), imm);
+ else
+ return arc_sub_i(buf, REG_LO(rd), imm);
+}
+
+u8 sub_r64(u8 *buf, u8 rd, u8 rs)
+{
+ u8 len;
+
+ len = arc_subf_r(buf, REG_LO(rd), REG_LO(rs));
+ len += arc_sbc_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ return len;
+}
+
+u8 sub_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ u8 len;
+
+ len = mov_r64_i32(buf, JIT_REG_TMP, imm);
+ len += sub_r64(BUF(buf, len), rd, JIT_REG_TMP);
+ return len;
+}
+
+static u8 cmp_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_cmp_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 neg_r32(u8 *buf, u8 r)
+{
+ return arc_neg_r(buf, REG_LO(r), REG_LO(r));
+}
+
+/* In a two's complement system, -r is (~r + 1). */
+u8 neg_r64(u8 *buf, u8 r)
+{
+ u8 len;
+
+ len = arc_not_r(buf, REG_LO(r), REG_LO(r));
+ len += arc_not_r(BUF(buf, len), REG_HI(r), REG_HI(r));
+ len += add_r64_i32(BUF(buf, len), r, 1);
+ return len;
+}
+
+u8 mul_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_mpy_r(buf, REG_LO(rd), REG_LO(rd), REG_LO(rs));
+}
+
+u8 mul_r32_i32(u8 *buf, u8 rd, s32 imm)
+{
+ return arc_mpy_i(buf, REG_LO(rd), REG_LO(rd), imm);
+}
+
+/*
+ * MUL B, C
+ * --------
+ * mpy t0, B_hi, C_lo
+ * mpy t1, B_lo, C_hi
+ * mpydu B_lo, B_lo, C_lo
+ * add B_hi, B_hi, t0
+ * add B_hi, B_hi, t1
+ */
+u8 mul_r64(u8 *buf, u8 rd, u8 rs)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 t1 = REG_HI(JIT_REG_TMP);
+ const u8 C_lo = REG_LO(rs);
+ const u8 C_hi = REG_HI(rs);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ u8 len;
+
+ len = arc_mpy_r(buf, t0, B_hi, C_lo);
+ len += arc_mpy_r(BUF(buf, len), t1, B_lo, C_hi);
+ len += arc_mpydu_r(BUF(buf, len), B_lo, C_lo);
+ len += arc_add_r(BUF(buf, len), B_hi, t0);
+ len += arc_add_r(BUF(buf, len), B_hi, t1);
+
+ return len;
+}
+
+/*
+ * MUL B, imm
+ * ----------
+ *
+ * To get a 64-bit result from a signed 64x32 multiplication:
+ *
+ * B_hi B_lo *
+ * sign imm
+ * -----------------------------
+ * HI(B_lo*imm) LO(B_lo*imm) +
+ * B_hi*imm +
+ * B_lo*sign
+ * -----------------------------
+ * res_hi res_lo
+ *
+ * mpy t1, B_lo, sign(imm)
+ * mpy t0, B_hi, imm
+ * mpydu B_lo, B_lo, imm
+ * add B_hi, B_hi, t0
+ * add B_hi, B_hi, t1
+ *
+ * Note: We can't use signed double multiplication, "mpyd", instead of an
+ * unsigned version, "mpydu", and then get rid of the sign adjustments
+ * calculated in "t1". The signed multiplication, "mpyd", will consider
+ * both operands, "B_lo" and "imm", as signed inputs. However, for this
+ * 64x32 multiplication, "B_lo" must be treated as an unsigned number.
+ */
+u8 mul_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 t1 = REG_HI(JIT_REG_TMP);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ u8 len = 0;
+
+ if (imm == 1)
+ return 0;
+
+ /* Is the sign-extension of the immediate "-1"? */
+ if (imm < 0)
+ len += arc_neg_r(BUF(buf, len), t1, B_lo);
+
+ len += arc_mpy_i(BUF(buf, len), t0, B_hi, imm);
+ len += arc_mpydu_i(BUF(buf, len), B_lo, imm);
+ len += arc_add_r(BUF(buf, len), B_hi, t0);
+
+ /* Add the "sign*B_lo" part, if necessary. */
+ if (imm < 0)
+ len += arc_add_r(BUF(buf, len), B_hi, t1);
+
+ return len;
+}
+
+u8 div_r32(u8 *buf, u8 rd, u8 rs, bool sign_ext)
+{
+ if (sign_ext)
+ return arc_divs_r(buf, REG_LO(rd), REG_LO(rs));
+ else
+ return arc_divu_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 div_r32_i32(u8 *buf, u8 rd, s32 imm, bool sign_ext)
+{
+ if (imm == 0)
+ return 0;
+
+ if (sign_ext)
+ return arc_divs_i(buf, REG_LO(rd), imm);
+ else
+ return arc_divu_i(buf, REG_LO(rd), imm);
+}
+
+u8 mod_r32(u8 *buf, u8 rd, u8 rs, bool sign_ext)
+{
+ if (sign_ext)
+ return arc_rems_r(buf, REG_LO(rd), REG_LO(rs));
+ else
+ return arc_remu_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 mod_r32_i32(u8 *buf, u8 rd, s32 imm, bool sign_ext)
+{
+ if (imm == 0)
+ return 0;
+
+ if (sign_ext)
+ return arc_rems_i(buf, REG_LO(rd), imm);
+ else
+ return arc_remu_i(buf, REG_LO(rd), imm);
+}
+
+u8 and_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_and_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 and_r32_i32(u8 *buf, u8 rd, s32 imm)
+{
+ return arc_and_i(buf, REG_LO(rd), imm);
+}
+
+u8 and_r64(u8 *buf, u8 rd, u8 rs)
+{
+ u8 len;
+
+ len = arc_and_r(buf, REG_LO(rd), REG_LO(rs));
+ len += arc_and_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ return len;
+}
+
+u8 and_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ u8 len;
+
+ len = mov_r64_i32(buf, JIT_REG_TMP, imm);
+ len += and_r64(BUF(buf, len), rd, JIT_REG_TMP);
+ return len;
+}
+
+static u8 tst_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_tst_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 or_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_or_r(buf, REG_LO(rd), REG_LO(rd), REG_LO(rs));
+}
+
+u8 or_r32_i32(u8 *buf, u8 rd, s32 imm)
+{
+ return arc_or_i(buf, REG_LO(rd), imm);
+}
+
+u8 or_r64(u8 *buf, u8 rd, u8 rs)
+{
+ u8 len;
+
+ len = arc_or_r(buf, REG_LO(rd), REG_LO(rd), REG_LO(rs));
+ len += arc_or_r(BUF(buf, len), REG_HI(rd), REG_HI(rd), REG_HI(rs));
+ return len;
+}
+
+u8 or_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ u8 len;
+
+ len = mov_r64_i32(buf, JIT_REG_TMP, imm);
+ len += or_r64(BUF(buf, len), rd, JIT_REG_TMP);
+ return len;
+}
+
+u8 xor_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_xor_r(buf, REG_LO(rd), REG_LO(rs));
+}
+
+u8 xor_r32_i32(u8 *buf, u8 rd, s32 imm)
+{
+ return arc_xor_i(buf, REG_LO(rd), imm);
+}
+
+u8 xor_r64(u8 *buf, u8 rd, u8 rs)
+{
+ u8 len;
+
+ len = arc_xor_r(buf, REG_LO(rd), REG_LO(rs));
+ len += arc_xor_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ return len;
+}
+
+u8 xor_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ u8 len;
+
+ len = mov_r64_i32(buf, JIT_REG_TMP, imm);
+ len += xor_r64(BUF(buf, len), rd, JIT_REG_TMP);
+ return len;
+}
+
+/* "asl a,b,c" --> "a = (b << (c & 31))". */
+u8 lsh_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_asl_r(buf, REG_LO(rd), REG_LO(rd), REG_LO(rs));
+}
+
+u8 lsh_r32_i32(u8 *buf, u8 rd, u8 imm)
+{
+ return arc_asli_r(buf, REG_LO(rd), REG_LO(rd), imm);
+}
+
+/*
+ * algorithm
+ * ---------
+ * if (n <= 32)
+ * to_hi = lo >> (32-n) # (32-n) is the negate of "n" in a 5-bit width.
+ * lo <<= n
+ * hi <<= n
+ * hi |= to_hi
+ * else
+ * hi = lo << (n-32)
+ * lo = 0
+ *
+ * assembly translation for "LSH B, C"
+ * (heavily influenced by ARC gcc)
+ * -----------------------------------
+ * not t0, C_lo # The first 3 lines are almost the same as:
+ * lsr t1, B_lo, 1 # neg t0, C_lo
+ * lsr t1, t1, t0 # lsr t1, B_lo, t0 --> t1 is "to_hi"
+ * mov t0, C_lo* # with one important difference. In "neg"
+ * asl B_lo, B_lo, t0 # version, when C_lo=0, t1 becomes B_lo while
+ * asl B_hi, B_hi, t0 # it should be 0. The "not" approach instead,
+ * or B_hi, B_hi, t1 # "shift"s t1 once and 31 times, practically
+ * btst t0, 5 # setting it to 0 when C_lo=0.
+ * mov.ne B_hi, B_lo**
+ * mov.ne B_lo, 0
+ *
+ * *The "mov t0, C_lo" is necessary to cover the cases that C is the same
+ * register as B.
+ *
+ * **ARC performs a shift in this manner: B <<= (C & 31)
+ * For 32<=n<64, "n-32" and "n&31" are the same. Therefore, "B << n" and
+ * "B << (n-32)" yield the same results. e.g. the results of "B << 35" and
+ * "B << 3" are the same.
+ *
+ * The behaviour is undefined for n >= 64.
+ */
+u8 lsh_r64(u8 *buf, u8 rd, u8 rs)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 t1 = REG_HI(JIT_REG_TMP);
+ const u8 C_lo = REG_LO(rs);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ u8 len;
+
+ len = arc_not_r(buf, t0, C_lo);
+ len += arc_lsri_r(BUF(buf, len), t1, B_lo, 1);
+ len += arc_lsr_r(BUF(buf, len), t1, t1, t0);
+ len += arc_mov_r(BUF(buf, len), t0, C_lo);
+ len += arc_asl_r(BUF(buf, len), B_lo, B_lo, t0);
+ len += arc_asl_r(BUF(buf, len), B_hi, B_hi, t0);
+ len += arc_or_r(BUF(buf, len), B_hi, B_hi, t1);
+ len += arc_btst_i(BUF(buf, len), t0, 5);
+ len += arc_mov_cc_r(BUF(buf, len), CC_unequal, B_hi, B_lo);
+ len += arc_movu_cc_r(BUF(buf, len), CC_unequal, B_lo, 0);
+
+ return len;
+}
+
+/*
+ * if (n < 32)
+ * to_hi = B_lo >> 32-n # extract upper n bits
+ * lo <<= n
+ * hi <<=n
+ * hi |= to_hi
+ * else if (n < 64)
+ * hi = lo << n-32
+ * lo = 0
+ */
+u8 lsh_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ const u8 n = (u8)imm;
+ u8 len = 0;
+
+ if (n == 0) {
+ return 0;
+ } else if (n <= 31) {
+ len = arc_lsri_r(buf, t0, B_lo, 32 - n);
+ len += arc_asli_r(BUF(buf, len), B_lo, B_lo, n);
+ len += arc_asli_r(BUF(buf, len), B_hi, B_hi, n);
+ len += arc_or_r(BUF(buf, len), B_hi, B_hi, t0);
+ } else if (n <= 63) {
+ len = arc_asli_r(buf, B_hi, B_lo, n - 32);
+ len += arc_movi_r(BUF(buf, len), B_lo, 0);
+ }
+ /* n >= 64 is undefined behaviour. */
+
+ return len;
+}
+
+/* "lsr a,b,c" --> "a = (b >> (c & 31))". */
+u8 rsh_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_lsr_r(buf, REG_LO(rd), REG_LO(rd), REG_LO(rs));
+}
+
+u8 rsh_r32_i32(u8 *buf, u8 rd, u8 imm)
+{
+ return arc_lsri_r(buf, REG_LO(rd), REG_LO(rd), imm);
+}
+
+/*
+ * For better commentary, see lsh_r64().
+ *
+ * algorithm
+ * ---------
+ * if (n <= 32)
+ * to_lo = hi << (32-n)
+ * hi >>= n
+ * lo >>= n
+ * lo |= to_lo
+ * else
+ * lo = hi >> (n-32)
+ * hi = 0
+ *
+ * RSH B,C
+ * ----------
+ * not t0, C_lo
+ * asl t1, B_hi, 1
+ * asl t1, t1, t0
+ * mov t0, C_lo
+ * lsr B_hi, B_hi, t0
+ * lsr B_lo, B_lo, t0
+ * or B_lo, B_lo, t1
+ * btst t0, 5
+ * mov.ne B_lo, B_hi
+ * mov.ne B_hi, 0
+ */
+u8 rsh_r64(u8 *buf, u8 rd, u8 rs)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 t1 = REG_HI(JIT_REG_TMP);
+ const u8 C_lo = REG_LO(rs);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ u8 len;
+
+ len = arc_not_r(buf, t0, C_lo);
+ len += arc_asli_r(BUF(buf, len), t1, B_hi, 1);
+ len += arc_asl_r(BUF(buf, len), t1, t1, t0);
+ len += arc_mov_r(BUF(buf, len), t0, C_lo);
+ len += arc_lsr_r(BUF(buf, len), B_hi, B_hi, t0);
+ len += arc_lsr_r(BUF(buf, len), B_lo, B_lo, t0);
+ len += arc_or_r(BUF(buf, len), B_lo, B_lo, t1);
+ len += arc_btst_i(BUF(buf, len), t0, 5);
+ len += arc_mov_cc_r(BUF(buf, len), CC_unequal, B_lo, B_hi);
+ len += arc_movu_cc_r(BUF(buf, len), CC_unequal, B_hi, 0);
+
+ return len;
+}
+
+/*
+ * if (n < 32)
+ * to_lo = B_lo << 32-n # extract lower n bits, right-padded with 32-n 0s
+ * lo >>=n
+ * hi >>=n
+ * hi |= to_lo
+ * else if (n < 64)
+ * lo = hi >> n-32
+ * hi = 0
+ */
+u8 rsh_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ const u8 n = (u8)imm;
+ u8 len = 0;
+
+ if (n == 0) {
+ return 0;
+ } else if (n <= 31) {
+ len = arc_asli_r(buf, t0, B_hi, 32 - n);
+ len += arc_lsri_r(BUF(buf, len), B_lo, B_lo, n);
+ len += arc_lsri_r(BUF(buf, len), B_hi, B_hi, n);
+ len += arc_or_r(BUF(buf, len), B_lo, B_lo, t0);
+ } else if (n <= 63) {
+ len = arc_lsri_r(buf, B_lo, B_hi, n - 32);
+ len += arc_movi_r(BUF(buf, len), B_hi, 0);
+ }
+ /* n >= 64 is undefined behaviour. */
+
+ return len;
+}
+
+/* "asr a,b,c" --> "a = (b s>> (c & 31))". */
+u8 arsh_r32(u8 *buf, u8 rd, u8 rs)
+{
+ return arc_asr_r(buf, REG_LO(rd), REG_LO(rd), REG_LO(rs));
+}
+
+u8 arsh_r32_i32(u8 *buf, u8 rd, u8 imm)
+{
+ return arc_asri_r(buf, REG_LO(rd), REG_LO(rd), imm);
+}
+
+/*
+ * For comparison, see rsh_r64().
+ *
+ * algorithm
+ * ---------
+ * if (n <= 32)
+ * to_lo = hi << (32-n)
+ * hi s>>= n
+ * lo >>= n
+ * lo |= to_lo
+ * else
+ * hi_sign = hi s>>31
+ * lo = hi s>> (n-32)
+ * hi = hi_sign
+ *
+ * ARSH B,C
+ * ----------
+ * not t0, C_lo
+ * asl t1, B_hi, 1
+ * asl t1, t1, t0
+ * mov t0, C_lo
+ * asr B_hi, B_hi, t0
+ * lsr B_lo, B_lo, t0
+ * or B_lo, B_lo, t1
+ * btst t0, 5
+ * asr t0, B_hi, 31 # now, t0 = 0 or -1 based on B_hi's sign
+ * mov.ne B_lo, B_hi
+ * mov.ne B_hi, t0
+ */
+u8 arsh_r64(u8 *buf, u8 rd, u8 rs)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 t1 = REG_HI(JIT_REG_TMP);
+ const u8 C_lo = REG_LO(rs);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ u8 len;
+
+ len = arc_not_r(buf, t0, C_lo);
+ len += arc_asli_r(BUF(buf, len), t1, B_hi, 1);
+ len += arc_asl_r(BUF(buf, len), t1, t1, t0);
+ len += arc_mov_r(BUF(buf, len), t0, C_lo);
+ len += arc_asr_r(BUF(buf, len), B_hi, B_hi, t0);
+ len += arc_lsr_r(BUF(buf, len), B_lo, B_lo, t0);
+ len += arc_or_r(BUF(buf, len), B_lo, B_lo, t1);
+ len += arc_btst_i(BUF(buf, len), t0, 5);
+ len += arc_asri_r(BUF(buf, len), t0, B_hi, 31);
+ len += arc_mov_cc_r(BUF(buf, len), CC_unequal, B_lo, B_hi);
+ len += arc_mov_cc_r(BUF(buf, len), CC_unequal, B_hi, t0);
+
+ return len;
+}
+
+/*
+ * if (n < 32)
+ * to_lo = lo << 32-n # extract lower n bits, right-padded with 32-n 0s
+ * lo >>=n
+ * hi s>>=n
+ * hi |= to_lo
+ * else if (n < 64)
+ * lo = hi s>> n-32
+ * hi = (lo[msb] ? -1 : 0)
+ */
+u8 arsh_r64_i32(u8 *buf, u8 rd, s32 imm)
+{
+ const u8 t0 = REG_LO(JIT_REG_TMP);
+ const u8 B_lo = REG_LO(rd);
+ const u8 B_hi = REG_HI(rd);
+ const u8 n = (u8)imm;
+ u8 len = 0;
+
+ if (n == 0) {
+ return 0;
+ } else if (n <= 31) {
+ len = arc_asli_r(buf, t0, B_hi, 32 - n);
+ len += arc_lsri_r(BUF(buf, len), B_lo, B_lo, n);
+ len += arc_asri_r(BUF(buf, len), B_hi, B_hi, n);
+ len += arc_or_r(BUF(buf, len), B_lo, B_lo, t0);
+ } else if (n <= 63) {
+ len = arc_asri_r(buf, B_lo, B_hi, n - 32);
+ len += arc_movi_r(BUF(buf, len), B_hi, -1);
+ len += arc_btst_i(BUF(buf, len), B_lo, 31);
+ len += arc_movu_cc_r(BUF(buf, len), CC_equal, B_hi, 0);
+ }
+ /* n >= 64 is undefined behaviour. */
+
+ return len;
+}
+
+u8 gen_swap(u8 *buf, u8 rd, u8 size, u8 endian, bool force, bool do_zext)
+{
+ u8 len = 0;
+#ifdef __BIG_ENDIAN
+ const u8 host_endian = BPF_FROM_BE;
+#else
+ const u8 host_endian = BPF_FROM_LE;
+#endif
+ if (host_endian != endian || force) {
+ switch (size) {
+ case 16:
+ /*
+ * r = B4B3_B2B1 << 16 --> r = B2B1_0000
+ * then, swape(r) would become the desired 0000_B1B2
+ */
+ len = arc_asli_r(buf, REG_LO(rd), REG_LO(rd), 16);
+ fallthrough;
+ case 32:
+ len += arc_swape_r(BUF(buf, len), REG_LO(rd));
+ if (do_zext)
+ len += zext(BUF(buf, len), rd);
+ break;
+ case 64:
+ /*
+ * swap "hi" and "lo":
+ * hi ^= lo;
+ * lo ^= hi;
+ * hi ^= lo;
+ * and then swap the bytes in "hi" and "lo".
+ */
+ len = arc_xor_r(buf, REG_HI(rd), REG_LO(rd));
+ len += arc_xor_r(BUF(buf, len), REG_LO(rd), REG_HI(rd));
+ len += arc_xor_r(BUF(buf, len), REG_HI(rd), REG_LO(rd));
+ len += arc_swape_r(BUF(buf, len), REG_LO(rd));
+ len += arc_swape_r(BUF(buf, len), REG_HI(rd));
+ break;
+ default:
+ /* The caller must have handled this. */
+ break;
+ }
+ } else {
+ /*
+ * If the same endianness, there's not much to do other
+ * than zeroing out the upper bytes based on the "size".
+ */
+ switch (size) {
+ case 16:
+ len = arc_and_i(buf, REG_LO(rd), 0xffff);
+ fallthrough;
+ case 32:
+ if (do_zext)
+ len += zext(BUF(buf, len), rd);
+ break;
+ case 64:
+ break;
+ default:
+ /* The caller must have handled this. */
+ break;
+ }
+ }
+
+ return len;
+}
+
+/*
+ * To create a frame, all that is needed is:
+ *
+ * push fp
+ * mov fp, sp
+ * sub sp, <frame_size>
+ *
+ * "push fp" is taken care of separately while saving the clobbered registers.
+ * All that remains is copying SP value to FP and shrinking SP's address space
+ * for any possible function call to come.
+ */
+static inline u8 frame_create(u8 *buf, u16 size)
+{
+ u8 len;
+
+ len = arc_mov_r(buf, ARC_R_FP, ARC_R_SP);
+ if (IN_U6_RANGE(size))
+ len += arc_subi_r(BUF(buf, len), ARC_R_SP, size);
+ else
+ len += arc_sub_i(BUF(buf, len), ARC_R_SP, size);
+ return len;
+}
+
+/*
+ * mov sp, fp
+ *
+ * The value of SP upon entering was copied to FP.
+ */
+static inline u8 frame_restore(u8 *buf)
+{
+ return arc_mov_r(buf, ARC_R_SP, ARC_R_FP);
+}
+
+/*
+ * Going from a JITed code to the native caller:
+ *
+ * mov ARC_ABI_RET_lo, BPF_REG_0_lo # r0 <- r8
+ * mov ARC_ABI_RET_hi, BPF_REG_0_hi # r1 <- r9
+ */
+static u8 bpf_to_arc_return(u8 *buf)
+{
+ u8 len;
+
+ len = arc_mov_r(buf, ARC_R_0, REG_LO(BPF_REG_0));
+ len += arc_mov_r(BUF(buf, len), ARC_R_1, REG_HI(BPF_REG_0));
+ return len;
+}
+
+/*
+ * Coming back from an external (in-kernel) function to the JITed code:
+ *
+ * mov ARC_ABI_RET_lo, BPF_REG_0_lo # r8 <- r0
+ * mov ARC_ABI_RET_hi, BPF_REG_0_hi # r9 <- r1
+ */
+u8 arc_to_bpf_return(u8 *buf)
+{
+ u8 len;
+
+ len = arc_mov_r(buf, REG_LO(BPF_REG_0), ARC_R_0);
+ len += arc_mov_r(BUF(buf, len), REG_HI(BPF_REG_0), ARC_R_1);
+ return len;
+}
+
+/*
+ * This translation leads to:
+ *
+ * mov r10, addr # always an 8-byte instruction
+ * jl [r10]
+ *
+ * The length of the "mov" must be fixed (8), otherwise it may diverge
+ * during the normal and extra passes:
+ *
+ * normal pass extra pass
+ *
+ * 180: mov r10,0 | 180: mov r10,0x700578d8
+ * 184: jl [r10] | 188: jl [r10]
+ * 188: add.f r16,r16,0x1 | 18c: adc r17,r17,0
+ * 18c: adc r17,r17,0 |
+ *
+ * In the above example, the change from "r10 <- 0" to "r10 <- 0x700578d8"
+ * has led to an increase in the length of the "mov" instruction.
+ * Inadvertently, that caused the loss of the "add.f" instruction.
+ */
+static u8 jump_and_link(u8 *buf, u32 addr)
+{
+ u8 len;
+
+ len = arc_mov_i_fixed(buf, REG_LO(JIT_REG_TMP), addr);
+ len += arc_jl(BUF(buf, len), REG_LO(JIT_REG_TMP));
+ return len;
+}
+
+/*
+ * This function determines which ARC registers must be saved and restored.
+ * It does so by looking into:
+ *
+ * "bpf_reg": The clobbered (destination) BPF register
+ * "is_call": Indicator if the current instruction is a call
+ *
+ * When a register of interest is clobbered, its corresponding bit position
+ * in return value, "usage", is set to true.
+ */
+u32 mask_for_used_regs(u8 bpf_reg, bool is_call)
+{
+ u32 usage = 0;
+
+ /* BPF registers that must be saved. */
+ if (bpf_reg >= BPF_REG_6 && bpf_reg <= BPF_REG_9) {
+ usage |= BIT(REG_LO(bpf_reg));
+ usage |= BIT(REG_HI(bpf_reg));
+ /*
+ * Using the frame pointer register implies that it should
+ * be saved and reinitialised with the current frame data.
+ */
+ } else if (bpf_reg == BPF_REG_FP) {
+ usage |= BIT(REG_LO(BPF_REG_FP));
+ /* Could there be some ARC registers that must to be saved? */
+ } else {
+ if (REG_LO(bpf_reg) >= ARC_CALLEE_SAVED_REG_FIRST &&
+ REG_LO(bpf_reg) <= ARC_CALLEE_SAVED_REG_LAST)
+ usage |= BIT(REG_LO(bpf_reg));
+
+ if (REG_HI(bpf_reg) >= ARC_CALLEE_SAVED_REG_FIRST &&
+ REG_HI(bpf_reg) <= ARC_CALLEE_SAVED_REG_LAST)
+ usage |= BIT(REG_HI(bpf_reg));
+ }
+
+ /* A "call" indicates that ARC's "blink" reg must be saved. */
+ usage |= is_call ? BIT(ARC_R_BLINK) : 0;
+
+ return usage;
+}
+
+/*
+ * push blink # if blink is marked as clobbered
+ * push r[0-n] # if r[i] is marked as clobbered
+ * push fp # if fp is marked as clobbered
+ * mov fp, sp # if frame_size > 0 (clobbers fp)
+ * sub sp, <frame_size> # same as above
+ */
+u8 arc_prologue(u8 *buf, u32 usage, u16 frame_size)
+{
+ u8 len = 0;
+ u32 gp_regs = 0;
+
+ /* Deal with blink first. */
+ if (usage & BIT(ARC_R_BLINK))
+ len += arc_push_r(BUF(buf, len), ARC_R_BLINK);
+
+ gp_regs = usage & ~(BIT(ARC_R_BLINK) | BIT(ARC_R_FP));
+ while (gp_regs) {
+ u8 reg = __builtin_ffs(gp_regs) - 1;
+
+ len += arc_push_r(BUF(buf, len), reg);
+ gp_regs &= ~BIT(reg);
+ }
+
+ /* Deal with fp last. */
+ if ((usage & BIT(ARC_R_FP)) || frame_size > 0)
+ len += arc_push_r(BUF(buf, len), ARC_R_FP);
+
+ if (frame_size > 0)
+ len += frame_create(BUF(buf, len), frame_size);
+
+#ifdef ARC_BPF_JIT_DEBUG
+ if ((usage & BIT(ARC_R_FP)) && frame_size == 0) {
+ pr_err("FP is being saved while there is no frame.");
+ BUG();
+ }
+#endif
+
+ return len;
+}
+
+/*
+ * mov sp, fp # if frame_size > 0
+ * pop fp # if fp is marked as clobbered
+ * pop r[n-0] # if r[i] is marked as clobbered
+ * pop blink # if blink is marked as clobbered
+ * mov r0, r8 # always: ABI_return <- BPF_return
+ * mov r1, r9 # continuation of above
+ * j [blink] # always
+ *
+ * "fp being marked as clobbered" and "frame_size > 0" are the two sides of
+ * the same coin.
+ */
+u8 arc_epilogue(u8 *buf, u32 usage, u16 frame_size)
+{
+ u32 len = 0;
+ u32 gp_regs = 0;
+
+#ifdef ARC_BPF_JIT_DEBUG
+ if ((usage & BIT(ARC_R_FP)) && frame_size == 0) {
+ pr_err("FP is being saved while there is no frame.");
+ BUG();
+ }
+#endif
+
+ if (frame_size > 0)
+ len += frame_restore(BUF(buf, len));
+
+ /* Deal with fp first. */
+ if ((usage & BIT(ARC_R_FP)) || frame_size > 0)
+ len += arc_pop_r(BUF(buf, len), ARC_R_FP);
+
+ gp_regs = usage & ~(BIT(ARC_R_BLINK) | BIT(ARC_R_FP));
+ while (gp_regs) {
+ /* "usage" is 32-bit, each bit indicating an ARC register. */
+ u8 reg = 31 - __builtin_clz(gp_regs);
+
+ len += arc_pop_r(BUF(buf, len), reg);
+ gp_regs &= ~BIT(reg);
+ }
+
+ /* Deal with blink last. */
+ if (usage & BIT(ARC_R_BLINK))
+ len += arc_pop_r(BUF(buf, len), ARC_R_BLINK);
+
+ /* Wrap up the return value and jump back to the caller. */
+ len += bpf_to_arc_return(BUF(buf, len));
+ len += arc_jmp_return(BUF(buf, len));
+
+ return len;
+}
+
+/*
+ * For details on the algorithm, see the comments of "gen_jcc_64()".
+ *
+ * This data structure is holding information for jump translations.
+ *
+ * jit_off: How many bytes into the current JIT address, "b"ranch insn. occurs
+ * cond: The condition that the ARC branch instruction must use
+ *
+ * e.g.:
+ *
+ * BPF_JGE R1, R0, @target
+ * ------------------------
+ * |
+ * v
+ * 0x1000: cmp r3, r1 # 0x1000 is the JIT address for "BPF_JGE ..." insn
+ * 0x1004: bhi @target # first jump (branch higher)
+ * 0x1008: blo @end # second jump acting as a skip (end is 0x1014)
+ * 0x100C: cmp r2, r0 # the lower 32 bits are evaluated
+ * 0x1010: bhs @target # third jump (branch higher or same)
+ * 0x1014: ...
+ *
+ * The jit_off(set) of the "bhi" is 4 bytes.
+ * The cond(ition) for the "bhi" is "CC_great_u".
+ *
+ * The jit_off(set) is necessary for calculating the exact displacement
+ * to the "target" address:
+ *
+ * jit_address + jit_off(set) - @target
+ * 0x1000 + 4 - @target
+ */
+#define JCC64_NR_OF_JMPS 3 /* Number of jumps in jcc64 template. */
+#define JCC64_INSNS_TO_END 3 /* Number of insn. inclusive the 2nd jmp to end. */
+#define JCC64_SKIP_JMP 1 /* Index of the "skip" jump to "end". */
+static const struct {
+ /*
+ * "jit_off" is common between all "jmp[]" and is coupled with
+ * "cond" of each "jmp[]" instance. e.g.:
+ *
+ * arcv2_64_jccs.jit_off[1]
+ * arcv2_64_jccs.jmp[ARC_CC_UGT].cond[1]
+ *
+ * Are indicating that the second jump in JITed code of "UGT"
+ * is at offset "jit_off[1]" while its condition is "cond[1]".
+ */
+ u8 jit_off[JCC64_NR_OF_JMPS];
+
+ struct {
+ u8 cond[JCC64_NR_OF_JMPS];
+ } jmp[ARC_CC_SLE + 1];
+} arcv2_64_jccs = {
+ .jit_off = {
+ INSN_len_normal * 1,
+ INSN_len_normal * 2,
+ INSN_len_normal * 4
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * bhi @target # 1: u>
+ * blo @end # 2: u<
+ * cmp rd_lo, rs_lo
+ * bhi @target # 3: u>
+ * end:
+ */
+ .jmp[ARC_CC_UGT] = {
+ .cond = {CC_great_u, CC_less_u, CC_great_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * bhi @target # 1: u>
+ * blo @end # 2: u<
+ * cmp rd_lo, rs_lo
+ * bhs @target # 3: u>=
+ * end:
+ */
+ .jmp[ARC_CC_UGE] = {
+ .cond = {CC_great_u, CC_less_u, CC_great_eq_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * blo @target # 1: u<
+ * bhi @end # 2: u>
+ * cmp rd_lo, rs_lo
+ * blo @target # 3: u<
+ * end:
+ */
+ .jmp[ARC_CC_ULT] = {
+ .cond = {CC_less_u, CC_great_u, CC_less_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * blo @target # 1: u<
+ * bhi @end # 2: u>
+ * cmp rd_lo, rs_lo
+ * bls @target # 3: u<=
+ * end:
+ */
+ .jmp[ARC_CC_ULE] = {
+ .cond = {CC_less_u, CC_great_u, CC_less_eq_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * bgt @target # 1: s>
+ * blt @end # 2: s<
+ * cmp rd_lo, rs_lo
+ * bhi @target # 3: u>
+ * end:
+ */
+ .jmp[ARC_CC_SGT] = {
+ .cond = {CC_great_s, CC_less_s, CC_great_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * bgt @target # 1: s>
+ * blt @end # 2: s<
+ * cmp rd_lo, rs_lo
+ * bhs @target # 3: u>=
+ * end:
+ */
+ .jmp[ARC_CC_SGE] = {
+ .cond = {CC_great_s, CC_less_s, CC_great_eq_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * blt @target # 1: s<
+ * bgt @end # 2: s>
+ * cmp rd_lo, rs_lo
+ * blo @target # 3: u<
+ * end:
+ */
+ .jmp[ARC_CC_SLT] = {
+ .cond = {CC_less_s, CC_great_s, CC_less_u}
+ },
+ /*
+ * cmp rd_hi, rs_hi
+ * blt @target # 1: s<
+ * bgt @end # 2: s>
+ * cmp rd_lo, rs_lo
+ * bls @target # 3: u<=
+ * end:
+ */
+ .jmp[ARC_CC_SLE] = {
+ .cond = {CC_less_s, CC_great_s, CC_less_eq_u}
+ }
+};
+
+/*
+ * The displacement (offset) for ARC's "b"ranch instruction is the distance
+ * from the aligned version of _current_ instruction (PCL) to the target
+ * instruction:
+ *
+ * DISP = TARGET - PCL # PCL is the word aligned PC
+ */
+static inline s32 get_displacement(u32 curr_off, u32 targ_off)
+{
+ return (s32)(targ_off - (curr_off & ~3L));
+}
+
+/*
+ * "disp"lacement should be:
+ *
+ * 1. 16-bit aligned.
+ * 2. fit in S25, because no "condition code" is supposed to be encoded.
+ */
+static inline bool is_valid_far_disp(s32 disp)
+{
+ return (!(disp & 1) && IN_S25_RANGE(disp));
+}
+
+/*
+ * "disp"lacement should be:
+ *
+ * 1. 16-bit aligned.
+ * 2. fit in S21, because "condition code" is supposed to be encoded too.
+ */
+static inline bool is_valid_near_disp(s32 disp)
+{
+ return (!(disp & 1) && IN_S21_RANGE(disp));
+}
+
+/*
+ * cmp rd_hi, rs_hi
+ * cmp.z rd_lo, rs_lo
+ * b{eq,ne} @target
+ * | |
+ * | `--> "eq" param is false (JNE)
+ * `-----> "eq" param is true (JEQ)
+ */
+static int gen_j_eq_64(u8 *buf, u8 rd, u8 rs, bool eq,
+ u32 curr_off, u32 targ_off)
+{
+ s32 disp;
+ u8 len = 0;
+
+ len += arc_cmp_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ len += arc_cmpz_r(BUF(buf, len), REG_LO(rd), REG_LO(rs));
+ disp = get_displacement(curr_off + len, targ_off);
+ len += arc_bcc(BUF(buf, len), eq ? CC_equal : CC_unequal, disp);
+
+ return len;
+}
+
+/*
+ * tst rd_hi, rs_hi
+ * tst.z rd_lo, rs_lo
+ * bne @target
+ */
+static u8 gen_jset_64(u8 *buf, u8 rd, u8 rs, u32 curr_off, u32 targ_off)
+{
+ u8 len = 0;
+ s32 disp;
+
+ len += arc_tst_r(BUF(buf, len), REG_HI(rd), REG_HI(rs));
+ len += arc_tstz_r(BUF(buf, len), REG_LO(rd), REG_LO(rs));
+ disp = get_displacement(curr_off + len, targ_off);
+ len += arc_bcc(BUF(buf, len), CC_unequal, disp);
+
+ return len;
+}
+
+/*
+ * Verify if all the jumps for a JITed jcc64 operation are valid,
+ * by consulting the data stored at "arcv2_64_jccs".
+ */
+static bool check_jcc_64(u32 curr_off, u32 targ_off, u8 cond)
+{
+ size_t i;
+
+ if (cond >= ARC_CC_LAST)
+ return false;
+
+ for (i = 0; i < JCC64_NR_OF_JMPS; i++) {
+ u32 from, to;
+
+ from = curr_off + arcv2_64_jccs.jit_off[i];
+ /* for the 2nd jump, we jump to the end of block. */
+ if (i != JCC64_SKIP_JMP)
+ to = targ_off;
+ else
+ to = from + (JCC64_INSNS_TO_END * INSN_len_normal);
+ /* There is a "cc" in the instruction, so a "near" jump. */
+ if (!is_valid_near_disp(get_displacement(from, to)))
+ return false;
+ }
+
+ return true;
+}
+
+/* Can the jump from "curr_off" to "targ_off" actually happen? */
+bool check_jmp_64(u32 curr_off, u32 targ_off, u8 cond)
+{
+ s32 disp;
+
+ switch (cond) {
+ case ARC_CC_UGT:
+ case ARC_CC_UGE:
+ case ARC_CC_ULT:
+ case ARC_CC_ULE:
+ case ARC_CC_SGT:
+ case ARC_CC_SGE:
+ case ARC_CC_SLT:
+ case ARC_CC_SLE:
+ return check_jcc_64(curr_off, targ_off, cond);
+ case ARC_CC_EQ:
+ case ARC_CC_NE:
+ case ARC_CC_SET:
+ /*
+ * The "jump" for the JITed BPF_J{SET,EQ,NE} is actually the
+ * 3rd instruction. See comments of "gen_j{set,_eq}_64()".
+ */
+ curr_off += 2 * INSN_len_normal;
+ disp = get_displacement(curr_off, targ_off);
+ /* There is a "cc" field in the issued instruction. */
+ return is_valid_near_disp(disp);
+ case ARC_CC_AL:
+ disp = get_displacement(curr_off, targ_off);
+ return is_valid_far_disp(disp);
+ default:
+ return false;
+ }
+}
+
+/*
+ * The template for the 64-bit jumps with the following BPF conditions
+ *
+ * u< u<= u> u>= s< s<= s> s>=
+ *
+ * Looks like below:
+ *
+ * cmp rd_hi, rs_hi
+ * b<c1> @target
+ * b<c2> @end
+ * cmp rd_lo, rs_lo # if execution reaches here, r{d,s}_hi are equal
+ * b<c3> @target
+ * end:
+ *
+ * "c1" is the condition that JIT is handling minus the equality part.
+ * For instance if we have to translate an "unsigned greater or equal",
+ * then "c1" will be "unsigned greater". We won't know about equality
+ * until all 64-bits of data (higeher and lower registers) are processed.
+ *
+ * "c2" is the counter logic of "c1". For instance, if "c1" is originated
+ * from "s>", then "c2" would be "s<". Notice that equality doesn't play
+ * a role here either, because the lower 32 bits are not processed yet.
+ *
+ * "c3" is the unsigned version of "c1", no matter if the BPF condition
+ * was signed or unsigned. An unsigned version is necessary, because the
+ * MSB of the lower 32 bits does not reflect a sign in the whole 64-bit
+ * scheme. Otherwise, 64-bit comparisons like
+ * (0x0000_0000,0x8000_0000) s>= (0x0000_0000,0x0000_0000)
+ * would yield an incorrect result. Finally, if there is an equality
+ * check in the BPF condition, it will be reflected in "c3".
+ *
+ * You can find all the instances of this template where the
+ * "arcv2_64_jccs" is getting initialised.
+ */
+static u8 gen_jcc_64(u8 *buf, u8 rd, u8 rs, u8 cond,
+ u32 curr_off, u32 targ_off)
+{
+ s32 disp;
+ u32 end_off;
+ const u8 *cc = arcv2_64_jccs.jmp[cond].cond;
+ u8 len = 0;
+
+ /* cmp rd_hi, rs_hi */
+ len += arc_cmp_r(buf, REG_HI(rd), REG_HI(rs));
+
+ /* b<c1> @target */
+ disp = get_displacement(curr_off + len, targ_off);
+ len += arc_bcc(BUF(buf, len), cc[0], disp);
+
+ /* b<c2> @end */
+ end_off = curr_off + len + (JCC64_INSNS_TO_END * INSN_len_normal);
+ disp = get_displacement(curr_off + len, end_off);
+ len += arc_bcc(BUF(buf, len), cc[1], disp);
+
+ /* cmp rd_lo, rs_lo */
+ len += arc_cmp_r(BUF(buf, len), REG_LO(rd), REG_LO(rs));
+
+ /* b<c3> @target */
+ disp = get_displacement(curr_off + len, targ_off);
+ len += arc_bcc(BUF(buf, len), cc[2], disp);
+
+ return len;
+}
+
+/*
+ * This function only applies the necessary logic to make the proper
+ * translations. All the sanity checks must have already been done
+ * by calling the check_jmp_64().
+ */
+u8 gen_jmp_64(u8 *buf, u8 rd, u8 rs, u8 cond, u32 curr_off, u32 targ_off)
+{
+ u8 len = 0;
+ bool eq = false;
+ s32 disp;
+
+ switch (cond) {
+ case ARC_CC_AL:
+ disp = get_displacement(curr_off, targ_off);
+ len = arc_b(buf, disp);
+ break;
+ case ARC_CC_UGT:
+ case ARC_CC_UGE:
+ case ARC_CC_ULT:
+ case ARC_CC_ULE:
+ case ARC_CC_SGT:
+ case ARC_CC_SGE:
+ case ARC_CC_SLT:
+ case ARC_CC_SLE:
+ len = gen_jcc_64(buf, rd, rs, cond, curr_off, targ_off);
+ break;
+ case ARC_CC_EQ:
+ eq = true;
+ fallthrough;
+ case ARC_CC_NE:
+ len = gen_j_eq_64(buf, rd, rs, eq, curr_off, targ_off);
+ break;
+ case ARC_CC_SET:
+ len = gen_jset_64(buf, rd, rs, curr_off, targ_off);
+ break;
+ default:
+#ifdef ARC_BPF_JIT_DEBUG
+ pr_err("64-bit jump condition is not known.");
+ BUG();
+#endif
+ }
+ return len;
+}
+
+/*
+ * The condition codes to use when generating JIT instructions
+ * for 32-bit jumps.
+ *
+ * The "ARC_CC_AL" index is not really used by the code, but it
+ * is here for the sake of completeness.
+ *
+ * The "ARC_CC_SET" becomes "CC_unequal" because of the "tst"
+ * instruction that precedes the conditional branch.
+ */
+static const u8 arcv2_32_jmps[ARC_CC_LAST] = {
+ [ARC_CC_UGT] = CC_great_u,
+ [ARC_CC_UGE] = CC_great_eq_u,
+ [ARC_CC_ULT] = CC_less_u,
+ [ARC_CC_ULE] = CC_less_eq_u,
+ [ARC_CC_SGT] = CC_great_s,
+ [ARC_CC_SGE] = CC_great_eq_s,
+ [ARC_CC_SLT] = CC_less_s,
+ [ARC_CC_SLE] = CC_less_eq_s,
+ [ARC_CC_AL] = CC_always,
+ [ARC_CC_EQ] = CC_equal,
+ [ARC_CC_NE] = CC_unequal,
+ [ARC_CC_SET] = CC_unequal
+};
+
+/* Can the jump from "curr_off" to "targ_off" actually happen? */
+bool check_jmp_32(u32 curr_off, u32 targ_off, u8 cond)
+{
+ u8 addendum;
+ s32 disp;
+
+ if (cond >= ARC_CC_LAST)
+ return false;
+
+ /*
+ * The unconditional jump happens immediately, while the rest
+ * are either preceded by a "cmp" or "tst" instruction.
+ */
+ addendum = (cond == ARC_CC_AL) ? 0 : INSN_len_normal;
+ disp = get_displacement(curr_off + addendum, targ_off);
+
+ if (ARC_CC_AL)
+ return is_valid_far_disp(disp);
+ else
+ return is_valid_near_disp(disp);
+}
+
+/*
+ * The JITed code for 32-bit (conditional) branches:
+ *
+ * ARC_CC_AL @target
+ * b @jit_targ_addr
+ *
+ * ARC_CC_SET rd, rs, @target
+ * tst rd, rs
+ * bnz @jit_targ_addr
+ *
+ * ARC_CC_xx rd, rs, @target
+ * cmp rd, rs
+ * b<cc> @jit_targ_addr # cc = arcv2_32_jmps[xx]
+ */
+u8 gen_jmp_32(u8 *buf, u8 rd, u8 rs, u8 cond, u32 curr_off, u32 targ_off)
+{
+ s32 disp;
+ u8 len = 0;
+
+ /*
+ * Although this must have already been checked by "check_jmp_32()",
+ * we're not going to risk accessing "arcv2_32_jmps" array without
+ * the boundary check.
+ */
+ if (cond >= ARC_CC_LAST) {
+#ifdef ARC_BPF_JIT_DEBUG
+ pr_err("32-bit jump condition is not known.");
+ BUG();
+#endif
+ return 0;
+ }
+
+ /* If there is a "condition", issue the "cmp" or "tst" first. */
+ if (cond != ARC_CC_AL) {
+ if (cond == ARC_CC_SET)
+ len = tst_r32(buf, rd, rs);
+ else
+ len = cmp_r32(buf, rd, rs);
+ /*
+ * The issued instruction affects the "disp"lacement as
+ * it alters the "curr_off" by its "len"gth. The "curr_off"
+ * should always point to the jump instruction.
+ */
+ disp = get_displacement(curr_off + len, targ_off);
+ len += arc_bcc(BUF(buf, len), arcv2_32_jmps[cond], disp);
+ } else {
+ /* The straight forward unconditional jump. */
+ disp = get_displacement(curr_off, targ_off);
+ len = arc_b(buf, disp);
+ }
+
+ return len;
+}
+
+/*
+ * Generate code for functions calls. There can be two types of calls:
+ *
+ * - Calling another BPF function
+ * - Calling an in-kernel function which is compiled by ARC gcc
+ *
+ * In the later case, we must comply to ARCv2 ABI and handle arguments
+ * and return values accordingly.
+ */
+u8 gen_func_call(u8 *buf, ARC_ADDR func_addr, bool external_func)
+{
+ u8 len = 0;
+
+ /*
+ * In case of an in-kernel function call, always push the 5th
+ * argument onto the stack, because that's where the ABI dictates
+ * it should be found. If the callee doesn't really use it, no harm
+ * is done. The stack is readjusted either way after the call.
+ */
+ if (external_func)
+ len += push_r64(BUF(buf, len), BPF_REG_5);
+
+ len += jump_and_link(BUF(buf, len), func_addr);
+
+ if (external_func)
+ len += arc_add_i(BUF(buf, len), ARC_R_SP, ARC_R_SP, ARG5_SIZE);
+
+ return len;
+}
diff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c
new file mode 100644
index 000000000000..e3628922c24a
--- /dev/null
+++ b/arch/arc/net/bpf_jit_core.c
@@ -0,0 +1,1425 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The back-end-agnostic part of Just-In-Time compiler for eBPF bytecode.
+ *
+ * Copyright (c) 2024 Synopsys Inc.
+ * Author: Shahab Vahedi <shahab@synopsys.com>
+ */
+#include <linux/bug.h>
+#include "bpf_jit.h"
+
+/*
+ * Check for the return value. A pattern used often in this file.
+ * There must be a "ret" variable of type "int" in the scope.
+ */
+#define CHECK_RET(cmd) \
+ do { \
+ ret = (cmd); \
+ if (ret < 0) \
+ return ret; \
+ } while (0)
+
+#ifdef ARC_BPF_JIT_DEBUG
+/* Dumps bytes in /var/log/messages at KERN_INFO level (4). */
+static void dump_bytes(const u8 *buf, u32 len, const char *header)
+{
+ u8 line[64];
+ size_t i, j;
+
+ pr_info("-----------------[ %s ]-----------------\n", header);
+
+ for (i = 0, j = 0; i < len; i++) {
+ /* Last input byte? */
+ if (i == len - 1) {
+ j += scnprintf(line + j, 64 - j, "0x%02x", buf[i]);
+ pr_info("%s\n", line);
+ break;
+ }
+ /* End of line? */
+ else if (i % 8 == 7) {
+ j += scnprintf(line + j, 64 - j, "0x%02x", buf[i]);
+ pr_info("%s\n", line);
+ j = 0;
+ } else {
+ j += scnprintf(line + j, 64 - j, "0x%02x, ", buf[i]);
+ }
+ }
+}
+#endif /* ARC_BPF_JIT_DEBUG */
+
+/********************* JIT context ***********************/
+
+/*
+ * buf: Translated instructions end up here.
+ * len: The length of whole block in bytes.
+ * index: The offset at which the _next_ instruction may be put.
+ */
+struct jit_buffer {
+ u8 *buf;
+ u32 len;
+ u32 index;
+};
+
+/*
+ * This is a subset of "struct jit_context" that its information is deemed
+ * necessary for the next extra pass to come.
+ *
+ * bpf_header: Needed to finally lock the region.
+ * bpf2insn: Used to find the translation for instructions of interest.
+ *
+ * Things like "jit.buf" and "jit.len" can be retrieved respectively from
+ * "prog->bpf_func" and "prog->jited_len".
+ */
+struct arc_jit_data {
+ struct bpf_binary_header *bpf_header;
+ u32 *bpf2insn;
+};
+
+/*
+ * The JIT pertinent context that is used by different functions.
+ *
+ * prog: The current eBPF program being handled.
+ * orig_prog: The original eBPF program before any possible change.
+ * jit: The JIT buffer and its length.
+ * bpf_header: The JITed program header. "jit.buf" points inside it.
+ * emit: If set, opcodes are written to memory; else, a dry-run.
+ * do_zext: If true, 32-bit sub-regs must be zero extended.
+ * bpf2insn: Maps BPF insn indices to their counterparts in jit.buf.
+ * bpf2insn_valid: Indicates if "bpf2ins" is populated with the mappings.
+ * jit_data: A piece of memory to transfer data to the next pass.
+ * arc_regs_clobbered: Each bit status determines if that arc reg is clobbered.
+ * save_blink: Whether ARC's "blink" register needs to be saved.
+ * frame_size: Derived from "prog->aux->stack_depth".
+ * epilogue_offset: Used by early "return"s in the code to jump here.
+ * need_extra_pass: A forecast if an "extra_pass" will occur.
+ * is_extra_pass: Indicates if the current pass is an extra pass.
+ * user_bpf_prog: True, if VM opcodes come from a real program.
+ * blinded: True if "constant blinding" step returned a new "prog".
+ * success: Indicates if the whole JIT went OK.
+ */
+struct jit_context {
+ struct bpf_prog *prog;
+ struct bpf_prog *orig_prog;
+ struct jit_buffer jit;
+ struct bpf_binary_header *bpf_header;
+ bool emit;
+ bool do_zext;
+ u32 *bpf2insn;
+ bool bpf2insn_valid;
+ struct arc_jit_data *jit_data;
+ u32 arc_regs_clobbered;
+ bool save_blink;
+ u16 frame_size;
+ u32 epilogue_offset;
+ bool need_extra_pass;
+ bool is_extra_pass;
+ bool user_bpf_prog;
+ bool blinded;
+ bool success;
+};
+
+/*
+ * If we're in ARC_BPF_JIT_DEBUG mode and the debug level is right, dump the
+ * input BPF stream. "bpf_jit_dump()" is not fully suited for this purpose.
+ */
+static void vm_dump(const struct bpf_prog *prog)
+{
+#ifdef ARC_BPF_JIT_DEBUG
+ if (bpf_jit_enable > 1)
+ dump_bytes((u8 *)prog->insns, 8 * prog->len, " VM ");
+#endif
+}
+
+/*
+ * If the right level of debug is set, dump the bytes. There are 2 variants
+ * of this function:
+ *
+ * 1. Use the standard bpf_jit_dump() which is meant only for JITed code.
+ * 2. Use the dump_bytes() to match its "vm_dump()" instance.
+ */
+static void jit_dump(const struct jit_context *ctx)
+{
+#ifdef ARC_BPF_JIT_DEBUG
+ u8 header[8];
+#endif
+ const int pass = ctx->is_extra_pass ? 2 : 1;
+
+ if (bpf_jit_enable <= 1 || !ctx->prog->jited)
+ return;
+
+#ifdef ARC_BPF_JIT_DEBUG
+ scnprintf(header, sizeof(header), "JIT:%d", pass);
+ dump_bytes(ctx->jit.buf, ctx->jit.len, header);
+ pr_info("\n");
+#else
+ bpf_jit_dump(ctx->prog->len, ctx->jit.len, pass, ctx->jit.buf);
+#endif
+}
+
+/* Initialise the context so there's no garbage. */
+static int jit_ctx_init(struct jit_context *ctx, struct bpf_prog *prog)
+{
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->orig_prog = prog;
+
+ /* If constant blinding was requested but failed, scram. */
+ ctx->prog = bpf_jit_blind_constants(prog);
+ if (IS_ERR(ctx->prog))
+ return PTR_ERR(ctx->prog);
+ ctx->blinded = (ctx->prog != ctx->orig_prog);
+
+ /* If the verifier doesn't zero-extend, then we have to do it. */
+ ctx->do_zext = !ctx->prog->aux->verifier_zext;
+
+ ctx->is_extra_pass = ctx->prog->jited;
+ ctx->user_bpf_prog = ctx->prog->is_func;
+
+ return 0;
+}
+
+/*
+ * Only after the first iteration of normal pass (the dry-run),
+ * there are valid offsets in ctx->bpf2insn array.
+ */
+static inline bool offsets_available(const struct jit_context *ctx)
+{
+ return ctx->bpf2insn_valid;
+}
+
+/*
+ * "*mem" should be freed when there is no "extra pass" to come,
+ * or the compilation terminated abruptly. A few of such memory
+ * allocations are: ctx->jit_data and ctx->bpf2insn.
+ */
+static inline void maybe_free(struct jit_context *ctx, void **mem)
+{
+ if (*mem) {
+ if (!ctx->success || !ctx->need_extra_pass) {
+ kfree(*mem);
+ *mem = NULL;
+ }
+ }
+}
+
+/*
+ * Free memories based on the status of the context.
+ *
+ * A note about "bpf_header": On successful runs, "bpf_header" is
+ * not freed, because "jit.buf", a sub-array of it, is returned as
+ * the "bpf_func". However, "bpf_header" is lost and nothing points
+ * to it. This should not cause a leakage, because apparently
+ * "bpf_header" can be revived by "bpf_jit_binary_hdr()". This is
+ * how "bpf_jit_free()" in "kernel/bpf/core.c" releases the memory.
+ */
+static void jit_ctx_cleanup(struct jit_context *ctx)
+{
+ if (ctx->blinded) {
+ /* if all went well, release the orig_prog. */
+ if (ctx->success)
+ bpf_jit_prog_release_other(ctx->prog, ctx->orig_prog);
+ else
+ bpf_jit_prog_release_other(ctx->orig_prog, ctx->prog);
+ }
+
+ maybe_free(ctx, (void **)&ctx->bpf2insn);
+ maybe_free(ctx, (void **)&ctx->jit_data);
+
+ if (!ctx->bpf2insn)
+ ctx->bpf2insn_valid = false;
+
+ /* Freeing "bpf_header" is enough. "jit.buf" is a sub-array of it. */
+ if (!ctx->success && ctx->bpf_header) {
+ bpf_jit_binary_free(ctx->bpf_header);
+ ctx->bpf_header = NULL;
+ ctx->jit.buf = NULL;
+ ctx->jit.index = 0;
+ ctx->jit.len = 0;
+ }
+
+ ctx->emit = false;
+ ctx->do_zext = false;
+}
+
+/*
+ * Analyse the register usage and record the frame size.
+ * The register usage is determined by consulting the back-end.
+ */
+static void analyze_reg_usage(struct jit_context *ctx)
+{
+ size_t i;
+ u32 usage = 0;
+ const struct bpf_insn *insn = ctx->prog->insnsi;
+
+ for (i = 0; i < ctx->prog->len; i++) {
+ u8 bpf_reg;
+ bool call;
+
+ bpf_reg = insn[i].dst_reg;
+ call = (insn[i].code == (BPF_JMP | BPF_CALL)) ? true : false;
+ usage |= mask_for_used_regs(bpf_reg, call);
+ }
+
+ ctx->arc_regs_clobbered = usage;
+ ctx->frame_size = ctx->prog->aux->stack_depth;
+}
+
+/* Verify that no instruction will be emitted when there is no buffer. */
+static inline int jit_buffer_check(const struct jit_context *ctx)
+{
+ if (ctx->emit) {
+ if (!ctx->jit.buf) {
+ pr_err("bpf-jit: inconsistence state; no "
+ "buffer to emit instructions.\n");
+ return -EINVAL;
+ } else if (ctx->jit.index > ctx->jit.len) {
+ pr_err("bpf-jit: estimated JIT length is less "
+ "than the emitted instructions.\n");
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+/* On a dry-run (emit=false), "jit.len" is growing gradually. */
+static inline void jit_buffer_update(struct jit_context *ctx, u32 n)
+{
+ if (!ctx->emit)
+ ctx->jit.len += n;
+ else
+ ctx->jit.index += n;
+}
+
+/* Based on "emit", determine the address where instructions are emitted. */
+static inline u8 *effective_jit_buf(const struct jit_context *ctx)
+{
+ return ctx->emit ? (ctx->jit.buf + ctx->jit.index) : NULL;
+}
+
+/* Prologue based on context variables set by "analyze_reg_usage()". */
+static int handle_prologue(struct jit_context *ctx)
+{
+ int ret;
+ u8 *buf = effective_jit_buf(ctx);
+ u32 len = 0;
+
+ CHECK_RET(jit_buffer_check(ctx));
+
+ len = arc_prologue(buf, ctx->arc_regs_clobbered, ctx->frame_size);
+ jit_buffer_update(ctx, len);
+
+ return 0;
+}
+
+/* The counter part for "handle_prologue()". */
+static int handle_epilogue(struct jit_context *ctx)
+{
+ int ret;
+ u8 *buf = effective_jit_buf(ctx);
+ u32 len = 0;
+
+ CHECK_RET(jit_buffer_check(ctx));
+
+ len = arc_epilogue(buf, ctx->arc_regs_clobbered, ctx->frame_size);
+ jit_buffer_update(ctx, len);
+
+ return 0;
+}
+
+/* Tell which number of the BPF instruction we are dealing with. */
+static inline s32 get_index_for_insn(const struct jit_context *ctx,
+ const struct bpf_insn *insn)
+{
+ return (insn - ctx->prog->insnsi);
+}
+
+/*
+ * In most of the cases, the "offset" is read from "insn->off". However,
+ * if it is an unconditional BPF_JMP32, then it comes from "insn->imm".
+ *
+ * (Courtesy of "cpu=v4" support)
+ */
+static inline s32 get_offset(const struct bpf_insn *insn)
+{
+ if ((BPF_CLASS(insn->code) == BPF_JMP32) &&
+ (BPF_OP(insn->code) == BPF_JA))
+ return insn->imm;
+ else
+ return insn->off;
+}
+
+/*
+ * Determine to which number of the BPF instruction we're jumping to.
+ *
+ * The "offset" is interpreted as the "number" of BPF instructions
+ * from the _next_ BPF instruction. e.g.:
+ *
+ * 4 means 4 instructions after the next insn
+ * 0 means 0 instructions after the next insn -> fallthrough.
+ * -1 means 1 instruction before the next insn -> jmp to current insn.
+ *
+ * Another way to look at this, "offset" is the number of instructions
+ * that exist between the current instruction and the target instruction.
+ *
+ * It is worth noting that a "mov r,i64", which is 16-byte long, is
+ * treated as two instructions long, therefore "offset" needn't be
+ * treated specially for those. Everything is uniform.
+ */
+static inline s32 get_target_index_for_insn(const struct jit_context *ctx,
+ const struct bpf_insn *insn)
+{
+ return (get_index_for_insn(ctx, insn) + 1) + get_offset(insn);
+}
+
+/* Is there an immediate operand encoded in the "insn"? */
+static inline bool has_imm(const struct bpf_insn *insn)
+{
+ return BPF_SRC(insn->code) == BPF_K;
+}
+
+/* Is the last BPF instruction? */
+static inline bool is_last_insn(const struct bpf_prog *prog, u32 idx)
+{
+ return idx == (prog->len - 1);
+}
+
+/*
+ * Invocation of this function, conditionally signals the need for
+ * an extra pass. The conditions that must be met are:
+ *
+ * 1. The current pass itself shouldn't be an extra pass.
+ * 2. The stream of bytes being JITed must come from a user program.
+ */
+static inline void set_need_for_extra_pass(struct jit_context *ctx)
+{
+ if (!ctx->is_extra_pass)
+ ctx->need_extra_pass = ctx->user_bpf_prog;
+}
+
+/*
+ * Check if the "size" is valid and then transfer the control to
+ * the back-end for the swap.
+ */
+static int handle_swap(u8 *buf, u8 rd, u8 size, u8 endian,
+ bool force, bool do_zext, u8 *len)
+{
+ /* Sanity check on the size. */
+ switch (size) {
+ case 16:
+ case 32:
+ case 64:
+ break;
+ default:
+ pr_err("bpf-jit: invalid size for swap.\n");
+ return -EINVAL;
+ }
+
+ *len = gen_swap(buf, rd, size, endian, force, do_zext);
+
+ return 0;
+}
+
+/* Checks if the (instruction) index is in valid range. */
+static inline bool check_insn_idx_valid(const struct jit_context *ctx,
+ const s32 idx)
+{
+ return (idx >= 0 && idx < ctx->prog->len);
+}
+
+/*
+ * Decouple the back-end from BPF by converting BPF conditions
+ * to internal enum. ARC_CC_* start from 0 and are used as index
+ * to an array. BPF_J* usage must end after this conversion.
+ */
+static int bpf_cond_to_arc(const u8 op, u8 *arc_cc)
+{
+ switch (op) {
+ case BPF_JA:
+ *arc_cc = ARC_CC_AL;
+ break;
+ case BPF_JEQ:
+ *arc_cc = ARC_CC_EQ;
+ break;
+ case BPF_JGT:
+ *arc_cc = ARC_CC_UGT;
+ break;
+ case BPF_JGE:
+ *arc_cc = ARC_CC_UGE;
+ break;
+ case BPF_JSET:
+ *arc_cc = ARC_CC_SET;
+ break;
+ case BPF_JNE:
+ *arc_cc = ARC_CC_NE;
+ break;
+ case BPF_JSGT:
+ *arc_cc = ARC_CC_SGT;
+ break;
+ case BPF_JSGE:
+ *arc_cc = ARC_CC_SGE;
+ break;
+ case BPF_JLT:
+ *arc_cc = ARC_CC_ULT;
+ break;
+ case BPF_JLE:
+ *arc_cc = ARC_CC_ULE;
+ break;
+ case BPF_JSLT:
+ *arc_cc = ARC_CC_SLT;
+ break;
+ case BPF_JSLE:
+ *arc_cc = ARC_CC_SLE;
+ break;
+ default:
+ pr_err("bpf-jit: can't handle condition 0x%02X\n", op);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Check a few things for a supposedly "jump" instruction:
+ *
+ * 0. "insn" is a "jump" instruction, but not the "call/exit" variant.
+ * 1. The current "insn" index is in valid range.
+ * 2. The index of target instruction is in valid range.
+ */
+static int check_bpf_jump(const struct jit_context *ctx,
+ const struct bpf_insn *insn)
+{
+ const u8 class = BPF_CLASS(insn->code);
+ const u8 op = BPF_OP(insn->code);
+
+ /* Must be a jmp(32) instruction that is not a "call/exit". */
+ if ((class != BPF_JMP && class != BPF_JMP32) ||
+ (op == BPF_CALL || op == BPF_EXIT)) {
+ pr_err("bpf-jit: not a jump instruction.\n");
+ return -EINVAL;
+ }
+
+ if (!check_insn_idx_valid(ctx, get_index_for_insn(ctx, insn))) {
+ pr_err("bpf-jit: the bpf jump insn is not in prog.\n");
+ return -EINVAL;
+ }
+
+ if (!check_insn_idx_valid(ctx, get_target_index_for_insn(ctx, insn))) {
+ pr_err("bpf-jit: bpf jump label is out of range.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Based on input "insn", consult "ctx->bpf2insn" to get the
+ * related index (offset) of the translation in JIT stream.
+ */
+static u32 get_curr_jit_off(const struct jit_context *ctx,
+ const struct bpf_insn *insn)
+{
+ const s32 idx = get_index_for_insn(ctx, insn);
+#ifdef ARC_BPF_JIT_DEBUG
+ BUG_ON(!offsets_available(ctx) || !check_insn_idx_valid(ctx, idx));
+#endif
+ return ctx->bpf2insn[idx];
+}
+
+/*
+ * The input "insn" must be a jump instruction.
+ *
+ * Based on input "insn", consult "ctx->bpf2insn" to get the
+ * related JIT index (offset) of "target instruction" that
+ * "insn" would jump to.
+ */
+static u32 get_targ_jit_off(const struct jit_context *ctx,
+ const struct bpf_insn *insn)
+{
+ const s32 tidx = get_target_index_for_insn(ctx, insn);
+#ifdef ARC_BPF_JIT_DEBUG
+ BUG_ON(!offsets_available(ctx) || !check_insn_idx_valid(ctx, tidx));
+#endif
+ return ctx->bpf2insn[tidx];
+}
+
+/*
+ * This function will return 0 for a feasible jump.
+ *
+ * Consult the back-end to check if it finds it feasible to emit
+ * the necessary instructions based on "cond" and the displacement
+ * between the "from_off" and the "to_off".
+ */
+static int feasible_jit_jump(u32 from_off, u32 to_off, u8 cond, bool j32)
+{
+ int ret = 0;
+
+ if (j32) {
+ if (!check_jmp_32(from_off, to_off, cond))
+ ret = -EFAULT;
+ } else {
+ if (!check_jmp_64(from_off, to_off, cond))
+ ret = -EFAULT;
+ }
+
+ if (ret != 0)
+ pr_err("bpf-jit: the JIT displacement is not OK.\n");
+
+ return ret;
+}
+
+/*
+ * This jump handler performs the following steps:
+ *
+ * 1. Compute ARC's internal condition code from BPF's
+ * 2. Determine the bitness of the operation (32 vs. 64)
+ * 3. Sanity check on BPF stream
+ * 4. Sanity check on what is supposed to be JIT's displacement
+ * 5. And finally, emit the necessary instructions
+ *
+ * The last two steps are performed through the back-end.
+ * The value of steps 1 and 2 are necessary inputs for the back-end.
+ */
+static int handle_jumps(const struct jit_context *ctx,
+ const struct bpf_insn *insn,
+ u8 *len)
+{
+ u8 cond;
+ int ret = 0;
+ u8 *buf = effective_jit_buf(ctx);
+ const bool j32 = (BPF_CLASS(insn->code) == BPF_JMP32) ? true : false;
+ const u8 rd = insn->dst_reg;
+ u8 rs = insn->src_reg;
+ u32 curr_off = 0, targ_off = 0;
+
+ *len = 0;
+
+ /* Map the BPF condition to internal enum. */
+ CHECK_RET(bpf_cond_to_arc(BPF_OP(insn->code), &cond));
+
+ /* Sanity check on the BPF byte stream. */
+ CHECK_RET(check_bpf_jump(ctx, insn));
+
+ /*
+ * Move the immediate into a temporary register _now_ for 2 reasons:
+ *
+ * 1. "gen_jmp_{32,64}()" deal with operands in registers.
+ *
+ * 2. The "len" parameter will grow so that the current jit offset
+ * (curr_off) will have increased to a point where the necessary
+ * instructions can be inserted by "gen_jmp_{32,64}()".
+ */
+ if (has_imm(insn) && cond != ARC_CC_AL) {
+ if (j32) {
+ *len += mov_r32_i32(BUF(buf, *len), JIT_REG_TMP,
+ insn->imm);
+ } else {
+ *len += mov_r64_i32(BUF(buf, *len), JIT_REG_TMP,
+ insn->imm);
+ }
+ rs = JIT_REG_TMP;
+ }
+
+ /* If the offsets are known, check if the branch can occur. */
+ if (offsets_available(ctx)) {
+ curr_off = get_curr_jit_off(ctx, insn) + *len;
+ targ_off = get_targ_jit_off(ctx, insn);
+
+ /* Sanity check on the back-end side. */
+ CHECK_RET(feasible_jit_jump(curr_off, targ_off, cond, j32));
+ }
+
+ if (j32) {
+ *len += gen_jmp_32(BUF(buf, *len), rd, rs, cond,
+ curr_off, targ_off);
+ } else {
+ *len += gen_jmp_64(BUF(buf, *len), rd, rs, cond,
+ curr_off, targ_off);
+ }
+
+ return ret;
+}
+
+/* Jump to translated epilogue address. */
+static int handle_jmp_epilogue(struct jit_context *ctx,
+ const struct bpf_insn *insn, u8 *len)
+{
+ u8 *buf = effective_jit_buf(ctx);
+ u32 curr_off = 0, epi_off = 0;
+
+ /* Check the offset only if the data is available. */
+ if (offsets_available(ctx)) {
+ curr_off = get_curr_jit_off(ctx, insn);
+ epi_off = ctx->epilogue_offset;
+
+ if (!check_jmp_64(curr_off, epi_off, ARC_CC_AL)) {
+ pr_err("bpf-jit: epilogue offset is not valid.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Jump to "epilogue offset" (rd and rs don't matter). */
+ *len = gen_jmp_64(buf, 0, 0, ARC_CC_AL, curr_off, epi_off);
+
+ return 0;
+}
+
+/* Try to get the resolved address and generate the instructions. */
+static int handle_call(struct jit_context *ctx,
+ const struct bpf_insn *insn,
+ u8 *len)
+{
+ int ret;
+ bool in_kernel_func, fixed = false;
+ u64 addr = 0;
+ u8 *buf = effective_jit_buf(ctx);
+
+ ret = bpf_jit_get_func_addr(ctx->prog, insn, ctx->is_extra_pass,
+ &addr, &fixed);
+ if (ret < 0) {
+ pr_err("bpf-jit: can't get the address for call.\n");
+ return ret;
+ }
+ in_kernel_func = (fixed ? true : false);
+
+ /* No valuable address retrieved (yet). */
+ if (!fixed && !addr)
+ set_need_for_extra_pass(ctx);
+
+ *len = gen_func_call(buf, (ARC_ADDR)addr, in_kernel_func);
+
+ if (insn->src_reg != BPF_PSEUDO_CALL) {
+ /* Assigning ABI's return reg to JIT's return reg. */
+ *len += arc_to_bpf_return(BUF(buf, *len));
+ }
+
+ return 0;
+}
+
+/*
+ * Try to generate instructions for loading a 64-bit immediate.
+ * These sort of instructions are usually associated with the 64-bit
+ * relocations: R_BPF_64_64. Therefore, signal the need for an extra
+ * pass if the circumstances are right.
+ */
+static int handle_ld_imm64(struct jit_context *ctx,
+ const struct bpf_insn *insn,
+ u8 *len)
+{
+ const s32 idx = get_index_for_insn(ctx, insn);
+ u8 *buf = effective_jit_buf(ctx);
+
+ /* We're about to consume 2 VM instructions. */
+ if (is_last_insn(ctx->prog, idx)) {
+ pr_err("bpf-jit: need more data for 64-bit immediate.\n");
+ return -EINVAL;
+ }
+
+ *len = mov_r64_i64(buf, insn->dst_reg, insn->imm, (insn + 1)->imm);
+
+ if (bpf_pseudo_func(insn))
+ set_need_for_extra_pass(ctx);
+
+ return 0;
+}
+
+/*
+ * Handles one eBPF instruction at a time. To make this function faster,
+ * it does not call "jit_buffer_check()". Else, it would call it for every
+ * instruction. As a result, it should not be invoked directly. Only
+ * "handle_body()", that has already executed the "check", may call this
+ * function.
+ *
+ * If the "ret" value is negative, something has went wrong. Else,
+ * it mostly holds the value 0 and rarely 1. Number 1 signals
+ * the loop in "handle_body()" to skip the next instruction, because
+ * it has been consumed as part of a 64-bit immediate value.
+ */
+static int handle_insn(struct jit_context *ctx, u32 idx)
+{
+ const struct bpf_insn *insn = &ctx->prog->insnsi[idx];
+ const u8 code = insn->code;
+ const u8 dst = insn->dst_reg;
+ const u8 src = insn->src_reg;
+ const s16 off = insn->off;
+ const s32 imm = insn->imm;
+ u8 *buf = effective_jit_buf(ctx);
+ u8 len = 0;
+ int ret = 0;
+
+ switch (code) {
+ /* dst += src (32-bit) */
+ case BPF_ALU | BPF_ADD | BPF_X:
+ len = add_r32(buf, dst, src);
+ break;
+ /* dst += imm (32-bit) */
+ case BPF_ALU | BPF_ADD | BPF_K:
+ len = add_r32_i32(buf, dst, imm);
+ break;
+ /* dst -= src (32-bit) */
+ case BPF_ALU | BPF_SUB | BPF_X:
+ len = sub_r32(buf, dst, src);
+ break;
+ /* dst -= imm (32-bit) */
+ case BPF_ALU | BPF_SUB | BPF_K:
+ len = sub_r32_i32(buf, dst, imm);
+ break;
+ /* dst = -dst (32-bit) */
+ case BPF_ALU | BPF_NEG:
+ len = neg_r32(buf, dst);
+ break;
+ /* dst *= src (32-bit) */
+ case BPF_ALU | BPF_MUL | BPF_X:
+ len = mul_r32(buf, dst, src);
+ break;
+ /* dst *= imm (32-bit) */
+ case BPF_ALU | BPF_MUL | BPF_K:
+ len = mul_r32_i32(buf, dst, imm);
+ break;
+ /* dst /= src (32-bit) */
+ case BPF_ALU | BPF_DIV | BPF_X:
+ len = div_r32(buf, dst, src, off == 1);
+ break;
+ /* dst /= imm (32-bit) */
+ case BPF_ALU | BPF_DIV | BPF_K:
+ len = div_r32_i32(buf, dst, imm, off == 1);
+ break;
+ /* dst %= src (32-bit) */
+ case BPF_ALU | BPF_MOD | BPF_X:
+ len = mod_r32(buf, dst, src, off == 1);
+ break;
+ /* dst %= imm (32-bit) */
+ case BPF_ALU | BPF_MOD | BPF_K:
+ len = mod_r32_i32(buf, dst, imm, off == 1);
+ break;
+ /* dst &= src (32-bit) */
+ case BPF_ALU | BPF_AND | BPF_X:
+ len = and_r32(buf, dst, src);
+ break;
+ /* dst &= imm (32-bit) */
+ case BPF_ALU | BPF_AND | BPF_K:
+ len = and_r32_i32(buf, dst, imm);
+ break;
+ /* dst |= src (32-bit) */
+ case BPF_ALU | BPF_OR | BPF_X:
+ len = or_r32(buf, dst, src);
+ break;
+ /* dst |= imm (32-bit) */
+ case BPF_ALU | BPF_OR | BPF_K:
+ len = or_r32_i32(buf, dst, imm);
+ break;
+ /* dst ^= src (32-bit) */
+ case BPF_ALU | BPF_XOR | BPF_X:
+ len = xor_r32(buf, dst, src);
+ break;
+ /* dst ^= imm (32-bit) */
+ case BPF_ALU | BPF_XOR | BPF_K:
+ len = xor_r32_i32(buf, dst, imm);
+ break;
+ /* dst <<= src (32-bit) */
+ case BPF_ALU | BPF_LSH | BPF_X:
+ len = lsh_r32(buf, dst, src);
+ break;
+ /* dst <<= imm (32-bit) */
+ case BPF_ALU | BPF_LSH | BPF_K:
+ len = lsh_r32_i32(buf, dst, imm);
+ break;
+ /* dst >>= src (32-bit) [unsigned] */
+ case BPF_ALU | BPF_RSH | BPF_X:
+ len = rsh_r32(buf, dst, src);
+ break;
+ /* dst >>= imm (32-bit) [unsigned] */
+ case BPF_ALU | BPF_RSH | BPF_K:
+ len = rsh_r32_i32(buf, dst, imm);
+ break;
+ /* dst >>= src (32-bit) [signed] */
+ case BPF_ALU | BPF_ARSH | BPF_X:
+ len = arsh_r32(buf, dst, src);
+ break;
+ /* dst >>= imm (32-bit) [signed] */
+ case BPF_ALU | BPF_ARSH | BPF_K:
+ len = arsh_r32_i32(buf, dst, imm);
+ break;
+ /* dst = src (32-bit) */
+ case BPF_ALU | BPF_MOV | BPF_X:
+ len = mov_r32(buf, dst, src, (u8)off);
+ break;
+ /* dst = imm32 (32-bit) */
+ case BPF_ALU | BPF_MOV | BPF_K:
+ len = mov_r32_i32(buf, dst, imm);
+ break;
+ /* dst = swap(dst) */
+ case BPF_ALU | BPF_END | BPF_FROM_LE:
+ case BPF_ALU | BPF_END | BPF_FROM_BE:
+ case BPF_ALU64 | BPF_END | BPF_FROM_LE: {
+ CHECK_RET(handle_swap(buf, dst, imm, BPF_SRC(code),
+ BPF_CLASS(code) == BPF_ALU64,
+ ctx->do_zext, &len));
+ break;
+ }
+ /* dst += src (64-bit) */
+ case BPF_ALU64 | BPF_ADD | BPF_X:
+ len = add_r64(buf, dst, src);
+ break;
+ /* dst += imm32 (64-bit) */
+ case BPF_ALU64 | BPF_ADD | BPF_K:
+ len = add_r64_i32(buf, dst, imm);
+ break;
+ /* dst -= src (64-bit) */
+ case BPF_ALU64 | BPF_SUB | BPF_X:
+ len = sub_r64(buf, dst, src);
+ break;
+ /* dst -= imm32 (64-bit) */
+ case BPF_ALU64 | BPF_SUB | BPF_K:
+ len = sub_r64_i32(buf, dst, imm);
+ break;
+ /* dst = -dst (64-bit) */
+ case BPF_ALU64 | BPF_NEG:
+ len = neg_r64(buf, dst);
+ break;
+ /* dst *= src (64-bit) */
+ case BPF_ALU64 | BPF_MUL | BPF_X:
+ len = mul_r64(buf, dst, src);
+ break;
+ /* dst *= imm32 (64-bit) */
+ case BPF_ALU64 | BPF_MUL | BPF_K:
+ len = mul_r64_i32(buf, dst, imm);
+ break;
+ /* dst &= src (64-bit) */
+ case BPF_ALU64 | BPF_AND | BPF_X:
+ len = and_r64(buf, dst, src);
+ break;
+ /* dst &= imm32 (64-bit) */
+ case BPF_ALU64 | BPF_AND | BPF_K:
+ len = and_r64_i32(buf, dst, imm);
+ break;
+ /* dst |= src (64-bit) */
+ case BPF_ALU64 | BPF_OR | BPF_X:
+ len = or_r64(buf, dst, src);
+ break;
+ /* dst |= imm32 (64-bit) */
+ case BPF_ALU64 | BPF_OR | BPF_K:
+ len = or_r64_i32(buf, dst, imm);
+ break;
+ /* dst ^= src (64-bit) */
+ case BPF_ALU64 | BPF_XOR | BPF_X:
+ len = xor_r64(buf, dst, src);
+ break;
+ /* dst ^= imm32 (64-bit) */
+ case BPF_ALU64 | BPF_XOR | BPF_K:
+ len = xor_r64_i32(buf, dst, imm);
+ break;
+ /* dst <<= src (64-bit) */
+ case BPF_ALU64 | BPF_LSH | BPF_X:
+ len = lsh_r64(buf, dst, src);
+ break;
+ /* dst <<= imm32 (64-bit) */
+ case BPF_ALU64 | BPF_LSH | BPF_K:
+ len = lsh_r64_i32(buf, dst, imm);
+ break;
+ /* dst >>= src (64-bit) [unsigned] */
+ case BPF_ALU64 | BPF_RSH | BPF_X:
+ len = rsh_r64(buf, dst, src);
+ break;
+ /* dst >>= imm32 (64-bit) [unsigned] */
+ case BPF_ALU64 | BPF_RSH | BPF_K:
+ len = rsh_r64_i32(buf, dst, imm);
+ break;
+ /* dst >>= src (64-bit) [signed] */
+ case BPF_ALU64 | BPF_ARSH | BPF_X:
+ len = arsh_r64(buf, dst, src);
+ break;
+ /* dst >>= imm32 (64-bit) [signed] */
+ case BPF_ALU64 | BPF_ARSH | BPF_K:
+ len = arsh_r64_i32(buf, dst, imm);
+ break;
+ /* dst = src (64-bit) */
+ case BPF_ALU64 | BPF_MOV | BPF_X:
+ len = mov_r64(buf, dst, src, (u8)off);
+ break;
+ /* dst = imm32 (sign extend to 64-bit) */
+ case BPF_ALU64 | BPF_MOV | BPF_K:
+ len = mov_r64_i32(buf, dst, imm);
+ break;
+ /* dst = imm64 */
+ case BPF_LD | BPF_DW | BPF_IMM:
+ CHECK_RET(handle_ld_imm64(ctx, insn, &len));
+ /* Tell the loop to skip the next instruction. */
+ ret = 1;
+ break;
+ /* dst = *(size *)(src + off) */
+ case BPF_LDX | BPF_MEM | BPF_W:
+ case BPF_LDX | BPF_MEM | BPF_H:
+ case BPF_LDX | BPF_MEM | BPF_B:
+ case BPF_LDX | BPF_MEM | BPF_DW:
+ len = load_r(buf, dst, src, off, BPF_SIZE(code), false);
+ break;
+ case BPF_LDX | BPF_MEMSX | BPF_W:
+ case BPF_LDX | BPF_MEMSX | BPF_H:
+ case BPF_LDX | BPF_MEMSX | BPF_B:
+ len = load_r(buf, dst, src, off, BPF_SIZE(code), true);
+ break;
+ /* *(size *)(dst + off) = src */
+ case BPF_STX | BPF_MEM | BPF_W:
+ case BPF_STX | BPF_MEM | BPF_H:
+ case BPF_STX | BPF_MEM | BPF_B:
+ case BPF_STX | BPF_MEM | BPF_DW:
+ len = store_r(buf, src, dst, off, BPF_SIZE(code));
+ break;
+ case BPF_ST | BPF_MEM | BPF_W:
+ case BPF_ST | BPF_MEM | BPF_H:
+ case BPF_ST | BPF_MEM | BPF_B:
+ case BPF_ST | BPF_MEM | BPF_DW:
+ len = store_i(buf, imm, dst, off, BPF_SIZE(code));
+ break;
+ case BPF_JMP | BPF_JA:
+ case BPF_JMP | BPF_JEQ | BPF_X:
+ case BPF_JMP | BPF_JEQ | BPF_K:
+ case BPF_JMP | BPF_JNE | BPF_X:
+ case BPF_JMP | BPF_JNE | BPF_K:
+ case BPF_JMP | BPF_JSET | BPF_X:
+ case BPF_JMP | BPF_JSET | BPF_K:
+ case BPF_JMP | BPF_JGT | BPF_X:
+ case BPF_JMP | BPF_JGT | BPF_K:
+ case BPF_JMP | BPF_JGE | BPF_X:
+ case BPF_JMP | BPF_JGE | BPF_K:
+ case BPF_JMP | BPF_JSGT | BPF_X:
+ case BPF_JMP | BPF_JSGT | BPF_K:
+ case BPF_JMP | BPF_JSGE | BPF_X:
+ case BPF_JMP | BPF_JSGE | BPF_K:
+ case BPF_JMP | BPF_JLT | BPF_X:
+ case BPF_JMP | BPF_JLT | BPF_K:
+ case BPF_JMP | BPF_JLE | BPF_X:
+ case BPF_JMP | BPF_JLE | BPF_K:
+ case BPF_JMP | BPF_JSLT | BPF_X:
+ case BPF_JMP | BPF_JSLT | BPF_K:
+ case BPF_JMP | BPF_JSLE | BPF_X:
+ case BPF_JMP | BPF_JSLE | BPF_K:
+ case BPF_JMP32 | BPF_JA:
+ case BPF_JMP32 | BPF_JEQ | BPF_X:
+ case BPF_JMP32 | BPF_JEQ | BPF_K:
+ case BPF_JMP32 | BPF_JNE | BPF_X:
+ case BPF_JMP32 | BPF_JNE | BPF_K:
+ case BPF_JMP32 | BPF_JSET | BPF_X:
+ case BPF_JMP32 | BPF_JSET | BPF_K:
+ case BPF_JMP32 | BPF_JGT | BPF_X:
+ case BPF_JMP32 | BPF_JGT | BPF_K:
+ case BPF_JMP32 | BPF_JGE | BPF_X:
+ case BPF_JMP32 | BPF_JGE | BPF_K:
+ case BPF_JMP32 | BPF_JSGT | BPF_X:
+ case BPF_JMP32 | BPF_JSGT | BPF_K:
+ case BPF_JMP32 | BPF_JSGE | BPF_X:
+ case BPF_JMP32 | BPF_JSGE | BPF_K:
+ case BPF_JMP32 | BPF_JLT | BPF_X:
+ case BPF_JMP32 | BPF_JLT | BPF_K:
+ case BPF_JMP32 | BPF_JLE | BPF_X:
+ case BPF_JMP32 | BPF_JLE | BPF_K:
+ case BPF_JMP32 | BPF_JSLT | BPF_X:
+ case BPF_JMP32 | BPF_JSLT | BPF_K:
+ case BPF_JMP32 | BPF_JSLE | BPF_X:
+ case BPF_JMP32 | BPF_JSLE | BPF_K:
+ CHECK_RET(handle_jumps(ctx, insn, &len));
+ break;
+ case BPF_JMP | BPF_CALL:
+ CHECK_RET(handle_call(ctx, insn, &len));
+ break;
+
+ case BPF_JMP | BPF_EXIT:
+ /* If this is the last instruction, epilogue will follow. */
+ if (is_last_insn(ctx->prog, idx))
+ break;
+ CHECK_RET(handle_jmp_epilogue(ctx, insn, &len));
+ break;
+ default:
+ pr_err("bpf-jit: can't handle instruction code 0x%02X\n", code);
+ return -EOPNOTSUPP;
+ }
+
+ if (BPF_CLASS(code) == BPF_ALU) {
+ /*
+ * Skip the "swap" instructions. Even 64-bit swaps are of type
+ * BPF_ALU (and not BPF_ALU64). Therefore, for the swaps, one
+ * has to look at the "size" of the operations rather than the
+ * ALU type. "gen_swap()" specifically takes care of that.
+ */
+ if (BPF_OP(code) != BPF_END && ctx->do_zext)
+ len += zext(BUF(buf, len), dst);
+ }
+
+ jit_buffer_update(ctx, len);
+
+ return ret;
+}
+
+static int handle_body(struct jit_context *ctx)
+{
+ int ret;
+ bool populate_bpf2insn = false;
+ const struct bpf_prog *prog = ctx->prog;
+
+ CHECK_RET(jit_buffer_check(ctx));
+
+ /*
+ * Record the mapping for the instructions during the dry-run.
+ * Doing it this way allows us to have the mapping ready for
+ * the jump instructions during the real compilation phase.
+ */
+ if (!ctx->emit)
+ populate_bpf2insn = true;
+
+ for (u32 i = 0; i < prog->len; i++) {
+ /* During the dry-run, jit.len grows gradually per BPF insn. */
+ if (populate_bpf2insn)
+ ctx->bpf2insn[i] = ctx->jit.len;
+
+ CHECK_RET(handle_insn(ctx, i));
+ if (ret > 0) {
+ /* "ret" is 1 if two (64-bit) chunks were consumed. */
+ ctx->bpf2insn[i + 1] = ctx->bpf2insn[i];
+ i++;
+ }
+ }
+
+ /* If bpf2insn had to be populated, then it is done at this point. */
+ if (populate_bpf2insn)
+ ctx->bpf2insn_valid = true;
+
+ return 0;
+}
+
+/*
+ * Initialize the memory with "unimp_s" which is the mnemonic for
+ * "unimplemented" instruction and always raises an exception.
+ *
+ * The instruction is 2 bytes. If "size" is odd, there is not much
+ * that can be done about the last byte in "area". Because, the
+ * CPU always fetches instructions in two bytes. Therefore, the
+ * byte beyond the last one is going to accompany it during a
+ * possible fetch. In the most likely case of a little endian
+ * system, that beyond-byte will become the major opcode and
+ * we have no control over its initialisation.
+ */
+static void fill_ill_insn(void *area, unsigned int size)
+{
+ const u16 unimp_s = 0x79e0;
+
+ if (size & 1) {
+ *((u8 *)area + (size - 1)) = 0xff;
+ size -= 1;
+ }
+
+ memset16(area, unimp_s, size >> 1);
+}
+
+/* Piece of memory that can be allocated at the beginning of jit_prepare(). */
+static int jit_prepare_early_mem_alloc(struct jit_context *ctx)
+{
+ ctx->bpf2insn = kcalloc(ctx->prog->len, sizeof(ctx->jit.len),
+ GFP_KERNEL);
+
+ if (!ctx->bpf2insn) {
+ pr_err("bpf-jit: could not allocate memory for "
+ "mapping of the instructions.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/*
+ * Memory allocations that rely on parameters known at the end of
+ * jit_prepare().
+ */
+static int jit_prepare_final_mem_alloc(struct jit_context *ctx)
+{
+ const size_t alignment = sizeof(u32);
+
+ ctx->bpf_header = bpf_jit_binary_alloc(ctx->jit.len, &ctx->jit.buf,
+ alignment, fill_ill_insn);
+ if (!ctx->bpf_header) {
+ pr_err("bpf-jit: could not allocate memory for translation.\n");
+ return -ENOMEM;
+ }
+
+ if (ctx->need_extra_pass) {
+ ctx->jit_data = kzalloc(sizeof(*ctx->jit_data), GFP_KERNEL);
+ if (!ctx->jit_data)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/*
+ * The first phase of the translation without actually emitting any
+ * instruction. It helps in getting a forecast on some aspects, such
+ * as the length of the whole program or where the epilogue starts.
+ *
+ * Whenever the necessary parameters are known, memories are allocated.
+ */
+static int jit_prepare(struct jit_context *ctx)
+{
+ int ret;
+
+ /* Dry run. */
+ ctx->emit = false;
+
+ CHECK_RET(jit_prepare_early_mem_alloc(ctx));
+
+ /* Get the length of prologue section after some register analysis. */
+ analyze_reg_usage(ctx);
+ CHECK_RET(handle_prologue(ctx));
+
+ CHECK_RET(handle_body(ctx));
+
+ /* Record at which offset epilogue begins. */
+ ctx->epilogue_offset = ctx->jit.len;
+
+ /* Process the epilogue section now. */
+ CHECK_RET(handle_epilogue(ctx));
+
+ CHECK_RET(jit_prepare_final_mem_alloc(ctx));
+
+ return 0;
+}
+
+/*
+ * jit_compile() is the real compilation phase. jit_prepare() is
+ * invoked before jit_compile() as a dry-run to make sure everything
+ * will go OK and allocate the necessary memory.
+ *
+ * In the end, jit_compile() checks if it has produced the same number
+ * of instructions as jit_prepare() would.
+ */
+static int jit_compile(struct jit_context *ctx)
+{
+ int ret;
+
+ /* Let there be code. */
+ ctx->emit = true;
+
+ CHECK_RET(handle_prologue(ctx));
+
+ CHECK_RET(handle_body(ctx));
+
+ CHECK_RET(handle_epilogue(ctx));
+
+ if (ctx->jit.index != ctx->jit.len) {
+ pr_err("bpf-jit: divergence between the phases; "
+ "%u vs. %u (bytes).\n",
+ ctx->jit.len, ctx->jit.index);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*
+ * Calling this function implies a successful JIT. A successful
+ * translation is signaled by setting the right parameters:
+ *
+ * prog->jited=1, prog->jited_len=..., prog->bpf_func=...
+ */
+static int jit_finalize(struct jit_context *ctx)
+{
+ struct bpf_prog *prog = ctx->prog;
+
+ /* We're going to need this information for the "do_extra_pass()". */
+ if (ctx->need_extra_pass) {
+ ctx->jit_data->bpf_header = ctx->bpf_header;
+ ctx->jit_data->bpf2insn = ctx->bpf2insn;
+ prog->aux->jit_data = (void *)ctx->jit_data;
+ } else {
+ /*
+ * If things seem finalised, then mark the JITed memory
+ * as R-X and flush it.
+ */
+ if (bpf_jit_binary_lock_ro(ctx->bpf_header)) {
+ pr_err("bpf-jit: Could not lock the JIT memory.\n");
+ return -EFAULT;
+ }
+ flush_icache_range((unsigned long)ctx->bpf_header,
+ (unsigned long)
+ BUF(ctx->jit.buf, ctx->jit.len));
+ prog->aux->jit_data = NULL;
+ bpf_prog_fill_jited_linfo(prog, ctx->bpf2insn);
+ }
+
+ ctx->success = true;
+ prog->bpf_func = (void *)ctx->jit.buf;
+ prog->jited_len = ctx->jit.len;
+ prog->jited = 1;
+
+ jit_ctx_cleanup(ctx);
+ jit_dump(ctx);
+
+ return 0;
+}
+
+/*
+ * A lenient verification for the existence of JIT context in "prog".
+ * Apparently the JIT internals, namely jit_subprogs() in bpf/verifier.c,
+ * may request for a second compilation although nothing needs to be done.
+ */
+static inline int check_jit_context(const struct bpf_prog *prog)
+{
+ if (!prog->aux->jit_data) {
+ pr_notice("bpf-jit: no jit data for the extra pass.\n");
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* Reuse the previous pass's data. */
+static int jit_resume_context(struct jit_context *ctx)
+{
+ struct arc_jit_data *jdata =
+ (struct arc_jit_data *)ctx->prog->aux->jit_data;
+
+ if (!jdata) {
+ pr_err("bpf-jit: no jit data for the extra pass.\n");
+ return -EINVAL;
+ }
+
+ ctx->jit.buf = (u8 *)ctx->prog->bpf_func;
+ ctx->jit.len = ctx->prog->jited_len;
+ ctx->bpf_header = jdata->bpf_header;
+ ctx->bpf2insn = (u32 *)jdata->bpf2insn;
+ ctx->bpf2insn_valid = ctx->bpf2insn ? true : false;
+ ctx->jit_data = jdata;
+
+ return 0;
+}
+
+/*
+ * Patch in the new addresses. The instructions of interest are:
+ *
+ * - call
+ * - ld r64, imm64
+ *
+ * For "call"s, it resolves the addresses one more time through the
+ * handle_call().
+ *
+ * For 64-bit immediate loads, it just retranslates them, because the BPF
+ * core in kernel might have changed the value since the normal pass.
+ */
+static int jit_patch_relocations(struct jit_context *ctx)
+{
+ const u8 bpf_opc_call = BPF_JMP | BPF_CALL;
+ const u8 bpf_opc_ldi64 = BPF_LD | BPF_DW | BPF_IMM;
+ const struct bpf_prog *prog = ctx->prog;
+ int ret;
+
+ ctx->emit = true;
+ for (u32 i = 0; i < prog->len; i++) {
+ const struct bpf_insn *insn = &prog->insnsi[i];
+ u8 dummy;
+ /*
+ * Adjust "ctx.jit.index", so "gen_*()" functions below
+ * can use it for their output addresses.
+ */
+ ctx->jit.index = ctx->bpf2insn[i];
+
+ if (insn->code == bpf_opc_call) {
+ CHECK_RET(handle_call(ctx, insn, &dummy));
+ } else if (insn->code == bpf_opc_ldi64) {
+ CHECK_RET(handle_ld_imm64(ctx, insn, &dummy));
+ /* Skip the next instruction. */
+ ++i;
+ }
+ }
+ return 0;
+}
+
+/*
+ * A normal pass that involves a "dry-run" phase, jit_prepare(),
+ * to get the necessary data for the real compilation phase,
+ * jit_compile().
+ */
+static struct bpf_prog *do_normal_pass(struct bpf_prog *prog)
+{
+ struct jit_context ctx;
+
+ /* Bail out if JIT is disabled. */
+ if (!prog->jit_requested)
+ return prog;
+
+ if (jit_ctx_init(&ctx, prog)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ /* Get the lengths and allocate buffer. */
+ if (jit_prepare(&ctx)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ if (jit_compile(&ctx)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ if (jit_finalize(&ctx)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ return ctx.prog;
+}
+
+/*
+ * If there are multi-function BPF programs that call each other,
+ * their translated addresses are not known all at once. Therefore,
+ * an extra pass is needed to consult the bpf_jit_get_func_addr()
+ * again to get the newly translated addresses in order to resolve
+ * the "call"s.
+ */
+static struct bpf_prog *do_extra_pass(struct bpf_prog *prog)
+{
+ struct jit_context ctx;
+
+ /* Skip if there's no context to resume from. */
+ if (check_jit_context(prog))
+ return prog;
+
+ if (jit_ctx_init(&ctx, prog)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ if (jit_resume_context(&ctx)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ if (jit_patch_relocations(&ctx)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ if (jit_finalize(&ctx)) {
+ jit_ctx_cleanup(&ctx);
+ return prog;
+ }
+
+ return ctx.prog;
+}
+
+/*
+ * This function may be invoked twice for the same stream of BPF
+ * instructions. The "extra pass" happens, when there are
+ * (re)locations involved that their addresses are not known
+ * during the first run.
+ */
+struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
+{
+ vm_dump(prog);
+
+ /* Was this program already translated? */
+ if (!prog->jited)
+ return do_normal_pass(prog);
+ else
+ return do_extra_pass(prog);
+
+ return prog;
+}
diff --git a/arch/arm/Kbuild b/arch/arm/Kbuild
index b506622e7e23..69de6b6243c7 100644
--- a/arch/arm/Kbuild
+++ b/arch/arm/Kbuild
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_FPE_NWFPE) += nwfpe/
# Put arch/arm/fastfpe/ to use this.
-obj-$(CONFIG_FPE_FASTFPE) += $(patsubst $(srctree)/$(src)/%,%,$(wildcard $(srctree)/$(src)/fastfpe/))
+obj-$(CONFIG_FPE_FASTFPE) += $(patsubst $(src)/%,%,$(wildcard $(src)/fastfpe/))
obj-$(CONFIG_VFP) += vfp/
obj-$(CONFIG_XEN) += xen/
obj-$(CONFIG_VDSO) += vdso/
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b14aed3a17ab..954a1916a500 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -34,7 +34,9 @@ config ARM
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7
+ select ARCH_NEED_CMPXCHG_1_EMU if CPU_V6
select ARCH_SUPPORTS_ATOMIC_RMW
+ select ARCH_SUPPORTS_CFI_CLANG
select ARCH_SUPPORTS_HUGETLBFS if ARM_LPAE
select ARCH_SUPPORTS_PER_VMA_LOCK
select ARCH_USE_BUILTIN_BSWAP
@@ -99,7 +101,7 @@ config ARM
select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU
select HAVE_EXIT_THREAD
- select HAVE_FAST_GUP if ARM_LPAE
+ select HAVE_GUP_FAST if ARM_LPAE
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_FUNCTION_GRAPH_TRACER
@@ -1233,9 +1235,9 @@ config HIGHPTE
consumed by page tables. Setting this option will allow
user-space 2nd level page tables to reside in high memory.
-config CPU_SW_DOMAIN_PAN
- bool "Enable use of CPU domains to implement privileged no-access"
- depends on MMU && !ARM_LPAE
+config ARM_PAN
+ bool "Enable privileged no-access"
+ depends on MMU
default y
help
Increase kernel security by ensuring that normal kernel accesses
@@ -1244,10 +1246,26 @@ config CPU_SW_DOMAIN_PAN
by ensuring that magic values (such as LIST_POISON) will always
fault when dereferenced.
+ The implementation uses CPU domains when !CONFIG_ARM_LPAE and
+ disabling of TTBR0 page table walks with CONFIG_ARM_LPAE.
+
+config CPU_SW_DOMAIN_PAN
+ def_bool y
+ depends on ARM_PAN && !ARM_LPAE
+ help
+ Enable use of CPU domains to implement privileged no-access.
+
CPUs with low-vector mappings use a best-efforts implementation.
Their lower 1MB needs to remain accessible for the vectors, but
the remainder of userspace will become appropriately inaccessible.
+config CPU_TTBR0_PAN
+ def_bool y
+ depends on ARM_PAN && ARM_LPAE
+ help
+ Enable privileged no-access by disabling TTBR0 page table walks when
+ running in kernel mode.
+
config HW_PERF_EVENTS
def_bool y
depends on ARM_PMU
@@ -1465,7 +1483,8 @@ config ARM_ATAG_DTB_COMPAT
from the ATAG list and store it at run time into the appended DTB.
choice
- prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT
+ prompt "Kernel command line type"
+ depends on ARM_ATAG_DTB_COMPAT
default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
@@ -1494,7 +1513,8 @@ config CMDLINE
memory size and the root device (e.g., mem=64M root=/dev/nfs).
choice
- prompt "Kernel command line type" if CMDLINE != ""
+ prompt "Kernel command line type"
+ depends on CMDLINE != ""
default CMDLINE_FROM_BOOTLOADER
config CMDLINE_FROM_BOOTLOADER
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d82908b1b1bb..71afdd98ddf2 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -130,6 +130,13 @@ endif
# Accept old syntax despite ".syntax unified"
AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
+# The GCC option -ffreestanding is required in order to compile code containing
+# ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel)
+CC_FLAGS_FPU := -ffreestanding
+# Enable <arm_neon.h>
+CC_FLAGS_FPU += -isystem $(shell $(CC) -print-file-name=include)
+CC_FLAGS_FPU += -march=armv7-a -mfloat-abi=softfp -mfpu=neon
+
ifeq ($(CONFIG_THUMB2_KERNEL),y)
CFLAGS_ISA :=-Wa,-mimplicit-it=always $(AFLAGS_NOWARN)
AFLAGS_ISA :=$(CFLAGS_ISA) -Wa$(comma)-mthumb
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index abd6a2889fd0..ba9b9a802469 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -25,8 +25,7 @@ targets := Image zImage xipImage bootpImage uImage
ifeq ($(CONFIG_XIP_KERNEL),y)
-cmd_deflate_xip_data = $(CONFIG_SHELL) -c \
- '$(srctree)/$(src)/deflate_xip_data.sh $< $@'
+cmd_deflate_xip_data = $(CONFIG_SHELL) -c '$(src)/deflate_xip_data.sh $< $@'
ifeq ($(CONFIG_XIP_DEFLATED_DATA),y)
quiet_cmd_mkxip = XIPZ $@
diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
index a2934e6fd89a..f3443f7d7b02 100644
--- a/arch/arm/boot/bootp/Makefile
+++ b/arch/arm/boot/bootp/Makefile
@@ -5,7 +5,6 @@
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
-GCOV_PROFILE := n
ifdef PHYS_OFFSET
add_hex = $(shell printf 0x%x $$(( $(1) + $(2) )) )
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 726ecabcef09..6bca03c0c7f0 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -22,13 +22,6 @@ ifeq ($(CONFIG_ARM_VIRT_EXT),y)
OBJS += hyp-stub.o
endif
-GCOV_PROFILE := n
-KASAN_SANITIZE := n
-
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-UBSAN_SANITIZE := n
-
#
# Architecture dependencies
#
diff --git a/arch/arm/boot/dts/allwinner/Makefile b/arch/arm/boot/dts/allwinner/Makefile
index 2d26c3397f14..cd0d044882cf 100644
--- a/arch/arm/boot/dts/allwinner/Makefile
+++ b/arch/arm/boot/dts/allwinner/Makefile
@@ -61,6 +61,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
sun5i-a13-olinuxino.dtb \
sun5i-a13-olinuxino-micro.dtb \
sun5i-a13-pocketbook-touch-lux-3.dtb \
+ sun5i-a13-pocketbook-614-plus.dtb \
sun5i-a13-q8-tablet.dtb \
sun5i-a13-utoo-p66.dtb \
sun5i-gr8-chip-pro.dtb \
@@ -260,68 +261,6 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-v3s-licheepi-zero.dtb \
sun8i-v3s-licheepi-zero-dock.dtb \
sun8i-v40-bananapi-m2-berry.dtb
-dtb-$(CONFIG_MACH_SUN8I) += \
- sun8i-a23-evb.dtb \
- sun8i-a23-gt90h-v4.dtb \
- sun8i-a23-inet86dz.dtb \
- sun8i-a23-ippo-q8h-v5.dtb \
- sun8i-a23-ippo-q8h-v1.2.dtb \
- sun8i-a23-polaroid-mid2407pxe03.dtb \
- sun8i-a23-polaroid-mid2809pxe04.dtb \
- sun8i-a23-q8-tablet.dtb \
- sun8i-a33-et-q8-v1.6.dtb \
- sun8i-a33-ga10h-v1.1.dtb \
- sun8i-a33-inet-d978-rev2.dtb \
- sun8i-a33-ippo-q8h-v1.2.dtb \
- sun8i-a33-olinuxino.dtb \
- sun8i-a33-q8-tablet.dtb \
- sun8i-a33-sinlinx-sina33.dtb \
- sun8i-a83t-allwinner-h8homlet-v2.dtb \
- sun8i-a83t-bananapi-m3.dtb \
- sun8i-a83t-cubietruck-plus.dtb \
- sun8i-a83t-tbs-a711.dtb \
- sun8i-h2-plus-bananapi-m2-zero.dtb \
- sun8i-h2-plus-libretech-all-h3-cc.dtb \
- sun8i-h2-plus-orangepi-r1.dtb \
- sun8i-h2-plus-orangepi-zero.dtb \
- sun8i-h3-bananapi-m2-plus.dtb \
- sun8i-h3-bananapi-m2-plus-v1.2.dtb \
- sun8i-h3-beelink-x2.dtb \
- sun8i-h3-libretech-all-h3-cc.dtb \
- sun8i-h3-mapleboard-mp130.dtb \
- sun8i-h3-nanopi-duo2.dtb \
- sun8i-h3-nanopi-m1.dtb\
- \
- sun8i-h3-nanopi-m1-plus.dtb \
- sun8i-h3-nanopi-neo.dtb \
- sun8i-h3-nanopi-neo-air.dtb \
- sun8i-h3-nanopi-r1.dtb \
- sun8i-h3-orangepi-2.dtb \
- sun8i-h3-orangepi-lite.dtb \
- sun8i-h3-orangepi-one.dtb \
- sun8i-h3-orangepi-pc.dtb \
- sun8i-h3-orangepi-pc-plus.dtb \
- sun8i-h3-orangepi-plus.dtb \
- sun8i-h3-orangepi-plus2e.dtb \
- sun8i-h3-orangepi-zero-plus2.dtb \
- sun8i-h3-rervision-dvk.dtb \
- sun8i-h3-zeropi.dtb \
- sun8i-h3-emlid-neutis-n5h3-devboard.dtb \
- sun8i-r16-bananapi-m2m.dtb \
- sun8i-r16-nintendo-nes-classic.dtb \
- sun8i-r16-nintendo-super-nes-classic.dtb \
- sun8i-r16-parrot.dtb \
- sun8i-r40-bananapi-m2-ultra.dtb \
- sun8i-r40-oka40i-c.dtb \
- sun8i-s3-elimo-initium.dtb \
- sun8i-s3-lichee-zero-plus.dtb \
- sun8i-s3-pinecube.dtb \
- sun8i-t113s-mangopi-mq-r-t113.dtb \
- sun8i-t3-cqa3t-bv3.dtb \
- sun8i-v3-sl631-imx179.dtb \
- sun8i-v3s-licheepi-zero.dtb \
- sun8i-v3s-licheepi-zero-dock.dtb \
- sun8i-v40-bananapi-m2-berry.dtb
dtb-$(CONFIG_MACH_SUN9I) += \
sun9i-a80-optimus.dtb \
sun9i-a80-cubieboard4.dtb
diff --git a/arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts b/arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts
new file mode 100644
index 000000000000..ab8d138dc11d
--- /dev/null
+++ b/arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 Denis Burkov <hitechshell@mail.ru>
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "PocketBook 614 Plus";
+ compatible = "pocketbook,614-plus", "allwinner,sun5i-a13";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_POWER;
+ linux,default-trigger = "default-on";
+ gpios = <&pio 4 8 GPIO_ACTIVE_LOW>; /* PE8 */
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-0 {
+ label = "Right";
+ linux,code = <KEY_NEXT>;
+ gpios = <&pio 6 9 GPIO_ACTIVE_LOW>; /* PG9 */
+ };
+
+ key-1 {
+ label = "Left";
+ linux,code = <KEY_PREVIOUS>;
+ gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 */
+ };
+ };
+
+ reg_3v3_mmc0: regulator-mmc0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-mmc0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 4 4 GPIO_ACTIVE_LOW>; /* PE4 */
+ vin-supply = <&reg_vcc3v3>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ status = "okay";
+
+ button-300 {
+ label = "Down";
+ linux,code = <KEY_DOWN>;
+ channel = <0>;
+ voltage = <300000>;
+ };
+
+ button-700 {
+ label = "Up";
+ linux,code = <KEY_UP>;
+ channel = <0>;
+ voltage = <700000>;
+ };
+
+ button-1000 {
+ label = "Left";
+ linux,code = <KEY_LEFT>;
+ channel = <0>;
+ voltage = <1000000>;
+ };
+
+ button-1200 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <1200000>;
+ };
+
+ button-1500 {
+ label = "Right";
+ linux,code = <KEY_RIGHT>;
+ channel = <0>;
+ voltage = <1500000>;
+ };
+};
+
+&mmc0 {
+ vmmc-supply = <&reg_3v3_mmc0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_4bit_pc_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
+
+&reg_usb0_vbus {
+ status = "okay";
+ gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+};
+
+&reg_usb1_vbus {
+ gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pg_pins>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
+&battery_power_supply {
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+ usb0_vbus_det-gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/allwinner/sun5i-a13.dtsi b/arch/arm/boot/dts/allwinner/sun5i-a13.dtsi
index 3325ab07094a..2c9152b151be 100644
--- a/arch/arm/boot/dts/allwinner/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun5i-a13.dtsi
@@ -62,14 +62,14 @@
};
trips {
- cpu_alert0: cpu_alert0 {
+ cpu_alert0: cpu-alert0 {
/* milliCelsius */
temperature = <85000>;
hysteresis = <2000>;
type = "passive";
};
- cpu_crit: cpu_crit {
+ cpu_crit: cpu-crit {
/* milliCelsius */
temperature = <100000>;
hysteresis = <2000>;
diff --git a/arch/arm/boot/dts/allwinner/sun5i-gr8-chip-pro.dts b/arch/arm/boot/dts/allwinner/sun5i-gr8-chip-pro.dts
index 5c3562b85a5b..ffbd99c176db 100644
--- a/arch/arm/boot/dts/allwinner/sun5i-gr8-chip-pro.dts
+++ b/arch/arm/boot/dts/allwinner/sun5i-gr8-chip-pro.dts
@@ -77,7 +77,7 @@
};
};
- mmc0_pwrseq: mmc0_pwrseq {
+ mmc0_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */
};
diff --git a/arch/arm/boot/dts/allwinner/sun5i-r8-chip.dts b/arch/arm/boot/dts/allwinner/sun5i-r8-chip.dts
index 4192c23848c3..8c784a2c086e 100644
--- a/arch/arm/boot/dts/allwinner/sun5i-r8-chip.dts
+++ b/arch/arm/boot/dts/allwinner/sun5i-r8-chip.dts
@@ -77,7 +77,7 @@
};
};
- mmc0_pwrseq: mmc0_pwrseq {
+ mmc0_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 2 19 GPIO_ACTIVE_LOW>; /* PC19 */
};
diff --git a/arch/arm/boot/dts/allwinner/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/allwinner/sun6i-a31-hummingbird.dts
index 236ebfc06192..5bce7a32651e 100644
--- a/arch/arm/boot/dts/allwinner/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/allwinner/sun6i-a31-hummingbird.dts
@@ -109,7 +109,7 @@
};
};
- reg_vga_3v3: vga_3v3_regulator {
+ reg_vga_3v3: vga-3v3-regulator {
compatible = "regulator-fixed";
regulator-name = "vga-3v3";
regulator-min-microvolt = <3300000>;
@@ -119,7 +119,7 @@
gpio = <&pio 7 25 GPIO_ACTIVE_HIGH>; /* PH25 */
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 */
};
diff --git a/arch/arm/boot/dts/allwinner/sun6i-a31.dtsi b/arch/arm/boot/dts/allwinner/sun6i-a31.dtsi
index 5cce4918f84c..f0145d6b9c53 100644
--- a/arch/arm/boot/dts/allwinner/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun6i-a31.dtsi
@@ -179,14 +179,14 @@
};
trips {
- cpu_alert0: cpu_alert0 {
+ cpu_alert0: cpu-alert0 {
/* milliCelsius */
temperature = <70000>;
hysteresis = <2000>;
type = "passive";
};
- cpu_crit: cpu_crit {
+ cpu_crit: cpu-crit {
/* milliCelsius */
temperature = <100000>;
hysteresis = <2000>;
@@ -1318,7 +1318,7 @@
compatible = "allwinner,sun6i-a31-prcm";
reg = <0x01f01400 0x200>;
- ar100: ar100_clk {
+ ar100: ar100-clk {
compatible = "allwinner,sun6i-a31-ar100-clk";
#clock-cells = <0>;
clocks = <&rtc CLK_OSC32K>, <&osc24M>,
@@ -1327,7 +1327,7 @@
clock-output-names = "ar100";
};
- ahb0: ahb0_clk {
+ ahb0: ahb0-clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <1>;
@@ -1336,14 +1336,14 @@
clock-output-names = "ahb0";
};
- apb0: apb0_clk {
+ apb0: apb0-clk {
compatible = "allwinner,sun6i-a31-apb0-clk";
#clock-cells = <0>;
clocks = <&ahb0>;
clock-output-names = "apb0";
};
- apb0_gates: apb0_gates_clk {
+ apb0_gates: apb0-gates-clk {
compatible = "allwinner,sun6i-a31-apb0-gates-clk";
#clock-cells = <1>;
clocks = <&apb0>;
@@ -1353,14 +1353,14 @@
"apb0_i2c";
};
- ir_clk: ir_clk {
+ ir_clk: ir-clk {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
clocks = <&rtc CLK_OSC32K>, <&osc24M>;
clock-output-names = "ir";
};
- apb0_rst: apb0_rst {
+ apb0_rst: apb0-rst {
compatible = "allwinner,sun6i-a31-clock-reset";
#reset-cells = <1>;
};
diff --git a/arch/arm/boot/dts/allwinner/sun6i-a31s-sinovoip-bpi-m2.dts b/arch/arm/boot/dts/allwinner/sun6i-a31s-sinovoip-bpi-m2.dts
index 96554ab4f6d3..f63d67ec9887 100644
--- a/arch/arm/boot/dts/allwinner/sun6i-a31s-sinovoip-bpi-m2.dts
+++ b/arch/arm/boot/dts/allwinner/sun6i-a31s-sinovoip-bpi-m2.dts
@@ -75,7 +75,7 @@
};
};
- mmc2_pwrseq: mmc2_pwrseq {
+ mmc2_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 WIFI_EN */
};
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-bananapi-m1-plus.dts
index caa935ca4f19..f2d7fab9978d 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-bananapi-m1-plus.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-bananapi-m1-plus.dts
@@ -86,7 +86,7 @@
};
};
- mmc3_pwrseq: mmc3_pwrseq {
+ mmc3_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 WL-PMU-EN */
};
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-cubietruck.dts
index 52160e368304..be9b31d0f4b5 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-cubietruck.dts
@@ -96,7 +96,7 @@
};
};
- mmc3_pwrseq: mmc3_pwrseq {
+ mmc3_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 WIFI_EN */
clocks = <&ccu CLK_OUT_A>;
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-hummingbird.dts
index 3def2a330598..f1e26b75cd90 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-hummingbird.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-hummingbird.dts
@@ -65,7 +65,7 @@
stdout-path = "serial0:115200n8";
};
- reg_mmc3_vdd: mmc3_vdd {
+ reg_mmc3_vdd: regulator-mmc3-vdd {
compatible = "regulator-fixed";
regulator-name = "mmc3_vdd";
regulator-min-microvolt = <3000000>;
@@ -74,7 +74,7 @@
gpio = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
};
- reg_gmac_vdd: gmac_vdd {
+ reg_gmac_vdd: regulator-gmac-vdd {
compatible = "regulator-fixed";
regulator-name = "gmac_vdd";
regulator-min-microvolt = <3000000>;
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som-evb-emmc.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som-evb-emmc.dts
index 20bf09b2226c..fb835730bbc4 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som-evb-emmc.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som-evb-emmc.dts
@@ -14,7 +14,7 @@
model = "Olimex A20-Olimex-SOM-EVB-eMMC";
compatible = "olimex,a20-olimex-som-evb-emmc", "allwinner,sun7i-a20";
- mmc2_pwrseq: mmc2_pwrseq {
+ mmc2_pwrseq: pwrseq {
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&pio 2 18 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb-emmc.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb-emmc.dts
index a59755a2e7a9..e8977c2fe798 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb-emmc.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb-emmc.dts
@@ -13,7 +13,7 @@
model = "Olimex A20-SOM204-EVB-eMMC";
compatible = "olimex,a20-olimex-som204-evb-emmc", "allwinner,sun7i-a20";
- mmc2_pwrseq: mmc2_pwrseq {
+ mmc2_pwrseq: pwrseq-1 {
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&pio 2 16 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts
index 54af6c18075b..a55406657449 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts
@@ -65,7 +65,7 @@
};
};
- rtl_pwrseq: rtl_pwrseq {
+ rtl_pwrseq: pwrseq-0 {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 6 9 GPIO_ACTIVE_LOW>;
};
@@ -177,7 +177,7 @@
non-removable;
status = "okay";
- rtl8723bs: sdio_wifi@1 {
+ rtl8723bs: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-lime2.dts
index ecb91fb899ff..435a189332e8 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-lime2.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-lime2.dts
@@ -82,7 +82,7 @@
};
};
- reg_axp_ipsout: axp_ipsout {
+ reg_axp_ipsout: regulator-axp-ipsout {
compatible = "regulator-fixed";
regulator-name = "axp-ipsout";
regulator-min-microvolt = <5000000>;
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-wits-pro-a20-dkt.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-wits-pro-a20-dkt.dts
index 3bfae98f3cc3..29199b6a3b4a 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-wits-pro-a20-dkt.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-wits-pro-a20-dkt.dts
@@ -60,7 +60,7 @@
stdout-path = "serial0:115200n8";
};
- mmc3_pwrseq: mmc3_pwrseq {
+ mmc3_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 WIFI_EN */
};
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi b/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi
index 5574299685ab..5f44f09c5545 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi
@@ -153,14 +153,14 @@
};
trips {
- cpu_alert0: cpu_alert0 {
+ cpu_alert0: cpu-alert0 {
/* milliCelsius */
temperature = <75000>;
hysteresis = <2000>;
type = "passive";
};
- cpu_crit: cpu_crit {
+ cpu_crit: cpu-crit {
/* milliCelsius */
temperature = <100000>;
hysteresis = <2000>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/allwinner/sun8i-a23-a33.dtsi
index cd4bf60dbb3c..2af8382ccdf5 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-a23-a33.dtsi
@@ -108,7 +108,7 @@
#size-cells = <1>;
ranges;
- osc24M: osc24M_clk {
+ osc24M: osc24M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -116,7 +116,7 @@
clock-output-names = "osc24M";
};
- ext_osc32k: ext_osc32k_clk {
+ ext_osc32k: ext-osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
@@ -733,7 +733,7 @@
compatible = "allwinner,sun8i-a23-prcm";
reg = <0x01f01400 0x200>;
- ar100: ar100_clk {
+ ar100: ar100-clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <1>;
@@ -742,7 +742,7 @@
clock-output-names = "ar100";
};
- ahb0: ahb0_clk {
+ ahb0: ahb0-clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <1>;
@@ -751,14 +751,14 @@
clock-output-names = "ahb0";
};
- apb0: apb0_clk {
+ apb0: apb0-clk {
compatible = "allwinner,sun8i-a23-apb0-clk";
#clock-cells = <0>;
clocks = <&ahb0>;
clock-output-names = "apb0";
};
- apb0_gates: apb0_gates_clk {
+ apb0_gates: apb0-gates-clk {
compatible = "allwinner,sun8i-a23-apb0-gates-clk";
#clock-cells = <1>;
clocks = <&apb0>;
@@ -767,7 +767,7 @@
"apb0_i2c";
};
- apb0_rst: apb0_rst {
+ apb0_rst: apb0-rst {
compatible = "allwinner,sun6i-a31-clock-reset";
#reset-cells = <1>;
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2407pxe03.dts b/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2407pxe03.dts
index d5f6aebd7216..0c585a6d990d 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2407pxe03.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2407pxe03.dts
@@ -52,7 +52,7 @@
ethernet0 = &esp8089;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL6 */
/* The esp8089 needs 200 ms after driving wifi-en high */
@@ -76,7 +76,7 @@
non-removable;
status = "okay";
- esp8089: sdio_wifi@1 {
+ esp8089: wifi@1 {
compatible = "esp,esp8089";
reg = <1>;
esp,crystal-26M-en = <2>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2809pxe04.dts b/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2809pxe04.dts
index 9f9232a2fefb..63cb4e194a03 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2809pxe04.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2809pxe04.dts
@@ -52,7 +52,7 @@
ethernet0 = &esp8089;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL6 */
/* The esp8089 needs 200 ms after driving wifi-en high */
@@ -69,7 +69,7 @@
non-removable;
status = "okay";
- esp8089: sdio_wifi@1 {
+ esp8089: wifi@1 {
compatible = "esp,esp8089";
reg = <1>;
esp,crystal-26M-en = <2>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a33-ga10h-v1.1.dts b/arch/arm/boot/dts/allwinner/sun8i-a33-ga10h-v1.1.dts
index 2dfdd0a3151e..f00ce03ffc84 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a33-ga10h-v1.1.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a33-ga10h-v1.1.dts
@@ -85,7 +85,7 @@
non-removable;
status = "okay";
- rtl8703as: sdio_wifi@1 {
+ rtl8703as: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts b/arch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts
index 065cb620aa99..162ba93f7484 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts
@@ -78,7 +78,7 @@
non-removable;
status = "okay";
- rtl8723bs: sdio_wifi@1 {
+ rtl8723bs: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a33.dtsi b/arch/arm/boot/dts/allwinner/sun8i-a33.dtsi
index 30fdd2703b1f..36b2d78cdab9 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-a33.dtsi
@@ -323,35 +323,35 @@
};
trips {
- cpu_alert0: cpu_alert0 {
+ cpu_alert0: cpu-alert0 {
/* milliCelsius */
temperature = <75000>;
hysteresis = <2000>;
type = "passive";
};
- gpu_alert0: gpu_alert0 {
+ gpu_alert0: gpu-alert0 {
/* milliCelsius */
temperature = <85000>;
hysteresis = <2000>;
type = "passive";
};
- cpu_alert1: cpu_alert1 {
+ cpu_alert1: cpu-alert1 {
/* milliCelsius */
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
};
- gpu_alert1: gpu_alert1 {
+ gpu_alert1: gpu-alert1 {
/* milliCelsius */
temperature = <95000>;
hysteresis = <2000>;
type = "hot";
};
- cpu_crit: cpu_crit {
+ cpu_crit: cpu-crit {
/* milliCelsius */
temperature = <110000>;
hysteresis = <2000>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a83t-bananapi-m3.dts b/arch/arm/boot/dts/allwinner/sun8i-a83t-bananapi-m3.dts
index 8d56b103f063..32e811fa23e2 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a83t-bananapi-m3.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a83t-bananapi-m3.dts
@@ -95,7 +95,7 @@
gpio = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&ac100_rtc 1>;
clock-names = "ext_clock";
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/allwinner/sun8i-a83t-cubietruck-plus.dts
index 870993393fc2..d5e6ddaffbce 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a83t-cubietruck-plus.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a83t-cubietruck-plus.dts
@@ -144,7 +144,7 @@
compatible = "linux,spdif-dit";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&ac100_rtc 1>;
clock-names = "ext_clock";
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/allwinner/sun8i-a83t-tbs-a711.dts
index a7d4ca308990..43982b106a4d 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a83t-tbs-a711.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-a83t-tbs-a711.dts
@@ -123,7 +123,7 @@
vin-supply = <&reg_vbat>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
diff --git a/arch/arm/boot/dts/allwinner/sun8i-a83t.dtsi b/arch/arm/boot/dts/allwinner/sun8i-a83t.dtsi
index 94eb3bfc989e..addf0cb0f465 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-a83t.dtsi
@@ -164,7 +164,7 @@
ranges;
/* TODO: PRCM block has a mux for this. */
- osc24M: osc24M_clk {
+ osc24M: osc24M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -177,14 +177,14 @@
* It is an internal RC-based oscillator.
* TODO: Its controls are in the PRCM block.
*/
- osc16M: osc16M_clk {
+ osc16M: osc16M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <16000000>;
clock-output-names = "osc16M";
};
- osc16Md512: osc16Md512_clk {
+ osc16Md512: osc16Md512-clk {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <512>;
@@ -1127,7 +1127,7 @@
#reset-cells = <1>;
};
- r_cpucfg@1f01c00 {
+ cpucfg@1f01c00 {
compatible = "allwinner,sun8i-a83t-r-cpucfg";
reg = <0x1f01c00 0x400>;
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-m2-zero.dts
index d729b7c705db..d3a7c9fa23e4 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-m2-zero.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-m2-zero.dts
@@ -103,7 +103,7 @@
cpu-supply = <&reg_vcc1v2>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-r1.dts b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-r1.dts
index 3356f4210d45..79b03b31c5eb 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-r1.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-r1.dts
@@ -43,11 +43,12 @@
/* Orange Pi R1 is based on Orange Pi Zero design */
#include "sun8i-h2-plus-orangepi-zero.dts"
+/delete-node/ &reg_vcc_wifi;
+
/ {
model = "Xunlong Orange Pi R1";
compatible = "xunlong,orangepi-r1", "allwinner,sun8i-h2-plus";
- /delete-node/ reg_vcc_wifi;
/*
* Ths pin of this regulator is the same with the Wi-Fi extra
@@ -89,7 +90,7 @@
vmmc-supply = <&reg_vcc3v3>;
vqmmc-supply = <&reg_vcc3v3>;
- rtl8189etv: sdio_wifi@1 {
+ rtl8189etv: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
index 3706216ffb40..1b001f2ad0ef 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
@@ -80,7 +80,7 @@
};
};
- reg_vcc_wifi: reg_vcc_wifi {
+ reg_vcc_wifi: reg-vcc-wifi {
compatible = "regulator-fixed";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -105,7 +105,7 @@
states = <1100000 0>, <1300000 1>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
post-power-on-delay-ms = <200>;
@@ -149,7 +149,7 @@
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
- xr819: sdio_wifi@1 {
+ xr819: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-beelink-x2.dts
index a6d38ecee141..5b77300307de 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-beelink-x2.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-beelink-x2.dts
@@ -122,7 +122,7 @@
compatible = "linux,spdif-dit";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
@@ -185,7 +185,7 @@
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
- sdiowifi: sdio_wifi@1 {
+ sdiowifi: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-duo2.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-duo2.dts
index 343b02b97155..2b0566d4b386 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-duo2.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-duo2.dts
@@ -87,7 +87,7 @@
vin-supply = <&reg_vcc5v0>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
@@ -119,7 +119,7 @@
non-removable;
status = "okay";
- sdio_wifi: sdio_wifi@1 {
+ sdio_wifi: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
interrupt-parent = <&pio>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-m1-plus.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-m1-plus.dts
index 4ba533b0340f..59bd0746acf8 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-m1-plus.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-m1-plus.dts
@@ -62,7 +62,7 @@
gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
};
@@ -132,7 +132,7 @@
non-removable;
status = "okay";
- sdio_wifi: sdio_wifi@1 {
+ sdio_wifi: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
interrupt-parent = <&pio>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
index 9e1a33f94cad..6d85370e04f1 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
@@ -73,7 +73,7 @@
};
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-r1.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-r1.dts
index 42cd1131adf3..870649760f70 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-r1.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-r1.dts
@@ -43,7 +43,7 @@
<1300000 0x1>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-2.dts
index f1f9dbead32a..d2ae47b074bf 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-2.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-2.dts
@@ -105,7 +105,7 @@
};
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 WIFI_EN */
};
@@ -169,7 +169,7 @@
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
- rtl8189: sdio_wifi@1 {
+ rtl8189: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-lite.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-lite.dts
index 305b34a321f5..6a4316a52469 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-lite.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-lite.dts
@@ -143,7 +143,7 @@
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
- rtl8189ftv: sdio_wifi@1 {
+ rtl8189ftv: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc-plus.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc-plus.dts
index babf4cf1b2f6..8a49b3376dfc 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc-plus.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc-plus.dts
@@ -63,7 +63,7 @@
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
- rtl8189ftv: sdio_wifi@1 {
+ rtl8189ftv: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-zero-plus2.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-zero-plus2.dts
index 561ea1d2f861..7a6444a10e25 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-zero-plus2.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-zero-plus2.dts
@@ -92,7 +92,7 @@
regulator-max-microvolt = <3300000>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
post-power-on-delay-ms = <200>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-q8-common.dtsi b/arch/arm/boot/dts/allwinner/sun8i-q8-common.dtsi
index 3d9a1524e17e..272584881bb2 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-q8-common.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-q8-common.dtsi
@@ -62,7 +62,7 @@
};
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
/*
* Q8 boards use various PL# pins as wifi-en. On other boards
@@ -94,7 +94,7 @@
non-removable;
status = "okay";
- sdio_wifi: sdio_wifi@1 {
+ sdio_wifi: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-r16-bananapi-m2m.dts b/arch/arm/boot/dts/allwinner/sun8i-r16-bananapi-m2m.dts
index bc394686fedb..f4bf46b35bec 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r16-bananapi-m2m.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-r16-bananapi-m2m.dts
@@ -88,7 +88,7 @@
regulator-max-microvolt = <5000000>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL06 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-r16-parrot.dts b/arch/arm/boot/dts/allwinner/sun8i-r16-parrot.dts
index 95543a9c2118..75067522ff59 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-r16-parrot.dts
@@ -75,7 +75,7 @@
};
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL06 */
};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
index 28197bbcb1d5..cd2351acc32f 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
@@ -100,7 +100,7 @@
enable-active-high;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */
clocks = <&ccu CLK_OUTA>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-oka40i-c.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-oka40i-c.dts
index 0bd1336206b8..15b0b4de626a 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r40-oka40i-c.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40-oka40i-c.dts
@@ -62,7 +62,7 @@
regulator-max-microvolt = <5000000>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; // PB10 WIFI_EN
clocks = <&ccu CLK_OUTA>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-s3-pinecube.dts b/arch/arm/boot/dts/allwinner/sun8i-s3-pinecube.dts
index 20966e954eda..e0d4404b5957 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-s3-pinecube.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-s3-pinecube.dts
@@ -51,7 +51,7 @@
startup-delay-us = <200000>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 1 3 GPIO_ACTIVE_LOW>; /* PB3 WIFI-RST */
post-power-on-delay-ms = <200>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi b/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
index e8a04476b776..9e13c2aa8911 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
@@ -98,7 +98,7 @@
#size-cells = <1>;
ranges;
- osc24M: osc24M_clk {
+ osc24M: osc24M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -106,7 +106,7 @@
clock-output-names = "osc24M";
};
- osc32k: osc32k_clk {
+ osc32k: osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm/boot/dts/allwinner/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/allwinner/sun8i-v40-bananapi-m2-berry.dts
index 434871040aca..6575ef274453 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-v40-bananapi-m2-berry.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-v40-bananapi-m2-berry.dts
@@ -94,7 +94,7 @@
enable-active-high;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */
clocks = <&ccu CLK_OUTA>;
diff --git a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
index 7d3f3300f431..a1ae0929cec9 100644
--- a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
@@ -196,14 +196,14 @@
* The actual TX clock rate is not controlled by the
* gmac_tx clock.
*/
- mii_phy_tx_clk: mii_phy_tx_clk {
+ mii_phy_tx_clk: mii-phy-tx-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <25000000>;
clock-output-names = "mii_phy_tx";
};
- gmac_int_tx_clk: gmac_int_tx_clk {
+ gmac_int_tx_clk: gmac-int-tx-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <125000000>;
diff --git a/arch/arm/boot/dts/allwinner/sunxi-bananapi-m2-plus.dtsi b/arch/arm/boot/dts/allwinner/sunxi-bananapi-m2-plus.dtsi
index 1d1d127cf38f..873817ddb4ea 100644
--- a/arch/arm/boot/dts/allwinner/sunxi-bananapi-m2-plus.dtsi
+++ b/arch/arm/boot/dts/allwinner/sunxi-bananapi-m2-plus.dtsi
@@ -98,7 +98,7 @@
gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
diff --git a/arch/arm/boot/dts/allwinner/sunxi-h3-h5-emlid-neutis.dtsi b/arch/arm/boot/dts/allwinner/sunxi-h3-h5-emlid-neutis.dtsi
index 60804b0e6c56..be5f5528a118 100644
--- a/arch/arm/boot/dts/allwinner/sunxi-h3-h5-emlid-neutis.dtsi
+++ b/arch/arm/boot/dts/allwinner/sunxi-h3-h5-emlid-neutis.dtsi
@@ -18,7 +18,7 @@
stdout-path = "serial0:115200n8";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; /* PC7 */
post-power-on-delay-ms = <200>;
diff --git a/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
index ade1cd50e445..7df60515a903 100644
--- a/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
@@ -83,7 +83,7 @@
#size-cells = <1>;
ranges;
- osc24M: osc24M_clk {
+ osc24M: osc24M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -91,7 +91,7 @@
clock-output-names = "osc24M";
};
- osc32k: osc32k_clk {
+ osc32k: osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm/boot/dts/arm/arm-realview-eb-bbrevd.dtsi b/arch/arm/boot/dts/arm/arm-realview-eb-bbrevd.dtsi
index a79e1d1d30a7..7f62aef9ca8a 100644
--- a/arch/arm/boot/dts/arm/arm-realview-eb-bbrevd.dtsi
+++ b/arch/arm/boot/dts/arm/arm-realview-eb-bbrevd.dtsi
@@ -22,7 +22,7 @@
/ {
/* Introduce a fixed regulator for the new ethernet controller */
- veth: fixedregulator@0 {
+ veth: regulator-veth {
compatible = "regulator-fixed";
regulator-name = "veth";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/arm/arm-realview-eb.dtsi b/arch/arm/boot/dts/arm/arm-realview-eb.dtsi
index fbb2258b451f..16f784da5a55 100644
--- a/arch/arm/boot/dts/arm/arm-realview-eb.dtsi
+++ b/arch/arm/boot/dts/arm/arm-realview-eb.dtsi
@@ -45,7 +45,7 @@
};
/* The voltage to the MMC card is hardwired at 3.3V */
- vmmc: fixedregulator@0 {
+ vmmc: regulator-vmmc {
compatible = "regulator-fixed";
regulator-name = "vmmc";
regulator-min-microvolt = <3300000>;
@@ -53,13 +53,13 @@
regulator-boot-on;
};
- xtal24mhz: xtal24mhz@24M {
+ xtal24mhz: mclk: kmiclk: sspclk: uartclk: wdogclk: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
- timclk: timclk@1M {
+ timclk: clock-1000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <24>;
@@ -67,48 +67,8 @@
clocks = <&xtal24mhz>;
};
- mclk: mclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- kmiclk: kmiclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- sspclk: sspclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- uartclk: uartclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- wdogclk: wdogclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
/* FIXME: this actually hangs off the PLL clocks */
- pclk: pclk@0 {
+ pclk: clock-pclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
diff --git a/arch/arm/boot/dts/arm/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
index d99bac02232b..b9b10cbd65aa 100644
--- a/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
+++ b/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
@@ -63,13 +63,13 @@
regulator-boot-on;
};
- xtal24mhz: xtal24mhz@24M {
+ xtal24mhz: mclk: kmiclk: sspclk: uartclk: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
- timclk: timclk@1M {
+ timclk: clock-1000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <24>;
@@ -77,40 +77,8 @@
clocks = <&xtal24mhz>;
};
- mclk: mclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- kmiclk: kmiclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- sspclk: sspclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- uartclk: uartclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
/* FIXME: this actually hangs off the PLL clocks */
- pclk: pclk@0 {
+ pclk: clock-pclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
diff --git a/arch/arm/boot/dts/arm/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm/arm-realview-pb11mp.dts
index 89103d54ecc1..ce35748f3d25 100644
--- a/arch/arm/boot/dts/arm/arm-realview-pb11mp.dts
+++ b/arch/arm/boot/dts/arm/arm-realview-pb11mp.dts
@@ -163,19 +163,19 @@
regulator-boot-on;
};
- xtal24mhz: xtal24mhz@24M {
+ xtal24mhz: mclk: kmiclk: sspclk: uartclk: wdogclk: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
- refclk32khz: refclk32khz {
+ refclk32khz: clock-32768 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
};
- timclk: timclk@1M {
+ timclk: clock-1000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <24>;
@@ -183,48 +183,8 @@
clocks = <&xtal24mhz>;
};
- mclk: mclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- kmiclk: kmiclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- sspclk: sspclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- uartclk: uartclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- wdogclk: wdogclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
/* FIXME: this actually hangs off the PLL clocks */
- pclk: pclk@0 {
+ pclk: clock-pclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
diff --git a/arch/arm/boot/dts/arm/arm-realview-pbx.dtsi b/arch/arm/boot/dts/arm/arm-realview-pbx.dtsi
index ec1507c5147c..e625403a9456 100644
--- a/arch/arm/boot/dts/arm/arm-realview-pbx.dtsi
+++ b/arch/arm/boot/dts/arm/arm-realview-pbx.dtsi
@@ -62,19 +62,19 @@
regulator-boot-on;
};
- xtal24mhz: xtal24mhz@24M {
+ xtal24mhz: mclk: kmiclk: sspclk: uartclk: wdogclk: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
- refclk32khz: refclk32khz {
+ refclk32khz: clock-32768 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
};
- timclk: timclk@1M {
+ timclk: clock-1000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <24>;
@@ -82,48 +82,8 @@
clocks = <&xtal24mhz>;
};
- mclk: mclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- kmiclk: kmiclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- sspclk: sspclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- uartclk: uartclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
- wdogclk: wdogclk@24M {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
/* FIXME: this actually hangs off the PLL clocks */
- pclk: pclk@0 {
+ pclk: clock-pclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
diff --git a/arch/arm/boot/dts/arm/integratorap-im-pd1.dts b/arch/arm/boot/dts/arm/integratorap-im-pd1.dts
index 367850ea0912..db13e09f2fab 100644
--- a/arch/arm/boot/dts/arm/integratorap-im-pd1.dts
+++ b/arch/arm/boot/dts/arm/integratorap-im-pd1.dts
@@ -54,7 +54,7 @@
};
/* Also used for the Smart Card Interface SCI */
- impd1_uartclk: clock@1_4 {
+ impd1_uartclk: clock-uart {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <4>;
@@ -64,7 +64,7 @@
};
/* For the SSP the clock is divided by 64 */
- impd1_sspclk: clock@1_64 {
+ impd1_sspclk: clock-ssp {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <64>;
diff --git a/arch/arm/boot/dts/arm/integratorap.dts b/arch/arm/boot/dts/arm/integratorap.dts
index d9927d3181dc..9b6a1dbaf265 100644
--- a/arch/arm/boot/dts/arm/integratorap.dts
+++ b/arch/arm/boot/dts/arm/integratorap.dts
@@ -57,22 +57,14 @@
};
/* 24 MHz chrystal on the Integrator/AP development board */
- xtal24mhz: xtal24mhz@24M {
+ xtal24mhz: pclk: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
- pclk: pclk@0 {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&xtal24mhz>;
- };
-
/* The UART clock is 14.74 MHz divided by an ICS525 */
- uartclk: uartclk@14.74M {
+ uartclk: clock-14745600 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <14745600>;
@@ -81,7 +73,7 @@
core-module@10000000 {
/* 24 MHz chrystal on the core module */
- cm24mhz: cm24mhz@24M {
+ cm24mhz: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
diff --git a/arch/arm/boot/dts/arm/integratorcp.dts b/arch/arm/boot/dts/arm/integratorcp.dts
index c011333eb165..8ad1a8957ace 100644
--- a/arch/arm/boot/dts/arm/integratorcp.dts
+++ b/arch/arm/boot/dts/arm/integratorcp.dts
@@ -47,14 +47,14 @@
*/
/* The codec chrystal operates at 24.576 MHz */
- xtal_codec: xtal24.576@24.576M {
+ xtal_codec: clock-24576000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24576000>;
};
/* The chrystal is divided by 2 by the codec for the AACI bit clock */
- aaci_bitclk: aaci_bitclk@12.288M {
+ aaci_bitclk: clock-12288000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <2>;
@@ -63,21 +63,21 @@
};
/* This is a 25MHz chrystal on the base board */
- xtal25mhz: xtal25mhz@25M {
+ xtal25mhz: clock-25000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <25000000>;
};
/* The UART clock is 14.74 MHz divided from 25MHz by an ICS525 */
- uartclk: uartclk@14.74M {
+ uartclk: clock-14745600 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <14745600>;
};
/* Actually sysclk I think */
- pclk: pclk@0 {
+ pclk: clock-pclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
@@ -85,7 +85,7 @@
core-module@10000000 {
/* 24 MHz chrystal on the core module */
- cm24mhz: cm24mhz@24M {
+ cm24mhz: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -131,7 +131,7 @@
};
/* The timer clock is the 24 MHz oscillator divided to 1MHz */
- timclk: timclk@1M {
+ timclk: clock-1000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <24>;
diff --git a/arch/arm/boot/dts/arm/mps2.dtsi b/arch/arm/boot/dts/arm/mps2.dtsi
index ce308820765b..e240bc8aa605 100644
--- a/arch/arm/boot/dts/arm/mps2.dtsi
+++ b/arch/arm/boot/dts/arm/mps2.dtsi
@@ -48,37 +48,37 @@
#address-cells = <1>;
#size-cells = <1>;
- oscclk0: clk-osc0 {
+ oscclk0: clock-50000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
};
- oscclk1: clk-osc1 {
+ oscclk1: clock-24576000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24576000>;
};
- oscclk2: clk-osc2 {
+ oscclk2: clock-25000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
- cfgclk: clk-cfg {
+ cfgclk: clock-5000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <5000000>;
};
- spicfgclk: clk-spicfg {
+ spicfgclk: clock-75000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <75000000>;
};
- sysclk: clk-sys {
+ sysclk: spiclcd: spicon: i2cclcd: i2caud: clock-sys {
compatible = "fixed-factor-clock";
clocks = <&oscclk0>;
#clock-cells = <0>;
@@ -86,7 +86,7 @@
clock-mult = <1>;
};
- audmclk: clk-audm {
+ audmclk: clk-12388000 {
compatible = "fixed-factor-clock";
clocks = <&oscclk1>;
#clock-cells = <0>;
@@ -94,7 +94,7 @@
clock-mult = <1>;
};
- audsclk: clk-auds {
+ audsclk: clk-3072000 {
compatible = "fixed-factor-clock";
clocks = <&oscclk1>;
#clock-cells = <0>;
@@ -102,38 +102,6 @@
clock-mult = <1>;
};
- spiclcd: clk-cpiclcd {
- compatible = "fixed-factor-clock";
- clocks = <&oscclk0>;
- #clock-cells = <0>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
- spicon: clk-spicon {
- compatible = "fixed-factor-clock";
- clocks = <&oscclk0>;
- #clock-cells = <0>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
- i2cclcd: clk-i2cclcd {
- compatible = "fixed-factor-clock";
- clocks = <&oscclk0>;
- #clock-cells = <0>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
- i2caud: clk-i2caud {
- compatible = "fixed-factor-clock";
- clocks = <&oscclk0>;
- #clock-cells = <0>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
soc {
compatible = "simple-bus";
ranges;
diff --git a/arch/arm/boot/dts/arm/versatile-ab.dts b/arch/arm/boot/dts/arm/versatile-ab.dts
index de45aa99e260..6fe6b49f5d8e 100644
--- a/arch/arm/boot/dts/arm/versatile-ab.dts
+++ b/arch/arm/boot/dts/arm/versatile-ab.dts
@@ -24,7 +24,7 @@
reg = <0x0 0x08000000>;
};
- xtal24mhz: xtal24mhz@24M {
+ xtal24mhz: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -142,14 +142,14 @@
};
/* OSC1 on AB, OSC4 on PB */
- osc1: cm_aux_osc@24M {
+ osc1: clock-osc {
#clock-cells = <0>;
compatible = "arm,versatile-cm-auxosc";
clocks = <&xtal24mhz>;
};
/* The timer clock is the 24 MHz oscillator divided to 1MHz */
- timclk: timclk@1M {
+ timclk: clock-1000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <24>;
@@ -157,7 +157,7 @@
clocks = <&xtal24mhz>;
};
- pclk: pclk@24M {
+ pclk: clock-24000000 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clock-div = <1>;
diff --git a/arch/arm/boot/dts/arm/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/arm/vexpress-v2m-rs1.dtsi
index 8af4b77fe655..158b3923eae3 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/arm/vexpress-v2m-rs1.dtsi
@@ -20,7 +20,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
- v2m_fixed_3v3: fixed-regulator-0 {
+ v2m_fixed_3v3: regulator-3v3 {
compatible = "regulator-fixed";
regulator-name = "3V3";
regulator-min-microvolt = <3300000>;
@@ -28,21 +28,21 @@
regulator-always-on;
};
- v2m_clk24mhz: clk24mhz {
+ v2m_clk24mhz: clock-24000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "v2m:clk24mhz";
};
- v2m_refclk1mhz: refclk1mhz {
+ v2m_refclk1mhz: clock-1000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000>;
clock-output-names = "v2m:refclk1mhz";
};
- v2m_refclk32khz: refclk32khz {
+ v2m_refclk32khz: clock-32768 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
diff --git a/arch/arm/boot/dts/arm/vexpress-v2m.dtsi b/arch/arm/boot/dts/arm/vexpress-v2m.dtsi
index c5e92f6d2fcd..be03f2a8a57a 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/arm/vexpress-v2m.dtsi
@@ -351,7 +351,7 @@
};
};
- v2m_fixed_3v3: fixed-regulator-0 {
+ v2m_fixed_3v3: regulator-3v3 {
compatible = "regulator-fixed";
regulator-name = "3V3";
regulator-min-microvolt = <3300000>;
@@ -359,21 +359,21 @@
regulator-always-on;
};
- v2m_clk24mhz: clk24mhz {
+ v2m_clk24mhz: clock-24000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "v2m:clk24mhz";
};
- v2m_refclk1mhz: refclk1mhz {
+ v2m_refclk1mhz: clock-1000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000>;
clock-output-names = "v2m:refclk1mhz";
};
- v2m_refclk32khz: refclk32khz {
+ v2m_refclk32khz: clock-32768 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
@@ -436,7 +436,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- oscclk0 {
+ clock-controller-0 {
/* MCC static memory clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 0>;
@@ -445,7 +445,7 @@
clock-output-names = "v2m:oscclk0";
};
- v2m_oscclk1: oscclk1 {
+ v2m_oscclk1: clock-controller-1 {
/* CLCD clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
@@ -454,7 +454,7 @@
clock-output-names = "v2m:oscclk1";
};
- v2m_oscclk2: oscclk2 {
+ v2m_oscclk2: clock-controller-2 {
/* IO FPGA peripheral clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 2>;
@@ -463,7 +463,7 @@
clock-output-names = "v2m:oscclk2";
};
- volt-vio {
+ regulator-vio {
/* Logic level voltage */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 0>;
diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca15-tc1.dts
index 679537e17ff5..5a91e936edef 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca15-tc1.dts
@@ -142,7 +142,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- oscclk0 {
+ clock-controller-0 {
/* CPU PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 0>;
@@ -151,7 +151,7 @@
clock-output-names = "oscclk0";
};
- oscclk4 {
+ clock-controller-4 {
/* Multiplexed AXI master clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 4>;
@@ -160,7 +160,7 @@
clock-output-names = "oscclk4";
};
- hdlcd_clk: oscclk5 {
+ hdlcd_clk: clock-controller-5 {
/* HDLCD PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 5>;
@@ -169,7 +169,7 @@
clock-output-names = "oscclk5";
};
- smbclk: oscclk6 {
+ smbclk: clock-controller-6 {
/* SMB clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 6>;
@@ -178,7 +178,7 @@
clock-output-names = "oscclk6";
};
- sys_pll: oscclk7 {
+ sys_pll: clock-controller-7 {
/* SYS PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 7>;
@@ -187,7 +187,7 @@
clock-output-names = "oscclk7";
};
- oscclk8 {
+ clock-controller-8 {
/* DDR2 PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 8>;
@@ -196,7 +196,7 @@
clock-output-names = "oscclk8";
};
- volt-cores {
+ regulator-cores {
/* CPU core voltage */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 0>;
diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca15_a7.dts
index 511e87cc2bc5..6ef23c53d2d8 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca15_a7.dts
@@ -253,7 +253,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- oscclk0 {
+ clock-controller-0 {
/* A15 PLL 0 reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 0>;
@@ -262,7 +262,7 @@
clock-output-names = "oscclk0";
};
- oscclk1 {
+ clock-controller-1 {
/* A15 PLL 1 reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
@@ -271,7 +271,7 @@
clock-output-names = "oscclk1";
};
- oscclk2 {
+ clock-controller-2 {
/* A7 PLL 0 reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 2>;
@@ -280,7 +280,7 @@
clock-output-names = "oscclk2";
};
- oscclk3 {
+ clock-controller-3 {
/* A7 PLL 1 reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 3>;
@@ -289,7 +289,7 @@
clock-output-names = "oscclk3";
};
- oscclk4 {
+ clock-controller-4 {
/* External AXI master clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 4>;
@@ -298,7 +298,7 @@
clock-output-names = "oscclk4";
};
- hdlcd_clk: oscclk5 {
+ hdlcd_clk: clock-controller-5 {
/* HDLCD PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 5>;
@@ -307,7 +307,7 @@
clock-output-names = "oscclk5";
};
- smbclk: oscclk6 {
+ smbclk: clock-controller-6 {
/* Static memory controller clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 6>;
@@ -316,7 +316,7 @@
clock-output-names = "oscclk6";
};
- oscclk7 {
+ clock-controller-7 {
/* SYS PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 7>;
@@ -325,7 +325,7 @@
clock-output-names = "oscclk7";
};
- oscclk8 {
+ clock-controller-8 {
/* DDR2 PLL reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 8>;
@@ -334,7 +334,7 @@
clock-output-names = "oscclk8";
};
- volt-a15 {
+ regulator-a15 {
/* A15 CPU core voltage */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 0>;
@@ -345,7 +345,7 @@
label = "A15 Vcore";
};
- volt-a7 {
+ regulator-a7 {
/* A7 CPU core voltage */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 1>;
diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts
index ff1f9a1bcfcf..e3896253f33e 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts
@@ -145,7 +145,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- cpu_clk: oscclk0 {
+ cpu_clk: clock-controller-0 {
/* CPU and internal AXI reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 0>;
@@ -154,7 +154,7 @@
clock-output-names = "oscclk0";
};
- axi_clk: oscclk1 {
+ axi_clk: clock-controller-1 {
/* Multiplexed AXI master clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
@@ -163,7 +163,7 @@
clock-output-names = "oscclk1";
};
- oscclk2 {
+ clock-controller-2 {
/* DDR2 */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 2>;
@@ -172,7 +172,7 @@
clock-output-names = "oscclk2";
};
- hdlcd_clk: oscclk3 {
+ hdlcd_clk: clock-controller-3 {
/* HDLCD */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 3>;
@@ -181,7 +181,7 @@
clock-output-names = "oscclk3";
};
- oscclk4 {
+ clock-controller-4 {
/* Test chip gate configuration */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 4>;
@@ -190,7 +190,7 @@
clock-output-names = "oscclk4";
};
- smbclk: oscclk5 {
+ smbclk: clock-controller-5 {
/* SMB clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 5>;
diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
index 8bf35666412b..43a5a4ab6ff0 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
@@ -187,7 +187,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- oscclk0: extsaxiclk {
+ oscclk0: clock-controller-0 {
/* ACLK clock to the AXI master port on the test chip */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 0>;
@@ -196,7 +196,7 @@
clock-output-names = "extsaxiclk";
};
- oscclk1: clcdclk {
+ oscclk1: clock-controller-1 {
/* Reference clock for the CLCD */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
@@ -205,7 +205,7 @@
clock-output-names = "clcdclk";
};
- smbclk: oscclk2: tcrefclk {
+ smbclk: oscclk2: clock-controller-2 {
/* Reference clock for the test chip internal PLLs */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 2>;
@@ -214,7 +214,7 @@
clock-output-names = "tcrefclk";
};
- volt-vd10 {
+ regulator-vd10 {
/* Test Chip internal logic voltage */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 0>;
@@ -223,7 +223,7 @@
label = "VD10";
};
- volt-vd10-s2 {
+ regulator-vd10-s2 {
/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 1>;
@@ -232,7 +232,7 @@
label = "VD10_S2";
};
- volt-vd10-s3 {
+ regulator-vd10-s3 {
/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 2>;
@@ -241,7 +241,7 @@
label = "VD10_S3";
};
- volt-vcc1v8 {
+ regulator-vcc1v8 {
/* DDR2 SDRAM and Test Chip DDR2 I/O supply */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 3>;
@@ -250,7 +250,7 @@
label = "VCC1V8";
};
- volt-ddr2vtt {
+ regulator-ddr2vtt {
/* DDR2 SDRAM VTT termination voltage */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 4>;
@@ -259,7 +259,7 @@
label = "DDR2VTT";
};
- volt-vcc3v3 {
+ regulator-vcc3v3 {
/* Local board supply for miscellaneous logic external to the Test Chip */
arm,vexpress-sysreg,func = <2 5>;
compatible = "arm,vexpress-volt";
diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index d3ac20e316d0..e51c6d203725 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -9,17 +9,21 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-ampere-mtmitchell.dtb \
aspeed-bmc-arm-stardragon4800-rep2.dtb \
aspeed-bmc-asrock-e3c246d4i.dtb \
+ aspeed-bmc-asrock-e3c256d4i.dtb \
aspeed-bmc-asrock-romed8hm3.dtb \
+ aspeed-bmc-asrock-spc621d8hm3.dtb \
+ aspeed-bmc-asrock-x570d4u.dtb \
+ aspeed-bmc-asus-x4tf.dtb \
aspeed-bmc-bytedance-g220a.dtb \
aspeed-bmc-delta-ahe50dc.dtb \
aspeed-bmc-facebook-bletchley.dtb \
- aspeed-bmc-facebook-cloudripper.dtb \
aspeed-bmc-facebook-cmm.dtb \
aspeed-bmc-facebook-elbert.dtb \
aspeed-bmc-facebook-fuji.dtb \
aspeed-bmc-facebook-galaxy100.dtb \
aspeed-bmc-facebook-greatlakes.dtb \
- aspeed-bmc-facebook-minerva-cmc.dtb \
+ aspeed-bmc-facebook-harma.dtb \
+ aspeed-bmc-facebook-minerva.dtb \
aspeed-bmc-facebook-minipack.dtb \
aspeed-bmc-facebook-tiogapass.dtb \
aspeed-bmc-facebook-wedge40.dtb \
@@ -33,6 +37,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-ibm-rainier.dtb \
aspeed-bmc-ibm-rainier-1s4u.dtb \
aspeed-bmc-ibm-rainier-4u.dtb \
+ aspeed-bmc-ibm-system1.dtb \
aspeed-bmc-intel-s2600wf.dtb \
aspeed-bmc-inspur-fp5280g2.dtb \
aspeed-bmc-inspur-nf5280m6.dtb \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts
index 7b540880cef9..3c8925034a8c 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts
@@ -813,7 +813,6 @@
};
&adc0 {
- ref_voltage = <2500>;
status = "okay";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts
index c4b2efbfdf56..bb2e6ef609af 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts
@@ -83,6 +83,9 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+
+ nvmem-cells = <&eth0_macaddress>;
+ nvmem-cell-names = "mac-address";
};
&i2c1 {
@@ -103,6 +106,12 @@
compatible = "st,24c128", "atmel,24c128";
reg = <0x57>;
pagesize = <16>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eth0_macaddress: macaddress@3f80 {
+ reg = <0x3f80 6>;
+ };
};
};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts
new file mode 100644
index 000000000000..9d00ce9475f2
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/watchdog/aspeed-wdt.h>
+
+/{
+ model = "ASRock E3C256D4I BMC";
+ compatible = "asrock,e3c256d4i-bmc", "aspeed,ast2500";
+
+ aliases {
+ serial4 = &uart5;
+
+ i2c20 = &i2c2mux0ch0;
+ i2c21 = &i2c2mux0ch1;
+ i2c22 = &i2c2mux0ch2;
+ i2c23 = &i2c2mux0ch3;
+ };
+
+ chosen {
+ stdout-path = &uart5;
+ };
+
+ memory@80000000 {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ /* BMC heartbeat */
+ led-0 {
+ gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_LOW>;
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_GREEN>;
+ linux,default-trigger = "timer";
+ };
+
+ /* system fault */
+ led-1 {
+ gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+ function = LED_FUNCTION_FAULT;
+ color = <LED_COLOR_ID_RED>;
+ panic-indicator;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+ <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>,
+ <&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>,
+ <&adc 12>, <&adc 13>, <&adc 14>, <&adc 15>;
+ };
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <100000000>; /* 100 MHz */
+#include "openbmc-flash-layout-64.dtsi"
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&uart_routing {
+ status = "okay";
+};
+
+&mac0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+
+ nvmem-cells = <&eth0_macaddress>;
+ nvmem-cell-names = "mac-address";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9545";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c2mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c2mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c2mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c2mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&i2c10 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+
+ vrm@60 {
+ compatible = "isil,isl69269";
+ reg = <0x60>;
+ };
+};
+
+&i2c12 {
+ status = "okay";
+
+ /* FRU eeprom */
+ eeprom@57 {
+ compatible = "st,24c128", "atmel,24c128";
+ reg = <0x57>;
+ pagesize = <16>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eth0_macaddress: macaddress@3f80 {
+ reg = <0x3f80 6>;
+ };
+ };
+};
+
+&video {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&lpc_snoop {
+ status = "okay";
+ snoop-ports = <0x80>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca2>;
+};
+
+&peci0 {
+ status = "okay";
+};
+
+&wdt1 {
+ aspeed,reset-mask = <(AST2500_WDT_RESET_DEFAULT & ~AST2500_WDT_RESET_LPC)>;
+};
+
+&wdt2 {
+ aspeed,reset-mask = <(AST2500_WDT_RESET_DEFAULT & ~AST2500_WDT_RESET_LPC)>;
+};
+
+&pwm_tacho {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0_default /* CPU */
+ &pinctrl_pwm2_default /* rear */
+ &pinctrl_pwm4_default>; /* front */
+
+ /* CPU */
+ fan@0 {
+ reg = <0x00>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+ };
+
+ /* rear */
+ fan@2 {
+ reg = <0x02>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x02>;
+ };
+
+ /* front */
+ fan@4 {
+ reg = <0x04>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x04>;
+ };
+};
+
+&gpio {
+ status = "okay";
+ gpio-line-names =
+ /* A */ "", "", "NMI_BTN_N", "BMC_NMI", "", "", "", "",
+ /* B */ "", "", "", "", "", "", "", "",
+ /* C */ "", "", "", "", "", "", "", "",
+ /* D */ "BMC_PSIN", "BMC_PSOUT", "BMC_RESETCON", "RESETCON",
+ "", "", "", "",
+ /* E */ "", "", "", "", "", "", "", "",
+ /* F */ "LOCATORLED_STATUS_N", "LOCATORBTN", "", "",
+ "", "", "BMC_PCH_SCI_LPC", "BMC_NCSI_MUX_CTL",
+ /* G */ "HWM_BAT_EN", "CHASSIS_ID0", "CHASSIS_ID1", "CHASSIS_ID2",
+ "", "", "", "",
+ /* H */ "FM_ME_RCVR_N", "O_PWROK", "", "D4_DIMM_EVENT_3V_N",
+ "MFG_MODE_N", "BMC_RTCRST", "BMC_HB_LED_N", "BMC_CASEOPEN",
+ /* I */ "", "", "", "", "", "", "", "",
+ /* J */ "BMC_READY", "BMC_PCH_BIOS_CS_N", "BMC_SMI", "", "", "", "", "",
+ /* K */ "", "", "", "", "", "", "", "",
+ /* L */ "", "", "", "", "", "", "", "",
+ /* M */ "", "", "", "", "", "", "", "",
+ /* N */ "", "", "", "", "", "", "", "",
+ /* O */ "", "", "", "", "", "", "", "",
+ /* P */ "", "", "", "", "", "", "", "",
+ /* Q */ "", "", "", "", "", "", "", "",
+ /* R */ "", "", "", "", "", "", "", "",
+ /* S */ "PCHHOT_BMC_N", "", "RSMRST", "", "", "", "", "",
+ /* T */ "", "", "", "", "", "", "", "",
+ /* U */ "", "", "", "", "", "", "", "",
+ /* V */ "", "", "", "", "", "", "", "",
+ /* W */ "", "", "", "", "", "", "", "",
+ /* X */ "", "", "", "", "", "", "", "",
+ /* Y */ "SLP_S3", "SLP_S5", "", "", "", "", "", "",
+ /* Z */ "CPU_CATERR_BMC_N", "", "SYSTEM_FAULT_LED_N", "BMC_THROTTLE_N",
+ "", "", "", "",
+ /* AA */ "CPU1_THERMTRIP_LATCH_N", "", "CPU1_PROCHOT_N", "",
+ "", "", "IRQ_SMI_ACTIVE_N", "FM_BIOS_POST_CMPLT_N",
+ /* AB */ "", "", "ME_OVERRIDE", "BMC_DMI_MODIFY", "", "", "", "",
+ /* AC */ "", "", "", "", "", "", "", "";
+};
+
+&adc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default /* 3VSB */
+ &pinctrl_adc1_default /* 5VSB */
+ &pinctrl_adc2_default /* CPU1 */
+ &pinctrl_adc3_default /* VCCSA */
+ &pinctrl_adc4_default /* VCCM */
+ &pinctrl_adc5_default /* V10M */
+ &pinctrl_adc6_default /* VCCIO */
+ &pinctrl_adc7_default /* VCCGT */
+ &pinctrl_adc8_default /* VPPM */
+ &pinctrl_adc9_default /* BAT */
+ &pinctrl_adc10_default /* 3V */
+ &pinctrl_adc11_default /* 5V */
+ &pinctrl_adc12_default /* 12V */
+ &pinctrl_adc13_default /* GND */
+ &pinctrl_adc14_default /* GND */
+ &pinctrl_adc15_default>; /* GND */
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
index 4554abf0c7cd..6dd221644dc6 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
@@ -71,6 +71,9 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+
+ nvmem-cells = <&eth0_macaddress>;
+ nvmem-cell-names = "mac-address";
};
&i2c0 {
@@ -98,14 +101,14 @@
/* IPB PMIC */
lm25066@40 {
- compatible = "lm25066";
+ compatible = "ti,lm25066";
reg = <0x40>;
shunt-resistor-micro-ohms = <1000>;
};
/* 12VSB PMIC */
lm25066@41 {
- compatible = "lm25066";
+ compatible = "ti,lm25066";
reg = <0x41>;
shunt-resistor-micro-ohms = <10000>;
};
@@ -131,6 +134,12 @@
compatible = "st,24c128", "atmel,24c128";
reg = <0x50>;
pagesize = <16>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eth0_macaddress: macaddress@3f80 {
+ reg = <0x3f80 6>;
+ };
};
};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts
new file mode 100644
index 000000000000..555485871e7a
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/common.h>
+
+/{
+ model = "ASRock SPC621D8HM3 BMC";
+ compatible = "asrock,spc621d8hm3-bmc", "aspeed,ast2500";
+
+ aliases {
+ serial4 = &uart5;
+
+ i2c20 = &i2c1mux0ch0;
+ i2c21 = &i2c1mux0ch1;
+ };
+
+ chosen {
+ stdout-path = &uart5;
+ };
+
+ memory@80000000 {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ /* BMC heartbeat */
+ led-0 {
+ gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_LOW>;
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_GREEN>;
+ linux,default-trigger = "timer";
+ };
+
+ /* system fault */
+ led-1 {
+ gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+ function = LED_FUNCTION_FAULT;
+ color = <LED_COLOR_ID_RED>;
+ panic-indicator;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+ <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>,
+ <&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>,
+ <&adc 12>, <&adc 13>, <&adc 14>, <&adc 15>;
+ };
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>; /* 50 MHz */
+#include "openbmc-flash-layout-64.dtsi"
+ };
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&vuart {
+ status = "okay";
+ aspeed,lpc-io-reg = <0x2f8>;
+ aspeed,lpc-interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mac0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+
+ nvmem-cells = <&eth0_macaddress>;
+ nvmem-cell-names = "mac-address";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ /* hardware monitor/thermal sensor */
+ temperature-sensor@29 {
+ compatible = "nuvoton,nct7802";
+ reg = <0x29>;
+ };
+
+ /* motherboard temp sensor (TMP1, near BMC) */
+ temperature-sensor@4c {
+ compatible = "nuvoton,w83773g";
+ reg = <0x4c>;
+ };
+
+ /* motherboard FRU eeprom */
+ eeprom@50 {
+ compatible = "st,24c128", "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <16>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eth0_macaddress: macaddress@3f80 {
+ reg = <0x3f80 6>;
+ };
+ };
+
+ /* M.2 slot smbus mux */
+ i2c-mux@71 {
+ compatible = "nxp,pca9545";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c1mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c1mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&i2c10 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+};
+
+&i2c12 {
+ status = "okay";
+};
+
+&i2c13 {
+ status = "okay";
+};
+
+&video {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&lpc_snoop {
+ status = "okay";
+ snoop-ports = <0x80>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca2>;
+};
+
+&peci0 {
+ status = "okay";
+};
+
+&pwm_tacho {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0_default
+ &pinctrl_pwm2_default
+ &pinctrl_pwm3_default
+ &pinctrl_pwm4_default>;
+
+ fan@0 {
+ reg = <0x00>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+ };
+
+ 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>;
+ };
+};
+
+&gpio {
+ status = "okay";
+ gpio-line-names =
+ /* A */ "LOCATORLED_STATUS_N", "LOCATORBTN_N",
+ "BMC_READY_N", "FM_SPD_DDRCPU_LVLSHFT_EN",
+ "", "", "", "",
+ /* B */ "NODE_ID_1", "NODE_ID_2", "PSU_FAN_FAIL_N", "",
+ "", "", "", "GPIO_RST",
+ /* C */ "", "", "", "", "", "", "", "",
+ /* D */ "FP_PWR_BTN_MUX_N", "FM_BMC_PWRBTN_OUT_N",
+ "FP_RST_BTN_N", "RST_BMC_RSTBTN_OUT_N",
+ "NMI_BTN_N", "BMC_NMI",
+ "", "",
+ /* E */ "", "", "", "FM_ME_RCVR_N", "", "", "", "",
+ /* F */ "BMC_SMB_SEL_N", "FM_CPU2_DISABLE_COD_N",
+ "FM_REMOTE_DEBUG_BMC_EN", "FM_CPU_ERR0_LVT3_EN",
+ "FM_CPU_ERR1_LVT3_EN", "FM_CPU_ERR2_LVT3_EN",
+ "FM_MEM_THERM_EVENT_CPU1_LVT3_N", "FM_MEM_THERM_EVENT_CPU2_LVT3_N",
+ /* G */ "HWM_BAT_EN", "", "BMC_PHYRST_N", "FM_BIOS_SPI_BMC_CTRL",
+ "BMC_ALERT1_N", "BMC_ALERT2_N", "BMC_ALERT3_N", "IRQ_SML0_ALERT_N",
+ /* H */ "BMC_SMB_PRESENT_1_N", "FM_PCH_CORE_VID_0", "FM_PCH_CORE_VID_1", "",
+ "FM_MFG_MODE", "BMC_RTCRST", "BMC_HB_LED_N", "BMC_CASEOPEN",
+ /* I */ "IRQ_PVDDQ_ABCD_CPU1_VRHOT_LVC3_N", "IRQ_PVDDQ_ABCD_CPU2_VRHOT_LVC3_N",
+ "IRQ_PVDDQ_EFGH_CPU1_VRHOT_LVC3_N", "IRQ_PVDDQ_EFGH_CPU2_VRHOT_LVC3_N",
+ "", "", "", "",
+ /* J */ "", "", "", "", "", "", "", "",
+ /* K */ "", "", "", "", "", "", "", "",
+ /* L */ "", "", "", "", "", "", "", "",
+ /* M */ "FM_PVCCIN_CPU1_PWR_IN_ALERT_N", "FM_PVCCIN_CPU2_PWR_IN_ALERT_N",
+ "IRQ_PVCCIN_CPU1_VRHOT_LVC3_N", "IRQ_PVCCIN_CPU2_VRHOT_LVC3_N",
+ "FM_CPU1_PROCHOT_BMC_LVC3_N", "",
+ "FM_CPU1_MEMHOT_OUT_N", "FM_CPU2_MEMHOT_OUT_N",
+ /* N */ "", "", "", "", "", "", "", "",
+ /* O */ "", "", "", "", "", "", "", "",
+ /* P */ "", "", "", "", "", "", "", "",
+ /* Q */ "", "", "", "", "", "", "RST_GLB_RST_WARN_N", "PCIE_WAKE_N",
+ /* R */ "", "", "FM_BMC_SUSACK_N", "FM_BMC_EUP_LOT6_N",
+ "", "FM_BMC_PCH_SCI_LPC_N", "", "",
+ /* S */ "FM_DBP_PRESENT_N", "FM_CPU2_SKTOCC_LCT3_N",
+ "FM_CPU1_FIVR_FAULT_LVT3", "FM_CPU2_FIVR_FAULT_LVT3",
+ "", "", "", "",
+ /* T */ "", "", "", "", "", "", "", "",
+ /* U */ "", "", "", "", "", "", "", "",
+ /* V */ "", "", "", "", "", "", "", "",
+ /* W */ "", "", "", "", "", "", "", "",
+ /* X */ "", "", "", "", "", "", "", "",
+ /* Y */ "FM_SLPS3_N", "FM_SLPS4_N", "", "FM_BMC_ONCTL_N_PLD",
+ "", "", "", "",
+ /* Z */ "FM_CPU_MSMI_CATERR_LVT3_N", "", "SYSTEM_FAULT_LED_N", "BMC_THROTTLE_N",
+ "", "", "", "",
+ /* AA */ "FM_CPU1_THERMTRIP_LATCH_LVT3_N", "FM_CPU2_THERMTRIP_LATCH_LVT3_N",
+ "FM_BIOS_POST_COMPLT_N", "DBP_BMC_SYSPWROK",
+ "", "IRQ_SML0_ALERT_MUX_N",
+ "IRQ_SMI_ACTIVE_N", "IRQ_NMI_EVENT_N",
+ /* AB */ "FM_PCH_BMC_THERMTRIP_N", "PWRGD_SYS_PWROK",
+ "ME_OVERRIDE", "IRQ_BMC_PCH_SMI_LPC_N",
+ "", "", "", "",
+ /* AC */ "", "", "", "", "", "", "", "";
+};
+
+&adc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default /* 3VSB */
+ &pinctrl_adc1_default /* 5VSB */
+ &pinctrl_adc2_default /* CPU1 */
+ &pinctrl_adc3_default /* NC */
+ &pinctrl_adc4_default /* VCCMABCD */
+ &pinctrl_adc5_default /* VCCMEFGH */
+ &pinctrl_adc6_default /* NC */
+ &pinctrl_adc7_default /* NC */
+ &pinctrl_adc8_default /* PVNN_PCH */
+ &pinctrl_adc9_default /* 1P05PCH */
+ &pinctrl_adc10_default /* 1P8PCH */
+ &pinctrl_adc11_default /* BAT */
+ &pinctrl_adc12_default /* 3V */
+ &pinctrl_adc13_default /* 5V */
+ &pinctrl_adc14_default /* 12V */
+ &pinctrl_adc15_default>; /* GND */
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
new file mode 100644
index 000000000000..8dee4faa9e07
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Asrock Rack X570D4U BMC";
+ compatible = "asrock,x570d4u-bmc", "aspeed,ast2500";
+
+ aliases {
+ i2c40 = &i2c4mux0ch0;
+ i2c41 = &i2c4mux0ch1;
+ i2c42 = &i2c4mux0ch2;
+ i2c43 = &i2c4mux0ch3;
+ };
+
+ chosen {
+ stdout-path = &uart5;
+ };
+
+ memory@80000000 {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pci_memory: region@9a000000 {
+ no-map;
+ reg = <0x9a000000 0x00010000>; /* 64K */
+ };
+
+ video_engine_memory: jpegbuffer {
+ size = <0x02800000>; /* 40M */
+ alignment = <0x01000000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+
+ gfx_memory: framebuffer {
+ size = <0x01000000>;
+ alignment = <0x01000000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ /* led-heartbeat-n */
+ gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "timer";
+ };
+
+ led-1 {
+ /* led-fault-n */
+ gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_FAULT;
+ panic-indicator;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, <&adc 4>,
+ <&adc 5>, <&adc 6>, <&adc 7>, <&adc 8>, <&adc 9>,
+ <&adc 10>, <&adc 11>, <&adc 12>;
+ };
+};
+
+&gpio {
+ status = "okay";
+ gpio-line-names =
+ /* A */ "input-locatorled-n", "", "", "", "", "", "", "",
+ /* B */ "input-bios-post-cmplt-n", "", "", "", "", "", "", "",
+ /* C */ "", "", "", "", "", "", "control-locatorbutton-n", "",
+ /* D */ "button-power-n", "control-power-n", "button-reset-n",
+ "control-reset-n", "", "", "", "",
+ /* E */ "", "", "", "", "", "", "", "",
+ /* F */ "", "", "", "", "", "", "", "",
+ /* G */ "output-hwm-vbat-enable", "input-id0-n", "input-id1-n",
+ "input-id2-n", "input-aux-smb-alert-n", "",
+ "input-psu-smb-alert-n", "",
+ /* H */ "", "", "", "", "input-mfg-mode-n", "",
+ "led-heartbeat-n", "input-case-open-n",
+ /* I */ "", "", "", "", "", "", "", "",
+ /* J */ "output-bmc-ready-n", "", "", "", "", "", "", "",
+ /* K */ "", "", "", "", "", "", "", "",
+ /* L */ "", "", "", "", "", "", "", "",
+ /* M */ "", "", "", "", "", "", "", "",
+ /* N */ "", "", "", "", "", "", "", "",
+ /* O */ "", "", "", "", "", "", "", "",
+ /* P */ "", "", "", "", "", "", "", "",
+ /* Q */ "", "", "", "", "input-bmc-smb-present-n", "", "",
+ "input-pcie-wake-n",
+ /* R */ "", "", "", "", "", "", "", "",
+ /* S */ "input-bmc-pchhot-n", "", "", "", "", "", "", "",
+ /* T */ "", "", "", "", "", "", "", "",
+ /* U */ "", "", "", "", "", "", "", "",
+ /* V */ "", "", "", "", "", "", "", "",
+ /* W */ "", "", "", "", "", "", "", "",
+ /* X */ "", "", "", "", "", "", "", "",
+ /* Y */ "input-sleep-s3-n", "input-sleep-s5-n", "", "", "", "",
+ "", "",
+ /* Z */ "", "", "led-fault-n", "output-bmc-throttle-n", "", "",
+ "", "",
+ /* AA */ "input-cpu1-thermtrip-latch-n", "",
+ "input-cpu1-prochot-n", "", "", "", "", "",
+ /* AB */ "", "input-power-good", "", "", "", "", "", "",
+ /* AC */ "", "", "", "", "", "", "", "";
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ label = "bmc";
+ m25p,fast-read;
+ spi-max-frequency = <10000000>;
+#include "openbmc-flash-layout-64.dtsi"
+ };
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&vuart {
+ status = "okay";
+};
+
+&mac0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+
+ nvmem-cells = <&eth0_macaddress>;
+ nvmem-cell-names = "mac-address";
+};
+
+&mac1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii2_default &pinctrl_mdio2_default>;
+ use-ncsi;
+
+ nvmem-cells = <&eth1_macaddress>;
+ nvmem-cell-names = "mac-address";
+};
+
+&i2c0 {
+ /* SMBus on auxiliary panel header (AUX_PANEL1) */
+ status = "okay";
+};
+
+&i2c1 {
+ /* Hardware monitoring SMBus */
+ status = "okay";
+
+ w83773g@4c {
+ compatible = "nuvoton,w83773g";
+ reg = <0x4c>;
+ };
+};
+
+&i2c2 {
+ /* PSU SMBus (PSU_SMB1) */
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9545";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c4mux0ch0: i2c@0 {
+ /* SMBus on PCI express 16x slot */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c4mux0ch1: i2c@1 {
+ /* SMBus on PCI express 8x slot */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c4mux0ch2: i2c@2 {
+ /* Unknown */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c4mux0ch3: i2c@3 {
+ /* SMBus on PCI express 1x slot */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c5 {
+ /* SMBus on BMC connector (BMC_SMB_1) */
+ status = "okay";
+};
+
+&i2c7 {
+ /* FRU and SPD EEPROM SMBus */
+ status = "okay";
+
+ eeprom@57 {
+ compatible = "st,24c128", "atmel,24c128";
+ reg = <0x57>;
+ pagesize = <16>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eth0_macaddress: macaddress@3f80 {
+ reg = <0x3f80 6>;
+ };
+
+ eth1_macaddress: macaddress@3f88 {
+ reg = <0x3f88 6>;
+ };
+ };
+};
+
+&i2c8 {
+ /* SMBus on intelligent platform management bus header (IPMB_1) */
+ status = "okay";
+};
+
+&gfx {
+ status = "okay";
+};
+
+&pinctrl {
+ aspeed,external-nodes = <&gfx &lhc>;
+};
+
+&vhub {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&uhci {
+ status = "okay";
+};
+
+&kcs3 {
+ aspeed,lpc-io-reg = <0xca2>;
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&lpc_snoop {
+ status = "okay";
+ snoop-ports = <0x80>;
+};
+
+&p2a {
+ status = "okay";
+ memory-region = <&pci_memory>;
+};
+
+&video {
+ status = "okay";
+ memory-region = <&video_engine_memory>;
+};
+
+&pwm_tacho {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0_default
+ &pinctrl_pwm1_default
+ &pinctrl_pwm2_default
+ &pinctrl_pwm3_default
+ &pinctrl_pwm4_default
+ &pinctrl_pwm5_default>;
+
+ fan@0 {
+ /* FAN1 (4-pin) */
+ reg = <0x00>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+ };
+
+ fan@1 {
+ /* FAN2 (4-pin) */
+ reg = <0x01>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x01>;
+ };
+
+ fan@2 {
+ /* FAN3 (4-pin) */
+ reg = <0x02>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x02>;
+ };
+
+ fan@3 {
+ /* FAN4 (6-pin) */
+ reg = <0x03>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x04 0x0b>;
+ };
+
+ fan@4 {
+ /* FAN6 (6-pin) */
+ reg = <0x04>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x06 0x0d>;
+ };
+
+ fan@5 {
+ /* FAN5 (6-pin) */
+ reg = <0x05>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x05 0x0c>;
+ };
+};
+
+&adc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default /* 3VSB */
+ &pinctrl_adc1_default /* 5VSB */
+ &pinctrl_adc2_default /* VCPU */
+ &pinctrl_adc3_default /* VSOC */
+ &pinctrl_adc4_default /* VCCM */
+ &pinctrl_adc5_default /* APU-VDDP */
+ &pinctrl_adc6_default /* PM-VDD-CLDO */
+ &pinctrl_adc7_default /* PM-VDDCR-S5 */
+ &pinctrl_adc8_default /* PM-VDDCR */
+ &pinctrl_adc9_default /* VBAT */
+ &pinctrl_adc10_default /* 3V */
+ &pinctrl_adc11_default /* 5V */
+ &pinctrl_adc12_default>; /* 12V */
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
new file mode 100644
index 000000000000..64f4ed07c7d2
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2024 ASUS Corp.
+
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include "aspeed-g6-pinctrl.dtsi"
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+ model = "ASUS-X4TF";
+ compatible = "asus,x4tf-bmc", "aspeed,ast2600";
+
+ aliases {
+ serial4 = &uart5;
+ };
+
+ chosen {
+ stdout-path = "serial4:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ video_engine_memory: video {
+ size = <0x04000000>;
+ alignment = <0x01000000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+ <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-heartbeat {
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-uid {
+ gpios = <&gpio0 ASPEED_GPIO(P, 1) (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+ default-state = "off";
+ };
+
+ led-status_Y {
+ gpios = <&gpio1 ASPEED_GPIO(B, 1) GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led-sys_boot_status {
+ gpios = <&gpio1 ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+};
+
+&adc0 {
+ vref = <2500>;
+ 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>;
+};
+
+&adc1 {
+ vref = <2500>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
+ &pinctrl_adc10_default &pinctrl_adc11_default
+ &pinctrl_adc12_default &pinctrl_adc13_default
+ &pinctrl_adc14_default &pinctrl_adc15_default>;
+};
+
+&peci0 {
+ status = "okay";
+};
+
+&lpc_snoop {
+ snoop-ports = <0x80>;
+ status = "okay";
+};
+
+&mac2 {
+ status = "okay";
+ phy-mode = "rmii";
+ use-ncsi;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii3_default>;
+};
+
+&mac3 {
+ status = "okay";
+ phy-mode = "rmii";
+ use-ncsi;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+};
+
+&fmc {
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-64.dtsi"
+ };
+};
+
+&spi1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1_default>;
+
+ flash@0 {
+ status = "okay";
+ label = "bios";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp75";
+ reg = <0x48>;
+ };
+
+ temperature-sensor@49 {
+ compatible = "ti,tmp75";
+ reg = <0x49>;
+ };
+
+ pca9555_4_20: gpio@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9555_4_22: gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9555_4_24: gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names =
+ /*A0 - A3 0*/ "", "STRAP_BMC_BATTERY_GPIO1", "", "",
+ /*A4 - A7 4*/ "", "", "", "",
+ /*B0 - B7 8*/ "", "", "", "", "", "", "", "";
+ };
+
+ pca9555_4_26: gpio@26 {
+ compatible = "nxp,pca9555";
+ reg = <0x26>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ status = "okay";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel_1: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ channel_2: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ channel_3: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ channel_4: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c5 {
+ status = "okay";
+
+ pca9555_5_24: gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ status = "okay";
+ reg = <0x70 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel_5: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ pca9555_5_5_20: gpio@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names =
+ "", "", "", "", "", "", "", "",
+ "", "", "SYS_FAN6", "SYS_FAN5",
+ "SYS_FAN4", "SYS_FAN3",
+ "SYS_FAN2", "SYS_FAN1";
+ };
+
+ pca9555_5_5_21: gpio@21 {
+ compatible = "nxp,pca9555";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ power-monitor@44 {
+ compatible = "ti,ina219";
+ reg = <0x44>;
+ shunt-resistor = <2>;
+ };
+ };
+
+ channel_6: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ channel_7: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ channel_8: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ pca9555_6_27: gpio@27 {
+ compatible = "nxp,pca9555";
+ reg = <0x27>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9555_6_20: gpio@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names =
+ /*A0 0*/ "", "", "", "", "", "", "", "",
+ /*B0 8*/ "Drive_NVMe1", "Drive_NVMe2", "", "",
+ /*B4 12*/ "", "", "", "";
+ };
+
+ pca9555_6_21: gpio@21 {
+ compatible = "nxp,pca9555";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ status = "okay";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ idle-state = <1>;
+
+ channel_9: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp75";
+ reg = <0x48>;
+ };
+
+ temperature-sensor@49 {
+ compatible = "ti,tmp75";
+ reg = <0x49>;
+ };
+
+ power-monitor@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <2>;
+ };
+
+ power-monitor@41 {
+ compatible = "ti,ina219";
+ reg = <0x41>;
+ shunt-resistor = <5>;
+ };
+ };
+
+ channel_10: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ channel_11: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ channel_12: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9546";
+ status = "okay";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ channel_13: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ channel_14: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ channel_15: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ channel_16: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c8 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ status = "okay";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ channel_17: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ channel_18: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp75";
+ reg = <0x48>;
+ };
+
+ power-monitor@41 {
+ compatible = "ti,ina219";
+ reg = <0x41>;
+ shunt-resistor = <5>;
+ };
+ };
+
+ channel_19: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ channel_20: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&i2c10 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+};
+
+&i2c14 {
+ status = "okay";
+ multi-master;
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c08";
+ reg = <0x51>;
+ };
+};
+
+&sgpiom0 {
+ status = "okay";
+ ngpios = <128>;
+};
+
+&video {
+ status = "okay";
+ memory-region = <&video_engine_memory>;
+};
+
+&sdc {
+ status = "okay";
+};
+
+&lpc_snoop {
+ status = "okay";
+ snoop-ports = <0x80>;
+};
+
+&kcs1 {
+ aspeed,lpc-io-reg = <0xca0>;
+ status = "okay";
+};
+
+&kcs2 {
+ aspeed,lpc-io-reg = <0xca8>;
+ status = "okay";
+};
+
+&kcs3 {
+ aspeed,lpc-io-reg = <0xca2>;
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&uart_routing {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+};
+
+&gpio0 {
+ gpio-line-names =
+ /*A0 0*/ "", "", "", "", "", "", "", "",
+ /*B0 8*/ "", "", "", "", "", "", "PS_PWROK", "",
+ /*C0 16*/ "", "", "", "", "", "", "", "",
+ /*D0 24*/ "", "", "", "", "", "", "", "",
+ /*E0 32*/ "", "", "", "", "", "", "", "",
+ /*F0 40*/ "", "", "", "", "", "", "", "",
+ /*G0 48*/ "", "", "", "", "", "", "", "",
+ /*H0 56*/ "", "", "", "", "", "", "", "",
+ /*I0 64*/ "", "", "", "", "", "", "", "",
+ /*J0 72*/ "", "", "", "", "", "", "", "",
+ /*K0 80*/ "", "", "", "", "", "", "", "",
+ /*L0 88*/ "", "", "", "", "", "", "", "",
+ /*M0 96*/ "", "", "", "", "", "", "", "",
+ /*N0 104*/ "", "", "", "",
+ /*N4 108*/ "POST_COMPLETE", "ESR1_GPIO_AST_SPISEL", "", "",
+ /*O0 112*/ "", "", "", "", "", "", "", "",
+ /*P0 120*/ "ID_BUTTON", "ID_OUT", "POWER_BUTTON", "POWER_OUT",
+ /*P4 124*/ "RESET_BUTTON", "RESET_OUT", "", "HEARTBEAT",
+ /*Q0 128*/ "", "", "", "", "", "", "", "",
+ /*R0 136*/ "", "", "", "", "", "", "", "",
+ /*S0 144*/ "", "", "", "", "", "", "", "",
+ /*T0 152*/ "", "", "", "", "", "", "", "",
+ /*U0 160*/ "", "", "", "", "", "", "", "",
+ /*V0 168*/ "", "", "", "", "", "", "", "",
+ /*W0 176*/ "", "", "", "", "", "", "", "",
+ /*X0 184*/ "", "", "", "", "", "", "", "",
+ /*Y0 192*/ "", "", "", "", "", "", "", "",
+ /*Z0 200*/ "", "", "", "", "", "", "", "";
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
index 6600f7e9bf5e..b6bfdaea08e6 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
@@ -14,11 +14,11 @@
#define EFUSE(hexaddr, num) \
efuse@##hexaddr { \
- compatible = "lm25066"; \
+ compatible = "ti,lm25066"; \
reg = <0x##hexaddr>; \
shunt-resistor-micro-ohms = <675>; \
regulators { \
- efuse##num: vout0 { \
+ efuse##num: vout { \
regulator-name = __stringify(efuse##num##-reg); \
}; \
}; \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-cloudripper.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-cloudripper.dts
deleted file mode 100644
index d49328fa487a..000000000000
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-cloudripper.dts
+++ /dev/null
@@ -1,544 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-// Copyright (c) 2020 Facebook Inc.
-
-/dts-v1/;
-
-#include <dt-bindings/leds/common.h>
-#include "ast2600-facebook-netbmc-common.dtsi"
-
-/ {
- model = "Facebook Cloudripper BMC";
- compatible = "facebook,cloudripper-bmc", "aspeed,ast2600";
-
- aliases {
- /*
- * PCA9548 (1-0070) provides 8 channels connecting to
- * SMB (Switch Main Board).
- */
- i2c16 = &imux16;
- i2c17 = &imux17;
- i2c18 = &imux18;
- i2c19 = &imux19;
- i2c20 = &imux20;
- i2c21 = &imux21;
- i2c22 = &imux22;
- i2c23 = &imux23;
-
- /*
- * PCA9548 (2-0070) provides 8 channels connecting to
- * SCM (System Controller Module).
- */
- i2c24 = &imux24;
- i2c25 = &imux25;
- i2c26 = &imux26;
- i2c27 = &imux27;
- i2c28 = &imux28;
- i2c29 = &imux29;
- i2c30 = &imux30;
- i2c31 = &imux31;
-
- /*
- * PCA9548 (3-0070) provides 8 channels connecting to
- * SMB (Switch Main Board).
- */
- i2c32 = &imux32;
- i2c33 = &imux33;
- i2c34 = &imux34;
- i2c35 = &imux35;
- i2c36 = &imux36;
- i2c37 = &imux37;
- i2c38 = &imux38;
- i2c39 = &imux39;
-
- /*
- * PCA9548 (8-0070) provides 8 channels connecting to
- * PDB (Power Delivery Board).
- */
- i2c40 = &imux40;
- i2c41 = &imux41;
- i2c42 = &imux42;
- i2c43 = &imux43;
- i2c44 = &imux44;
- i2c45 = &imux45;
- i2c46 = &imux46;
- i2c47 = &imux47;
-
- /*
- * PCA9548 (15-0076) provides 8 channels connecting to
- * FCM (Fan Controller Module).
- */
- i2c48 = &imux48;
- i2c49 = &imux49;
- i2c50 = &imux50;
- i2c51 = &imux51;
- i2c52 = &imux52;
- i2c53 = &imux53;
- i2c54 = &imux54;
- i2c55 = &imux55;
- };
-
- spi_gpio: spi {
- num-chipselects = <2>;
- cs-gpios = <&gpio0 ASPEED_GPIO(X, 0) GPIO_ACTIVE_LOW>,
- <&gpio0 ASPEED_GPIO(X, 1) GPIO_ACTIVE_HIGH>;
-
- eeprom@1 {
- compatible = "atmel,at93c46d";
- spi-max-frequency = <250000>;
- data-size = <16>;
- spi-cs-high;
- reg = <1>;
- };
- };
-};
-
-&ehci1 {
- status = "okay";
-};
-
-/*
- * "mdio1" is connected to the MDC/MDIO interface of the on-board
- * management switch (whose ports are connected to BMC, Host and front
- * panel ethernet port).
- */
-&mdio1 {
- status = "okay";
-};
-
-&mdio3 {
- status = "okay";
-
- ethphy1: ethernet-phy@13 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <0x0d>;
- };
-};
-
-&mac3 {
- status = "okay";
- phy-mode = "rgmii";
- phy-handle = <&ethphy1>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_rgmii4_default>;
-};
-
-&i2c0 {
- multi-master;
- bus-frequency = <1000000>;
-};
-
-&i2c1 {
- /*
- * PCA9548 (1-0070) provides 8 channels connecting to SMB (Switch
- * Main Board).
- */
- i2c-mux@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>;
- };
- };
-};
-
-&i2c2 {
- /*
- * PCA9548 (2-0070) provides 8 channels connecting to SCM (System
- * Controller Module).
- */
- i2c-mux@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>;
- };
- };
-};
-
-&i2c3 {
- /*
- * PCA9548 (3-0070) provides 8 channels connecting to SMB (Switch
- * Main Board).
- */
- i2c-mux@70 {
- compatible = "nxp,pca9548";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x70>;
- 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>;
- };
- };
-};
-
-&i2c6 {
- lp5012@14 {
- compatible = "ti,lp5012";
- reg = <0x14>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- multi-led@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- color = <LED_COLOR_ID_MULTI>;
- function = LED_FUNCTION_ACTIVITY;
- label = "sys";
-
- led@0 {
- reg = <0>;
- color = <LED_COLOR_ID_RED>;
- };
-
- led@1 {
- reg = <1>;
- color = <LED_COLOR_ID_BLUE>;
- };
-
- led@2 {
- reg = <2>;
- color = <LED_COLOR_ID_GREEN>;
- };
- };
-
- multi-led@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- color = <LED_COLOR_ID_MULTI>;
- function = LED_FUNCTION_ACTIVITY;
- label = "fan";
-
- led@0 {
- reg = <0>;
- color = <LED_COLOR_ID_RED>;
- };
-
- led@1 {
- reg = <1>;
- color = <LED_COLOR_ID_BLUE>;
- };
-
- led@2 {
- reg = <2>;
- color = <LED_COLOR_ID_GREEN>;
- };
- };
-
- multi-led@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- color = <LED_COLOR_ID_MULTI>;
- function = LED_FUNCTION_ACTIVITY;
- label = "psu";
-
- led@0 {
- reg = <0>;
- color = <LED_COLOR_ID_RED>;
- };
-
- led@1 {
- reg = <1>;
- color = <LED_COLOR_ID_BLUE>;
- };
-
- led@2 {
- reg = <2>;
- color = <LED_COLOR_ID_GREEN>;
- };
- };
-
- multi-led@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- color = <LED_COLOR_ID_MULTI>;
- function = LED_FUNCTION_ACTIVITY;
- label = "scm";
-
- led@0 {
- reg = <0>;
- color = <LED_COLOR_ID_RED>;
- };
-
- led@1 {
- reg = <1>;
- color = <LED_COLOR_ID_BLUE>;
- };
-
- led@2 {
- reg = <2>;
- color = <LED_COLOR_ID_GREEN>;
- };
- };
- };
-};
-
-&i2c8 {
- /*
- * PCA9548 (8-0070) provides 8 channels connecting to PDB (Power
- * Delivery Board).
- */
- i2c-mux@70 {
- compatible = "nxp,pca9548";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x70>;
- i2c-mux-idle-disconnect;
-
- imux40: i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- };
-
- imux41: i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- };
-
- imux42: i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- };
-
- imux43: i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- };
-
- imux44: i2c@4 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <4>;
- };
-
- imux45: i2c@5 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <5>;
- };
-
- imux46: i2c@6 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <6>;
- };
-
- imux47: i2c@7 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <7>;
- };
-
- };
-};
-
-&i2c15 {
- /*
- * PCA9548 (15-0076) provides 8 channels connecting to FCM (Fan
- * Controller Module).
- */
- i2c-mux@76 {
- compatible = "nxp,pca9548";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x76>;
- i2c-mux-idle-disconnect;
-
- imux48: i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- };
-
- imux49: i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- };
-
- imux50: i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- };
-
- imux51: i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- };
-
- imux52: i2c@4 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <4>;
- };
-
- imux53: i2c@5 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <5>;
- };
-
- imux54: i2c@6 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <6>;
- };
-
- imux55: i2c@7 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <7>;
- };
- };
-};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-greatlakes.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-greatlakes.dts
index 7a53f54833a0..998598c15fd0 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-greatlakes.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-greatlakes.dts
@@ -66,7 +66,7 @@
pinctrl-0 = <&pinctrl_rmii4_default>;
no-hw-checksum;
use-ncsi;
- mlx,multi-host;
+ mellanox,multi-host;
ncsi-ctrl,start-redo-probe;
ncsi-ctrl,no-channel-monitor;
ncsi-package = <1>;
@@ -211,7 +211,6 @@
};
&adc0 {
- ref_voltage = <2500>;
status = "okay";
pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
&pinctrl_adc2_default &pinctrl_adc3_default
@@ -220,7 +219,6 @@
};
&adc1 {
- ref_voltage = <2500>;
status = "okay";
pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc10_default
&pinctrl_adc11_default &pinctrl_adc12_default
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
new file mode 100644
index 000000000000..c118d473a76f
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -0,0 +1,648 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2023 Facebook Inc.
+
+/dts-v1/;
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+ model = "Facebook Harma";
+ compatible = "facebook,harma-bmc", "aspeed,ast2600";
+
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart4;
+ serial4 = &uart5;
+
+ i2c20 = &imux20;
+ i2c21 = &imux21;
+ i2c22 = &imux22;
+ i2c23 = &imux23;
+ i2c24 = &imux24;
+ i2c25 = &imux25;
+ i2c26 = &imux26;
+ i2c27 = &imux27;
+ i2c28 = &imux28;
+ i2c29 = &imux29;
+ i2c30 = &imux30;
+ i2c31 = &imux31;
+
+ spi1 = &spi_gpio;
+ };
+
+ chosen {
+ stdout-path = &uart5;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "bmc_heartbeat_amber";
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-1 {
+ label = "fp_id_amber";
+ default-state = "off";
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-2 {
+ label = "power_blue";
+ default-state = "off";
+ gpios = <&gpio0 124 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spi_gpio: spi-gpio {
+ status = "okay";
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-sck = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+ gpio-miso = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
+ num-chipselects = <1>;
+ cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+
+ tpmdev@0 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ spi-max-frequency = <33000000>;
+ reg = <0>;
+ };
+ };
+};
+
+// HOST BIOS Debug
+&uart1 {
+ status = "okay";
+};
+
+// SOL Host Console
+&uart2 {
+ status = "okay";
+ pinctrl-0 = <>;
+};
+
+// SOL BMC Console
+&uart4 {
+ status = "okay";
+ pinctrl-0 = <>;
+};
+
+// BMC Debug Console
+&uart5 {
+ status = "okay";
+};
+
+// MTIA
+&uart6 {
+ status = "okay";
+};
+
+&uart_routing {
+ status = "okay";
+};
+
+&wdt1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdtrst1_default>;
+ aspeed,reset-type = "soc";
+ aspeed,external-signal;
+ aspeed,ext-push-pull;
+ aspeed,ext-active-high;
+ aspeed,ext-pulse-duration = <256>;
+};
+
+&mac3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+ use-ncsi;
+ mellanox,multi-host;
+};
+
+&rtc {
+ status = "okay";
+};
+
+&fmc {
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+ };
+
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+// BIOS Flash
+&spi2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2_default>;
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "pnor";
+ spi-max-frequency = <12000000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ };
+};
+
+&kcs2 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca8>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca2>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ temperature-sensor@4b {
+ compatible = "ti,tmp75";
+ reg = <0x4b>;
+ };
+
+ // MB NIC FRU
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9543";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ imux20: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ //Retimer Flash
+ eeprom@50 {
+ compatible = "atmel,24c2048";
+ reg = <0x50>;
+ pagesize = <128>;
+ };
+ };
+ imux21: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ retimer@24 {
+ compatible = "asteralabs,pt5161l";
+ reg = <0x24>;
+ };
+ };
+ };
+};
+
+&i2c4 {
+ status = "okay";
+ // PDB FRU
+ eeprom@52 {
+ compatible = "atmel,24c64";
+ reg = <0x52>;
+ };
+
+ power-monitor@69 {
+ compatible = "pmbus";
+ reg = <0x69>;
+ };
+
+ temperature-sensor@49 {
+ compatible = "ti,tmp75";
+ reg = <0x49>;
+ };
+
+ power-monitor@22 {
+ compatible = "lltc,ltc4286";
+ reg = <0x22>;
+ adi,vrange-low-enable;
+ shunt-resistor-micro-ohms = <500>;
+ };
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9543";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ imux22: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+ imux23: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+ };
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+
+ gpio@30 {
+ compatible = "nxp,pca9555";
+ reg = <0x30>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ gpio@31 {
+ compatible = "nxp,pca9555";
+ reg = <0x31>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "","","","",
+ "","","presence-cmm","",
+ "","","","",
+ "","","","";
+ };
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9546";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ 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>;
+ };
+ };
+ // PTTV FRU
+ eeprom@52 {
+ compatible = "atmel,24c64";
+ reg = <0x52>;
+ };
+};
+
+&i2c11 {
+ status = "okay";
+};
+
+&i2c12 {
+ status = "okay";
+ retimer@24 {
+ compatible = "asteralabs,pt5161l";
+ reg = <0x24>;
+ };
+};
+
+&i2c13 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9545";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ imux28: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+ imux29: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ //MB FRU
+ eeprom@54 {
+ compatible = "atmel,24c64";
+ reg = <0x54>;
+ };
+ };
+ imux30: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+ imux31: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+// To Debug card
+&i2c14 {
+ status = "okay";
+ multi-master;
+
+ ipmb@10 {
+ compatible = "ipmb-dev";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ i2c-protocol;
+ };
+};
+
+&i2c15 {
+ status = "okay";
+
+ // SCM FRU
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ };
+
+ // BSM FRU
+ eeprom@56 {
+ compatible = "atmel,24c64";
+ reg = <0x56>;
+ };
+};
+
+&adc0 {
+ aspeed,int-vref-microvolt = <2500000>;
+ status = "okay";
+ 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>;
+};
+
+&adc1 {
+ aspeed,int-vref-microvolt = <2500000>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc10_default>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ gpio-line-names =
+ /*A0-A7*/ "","","","","","","","",
+ /*B0-B7*/ "","","","",
+ "bmc-spi-mux-select-0","led-identify","","",
+ /*C0-C7*/ "reset-cause-platrst","","","","",
+ "cpu0-err-alert","","",
+ /*D0-D7*/ "","","sol-uart-select","","","","","",
+ /*E0-E7*/ "","","","","","","","",
+ /*F0-F7*/ "","","","","","","","",
+ /*G0-G7*/ "","","","","","","","",
+ /*H0-H7*/ "","","","","","","","",
+ /*I0-I7*/ "","","","","","","","",
+ /*J0-J7*/ "","","","","","","","",
+ /*K0-K7*/ "","","","","","","","",
+ /*L0-L7*/ "","","","",
+ "leakage-detect-alert","","","",
+ /*M0-M7*/ "","","","","","","","",
+ /*N0-N7*/ "led-postcode-0","led-postcode-1",
+ "led-postcode-2","led-postcode-3",
+ "led-postcode-4","led-postcode-5",
+ "led-postcode-6","led-postcode-7",
+ /*O0-O7*/ "","","","","","","","",
+ /*P0-P7*/ "power-button","power-host-control",
+ "reset-button","","led-power","","","",
+ /*Q0-Q7*/ "","","","","","","","",
+ /*R0-R7*/ "","","","","","","","",
+ /*S0-S7*/ "","","","","","","","",
+ /*T0-T7*/ "","","","","","","","",
+ /*U0-U7*/ "","","","","","","led-identify-gate","",
+ /*V0-V7*/ "","","","",
+ "rtc-battery-voltage-read-enable","","","",
+ /*W0-W7*/ "","","","","","","","",
+ /*X0-X7*/ "","","","","","","","",
+ /*Y0-Y7*/ "","","","","","","","",
+ /*Z0-Z7*/ "","","","","","","presence-post-card","";
+};
+
+&gpio1 {
+ gpio-line-names =
+ /*18A0-18A7*/ "ac-power-button","","","","","","","",
+ /*18B0-18B7*/ "","","","","","","","",
+ /*18C0-18C7*/ "","","","","","","","",
+ /*18D0-18D7*/ "","","","","","","","",
+ /*18E0-18E3*/ "","","","","","","","";
+};
+
+&sgpiom0 {
+ status = "okay";
+ max-ngpios = <128>;
+ ngpios = <128>;
+ bus-frequency = <2000000>;
+ gpio-line-names =
+ /*in - out - in - out */
+ /*A0-A3 line 0-7*/
+ "presence-scm-cable","power-config-disable-e1s-0",
+ "","",
+ "","power-config-disable-e1s-1",
+ "","",
+ /*A4-A7 line 8-15*/
+ "","power-config-asic-module-enable",
+ "","power-config-asic-power-good",
+ "","power-config-pdb-power-good",
+ "presence-cpu","smi-control-n",
+ /*B0-B3 line 16-23*/
+ "","nmi-control-n",
+ "","nmi-control-sync-flood-n",
+ "","",
+ "","",
+ /*B4-B7 line 24-31*/
+ "","FM_CPU_SP5R1",
+ "reset-cause-rsmrst","FM_CPU_SP5R2",
+ "","FM_CPU_SP5R3",
+ "","FM_CPU_SP5R4",
+ /*C0-C3 line 32-39*/
+ "","FM_CPU0_SA0",
+ "","FM_CPU0_SA1",
+ "","rt-cpu0-p0-enable",
+ "","rt-cpu0-p1-enable",
+ /*C4-C7 line 40-47*/
+ "","smb-rt-rom-p0-select",
+ "","smb-rt-rom-p1-select",
+ "","i3c-cpu-mux0-oe-n",
+ "","i3c-cpu-mux0-select",
+ /*D0-D3 line 48-55*/
+ "","i3c-cpu-mux1-oe-n",
+ "","i3c-cpu-mux1-select",
+ "","reset-control-bmc",
+ "","reset-control-cpu0-p0-mux",
+ /*D4-D7 line 56-63*/
+ "","reset-control-cpu0-p1-mux",
+ "","reset-control-e1s-mux",
+ "power-host-good","reset-control-mb-mux",
+ "host0-ready","reset-control-smb-e1s-0",
+ /*E0-E3 line 64-71*/
+ "","reset-control-smb-e1s-1",
+ "post-end-n","reset-control-srst",
+ "presence-e1s-0","reset-control-usb-hub",
+ "","reset-control",
+ /*E4-E7 line 72-79*/
+ "presence-e1s-1","reset-control-cpu-kbrst",
+ "","reset-control-platrst",
+ "","bmc-jtag-mux-select-0",
+ "","bmc-jtag-mux-select-1",
+ /*F0-F3 line 80-87*/
+ "","bmc-jtag-select",
+ "","bmc-ready-n",
+ "","bmc-ready-sgpio",
+ "","rt-cpu0-p0-force-enable",
+ /*F4-F7 line 88-95*/
+ "presence-asic-modules-0","rt-cpu0-p1-force-enable",
+ "presence-asic-modules-1","bios-debug-msg-disable",
+ "","uart-control-buffer-select",
+ "","ac-control-n",
+ /*G0-G3 line 96-103*/
+ "FM_CPU_CORETYPE2","",
+ "FM_CPU_CORETYPE1","",
+ "FM_CPU_CORETYPE0","",
+ "FM_BOARD_REV_ID5","",
+ /*G4-G7 line 104-111*/
+ "FM_BOARD_REV_ID4","",
+ "FM_BOARD_REV_ID3","",
+ "FM_BOARD_REV_ID2","",
+ "FM_BOARD_REV_ID1","",
+ /*H0-H3 line 112-119*/
+ "FM_BOARD_REV_ID0","",
+ "","","","","","",
+ /*H4-H7 line 120-127*/
+ "","",
+ "reset-control-pcie-expansion-3","",
+ "reset-control-pcie-expansion-2","",
+ "reset-control-pcie-expansion-1","",
+ /*I0-I3 line 128-135*/
+ "reset-control-pcie-expansion-0","",
+ "FM_EXP_SLOT_ID1","",
+ "FM_EXP_SLOT_ID0","",
+ "","",
+ /*I4-I7 line 136-143*/
+ "","","","","","","","",
+ /*J0-J3 line 144-151*/
+ "","","","","","","","",
+ /*J4-J7 line 152-159*/
+ "SLOT_ID_BCB_0","",
+ "SLOT_ID_BCB_1","",
+ "SLOT_ID_BCB_2","",
+ "SLOT_ID_BCB_3","",
+ /*K0-K3 line 160-167*/
+ "","","","","","","P0_I3C_APML_ALERT_L","",
+ /*K4-K7 line 168-175*/
+ "","","","","","","irq-uv-detect-alert","",
+ /*L0-L3 line 176-183*/
+ "irq-hsc-alert","",
+ "cpu0-prochot-alert","",
+ "cpu0-thermtrip-alert","",
+ "reset-cause-pcie","",
+ /*L4-L7 line 184-191*/
+ "pvdd11-ocp-alert","","","","","","","",
+ /*M0-M3 line 192-199*/
+ "","","","","","","","",
+ /*M4-M7 line 200-207*/
+ "","","","","","","","",
+ /*N0-N3 line 208-215*/
+ "","","","","","","","",
+ /*N4-N7 line 216-223*/
+ "","","","","","","","",
+ /*O0-O3 line 224-231*/
+ "","","","","","","","",
+ /*O4-O7 line 232-239*/
+ "","","","","","","","",
+ /*P0-P3 line 240-247*/
+ "","","","","","","","",
+ /*P4-P7 line 248-255*/
+ "","","","","","","","";
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts
deleted file mode 100644
index f04ef9063520..000000000000
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts
+++ /dev/null
@@ -1,265 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-// Copyright (c) 2023 Facebook Inc.
-/dts-v1/;
-
-#include "aspeed-g6.dtsi"
-#include <dt-bindings/gpio/aspeed-gpio.h>
-#include <dt-bindings/i2c/i2c.h>
-
-/ {
- model = "Facebook Minerva CMC";
- compatible = "facebook,minerva-cmc", "aspeed,ast2600";
-
- aliases {
- serial5 = &uart5;
- };
-
- chosen {
- stdout-path = "serial5:57600n8";
- };
-
- memory@80000000 {
- device_type = "memory";
- reg = <0x80000000 0x80000000>;
- };
-
- iio-hwmon {
- compatible = "iio-hwmon";
- io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
- <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
- <&adc1 2>;
- };
-};
-
-&uart6 {
- status = "okay";
-};
-
-&wdt1 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_wdtrst1_default>;
- aspeed,reset-type = "soc";
- aspeed,external-signal;
- aspeed,ext-push-pull;
- aspeed,ext-active-high;
- aspeed,ext-pulse-duration = <256>;
-};
-
-&mac3 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_rmii4_default>;
- use-ncsi;
- mlx,multi-host;
-};
-
-&fmc {
- status = "okay";
- flash@0 {
- status = "okay";
- m25p,fast-read;
- label = "bmc";
- spi-max-frequency = <50000000>;
-#include "openbmc-flash-layout-128.dtsi"
- };
- flash@1 {
- status = "okay";
- m25p,fast-read;
- label = "alt-bmc";
- spi-max-frequency = <50000000>;
- };
-};
-
-&rtc {
- status = "okay";
-};
-
-&sgpiom1 {
- status = "okay";
- ngpios = <128>;
- bus-frequency = <2000000>;
-};
-
-&i2c0 {
- status = "okay";
-};
-
-&i2c1 {
- status = "okay";
-
- temperature-sensor@4b {
- compatible = "ti,tmp75";
- reg = <0x4B>;
- };
-
- eeprom@51 {
- compatible = "atmel,24c128";
- reg = <0x51>;
- };
-};
-
-&i2c2 {
- status = "okay";
-
- i2c-mux@77 {
- compatible = "nxp,pca9548";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
-
- i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
-
- i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
-
- i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
-
- i2c@4 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <4>;
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
-
- i2c@5 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <5>;
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
- };
-};
-
-&i2c3 {
- status = "okay";
-};
-
-&i2c4 {
- status = "okay";
-};
-
-&i2c5 {
- status = "okay";
-};
-
-&i2c6 {
- status = "okay";
-};
-
-&i2c7 {
- status = "okay";
-};
-
-&i2c8 {
- status = "okay";
-};
-
-&i2c9 {
- status = "okay";
-};
-
-&i2c10 {
- status = "okay";
-};
-
-&i2c11 {
- status = "okay";
-};
-
-&i2c12 {
- status = "okay";
-};
-
-&i2c13 {
- status = "okay";
-};
-
-&i2c14 {
- status = "okay";
- multi-master;
-
- ipmb@10 {
- compatible = "ipmb-dev";
- reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
- i2c-protocol;
- };
-};
-
-&i2c15 {
- status = "okay";
-
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
-};
-
-&adc0 {
- aspeed,int-vref-microvolt = <2500000>;
- status = "okay";
- 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>;
-};
-
-&adc1 {
- aspeed,int-vref-microvolt = <2500000>;
- status = "okay";
- pinctrl-0 = <&pinctrl_adc10_default>;
-};
-
-&ehci1 {
- status = "okay";
-};
-
-&uhci {
- status = "okay";
-};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
new file mode 100644
index 000000000000..942e53d5c714
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
@@ -0,0 +1,543 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2023 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+ model = "Facebook Minerva CMM";
+ compatible = "facebook,minerva-cmc", "aspeed,ast2600";
+
+ aliases {
+ serial5 = &uart5;
+ /*
+ * PCA9548 (2-0077) provides 8 channels connecting to
+ * 6 pcs of FCB (Fan Controller Board).
+ */
+ i2c16 = &imux16;
+ i2c17 = &imux17;
+ i2c18 = &imux18;
+ i2c19 = &imux19;
+ i2c20 = &imux20;
+ i2c21 = &imux21;
+ };
+
+ chosen {
+ stdout-path = "serial5:57600n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-fan-fault {
+ label = "led-fan-fault";
+ gpios = <&leds_gpio 9 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+};
+
+&uart6 {
+ status = "okay";
+};
+
+&wdt1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdtrst1_default>;
+ aspeed,reset-type = "soc";
+ aspeed,external-signal;
+ aspeed,ext-push-pull;
+ aspeed,ext-active-high;
+ aspeed,ext-pulse-duration = <256>;
+};
+
+&mac3 {
+ status = "okay";
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+ };
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sgpiom0 {
+ status = "okay";
+ ngpios = <128>;
+ bus-frequency = <2000000>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ power-monitor@40 {
+ compatible = "ti,ina230";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ power-monitor@41 {
+ compatible = "ti,ina230";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+
+ power-monitor@67 {
+ compatible = "adi,ltc2945";
+ reg = <0x67>;
+ };
+
+ power-monitor@68 {
+ compatible = "adi,ltc2945";
+ reg = <0x68>;
+ };
+
+ leds_gpio: gpio@19 {
+ compatible = "nxp,pca9555";
+ reg = <0x19>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ temperature-sensor@4b {
+ compatible = "ti,tmp75";
+ reg = <0x4b>;
+ };
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp75";
+ reg = <0x48>;
+ };
+
+ eeprom@54 {
+ compatible = "atmel,24c128";
+ reg = <0x54>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ imux16: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ imux17: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ imux18: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ imux19: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ imux20: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ imux21: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ pwm@5e{
+ compatible = "max31790";
+ reg = <0x5e>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&i2c10 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+};
+
+&i2c12 {
+ status = "okay";
+};
+
+&i2c13 {
+ status = "okay";
+};
+
+&i2c14 {
+ status = "okay";
+ multi-master;
+
+ ipmb@10 {
+ compatible = "ipmb-dev";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ i2c-protocol;
+ };
+};
+
+&i2c15 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+};
+
+&adc0 {
+ aspeed,int-vref-microvolt = <2500000>;
+ status = "okay";
+ 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>;
+};
+
+&adc1 {
+ aspeed,int-vref-microvolt = <2500000>;
+ status = "okay";
+ pinctrl-0 = <&pinctrl_adc10_default>;
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&uhci {
+ status = "okay";
+};
+
+&gpio0 {
+ gpio-line-names =
+ /*A0-A7*/ "","","","","","","","",
+ /*B0-B7*/ "","","","","","","","",
+ /*C0-C7*/ "","","","","BLADE_UART_SEL2","","","",
+ /*D0-D7*/ "","","","","","","","",
+ /*E0-E7*/ "","","","","","","","",
+ /*F0-F7*/ "","","","","","","","",
+ /*G0-G7*/ "","","","","","","","",
+ /*H0-H7*/ "","","","","","","","",
+ /*I0-I7*/ "","","","","","","","",
+ /*J0-J7*/ "","","","","","","","",
+ /*K0-K7*/ "","","","","","","","",
+ /*L0-L7*/ "","","","","BLADE_UART_SEL0","","","",
+ /*M0-M7*/ "","","","","","BLADE_UART_SEL1","","",
+ /*N0-N7*/ "","","","","","","","",
+ /*O0-O7*/ "","","","","","","","",
+ /*P0-P7*/ "","","","","","","","",
+ /*Q0-Q7*/ "","","","","","","","",
+ /*R0-R7*/ "","","","","","","","",
+ /*S0-S7*/ "","","","","","","","",
+ /*T0-T7*/ "","","","","","","","",
+ /*U0-U7*/ "","","","","","","","",
+ /*V0-V7*/ "","","","","BAT_DETECT","","","",
+ /*W0-W7*/ "","","","","","","","",
+ /*X0-X7*/ "","","BLADE_UART_SEL3","","","","","",
+ /*Y0-Y7*/ "","","","","","","","",
+ /*Z0-Z7*/ "","","","","","","","";
+};
+
+&sgpiom0 {
+ gpio-line-names =
+ /*"input pin","output pin"*/
+ /*A0 - A7*/
+ "PRSNT_MTIA_BLADE0_N","PWREN_MTIA_BLADE0_EN",
+ "PRSNT_MTIA_BLADE1_N","PWREN_MTIA_BLADE1_EN",
+ "PRSNT_MTIA_BLADE2_N","PWREN_MTIA_BLADE2_EN",
+ "PRSNT_MTIA_BLADE3_N","PWREN_MTIA_BLADE3_EN",
+ "PRSNT_MTIA_BLADE4_N","PWREN_MTIA_BLADE4_EN",
+ "PRSNT_MTIA_BLADE5_N","PWREN_MTIA_BLADE5_EN",
+ "PRSNT_MTIA_BLADE6_N","PWREN_MTIA_BLADE6_EN",
+ "PRSNT_MTIA_BLADE7_N","PWREN_MTIA_BLADE7_EN",
+ /*B0 - B7*/
+ "PRSNT_MTIA_BLADE8_N","PWREN_MTIA_BLADE8_EN",
+ "PRSNT_MTIA_BLADE9_N","PWREN_MTIA_BLADE9_EN",
+ "PRSNT_MTIA_BLADE10_N","PWREN_MTIA_BLADE10_EN",
+ "PRSNT_MTIA_BLADE11_N","PWREN_MTIA_BLADE11_EN",
+ "PRSNT_MTIA_BLADE12_N","PWREN_MTIA_BLADE12_EN",
+ "PRSNT_MTIA_BLADE13_N","PWREN_MTIA_BLADE13_EN",
+ "PRSNT_MTIA_BLADE14_N","PWREN_MTIA_BLADE14_EN",
+ "PRSNT_MTIA_BLADE15_N","PWREN_MTIA_BLADE15_EN",
+ /*C0 - C7*/
+ "PRSNT_NW_BLADE0_N","PWREN_NW_BLADE0_EN",
+ "PRSNT_NW_BLADE1_N","PWREN_NW_BLADE1_EN",
+ "PRSNT_NW_BLADE2_N","PWREN_NW_BLADE2_EN",
+ "PRSNT_NW_BLADE3_N","PWREN_NW_BLADE3_EN",
+ "PRSNT_NW_BLADE4_N","PWREN_NW_BLADE4_EN",
+ "PRSNT_NW_BLADE5_N","PWREN_NW_BLADE5_EN",
+ "PRSNT_FCB_TOP_0_N","PWREN_MTIA_BLADE0_HSC_EN",
+ "PRSNT_FCB_TOP_1_N","PWREN_MTIA_BLADE1_HSC_EN",
+ /*D0 - D7*/
+ "PRSNT_FCB_MIDDLE_0_N","PWREN_MTIA_BLADE2_HSC_EN",
+ "PRSNT_FCB_MIDDLE_1_N","PWREN_MTIA_BLADE3_HSC_EN",
+ "PRSNT_FCB_BOTTOM_0_N","PWREN_MTIA_BLADE4_HSC_EN",
+ "PRSNT_FCB_BOTTOM_1_N","PWREN_MTIA_BLADE5_HSC_EN",
+ "PWRGD_MTIA_BLADE0_PWROK_L_BUF","PWREN_MTIA_BLADE6_HSC_EN",
+ "PWRGD_MTIA_BLADE1_PWROK_L_BUF","PWREN_MTIA_BLADE7_HSC_EN",
+ "PWRGD_MTIA_BLADE2_PWROK_L_BUF","PWREN_MTIA_BLADE8_HSC_EN",
+ "PWRGD_MTIA_BLADE3_PWROK_L_BUF","PWREN_MTIA_BLADE9_HSC_EN",
+ /*E0 - E7*/
+ "PWRGD_MTIA_BLADE4_PWROK_L_BUF","PWREN_MTIA_BLADE10_HSC_EN",
+ "PWRGD_MTIA_BLADE5_PWROK_L_BUF","PWREN_MTIA_BLADE11_HSC_EN",
+ "PWRGD_MTIA_BLADE6_PWROK_L_BUF","PWREN_MTIA_BLADE12_HSC_EN",
+ "PWRGD_MTIA_BLADE7_PWROK_L_BUF","PWREN_MTIA_BLADE13_HSC_EN",
+ "PWRGD_MTIA_BLADE8_PWROK_L_BUF","PWREN_MTIA_BLADE14_HSC_EN",
+ "PWRGD_MTIA_BLADE9_PWROK_L_BUF","PWREN_MTIA_BLADE15_HSC_EN",
+ "PWRGD_MTIA_BLADE10_PWROK_L_BUF","PWREN_NW_BLADE0_HSC_EN",
+ "PWRGD_MTIA_BLADE11_PWROK_L_BUF","PWREN_NW_BLADE1_HSC_EN",
+ /*F0 - F7*/
+ "PWRGD_MTIA_BLADE12_PWROK_L_BUF","PWREN_NW_BLADE2_HSC_EN",
+ "PWRGD_MTIA_BLADE13_PWROK_L_BUF","PWREN_NW_BLADE3_HSC_EN",
+ "PWRGD_MTIA_BLADE14_PWROK_L_BUF","PWREN_NW_BLADE4_HSC_EN",
+ "PWRGD_MTIA_BLADE15_PWROK_L_BUF","PWREN_NW_BLADE5_HSC_EN",
+ "PWRGD_NW_BLADE0_PWROK_L_BUF","PWREN_FCB_TOP_L_EN",
+ "PWRGD_NW_BLADE1_PWROK_L_BUF","PWREN_FCB_TOP_R_EN",
+ "PWRGD_NW_BLADE2_PWROK_L_BUF","PWREN_FCB_MIDDLE_L_EN",
+ "PWRGD_NW_BLADE3_PWROK_L_BUF","PWREN_FCB_MIDDLE_R_EN",
+ /*G0 - G7*/
+ "PWRGD_NW_BLADE4_PWROK_L_BUF","PWREN_FCB_BOTTOM_L_EN",
+ "PWRGD_NW_BLADE5_PWROK_L_BUF","PWREN_FCB_BOTTOM_R_EN",
+ "PWRGD_FCB_TOP_0_PWROK_L_BUF","FM_CMM_AC_CYCLE_N",
+ "PWRGD_FCB_TOP_1_PWROK_L_BUF","MGMT_SFP_TX_DIS",
+ "PWRGD_FCB_MIDDLE_0_PWROK_L_BUF","",
+ "PWRGD_FCB_MIDDLE_1_PWROK_L_BUF","RST_I2CRST_MTIA_BLADE0_1_N",
+ "PWRGD_FCB_BOTTOM_0_PWROK_L_BUF","RST_I2CRST_MTIA_BLADE2_3_N",
+ "PWRGD_FCB_BOTTOM_1_PWROK_L_BUF","RST_I2CRST_MTIA_BLADE4_5_N",
+ /*H0 - H7*/
+ "LEAK_DETECT_MTIA_BLADE0_N_BUF","RST_I2CRST_MTIA_BLADE6_7_N",
+ "LEAK_DETECT_MTIA_BLADE1_N_BUF","RST_I2CRST_MTIA_BLADE8_9_N",
+ "LEAK_DETECT_MTIA_BLADE2_N_BUF","RST_I2CRST_MTIA_BLADE10_11_N",
+ "LEAK_DETECT_MTIA_BLADE3_N_BUF","RST_I2CRST_MTIA_BLADE12_13_N",
+ "LEAK_DETECT_MTIA_BLADE4_N_BUF","RST_I2CRST_MTIA_BLADE14_15_N",
+ "LEAK_DETECT_MTIA_BLADE5_N_BUF","RST_I2CRST_NW_BLADE0_1_2_N",
+ "LEAK_DETECT_MTIA_BLADE6_N_BUF","RST_I2CRST_NW_BLADE3_4_5_N",
+ "LEAK_DETECT_MTIA_BLADE7_N_BUF","RST_I2CRST_FCB_N",
+ /*I0 - I7*/
+ "LEAK_DETECT_MTIA_BLADE8_N_BUF","RST_I2CRST_FCB_B_L_N",
+ "LEAK_DETECT_MTIA_BLADE9_N_BUF","RST_I2CRST_FCB_B_R_N",
+ "LEAK_DETECT_MTIA_BLADE10_N_BUF","RST_I2CRST_FCB_M_L_N",
+ "LEAK_DETECT_MTIA_BLADE11_N_BUF","RST_I2CRST_FCB_M_R_N",
+ "LEAK_DETECT_MTIA_BLADE12_N_BUF","RST_I2CRST_FCB_T_L_N",
+ "LEAK_DETECT_MTIA_BLADE13_N_BUF","RST_I2CRST_FCB_T_R_N",
+ "LEAK_DETECT_MTIA_BLADE14_N_BUF","BMC_READY",
+ "LEAK_DETECT_MTIA_BLADE15_N_BUF","wFM_88E6393X_BIN_UPDATE_EN_N",
+ /*J0 - J7*/
+ "LEAK_DETECT_NW_BLADE0_N_BUF","WATER_VALVE_CLOSED_N",
+ "LEAK_DETECT_NW_BLADE1_N_BUF","",
+ "LEAK_DETECT_NW_BLADE2_N_BUF","",
+ "LEAK_DETECT_NW_BLADE3_N_BUF","",
+ "LEAK_DETECT_NW_BLADE4_N_BUF","",
+ "LEAK_DETECT_NW_BLADE5_N_BUF","",
+ "MTIA_BLADE0_STATUS_LED","",
+ "MTIA_BLADE1_STATUS_LED","",
+ /*K0 - K7*/
+ "MTIA_BLADE2_STATUS_LED","",
+ "MTIA_BLADE3_STATUS_LED","",
+ "MTIA_BLADE4_STATUS_LED","",
+ "MTIA_BLADE5_STATUS_LED","",
+ "MTIA_BLADE6_STATUS_LED","",
+ "MTIA_BLADE7_STATUS_LED","",
+ "MTIA_BLADE8_STATUS_LED","",
+ "MTIA_BLADE9_STATUS_LED","",
+ /*L0 - L7*/
+ "MTIA_BLADE10_STATUS_LED","",
+ "MTIA_BLADE11_STATUS_LED","",
+ "MTIA_BLADE12_STATUS_LED","",
+ "MTIA_BLADE13_STATUS_LED","",
+ "MTIA_BLADE14_STATUS_LED","",
+ "MTIA_BLADE15_STATUS_LED","",
+ "NW_BLADE0_STATUS_LED","",
+ "NW_BLADE1_STATUS_LED","",
+ /*M0 - M7*/
+ "NW_BLADE2_STATUS_LED","",
+ "NW_BLADE3_STATUS_LED","",
+ "NW_BLADE4_STATUS_LED","",
+ "NW_BLADE5_STATUS_LED","",
+ "RPU_READY","",
+ "IT_GEAR_RPU_LINK_N","",
+ "IT_GEAR_LEAK","",
+ "WATER_VALVE_CLOSED_N","",
+ /*N0 - N7*/
+ "VALVE_STS0","",
+ "VALVE_STS1","",
+ "VALVE_STS2","",
+ "VALVE_STS3","",
+ "CR_TOGGLE_BOOT_BUF_N","",
+ "CMM_LC_RDY_LED_N","",
+ "CMM_LC_UNRDY_LED_N","",
+ "CMM_CABLE_CARTRIDGE_PRSNT_BOT_N","",
+ /*O0 - O7*/
+ "CMM_CABLE_CARTRIDGE_PRSNT_TOP_N","",
+ "BOT_BCB_CABLE_PRSNT_N","",
+ "TOP_BCB_CABLE_PRSNT_N","",
+ "CHASSIS0_LEAK_Q_N","",
+ "CHASSIS1_LEAK_Q_N","",
+ "LEAK0_DETECT","",
+ "LEAK1_DETECT","",
+ "MGMT_SFP_PRSNT_N","",
+ /*P0 - P7*/
+ "MGMT_SFP_TX_FAULT","",
+ "MGMT_SFP_RX_LOS","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","";
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
index 64075cc41d92..98477792aa00 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
@@ -88,7 +88,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rmii3_default>;
use-ncsi;
- mlx,multi-host;
+ mellanox,multi-host;
};
&mac3 {
@@ -96,7 +96,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rmii4_default>;
use-ncsi;
- mlx,multi-host;
+ mellanox,multi-host;
};
&fmc {
@@ -369,7 +369,14 @@
&i2c13 {
status = "okay";
- bus-frequency = <400000>;
+ bus-frequency = <100000>;
+ multi-master;
+
+ ipmb@10 {
+ compatible = "ipmb-dev";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ i2c-protocol;
+ };
};
&i2c14 {
@@ -596,7 +603,6 @@
};
&adc0 {
- ref_voltage = <2500>;
status = "okay";
pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
&pinctrl_adc2_default &pinctrl_adc3_default
@@ -605,7 +611,6 @@
};
&adc1 {
- ref_voltage = <2500>;
status = "okay";
pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default>;
};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemitev2.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemitev2.dts
index 6bf2ff85a40e..5143f85fbd70 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemitev2.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemitev2.dts
@@ -95,7 +95,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rmii1_default>;
use-ncsi;
- mlx,multi-host;
+ mellanox,multi-host;
};
&adc {
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts
index cad1b9aac97b..6fdda42575df 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts
@@ -488,7 +488,7 @@
#gpio-cells = <2>;
led@0 {
- label = "nvme0";
+ label = "nvme3";
reg = <0>;
retain-state-shutdown;
default-state = "keep";
@@ -496,7 +496,7 @@
};
led@1 {
- label = "nvme1";
+ label = "nvme2";
reg = <1>;
retain-state-shutdown;
default-state = "keep";
@@ -504,7 +504,7 @@
};
led@2 {
- label = "nvme2";
+ label = "nvme1";
reg = <2>;
retain-state-shutdown;
default-state = "keep";
@@ -512,7 +512,7 @@
};
led@3 {
- label = "nvme3";
+ label = "nvme0";
reg = <3>;
retain-state-shutdown;
default-state = "keep";
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
new file mode 100644
index 000000000000..dcbc16308ab5
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -0,0 +1,1623 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2023 IBM Corp.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/leds/leds-pca955x.h>
+
+/ {
+ model = "System1";
+ compatible = "ibm,system1-bmc", "aspeed,ast2600";
+
+ aliases {
+ i2c16 = &i2c8mux1chn0;
+ i2c17 = &i2c8mux1chn1;
+ i2c18 = &i2c8mux1chn2;
+ i2c19 = &i2c8mux1chn3;
+ i2c20 = &i2c8mux1chn4;
+ i2c21 = &i2c8mux1chn5;
+ i2c22 = &i2c8mux1chn6;
+ i2c23 = &i2c8mux1chn7;
+ i2c24 = &i2c3mux0chn0;
+ i2c25 = &i2c3mux0chn1;
+ i2c26 = &i2c3mux0chn2;
+ i2c27 = &i2c3mux0chn3;
+ i2c28 = &i2c3mux0chn4;
+ i2c29 = &i2c3mux0chn5;
+ i2c30 = &i2c3mux0chn6;
+ i2c31 = &i2c3mux0chn7;
+ i2c32 = &i2c6mux0chn0;
+ i2c33 = &i2c6mux0chn1;
+ i2c34 = &i2c6mux0chn2;
+ i2c35 = &i2c6mux0chn3;
+ i2c36 = &i2c6mux0chn4;
+ i2c37 = &i2c6mux0chn5;
+ i2c38 = &i2c6mux0chn6;
+ i2c39 = &i2c6mux0chn7;
+ i2c40 = &i2c7mux0chn0;
+ i2c41 = &i2c7mux0chn1;
+ i2c42 = &i2c7mux0chn2;
+ i2c43 = &i2c7mux0chn3;
+ i2c44 = &i2c7mux0chn4;
+ i2c45 = &i2c7mux0chn5;
+ i2c46 = &i2c7mux0chn6;
+ i2c47 = &i2c7mux0chn7;
+ i2c48 = &i2c8mux0chn0;
+ i2c49 = &i2c8mux0chn1;
+ i2c50 = &i2c8mux0chn2;
+ i2c51 = &i2c8mux0chn3;
+ i2c52 = &i2c8mux0chn4;
+ i2c53 = &i2c8mux0chn5;
+ i2c54 = &i2c8mux0chn6;
+ i2c55 = &i2c8mux0chn7;
+ i2c56 = &i2c14mux0chn0;
+ i2c57 = &i2c14mux0chn1;
+ i2c58 = &i2c14mux0chn2;
+ i2c59 = &i2c14mux0chn3;
+ i2c60 = &i2c14mux0chn4;
+ i2c61 = &i2c14mux0chn5;
+ i2c62 = &i2c14mux0chn6;
+ i2c63 = &i2c14mux0chn7;
+ i2c64 = &i2c15mux0chn0;
+ i2c65 = &i2c15mux0chn1;
+ i2c66 = &i2c15mux0chn2;
+ i2c67 = &i2c15mux0chn3;
+ i2c68 = &i2c15mux0chn4;
+ i2c69 = &i2c15mux0chn5;
+ i2c70 = &i2c15mux0chn6;
+ i2c71 = &i2c15mux0chn7;
+ };
+
+ chosen {
+ stdout-path = "uart5:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ eventlog: tcg-event-log@b3d00000 {
+ no-map;
+ reg = <0xb3d00000 0x100000>;
+ };
+
+ ramoops@b3e00000 {
+ compatible = "ramoops";
+ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */
+ record-size = <0x8000>;
+ console-size = <0x8000>;
+ ftrace-size = <0x8000>;
+ pmsg-size = <0x8000>;
+ max-reason = <3>; /* KMSG_DUMP_EMERG */
+ };
+
+ /* LPC FW cycle bridge region requires natural alignment */
+ flash_memory: region@b4000000 {
+ no-map;
+ reg = <0xb4000000 0x04000000>; /* 64M */
+ };
+
+ /* VGA region is dictated by hardware strapping */
+ vga_memory: region@bf000000 {
+ no-map;
+ compatible = "shared-dma-pool";
+ reg = <0xbf000000 0x01000000>; /* 16M */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ gpios = <&gpio0 ASPEED_GPIO(L, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ led-1 {
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ led-2 {
+ gpios = <&gpio0 ASPEED_GPIO(S, 6) GPIO_ACTIVE_HIGH>;
+ };
+
+ led-3 {
+ gpios = <&gpio0 ASPEED_GPIO(S, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ led-4 {
+ gpios = <&pca3 5 GPIO_ACTIVE_LOW>;
+ };
+
+ led-5 {
+ gpios = <&pca3 6 GPIO_ACTIVE_LOW>;
+ };
+
+ led-6 {
+ gpios = <&pca3 7 GPIO_ACTIVE_LOW>;
+ };
+
+ led-7 {
+ gpios = <&pca3 8 GPIO_ACTIVE_LOW>;
+ };
+
+ led-8 {
+ gpios = <&pca3 9 GPIO_ACTIVE_LOW>;
+ };
+
+ led-9 {
+ gpios = <&pca3 10 GPIO_ACTIVE_LOW>;
+ };
+
+ led-a {
+ gpios = <&pca3 11 GPIO_ACTIVE_LOW>;
+ };
+
+ led-b {
+ gpios = <&pca4 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-c {
+ gpios = <&pca4 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-d {
+ gpios = <&pca4 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-e {
+ gpios = <&pca4 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ poll-interval = <1000>;
+
+ event-nvme0-presence {
+ label = "nvme0-presence";
+ gpios = <&pca4 0 GPIO_ACTIVE_LOW>;
+ linux,code = <0>;
+ };
+
+ event-nvme1-presence {
+ label = "nvme1-presence";
+ gpios = <&pca4 1 GPIO_ACTIVE_LOW>;
+ linux,code = <1>;
+ };
+
+ event-nvme2-presence {
+ label = "nvme2-presence";
+ gpios = <&pca4 2 GPIO_ACTIVE_LOW>;
+ linux,code = <2>;
+ };
+
+ event-nvme3-presence {
+ label = "nvme3-presence";
+ gpios = <&pca4 3 GPIO_ACTIVE_LOW>;
+ linux,code = <3>;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&p12v_vd 0>, <&p5v_aux_vd 0>,
+ <&p5v_bmc_aux_vd 0>, <&p3v3_aux_vd 0>,
+ <&p3v3_bmc_aux_vd 0>, <&p1v8_bmc_aux_vd 0>,
+ <&adc1 4>, <&adc0 2>, <&adc1 0>,
+ <&p2v5_aux_vd 0>, <&adc1 7>;
+ };
+
+ p12v_vd: voltage-divider1 {
+ compatible = "voltage-divider";
+ io-channels = <&adc1 3>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 1127/127 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <15>;
+ full-ohms = <133>;
+ };
+
+ p5v_aux_vd: voltage-divider2 {
+ compatible = "voltage-divider";
+ io-channels = <&adc1 5>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 1365/365 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <50>;
+ full-ohms = <187>;
+ };
+
+ p5v_bmc_aux_vd: voltage-divider3 {
+ compatible = "voltage-divider";
+ io-channels = <&adc0 3>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 1365/365 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <50>;
+ full-ohms = <187>;
+ };
+
+ p3v3_aux_vd: voltage-divider4 {
+ compatible = "voltage-divider";
+ io-channels = <&adc1 2>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 1698/698 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <14>;
+ full-ohms = <34>;
+ };
+
+ p3v3_bmc_aux_vd: voltage-divider5 {
+ compatible = "voltage-divider";
+ io-channels = <&adc0 7>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 1698/698 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <14>;
+ full-ohms = <34>;
+ };
+
+ p1v8_bmc_aux_vd: voltage-divider6 {
+ compatible = "voltage-divider";
+ io-channels = <&adc0 6>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 4000/3000 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <3>;
+ full-ohms = <4>;
+ };
+
+ p2v5_aux_vd: voltage-divider7 {
+ compatible = "voltage-divider";
+ io-channels = <&adc1 1>;
+ #io-channel-cells = <1>;
+
+ /*
+ * Scale the system voltage by 2100/1100 to fit the ADC range.
+ * Use small nominator to prevent integer overflow.
+ */
+ output-ohms = <11>;
+ full-ohms = <21>;
+ };
+
+ p1v8_bmc_aux: fixedregulator-p1v8-bmc-aux {
+ compatible = "regulator-fixed";
+ regulator-name = "p1v8_bmc_aux";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+};
+
+&adc0 {
+ status = "okay";
+ vref-supply = <&p1v8_bmc_aux>;
+
+ 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>;
+};
+
+&adc1 {
+ status = "okay";
+ vref-supply = <&p1v8_bmc_aux>;
+ aspeed,battery-sensing;
+
+ aspeed,int-vref-microvolt = <2500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc8_default
+ &pinctrl_adc9_default
+ &pinctrl_adc10_default
+ &pinctrl_adc11_default
+ &pinctrl_adc12_default
+ &pinctrl_adc13_default
+ &pinctrl_adc14_default
+ &pinctrl_adc15_default>;
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&uhci {
+ status = "okay";
+};
+
+&gpio0 {
+ gpio-line-names =
+ /*A0-A7*/ "","","","","","","","",
+ /*B0-B7*/ "","","","","bmc-tpm-reset","","","",
+ /*C0-C7*/ "","","","","","","","",
+ /*D0-D7*/ "","","","","","","","",
+ /*E0-E7*/ "","","","","","","","",
+ /*F0-F7*/ "","","","","","","","",
+ /*G0-G7*/ "","","","","","","","",
+ /*H0-H7*/ "","","","","","","","",
+ /*I0-I7*/ "","","","","","","","",
+ /*J0-J7*/ "","","","","","","","",
+ /*K0-K7*/ "","","","","","","","",
+ /*L0-L7*/ "","","","","","","","bmc-ready",
+ /*M0-M7*/ "","","","","","","","",
+ /*N0-N7*/ "","","","","","","","",
+ /*O0-O7*/ "","","","","","","","",
+ /*P0-P7*/ "","","","","","","","bmc-hb",
+ /*Q0-Q7*/ "","","","","","","","",
+ /*R0-R7*/ "","","","","","","","",
+ /*S0-S7*/ "","","","","","","rear-enc-fault0","rear-enc-id0",
+ /*T0-T7*/ "","","","","","","","",
+ /*U0-U7*/ "","","","","","","","",
+ /*V0-V7*/ "","rtc-battery-voltage-read-enable","","power-chassis-control","","","","",
+ /*W0-W7*/ "","","","","","","","",
+ /*X0-X7*/ "","power-chassis-good","","","","","","",
+ /*Y0-Y7*/ "","","","","","","","",
+ /*Z0-Z7*/ "","","","","","","","";
+};
+
+&emmc_controller {
+ status = "okay";
+};
+
+&pinctrl_emmc_default {
+ bias-disable;
+};
+
+&emmc {
+ status = "okay";
+ clk-phase-mmc-hs200 = <180>, <180>;
+};
+
+&ibt {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&vuart1 {
+ status = "okay";
+};
+
+&vuart2 {
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+ memory-region = <&flash_memory>;
+};
+
+&mac2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii3_default>;
+ clocks = <&syscon ASPEED_CLK_GATE_MAC3CLK>,
+ <&syscon ASPEED_CLK_MAC3RCLK>;
+ clock-names = "MACCLK", "RCLK";
+ use-ncsi;
+};
+
+&mac3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+ clocks = <&syscon ASPEED_CLK_GATE_MAC4CLK>,
+ <&syscon ASPEED_CLK_MAC4RCLK>;
+ clock-names = "MACCLK", "RCLK";
+ use-ncsi;
+};
+
+&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 {
+ status = "okay";
+};
+
+&kcs2 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca8 0xcac>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca2>;
+ aspeed,lpc-interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ };
+
+ regulator@60 {
+ compatible = "maxim,max8952";
+ reg = <0x60>;
+
+ max8952,default-mode = <0>;
+ max8952,dvs-mode-microvolt = <1250000>, <1200000>,
+ <1050000>, <950000>;
+ max8952,sync-freq = <0>;
+ max8952,ramp-speed = <0>;
+
+ regulator-name = "VR_v77_1v4";
+ regulator-min-microvolt = <770000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ regulator@42 {
+ compatible = "infineon,ir38263";
+ reg = <0x42>;
+ };
+
+ led-controller@60 {
+ compatible = "nxp,pca9552";
+ reg = <0x60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ led@0 {
+ label = "nic1-perst";
+ reg = <0>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@1 {
+ label = "bmc-perst";
+ reg = <1>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@2 {
+ label = "reset-M2-SSD1-2-perst";
+ reg = <2>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@3 {
+ label = "pcie-perst1";
+ reg = <3>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@4 {
+ label = "pcie-perst2";
+ reg = <4>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@5 {
+ label = "pcie-perst3";
+ reg = <5>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@6 {
+ label = "pcie-perst4";
+ reg = <6>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@7 {
+ label = "pcie-perst5";
+ reg = <7>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@8 {
+ label = "pcie-perst6";
+ reg = <8>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@9 {
+ label = "pcie-perst7";
+ reg = <9>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@10 {
+ label = "pcie-perst8";
+ reg = <10>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@11 {
+ label = "PV-cp0-sw1stk4-perst";
+ reg = <11>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@12 {
+ label = "PV-cp0-sw1stk5-perst";
+ reg = <12>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@13 {
+ label = "pe-cp-drv0-perst";
+ reg = <13>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@14 {
+ label = "pe-cp-drv1-perst";
+ reg = <14>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@15 {
+ label = "lom-perst";
+ reg = <15>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+ };
+
+ gpio@74 {
+ compatible = "nxp,pca9539";
+ reg = <0x74>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "PLUG_DETECT_PCIE_J101_N",
+ "PLUG_DETECT_PCIE_J102_N",
+ "PLUG_DETECT_PCIE_J103_N",
+ "PLUG_DETECT_PCIE_J104_N",
+ "PLUG_DETECT_PCIE_J105_N",
+ "PLUG_DETECT_PCIE_J106_N",
+ "PLUG_DETECT_PCIE_J107_N",
+ "PLUG_DETECT_PCIE_J108_N",
+ "PLUG_DETECT_M2_SSD1_N",
+ "PLUG_DETECT_NIC1_N",
+ "SEL_SMB_DIMM_CPU0",
+ "presence-ps2",
+ "presence-ps3",
+ "", "",
+ "PWRBRD_PLUG_DETECT2_N";
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ power-supply@58 {
+ compatible = "ibm,cffps";
+ reg = <0x58>;
+ };
+
+ power-supply@59 {
+ compatible = "ibm,cffps";
+ reg = <0x59>;
+ };
+
+ power-supply@5a {
+ compatible = "ibm,cffps";
+ reg = <0x5a>;
+ };
+
+ power-supply@5b {
+ compatible = "ibm,cffps";
+ reg = <0x5b>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c3mux0chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c3mux0chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c3mux0chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c3mux0chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ i2c3mux0chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ i2c3mux0chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ i2c3mux0chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ i2c3mux0chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+
+ regulator@42 {
+ compatible = "infineon,ir38263";
+ reg = <0x42>;
+ };
+
+ regulator@43 {
+ compatible = "infineon,ir38060";
+ reg = <0x43>;
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ fan-controller@52 {
+ compatible = "maxim,max31785a";
+ reg = <0x52>;
+ };
+
+ fan-controller@54 {
+ compatible = "maxim,max31785a";
+ reg = <0x54>;
+ };
+
+ eeprom@55 {
+ compatible = "atmel,24c64";
+ reg = <0x55>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c6mux0chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c6mux0chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c6mux0chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c6mux0chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ i2c6mux0chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ humidity-sensor@40 {
+ compatible = "ti,hdc1080";
+ reg = <0x40>;
+ };
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp275";
+ reg = <0x48>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c32";
+ reg = <0x50>;
+ };
+
+ led-controller@60 {
+ compatible = "nxp,pca9551";
+ reg = <0x60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ led@0 {
+ label = "enclosure-id-led";
+ reg = <0>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@1 {
+ label = "attention-led";
+ reg = <1>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@2 {
+ label = "enclosure-fault-rollup-led";
+ reg = <2>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@3 {
+ label = "power-on-led";
+ reg = <3>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+ };
+
+ temperature-sensor@76 {
+ compatible = "infineon,dps310";
+ reg = <0x76>;
+ };
+ };
+
+ i2c6mux0chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ i2c6mux0chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ i2c6mux0chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+
+ pca3: gpio@74 {
+ compatible = "nxp,pca9539";
+ reg = <0x74>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca4: gpio@77 {
+ compatible = "nxp,pca9539";
+ reg = <0x77>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "PE_NVMED0_EXP_PRSNT_N",
+ "PE_NVMED1_EXP_PRSNT_N",
+ "PE_NVMED2_EXP_PRSNT_N",
+ "PE_NVMED3_EXP_PRSNT_N",
+ "LED_FAULT_NVMED0",
+ "LED_FAULT_NVMED1",
+ "LED_FAULT_NVMED2",
+ "LED_FAULT_NVMED3",
+ "FAN0_PRESENCE_R_N",
+ "FAN1_PRESENCE_R_N",
+ "FAN2_PRESENCE_R_N",
+ "FAN3_PRESENCE_R_N",
+ "FAN4_PRESENCE_R_N",
+ "FAN5_PRESENCE_N",
+ "FAN6_PRESENCE_N",
+ "";
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c7mux0chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c7mux0chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c7mux0chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c7mux0chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ regulator@58 {
+ compatible = "mps,mp2973";
+ reg = <0x58>;
+ };
+ };
+
+ i2c7mux0chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ i2c7mux0chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ regulator@40 {
+ compatible = "infineon,tda38640";
+ reg = <0x40>;
+ };
+ };
+
+ i2c7mux0chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ i2c7mux0chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c8 {
+ status = "okay";
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c8mux0chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ regulator@58 {
+ compatible = "mps,mp2971";
+ reg = <0x58>;
+ };
+ };
+
+ i2c8mux0chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ regulator@40 {
+ compatible = "infineon,tda38640";
+ reg = <0x40>;
+ };
+
+ regulator@41 {
+ compatible = "infineon,tda38640";
+ reg = <0x41>;
+ };
+
+ regulator@58 {
+ compatible = "mps,mp2971";
+ reg = <0x58>;
+ };
+
+ regulator@5b {
+ compatible = "mps,mp2971";
+ reg = <0x5b>;
+ };
+ };
+
+ i2c8mux0chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c8mux0chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ i2c8mux0chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c8mux1chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c8mux1chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c8mux1chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c8mux1chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ i2c8mux1chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ i2c8mux1chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ i2c8mux1chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ i2c8mux1chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+ };
+
+ i2c8mux0chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ i2c8mux0chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ temperature-sensor@4c {
+ compatible = "ti,tmp423";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c8mux0chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ regulator@40 {
+ compatible = "infineon,ir38060";
+ reg = <0x40>;
+ };
+ };
+ };
+};
+
+&i2c9 {
+ status = "okay";
+
+ regulator@40 {
+ compatible = "infineon,ir38263";
+ reg = <0x40>;
+ };
+
+ regulator@41 {
+ compatible = "infineon,ir38263";
+ reg = <0x41>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ };
+
+ regulator@60 {
+ compatible = "maxim,max8952";
+ reg = <0x60>;
+
+ max8952,default-mode = <0>;
+ max8952,dvs-mode-microvolt = <1250000>, <1200000>,
+ <1050000>, <950000>;
+ max8952,sync-freq = <0>;
+ max8952,ramp-speed = <0>;
+
+ regulator-name = "VR_v77_1v4";
+ regulator-min-microvolt = <770000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&i2c11 {
+ status = "okay";
+
+ tpm@2e {
+ compatible = "tcg,tpm-tis-i2c";
+ reg = <0x2e>;
+ memory-region = <&eventlog>;
+ };
+};
+
+&i2c12 {
+ status = "okay";
+};
+
+&i2c13 {
+ status = "okay";
+
+ regulator@41 {
+ compatible = "infineon,ir38263";
+ reg = <0x41>;
+ };
+
+ led-controller@61 {
+ compatible = "nxp,pca9552";
+ reg = <0x61>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ led@0 {
+ label = "efuse-12v-slots";
+ reg = <0>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@1 {
+ label = "efuse-3p3v-slot";
+ reg = <1>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@3 {
+ label = "nic2-pert";
+ reg = <3>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@4 {
+ label = "pcie-perst9";
+ reg = <4>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@5 {
+ label = "pcie-perst10";
+ reg = <5>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@6 {
+ label = "pcie-perst11";
+ reg = <6>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@7 {
+ label = "pcie-perst12";
+ reg = <7>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@8 {
+ label = "pcie-perst13";
+ reg = <8>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@9 {
+ label = "pcie-perst14";
+ reg = <9>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@10 {
+ label = "pcie-perst15";
+ reg = <10>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@11 {
+ label = "pcie-perst16";
+ reg = <11>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@12 {
+ label = "PV-cp1-sw1stk4-perst";
+ reg = <12>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@13 {
+ label = "PV-cp1-sw1stk5-perst";
+ reg = <13>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@14 {
+ label = "pe-cp-drv2-perst";
+ reg = <14>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+
+ led@15 {
+ label = "pe-cp-drv3-perst";
+ reg = <15>;
+ retain-state-shutdown;
+ default-state = "keep";
+ type = <PCA955X_TYPE_LED>;
+ };
+ };
+
+ gpio@75 {
+ compatible = "nxp,pca9539";
+ reg = <0x75>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "PLUG_DETECT_PCIE_J109_N",
+ "PLUG_DETECT_PCIE_J110_N",
+ "PLUG_DETECT_PCIE_J111_N",
+ "PLUG_DETECT_PCIE_J112_N",
+ "PLUG_DETECT_PCIE_J113_N",
+ "PLUG_DETECT_PCIE_J114_N",
+ "PLUG_DETECT_PCIE_J115_N",
+ "PLUG_DETECT_PCIE_J116_N",
+ "PLUG_DETECT_M2_SSD2_N",
+ "PLUG_DETECT_NIC2_N",
+ "SEL_SMB_DIMM_CPU1",
+ "presence-ps0",
+ "presence-ps1",
+ "", "",
+ "PWRBRD_PLUG_DETECT1_N";
+ };
+
+ gpio@76 {
+ compatible = "nxp,pca9539";
+ reg = <0x76>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "SW1_BOOTRCVRYB1_N",
+ "SW1_BOOTRCVRYB0_N",
+ "SW2_BOOTRCVRYB1_N",
+ "SW2_BOOTRCVRYB0_N",
+ "SW3_4_BOOTRCVRYB1_N",
+ "SW3_4_BOOTRCVRYB0_N",
+ "SW5_BOOTRCVRYB1_N",
+ "SW5_BOOTRCVRYB0_N",
+ "SW6_BOOTRCVRYB1_N",
+ "SW6_BOOTRCVRYB0_N",
+ "SW1_RESET_N",
+ "SW3_RESET_N",
+ "SW4_RESET_N",
+ "SW2_RESET_N",
+ "SW5_RESET_N",
+ "SW6_RESET_N";
+ };
+};
+
+&i2c14 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c14mux0chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c14mux0chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c14mux0chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c14mux0chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ regulator@58 {
+ compatible = "mps,mp2973";
+ reg = <0x58>;
+ };
+ };
+
+ i2c14mux0chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ i2c14mux0chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ regulator@40 {
+ compatible = "infineon,tda38640";
+ reg = <0x40>;
+ };
+ };
+
+ i2c14mux0chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ i2c14mux0chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c15 {
+ status = "okay";
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c15mux0chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ regulator@58 {
+ compatible = "mps,mp2971";
+ reg = <0x58>;
+ };
+ };
+
+ i2c15mux0chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ regulator@40 {
+ compatible = "infineon,tda38640";
+ reg = <0x40>;
+ };
+
+ regulator@41 {
+ compatible = "infineon,tda38640";
+ reg = <0x41>;
+ };
+
+ regulator@58 {
+ compatible = "mps,mp2971";
+ reg = <0x58>;
+ };
+
+ regulator@5b {
+ compatible = "mps,mp2971";
+ reg = <0x5b>;
+ };
+ };
+
+ i2c15mux0chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c15mux0chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ i2c15mux0chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c15mux1chn0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c15mux1chn1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c15mux1chn2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c15mux1chn3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ i2c15mux1chn4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ i2c15mux1chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ i2c15mux1chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ i2c15mux1chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+ };
+
+ i2c15mux0chn5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ i2c15mux0chn6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ temperature-sensor@4c {
+ compatible = "ti,tmp423";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c15mux0chn7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ regulator@40 {
+ compatible = "infineon,ir38060";
+ reg = <0x40>;
+ };
+
+ temperature-sensor@4c {
+ compatible = "ti,tmp423";
+ reg = <0x4c>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g4.dtsi
index 857cb26ed6d7..c669ec202085 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g4.dtsi
@@ -463,7 +463,7 @@
interrupt-controller;
};
- i2c0: i2c-bus@40 {
+ i2c0: i2c@40 {
#address-cells = <1>;
#size-cells = <0>;
@@ -478,7 +478,7 @@
/* Does not need pinctrl properties */
};
- i2c1: i2c-bus@80 {
+ i2c1: i2c@80 {
#address-cells = <1>;
#size-cells = <0>;
@@ -493,7 +493,7 @@
/* Does not need pinctrl properties */
};
- i2c2: i2c-bus@c0 {
+ i2c2: i2c@c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -509,7 +509,7 @@
status = "disabled";
};
- i2c3: i2c-bus@100 {
+ i2c3: i2c@100 {
#address-cells = <1>;
#size-cells = <0>;
@@ -525,7 +525,7 @@
status = "disabled";
};
- i2c4: i2c-bus@140 {
+ i2c4: i2c@140 {
#address-cells = <1>;
#size-cells = <0>;
@@ -541,7 +541,7 @@
status = "disabled";
};
- i2c5: i2c-bus@180 {
+ i2c5: i2c@180 {
#address-cells = <1>;
#size-cells = <0>;
@@ -557,7 +557,7 @@
status = "disabled";
};
- i2c6: i2c-bus@1c0 {
+ i2c6: i2c@1c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -573,7 +573,7 @@
status = "disabled";
};
- i2c7: i2c-bus@300 {
+ i2c7: i2c@300 {
#address-cells = <1>;
#size-cells = <0>;
@@ -589,7 +589,7 @@
status = "disabled";
};
- i2c8: i2c-bus@340 {
+ i2c8: i2c@340 {
#address-cells = <1>;
#size-cells = <0>;
@@ -605,7 +605,7 @@
status = "disabled";
};
- i2c9: i2c-bus@380 {
+ i2c9: i2c@380 {
#address-cells = <1>;
#size-cells = <0>;
@@ -621,7 +621,7 @@
status = "disabled";
};
- i2c10: i2c-bus@3c0 {
+ i2c10: i2c@3c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -637,7 +637,7 @@
status = "disabled";
};
- i2c11: i2c-bus@400 {
+ i2c11: i2c@400 {
#address-cells = <1>;
#size-cells = <0>;
@@ -653,7 +653,7 @@
status = "disabled";
};
- i2c12: i2c-bus@440 {
+ i2c12: i2c@440 {
#address-cells = <1>;
#size-cells = <0>;
@@ -669,7 +669,7 @@
status = "disabled";
};
- i2c13: i2c-bus@480 {
+ i2c13: i2c@480 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/aspeed/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g5.dtsi
index e6f3cf3c721e..6e05cbcce49c 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g5.dtsi
@@ -592,7 +592,7 @@
interrupt-controller;
};
- i2c0: i2c-bus@40 {
+ i2c0: i2c@40 {
#address-cells = <1>;
#size-cells = <0>;
@@ -607,7 +607,7 @@
/* Does not need pinctrl properties */
};
- i2c1: i2c-bus@80 {
+ i2c1: i2c@80 {
#address-cells = <1>;
#size-cells = <0>;
@@ -622,7 +622,7 @@
/* Does not need pinctrl properties */
};
- i2c2: i2c-bus@c0 {
+ i2c2: i2c@c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -638,7 +638,7 @@
status = "disabled";
};
- i2c3: i2c-bus@100 {
+ i2c3: i2c@100 {
#address-cells = <1>;
#size-cells = <0>;
@@ -654,7 +654,7 @@
status = "disabled";
};
- i2c4: i2c-bus@140 {
+ i2c4: i2c@140 {
#address-cells = <1>;
#size-cells = <0>;
@@ -670,7 +670,7 @@
status = "disabled";
};
- i2c5: i2c-bus@180 {
+ i2c5: i2c@180 {
#address-cells = <1>;
#size-cells = <0>;
@@ -686,7 +686,7 @@
status = "disabled";
};
- i2c6: i2c-bus@1c0 {
+ i2c6: i2c@1c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -702,7 +702,7 @@
status = "disabled";
};
- i2c7: i2c-bus@300 {
+ i2c7: i2c@300 {
#address-cells = <1>;
#size-cells = <0>;
@@ -718,7 +718,7 @@
status = "disabled";
};
- i2c8: i2c-bus@340 {
+ i2c8: i2c@340 {
#address-cells = <1>;
#size-cells = <0>;
@@ -734,7 +734,7 @@
status = "disabled";
};
- i2c9: i2c-bus@380 {
+ i2c9: i2c@380 {
#address-cells = <1>;
#size-cells = <0>;
@@ -750,7 +750,7 @@
status = "disabled";
};
- i2c10: i2c-bus@3c0 {
+ i2c10: i2c@3c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -766,7 +766,7 @@
status = "disabled";
};
- i2c11: i2c-bus@400 {
+ i2c11: i2c@400 {
#address-cells = <1>;
#size-cells = <0>;
@@ -782,7 +782,7 @@
status = "disabled";
};
- i2c12: i2c-bus@440 {
+ i2c12: i2c@440 {
#address-cells = <1>;
#size-cells = <0>;
@@ -798,7 +798,7 @@
status = "disabled";
};
- i2c13: i2c-bus@480 {
+ i2c13: i2c@480 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
index 29f94696d8b1..0c00882f111a 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
@@ -867,22 +867,26 @@
};
fsim0: fsi@1e79b000 {
+ #interrupt-cells = <1>;
compatible = "aspeed,ast2600-fsi-master", "fsi-master";
reg = <0x1e79b000 0x94>;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fsi1_default>;
clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
+ interrupt-controller;
status = "disabled";
};
fsim1: fsi@1e79b100 {
+ #interrupt-cells = <1>;
compatible = "aspeed,ast2600-fsi-master", "fsi-master";
reg = <0x1e79b100 0x94>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fsi2_default>;
clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
+ interrupt-controller;
status = "disabled";
};
@@ -901,7 +905,7 @@
#include "aspeed-g6-pinctrl.dtsi"
&i2c {
- i2c0: i2c-bus@80 {
+ i2c0: i2c@80 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x80 0x80>;
@@ -915,7 +919,7 @@
status = "disabled";
};
- i2c1: i2c-bus@100 {
+ i2c1: i2c@100 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x100 0x80>;
@@ -929,7 +933,7 @@
status = "disabled";
};
- i2c2: i2c-bus@180 {
+ i2c2: i2c@180 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x180 0x80>;
@@ -943,7 +947,7 @@
status = "disabled";
};
- i2c3: i2c-bus@200 {
+ i2c3: i2c@200 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x200 0x80>;
@@ -957,7 +961,7 @@
status = "disabled";
};
- i2c4: i2c-bus@280 {
+ i2c4: i2c@280 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x280 0x80>;
@@ -971,7 +975,7 @@
status = "disabled";
};
- i2c5: i2c-bus@300 {
+ i2c5: i2c@300 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x300 0x80>;
@@ -985,7 +989,7 @@
status = "disabled";
};
- i2c6: i2c-bus@380 {
+ i2c6: i2c@380 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x380 0x80>;
@@ -999,7 +1003,7 @@
status = "disabled";
};
- i2c7: i2c-bus@400 {
+ i2c7: i2c@400 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x400 0x80>;
@@ -1013,7 +1017,7 @@
status = "disabled";
};
- i2c8: i2c-bus@480 {
+ i2c8: i2c@480 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x480 0x80>;
@@ -1027,7 +1031,7 @@
status = "disabled";
};
- i2c9: i2c-bus@500 {
+ i2c9: i2c@500 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x500 0x80>;
@@ -1041,7 +1045,7 @@
status = "disabled";
};
- i2c10: i2c-bus@580 {
+ i2c10: i2c@580 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x580 0x80>;
@@ -1055,7 +1059,7 @@
status = "disabled";
};
- i2c11: i2c-bus@600 {
+ i2c11: i2c@600 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x600 0x80>;
@@ -1069,7 +1073,7 @@
status = "disabled";
};
- i2c12: i2c-bus@680 {
+ i2c12: i2c@680 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x680 0x80>;
@@ -1083,7 +1087,7 @@
status = "disabled";
};
- i2c13: i2c-bus@700 {
+ i2c13: i2c@700 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x700 0x80>;
@@ -1097,7 +1101,7 @@
status = "disabled";
};
- i2c14: i2c-bus@780 {
+ i2c14: i2c@780 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x780 0x80>;
@@ -1111,7 +1115,7 @@
status = "disabled";
};
- i2c15: i2c-bus@800 {
+ i2c15: i2c@800 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x800 0x80>;
diff --git a/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi b/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi
index cc466910bb52..07ce3b2bc62a 100644
--- a/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi
+++ b/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi
@@ -165,10 +165,12 @@
};
fsi_hub0: hub@3400 {
+ #interrupt-cells = <1>;
compatible = "fsi-master-hub";
reg = <0x3400 0x400>;
#address-cells = <2>;
#size-cells = <0>;
+ interrupt-controller;
};
};
};
diff --git a/arch/arm/boot/dts/broadcom/Makefile b/arch/arm/boot/dts/broadcom/Makefile
index 7099d9560033..5881bcc95eba 100644
--- a/arch/arm/boot/dts/broadcom/Makefile
+++ b/arch/arm/boot/dts/broadcom/Makefile
@@ -64,6 +64,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm47081-luxul-xap-1410.dtb \
bcm47081-luxul-xwr-1200.dtb \
bcm47081-tplink-archer-c5-v2.dtb \
+ bcm4709-asus-rt-ac3200.dtb \
bcm4709-asus-rt-ac87u.dtb \
bcm4709-buffalo-wxr-1900dhp.dtb \
bcm4709-linksys-ea9200.dtb \
@@ -71,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm4709-netgear-r8000.dtb \
bcm4709-tplink-archer-c9-v1.dtb \
bcm47094-asus-rt-ac3100.dtb \
+ bcm47094-asus-rt-ac5300.dtb \
bcm47094-asus-rt-ac88u.dtb \
bcm47094-dlink-dir-885l.dtb \
bcm47094-dlink-dir-890l.dtb \
diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts
index d5f8823230db..353bb50ce542 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts
@@ -5,6 +5,7 @@
#include "bcm283x-rpi-led-deprecated.dtsi"
#include "bcm283x-rpi-usb-peripheral.dtsi"
#include "bcm283x-rpi-wifi-bt.dtsi"
+#include <dt-bindings/leds/common.h>
/ {
compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
@@ -15,6 +16,13 @@
stdout-path = "serial1:115200n8";
};
+ cam1_reg: regulator-cam1 {
+ compatible = "regulator-fixed";
+ regulator-name = "cam1-reg";
+ enable-active-high;
+ gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
+ };
+
sd_io_1v8_reg: regulator-sd-io-1v8 {
compatible = "regulator-gpio";
regulator-name = "vdd-sd-io";
@@ -197,6 +205,27 @@
phy1: ethernet-phy@1 {
/* No PHY interrupt */
reg = <0x1>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* LED1 */
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ /* LED2 */
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
index 5a2869a18bd5..ca9be91b4f36 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
@@ -30,6 +30,7 @@
&genet_mdio {
clock-frequency = <1950000>;
+ /delete-node/ leds;
};
&led_pwr {
diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
index d7ba02f586d3..6bc77dd48c0d 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
+#include <dt-bindings/leds/common.h>
#include "bcm2711-rpi-cm4.dtsi"
#include "bcm283x-rpi-led-deprecated.dtsi"
#include "bcm283x-rpi-usb-host.dtsi"
@@ -101,6 +102,38 @@
status = "okay";
};
+&i2c0_1 {
+ rtc@51 {
+ /* Attention: An alarm resets the machine */
+ compatible = "nxp,pcf85063a";
+ reg = <0x51>;
+ quartz-load-femtofarads = <7000>;
+ };
+};
+
+&phy1 {
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* LED2 */
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ /* LED3 */
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+};
+
&led_act {
gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
index d233a191c139..6bf4241fe3b7 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
@@ -17,14 +17,33 @@
pcie0 = &pcie0;
blconfig = &blconfig;
};
-};
-&firmware {
- firmware_clocks: clocks {
- compatible = "raspberrypi,firmware-clocks";
- #clock-cells = <1>;
+ i2c0mux: i2c-mux0 {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&i2c0>;
+
+ pinctrl-names = "i2c0", "i2c0-vc";
+ pinctrl-0 = <&i2c0_gpio0>;
+ pinctrl-1 = <&i2c0_gpio44>;
+
+ i2c0_0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c0_1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
+};
+&firmware {
expgpio: gpio {
compatible = "raspberrypi,firmware-gpio";
gpio-controller;
@@ -54,6 +73,11 @@
clocks = <&firmware_clocks 4>;
};
+&i2c0 {
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
+};
+
&rmem {
/*
* RPi4's co-processor will copy the board's bootloader configuration
diff --git a/arch/arm/boot/dts/broadcom/bcm2711.dtsi b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
index 22c7f1561344..e4e42af21ef3 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
@@ -432,8 +432,8 @@
};
};
- arm-pmu {
- compatible = "arm,cortex-a72-pmu", "arm,armv8-pmuv3";
+ pmu {
+ compatible = "arm,cortex-a72-pmu";
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
@@ -1114,6 +1114,14 @@
#address-cells = <2>;
};
+&csi0 {
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&csi1 {
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+};
+
&cma {
/*
* arm64 reserves the CMA by default somewhere in ZONE_DMA32,
diff --git a/arch/arm/boot/dts/broadcom/bcm2835-rpi-common.dtsi b/arch/arm/boot/dts/broadcom/bcm2835-rpi-common.dtsi
index 4e7b4a592da7..8b3c21d9f333 100644
--- a/arch/arm/boot/dts/broadcom/bcm2835-rpi-common.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2835-rpi-common.dtsi
@@ -7,13 +7,6 @@
#include <dt-bindings/power/raspberrypi-power.h>
-&firmware {
- firmware_clocks: clocks {
- compatible = "raspberrypi,firmware-clocks";
- #clock-cells = <1>;
- };
-};
-
&hdmi {
clocks = <&firmware_clocks 9>,
<&firmware_clocks 13>;
diff --git a/arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi
index f0acc9390f31..e9bf41b9f5c1 100644
--- a/arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi
@@ -4,11 +4,12 @@
soc {
firmware: firmware {
compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
- #address-cells = <1>;
- #size-cells = <1>;
-
mboxes = <&mailbox>;
- dma-ranges;
+
+ firmware_clocks: clocks {
+ compatible = "raspberrypi,firmware-clocks";
+ #clock-cells = <1>;
+ };
};
power: power {
@@ -25,6 +26,20 @@
};
};
+&csi0 {
+ clocks = <&clocks BCM2835_CLOCK_CAM0>,
+ <&firmware_clocks 4>;
+ clock-names = "lp", "vpu";
+ power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
+};
+
+&csi1 {
+ clocks = <&clocks BCM2835_CLOCK_CAM1>,
+ <&firmware_clocks 4>;
+ clock-names = "lp", "vpu";
+ power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
+};
+
&gpio {
gpioout: gpioout {
brcm,pins = <6>;
diff --git a/arch/arm/boot/dts/broadcom/bcm283x.dtsi b/arch/arm/boot/dts/broadcom/bcm283x.dtsi
index 2ca8a2505a4d..69b0919f1324 100644
--- a/arch/arm/boot/dts/broadcom/bcm283x.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm283x.dtsi
@@ -454,6 +454,30 @@
status = "disabled";
};
+ csi0: csi@7e800000 {
+ compatible = "brcm,bcm2835-unicam";
+ reg = <0x7e800000 0x800>,
+ <0x7e802000 0x4>;
+ reg-names = "unicam", "cmi";
+ interrupts = <2 6>;
+ brcm,num-data-lanes = <2>;
+ status = "disabled";
+ port {
+ };
+ };
+
+ csi1: csi@7e801000 {
+ compatible = "brcm,bcm2835-unicam";
+ reg = <0x7e801000 0x800>,
+ <0x7e802004 0x4>;
+ reg-names = "unicam", "cmi";
+ interrupts = <2 7>;
+ brcm,num-data-lanes = <4>;
+ status = "disabled";
+ port {
+ };
+ };
+
i2c1: i2c@7e804000 {
compatible = "brcm,bcm2835-i2c";
reg = <0x7e804000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts b/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts
new file mode 100644
index 000000000000..53cb0c58f6d0
--- /dev/null
+++ b/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Author: Tom Brautaset <tbrautaset@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm4709.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "asus,rt-ac3200", "brcm,bcm4709", "brcm,bcm4708";
+ model = "ASUS RT-AC3200";
+
+ memory@0 {
+ reg = <0x00000000 0x08000000>,
+ <0x88000000 0x08000000>;
+ device_type = "memory";
+ };
+
+ nvram@1c080000 {
+ compatible = "brcm,nvram";
+ reg = <0x1c080000 0x00180000>;
+
+ et0macaddr: et0macaddr {
+ #nvmem-cell-cells = <1>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ button-reset {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wifi {
+ label = "Wi-Fi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-power {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ led-wan-red {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-wps {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_WPS;
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&et0macaddr 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ nvmem-cells = <&et0macaddr 1>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac2 {
+ nvmem-cells = <&et0macaddr 2>;
+ nvmem-cell-names = "mac-address";
+};
+
+&nandcs {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x00000000 0x00080000>;
+ label = "boot";
+ read-only;
+ };
+
+ partition@80000 {
+ reg = <0x00080000 0x00180000>;
+ label = "nvram";
+ };
+
+ partition@200000 {
+ compatible = "brcm,trx";
+ reg = <0x00200000 0x07e00000>;
+ label = "firmware";
+ };
+ };
+};
+
+&srab {
+ status = "okay";
+
+ ports {
+ port@0 {
+ label = "wan";
+ };
+
+ port@1 {
+ label = "lan1";
+ };
+
+ port@2 {
+ label = "lan2";
+ };
+
+ port@3 {
+ label = "lan3";
+ };
+
+ port@4 {
+ label = "lan4";
+ };
+ };
+};
+
+&usb2 {
+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
+};
+
+&usb3_phy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dts b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dts
index 5f089307cd8c..1655ac95769c 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dts
@@ -13,11 +13,22 @@
nvram@1c080000 {
et0macaddr: et0macaddr {
+ #nvmem-cell-cells = <1>;
};
};
};
&gmac0 {
- nvmem-cells = <&et0macaddr>;
+ nvmem-cells = <&et0macaddr 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ nvmem-cells = <&et0macaddr 1>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac2 {
+ nvmem-cells = <&et0macaddr 2>;
nvmem-cell-names = "mac-address";
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dtsi b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dtsi
index 09cefce27fb1..2cfaaabc7a6a 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dtsi
@@ -6,15 +6,13 @@
#include "bcm47094.dtsi"
#include "bcm5301x-nand-cs0-bch8.dtsi"
-/ {
- chosen {
- bootargs = "earlycon";
- };
+#include <dt-bindings/leds/common.h>
+/ {
memory@0 {
- device_type = "memory";
reg = <0x00000000 0x08000000>,
<0x88000000 0x18000000>;
+ device_type = "memory";
};
nvram@1c080000 {
@@ -22,76 +20,108 @@
reg = <0x1c080000 0x00180000>;
};
- leds {
- compatible = "gpio-leds";
+ gpio-keys {
+ compatible = "gpio-keys";
- led-power {
- label = "white:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
+ button-led {
+ label = "Backlight";
+ linux,code = <KEY_BRIGHTNESS_ZERO>;
+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
};
- led-wan-red {
- label = "red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+ button-reset {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wifi {
+ label = "Wi-Fi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
};
+ button-wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
led-lan {
- label = "white:lan";
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_LAN;
gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
};
+ led-power {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
led-usb2 {
- label = "white:usb2";
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
trigger-sources = <&ehci_port2>;
linux,default-trigger = "usbport";
};
led-usb3 {
- label = "white:usb3";
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
trigger-sources = <&ehci_port1>, <&xhci_port1>;
linux,default-trigger = "usbport";
};
+ led-wan-red {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+ };
+
led-wps {
- label = "white:wps";
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_WPS;
gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
};
};
+};
- gpio-keys {
- compatible = "gpio-keys";
-
- button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- };
+&nandcs {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
- button-reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ partition@0 {
+ reg = <0x00000000 0x00080000>;
+ label = "boot";
+ read-only;
};
- button-wifi {
- label = "Wi-Fi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+ partition@80000 {
+ reg = <0x00080000 0x00180000>;
+ label = "nvram";
};
- button-led {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+ partition@200000 {
+ compatible = "brcm,trx";
+ reg = <0x00200000 0x07e00000>;
+ label = "firmware";
};
};
};
&srab {
- compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
status = "okay";
ports {
@@ -136,28 +166,3 @@
&usb3_phy {
status = "okay";
};
-
-&nandcs {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "boot";
- reg = <0x00000000 0x00080000>;
- read-only;
- };
-
- partition@80000 {
- label = "nvram";
- reg = <0x00080000 0x00180000>;
- };
-
- partition@200000 {
- label = "firmware";
- reg = <0x00200000 0x07e00000>;
- compatible = "brcm,trx";
- };
- };
-};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts
new file mode 100644
index 000000000000..6c666dc7ad23
--- /dev/null
+++ b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Author: Tom Brautaset <tbrautaset@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm47094.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "asus,rt-ac5300", "brcm,bcm47094", "brcm,bcm4708";
+ model = "ASUS RT-AC5300";
+
+ memory@0 {
+ reg = <0x00000000 0x08000000>,
+ <0x88000000 0x18000000>;
+ device_type = "memory";
+ };
+
+ nvram@1c080000 {
+ compatible = "brcm,nvram";
+ reg = <0x1c080000 0x00180000>;
+
+ et1macaddr: et1macaddr {
+ #nvmem-cell-cells = <1>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ button-reset {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wifi {
+ label = "Wi-Fi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-lan {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_LAN;
+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
+ };
+
+ led-power {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ led-wan-red {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-wps {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_WPS;
+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&et1macaddr 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ nvmem-cells = <&et1macaddr 1>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac2 {
+ nvmem-cells = <&et1macaddr 2>;
+ nvmem-cell-names = "mac-address";
+};
+
+&nandcs {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x00000000 0x00080000>;
+ label = "boot";
+ read-only;
+ };
+
+ partition@80000 {
+ reg = <0x00080000 0x00180000>;
+ label = "nvram";
+ };
+
+ partition@200000 {
+ compatible = "brcm,trx";
+ reg = <0x00200000 0x07e00000>;
+ label = "firmware";
+ };
+ };
+};
+
+&srab {
+ status = "okay";
+
+ ports {
+ port@0 {
+ label = "lan4";
+ };
+
+ port@1 {
+ label = "lan3";
+ };
+
+ port@2 {
+ label = "lan2";
+ };
+
+ port@3 {
+ label = "lan1";
+ };
+
+ port@4 {
+ label = "wan";
+ };
+ };
+};
+
+&usb2 {
+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
+};
+
+&usb3_phy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac88u.dts b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac88u.dts
index fd344b55087e..a197f447fd97 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac88u.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac88u.dts
@@ -13,18 +13,40 @@
nvram@1c080000 {
et1macaddr: et1macaddr {
+ #nvmem-cell-cells = <1>;
};
};
switch {
compatible = "realtek,rtl8365mb";
- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
realtek,disable-leds;
dsa,member = <1 0>;
+ mdio {
+ compatible = "realtek,smi-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+
+ ethphy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+ };
+
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -68,29 +90,21 @@
};
};
};
+ };
+};
- mdio {
- compatible = "realtek,smi-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
-
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- ethphy1: ethernet-phy@1 {
- reg = <1>;
- };
+&gmac0 {
+ status = "disabled";
+};
- ethphy2: ethernet-phy@2 {
- reg = <2>;
- };
+&gmac1 {
+ nvmem-cells = <&et1macaddr 0>;
+ nvmem-cell-names = "mac-address";
+};
- ethphy3: ethernet-phy@3 {
- reg = <3>;
- };
- };
- };
+&gmac2 {
+ nvmem-cells = <&et1macaddr 1>;
+ nvmem-cell-names = "mac-address";
};
&srab {
@@ -111,12 +125,3 @@
};
};
};
-
-&gmac0 {
- status = "disabled";
-};
-
-&gmac1 {
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
-};
diff --git a/arch/arm/boot/dts/cirrus/ep7211-edb7211.dts b/arch/arm/boot/dts/cirrus/ep7211-edb7211.dts
index 7fb532f227af..808cd5778e27 100644
--- a/arch/arm/boot/dts/cirrus/ep7211-edb7211.dts
+++ b/arch/arm/boot/dts/cirrus/ep7211-edb7211.dts
@@ -30,7 +30,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: 320x240 {
+ timing0: timing-320x240 {
hactive = <320>;
hback-porch = <0>;
hfront-porch = <0>;
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts
index 2eec5f63d399..2f7c34c649ea 100644
--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts
@@ -90,11 +90,18 @@
timeout-ms = <5000>;
};
- gpio-beeper {
- compatible = "gpio-beeper";
+ gpio_pwm: pwm {
+ #pwm-cells = <3>;
+ compatible = "pwm-gpio";
gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
};
+ beeper {
+ compatible = "pwm-beeper";
+ pwms = <&gpio_pwm 0 1 0>;
+ beeper-hz = <1000>;
+ };
+
soc {
bus@c4000000 {
/* The first 16MB region at CS0 on the expansion bus */
diff --git a/arch/arm/boot/dts/marvell/armada-370-xp.dtsi b/arch/arm/boot/dts/marvell/armada-370-xp.dtsi
index 0b8c2a64b36f..954c891e5aee 100644
--- a/arch/arm/boot/dts/marvell/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/marvell/armada-370-xp.dtsi
@@ -168,7 +168,6 @@
mpic: interrupt-controller@20a00 {
compatible = "marvell,mpic";
#interrupt-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
msi-controller;
};
diff --git a/arch/arm/boot/dts/marvell/armada-375.dtsi b/arch/arm/boot/dts/marvell/armada-375.dtsi
index ddc49547d786..99778b4b7e7b 100644
--- a/arch/arm/boot/dts/marvell/armada-375.dtsi
+++ b/arch/arm/boot/dts/marvell/armada-375.dtsi
@@ -376,7 +376,6 @@
compatible = "marvell,mpic";
reg = <0x20a00 0x2d0>, <0x21070 0x58>;
#interrupt-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
msi-controller;
interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts b/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts
index 5a9ab8410b7b..2fb7304039be 100644
--- a/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts
+++ b/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts
@@ -43,6 +43,17 @@
};
};
};
+
+ led-7seg {
+ compatible = "gpio-7-segment";
+ segment-gpios = <&led_7seg_gpio 0 GPIO_ACTIVE_LOW>,
+ <&led_7seg_gpio 1 GPIO_ACTIVE_LOW>,
+ <&led_7seg_gpio 2 GPIO_ACTIVE_LOW>,
+ <&led_7seg_gpio 3 GPIO_ACTIVE_LOW>,
+ <&led_7seg_gpio 4 GPIO_ACTIVE_LOW>,
+ <&led_7seg_gpio 5 GPIO_ACTIVE_LOW>,
+ <&led_7seg_gpio 6 GPIO_ACTIVE_LOW>;
+ };
};
&pciec {
@@ -149,7 +160,7 @@
#size-cells = <0>;
reg = <3>;
- gpio@20 {
+ led_7seg_gpio: gpio@20 {
compatible = "nxp,pca9554";
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
index 7b755bb4e4e7..43202890c959 100644
--- a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
+++ b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
@@ -112,6 +112,19 @@
status = "disabled";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ front-button {
+ label = "Front Button";
+ linux,code = <KEY_VENDOR>;
+ linux,can-disable;
+ gpios = <&mcu 0 12 GPIO_ACTIVE_HIGH>;
+ /* debouncing is done by the microcontroller */
+ debounce-interval = <0>;
+ };
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "SPDIF";
@@ -218,7 +231,22 @@
#size-cells = <0>;
reg = <0>;
- /* STM32F0 command interface at address 0x2a */
+ mcu: system-controller@2a {
+ compatible = "cznic,turris-omnia-mcu";
+ reg = <0x2a>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_pins>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <11 IRQ_TYPE_NONE>;
+
+ gpio-controller;
+ #gpio-cells = <3>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
led-controller@2b {
compatible = "cznic,turris-omnia-leds";
@@ -501,6 +529,11 @@
};
&pinctrl {
+ mcu_pins: mcu-pins {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+
pcawan_pins: pcawan-pins {
marvell,pins = "mpp46";
marvell,function = "gpio";
diff --git a/arch/arm/boot/dts/marvell/armada-38x.dtsi b/arch/arm/boot/dts/marvell/armada-38x.dtsi
index 446861b6b17b..1181b13deabc 100644
--- a/arch/arm/boot/dts/marvell/armada-38x.dtsi
+++ b/arch/arm/boot/dts/marvell/armada-38x.dtsi
@@ -408,7 +408,6 @@
compatible = "marvell,mpic";
reg = <0x20a00 0x2d0>, <0x21070 0x58>;
#interrupt-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
msi-controller;
interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/marvell/armada-39x.dtsi b/arch/arm/boot/dts/marvell/armada-39x.dtsi
index 9d1cac49c022..6d05835efb42 100644
--- a/arch/arm/boot/dts/marvell/armada-39x.dtsi
+++ b/arch/arm/boot/dts/marvell/armada-39x.dtsi
@@ -268,7 +268,6 @@
compatible = "marvell,mpic";
reg = <0x20a00 0x2d0>, <0x21070 0x58>;
#interrupt-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
msi-controller;
interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-blackarmor-nas220.dts b/arch/arm/boot/dts/marvell/kirkwood-blackarmor-nas220.dts
index 07fbfca444d5..36b90c632fd6 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-blackarmor-nas220.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-blackarmor-nas220.dts
@@ -35,13 +35,13 @@
gpio_keys {
compatible = "gpio-keys";
- reset {
+ button-reset {
label = "Reset";
linux,code = <KEY_POWER>;
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
- button {
+ button-power {
label = "Power";
linux,code = <KEY_SLEEP>;
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
@@ -51,7 +51,7 @@
gpio-leds {
compatible = "gpio-leds";
- blue-power {
+ led-blue-power {
label = "nas220:blue:power";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "default-on";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-c200-v1.dts b/arch/arm/boot/dts/marvell/kirkwood-c200-v1.dts
index f59ff7578dfc..7e3ee64d4bdf 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-c200-v1.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-c200-v1.dts
@@ -29,25 +29,25 @@
pinctrl-0 = <&pmx_buttons>;
pinctrl-names = "default";
- power {
+ button-power {
label = "Power Button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
};
- reset {
+ button-reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
- usb1 {
+ button-usb1 {
label = "USB1 Button";
linux,code = <BTN_0>;
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
- usb2 {
+ button-usb2 {
label = "USB2 Button";
linux,code = <BTN_1>;
gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-cloudbox.dts b/arch/arm/boot/dts/marvell/kirkwood-cloudbox.dts
index 448b0cd23b5f..151edcd140a0 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-cloudbox.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-cloudbox.dts
@@ -58,10 +58,8 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
- power {
+ key-power {
label = "Power push button";
linux,code = <KEY_POWER>;
gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
@@ -71,11 +69,11 @@
gpio-leds {
compatible = "gpio-leds";
- red-fail {
+ led-red-fail {
label = "cloudbox:red:fail";
gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
};
- blue-sata {
+ led-blue-sata {
label = "cloudbox:blue:sata";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-d2net.dts b/arch/arm/boot/dts/marvell/kirkwood-d2net.dts
index bd3b266dd766..fcce8730d3e3 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-d2net.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-d2net.dts
@@ -37,7 +37,7 @@
gpio-leds {
compatible = "gpio-leds";
- red-fail {
+ led-red-fail {
label = "d2net_v2:red:fail";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-dir665.dts b/arch/arm/boot/dts/marvell/kirkwood-dir665.dts
index 0c0851cd9bec..2f6793f794cd 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-dir665.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-dir665.dts
@@ -137,38 +137,38 @@
gpio-leds {
compatible = "gpio-leds";
- blue-usb {
+ led-blue-usb {
label = "dir665:blue:usb";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
- blue-internet {
+ led-blue-internet {
/* Can only be turned on if the Internet
* Ethernet port has Link
*/
label = "dir665:blue:internet";
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
- amber-internet {
+ led-amber-internet {
label = "dir665:amber:internet";
gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
- blue-wifi5g {
+ led-blue-wifi5g {
label = "dir665:blue:5g";
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
};
- blue-status {
+ led-blue-status {
label = "dir665:blue:status";
gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
- blue-wps {
+ led-blue-wps {
label = "dir665:blue:wps";
gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
- amber-status {
+ led-amber-status {
label = "dir665:amber:status";
gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
};
- blue-24g {
+ led-blue-24g {
label = "dir665:blue:24g";
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
@@ -176,15 +176,13 @@
gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
- reset {
+ button-reset {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
- wps {
+ button-wps {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-dns320.dts b/arch/arm/boot/dts/marvell/kirkwood-dns320.dts
index d6b0f418fd01..d8279e0c4c4f 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-dns320.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-dns320.dts
@@ -24,24 +24,24 @@
&pmx_led_white_usb>;
pinctrl-names = "default";
- blue-power {
+ led-blue-power {
label = "dns320:blue:power";
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- blue-usb {
+ led-blue-usb {
label = "dns320:blue:usb";
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
- orange-l_hdd {
+ led-orange-l_hdd {
label = "dns320:orange:l_hdd";
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
- orange-r_hdd {
+ led-orange-r_hdd {
label = "dns320:orange:r_hdd";
gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
};
- orange-usb {
+ led-orange-usb {
label = "dns320:orange:usb";
gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; /* GPIO 35 */
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-dns325.dts b/arch/arm/boot/dts/marvell/kirkwood-dns325.dts
index 94d9c06cbbf5..7f396195e977 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-dns325.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-dns325.dts
@@ -24,24 +24,24 @@
&pmx_led_white_usb>;
pinctrl-names = "default";
- white-power {
+ led-white-power {
label = "dns325:white:power";
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- white-usb {
+ led-white-usb {
label = "dns325:white:usb";
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO 43 */
};
- red-l_hdd {
+ led-red-l_hdd {
label = "dns325:red:l_hdd";
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
- red-r_hdd {
+ led-red-r_hdd {
label = "dns325:red:r_hdd";
gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
};
- red-usb {
+ led-red-usb {
label = "dns325:red:usb";
gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/marvell/kirkwood-dnskw.dtsi
index 0738eb679fcd..20bcd031f3f5 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-dnskw.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-dnskw.dtsi
@@ -8,23 +8,21 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_power &pmx_button_unmount
&pmx_button_reset>;
pinctrl-names = "default";
- power {
+ button-power {
label = "Power button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
};
- eject {
+ button-eject {
label = "USB unmount button";
linux,code = <KEY_EJECTCD>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-dockstar.dts b/arch/arm/boot/dts/marvell/kirkwood-dockstar.dts
index 264938dfa4d9..090f1e2e5bb6 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-dockstar.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-dockstar.dts
@@ -42,12 +42,12 @@
pinctrl-0 = <&pmx_led_green &pmx_led_orange>;
pinctrl-names = "default";
- health {
+ led-health {
label = "status:green:health";
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- fault {
+ led-fault {
label = "status:orange:fault";
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-dreamplug.dts b/arch/arm/boot/dts/marvell/kirkwood-dreamplug.dts
index 328516351e84..590bee3c561c 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-dreamplug.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-dreamplug.dts
@@ -85,15 +85,15 @@
&pmx_led_wifi_ap >;
pinctrl-names = "default";
- bluetooth {
+ led-bluetooth {
label = "dreamplug:blue:bluetooth";
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- wifi {
+ led-wifi {
label = "dreamplug:green:wifi";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
- wifi-ap {
+ led-wifi-ap {
label = "dreamplug:green:wifi_ap";
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-goflexnet.dts b/arch/arm/boot/dts/marvell/kirkwood-goflexnet.dts
index d4cb3cd3e2a2..d5ac4e3974da 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-goflexnet.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-goflexnet.dts
@@ -85,44 +85,44 @@
>;
pinctrl-names = "default";
- health {
+ led-health {
label = "status:green:health";
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- fault {
+ led-fault {
label = "status:orange:fault";
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- left0 {
+ led-left0 {
label = "status:white:left0";
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- left1 {
+ led-left1 {
label = "status:white:left1";
gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
- left2 {
+ led-left2 {
label = "status:white:left2";
gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
};
- left3 {
+ led-left3 {
label = "status:white:left3";
gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
- right0 {
+ led-right0 {
label = "status:white:right0";
gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
};
- right1 {
+ led-right1 {
label = "status:white:right1";
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
- right2 {
+ led-right2 {
label = "status:white:right2";
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
- right3 {
+ led-right3 {
label = "status:white:right3";
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts
index dfb41393941d..d5aa8b505cc0 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts
@@ -59,19 +59,19 @@
&pmx_led_wmode_r &pmx_led_wmode_g >;
pinctrl-names = "default";
- health-r {
+ led-health-r {
label = "guruplug:red:health";
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
- health-g {
+ led-health-g {
label = "guruplug:green:health";
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- wmode-r {
+ led-wmode-r {
label = "guruplug:red:wmode";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
- wmode-g {
+ led-wmode-g {
label = "guruplug:green:wmode";
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-ib62x0.dts b/arch/arm/boot/dts/marvell/kirkwood-ib62x0.dts
index 962a910a6f5c..018c6b8f3e8a 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-ib62x0.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-ib62x0.dts
@@ -58,17 +58,15 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_reset &pmx_button_usb_copy>;
pinctrl-names = "default";
- copy {
+ button-copy {
label = "USB Copy";
linux,code = <KEY_COPY>;
gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
@@ -81,16 +79,16 @@
&pmx_led_usb_transfer>;
pinctrl-names = "default";
- green-os {
+ led-green-os {
label = "ib62x0:green:os";
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
default-state = "keep";
};
- red-os {
+ led-red-os {
label = "ib62x0:red:os";
gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
};
- usb-copy {
+ led-usb-copy {
label = "ib62x0:red:usb_copy";
gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-iconnect.dts b/arch/arm/boot/dts/marvell/kirkwood-iconnect.dts
index aed20185fd7a..91b46e77e0b6 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-iconnect.dts
@@ -89,32 +89,32 @@
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
- power-blue {
+ led-power-blue {
label = "power:blue";
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
default-state = "keep";
};
- power-red {
+ led-power-red {
label = "power:red";
gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
- usb1 {
+ led-usb1 {
label = "usb1:blue";
gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
};
- usb2 {
+ led-usb2 {
label = "usb2:blue";
gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
- usb3 {
+ led-usb3 {
label = "usb3:blue";
gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
- usb4 {
+ led-usb4 {
label = "usb4:blue";
gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
- otb {
+ led-otb {
label = "otb:blue";
gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
};
@@ -122,18 +122,16 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = < &pmx_button_reset &pmx_button_otb >;
pinctrl-names = "default";
- otb {
+ button-otb {
label = "OTB Button";
linux,code = <KEY_COPY>;
gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
debounce-interval = <100>;
};
- reset {
+ button-reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/marvell/kirkwood-iomega_ix2_200.dts
index 2338f495d517..039362152650 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-iomega_ix2_200.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-iomega_ix2_200.dts
@@ -127,44 +127,42 @@
&pmx_led_rebuild &pmx_led_health >;
pinctrl-names = "default";
- power_led {
+ led-power-led {
label = "status:white:power_led";
gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
default-state = "keep";
};
- rebuild_led {
+ led-rebuild-led {
label = "status:white:rebuild_led";
gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
};
- health_led {
+ led-health-led {
label = "status:red:health_led";
gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
};
- backup_led {
+ led-backup-led {
label = "status:blue:backup_led";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
};
gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_reset &pmx_button_power
&pmx_button_otb>;
pinctrl-names = "default";
- Power {
+ button-power {
label = "Power Button";
linux,code = <KEY_POWER>;
gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
};
- Reset {
+ button-reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
};
- OTB {
+ button-otb {
label = "OTB Button";
linux,code = <KEY_COPY>;
gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-l-50.dts b/arch/arm/boot/dts/marvell/kirkwood-l-50.dts
index c841eb8e7fb1..974bc9de4702 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-l-50.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-l-50.dts
@@ -97,52 +97,52 @@
leds {
compatible = "gpio-leds";
- status_green {
+ led-status-green {
label = "l-50:green:status";
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
};
- status_red {
+ led-status-red {
label = "l-50:red:status";
gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
};
- wifi {
+ led-wifi {
label = "l-50:green:wifi";
gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy0tpt";
};
- internet_green {
+ led-internet-green {
label = "l-50:green:internet";
gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
};
- internet_red {
+ led-internet-red {
label = "l-50:red:internet";
gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
};
- usb1_green {
+ led-usb1-green {
label = "l-50:green:usb1";
gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
linux,default-trigger = "usbport";
trigger-sources = <&hub_port3>;
};
- usb1_red {
+ led-usb1-red {
label = "l-50:red:usb1";
gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
};
- usb2_green {
+ led-usb2-green {
label = "l-50:green:usb2";
gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
linux,default-trigger = "usbport";
trigger-sources = <&hub_port1>;
};
- usb2_red {
+ led-usb2-red {
label = "l-50:red:usb2";
gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
};
@@ -193,7 +193,7 @@
keys {
compatible = "gpio-keys";
- factory_defaults {
+ button-factory-defaults {
label = "factory_defaults";
gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-laplug.dts b/arch/arm/boot/dts/marvell/kirkwood-laplug.dts
index 8c2b540eaf4f..90ea6cdee8e0 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-laplug.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-laplug.dts
@@ -51,7 +51,7 @@
gpio_keys {
compatible = "gpio-keys";
- power {
+ button-power {
label = "Power push button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
@@ -61,11 +61,11 @@
gpio-leds {
compatible = "gpio-leds";
- red-fail {
+ led-red-fail {
label = "laplug_v2:red:power";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
- blue-power {
+ led-blue-power {
label = "laplug_v2:blue:power";
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "default-on";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-linkstation.dtsi b/arch/arm/boot/dts/marvell/kirkwood-linkstation.dtsi
index b54c9980f636..8a11d2b9d449 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-linkstation.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-linkstation.dtsi
@@ -88,8 +88,6 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_function &pmx_power_switch
&pmx_power_auto_switch>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-linksys-viper.dts b/arch/arm/boot/dts/marvell/kirkwood-linksys-viper.dts
index 27fd6e2337d5..8a1c38ab6111 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-linksys-viper.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-linksys-viper.dts
@@ -33,18 +33,16 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = < &pmx_btn_wps &pmx_btn_reset >;
pinctrl-names = "default";
- wps {
+ button-wps {
label = "WPS Button";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
@@ -56,12 +54,12 @@
pinctrl-0 = < &pmx_led_white_health &pmx_led_white_pulse >;
pinctrl-names = "default";
- white-health {
+ led-white-health {
label = "viper:white:health";
gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
};
- white-pulse {
+ led-white-pulse {
label = "viper:white:pulse";
gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi
index f80af24b9e90..5e0b139dd4fb 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi
@@ -107,24 +107,22 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_function &pmx_power_switch
&pmx_power_auto_switch>;
pinctrl-names = "default";
- option {
+ button-option {
label = "Function Button";
linux,code = <KEY_OPTION>;
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
- reserved {
+ button-reserved {
label = "Power-on Switch";
linux,code = <KEY_RESERVED>;
linux,input-type = <5>;
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
- power {
+ button-power {
label = "Power-auto Switch";
linux,code = <KEY_ESC>;
linux,input-type = <5>;
@@ -139,28 +137,28 @@
&pmx_led_function_blue>;
pinctrl-names = "default";
- func_blue {
+ led-func-blue {
label = "lsxl:blue:func";
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
- alarm {
+ led-alarm {
label = "lsxl:red:alarm";
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
- info {
+ led-info {
label = "lsxl:amber:info";
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
};
- power {
+ led-power {
label = "lsxl:blue:power";
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- func_red {
+ led-func-red {
label = "lsxl:red:func";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-mplcec4.dts b/arch/arm/boot/dts/marvell/kirkwood-mplcec4.dts
index e87ea7146546..6533b49a15b2 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-mplcec4.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-mplcec4.dts
@@ -114,36 +114,36 @@
>;
pinctrl-names = "default";
- health {
+ led-health {
label = "status:green:health";
gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
};
- user1o {
+ led-user1o {
label = "user1:orange";
gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- user1g {
+ led-user1g {
label = "user1:green";
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- user0o {
+ led-user0o {
label = "user0:orange";
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- user0g {
+ led-user0g {
label = "user0:green";
gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- misc {
+ led-misc {
label = "status:orange:misc";
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
default-state = "on";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/marvell/kirkwood-mv88f6281gtw-ge.dts
index 5a77286136c7..e3b41784c876 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-mv88f6281gtw-ge.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-mv88f6281gtw-ge.dts
@@ -73,17 +73,17 @@
pinctrl-0 = <&pmx_leds &pmx_usb_led>;
pinctrl-names = "default";
- green-status {
+ led-green-status {
label = "gtw:green:Status";
gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
};
- red-status {
+ led-red-status {
label = "gtw:red:Status";
gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
};
- green-usb {
+ led-green-usb {
label = "gtw:green:USB";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
@@ -91,17 +91,15 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_keys>;
pinctrl-names = "default";
- restart {
+ button-restart {
label = "SWR Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- wps {
+ button-wps {
label = "WPS Button";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-netxbig.dtsi b/arch/arm/boot/dts/marvell/kirkwood-netxbig.dtsi
index b5737026e244..d4edf2727388 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-netxbig.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-netxbig.dtsi
@@ -53,26 +53,24 @@
gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
/*
* esc and power represent a three position rocker
* switch. Thus the conventional KEY_POWER does not fit
*/
- exc {
+ button-exc {
label = "Back power switch (on|auto)";
linux,code = <KEY_ESC>;
linux,input-type = <5>;
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
};
- power {
+ button-power {
label = "Back power switch (auto|off)";
linux,code = <KEY_1>;
linux,input-type = <5>;
gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
};
- option {
+ button-option {
label = "Function button";
linux,code = <KEY_OPTION>;
gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/marvell/kirkwood-ns2-common.dtsi
index 51530ea86622..d6b615cf6390 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-ns2-common.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-ns2-common.dtsi
@@ -55,10 +55,8 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
- power {
+ button-power {
label = "Power push button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
@@ -68,7 +66,7 @@
gpio-leds {
compatible = "gpio-leds";
- red-fail {
+ led-red-fail {
label = "ns2:red:fail";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-ns2lite.dts b/arch/arm/boot/dts/marvell/kirkwood-ns2lite.dts
index b0cb5907ed63..686bcd6f0f3c 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-ns2lite.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-ns2lite.dts
@@ -24,7 +24,7 @@
gpio-leds {
compatible = "gpio-leds";
- blue-sata {
+ led-blue-sata {
label = "ns2:blue:sata";
gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
linux,default-trigger = "disk-activity";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-nsa310.dts b/arch/arm/boot/dts/marvell/kirkwood-nsa310.dts
index c1799a07816e..3555ac1c3b15 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-nsa310.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-nsa310.dts
@@ -87,43 +87,43 @@
&pmx_led_hdd_green &pmx_led_hdd_red>;
pinctrl-names = "default";
- green-sys {
+ led-green-sys {
label = "nsa310:green:sys";
gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
};
- red-sys {
+ led-red-sys {
label = "nsa310:red:sys";
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
- green-hdd {
+ led-green-hdd {
label = "nsa310:green:hdd";
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
- red-hdd {
+ led-red-hdd {
label = "nsa310:red:hdd";
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- green-esata {
+ led-green-esata {
label = "nsa310:green:esata";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
- red-esata {
+ led-red-esata {
label = "nsa310:red:esata";
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
};
- green-usb {
+ led-green-usb {
label = "nsa310:green:usb";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
- red-usb {
+ led-red-usb {
label = "nsa310:red:usb";
gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
};
- green-copy {
+ led-green-copy {
label = "nsa310:green:copy";
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
- red-copy {
+ led-red-copy {
label = "nsa310:red:copy";
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-nsa310a.dts b/arch/arm/boot/dts/marvell/kirkwood-nsa310a.dts
index b85e314f045a..ddf84092aade 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-nsa310a.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-nsa310a.dts
@@ -75,39 +75,39 @@
gpio-leds {
compatible = "gpio-leds";
- green-sys {
+ led-green-sys {
label = "nsa310:green:sys";
gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
};
- red-sys {
+ led-red-sys {
label = "nsa310:red:sys";
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
- green-hdd {
+ led-green-hdd {
label = "nsa310:green:hdd";
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
- red-hdd {
+ led-red-hdd {
label = "nsa310:red:hdd";
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- green-esata {
+ led-green-esata {
label = "nsa310:green:esata";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
- red-esata {
+ led-red-esata {
label = "nsa310:red:esata";
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
};
- green-usb {
+ led-green-usb {
label = "nsa310:green:usb";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
- green-copy {
+ led-green-copy {
label = "nsa310:green:copy";
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
- red-copy {
+ led-red-copy {
label = "nsa310:red:copy";
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-nsa310s.dts b/arch/arm/boot/dts/marvell/kirkwood-nsa310s.dts
index 49da633a1bc0..47deb93c90a5 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-nsa310s.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-nsa310s.dts
@@ -35,24 +35,22 @@
keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_buttons>;
pinctrl-names = "default";
- power {
+ button-power {
label = "Power Button";
linux,code = <KEY_POWER>;
gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
};
- copy {
+ button-copy {
label = "Copy Button";
linux,code = <KEY_COPY>;
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-nsa320.dts b/arch/arm/boot/dts/marvell/kirkwood-nsa320.dts
index 652405e65006..dd5c8ffc8781 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-nsa320.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-nsa320.dts
@@ -142,39 +142,39 @@
&pmx_led_hdd1_green &pmx_led_hdd1_red>;
pinctrl-names = "default";
- green-sys {
+ led-green-sys {
label = "nsa320:green:sys";
gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
};
- orange-sys {
+ led-orange-sys {
label = "nsa320:orange:sys";
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
- green-hdd1 {
+ led-green-hdd1 {
label = "nsa320:green:hdd1";
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
- red-hdd1 {
+ led-red-hdd1 {
label = "nsa320:red:hdd1";
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- green-hdd2 {
+ led-green-hdd2 {
label = "nsa320:green:hdd2";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
- red-hdd2 {
+ led-red-hdd2 {
label = "nsa320:red:hdd2";
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
};
- green-usb {
+ led-green-usb {
label = "nsa320:green:usb";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
- green-copy {
+ led-green-copy {
label = "nsa320:green:copy";
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
- red-copy {
+ led-red-copy {
label = "nsa320:red:copy";
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-nsa325.dts b/arch/arm/boot/dts/marvell/kirkwood-nsa325.dts
index 371456de34b2..f0786a5f2ce6 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-nsa325.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-nsa325.dts
@@ -162,39 +162,39 @@
&pmx_led_hdd1_green &pmx_led_hdd1_red>;
pinctrl-names = "default";
- green-sys {
+ led-green-sys {
label = "nsa325:green:sys";
gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
};
- orange-sys {
+ led-orange-sys {
label = "nsa325:orange:sys";
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
- green-hdd1 {
+ led-green-hdd1 {
label = "nsa325:green:hdd1";
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
- red-hdd1 {
+ led-red-hdd1 {
label = "nsa325:red:hdd1";
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- green-hdd2 {
+ led-green-hdd2 {
label = "nsa325:green:hdd2";
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
- red-hdd2 {
+ led-red-hdd2 {
label = "nsa325:red:hdd2";
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
};
- green-usb {
+ led-green-usb {
label = "nsa325:green:usb";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
- green-copy {
+ led-green-copy {
label = "nsa325:green:copy";
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
- red-copy {
+ led-red-copy {
label = "nsa325:red:copy";
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-nsa3x0-common.dtsi b/arch/arm/boot/dts/marvell/kirkwood-nsa3x0-common.dtsi
index ea3d36512e9f..e9bd9c551af5 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-nsa3x0-common.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-nsa3x0-common.dtsi
@@ -63,22 +63,20 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_btn_reset &pmx_btn_copy &pmx_btn_power>;
pinctrl-names = "default";
- power {
+ button-power {
label = "Power Button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
- copy {
+ button-copy {
label = "Copy Button";
linux,code = <KEY_COPY>;
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/marvell/kirkwood-openblocks_a6.dts
index 8ea430168ea5..20c6290d2037 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-openblocks_a6.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-openblocks_a6.dts
@@ -115,10 +115,8 @@
compatible = "gpio-keys";
pinctrl-0 = <&pmx_gpio_init>;
pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- power {
+ button-power {
label = "Init Button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/marvell/kirkwood-openblocks_a7.dts
index 946f0f453dd1..9c438f10f737 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-openblocks_a7.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-openblocks_a7.dts
@@ -136,8 +136,6 @@
compatible = "gpio-keys";
pinctrl-0 = <&pmx_gpio_init>;
pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
button {
label = "Init Button";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-pogo_e02.dts b/arch/arm/boot/dts/marvell/kirkwood-pogo_e02.dts
index f9e95e55f36d..39a5345332da 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-pogo_e02.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-pogo_e02.dts
@@ -33,12 +33,12 @@
gpio-leds {
compatible = "gpio-leds";
- health {
+ led-health {
label = "pogo_e02:green:health";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- fault {
+ led-fault {
label = "pogo_e02:orange:fault";
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-pogoplug-series-4.dts b/arch/arm/boot/dts/marvell/kirkwood-pogoplug-series-4.dts
index 5aa4669ae254..0e9c4cf79822 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-pogoplug-series-4.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-pogoplug-series-4.dts
@@ -29,12 +29,10 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_eject>;
pinctrl-names = "default";
- eject {
+ button-eject {
debounce-interval = <50>;
wakeup-source;
linux,code = <KEY_EJECTCD>;
@@ -48,12 +46,12 @@
pinctrl-0 = <&pmx_led_green &pmx_led_red>;
pinctrl-names = "default";
- health {
+ led-health {
label = "pogoplugv4:green:health";
gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- fault {
+ led-fault {
label = "pogoplugv4:red:fault";
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-sheevaplug-esata.dts b/arch/arm/boot/dts/marvell/kirkwood-sheevaplug-esata.dts
index ae8f493c9a0f..eb185273376e 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-sheevaplug-esata.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-sheevaplug-esata.dts
@@ -33,7 +33,7 @@
pinctrl-0 = <&pmx_led_blue>;
pinctrl-names = "default";
- health {
+ led-health {
label = "sheevaplug:blue:health";
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
default-state = "keep";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-sheevaplug.dts b/arch/arm/boot/dts/marvell/kirkwood-sheevaplug.dts
index c73cc904e5c4..ce73fcf2255f 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-sheevaplug.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-sheevaplug.dts
@@ -28,13 +28,13 @@
pinctrl-0 = <&pmx_led_blue &pmx_led_red>;
pinctrl-names = "default";
- health {
+ led-health {
label = "sheevaplug:blue:health";
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- misc {
+ led-misc {
label = "sheevaplug:red:misc";
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi b/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi
index 20964eb48fd7..6b7c5218b1fb 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi
@@ -410,7 +410,7 @@
pinctrl-0 = <&pmx_alarmled_12>;
pinctrl-names = "default";
- hdd1-green {
+ led-hdd1-green {
label = "synology:alarm";
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
@@ -424,42 +424,42 @@
&pmx_hddled_26 &pmx_hddled_27>;
pinctrl-names = "default";
- hdd1-green {
+ led-hdd1-green {
label = "synology:green:hdd1";
gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
};
- hdd1-amber {
+ led-hdd1-amber {
label = "synology:amber:hdd1";
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
- hdd2-green {
+ led-hdd2-green {
label = "synology:green:hdd2";
gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
};
- hdd2-amber {
+ led-hdd2-amber {
label = "synology:amber:hdd2";
gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
};
- hdd3-green {
+ led-hdd3-green {
label = "synology:green:hdd3";
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
};
- hdd3-amber {
+ led-hdd3-amber {
label = "synology:amber:hdd3";
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
- hdd4-green {
+ led-hdd4-green {
label = "synology:green:hdd4";
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
};
- hdd4-amber {
+ led-hdd4-amber {
label = "synology:amber:hdd4";
gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
};
@@ -471,12 +471,12 @@
pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23>;
pinctrl-names = "default";
- hdd1-green {
+ led-hdd1-green {
label = "synology:green:hdd1";
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
- hdd1-amber {
+ led-hdd1-amber {
label = "synology:amber:hdd1";
gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
};
@@ -488,22 +488,22 @@
pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23 &pmx_hddled_20 &pmx_hddled_22>;
pinctrl-names = "default";
- hdd1-green {
+ led-hdd1-green {
label = "synology:green:hdd1";
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
- hdd1-amber {
+ led-hdd1-amber {
label = "synology:amber:hdd1";
gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
};
- hdd2-green {
+ led-hdd2-green {
label = "synology:green:hdd2";
gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
};
- hdd2-amber {
+ led-hdd2-amber {
label = "synology:amber:hdd2";
gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
};
@@ -518,52 +518,52 @@
&pmx_hddled_45>;
pinctrl-names = "default";
- hdd1-green {
+ led-hdd1-green {
label = "synology:green:hdd1";
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
- hdd1-amber {
+ led-hdd1-amber {
label = "synology:amber:hdd1";
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
- hdd2-green {
+ led-hdd2-green {
label = "synology:green:hdd2";
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
};
- hdd2-amber {
+ led-hdd2-amber {
label = "synology:amber:hdd2";
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
};
- hdd3-green {
+ led-hdd3-green {
label = "synology:green:hdd3";
gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
};
- hdd3-amber {
+ led-hdd3-amber {
label = "synology:amber:hdd3";
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
- hdd4-green {
+ led-hdd4-green {
label = "synology:green:hdd4";
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
- hdd4-amber {
+ led-hdd4-amber {
label = "synology:amber:hdd4";
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
- hdd5-green {
+ led-hdd5-green {
label = "synology:green:hdd5";
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
};
- hdd5-amber {
+ led-hdd5-amber {
label = "synology:amber:hdd5";
gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
};
@@ -575,22 +575,22 @@
pinctrl-0 = <&pmx_hddled_38 &pmx_hddled_39 &pmx_hddled_36 &pmx_hddled_37>;
pinctrl-names = "default";
- hdd1-green {
+ led-hdd1-green {
label = "synology:green:hdd1";
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
};
- hdd1-amber {
+ led-hdd1-amber {
label = "synology:amber:hdd1";
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
};
- hdd2-green {
+ led-hdd2-green {
label = "synology:green:hdd2";
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
- hdd2-amber {
+ led-hdd2-amber {
label = "synology:amber:hdd2";
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/kirkwood-t5325.dts b/arch/arm/boot/dts/marvell/kirkwood-t5325.dts
index ad093324e075..a6e77a487d00 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-t5325.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-t5325.dts
@@ -156,12 +156,10 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_power>;
pinctrl-names = "default";
- power {
+ button-power {
label = "Power Button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/marvell/kirkwood-ts219-6281.dts
index 30892c19aceb..a2e0ad4b84d8 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-ts219-6281.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-ts219-6281.dts
@@ -35,17 +35,15 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
pinctrl-names = "default";
- copy {
+ button-copy {
label = "USB Copy";
linux,code = <KEY_COPY>;
gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/marvell/kirkwood-ts219-6282.dts
index aba1205981f1..35be6bce1dba 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-ts219-6282.dts
+++ b/arch/arm/boot/dts/marvell/kirkwood-ts219-6282.dts
@@ -35,17 +35,15 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
pinctrl-names = "default";
- copy {
+ button-copy {
label = "USB Copy";
linux,code = <KEY_COPY>;
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/kirkwood-ts419.dtsi b/arch/arm/boot/dts/marvell/kirkwood-ts419.dtsi
index 717236853e45..f136059607b7 100644
--- a/arch/arm/boot/dts/marvell/kirkwood-ts419.dtsi
+++ b/arch/arm/boot/dts/marvell/kirkwood-ts419.dtsi
@@ -36,17 +36,15 @@
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
pinctrl-names = "default";
- copy {
+ button-copy {
label = "USB Copy";
linux,code = <KEY_COPY>;
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
- reset {
+ button-reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/mvebu-linkstation-gpio-simple.dtsi b/arch/arm/boot/dts/marvell/mvebu-linkstation-gpio-simple.dtsi
index c2d87ba6190a..055ac754c5fd 100644
--- a/arch/arm/boot/dts/marvell/mvebu-linkstation-gpio-simple.dtsi
+++ b/arch/arm/boot/dts/marvell/mvebu-linkstation-gpio-simple.dtsi
@@ -48,8 +48,6 @@
/ {
gpio_keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_power_switch>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/marvell/orion5x-lacie-d2-network.dts b/arch/arm/boot/dts/marvell/orion5x-lacie-d2-network.dts
index 03471d30bfd9..12a4aac2633e 100644
--- a/arch/arm/boot/dts/marvell/orion5x-lacie-d2-network.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-lacie-d2-network.dts
@@ -35,22 +35,21 @@
compatible = "gpio-keys";
pinctrl-0 = <&pmx_buttons>;
pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- front_button {
+
+ button-front {
label = "Front Push Button";
linux,code = <KEY_POWER>;
gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
};
- power_rocker_sw_on {
+ switch-power-rocker-sw-on {
label = "Power rocker switch (on|auto)";
linux,input-type = <5>; /* EV_SW */
linux,code = <1>; /* D2NET_SWITCH_POWER_ON */
gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
};
- power_rocker_sw_off {
+ switch-power-rocker-sw-off {
label = "Power rocker switch (auto|off)";
linux,input-type = <5>; /* EV_SW */
linux,code = <2>; /* D2NET_SWITCH_POWER_OFF */
diff --git a/arch/arm/boot/dts/marvell/orion5x-lacie-ethernet-disk-mini-v2.dts b/arch/arm/boot/dts/marvell/orion5x-lacie-ethernet-disk-mini-v2.dts
index f17e25ac98dd..f81acb9b7223 100644
--- a/arch/arm/boot/dts/marvell/orion5x-lacie-ethernet-disk-mini-v2.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-lacie-ethernet-disk-mini-v2.dts
@@ -39,9 +39,8 @@
compatible = "gpio-keys";
pinctrl-0 = <&pmx_power_button>;
pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- button@1 {
+
+ button-1 {
label = "Power-on Switch";
linux,code = <KEY_POWER>;
gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
@@ -53,7 +52,7 @@
pinctrl-0 = <&pmx_power_led>;
pinctrl-names = "default";
- led@1 {
+ led-1 {
label = "power:blue";
gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/orion5x-linkstation-lschl.dts b/arch/arm/boot/dts/marvell/orion5x-linkstation-lschl.dts
index ee751995c8d0..79fee048c900 100644
--- a/arch/arm/boot/dts/marvell/orion5x-linkstation-lschl.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-linkstation-lschl.dts
@@ -61,7 +61,7 @@
};
gpio_keys {
- func {
+ func-button {
label = "Function Button";
linux,code = <KEY_OPTION>;
gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
@@ -90,7 +90,7 @@
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
};
- func {
+ func-led {
label = "lschl:func:blue:top";
gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/marvell/orion5x-lswsgl.dts b/arch/arm/boot/dts/marvell/orion5x-lswsgl.dts
index 2fbc17d6dfa4..e0da406c430f 100644
--- a/arch/arm/boot/dts/marvell/orion5x-lswsgl.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-lswsgl.dts
@@ -74,22 +74,21 @@
compatible = "gpio-keys";
pinctrl-0 = <&pmx_buttons>;
pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- func {
+
+ key-func {
label = "Function Button";
linux,code = <KEY_OPTION>;
gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
};
- power {
+ key-power {
label = "Power-on Switch";
linux,input-type = <5>; /* EV_SW */
linux,code = <KEY_RESERVED>; /* LSMINI_SW_POWER */
gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
};
- autopower {
+ key-autopower {
label = "Power-auto Switch";
linux,input-type = <5>; /* EV_SW */
linux,code = <KEY_ESC>; /* LSMINI_SW_AUTOPOWER */
@@ -103,24 +102,24 @@
&pmx_led_power>;
pinctrl-names = "default";
- alarm {
+ led-alarm {
label = "lswsgl:alarm:red";
- gpio = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
};
- info {
+ led-info {
label = "lswsgl:info:amber";
- gpio = <&gpio0 3 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
};
- func {
+ led-func {
label = "lswsgl:func:blue:top";
- gpio = <&gpio0 9 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
};
- power {
+ led-power {
label = "lswsgl:power:blue:bottom";
- gpio = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
default-state = "on";
};
};
diff --git a/arch/arm/boot/dts/marvell/orion5x-maxtor-shared-storage-2.dts b/arch/arm/boot/dts/marvell/orion5x-maxtor-shared-storage-2.dts
index d57859998350..cb1bd24b7ae3 100644
--- a/arch/arm/boot/dts/marvell/orion5x-maxtor-shared-storage-2.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-maxtor-shared-storage-2.dts
@@ -35,15 +35,14 @@
compatible = "gpio-keys";
pinctrl-0 = <&pmx_buttons>;
pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- power {
+
+ key-power {
label = "Power";
linux,code = <KEY_POWER>;
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
};
- reset {
+ key-reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/orion5x-netgear-wnr854t.dts b/arch/arm/boot/dts/marvell/orion5x-netgear-wnr854t.dts
index fb203e7d37f5..d63ea15539aa 100644
--- a/arch/arm/boot/dts/marvell/orion5x-netgear-wnr854t.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-netgear-wnr854t.dts
@@ -35,7 +35,7 @@
pinctrl-0 = <&pmx_reset_button>;
pinctrl-names = "default";
- reset {
+ key-reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts b/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts
index fd78aa02a3c5..75ab913b21e5 100644
--- a/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts
+++ b/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts
@@ -32,7 +32,7 @@
pinctrl-0 = <&pmx_debug_led>;
pinctrl-names = "default";
- led@0 {
+ led-0 {
label = "rd88f5182:cpu";
linux,default-trigger = "heartbeat";
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/mediatek/mt2701-evb.dts b/arch/arm/boot/dts/mediatek/mt2701-evb.dts
index 9c7325f18933..4c76366aa938 100644
--- a/arch/arm/boot/dts/mediatek/mt2701-evb.dts
+++ b/arch/arm/boot/dts/mediatek/mt2701-evb.dts
@@ -231,7 +231,7 @@
<MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
<MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
<MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-up;
};
};
diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi
index f0b4a09004b3..814586abc297 100644
--- a/arch/arm/boot/dts/mediatek/mt7623.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi
@@ -1143,13 +1143,13 @@
<MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>,
<MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_2mA>;
+ drive-strength = <2>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins-clk {
pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_2mA>;
+ drive-strength = <2>;
bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
};
@@ -1167,14 +1167,14 @@
<MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>,
<MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
};
pins-clk {
pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
bias-pull-down;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
};
pins-wp {
@@ -1197,13 +1197,13 @@
<MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>,
<MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
};
pins-clk {
pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
};
@@ -1211,7 +1211,7 @@
nand_pins_default: nanddefault {
pins-ale {
pinmux = <MT7623_PIN_116_MSDC0_CMD_FUNC_NALE>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -1226,13 +1226,13 @@
<MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8>,
<MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up;
};
pins-we {
pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
};
};
diff --git a/arch/arm/boot/dts/nspire/nspire-classic.dtsi b/arch/arm/boot/dts/nspire/nspire-classic.dtsi
index a6e9cbf51524..0ee53d3ecd54 100644
--- a/arch/arm/boot/dts/nspire/nspire-classic.dtsi
+++ b/arch/arm/boot/dts/nspire/nspire-classic.dtsi
@@ -55,7 +55,7 @@
};
/ {
- memory {
+ memory@10000000 {
device_type = "memory";
reg = <0x10000000 0x2000000>; /* 32 MB */
};
diff --git a/arch/arm/boot/dts/nspire/nspire-cx.dts b/arch/arm/boot/dts/nspire/nspire-cx.dts
index 29f0181e5b38..debeff0ec010 100644
--- a/arch/arm/boot/dts/nspire/nspire-cx.dts
+++ b/arch/arm/boot/dts/nspire/nspire-cx.dts
@@ -122,7 +122,7 @@
model = "TI-NSPIRE CX";
compatible = "ti,nspire-cx";
- memory {
+ memory@10000000 {
device_type = "memory";
reg = <0x10000000 0x4000000>; /* 64 MB */
};
diff --git a/arch/arm/boot/dts/nspire/nspire.dtsi b/arch/arm/boot/dts/nspire/nspire.dtsi
index d56fef7250db..95588b716c6f 100644
--- a/arch/arm/boot/dts/nspire/nspire.dtsi
+++ b/arch/arm/boot/dts/nspire/nspire.dtsi
@@ -170,9 +170,12 @@
};
watchdog: watchdog@90060000 {
- compatible = "arm,primecell";
+ compatible = "arm,sp805", "arm,primecell";
reg = <0x90060000 0x1000>;
interrupts = <3>;
+ clocks = <&apb_pclk>, <&apb_pclk>;
+ clock-names = "wdog_clk", "apb_pclk";
+ status = "disabled";
};
rtc: rtc@90090000 {
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts
index 5787ae95d3b4..1f07ba382910 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts
@@ -525,7 +525,7 @@
};
};
- i2c-bus@4 {
+ i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
@@ -537,7 +537,7 @@
};
};
- i2c-bus@5 {
+ i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
@@ -549,7 +549,7 @@
};
};
- i2c-bus@6 {
+ i2c@6 {
#address-cells = <1>;
#size-cells = <0>;
reg = <6>;
@@ -561,7 +561,7 @@
};
};
- i2c-bus@7 {
+ i2c@7 {
#address-cells = <1>;
#size-cells = <0>;
reg = <7>;
@@ -580,7 +580,7 @@
reg = <0x77>;
i2c-mux-idle-disconnect;
- i2c-bus@2 {
+ i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
@@ -620,7 +620,7 @@
reg = <0x77>;
i2c-mux-idle-disconnect;
- i2c-bus@0 {
+ i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
@@ -632,7 +632,7 @@
};
};
- i2c-bus@1 {
+ i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
@@ -691,7 +691,7 @@
reg = <0x77>;
i2c-mux-idle-disconnect;
- i2c-bus@3 {
+ i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
@@ -703,7 +703,7 @@
};
};
- i2c-bus@4 {
+ i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
@@ -715,7 +715,7 @@
};
};
- i2c-bus@5 {
+ i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
@@ -726,7 +726,7 @@
reg = <0x28>;
};
};
- i2c-bus@6 {
+ i2c@6 {
#address-cells = <1>;
#size-cells = <0>;
reg = <6>;
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts
index baa39d0c1032..087f4ac43187 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts
@@ -215,43 +215,43 @@
reg = <0x70>;
i2c-mux-idle-disconnect;
- i2c_slot1a: i2c-bus@0 {
+ i2c_slot1a: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
};
- i2c_slot1b: i2c-bus@1 {
+ i2c_slot1b: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
- i2c_slot2a: i2c-bus@2 {
+ i2c_slot2a: i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
};
- i2c_slot2b: i2c-bus@3 {
+ i2c_slot2b: i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
};
- i2c_slot3: i2c-bus@4 {
+ i2c_slot3: i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
};
- i2c_slot4: i2c-bus@5 {
+ i2c_slot4: i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
};
- i2c_slot5: i2c-bus@6 {
+ i2c_slot5: i2c@6 {
#address-cells = <1>;
#size-cells = <0>;
reg = <6>;
@@ -265,24 +265,24 @@
#size-cells = <0>;
i2c-mux-idle-disconnect;
- i2c_m2_s1: i2c-bus@0 {
+ i2c_m2_s1: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
};
- i2c_m2_s2: i2c-bus@1 {
+ i2c_m2_s2: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
- i2c_m2_s3: i2c-bus@2 {
+ i2c_m2_s3: i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
};
- i2c_m2_s4: i2c-bus@3 {
+ i2c_m2_s4: i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
diff --git a/arch/arm/boot/dts/nvidia/tegra20-colibri.dtsi b/arch/arm/boot/dts/nvidia/tegra20-colibri.dtsi
index 8c1d5c9fa483..2ff7be8f1382 100644
--- a/arch/arm/boot/dts/nvidia/tegra20-colibri.dtsi
+++ b/arch/arm/boot/dts/nvidia/tegra20-colibri.dtsi
@@ -445,9 +445,9 @@
tegra_ac97: ac97@70002000 {
status = "okay";
- nvidia,codec-reset-gpio =
+ nvidia,codec-reset-gpios =
<&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>;
- nvidia,codec-sync-gpio =
+ nvidia,codec-sync-gpios =
<&gpio TEGRA_GPIO(P, 0) GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/nvidia/tegra20-paz00.dts b/arch/arm/boot/dts/nvidia/tegra20-paz00.dts
index afb922bd79a7..1408e1e00759 100644
--- a/arch/arm/boot/dts/nvidia/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/nvidia/tegra20-paz00.dts
@@ -533,6 +533,49 @@
0x00000000 0x00000000 0x00000000 0x00000000>;
};
};
+
+ emc-tables@1 {
+ nvidia,ram-code = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ emc-table@166500 {
+ reg = <166500>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <166500>;
+ nvidia,emc-registers = <0x0000000a 0x00000016
+ 0x00000008 0x00000003 0x00000004 0x00000004
+ 0x00000002 0x0000000c 0x00000003 0x00000003
+ 0x00000002 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x000004df
+ 0x00000000 0x00000003 0x00000003 0x00000003
+ 0x00000003 0x00000001 0x0000000a 0x000000c8
+ 0x00000003 0x00000006 0x00000004 0x00000008
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xe03b0323
+ 0x007fe010 0x00001414 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+
+ emc-table@333000 {
+ reg = <333000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <333000>;
+ nvidia,emc-registers = <0x00000018 0x00000033
+ 0x00000012 0x00000004 0x00000004 0x00000005
+ 0x00000003 0x0000000c 0x00000006 0x00000006
+ 0x00000003 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x00000bff
+ 0x00000000 0x00000003 0x00000003 0x00000006
+ 0x00000006 0x00000001 0x00000011 0x000000c8
+ 0x00000003 0x0000000e 0x00000007 0x00000008
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xf0440303
+ 0x007fe010 0x00001414 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+ };
};
usb@c5000000 {
diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index 4052cad859fa..92e291603ea1 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -99,6 +99,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-icore.dtb \
imx6dl-icore-mipi.dtb \
imx6dl-icore-rqs.dtb \
+ imx6dl-kontron-samx6i-ads2.dtb \
imx6dl-lanmcu.dtb \
imx6dl-mamoj.dtb \
imx6dl-mba6a.dtb \
@@ -207,6 +208,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-icore-ofcap10.dtb \
imx6q-icore-ofcap12.dtb \
imx6q-icore-rqs.dtb \
+ imx6q-kontron-samx6i-ads2.dtb \
imx6q-kp-tpc.dtb \
imx6q-logicpd.dtb \
imx6q-marsboard.dtb \
@@ -349,12 +351,15 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ull-phytec-segin-lc-rdk-nand.dtb \
imx6ull-phytec-tauri-emmc.dtb \
imx6ull-phytec-tauri-nand.dtb \
+ imx6ull-seeed-npi-dev-board-emmc.dtb \
+ imx6ull-seeed-npi-dev-board-nand.dtb \
imx6ull-tarragon-master.dtb \
imx6ull-tarragon-micro.dtb \
imx6ull-tarragon-slave.dtb \
imx6ull-tarragon-slavext.dtb \
imx6ull-tqma6ull2-mba6ulx.dtb \
imx6ull-tqma6ull2l-mba6ulx.dtb \
+ imx6ull-uti260b.dtb \
imx6ulz-14x14-evk.dtb \
imx6ulz-bsh-smm-m2.dtb
dtb-$(CONFIG_SOC_IMX7D) += \
diff --git a/arch/arm/boot/dts/nxp/imx/e60k02.dtsi b/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
index dd03e3860f97..0029c12f16c8 100644
--- a/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
@@ -14,6 +14,10 @@
#include <dt-bindings/input/input.h>
/ {
+ aliases {
+ mmc0 = &usdhc2;
+ mmc1 = &usdhc3;
+ };
chosen {
stdout-path = &uart1;
@@ -127,7 +131,7 @@
compatible = "ricoh,rc5t619";
reg = <0x32>;
interrupt-parent = <&gpio5>;
- interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
system-power-controller;
regulators {
diff --git a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
index 4e1bf080eaca..dcc3c9d488a8 100644
--- a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
@@ -145,7 +145,7 @@
compatible = "ricoh,rc5t619";
reg = <0x32>;
interrupt-parent = <&gpio4>;
- interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
system-power-controller;
regulators {
diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
index abc9233c5a1b..31b3fc972abb 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
@@ -15,6 +15,22 @@
device_type = "memory";
reg = <0xa0000000 0x08000000>; /* 128MB */
};
+
+ usbotgphy: usbotgphy {
+ compatible = "usb-nop-xceiv";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotgphy>;
+ reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>;
+ #phy-cells = <0>;
+ };
+
+ usbh2phy: usbh2phy {
+ compatible = "usb-nop-xceiv";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh2phy>;
+ reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+ #phy-cells = <0>;
+ };
};
&cspi1 {
@@ -84,6 +100,52 @@
MX27_PAD_NFWE_B__NFWE_B 0x0
>;
};
+
+ pinctrl_usbotgphy: usbotgphygrp {
+ fsl,pins = <
+ MX27_PAD_USBH1_RCV__GPIO2_25 0x1 /* reset gpio */
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x0
+ MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x0
+ MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x0
+ MX27_PAD_USBOTG_STP__USBOTG_STP 0x0
+ MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x0
+ MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x0
+ MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x0
+ MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x0
+ MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x0
+ MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x0
+ MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x0
+ MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x0
+ >;
+ };
+
+ pinctrl_usbh2phy: usbh2phygrp {
+ fsl,pins = <
+ MX27_PAD_USBH1_SUSP__GPIO2_22 0x0 /* reset gpio */
+ >;
+ };
+
+ pinctrl_usbh2: usbh2grp {
+ fsl,pins = <
+ MX27_PAD_USBH2_CLK__USBH2_CLK 0x0
+ MX27_PAD_USBH2_DIR__USBH2_DIR 0x0
+ MX27_PAD_USBH2_NXT__USBH2_NXT 0x0
+ MX27_PAD_USBH2_STP__USBH2_STP 0x0
+ MX27_PAD_CSPI2_SCLK__USBH2_DATA0 0x0
+ MX27_PAD_CSPI2_MOSI__USBH2_DATA1 0x0
+ MX27_PAD_CSPI2_MISO__USBH2_DATA2 0x0
+ MX27_PAD_CSPI2_SS1__USBH2_DATA3 0x0
+ MX27_PAD_CSPI2_SS2__USBH2_DATA4 0x0
+ MX27_PAD_CSPI1_SS2__USBH2_DATA5 0x0
+ MX27_PAD_CSPI2_SS0__USBH2_DATA6 0x0
+ MX27_PAD_USBH2_DATA7__USBH2_DATA7 0x0
+ >;
+ };
};
};
@@ -95,3 +157,19 @@
nand-on-flash-bbt;
status = "okay";
};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ phy_type = "ulpi";
+ phys = <&usbotgphy>;
+ status = "okay";
+};
+
+&usbh2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh2>;
+ phy_type = "ulpi";
+ phys = <&usbh2phy>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-apf51dev.dts b/arch/arm/boot/dts/nxp/imx/imx51-apf51dev.dts
index b61d55ca1467..de6b7607510a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-apf51dev.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-apf51dev.dts
@@ -25,8 +25,8 @@
pinctrl-0 = <&pinctrl_ipu_disp1>;
display-timings {
- lw700 {
- native-mode;
+ native-mode = <&timing0>;
+ timing0: timing-lw700 {
clock-frequency = <33000033>;
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-babbage.dts b/arch/arm/boot/dts/nxp/imx/imx51-babbage.dts
index 16ff543f3fbf..f4a47e8348b2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-babbage.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-babbage.dts
@@ -89,7 +89,7 @@
status = "disabled";
display-timings {
native-mode = <&timing1>;
- timing1: claawvga {
+ timing1: timing-claawvga {
clock-frequency = <27000000>;
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-ts4800.dts b/arch/arm/boot/dts/nxp/imx/imx51-ts4800.dts
index f7408722d68a..079bd3d14999 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-ts4800.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-ts4800.dts
@@ -45,7 +45,7 @@
backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 78770>;
+ pwms = <&pwm1 0 78770 0>;
brightness-levels = <0 150 200 255>;
default-brightness-level = <1>;
power-supply = <&backlight_reg>;
@@ -58,8 +58,8 @@
pinctrl-0 = <&pinctrl_lcd>;
display-timings {
- 800x480p60 {
- native-mode;
+ native-mode = <&timing0>;
+ timing0: timing-800x480p60 {
clock-frequency = <30066000>;
hactive = <800>;
vactive = <480>;
@@ -113,7 +113,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm_backlight>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-kp-ddc.dts b/arch/arm/boot/dts/nxp/imx/imx53-kp-ddc.dts
index 0e7f071fd10e..f6f116366643 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-kp-ddc.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-kp-ddc.dts
@@ -13,7 +13,7 @@
backlight_lcd: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm2 0 50000>;
+ pwms = <&pwm2 0 50000 0>;
power-supply = <&reg_backlight>;
brightness-levels = <0 24 28 32 36
40 44 48 52 56
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-kp.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-kp.dtsi
index 4508f34139a0..ae5f87b8612d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-kp.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx53-kp.dtsi
@@ -13,7 +13,7 @@
compatible = "pwm-beeper";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_buzzer>;
- pwms = <&pwm1 0 500000>;
+ pwms = <&pwm1 0 500000 0>;
};
gpio-buttons {
@@ -162,14 +162,6 @@
>;
};
-&pwm1 {
- #pwm-cells = <2>;
-};
-
-&pwm2 {
- #pwm-cells = <2>;
-};
-
&uart1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-m53evk.dts b/arch/arm/boot/dts/nxp/imx/imx53-m53evk.dts
index c323b4dbe9f0..ba0c62994f75 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-m53evk.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-m53evk.dts
@@ -17,8 +17,8 @@
pinctrl-0 = <&pinctrl_ipu_disp1>;
display-timings {
- 800x480p60 {
- native-mode;
+ native-mode = <&timing0>;
+ timing0: timing-800x480p60 {
clock-frequency = <31500000>;
hactive = <800>;
vactive = <480>;
@@ -41,7 +41,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 3000>;
+ pwms = <&pwm1 0 3000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
power-supply = <&reg_backlight>;
@@ -313,7 +313,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-m53menlo.dts b/arch/arm/boot/dts/nxp/imx/imx53-m53menlo.dts
index 4d77b6077fc1..558751e730f3 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-m53menlo.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-m53menlo.dts
@@ -64,6 +64,7 @@
reg = <0>;
lvds_decoder_in: endpoint {
+ data-mapping = "jeida-18";
remote-endpoint = <&lvds0_out>;
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-mba53.dts b/arch/arm/boot/dts/nxp/imx/imx53-mba53.dts
index 6a37616cef1c..2117de872703 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-mba53.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-mba53.dts
@@ -17,7 +17,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm2 0 50000>;
+ pwms = <&pwm2 0 50000 0>;
brightness-levels = <0 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100>;
default-brightness-level = <10>;
enable-gpios = <&gpio7 7 0>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts b/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts
index 70c4a4852256..e939acc1c88b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts
@@ -167,7 +167,7 @@
pwm_bl: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm2 0 50000>;
+ pwms = <&pwm2 0 50000 0>;
brightness-levels = <0 2 5 7 10 12 15 17 20 22 25 28 30 33 35
38 40 43 45 48 51 53 56 58 61 63 66 68 71
73 76 79 81 84 86 89 91 94 96 99 102 104
@@ -187,7 +187,7 @@
led-1 {
label = "alarm-brightness";
- pwms = <&pwm1 0 100000>;
+ pwms = <&pwm1 0 100000 0>;
max-brightness = <255>;
};
};
@@ -628,14 +628,12 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&pwm2 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi
index d80440446473..05d7a462ea25 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi
@@ -85,7 +85,7 @@
};
};
- panel {
+ panel_dpi: panel {
compatible = "sii,43wvf1g";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_display_power>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
index c84e9b052527..151e9cee3c87 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
+++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
@@ -10,8 +10,6 @@
/plugin/;
&{/} {
- /delete-node/ panel;
-
hdmi: connector-hdmi {
compatible = "hdmi-connector";
label = "hdmi";
@@ -82,6 +80,10 @@
};
};
+&panel_dpi {
+ status = "disabled";
+};
+
&tve {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-tqma53.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-tqma53.dtsi
index 294811bfc8d2..b2d7271d1d24 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-tqma53.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx53-tqma53.dtsi
@@ -202,14 +202,6 @@
};
};
-&pwm1 {
- #pwm-cells = <2>;
-};
-
-&pwm2 {
- #pwm-cells = <2>;
-};
-
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-tx53-x03x.dts b/arch/arm/boot/dts/nxp/imx/imx53-tx53-x03x.dts
index a7f77527269d..a02d77bb5672 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-tx53-x03x.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-tx53-x03x.dts
@@ -67,7 +67,7 @@
};
display-timings {
- VGA {
+ timing-vga {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -83,7 +83,7 @@
pixelclk-active = <0>;
};
- ETV570 {
+ timing-etc570 {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -99,7 +99,7 @@
pixelclk-active = <0>;
};
- ET0350 {
+ timing-et0350 {
clock-frequency = <6413760>;
hactive = <320>;
vactive = <240>;
@@ -115,7 +115,7 @@
pixelclk-active = <0>;
};
- ET0430 {
+ timing-et0430 {
clock-frequency = <9009000>;
hactive = <480>;
vactive = <272>;
@@ -131,7 +131,7 @@
pixelclk-active = <1>;
};
- ET0500 {
+ timing-et0500 {
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -147,7 +147,7 @@
pixelclk-active = <0>;
};
- ET0700 { /* same as ET0500 */
+ timing-et0700 { /* same as ET0500 */
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -163,7 +163,7 @@
pixelclk-active = <0>;
};
- ETQ570 {
+ timing-etq570 {
clock-frequency = <6596040>;
hactive = <320>;
vactive = <240>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-tx53-x13x.dts b/arch/arm/boot/dts/nxp/imx/imx53-tx53-x13x.dts
index 6cdf2082c742..e10c179dbdb3 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53-tx53-x13x.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx53-tx53-x13x.dts
@@ -191,7 +191,7 @@
display-timings {
native-mode = <&lvds0_timing0>;
- lvds0_timing0: hsd100pxn1 {
+ lvds0_timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -207,7 +207,7 @@
pixelclk-active = <1>;
};
- lvds0_timing1: nl12880bc20 {
+ lvds0_timing1: timing-nl12880bc20 {
clock-frequency = <71000000>;
hactive = <1280>;
vactive = <800>;
@@ -233,7 +233,7 @@
display-timings {
native-mode = <&lvds1_timing0>;
- lvds1_timing0: hsd100pxn1 {
+ lvds1_timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_4.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_4.dts
index dfa6f64d43cc..c9b2ea2b24b2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_4.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_4.dts
@@ -82,11 +82,10 @@
compatible = "lg,lg4573";
spi-max-frequency = <10000000>;
reg = <0>;
- power-on-delay = <10>;
display-timings {
- 480x800p57 {
- native-mode;
+ native-mode = <&timing0>;
+ timing0: timing-480x800p57 {
clock-frequency = <27000027>;
hactive = <480>;
vactive = <800>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_4.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_4.dts
index cc861a43eb58..9ec038f1d0ff 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_4.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_4.dts
@@ -14,7 +14,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
enable-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
@@ -36,8 +36,8 @@
status = "okay";
display-timings {
- 480x800p60 {
- native-mode;
+ native-mode = <&timing0>;
+ timing0: timing-480x800p60 {
clock-frequency = <30000000>;
hactive = <480>;
vactive = <800>;
@@ -79,6 +79,5 @@
};
&pwm1 {
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_7.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_7.dts
index b6cb78870cd5..b3129832f471 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_7.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_7.dts
@@ -25,8 +25,8 @@
status = "okay";
display-timings {
- 800x480p60 {
- native-mode;
+ native-mode = <&timing0>;
+ timing0: timing-800x480p60 {
clock-frequency = <33246000>;
hactive = <800>;
vactive = <480>;
@@ -49,7 +49,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 3000>;
+ pwms = <&pwm3 0 3000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
pinctrl-names = "default";
@@ -69,6 +69,5 @@
};
&pwm3 {
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i-ads2.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i-ads2.dts
new file mode 100644
index 000000000000..6a0c53f23a15
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i-ads2.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-kontron-samx6i.dtsi"
+#include "imx6qdl-kontron-samx6i-ads2.dtsi"
+
+/ {
+ model = "Kontron SMARC-sAMX6i Dual-Lite/Solo on SMARC Eval 2.0 carrier";
+ compatible = "kontron,imx6dl-samx6i-ads2", "kontron,imx6dl-samx6i", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i.dtsi
index a864fdbd5f16..5a9b819d7ee8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-kontron-samx6i.dtsi
@@ -7,6 +7,6 @@
#include "imx6qdl-kontron-samx6i.dtsi"
/ {
- model = "Kontron SMARC sAMX6i Dual-Lite/Solo";
+ model = "Kontron SMARC-sAMX6i Dual-Lite/Solo";
compatible = "kontron,imx6dl-samx6i", "fsl,imx6dl";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts
index 028951955bde..72ee236d2f5e 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts
@@ -21,7 +21,7 @@
backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 25000>; /* 25000ns -> 40kHz */
+ pwms = <&pwm3 0 25000 0>; /* 25000ns -> 40kHz */
brightness-levels = <0 4 8 16 32 64 128 160 192 224 255>;
default-brightness-level = <7>;
};
@@ -303,7 +303,6 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi
index f266f1b7e0cf..09d9ca0cb332 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi
@@ -55,7 +55,7 @@
compatible = "pwm-backlight";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_display>;
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = < 0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
@@ -349,7 +349,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts b/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts
index 02648806c275..d3f14b4d3b51 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts
@@ -36,7 +36,7 @@
backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 200000>;
+ pwms = <&pwm1 0 200000 0>;
brightness-levels = <0 61 499 1706 4079 8022 13938 22237 33328 47623 65535>;
num-interpolated-steps = <10>;
default-brightness-level = <60>;
@@ -117,14 +117,14 @@
color = <LED_COLOR_ID_RED>;
max-brightness = <248>;
default-state = "off";
- pwms = <&pwm2 0 500000>;
+ pwms = <&pwm2 0 500000 0>;
};
led_white: led-1 {
color = <LED_COLOR_ID_WHITE>;
max-brightness = <248>;
default-state = "off";
- pwms = <&pwm3 0 500000>;
+ pwms = <&pwm3 0 500000 0>;
linux,default-trigger = "heartbeat";
};
};
@@ -484,28 +484,24 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&pwm2 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
status = "okay";
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i-ads2.dts b/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i-ads2.dts
new file mode 100644
index 000000000000..94c395cc020e
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i-ads2.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-kontron-samx6i.dtsi"
+#include "imx6qdl-kontron-samx6i-ads2.dtsi"
+
+/ {
+ model = "Kontron SMARC-sAMX6i Quad/Dual on SMARC Eval 2.0 carrier";
+ compatible = "kontron,imx6q-samx6i-ads2", "kontron,imx6q-samx6i", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi
index 4d6a0c3e8455..e76963436079 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi
@@ -5,31 +5,8 @@
#include "imx6q.dtsi"
#include "imx6qdl-kontron-samx6i.dtsi"
-#include <dt-bindings/gpio/gpio.h>
/ {
- model = "Kontron SMARC sAMX6i Quad/Dual";
+ model = "Kontron SMARC-sAMX6i Quad/Dual";
compatible = "kontron,imx6q-samx6i", "fsl,imx6q";
};
-
-/* Quad/Dual SoMs have 3 chip-select signals */
-&ecspi4 {
- cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>,
- <&gpio3 29 GPIO_ACTIVE_LOW>,
- <&gpio3 25 GPIO_ACTIVE_LOW>;
-};
-
-&pinctrl_ecspi4 {
- fsl,pins = <
- MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x100b1
- MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x100b1
- MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1
-
- /* SPI4_IMX_CS2# - connected to internal flash */
- MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0
- /* SPI4_IMX_CS0# - connected to SMARC SPI0_CS0# */
- MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
- /* SPI4_CS3# - connected to SMARC SPI0_CS1# */
- MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0
- >;
-};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-kp.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-kp.dtsi
index 091903f53a56..c425d427663d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-kp.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-kp.dtsi
@@ -15,7 +15,7 @@
/ {
backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 255>;
num-interpolated-steps = <255>;
default-brightness-level = <250>;
@@ -23,7 +23,7 @@
beeper {
compatible = "pwm-beeper";
- pwms = <&pwm2 0 500000>;
+ pwms = <&pwm2 0 500000 0>;
};
lcd_display: display {
@@ -378,14 +378,12 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&pwm2 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts b/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts
index a7d5a68110fc..d392b5bd2eea 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts
@@ -67,7 +67,7 @@
backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 10000000>;
+ pwms = <&pwm1 0 10000000 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_backlight_novena>;
power-supply = <&reg_lvds_lcd>;
@@ -465,7 +465,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts b/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
index 46c6b96d8073..56b77cc0af2b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
@@ -124,7 +124,7 @@
backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 50000>;
+ pwms = <&pwm1 0 50000 0>;
brightness-levels = <
0 /*1 2 3 4 5 6*/ 7 8 9
10 11 12 13 14 15 16 17 18 19
@@ -571,7 +571,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts b/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
index 3508a2cd928a..a7d5693c5ab7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
@@ -22,7 +22,7 @@
compatible = "pwm-backlight";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_backlight>;
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 16 64 255>;
num-interpolated-steps = <16>;
default-brightness-level = <1>;
@@ -292,7 +292,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-var-dt6customboard.dts b/arch/arm/boot/dts/nxp/imx/imx6q-var-dt6customboard.dts
index 2290c1237634..0225a621ec7a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-var-dt6customboard.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-var-dt6customboard.dts
@@ -18,7 +18,7 @@
backlight_lvds: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm2 0 50000>;
+ pwms = <&pwm2 0 50000 0>;
brightness-levels = <0 4 8 16 32 64 128 248>;
default-brightness-level = <7>;
status = "okay";
@@ -203,7 +203,6 @@
};
&pwm2 {
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
index 338d292553ad..3a46ade3b6bd 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
@@ -13,7 +13,7 @@
backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 191000>;
+ pwms = <&pwm3 0 191000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <0>;
power-supply = <&reg_5v>;
@@ -212,7 +212,6 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-aristainetos2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-aristainetos2.dtsi
index db1bc511e71f..758eaf9d93d2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-aristainetos2.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-aristainetos2.dtsi
@@ -46,7 +46,7 @@
/ {
backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
enable-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
@@ -346,7 +346,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi
index 1e530d892b76..761566ae3cf5 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi
@@ -64,7 +64,7 @@
active-low;
label = "imx6:red:front";
max-brightness = <248>;
- pwms = <&pwm1 0 50000>;
+ pwms = <&pwm1 0 50000 0>;
};
};
@@ -233,7 +233,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi
index 42b2ba23aefc..a308a3584b62 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi
@@ -66,7 +66,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lvds_bl>;
enable-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>;
- pwms = <&pwm1 0 50000>;
+ pwms = <&pwm1 0 50000 0>;
brightness-levels = <
0 4 8 16 32 64 80 96 112
128 144 160 176 250
@@ -78,7 +78,7 @@
pwm_fan: pwm-fan {
compatible = "pwm-fan";
#cooling-cells = <2>;
- pwms = <&pwm4 0 50000>;
+ pwms = <&pwm4 0 50000 0>;
cooling-levels = <0 64 127 191 255>;
status = "disabled";
};
@@ -145,7 +145,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rgb_bl>;
enable-gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
- pwms = <&pwm3 0 5000000>;
+ pwms = <&pwm3 0 5000000 0>;
brightness-levels = <
250 176 160 144 128 112
96 80 64 48 32 16 8 1
@@ -736,17 +736,14 @@
};
&pwm1 {
- #pwm-cells = <2>;
status = "okay";
};
&pwm3 {
- #pwm-cells = <2>;
status = "okay";
};
&pwm4 {
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw52xx.dtsi
index 535679c27d6f..082a2e3a391f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw52xx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw52xx.dtsi
@@ -25,7 +25,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
@@ -485,7 +485,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: hsd100pxn1 {
+ timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -520,7 +520,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw53xx.dtsi
index 3e1c572af582..8ec442038ea0 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw53xx.dtsi
@@ -25,7 +25,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
@@ -482,7 +482,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: hsd100pxn1 {
+ timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -517,7 +517,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw54xx.dtsi
index 0ffa0357a6fa..9df9f79affae 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw54xx.dtsi
@@ -26,7 +26,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
@@ -529,7 +529,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: hsd100pxn1 {
+ timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -570,7 +570,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default", "state_dio";
pinctrl-0 = <&pinctrl_pwm4_backlight>;
pinctrl-1 = <&pinctrl_pwm4_dio>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi
index 46cf4080fec3..7693f92195d5 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi
@@ -66,7 +66,7 @@
backlight-display {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
@@ -584,7 +584,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: hsd100pxn1 {
+ timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -619,7 +619,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi
index a74cde050158..9d0836df0fed 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi
@@ -56,7 +56,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
@@ -486,7 +486,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: g101evn010 {
+ timing0: timing-g101evn010 {
clock-frequency = <68930000>;
hactive = <1280>;
vactive = <800>;
@@ -502,7 +502,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
index 1e723807ab4c..f4cb9e1d34a9 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
@@ -70,7 +70,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
@@ -551,7 +551,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: hsd100pxn1 {
+ timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -586,7 +586,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-icore.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-icore.dtsi
index efe11524b885..9975b6ee433d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-icore.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-icore.dtsi
@@ -20,7 +20,7 @@
backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 100000>;
+ pwms = <&pwm3 0 100000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
@@ -245,7 +245,6 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i-ads2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i-ads2.dtsi
new file mode 100644
index 000000000000..b4a79245b7b6
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i-ads2.dtsi
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree include for the Kontron SMARC-sAMX6i board on a SMARC Eval
+ * 2.0 carrier (ADS2).
+ *
+ */
+
+/ {
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ sound {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Line", "Line Out Jack",
+ "Microphone", "Microphone Jack",
+ "Line", "Line In Jack";
+ simple-audio-card,routing =
+ "Line Out Jack", "LINEOUTR",
+ "Line Out Jack", "LINEOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "IN1L", "Line In Jack",
+ "IN1R", "Line In Jack",
+ "Microphone Jack", "MICBIAS",
+ "IN2L", "Microphone Jack",
+ "IN2R", "Microphone Jack";
+
+ simple-audio-card,cpu {
+ sound-dai = <&ssi1>;
+ };
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&wm8904>;
+ };
+ };
+
+ reg_codec_mic: regulator-codec-mic {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_MIC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reg_codec_1p8v: regulator-codec-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8_S0_CODEC";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&audmux {
+ status = "okay";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&can2 {
+ status = "okay";
+};
+
+&ecspi4 {
+ flash@1 {
+ compatible = "jedec,spi-nor";
+ reg = <1>;
+ spi-max-frequency = <100000000>;
+ m25p,fast-read;
+ };
+};
+
+&fec {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ wm8904: audio-codec@1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ #sound-dai-cells = <0>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "mclk";
+ AVDD-supply = <&reg_codec_1p8v>;
+ CPVDD-supply = <&reg_codec_1p8v>;
+ DBVDD-supply = <&reg_codec_1p8v>;
+ DCVDD-supply = <&reg_codec_1p8v>;
+ MICVDD-supply = <&reg_codec_mic>;
+ };
+};
+
+&i2c3 {
+ eeprom@57 {
+ compatible = "atmel,24c64";
+ reg = <0x57>;
+ pagesize = <32>;
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+};
+
+&usdhc3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi
index 85aeebc9485d..99b5e78458aa 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi
@@ -61,6 +61,18 @@
vin-supply = <&reg_smarc_suppy>;
};
+ reg_sdio: regulator-sdio {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_sdio>;
+ regulator-name = "V_3V3_SD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ off-on-delay-us = <20000>;
+ };
+
reg_smarc_lcdbklt: regulator-smarc-lcdbklt {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -137,7 +149,7 @@
status = "disabled";
};
- i2c_intern: i2c-gpio-intern {
+ i2c_intern: i2c-0 {
compatible = "i2c-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c_gpio_intern>;
@@ -148,7 +160,7 @@
#size-cells = <0>;
};
- i2c_lcd: i2c-gpio-lcd {
+ i2c_lcd: i2c-1 {
compatible = "i2c-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c_gpio_lcd>;
@@ -160,7 +172,7 @@
status = "disabled";
};
- i2c_cam: i2c-gpio-cam {
+ i2c_cam: i2c-2 {
compatible = "i2c-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c_gpio_cam>;
@@ -178,7 +190,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_audmux>;
- audmux_ssi1 {
+ mux-ssi1 {
fsl,audmux-port = <MX51_AUDMUX_PORT1_SSI0>;
fsl,port-config = <
(IMX_AUDMUX_V2_PTCR_TFSEL(MX51_AUDMUX_PORT3) |
@@ -190,7 +202,7 @@
>;
};
- audmux_adu3 {
+ mux-aud3 {
fsl,audmux-port = <MX51_AUDMUX_PORT3>;
fsl,port-config = <
IMX_AUDMUX_V2_PTCR_SYN
@@ -198,7 +210,7 @@
>;
};
- audmux_ssi2 {
+ mux-ssi2 {
fsl,audmux-port = <MX51_AUDMUX_PORT2_SSI1>;
fsl,port-config = <
(IMX_AUDMUX_V2_PTCR_TFSEL(MX51_AUDMUX_PORT4) |
@@ -210,7 +222,7 @@
>;
};
- audmux_adu4 {
+ mux-aud4 {
fsl,audmux-port = <MX51_AUDMUX_PORT4>;
fsl,port-config = <
IMX_AUDMUX_V2_PTCR_SYN
@@ -244,7 +256,8 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi4>;
cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>,
- <&gpio3 29 GPIO_ACTIVE_LOW>;
+ <&gpio3 29 GPIO_ACTIVE_LOW>,
+ <&gpio3 25 GPIO_ACTIVE_LOW>;
status = "okay";
/* default boot source: workaround #1 for errata ERR006282 */
@@ -259,7 +272,7 @@
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-connection-type = "rgmii-id";
phy-handle = <&ethphy>;
mdio {
@@ -269,7 +282,7 @@
ethphy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
- reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
reset-assert-us = <1000>;
};
};
@@ -356,10 +369,6 @@
regulator-always-on;
};
- /*
- * Per schematics, of all VGEN's, only VGEN5 has some
- * usage ... but even that - over DNI resistor
- */
vgen1 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1550000>;
@@ -380,8 +389,7 @@
regulator-max-microvolt = <3300000>;
};
- reg_2p5v_s0: vgen5 {
- regulator-name = "V_2V5_S0";
+ vgen5 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
};
@@ -464,6 +472,8 @@
MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0
/* SPI_IMX_CS0# - connected to SMARC SPI0_CS0# */
MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
+ /* SPI4_CS3# - connected to SMARC SPI0_CS1# */
+ MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0
>;
};
@@ -516,7 +526,7 @@
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
- MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0 /* RST_GBE0_PHY# */
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 /* RST_GBE0_PHY# */
>;
};
@@ -642,6 +652,12 @@
>;
};
+ pinctrl_reg_sdio: reg-sdiogrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0 /* SDIO_PWR_EN */
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
@@ -694,7 +710,6 @@
MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0 /* CD */
MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b0 /* WP */
- MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0 /* PWR_EN */
>;
};
@@ -728,8 +743,7 @@
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
- wake-up-gpio = <&gpio6 18 GPIO_ACTIVE_HIGH>;
- reset-gpio = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+ reset-gpio = <&gpio3 13 GPIO_ACTIVE_LOW>;
};
/* LCD_BKLT_PWM */
@@ -797,12 +811,12 @@
pinctrl-0 = <&pinctrl_usdhc3>;
cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_sdio>;
no-1-8-v;
};
/* SDMMC */
&usdhc4 {
- /* Internal eMMC, optional on some boards */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4>;
bus-width = <8>;
@@ -811,11 +825,13 @@
non-removable;
vmmc-supply = <&reg_3p3v_s0>;
vqmmc-supply = <&reg_1p8v_s0>;
+ status = "okay";
};
&wdog1 {
/* CPLD is feeded by watchdog (hardwired) */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wdog1>;
+ fsl,ext-reset-output;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6.dtsi
index 4d2abcd44eff..60aa1e947f62 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6.dtsi
@@ -298,6 +298,7 @@
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ vdd-supply = <&reg_mba6_3p3v>;
ethernet@1 {
compatible = "usb424,9e00";
@@ -441,8 +442,6 @@
pinctrl_hog: hoggrp {
fsl,pins = <
- MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x0001b099
-
MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x0001b099
MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x0001b099
MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x0001b099
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6a.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6a.dtsi
index 238f3af42822..807f3c95e3ce 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6a.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6a.dtsi
@@ -22,12 +22,16 @@
compatible = "atmel,24c64";
reg = <0x57>;
pagesize = <32>;
- #address-cells = <1>;
- #size-cells = <1>;
vcc-supply = <&reg_mba6_3p3v>;
- mba_mac_address: mac-address@20 {
- reg = <0x20 0x6>;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mba_mac_address: mac-address@20 {
+ reg = <0x20 0x6>;
+ };
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6b.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6b.dtsi
index a587bc88f76f..789733a45b95 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6b.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-mba6b.dtsi
@@ -32,12 +32,16 @@
compatible = "atmel,24c64";
reg = <0x57>;
pagesize = <32>;
- #address-cells = <1>;
- #size-cells = <1>;
vcc-supply = <&reg_mba6_3p3v>;
- mba_mac_address: mac-address@20 {
- reg = <0x20 0x6>;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mba_mac_address: mac-address@20 {
+ reg = <0x20 0x6>;
+ };
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi
index f2542d725ce7..a30cf0d06206 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi
@@ -108,7 +108,7 @@
backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -117,7 +117,7 @@
backlight_lvds0: backlight-lvds0 {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -499,7 +499,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
@@ -512,7 +511,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
index 32a110a35b02..33174febf410 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
@@ -183,7 +183,7 @@
backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -192,7 +192,7 @@
backlight_lvds0: backlight-lvds0 {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -201,7 +201,7 @@
backlight_lvds1: backlight-lvds1 {
compatible = "pwm-backlight";
- pwms = <&pwm2 0 5000000>;
+ pwms = <&pwm2 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -735,14 +735,12 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&pwm2 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
status = "okay";
@@ -755,7 +753,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi
index 414196b75991..8e64314fa8b2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi
@@ -17,7 +17,7 @@
backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -26,7 +26,7 @@
backlight_lvds0: backlight-lvds0 {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -641,7 +641,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
@@ -654,7 +653,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi
index f278b14911ce..121177273dd0 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi
@@ -134,7 +134,7 @@
backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -143,7 +143,7 @@
backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -596,7 +596,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
@@ -609,7 +608,6 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-mira.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-mira.dtsi
index 1ca4d219609f..0b4c09b09c03 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-mira.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-mira.dtsi
@@ -15,7 +15,7 @@
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_backlight>;
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
status = "okay";
};
@@ -224,7 +224,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi
index 68e97180d33e..0a3deaf92eea 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi
@@ -144,8 +144,8 @@
};
sound-spdif {
- compatible = "fsl,imx-audio-spdif",
- "fsl,imx-sabreauto-spdif";
+ compatible = "fsl,imx-sabreauto-spdif",
+ "fsl,imx-audio-spdif";
model = "imx-spdif";
spdif-controller = <&spdif>;
spdif-in;
@@ -153,7 +153,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 5000000>;
+ pwms = <&pwm3 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
@@ -786,7 +786,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: hsd100pxn1 {
+ timing0: timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -802,7 +802,6 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi
index 84c8a9531e18..9c502bf77d0b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi
@@ -99,7 +99,7 @@
#clock-cells = <0>;
clock-frequency = <22000000>;
clock-output-names = "mipi_pwm3";
- pwms = <&pwm3 0 45>; /* 1 / 45 ns = 22 MHz */
+ pwms = <&pwm3 0 45 0>; /* 1 / 45 ns = 22 MHz */
status = "okay";
};
@@ -162,7 +162,7 @@
backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -171,7 +171,7 @@
backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_3p3v>;
@@ -654,21 +654,18 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
index 4fe58764b929..8f4f5fba68cc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
@@ -119,7 +119,7 @@
backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
@@ -755,7 +755,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-savageboard.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-savageboard.dtsi
index 02e6d36e85fa..6823a639ed2f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-savageboard.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-savageboard.dtsi
@@ -83,7 +83,7 @@
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <4>;
power-supply = <&reg_3p3v>;
- pwms = <&pwm1 0 10000>;
+ pwms = <&pwm1 0 10000 0>;
};
reg_3p3v: regulator-3p3v {
@@ -140,7 +140,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
index d59d5d0e1d19..6ab71a729fd8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
@@ -282,7 +282,6 @@
&pwm2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
- #pwm-cells = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lcd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lcd.dtsi
index 79f2354886b7..ded241a39906 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lcd.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lcd.dtsi
@@ -110,7 +110,7 @@
};
display-timings {
- VGA {
+ timing-vga {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -126,8 +126,7 @@
pixelclk-active = <0>;
};
- ETV570 {
- u-boot,panel-name = "edt,et057090dhu";
+ timing-etv570 {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -143,8 +142,7 @@
pixelclk-active = <0>;
};
- ET0350 {
- u-boot,panel-name = "edt,et0350g0dh6";
+ timing-et0350 {
clock-frequency = <6413760>;
hactive = <320>;
vactive = <240>;
@@ -160,8 +158,7 @@
pixelclk-active = <0>;
};
- ET0430 {
- u-boot,panel-name = "edt,et0430g0dh6";
+ timing-et0430 {
clock-frequency = <9009000>;
hactive = <480>;
vactive = <272>;
@@ -177,7 +174,7 @@
pixelclk-active = <1>;
};
- ET0500 {
+ timing-et0500 {
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -193,8 +190,7 @@
pixelclk-active = <0>;
};
- ET0700 { /* same as ET0500 */
- u-boot,panel-name = "edt,etm0700g0dh6";
+ timing-et0700 { /* same as ET0500 */
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -210,7 +206,7 @@
pixelclk-active = <0>;
};
- ETQ570 {
+ timing-etq570 {
clock-frequency = <6596040>;
hactive = <320>;
vactive = <240>;
@@ -226,8 +222,7 @@
pixelclk-active = <0>;
};
- CoMTFT { /* same as ET0700 but with inverted pixel clock */
- u-boot,panel-name = "edt,etm0700g0edh6";
+ timing-comtft { /* same as ET0700 but with inverted pixel clock */
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lvds.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lvds.dtsi
index 2ca2eb37e14f..4eb53d5677a6 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lvds.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-lvds.dtsi
@@ -127,8 +127,7 @@
};
display-timings {
- hsd100pxn1 {
- u-boot,panel-name = "hannstar,hsd100pxn1";
+ timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -142,7 +141,7 @@
pixelclk-active = <1>;
};
- VGA {
+ timing-vga {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -158,8 +157,7 @@
pixelclk-active = <0>;
};
- nl12880bc20 {
- u-boot,panel-name = "nlt,nl12880bc20-spwg-24";
+ timing-nl12880bc20 {
clock-frequency = <71000000>;
hactive = <1280>;
vactive = <800>;
@@ -175,8 +173,7 @@
pixelclk-active = <1>;
};
- ET0700 {
- u-boot,panel-name = "edt,etm0700g0dh6";
+ timing-et0700 {
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -192,8 +189,7 @@
pixelclk-active = <0>;
};
- ETV570 {
- u-boot,panel-name = "edt,et057090dhu";
+ timing-etv570 {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -224,7 +220,7 @@
};
display-timings {
- hsd100pxn1 {
+ timing-hsd100pxn1 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
@@ -238,7 +234,7 @@
pixelclk-active = <1>;
};
- VGA {
+ timing-vga {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -254,7 +250,7 @@
pixelclk-active = <0>;
};
- nl12880bc20 {
+ timing-nl12880bc20 {
clock-frequency = <71000000>;
hactive = <1280>;
vactive = <800>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-udoo.dtsi
index 647ba5e623dd..14272b42f9a1 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-udoo.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-udoo.dtsi
@@ -59,16 +59,6 @@
};
};
- reg_usb_h1_vbus: regulator-usb-h1-vbus {
- compatible = "regulator-fixed";
- regulator-name = "usb_h1_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */
- gpio = <&gpio7 12 0>;
- };
-
reg_panel: regulator-panel {
compatible = "regulator-fixed";
regulator-name = "lcd_panel";
@@ -285,9 +275,18 @@
&usbh1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbh>;
- vbus-supply = <&reg_usb_h1_vbus>;
- clocks = <&clks IMX6QDL_CLK_CKO>;
- status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ usb-port@1 {
+ compatible = "usb424,2514";
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ };
};
&usbotg {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 8431b8a994f4..d2200c9db25a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -397,11 +397,10 @@
reg = <0x02024000 0x4000>;
interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_ESAI_IPG>,
- <&clks IMX6QDL_CLK_ESAI_MEM>,
<&clks IMX6QDL_CLK_ESAI_EXTAL>,
<&clks IMX6QDL_CLK_ESAI_IPG>,
<&clks IMX6QDL_CLK_SPBA>;
- clock-names = "core", "mem", "extal", "fsys", "spba";
+ clock-names = "core", "extal", "fsys", "spba";
dmas = <&sdma 23 21 0>, <&sdma 24 21 0>;
dma-names = "rx", "tx";
status = "disabled";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-evk.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-evk.dts
index 239bc6dfc584..31eee0419af7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl-evk.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl-evk.dts
@@ -23,7 +23,7 @@
backlight_display: backlight_display {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
@@ -584,10 +584,8 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
- status = "okay";
};
&reg_vdd1p1 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
index 5636fb3661e8..03d6965f0149 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
@@ -138,7 +138,7 @@
pinctrl-0 = <&pinctrl_zforce>;
reg = <0x50>;
interrupt-parent = <&gpio5>;
- interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&ldo1_reg>;
reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
touchscreen-size-x = <1072>;
@@ -163,7 +163,7 @@
pinctrl-0 = <&pinctrl_ricoh_gpio>;
reg = <0x32>;
interrupt-parent = <&gpio5>;
- interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
system-power-controller;
regulators {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts b/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts
index e3e9b0ec4f73..febc2dd9967d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts
@@ -26,7 +26,7 @@
backlight_display: backlight-display {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
status = "okay";
@@ -314,10 +314,8 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
- status = "okay";
};
&snvs_poweroff {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi
index 3659fd5ecfa6..ddeb5b37fb78 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi
@@ -683,7 +683,6 @@
clocks = <&clks IMX6SLL_CLK_USBOH3>;
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
- fsl,anatop = <&anatop>;
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
index cd9cbc9ccc9e..1c1515a854c8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
@@ -18,7 +18,7 @@
backlight-lvds {
compatible = "pwm-backlight";
- pwms = <&pwm4 0 5000000>;
+ pwms = <&pwm4 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
power-supply = <&reg_3p3v>;
@@ -83,7 +83,7 @@
sound {
compatible = "fsl,imx-audio-sgtl5000";
model = "imx6sx-nitrogen6sx-sgtl5000";
- cpu-dai = <&ssi1>;
+ ssi-controller = <&ssi1>;
audio-codec = <&codec>;
audio-routing =
"MIC_IN", "Mic Jack",
@@ -229,10 +229,8 @@
};
&pwm4 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
- status = "okay";
};
&ssi1 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
index c6e85e4a0883..7d4170c27732 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
@@ -23,7 +23,7 @@
backlight_display: backlight-display {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 5000000>;
+ pwms = <&pwm3 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
@@ -184,8 +184,8 @@
};
sound-spdif {
- compatible = "fsl,imx-audio-spdif",
- "fsl,imx6sx-sdb-spdif";
+ compatible = "fsl,imx6sx-sdb-spdif",
+ "fsl,imx-audio-spdif";
model = "imx-spdif";
spdif-controller = <&spdif>;
spdif-out;
@@ -295,10 +295,8 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
- status = "okay";
};
&snvs_poweroff {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-softing-vining-2000.dts b/arch/arm/boot/dts/nxp/imx/imx6sx-softing-vining-2000.dts
index bfcd8f7d86dd..f999eb244373 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-softing-vining-2000.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-softing-vining-2000.dts
@@ -46,19 +46,19 @@
led-1 {
label = "red";
max-brightness = <255>;
- pwms = <&pwm6 0 50000>;
+ pwms = <&pwm6 0 50000 0>;
};
led-2 {
label = "green";
max-brightness = <255>;
- pwms = <&pwm2 0 50000>;
+ pwms = <&pwm2 0 50000 0>;
};
led-3 {
label = "blue";
max-brightness = <255>;
- pwms = <&pwm1 0 50000>;
+ pwms = <&pwm1 0 50000 0>;
};
};
};
@@ -505,24 +505,18 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
- status = "okay";
};
&pwm2 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
- status = "okay";
};
&pwm6 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm6>;
- status = "okay";
};
&reg_arm {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index 0de359d62a47..b386448486df 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -339,15 +339,14 @@
};
esai: esai@2024000 {
- compatible = "fsl,imx6sx-esai", "fsl,imx35-esai";
+ compatible = "fsl,imx35-esai";
reg = <0x02024000 0x4000>;
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_ESAI_IPG>,
- <&clks IMX6SX_CLK_ESAI_MEM>,
<&clks IMX6SX_CLK_ESAI_EXTAL>,
<&clks IMX6SX_CLK_ESAI_IPG>,
<&clks IMX6SX_CLK_SPBA>;
- clock-names = "core", "mem", "extal",
+ clock-names = "core", "extal",
"fsys", "spba";
dmas = <&sdma 23 21 0>,
<&sdma 24 21 0>;
@@ -929,7 +928,6 @@
clocks = <&clks IMX6SX_CLK_USBOH3>;
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
- fsl,anatop = <&anatop>;
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
@@ -957,7 +955,6 @@
fsl,usbphy = <&usbphynop1>;
fsl,usbmisc = <&usbmisc 2>;
phy_type = "hsic";
- fsl,anatop = <&anatop>;
dr_mode = "host";
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
index f10f0525490b..9cfb99ac9e9d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
@@ -16,7 +16,7 @@
backlight_display: backlight-display {
compatible = "pwm-backlight";
- pwms = <&pwm1 0 5000000>;
+ pwms = <&pwm1 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
status = "okay";
@@ -277,7 +277,6 @@
};
&pwm1 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-ccimx6ulsbcpro.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-ccimx6ulsbcpro.dts
index 1762bc47e18d..ed61ae8524fa 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-ccimx6ulsbcpro.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-ccimx6ulsbcpro.dts
@@ -18,7 +18,7 @@
lcd_backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm5 0 50000>;
+ pwms = <&pwm5 0 50000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
status = "okay";
@@ -168,7 +168,6 @@
};
&pwm5 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm5>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
index 2ca18f3dad0a..cdbb8c435cd6 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
@@ -21,7 +21,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm8 0 100000>;
+ pwms = <&pwm8 0 100000 0>;
brightness-levels = < 0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
@@ -194,7 +194,6 @@
};
&pwm8 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm8>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
index af337f18a266..be3cacb4fa7a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
@@ -9,7 +9,7 @@
backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 191000>;
+ pwms = <&pwm3 0 191000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_5v>;
@@ -143,7 +143,6 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi
index 14fc4828ba4e..ee86c36205f9 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi
@@ -20,7 +20,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm8 0 100000>;
+ pwms = <&pwm8 0 100000 0>;
brightness-levels = < 0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
@@ -187,7 +187,6 @@
};
&pwm8 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm8>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-43.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-43.dts
index 0c643706a158..4e8191a65211 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-43.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-43.dts
@@ -14,7 +14,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm7 0 5000000>;
+ pwms = <&pwm7 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
status = "okay";
@@ -41,7 +41,6 @@
};
&pwm7 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm7>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi
index 33d5f27285a4..d8f7877349c9 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi
@@ -35,7 +35,7 @@
pwm-beeper {
compatible = "pwm-beeper";
- pwms = <&pwm8 0 5000>;
+ pwms = <&pwm8 0 5000 0>;
};
reg_3v3: regulator-3v3 {
@@ -152,7 +152,6 @@
};
&pwm8 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm8>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi
index 07dcecbe485d..fe307f49b9e5 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi
@@ -22,7 +22,7 @@
backlight: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm3 0 5000000>;
+ pwms = <&pwm3 0 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
status = "okay";
@@ -177,7 +177,6 @@
};
&pwm3 {
- #pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
index 1db146ac1c17..864173e30709 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
@@ -405,7 +405,7 @@
status = "okay";
display-timings {
- VGA {
+ timing-vga {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -421,7 +421,7 @@
pixelclk-active = <1>;
};
- ETV570 {
+ timing-etv570 {
clock-frequency = <25200000>;
hactive = <640>;
vactive = <480>;
@@ -437,7 +437,7 @@
pixelclk-active = <1>;
};
- ET0350 {
+ timing-et0350 {
clock-frequency = <6413760>;
hactive = <320>;
vactive = <240>;
@@ -453,7 +453,7 @@
pixelclk-active = <1>;
};
- ET0430 {
+ timing-et0430 {
clock-frequency = <9009000>;
hactive = <480>;
vactive = <272>;
@@ -469,7 +469,7 @@
pixelclk-active = <0>;
};
- ET0500 {
+ timing-et0500 {
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -485,7 +485,7 @@
pixelclk-active = <1>;
};
- ET0700 { /* same as ET0500 */
+ timing-et0700 { /* same as ET0500 */
clock-frequency = <33264000>;
hactive = <800>;
vactive = <480>;
@@ -501,7 +501,7 @@
pixelclk-active = <1>;
};
- ETQ570 {
+ timing-etq570 {
clock-frequency = <6596040>;
hactive = <320>;
vactive = <240>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts
new file mode 100644
index 000000000000..cfcd8783c31d
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-seeed-npi.dtsi"
+#include "imx6ull-seeed-npi-dev-board.dtsi"
+
+/ {
+ model = "Seeed NPi iMX6ULL Dev Board with NAND";
+ compatible = "seeed,imx6ull-seeed-npi-emmc", "seeed,imx6ull-seeed-npi", "fsl,imx6ull";
+};
+
+&usdhc2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts
new file mode 100644
index 000000000000..87c9434b09c5
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-seeed-npi.dtsi"
+#include "imx6ull-seeed-npi-dev-board.dtsi"
+
+/ {
+ model = "Seeed NPi iMX6ULL Dev Board with NAND";
+ compatible = "seeed,imx6ull-seeed-npi-nand", "seeed,imx6ull-seeed-npi", "fsl,imx6ull";
+};
+
+&gpmi {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi
new file mode 100644
index 000000000000..6bb12e0bbc7e
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ gpio_buttons: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_button>;
+
+ button-0 {
+ gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+ label = "SW2";
+ linux,code = <KEY_A>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led-blue {
+ gpios = <&gpio4 19 GPIO_ACTIVE_LOW>;
+ label = "LED_B";
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+
+ led-green {
+ gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
+ label = "LED_G";
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+
+ led-red {
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ label = "LED_R";
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+
+ led-user {
+ gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+ label = "User";
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+ };
+
+ reg_5v_sys: regulator-5v-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "5V_SYS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_5v_sys>;
+ };
+
+ reg_3v3_in: regulator-3v3-in {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3_IN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ vin-supply = <&reg_5v_sys>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ vin-supply = <&reg_3v3_in>;
+ };
+
+ reg_sd1_vmmc: regulator-sd1-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3_SD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_vmmc>;
+ enable-active-high;
+ regulator-always-on;
+ vin-supply = <&reg_3v3>;
+ };
+};
+
+&csi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ status = "disabled"; /* LED Blue & Green shared */
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ micrel,led-mode = <1>;
+ clocks = <&clks IMX6UL_CLK_ENET_REF>;
+ clock-names = "rmii-ref";
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ micrel,led-mode = <1>;
+ clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+ clock-names = "rmii-ref";
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-0 = <&pinctrl_lcdif>;
+ pinctrl-names = "default";
+ status = "disabled";
+};
+
+&reg_dcdc_3v3 {
+ vin-supply = <&reg_3v3_in>;
+};
+
+&sai2 {
+ assigned-clock-rates = <320000000>;
+ assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
+ pinctrl-0 = <&pinctrl_sai2>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&pinctrl_uart2>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-0 = <&pinctrl_uart3>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ dr_mode = "otg";
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_usdhc1_cd>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_usdhc1_cd>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_usdhc1_cd>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ wakeup-source;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_button: buttongrp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x0b0b0
+ >;
+ };
+
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
+ >;
+ };
+
+ pinctrl_gpio_leds: ledgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x0b0b0
+ MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x0b0b0
+ MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x0b0b0
+ MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x0b0b0
+ >;
+ };
+
+ pinctrl_lcdif: lcdif-grp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ MX6UL_PAD_LCD_RESET__LCDIF_RESET 0x79
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ MX6UL_PAD_GPIO1_IO08__GPIO1_IO08 0x79
+ >;
+ };
+
+ pinctrl_reg_vmmc: usdhc1regvmmc {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059
+ >;
+ };
+
+ pinctrl_sai2: sai2-grp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x130b0
+ MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088
+ MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088
+ MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x120b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pin = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pin = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pin = <
+ MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x1b0b1
+ MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pin = <
+ MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pin = <
+ MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pin = <
+ MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc1_cd: usdhc1cd {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi
new file mode 100644
index 000000000000..f5ad6b5c1ad0
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Seeed NPi-iMX6ULL Dev Board";
+ compatible = "seeed,imx6ull-seeed-npi", "fsl,imx6ull";
+
+ reg_dcdc_3v3: regulator-dcdc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "DCDC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_dram_1v35: regulator-dram-1v35 {
+ compatible = "regulator-fixed";
+ regulator-name = "DRAM_1V35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ vin-supply = <&reg_dcdc_3v3>;
+ };
+
+ reg_vdd_arm_soc_in: regulator-vdd-arm-soc-in {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_ARM_SOC_IN";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ vin-supply = <&reg_dcdc_3v3>;
+ };
+
+ reg_dcdc_1v8: regulator-dcdc-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "DCDC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ vin-supply = <&reg_dcdc_3v3>;
+ };
+
+ reg_sd1_vqmmc: regulator-sd1-vqmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "NVCC_SD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_vqmmc>;
+ regulator-always-on;
+ vin-supply = <&reg_dcdc_1v8>;
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "disabled";
+};
+
+&usdhc1 {
+ vqmmc-supply = <&reg_sd1_vqmmc>;
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ keep-power-in-suspend;
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_DQS__RAWNAND_DQS 0x0b0b1
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x0b0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x0b0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0x0b0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x0b000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x0b0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0x0b0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x0b0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x0b0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x0b0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x0b0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x0b0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x0b0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x0b0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x0b0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x0b0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x0b0b1
+ >;
+ };
+
+ pinctrl_reg_vqmmc: usdhc1regvqmmc {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-master.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-master.dts
index 67007ce383e3..f9bbd589b66d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-master.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-master.dts
@@ -45,7 +45,7 @@
interrupts = <19 IRQ_TYPE_EDGE_RISING>;
spi-cpha;
spi-cpol;
- spi-max-frequency = <16000000>;
+ spi-max-frequency = <12000000>;
};
};
@@ -63,7 +63,7 @@
interrupts = <9 IRQ_TYPE_EDGE_RISING>;
spi-cpha;
spi-cpol;
- spi-max-frequency = <16000000>;
+ spi-max-frequency = <12000000>;
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slave.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slave.dts
index cee223b5f8e1..ef06619d7c86 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slave.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slave.dts
@@ -23,7 +23,7 @@
interrupts = <19 IRQ_TYPE_EDGE_RISING>;
spi-cpha;
spi-cpol;
- spi-max-frequency = <16000000>;
+ spi-max-frequency = <12000000>;
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slavext.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slavext.dts
index 7fd53b7a4372..83db65bf630f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slavext.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slavext.dts
@@ -45,7 +45,7 @@
interrupts = <19 IRQ_TYPE_EDGE_RISING>;
spi-cpha;
spi-cpol;
- spi-max-frequency = <16000000>;
+ spi-max-frequency = <12000000>;
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
new file mode 100644
index 000000000000..e4576d509a5b
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
@@ -0,0 +1,566 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) 2022-2024 Sebastian Reichel <sre@kernel.org>
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "UNI-T UTi260B Thermal Camera";
+ compatible = "uni-t,uti260b", "fsl,imx6ull";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>;
+ };
+
+ panel_backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_backlight_enable>;
+ power-supply = <&reg_vsd>;
+ pwms = <&pwm1 0 50000 0>;
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ /* generic 26650 battery */
+ device-chemistry = "lithium-ion";
+ charge-full-design-microamp-hours = <5000000>;
+ voltage-max-design-microvolt = <4200000>;
+ voltage-min-design-microvolt = <3300000>;
+ };
+
+ tp5000: charger {
+ compatible = "gpio-charger";
+ charger-type = "usb-sdp";
+ gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_charger_stat1>;
+ };
+
+ fuel-gauge {
+ compatible = "adc-battery";
+ charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ io-channel-names = "voltage";
+ io-channels = <&adc1 7>;
+ monitored-battery = <&battery>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_charger_stat2>;
+ power-supplies = <&tp5000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_gpio_keys>;
+ autorepeat;
+
+ up-key {
+ label = "Up";
+ gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_UP>;
+ };
+
+ down-key {
+ label = "Down";
+ gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_DOWN>;
+ };
+
+ left-key {
+ label = "Left";
+ gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_LEFT>;
+ };
+
+ right-key {
+ label = "Right";
+ gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RIGHT>;
+ };
+
+ ok-key {
+ label = "Ok";
+ gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_ENTER>;
+ };
+
+ return-key {
+ label = "Return";
+ gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_ESC>;
+ };
+
+ play-key {
+ label = "Media";
+ gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MEDIA>;
+ };
+
+ trigger-key {
+ label = "Trigger";
+ gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_TRIGGER>;
+ };
+
+ power-key {
+ label = "Power";
+ gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ };
+
+ light-key {
+ label = "Light";
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_LIGHTS_TOGGLE>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_led_ctrl>;
+
+ led {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_FLASH;
+ gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_poweroff>;
+ };
+
+ reg_vref: regulator-vref-4v2 {
+ compatible = "regulator-fixed";
+ regulator-name = "VREF_4V2";
+ regulator-min-microvolt = <4200000>;
+ regulator-max-microvolt = <4200000>;
+ };
+
+ reg_vsd: regulator-vsd {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&adc1 {
+ #io-channel-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_adc>;
+ vref-supply = <&reg_vref>;
+ status = "okay";
+};
+
+&csi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_csi>;
+ status = "okay";
+
+ port {
+ parallel_from_gc0308: endpoint {
+ remote-endpoint = <&gc0308_to_parallel>;
+ };
+ };
+};
+
+&ecspi3 {
+ cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_spi3>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "inanbo,t28cp45tn89-v17";
+ reg = <0>;
+ backlight = <&panel_backlight>;
+ power-supply = <&reg_vsd>;
+ spi-cpha;
+ spi-cpol;
+ spi-max-frequency = <1000000>;
+ spi-rx-bus-width = <0>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&display_out>;
+ };
+ };
+ };
+};
+
+&gpio1 {
+ ir-reset-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_LOW>;
+ line-name = "ir-reset-gpio";
+ output-low;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_ir_reset>;
+ };
+};
+
+&gpio2 {
+ /* configuring this to output-high results in poweroff */
+ power-en-hog {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_HIGH>;
+ line-name = "power-en-gpio";
+ output-low;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_poweroff2>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_i2c1>;
+ status = "okay";
+
+ camera@21 {
+ compatible = "galaxycore,gc0308";
+ reg = <0x21>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_gc0308>;
+ powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ vdd28-supply = <&reg_vsd>;
+
+ port {
+ gc0308_to_parallel: endpoint {
+ remote-endpoint = <&parallel_from_gc0308>;
+ bus-width = <8>;
+ data-shift = <2>; /* lines 9:2 are used */
+ hsync-active = <1>; /* active high */
+ vsync-active = <1>; /* active high */
+ data-active = <1>; /* active high */
+ pclk-sample = <1>; /* sample on rising edge */
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_i2c2>;
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&lcdif {
+ assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
+ status = "okay";
+
+ port {
+ display_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_pwm>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_uart>;
+ status = "okay";
+};
+
+&usbotg1 {
+ /* USB-C connector */
+ disable-over-current;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbotg2 {
+ /* thermal sensor */
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usdhc1 {
+ /* MicroSD */
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ no-1-8-v;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
+ pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
+ pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
+ wakeup-source;
+ vmmc-supply = <&reg_vsd>;
+ status = "okay";
+};
+
+&usdhc2 {
+ /* eMMC */
+ keep-power-in-suspend;
+ no-1-8-v;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_sdhc2>;
+ wakeup-source;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mux_wdog>;
+};
+
+&iomuxc {
+ mux_adc: adcgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__GPIO1_IO07 0xb0
+ >;
+ };
+
+ mux_backlight_enable: blenablegrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x3008
+ >;
+ };
+
+ mux_charger_stat1: charger1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0x3008
+ >;
+ };
+
+ mux_charger_stat2: charger2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x3008
+ >;
+ };
+
+ mux_csi: csi1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
+ >;
+ };
+
+ mux_gc0308: gc0308grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1e038
+ MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x1b088
+ MX6UL_PAD_GPIO1_IO06__GPIO1_IO06 0x1b088
+ >;
+ };
+
+ mux_gpio_keys: gpiokeygrp {
+ fsl,pins = <
+ MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11 0x3008
+ MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12 0x3008
+ MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13 0x3008
+ MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10 0x3008
+ MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09 0x3008
+ MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x3008
+ MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x3008
+ MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14 0x3008
+ MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x3008
+ MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x3008
+ >;
+ };
+
+ mux_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+ MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+ >;
+ };
+
+ mux_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001f8a8
+ MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001f8a8
+ >;
+ };
+
+ mux_ir_reset: irresetgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x3008
+ >;
+ };
+
+ mux_lcd_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ >;
+ };
+
+ mux_lcd_data: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ >;
+ };
+
+ mux_led_ctrl: ledctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x3008
+ >;
+ };
+
+ mux_poweroff: poweroffgrp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0x3008
+ >;
+ };
+
+ mux_poweroff2: poweroff2grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06 0x3008
+ >;
+ };
+
+ mux_pwm: pwm1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
+ >;
+ };
+
+ mux_sdhc1: sdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ mux_sdhc1_100mhz: sdhc1-100mhz-grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ mux_sdhc1_200mhz: sdhc1-200mhz-grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ mux_sdhc1_cd: sdhc1-cd-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
+ >;
+ };
+
+ mux_sdhc2: sdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ >;
+ };
+
+ mux_spi3: ecspi3grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x100b1
+ MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x100b1
+ MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x3008
+ >;
+ };
+
+ mux_uart: uartgrp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ mux_wdog: wdoggrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
index 9c81c6baa2d3..22dd72499ef2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
@@ -636,6 +636,15 @@
clock-names = "snvs-rtc";
};
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ value = <0x60>;
+ mask = <0x60>;
+ status = "disabled";
+ };
+
snvs_pwrkey: snvs-powerkey {
compatible = "fsl,sec-v4.0-pwrkey";
regmap = <&snvs>;
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts b/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts
index 5485fe118dc4..d38183edf0fd 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts
@@ -323,7 +323,6 @@
display-timings {
native-mode = <&timing5>;
timing0: timing0 {
- panel-name = "VGA";
clock-frequency = <25175000>;
hactive = <640>;
vactive = <480>;
@@ -340,7 +339,6 @@
};
timing1: timing1 {
- panel-name = "ETV570";
clock-frequency = <25175000>;
hactive = <640>;
vactive = <480>;
@@ -357,7 +355,6 @@
};
timing2: timing2 {
- panel-name = "ET0350";
clock-frequency = <6500000>;
hactive = <320>;
vactive = <240>;
@@ -374,7 +371,6 @@
};
timing3: timing3 {
- panel-name = "ET0430";
clock-frequency = <9000000>;
hactive = <480>;
vactive = <272>;
@@ -391,7 +387,6 @@
};
timing4: timing4 {
- panel-name = "ET0500", "ET0700";
clock-frequency = <33260000>;
hactive = <800>;
vactive = <480>;
@@ -408,7 +403,6 @@
};
timing5: timing5 {
- panel-name = "ETQ570";
clock-frequency = <6400000>;
hactive = <320>;
vactive = <240>;
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 6478a39b3be5..f06c6d425e91 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -1,10 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_QCOM) += \
+ msm8226-motorola-falcon.dtb \
qcom-apq8016-sbc.dtb \
qcom-apq8026-asus-sparrow.dtb \
qcom-apq8026-huawei-sturgeon.dtb \
qcom-apq8026-lg-lenok.dtb \
qcom-apq8026-samsung-matisse-wifi.dtb \
+ qcom-apq8026-samsung-milletwifi.dtb \
qcom-apq8060-dragonboard.dtb \
qcom-apq8064-cm-qs600.dtb \
qcom-apq8064-ifc6410.dtb \
@@ -26,6 +28,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8226-microsoft-dempsey.dtb \
qcom-msm8226-microsoft-makepeace.dtb \
qcom-msm8226-microsoft-moneypenny.dtb \
+ qcom-msm8226-samsung-ms013g.dtb \
qcom-msm8226-samsung-s3ve3g.dtb \
qcom-msm8660-surf.dtb \
qcom-msm8916-samsung-e5.dtb \
@@ -40,12 +43,17 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8960-cdp.dtb \
qcom-msm8960-samsung-expressatt.dtb \
qcom-msm8974-lge-nexus5-hammerhead.dtb \
+ qcom-msm8974-samsung-hlte.dtb \
qcom-msm8974-sony-xperia-rhine-amami.dtb \
qcom-msm8974-sony-xperia-rhine-honami.dtb \
qcom-msm8974pro-fairphone-fp2.dtb \
+ qcom-msm8974pro-htc-m8.dtb \
qcom-msm8974pro-oneplus-bacon.dtb \
qcom-msm8974pro-samsung-klte.dtb \
+ qcom-msm8974pro-samsung-kltechn.dtb \
+ qcom-msm8974pro-sony-xperia-shinano-aries.dtb \
qcom-msm8974pro-sony-xperia-shinano-castor.dtb \
+ qcom-msm8974pro-sony-xperia-shinano-leo.dtb \
qcom-mdm9615-wp8548-mangoh-green.dtb \
qcom-sdx55-mtp.dtb \
qcom-sdx55-t55.dtb \
diff --git a/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts b/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts
new file mode 100644
index 000000000000..5dbca83f2230
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+
+#include "qcom-msm8226.dtsi"
+#include "pm8226.dtsi"
+
+/delete-node/ &smem_region;
+
+/ {
+ model = "Motorola Moto G (2013)";
+ compatible = "motorola,falcon", "qcom,msm8226";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@3200000 {
+ compatible = "simple-framebuffer";
+ reg = <0x03200000 0x800000>;
+ width = <720>;
+ height = <1280>;
+ stride = <(720 * 3)>;
+ format = "r8g8b8";
+ vsp-supply = <&reg_lcd_pos>;
+ vsn-supply = <&reg_lcd_neg>;
+ vddio-supply = <&vddio_disp_vreg>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+ gpios = <&tlmm 51 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&tlmm 106 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ vddio_disp_vreg: regulator-vddio-disp {
+ compatible = "regulator-fixed";
+ regulator-name = "vddio_disp";
+ gpio = <&tlmm 34 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&pm8226_l8>;
+ startup-delay-us = <300>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@3200000 {
+ reg = <0x03200000 0x800000>;
+ no-map;
+ };
+
+ dhob@f500000 {
+ reg = <0x0f500000 0x40000>;
+ no-map;
+ };
+
+ shob@f540000 {
+ reg = <0x0f540000 0x2000>;
+ no-map;
+ };
+
+ smem_region: smem@fa00000 {
+ reg = <0x0fa00000 0x100000>;
+ no-map;
+ };
+
+ /* Actually <0x0fa00000 0x500000>, but first 100000 is smem */
+ reserved@fb00000 {
+ reg = <0x0fb00000 0x400000>;
+ no-map;
+ };
+ };
+};
+
+&blsp1_i2c2 {
+ status = "okay";
+
+ magnetometer@c {
+ compatible = "asahi-kasei,ak8963";
+ reg = <0xc>;
+ interrupts-extended = <&tlmm 66 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pm8226_l19>;
+ vid-supply = <&pm8226_lvs1>;
+ pinctrl-0 = <&mag_int_default &mag_reset_default>;
+ pinctrl-names = "default";
+ };
+
+ accelerometer@19 {
+ compatible = "st,lis3dh-accel";
+ reg = <0x19>;
+ interrupts-extended = <&tlmm 63 IRQ_TYPE_EDGE_FALLING>;
+ vdd-supply = <&pm8226_l19>;
+ vddio-supply = <&pm8226_lvs1>;
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+ mount-matrix = "0", "1", "0",
+ "1", "0", "0",
+ "0", "0", "-1";
+ st,drdy-int-pin = <1>;
+ };
+};
+
+&blsp1_i2c3 {
+ status = "okay";
+
+ regulator@3e {
+ compatible = "ti,tps65132";
+ reg = <0x3e>;
+ pinctrl-0 = <&reg_lcd_default>;
+ pinctrl-names = "default";
+
+ reg_lcd_pos: outp {
+ regulator-name = "outp";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-active-discharge = <1>;
+ regulator-boot-on;
+ enable-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_lcd_neg: outn {
+ regulator-name = "outn";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-active-discharge = <1>;
+ regulator-boot-on;
+ enable-gpios = <&tlmm 33 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp108";
+ reg = <0x48>;
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&temp_alert_default>;
+ pinctrl-names = "default";
+ #thermal-sensor-cells = <0>;
+ };
+};
+
+&pm8226_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm8226_vib {
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8226-regulators";
+
+ pm8226_s3: s3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_s4: s4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2200000>;
+ };
+
+ pm8226_s5: s5 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ };
+
+ pm8226_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l3: l3 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1337500>;
+ };
+
+ pm8226_l4: l4 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l5: l5 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allow-set-load;
+ };
+
+ pm8226_l7: l7 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
+
+ pm8226_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l9: l9 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l14: l14 {
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ };
+
+ pm8226_l15: l15 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ pm8226_l16: l16 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3350000>;
+ };
+
+ pm8226_l17: l17 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l18: l18 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l19: l19 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8226_l20: l20 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
+
+ pm8226_l21: l21 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ };
+
+ pm8226_l22: l22 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l23: l23 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l24: l24 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8226_l25: l25 {
+ regulator-min-microvolt = <1775000>;
+ regulator-max-microvolt = <2125000>;
+ };
+
+ pm8226_l26: l26 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l27: l27 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l28: l28 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ };
+
+ pm8226_lvs1: lvs1 {
+ regulator-always-on;
+ };
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8226_l17>;
+ vqmmc-supply = <&pm8226_l6>;
+
+ bus-width = <8>;
+ non-removable;
+
+ status = "okay";
+};
+
+&smbb {
+ qcom,fast-charge-safe-current = <2000000>;
+ qcom,fast-charge-current-limit = <1900000>;
+ qcom,fast-charge-safe-voltage = <4400000>;
+ qcom,minimum-input-voltage = <4300000>;
+
+ status = "okay";
+};
+
+&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio63";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+
+ mag_int_default: mag-int-default-state {
+ pins = "gpio66";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+
+ mag_reset_default: mag-reset-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ reg_lcd_default: reg-lcd-default-state {
+ pins = "gpio31", "gpio33";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ reg_vddio_disp_default: reg-vddio-disp-default-state {
+ pins = "gpio34";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ temp_alert_default: temp-alert-default-state {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+};
+
+&usb {
+ extcon = <&smbb>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&smbb>;
+ v1p8-supply = <&pm8226_l10>;
+ v3p3-supply = <&pm8226_l20>;
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-milletwifi.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-milletwifi.dts
new file mode 100644
index 000000000000..7d519156d91d
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-milletwifi.dts
@@ -0,0 +1,573 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2022, Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ * Copyright (c) 2023, Bryant Mairs <bryant@mai.rs>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/power/summit,smb347-charger.h>
+#include "qcom-msm8226.dtsi"
+#include "pm8226.dtsi"
+
+/delete-node/ &adsp_region;
+/delete-node/ &smem_region;
+
+/ {
+ model = "Samsung Galaxy Tab 4 8.0 Wi-Fi";
+ compatible = "samsung,milletwifi", "qcom,apq8026";
+ chassis-type = "tablet";
+
+ aliases {
+ display0 = &framebuffer0;
+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+ mmc1 = &sdhc_2; /* SDC2 SD card slot */
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ stdout-path = "display0";
+
+ framebuffer0: framebuffer@3200000 {
+ compatible = "simple-framebuffer";
+ reg = <0x03200000 0x800000>;
+ width = <800>;
+ height = <1280>;
+ stride = <(800 * 3)>;
+ format = "r8g8b8";
+ };
+ };
+
+ gpio-hall-sensor {
+ compatible = "gpio-keys";
+
+ event-hall-sensor {
+ label = "Cover";
+ gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ key-home {
+ label = "Home";
+ gpios = <&tlmm 108 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ debounce-interval = <15>;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <15>;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&tlmm 106 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ i2c-backlight {
+ compatible = "i2c-gpio";
+ sda-gpios = <&tlmm 20 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&tlmm 21 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-0 = <&backlight_i2c_default_state>;
+ pinctrl-names = "default";
+
+ i2c-gpio,delay-us = <4>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ backlight@2c {
+ compatible = "ti,lp8556";
+ reg = <0x2c>;
+ enable-supply = <&reg_backlight_vddio>;
+
+ dev-ctrl = /bits/ 8 <0x80>;
+ init-brt = /bits/ 8 <0x3f>;
+
+ /*
+ * Change transition duration: 200ms, Change
+ * transition strength: heavy, PWM hysteresis:
+ * 1-bit w/ 8-bit resolution
+ */
+ rom-a3h {
+ rom-addr = /bits/ 8 <0xa3>;
+ rom-val = /bits/ 8 <0x5e>;
+ };
+
+ /*
+ * PWM phase configuration: 3-phase/3 drivers
+ * (0, 120deg, 240deg, -, -, -),
+ * PWM frequency: 9616Hz (10-bit)
+ */
+ rom-a5h {
+ rom-addr = /bits/ 8 <0xa5>;
+ rom-val = /bits/ 8 <0x34>;
+ };
+
+ /*
+ * Enable LED drivers 2 & 3, Boot inductor
+ * current limit: 1.5A/2.6A
+ */
+ rom-a7h {
+ rom-addr = /bits/ 8 <0xa7>;
+ rom-val = /bits/ 8 <0xfa>;
+ };
+ };
+ };
+
+ reg_backlight_vddio: regulator-backlight-vddio {
+ compatible = "regulator-fixed";
+ regulator-name = "backlight_vddio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 74 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&backlight_vddio_default_state>;
+ pinctrl-names = "default";
+ };
+
+ reg_tsp_1p8v: regulator-tsp-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "tsp_1p8v";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 114 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&tsp_en1_default_state>;
+ pinctrl-names = "default";
+ };
+
+ reg_tsp_3p3v: regulator-tsp-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "tsp_3p3v";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&tsp_en_default_state>;
+ pinctrl-names = "default";
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@3200000 {
+ reg = <0x03200000 0x800000>;
+ no-map;
+ };
+
+ mpss_region: mpss@8400000 {
+ reg = <0x08400000 0x1f00000>;
+ no-map;
+ };
+
+ mba_region: mba@a300000 {
+ reg = <0x0a300000 0x100000>;
+ no-map;
+ };
+
+ reserved@cb00000 {
+ reg = <0x0cb00000 0x700000>;
+ no-map;
+ };
+
+ wcnss_region: wcnss@d200000 {
+ reg = <0x0d200000 0x700000>;
+ no-map;
+ };
+
+ adsp_region: adsp@d900000 {
+ reg = <0x0d900000 0x1800000>;
+ no-map;
+ };
+
+ venus@f100000 {
+ reg = <0x0f100000 0x500000>;
+ no-map;
+ };
+
+ smem_region: smem@fa00000 {
+ reg = <0x0fa00000 0x100000>;
+ no-map;
+ };
+
+ reserved@fb00000 {
+ reg = <0x0fb00000 0x260000>;
+ no-map;
+ };
+
+ rfsa@fd60000 {
+ reg = <0x0fd60000 0x20000>;
+ no-map;
+ };
+
+ rmtfs@fd80000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0fd80000 0x180000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ };
+ };
+};
+
+&blsp1_i2c2 {
+ status = "okay";
+
+ accelerometer@1d {
+ compatible = "st,lis2hh12";
+ reg = <0x1d>;
+
+ interrupts-extended = <&tlmm 54 IRQ_TYPE_LEVEL_HIGH>;
+
+ pinctrl-0 = <&accel_int_default_state>;
+ pinctrl-names = "default";
+
+ vdd-supply = <&pm8226_l19>;
+ vddio-supply = <&pm8226_lvs1>;
+
+ mount-matrix = "0", "1", "0",
+ "-1", "0", "0",
+ "0", "0", "1";
+
+ st,drdy-int-pin = <1>;
+ };
+};
+
+&blsp1_i2c3 {
+ status = "okay";
+
+ charger@6a {
+ compatible = "summit,smb358";
+ reg = <0x6a>;
+
+ interrupts-extended = <&tlmm 115 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&charger_int_default_state>;
+ pinctrl-names = "default";
+
+ summit,enable-usb-charging;
+ summit,enable-charge-control = <SMB3XX_CHG_ENABLE_SW>;
+ summit,fast-voltage-threshold-microvolt = <3000000>;
+ summit,chip-temperature-threshold-celsius = <130>;
+ summit,usb-current-limit-microamp = <1500000>;
+ };
+};
+
+&blsp1_i2c4 {
+ status = "okay";
+
+ muic: usb-switch@25 {
+ compatible = "siliconmitus,sm5502-muic";
+ reg = <0x25>;
+
+ interrupts-extended = <&tlmm 67 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&muic_int_default_state>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp1_i2c5 {
+ status = "okay";
+
+ touchscreen@48 {
+ compatible = "melfas,mms252", "melfas,mms114";
+ reg = <0x48>;
+ interrupts-extended = <&tlmm 17 IRQ_TYPE_EDGE_FALLING>;
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <1280>;
+ avdd-supply = <&reg_tsp_3p3v>;
+ vdd-supply = <&reg_tsp_1p8v>;
+ linux,keycodes = <KEY_APPSELECT KEY_BACK>;
+
+ pinctrl-0 = <&tsp_int_rst_default_state>;
+ pinctrl-names = "default";
+ };
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8226-regulators";
+
+ pm8226_s3: s3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_s4: s4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_s5: s5 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ };
+
+ pm8226_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l3: l3 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1337500>;
+ regulator-always-on;
+ };
+
+ pm8226_l4: l4 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l5: l5 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ pm8226_l7: l7 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
+
+ pm8226_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ pm8226_l9: l9 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l14: l14 {
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ };
+
+ pm8226_l15: l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8226_l16: l16 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3350000>;
+ };
+
+ pm8226_l17: l17 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ regulator-always-on;
+ };
+
+ pm8226_l18: l18 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l19: l19 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8226_l20: l20 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
+
+ pm8226_l21: l21 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l22: l22 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8226_l23: l23 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8226_l24: l24 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8226_l25: l25 {
+ regulator-min-microvolt = <1775000>;
+ regulator-max-microvolt = <2125000>;
+ };
+
+ pm8226_l26: l26 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_l27: l27 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l28: l28 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_lvs1: lvs1 {};
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8226_l17>;
+ vqmmc-supply = <&pm8226_l6>;
+
+ bus-width = <8>;
+ non-removable;
+
+ status = "okay";
+};
+
+&sdhc_2 {
+ vmmc-supply = <&pm8226_l18>;
+ vqmmc-supply = <&pm8226_l21>;
+
+ bus-width = <4>;
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&sdhc2_default_state>, <&sdc2_cd_default_state>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&tlmm {
+ accel_int_default_state: accel-int-default-state {
+ pins = "gpio54";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ backlight_i2c_default_state: backlight-i2c-default-state {
+ pins = "gpio20", "gpio21";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ backlight_vddio_default_state: backlight-vddio-default-state {
+ pins = "gpio74";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ charger_int_default_state: charger-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ muic_int_default_state: muic-int-default-state {
+ pins = "gpio67";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc2_cd_default_state: sdc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ tsp_en_default_state: tsp-en-default-state {
+ pins = "gpio31";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ tsp_en1_default_state: tsp-en1-default-state {
+ pins = "gpio114";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ tsp_int_rst_default_state: tsp-int-rst-default-state {
+ pins = "gpio17";
+ function = "gpio";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+};
+
+&usb {
+ extcon = <&muic>, <&muic>;
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&muic>;
+ v1p8-supply = <&pm8226_l10>;
+ v3p3-supply = <&pm8226_l20>;
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
index 9a5ba978775a..769e151747c3 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
@@ -87,7 +87,7 @@
};
idle-states {
- CPU_SPC: spc {
+ CPU_SPC: cpu-spc {
compatible = "qcom,idle-state-spc",
"arm,idle-state";
entry-latency-us = <400>;
@@ -666,12 +666,12 @@
qcom,controller-type = "pmic-arbiter";
};
- qfprom: qfprom@700000 {
+ qfprom: efuse@700000 {
compatible = "qcom,apq8064-qfprom", "qcom,qfprom";
reg = <0x00700000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
- ranges;
+
tsens_calib: calib@404 {
reg = <0x404 0x10>;
};
@@ -684,7 +684,6 @@
compatible = "qcom,gcc-apq8064", "syscon";
reg = <0x00900000 0x4000>;
#clock-cells = <1>;
- #power-domain-cells = <1>;
#reset-cells = <1>;
clocks = <&cxo_board>,
<&pxo_board>,
@@ -993,7 +992,7 @@
reg = <0x1a400000 0x100>;
};
- gpu: adreno-3xx@4300000 {
+ gpu: gpu@4300000 {
compatible = "qcom,adreno-320.2", "qcom,adreno";
reg = <0x04300000 0x20000>;
reg-names = "kgsl_3d0_reg_memory";
@@ -1334,6 +1333,16 @@
<&gcc PCIE_PHY_RESET>;
reset-names = "axi", "ahb", "por", "pci", "phy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
hdmi: hdmi-tx@4a00000 {
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
index 8204e64d9a97..2b52e5d5eb51 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
@@ -79,7 +79,7 @@
};
idle-states {
- CPU_SPC: spc {
+ CPU_SPC: cpu-spc {
compatible = "qcom,idle-state-spc",
"arm,idle-state";
entry-latency-us = <150>;
@@ -245,7 +245,7 @@
reg = <0xfc190000 0x10000>;
};
- qfprom: qfprom@fc4bc000 {
+ qfprom: efuse@fc4bc000 {
compatible = "qcom,apq8084-qfprom", "qcom,qfprom";
reg = <0xfc4bc000 0x1000>;
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
index 681cb3fc8085..56415ab34083 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
@@ -187,7 +187,6 @@
gcc: clock-controller@1800000 {
compatible = "qcom,gcc-ipq4019";
#clock-cells = <1>;
- #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x1800000 0x60000>;
clocks = <&xo>, <&sleep_clk>;
@@ -470,6 +469,16 @@
"phy_ahb";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
qpic_bam: dma-controller@7984000 {
@@ -598,24 +607,33 @@
reg = <0x90000 0x64>;
status = "disabled";
- ethphy0: ethernet-phy@0 {
+ ethernet-phy-package@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,qca8075-package";
reg = <0>;
- };
- ethphy1: ethernet-phy@1 {
- reg = <1>;
- };
+ qcom,tx-drive-strength-milliwatt = <300>;
- ethphy2: ethernet-phy@2 {
- reg = <2>;
- };
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
- ethphy3: ethernet-phy@3 {
- reg = <3>;
- };
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+
+ ethphy3: ethernet-phy@3 {
+ reg = <3>;
+ };
- ethphy4: ethernet-phy@4 {
- reg = <4>;
+ ethphy4: ethernet-phy@4 {
+ reg = <4>;
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
index 2eb6758b6a3a..da0fd75f4711 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
@@ -372,7 +372,7 @@
qcom,controller-type = "pmic-arbiter";
};
- qfprom: qfprom@700000 {
+ qfprom: efuse@700000 {
compatible = "qcom,ipq8064-qfprom", "qcom,qfprom";
reg = <0x00700000 0x1000>;
#address-cells = <1>;
@@ -519,7 +519,6 @@
reg = <0x00900000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
- #power-domain-cells = <1>;
tsens: thermal-sensor {
compatible = "qcom,ipq8064-tsens";
@@ -1121,6 +1120,16 @@
status = "disabled";
perst-gpios = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1: pcie@1b700000 {
@@ -1172,6 +1181,16 @@
status = "disabled";
perst-gpios = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie2: pcie@1b900000 {
@@ -1223,6 +1242,16 @@
status = "disabled";
perst-gpios = <&qcom_pinmux 63 GPIO_ACTIVE_LOW>;
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
qsgmii_csr: syscon@1bb00000 {
diff --git a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi
index 34c60994d026..573feb3218c3 100644
--- a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi
@@ -102,7 +102,6 @@
gcc: clock-controller@900000 {
compatible = "qcom,gcc-mdm9615";
#clock-cells = <1>;
- #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x900000 0x4000>;
clocks = <&cxo_board>,
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi
index 525d8c608b06..8839b23fc693 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi
@@ -287,6 +287,10 @@
status = "okay";
};
+&smbb {
+ status = "okay";
+};
+
&usb {
extcon = <&smbb>;
dr_mode = "peripheral";
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts b/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts
new file mode 100644
index 000000000000..2ecc5983d365
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts
@@ -0,0 +1,386 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+
+#include "qcom-msm8226.dtsi"
+#include "pm8226.dtsi"
+
+/delete-node/ &smem_region;
+
+/ {
+ model = "Samsung Galaxy Grand 2";
+ compatible = "samsung,ms013g", "qcom,msm8226";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+ mmc1 = &sdhc_2; /* SDC2 SD card slot */
+ serial0 = &blsp1_uart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-hall-sensor {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_hall_sensor_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Hall Effect Sensor";
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+ gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Buttons";
+
+ button-volume-up {
+ label = "Volume Up";
+ gpios = <&tlmm 106 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ button-volume-down {
+ label = "Volume Down";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ button-home {
+ label = "Home Key";
+ gpios = <&tlmm 108 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ };
+ };
+
+ reg_motor_vdd: regulator-motor-vdd {
+ compatible = "regulator-fixed";
+ regulator-name = "motor_vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 111 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&motor_en_default>;
+ pinctrl-names = "default";
+ };
+
+ reg_vdd_tsp_a: regulator-vdd-tsp-a {
+ compatible = "regulator-fixed";
+ regulator-name = "tsp_3p3v";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&tsp_en_default>;
+ pinctrl-names = "default";
+ };
+
+ reserved-memory {
+ smem_region: smem@fa00000 {
+ reg = <0x0fa00000 0x100000>;
+ no-map;
+ };
+ };
+
+ vibrator {
+ compatible = "regulator-haptic";
+ haptic-supply = <&reg_motor_vdd>;
+ min-microvolt = <3300000>;
+ max-microvolt = <3300000>;
+ };
+};
+
+&blsp1_i2c2 {
+ status = "okay";
+
+ accelerometer@18 {
+ compatible = "bosch,bma255";
+ reg = <0x18>;
+ interrupts-extended = <&tlmm 64 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8226_l19>;
+ vddio-supply = <&pm8226_lvs1>;
+
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+
+ mount-matrix = "0", "1", "0",
+ "-1", "0", "0",
+ "0", "0", "-1";
+ };
+};
+
+&blsp1_i2c5 {
+ status = "okay";
+
+ touchscreen@20 {
+ compatible = "zinitix,bt541";
+
+ reg = <0x20>;
+ interrupts-extended = <&tlmm 17 IRQ_TYPE_EDGE_FALLING>;
+
+ touchscreen-size-x = <720>;
+ touchscreen-size-y = <1280>;
+
+ vcca-supply = <&reg_vdd_tsp_a>;
+ vdd-supply = <&pm8226_lvs1>;
+
+ pinctrl-0 = <&tsp_int_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp1_uart3 {
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8226-regulators";
+
+ pm8226_s3: s3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_s4: s4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2200000>;
+ };
+
+ pm8226_s5: s5 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ };
+
+ pm8226_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l3: l3 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1337500>;
+ };
+
+ pm8226_l4: l4 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l5: l5 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allow-set-load;
+ regulator-always-on;
+ };
+
+ pm8226_l7: l7 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
+
+ pm8226_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l9: l9 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l14: l14 {
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ };
+
+ pm8226_l15: l15 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ pm8226_l16: l16 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3350000>;
+ };
+
+ pm8226_l17: l17 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ regulator-always-on;
+ };
+
+ pm8226_l18: l18 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l19: l19 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8226_l20: l20 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
+
+ pm8226_l21: l21 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ };
+
+ pm8226_l22: l22 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l23: l23 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8226_l24: l24 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8226_l25: l25 {
+ regulator-min-microvolt = <1775000>;
+ regulator-max-microvolt = <2125000>;
+ };
+
+ pm8226_l26: l26 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_l27: l27 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l28: l28 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_lvs1: lvs1 {};
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8226_l17>;
+ vqmmc-supply = <&pm8226_l6>;
+
+ bus-width = <8>;
+ non-removable;
+
+ status = "okay";
+};
+
+&sdhc_2 {
+ vmmc-supply = <&pm8226_l18>;
+ vqmmc-supply = <&pm8226_l21>;
+
+ bus-width = <4>;
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&sdhc2_default_state &sdhc2_cd_default>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio64";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ gpio_hall_sensor_default: gpio-hall-sensor-default-state {
+ pins = "gpio50";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio106", "gpio107", "gpio108";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ motor_en_default: motor-en-default-state {
+ pins = "gpio111";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdhc2_cd_default: sdhc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ tsp_en_default: tsp-en-default-state {
+ pins = "gpio31";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ tsp_int_default: tsp-int-default-state {
+ pins = "gpio17";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
index 270973e85625..b2f92ad6499a 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
@@ -635,7 +635,7 @@
reg = <0xfc4ab000 0x4>;
};
- qfprom: qfprom@fc4bc000 {
+ qfprom: efuse@fc4bc000 {
compatible = "qcom,msm8226-qfprom", "qcom,qfprom";
reg = <0xfc4bc000 0x1000>;
#address-cells = <1>;
@@ -1046,7 +1046,7 @@
};
};
- gpu: adreno@fdb00000 {
+ gpu: gpu@fdb00000 {
compatible = "qcom,adreno-305.18", "qcom,adreno";
reg = <0xfdb00000 0x10000>;
reg-names = "kgsl_3d0_reg_memory";
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi
index 455ba4bf1bf4..a66c474cd1aa 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi
@@ -113,7 +113,6 @@
gcc: clock-controller@900000 {
compatible = "qcom,gcc-msm8660";
#clock-cells = <1>;
- #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x900000 0x4000>;
clocks = <&pxo_board>, <&cxo_board>;
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8916-smp.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8916-smp.dtsi
index 36328dbe4212..1ba403b83cb1 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8916-smp.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8916-smp.dtsi
@@ -26,7 +26,7 @@
};
&CPU_SLEEP_0 {
- compatible = "qcom,idle-state-spc";
+ compatible = "qcom,idle-state-spc", "arm,idle-state";
};
&cpu0_acc {
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8926-motorola-peregrine.dts b/arch/arm/boot/dts/qcom/qcom-msm8926-motorola-peregrine.dts
index 0cbe2d2fbbb1..376a33125941 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8926-motorola-peregrine.dts
+++ b/arch/arm/boot/dts/qcom/qcom-msm8926-motorola-peregrine.dts
@@ -29,6 +29,10 @@
height = <1280>;
stride = <(720 * 3)>;
format = "r8g8b8";
+ vsp-supply = <&reg_lcd_pos>;
+ vsn-supply = <&reg_lcd_neg>;
+ vdd-supply = <&pm8226_l28>;
+ vddio-supply = <&vddio_disp_vreg>;
};
};
@@ -51,6 +55,18 @@
};
};
+ vddio_disp_vreg: regulator-vddio-disp {
+ compatible = "regulator-fixed";
+ regulator-name = "vddio_disp";
+ gpio = <&tlmm 34 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <300>;
+ enable-active-high;
+ regulator-boot-on;
+ vin-supply = <&pm8226_l8>;
+ pinctrl-0 = <&disp_vddio_default>;
+ pinctrl-names = "default";
+ };
+
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
@@ -68,12 +84,67 @@
};
};
+&blsp1_i2c2 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ magnetometer@c {
+ compatible = "asahi-kasei,ak8963";
+ reg = <0xc>;
+ interrupts-extended = <&tlmm 38 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pm8226_l19>;
+ pinctrl-0 = <&mag_int_default &mag_reset_default>;
+ pinctrl-names = "default";
+ };
+
+ accelerometer@18 {
+ compatible = "st,lis3dh-accel";
+ reg = <0x18>;
+ interrupts-extended = <&tlmm 1 IRQ_TYPE_EDGE_FALLING>;
+ vdd-supply = <&pm8226_l19>;
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+ st,drdy-int-pin = <1>;
+ };
+};
+
&blsp1_i2c3 {
+ clock-frequency = <400000>;
status = "okay";
+ regulator@3e {
+ compatible = "ti,tps65132";
+ reg = <0x3e>;
+ pinctrl-0 = <&reg_lcd_default>;
+ pinctrl-names = "default";
+
+ reg_lcd_pos: outp {
+ regulator-name = "outp";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-active-discharge = <1>;
+ regulator-boot-on;
+ enable-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_lcd_neg: outn {
+ regulator-name = "outn";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-active-discharge = <1>;
+ regulator-boot-on;
+ enable-gpios = <&tlmm 33 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
sensor@48 {
compatible = "ti,tmp108";
reg = <0x48>;
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&temp_alert_default>;
+ pinctrl-names = "default";
+ #thermal-sensor-cells = <0>;
};
};
@@ -278,6 +349,56 @@
status = "okay";
};
+&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio1";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+
+ disp_vddio_default: disp-vddio-default-state {
+ pins = "gpio34";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ mag_int_default: mag-int-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+
+ mag_reset_default: mag-reset-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ reg_lcd_default: reg-lcd-default-state {
+ pins = "gpio31", "gpio33";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ temp_alert_default: temp-alert-default-state {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+};
+
&usb {
extcon = <&smbb>;
dr_mode = "peripheral";
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
index 922f9e49468a..ebc43c5c6e5f 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
@@ -47,9 +47,9 @@
};
};
- memory {
+ memory@80000000 {
device_type = "memory";
- reg = <0x0 0x0>;
+ reg = <0x80000000 0>;
};
cpu-pmu {
@@ -129,7 +129,6 @@
gcc: clock-controller@900000 {
compatible = "qcom,gcc-msm8960";
#clock-cells = <1>;
- #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x900000 0x4000>;
clocks = <&cxo_board>,
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts
index 4aaae8537a3f..fdb6e22986cf 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts
@@ -182,7 +182,7 @@
status = "okay";
clock-frequency = <355000>;
- led-controller@38 {
+ backlight: led-controller@38 {
compatible = "ti,lm3630a";
status = "okay";
reg = <0x38>;
@@ -272,6 +272,8 @@
reg = <0>;
compatible = "lg,acx467akm-7";
+ backlight = <&backlight>;
+
pinctrl-names = "default";
pinctrl-0 = <&panel_pin>;
@@ -328,7 +330,7 @@
power-source = <PM8941_GPIO_S3>;
};
- otg {
+ otg-hog {
gpio-hog;
gpios = <35 GPIO_ACTIVE_HIGH>;
output-high;
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974-samsung-hlte.dts b/arch/arm/boot/dts/qcom/qcom-msm8974-samsung-hlte.dts
new file mode 100644
index 000000000000..903bb4d12513
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974-samsung-hlte.dts
@@ -0,0 +1,401 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974.dtsi"
+#include "pm8841.dtsi"
+#include "pm8941.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+ model = "Samsung Galaxy Note 3";
+ compatible = "samsung,hlte", "qcom,msm8974";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+ mmc1 = &sdhc_3; /* SDC3 SD card slot */
+ serial0 = &blsp1_uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_pin_a>;
+ pinctrl-names = "default";
+
+ key-home {
+ label = "Home Key";
+ gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ wakeup-source;
+ debounce-interval = <15>;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <15>;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ touch_ldo: regulator-touch {
+ compatible = "regulator-fixed";
+ regulator-name = "touch-ldo";
+
+ gpio = <&pm8941_gpios 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+
+ pinctrl-0 = <&touch_ldo_pin>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp1_i2c2 {
+ status = "okay";
+
+ touchscreen@20 {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x20>;
+
+ interrupt-parent = <&pm8941_gpios>;
+ interrupts = <30 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&pm8941_l10>;
+ vio-supply = <&touch_ldo>;
+
+ pinctrl-0 = <&touch_pin>;
+ pinctrl-names = "default";
+
+ syna,startup-delay-ms = <100>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rmi4-f01@1 {
+ reg = <0x1>;
+ syna,nosleep-mode = <1>;
+ };
+
+ rmi4-f12@12 {
+ reg = <0x12>;
+ syna,sensor-type = <1>;
+ };
+ };
+};
+
+&blsp2_i2c6 {
+ status = "okay";
+
+ fuelgauge@36 {
+ compatible = "maxim,max17048";
+ reg = <0x36>;
+
+ maxim,double-soc;
+ maxim,rcomp = /bits/ 8 <0x56>;
+
+ interrupt-parent = <&pm8941_gpios>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&fuelgauge_pin>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp1_uart2 {
+ status = "okay";
+};
+
+&pm8941_gpios {
+ gpio_keys_pin_a: gpio-keys-active-state {
+ pins = "gpio2", "gpio3", "gpio5";
+ function = "normal";
+ bias-pull-up;
+ power-source = <PM8941_GPIO_S3>;
+ };
+
+ fuelgauge_pin: fuelgauge-int-state {
+ pins = "gpio26";
+ function = "normal";
+ bias-disable;
+ input-enable;
+ power-source = <PM8941_GPIO_S3>;
+ };
+
+ touch_pin: touchscreen-int-state {
+ pins = "gpio30";
+ function = "normal";
+ bias-disable;
+ input-enable;
+ power-source = <PM8941_GPIO_S3>;
+ };
+
+ touch_ldo_pin: touchscreen-ldo-state {
+ pins = "gpio9";
+ function = "normal";
+ output-high;
+ power-source = <PM8941_GPIO_S3>;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+ };
+};
+
+&remoteproc_adsp {
+ cx-supply = <&pm8841_s2>;
+ status = "okay";
+};
+
+&remoteproc_mss {
+ cx-supply = <&pm8841_s2>;
+ mss-supply = <&pm8841_s3>;
+ mx-supply = <&pm8841_s1>;
+ pll-supply = <&pm8941_l12>;
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators-0 {
+ compatible = "qcom,rpm-pm8841-regulators";
+
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s2: s2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s3: s3 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s4: s4 {
+ regulator-min-microvolt = <815000>;
+ regulator-max-microvolt = <900000>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,rpm-pm8941-regulators";
+
+ pm8941_s1: s1 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ pm8941_s2: s2 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ };
+
+ pm8941_s3: s3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l1: l1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8941_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8941_l3: l3 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8941_l4: l4 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8941_l5: l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l7: l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l9: l9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8941_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l11: l11 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8941_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ pm8941_l13: l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8941_l14: l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l15: l15 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8941_l16: l16 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ pm8941_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8941_l18: l18 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8941_l19: l19 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3350000>;
+ };
+
+ pm8941_l20: l20 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ };
+
+ pm8941_l21: l21 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ };
+
+ pm8941_l22: l22 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8941_l23: l23 {
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8941_l24: l24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8941_l20>;
+ vqmmc-supply = <&pm8941_s3>;
+
+ pinctrl-0 = <&sdhc1_pin_a>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhc_3 {
+ max-frequency = <100000000>;
+
+ vmmc-supply = <&pm8941_l21>;
+ vqmmc-supply = <&pm8941_l21>;
+
+ pinctrl-0 = <&sdhc3_pin_a>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&tlmm {
+ sdhc1_pin_a: sdhc1-pin-active-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <4>;
+ bias-disable;
+ };
+
+ cmd-data-pins {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <4>;
+ bias-pull-up;
+ };
+ };
+
+ sdhc3_pin_a: sdhc3-pin-active-state {
+ pins = "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-disable;
+ };
+};
+
+&usb {
+ phys = <&usb_hs1_phy>;
+ phy-select = <&tcsr 0xb000 0>;
+
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+
+ status = "okay";
+};
+
+&usb_hs1_phy {
+ v1p8-supply = <&pm8941_l6>;
+ v3p3-supply = <&pm8941_l24>;
+
+ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
index 5efc38d712cc..15568579459a 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
@@ -14,6 +14,8 @@
#size-cells = <1>;
interrupt-parent = <&intc>;
+ chosen { };
+
clocks {
xo_board: xo_board {
compatible = "fixed-clock";
@@ -85,7 +87,7 @@
};
idle-states {
- CPU_SPC: spc {
+ CPU_SPC: cpu-spc {
compatible = "qcom,idle-state-spc",
"arm,idle-state";
entry-latency-us = <150>;
@@ -103,7 +105,7 @@
};
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0>;
};
@@ -130,7 +132,7 @@
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 0>;
+ mboxes = <&apcs 0>;
qcom,smd-edge = <15>;
rpm_requests: rpm-requests {
@@ -217,7 +219,7 @@
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 10>;
+ mboxes = <&apcs 10>;
qcom,local-pid = <0>;
qcom,remote-pid = <2>;
@@ -242,7 +244,7 @@
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 14>;
+ mboxes = <&apcs 14>;
qcom,local-pid = <0>;
qcom,remote-pid = <1>;
@@ -267,7 +269,7 @@
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 18>;
+ mboxes = <&apcs 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
@@ -292,9 +294,7 @@
#address-cells = <1>;
#size-cells = <0>;
- qcom,ipc-1 = <&apcs 8 13>;
- qcom,ipc-2 = <&apcs 8 9>;
- qcom,ipc-3 = <&apcs 8 19>;
+ mboxes = <0>, <&apcs 13>, <&apcs 9>, <&apcs 19>;
apps_smsm: apps@0 {
reg = <0>;
@@ -341,9 +341,11 @@
<0xf9002000 0x1000>;
};
- apcs: syscon@f9011000 {
- compatible = "syscon";
+ apcs: mailbox@f9011000 {
+ compatible = "qcom,msm8974-apcs-kpss-global",
+ "qcom,msm8994-apcs-kpss-global", "syscon";
reg = <0xf9011000 0x1000>;
+ #mbox-cells = <1>;
};
saw_l2: power-manager@f9012000 {
@@ -755,7 +757,7 @@
smd-edge {
interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 17>;
+ mboxes = <&apcs 17>;
qcom,smd-edge = <6>;
wcnss {
@@ -1231,7 +1233,7 @@
reg = <0xfc4ab000 0x4>;
};
- qfprom: qfprom@fc4bc000 {
+ qfprom: efuse@fc4bc000 {
compatible = "qcom,msm8974-qfprom", "qcom,qfprom";
reg = <0xfc4bc000 0x2100>;
#address-cells = <1>;
@@ -1574,7 +1576,7 @@
smd-edge {
interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 12>;
+ mboxes = <&apcs 12>;
qcom,smd-edge = <0>;
label = "modem";
@@ -2127,7 +2129,7 @@
};
};
- gpu: adreno@fdb00000 {
+ gpu: gpu@fdb00000 {
compatible = "qcom,adreno-330.1", "qcom,adreno";
reg = <0xfdb00000 0x10000>;
reg-names = "kgsl_3d0_reg_memory";
@@ -2211,7 +2213,7 @@
smd-edge {
interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 8>;
+ mboxes = <&apcs 8>;
qcom,smd-edge = <1>;
label = "lpass";
};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-htc-m8.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-htc-m8.dts
new file mode 100644
index 000000000000..b896cc1ad6f7
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-htc-m8.dts
@@ -0,0 +1,353 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include "qcom-msm8974pro.dtsi"
+#include "pm8841.dtsi"
+#include "pm8941.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "HTC One (M8)";
+ compatible = "htc,m8", "qcom,msm8974pro", "qcom,msm8974";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ key-volume-down {
+ label = "volume_down";
+ gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <20>;
+ wakeup-source;
+ };
+
+ key-volume-up {
+ label = "volume_up";
+ gpios = <&tlmm 28 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <20>;
+ wakeup-source;
+ };
+ };
+
+ vreg_boost: vreg-boost {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vreg-boost";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&boost_bypass_n_pin>;
+ pinctrl-names = "default";
+ };
+
+ vreg_vph_pwr: vreg-vph-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "vph-pwr";
+
+ regulator-min-microvolt = <3600000>;
+ regulator-max-microvolt = <3600000>;
+
+ regulator-always-on;
+ };
+};
+
+&pm8941_vib {
+ status = "okay";
+};
+
+&pronto {
+ vddmx-supply = <&pm8841_s1>;
+ vddcx-supply = <&pm8841_s2>;
+ vddpx-supply = <&pm8941_s3>;
+
+ pinctrl-0 = <&wcnss_pin_a>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ iris {
+ vddxo-supply = <&pm8941_l6>;
+ vddrfa-supply = <&pm8941_l11>;
+ vddpa-supply = <&pm8941_l19>;
+ vdddig-supply = <&pm8941_s3>;
+ };
+
+ smd-edge {
+ qcom,remote-pid = <4>;
+ label = "pronto";
+
+ wcnss {
+ status = "okay";
+ };
+ };
+};
+
+&rpm_requests {
+ regulators-0 {
+ compatible = "qcom,rpm-pm8841-regulators";
+
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s2: s2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s3: s3 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s4: s4 {
+ regulator-min-microvolt = <815000>;
+ regulator-max-microvolt = <900000>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,rpm-pm8941-regulators";
+
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+ vdd_l5_l7-supply = <&pm8941_s2>;
+ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+ vdd_l8_l16_l18_l19-supply = <&vreg_vph_pwr>;
+ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+ vdd_l21-supply = <&vreg_boost>;
+
+ pm8941_s1: s1 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_s2: s2 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ regulator-boot-on;
+ };
+
+ pm8941_s3: s3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8941_l3: l3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8941_l4: l4 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8941_l5: l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l7: l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l9: l9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8941_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8941_l11: l11 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8941_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_l13: l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l14: l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l15: l15 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8941_l16: l16 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ pm8941_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8941_l18: l18 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8941_l19: l19 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3350000>;
+ };
+
+ pm8941_l20: l20 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ regulator-boot-on;
+ };
+
+ pm8941_l21: l21 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l22: l22 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8941_l23: l23 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8941_l24: l24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ regulator-boot-on;
+ };
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8941_l20>;
+ vqmmc-supply = <&pm8941_s3>;
+
+ pinctrl-0 = <&sdc1_on>;
+ pinctrl-1 = <&sdc1_off>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+};
+
+&smbb {
+ status = "okay";
+};
+
+&tlmm {
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio27", "gpio28";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ sdc1_on: sdc1-on-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <10>;
+ bias-disable;
+ };
+
+ cmd-data-pins {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ wcnss_pin_a: wcnss-pin-active-state {
+ pins = "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+ function = "wlan";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+};
+
+&usb {
+ phys = <&usb_hs1_phy>;
+ phy-select = <&tcsr 0xb000 0>;
+ extcon = <&smbb>, <&usb_id>;
+ vbus-supply = <&chg_otg>;
+
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+
+ status = "okay";
+};
+
+&usb_hs1_phy {
+ v1p8-supply = <&pm8941_l6>;
+ v3p3-supply = <&pm8941_l24>;
+ extcon = <&smbb>;
+ qcom,init-seq = /bits/ 8 <0x1 0x63>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi
new file mode 100644
index 000000000000..b5443fd5b425
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi
@@ -0,0 +1,818 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro.dtsi"
+#include "pma8084.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ chassis-type = "handset";
+
+ aliases {
+ serial0 = &blsp1_uart1;
+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+ mmc1 = &sdhc_3; /* SDC2 SD card slot */
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pin_a>;
+
+ key-volume-down {
+ label = "volume_down";
+ gpios = <&pma8084_gpios 2 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <15>;
+ };
+
+ key-home {
+ label = "home_key";
+ gpios = <&pma8084_gpios 3 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_HOMEPAGE>;
+ wakeup-source;
+ debounce-interval = <15>;
+ };
+
+ key-volume-up {
+ label = "volume_up";
+ gpios = <&pma8084_gpios 5 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ i2c-gpio-touchkey {
+ compatible = "i2c-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sda-gpios = <&tlmm 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&tlmm 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_touchkey_pins>;
+
+ touchkey@20 {
+ compatible = "cypress,tm2-touchkey";
+ reg = <0x20>;
+
+ interrupt-parent = <&pma8084_gpios>;
+ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchkey_pin>;
+
+ vcc-supply = <&max77826_ldo15>;
+ vdd-supply = <&pma8084_l19>;
+
+ linux,keycodes = <KEY_APPSELECT KEY_BACK>;
+ };
+ };
+
+ i2c_led_gpio: i2c-gpio-led {
+ compatible = "i2c-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_led_gpioex_pins>;
+
+ i2c-gpio,delay-us = <2>;
+
+ gpio_expander: gpio@20 {
+ compatible = "nxp,pcal6416";
+ reg = <0x20>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ vcc-supply = <&pma8084_s4>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpioex_pin>;
+
+ reset-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>;
+ };
+
+ led-controller@30 {
+ compatible = "panasonic,an30259a";
+ reg = <0x30>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ };
+
+ led@2 {
+ reg = <2>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@3 {
+ reg = <3>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+ };
+ };
+
+ vreg_wlan: wlan-regulator {
+ compatible = "regulator-fixed";
+
+ regulator-name = "wl-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vreg_panel: panel-regulator {
+ compatible = "regulator-fixed";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_en_pin>;
+
+ regulator-name = "panel-vddr-reg";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+
+ gpio = <&pma8084_gpios 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vreg_vph_pwr: vreg-vph-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "vph-pwr";
+
+ regulator-min-microvolt = <3600000>;
+ regulator-max-microvolt = <3600000>;
+
+ regulator-always-on;
+ };
+};
+
+&blsp1_i2c2 {
+ status = "okay";
+
+ touchscreen@20 {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x20>;
+
+ interrupt-parent = <&pma8084_gpios>;
+ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&max77826_ldo13>;
+ vio-supply = <&pma8084_lvs2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_pin>;
+
+ syna,startup-delay-ms = <100>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rmi4-f01@1 {
+ reg = <0x1>;
+ syna,nosleep-mode = <1>;
+ };
+
+ rmi4-f12@12 {
+ reg = <0x12>;
+ syna,sensor-type = <1>;
+ };
+ };
+};
+
+&blsp1_i2c6 {
+ status = "okay";
+
+ pmic@60 {
+ reg = <0x60>;
+ compatible = "maxim,max77826";
+
+ regulators {
+ max77826_ldo1: LDO1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ max77826_ldo2: LDO2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ max77826_ldo3: LDO3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ max77826_ldo4: LDO4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ max77826_ldo5: LDO5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ max77826_ldo6: LDO6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ max77826_ldo7: LDO7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ max77826_ldo8: LDO8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ max77826_ldo9: LDO9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ max77826_ldo10: LDO10 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ max77826_ldo11: LDO11 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ max77826_ldo12: LDO12 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ max77826_ldo13: LDO13 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ max77826_ldo14: LDO14 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ max77826_ldo15: LDO15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ max77826_buck: BUCK {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ max77826_buckboost: BUCKBOOST {
+ regulator-min-microvolt = <3400000>;
+ regulator-max-microvolt = <3400000>;
+ };
+ };
+ };
+};
+
+&blsp1_uart2 {
+ status = "okay";
+};
+
+&blsp2_i2c6 {
+ status = "okay";
+
+ fuelgauge@36 {
+ compatible = "maxim,max17048";
+ reg = <0x36>;
+
+ maxim,double-soc;
+ maxim,rcomp = /bits/ 8 <0x56>;
+
+ interrupt-parent = <&pma8084_gpios>;
+ interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&fuelgauge_pin>;
+ };
+};
+
+&blsp2_uart2 {
+ status = "okay";
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&blsp2_uart2_pins_active>;
+ pinctrl-1 = <&blsp2_uart2_pins_sleep>;
+
+ bluetooth {
+ compatible = "brcm,bcm43540-bt";
+ max-speed = <3000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_pins>;
+ device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wakeup";
+ };
+};
+
+&gpu {
+ status = "okay";
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ status = "okay";
+
+ vdda-supply = <&pma8084_l2>;
+ vdd-supply = <&pma8084_l22>;
+ vddio-supply = <&pma8084_l12>;
+
+ panel: panel@0 {
+ reg = <0>;
+ compatible = "samsung,s6e3fa2";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
+
+ iovdd-supply = <&pma8084_lvs4>;
+ vddr-supply = <&vreg_panel>;
+
+ reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&panel_in>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+ status = "okay";
+
+ vddio-supply = <&pma8084_l12>;
+};
+
+&pma8084_gpios {
+ gpio_keys_pin_a: gpio-keys-active-state {
+ pins = "gpio2", "gpio3", "gpio5";
+ function = "normal";
+
+ bias-pull-up;
+ power-source = <PMA8084_GPIO_S4>;
+ };
+
+ touchkey_pin: touchkey-int-state {
+ pins = "gpio6";
+ function = "normal";
+ bias-disable;
+ input-enable;
+ power-source = <PMA8084_GPIO_S4>;
+ };
+
+ touch_pin: touchscreen-int-state {
+ pins = "gpio8";
+ function = "normal";
+ bias-disable;
+ input-enable;
+ power-source = <PMA8084_GPIO_S4>;
+ };
+
+ panel_en_pin: panel-en-state {
+ pins = "gpio14";
+ function = "normal";
+ bias-pull-up;
+ power-source = <PMA8084_GPIO_S4>;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ };
+
+ wlan_sleep_clk_pin: wlan-sleep-clk-state {
+ pins = "gpio16";
+ function = "func2";
+
+ output-high;
+ power-source = <PMA8084_GPIO_S4>;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+ };
+
+ panel_rst_pin: panel-rst-state {
+ pins = "gpio17";
+ function = "normal";
+ bias-disable;
+ power-source = <PMA8084_GPIO_S4>;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ };
+
+ fuelgauge_pin: fuelgauge-int-state {
+ pins = "gpio21";
+ function = "normal";
+ bias-disable;
+ input-enable;
+ power-source = <PMA8084_GPIO_S4>;
+ };
+};
+
+&remoteproc_adsp {
+ status = "okay";
+ cx-supply = <&pma8084_s2>;
+};
+
+&remoteproc_mss {
+ status = "okay";
+ cx-supply = <&pma8084_s2>;
+ mss-supply = <&pma8084_s6>;
+ mx-supply = <&pma8084_s1>;
+ pll-supply = <&pma8084_l12>;
+};
+
+&rpm_requests {
+ regulators-0 {
+ compatible = "qcom,rpm-pma8084-regulators";
+
+ pma8084_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ };
+
+ pma8084_s2: s2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pma8084_s3: s3 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pma8084_s4: s4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pma8084_s5: s5 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ };
+
+ pma8084_s6: s6 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pma8084_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pma8084_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pma8084_l3: l3 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pma8084_l4: l4 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pma8084_l5: l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pma8084_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pma8084_l7: l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pma8084_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pma8084_l9: l9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pma8084_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pma8084_l11: l11 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pma8084_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ pma8084_l13: l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pma8084_l14: l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pma8084_l15: l15 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pma8084_l16: l16 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ pma8084_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pma8084_l18: l18 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pma8084_l19: l19 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pma8084_l20: l20 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ };
+
+ pma8084_l21: l21 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+ };
+
+ pma8084_l22: l22 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pma8084_l23: l23 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pma8084_l24: l24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
+
+ pma8084_l25: l25 {
+ regulator-min-microvolt = <2100000>;
+ regulator-max-microvolt = <2100000>;
+ };
+
+ pma8084_l26: l26 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pma8084_l27: l27 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pma8084_lvs1: lvs1 {};
+ pma8084_lvs2: lvs2 {};
+ pma8084_lvs3: lvs3 {};
+ pma8084_lvs4: lvs4 {};
+
+ pma8084_5vs1: 5vs1 {};
+ };
+};
+
+&sdhc_1 {
+ status = "okay";
+
+ vmmc-supply = <&pma8084_l20>;
+ vqmmc-supply = <&pma8084_s4>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc1_on>;
+ pinctrl-1 = <&sdc1_off>;
+};
+
+&sdhc_2 {
+ status = "okay";
+ max-frequency = <100000000>;
+ vmmc-supply = <&vreg_wlan>;
+ vqmmc-supply = <&pma8084_s4>;
+ non-removable;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc2_on>;
+ pinctrl-1 = <&sdc2_off>;
+
+ wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+
+ /*
+ * Allow all klte* variants to load the same NVRAM file,
+ * as they have little difference in the WiFi part.
+ */
+ brcm,board-type = "samsung,klte";
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
+ };
+};
+
+&sdhc_3 {
+ status = "okay";
+ max-frequency = <100000000>;
+ vmmc-supply = <&pma8084_l21>;
+ vqmmc-supply = <&pma8084_l13>;
+
+ /*
+ * cd-gpio is intentionally disabled. If enabled, an SD card
+ * present during boot is not initialized correctly. Without
+ * cd-gpios the driver resorts to polling, so hotplug works.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc3_on /* &sdhc3_cd_pin */>;
+ /* cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; */
+};
+
+&tlmm {
+ /* This seems suspicious, but somebody with this device should look into it. */
+ blsp2_uart2_pins_active: blsp2-uart2-pins-active-state {
+ pins = "gpio45", "gpio46", "gpio47", "gpio48";
+ function = "blsp_uart8";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep-state {
+ pins = "gpio45", "gpio46", "gpio47", "gpio48";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ bt_pins: bt-pins-state {
+ hostwake-pins {
+ pins = "gpio75";
+ function = "gpio";
+ drive-strength = <16>;
+ };
+
+ devwake-pins {
+ pins = "gpio91";
+ function = "gpio";
+ drive-strength = <2>;
+ };
+ };
+
+ sdc1_on: sdhc1-on-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <4>;
+ bias-disable;
+ };
+
+ cmd-data-pins {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <4>;
+ bias-pull-up;
+ };
+ };
+
+ sdc3_on: sdc3-on-state {
+ pins = "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ sdhc3_cd_pin: sdc3-cd-on-state {
+ pins = "gpio62";
+ function = "gpio";
+
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc2_on: sdhc2-on-state {
+ clk-pins {
+ pins = "sdc2_clk";
+ drive-strength = <6>;
+ bias-disable;
+ };
+
+ cmd-data-pins {
+ pins = "sdc2_cmd", "sdc2_data";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
+ i2c_touchkey_pins: i2c-touchkey-state {
+ pins = "gpio95", "gpio96";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ i2c_led_gpioex_pins: i2c-led-gpioex-state {
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ gpioex_pin: gpioex-state {
+ pins = "gpio145";
+ function = "gpio";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ wifi_pin: wifi-state {
+ pins = "gpio92";
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ panel_te_pin: panel-state {
+ pins = "gpio12";
+ function = "mdp_vsync";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
+
+&usb {
+ status = "okay";
+
+ phys = <&usb_hs1_phy>;
+ phy-select = <&tcsr 0xb000 0>;
+
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+};
+
+&usb_hs1_phy {
+ status = "okay";
+
+ v1p8-supply = <&pma8084_l6>;
+ v3p3-supply = <&pma8084_l24>;
+
+ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts
index b93539e2b87e..954665f3a9dd 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts
@@ -1,817 +1,16 @@
// SPDX-License-Identifier: GPL-2.0
-#include "qcom-msm8974pro.dtsi"
-#include "pma8084.dtsi"
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
-#include <dt-bindings/leds/common.h>
+#include "qcom-msm8974pro-samsung-klte-common.dtsi"
/ {
model = "Samsung Galaxy S5";
compatible = "samsung,klte", "qcom,msm8974pro", "qcom,msm8974";
- chassis-type = "handset";
-
- aliases {
- serial0 = &blsp1_uart1;
- mmc0 = &sdhc_1; /* SDC1 eMMC slot */
- mmc1 = &sdhc_3; /* SDC2 SD card slot */
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_keys_pin_a>;
-
- key-volume-down {
- label = "volume_down";
- gpios = <&pma8084_gpios 2 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_VOLUMEDOWN>;
- debounce-interval = <15>;
- };
-
- key-home {
- label = "home_key";
- gpios = <&pma8084_gpios 3 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_HOMEPAGE>;
- wakeup-source;
- debounce-interval = <15>;
- };
-
- key-volume-up {
- label = "volume_up";
- gpios = <&pma8084_gpios 5 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_VOLUMEUP>;
- debounce-interval = <15>;
- };
- };
-
- i2c-gpio-touchkey {
- compatible = "i2c-gpio";
- #address-cells = <1>;
- #size-cells = <0>;
- sda-gpios = <&tlmm 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&tlmm 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c_touchkey_pins>;
-
- touchkey@20 {
- compatible = "cypress,tm2-touchkey";
- reg = <0x20>;
-
- interrupt-parent = <&pma8084_gpios>;
- interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
- pinctrl-names = "default";
- pinctrl-0 = <&touchkey_pin>;
-
- vcc-supply = <&max77826_ldo15>;
- vdd-supply = <&pma8084_l19>;
-
- linux,keycodes = <KEY_APPSELECT KEY_BACK>;
- };
- };
-
- i2c-gpio-led {
- compatible = "i2c-gpio";
- #address-cells = <1>;
- #size-cells = <0>;
- scl-gpios = <&tlmm 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- sda-gpios = <&tlmm 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c_led_gpioex_pins>;
-
- i2c-gpio,delay-us = <2>;
-
- gpio_expander: gpio@20 {
- compatible = "nxp,pcal6416";
- reg = <0x20>;
-
- gpio-controller;
- #gpio-cells = <2>;
-
- vcc-supply = <&pma8084_s4>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&gpioex_pin>;
-
- reset-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>;
- };
-
- led-controller@30 {
- compatible = "panasonic,an30259a";
- reg = <0x30>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- led@1 {
- reg = <1>;
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- };
-
- led@2 {
- reg = <2>;
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- };
-
- led@3 {
- reg = <3>;
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_BLUE>;
- };
- };
- };
-
- vreg_wlan: wlan-regulator {
- compatible = "regulator-fixed";
-
- regulator-name = "wl-reg";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
-
- gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-
- vreg_panel: panel-regulator {
- compatible = "regulator-fixed";
-
- pinctrl-names = "default";
- pinctrl-0 = <&panel_en_pin>;
-
- regulator-name = "panel-vddr-reg";
- regulator-min-microvolt = <1500000>;
- regulator-max-microvolt = <1500000>;
-
- gpio = <&pma8084_gpios 14 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-
- vreg_vph_pwr: vreg-vph-pwr {
- compatible = "regulator-fixed";
- regulator-name = "vph-pwr";
-
- regulator-min-microvolt = <3600000>;
- regulator-max-microvolt = <3600000>;
-
- regulator-always-on;
- };
-};
-
-&blsp1_i2c2 {
- status = "okay";
-
- touchscreen@20 {
- compatible = "syna,rmi4-i2c";
- reg = <0x20>;
-
- interrupt-parent = <&pma8084_gpios>;
- interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
-
- vdd-supply = <&max77826_ldo13>;
- vio-supply = <&pma8084_lvs2>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&touch_pin>;
-
- syna,startup-delay-ms = <100>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- rmi4-f01@1 {
- reg = <0x1>;
- syna,nosleep-mode = <1>;
- };
-
- rmi4-f12@12 {
- reg = <0x12>;
- syna,sensor-type = <1>;
- };
- };
-};
-
-&blsp1_i2c6 {
- status = "okay";
-
- pmic@60 {
- reg = <0x60>;
- compatible = "maxim,max77826";
-
- regulators {
- max77826_ldo1: LDO1 {
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- max77826_ldo2: LDO2 {
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- };
-
- max77826_ldo3: LDO3 {
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- max77826_ldo4: LDO4 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- max77826_ldo5: LDO5 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- max77826_ldo6: LDO6 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- };
-
- max77826_ldo7: LDO7 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- max77826_ldo8: LDO8 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- };
-
- max77826_ldo9: LDO9 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- max77826_ldo10: LDO10 {
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2950000>;
- };
-
- max77826_ldo11: LDO11 {
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2950000>;
- };
-
- max77826_ldo12: LDO12 {
- regulator-min-microvolt = <2500000>;
- regulator-max-microvolt = <3300000>;
- };
-
- max77826_ldo13: LDO13 {
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- max77826_ldo14: LDO14 {
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- max77826_ldo15: LDO15 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- max77826_buck: BUCK {
- regulator-min-microvolt = <1225000>;
- regulator-max-microvolt = <1225000>;
- };
-
- max77826_buckboost: BUCKBOOST {
- regulator-min-microvolt = <3400000>;
- regulator-max-microvolt = <3400000>;
- };
- };
- };
-};
-
-&blsp1_uart2 {
- status = "okay";
-};
-
-&blsp2_i2c6 {
- status = "okay";
-
- fuelgauge@36 {
- compatible = "maxim,max17048";
- reg = <0x36>;
-
- maxim,double-soc;
- maxim,rcomp = /bits/ 8 <0x56>;
-
- interrupt-parent = <&pma8084_gpios>;
- interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&fuelgauge_pin>;
- };
-};
-
-&blsp2_uart2 {
- status = "okay";
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&blsp2_uart2_pins_active>;
- pinctrl-1 = <&blsp2_uart2_pins_sleep>;
-
- bluetooth {
- compatible = "brcm,bcm43540-bt";
- max-speed = <3000000>;
- pinctrl-names = "default";
- pinctrl-0 = <&bt_pins>;
- device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
- shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
- interrupt-parent = <&tlmm>;
- interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "host-wakeup";
- };
-};
-
-&gpu {
- status = "okay";
-};
-
-&mdss {
- status = "okay";
-};
-
-&mdss_dsi0 {
- status = "okay";
-
- vdda-supply = <&pma8084_l2>;
- vdd-supply = <&pma8084_l22>;
- vddio-supply = <&pma8084_l12>;
-
- panel: panel@0 {
- reg = <0>;
- compatible = "samsung,s6e3fa2";
-
- pinctrl-names = "default";
- pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
-
- iovdd-supply = <&pma8084_lvs4>;
- vddr-supply = <&vreg_panel>;
-
- reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
-
- port {
- panel_in: endpoint {
- remote-endpoint = <&mdss_dsi0_out>;
- };
- };
- };
-};
-
-&mdss_dsi0_out {
- remote-endpoint = <&panel_in>;
- data-lanes = <0 1 2 3>;
-};
-
-&mdss_dsi0_phy {
- status = "okay";
-
- vddio-supply = <&pma8084_l12>;
};
-&pma8084_gpios {
- gpio_keys_pin_a: gpio-keys-active-state {
- pins = "gpio2", "gpio3", "gpio5";
- function = "normal";
-
- bias-pull-up;
- power-source = <PMA8084_GPIO_S4>;
- };
-
- touchkey_pin: touchkey-int-state {
- pins = "gpio6";
- function = "normal";
- bias-disable;
- input-enable;
- power-source = <PMA8084_GPIO_S4>;
- };
-
- touch_pin: touchscreen-int-state {
- pins = "gpio8";
- function = "normal";
- bias-disable;
- input-enable;
- power-source = <PMA8084_GPIO_S4>;
- };
-
- panel_en_pin: panel-en-state {
- pins = "gpio14";
- function = "normal";
- bias-pull-up;
- power-source = <PMA8084_GPIO_S4>;
- qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
- };
-
- wlan_sleep_clk_pin: wlan-sleep-clk-state {
- pins = "gpio16";
- function = "func2";
-
- output-high;
- power-source = <PMA8084_GPIO_S4>;
- qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
- };
-
- panel_rst_pin: panel-rst-state {
- pins = "gpio17";
- function = "normal";
- bias-disable;
- power-source = <PMA8084_GPIO_S4>;
- qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
- };
-
- fuelgauge_pin: fuelgauge-int-state {
- pins = "gpio21";
- function = "normal";
- bias-disable;
- input-enable;
- power-source = <PMA8084_GPIO_S4>;
- };
+&i2c_led_gpio {
+ scl-gpios = <&tlmm 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&tlmm 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
};
-&remoteproc_adsp {
- status = "okay";
- cx-supply = <&pma8084_s2>;
-};
-
-&remoteproc_mss {
- status = "okay";
- cx-supply = <&pma8084_s2>;
- mss-supply = <&pma8084_s6>;
- mx-supply = <&pma8084_s1>;
- pll-supply = <&pma8084_l12>;
-};
-
-&rpm_requests {
- regulators-0 {
- compatible = "qcom,rpm-pma8084-regulators";
-
- pma8084_s1: s1 {
- regulator-min-microvolt = <675000>;
- regulator-max-microvolt = <1050000>;
- regulator-always-on;
- };
-
- pma8084_s2: s2 {
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1050000>;
- };
-
- pma8084_s3: s3 {
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
- };
-
- pma8084_s4: s4 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pma8084_s5: s5 {
- regulator-min-microvolt = <2150000>;
- regulator-max-microvolt = <2150000>;
- };
-
- pma8084_s6: s6 {
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- };
-
- pma8084_l1: l1 {
- regulator-min-microvolt = <1225000>;
- regulator-max-microvolt = <1225000>;
- };
-
- pma8084_l2: l2 {
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- pma8084_l3: l3 {
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1200000>;
- };
-
- pma8084_l4: l4 {
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1225000>;
- };
-
- pma8084_l5: l5 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pma8084_l6: l6 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pma8084_l7: l7 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pma8084_l8: l8 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pma8084_l9: l9 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pma8084_l10: l10 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pma8084_l11: l11 {
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
- };
-
- pma8084_l12: l12 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- };
-
- pma8084_l13: l13 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pma8084_l14: l14 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pma8084_l15: l15 {
- regulator-min-microvolt = <2050000>;
- regulator-max-microvolt = <2050000>;
- };
-
- pma8084_l16: l16 {
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- };
-
- pma8084_l17: l17 {
- regulator-min-microvolt = <2850000>;
- regulator-max-microvolt = <2850000>;
- };
-
- pma8084_l18: l18 {
- regulator-min-microvolt = <2850000>;
- regulator-max-microvolt = <2850000>;
- };
-
- pma8084_l19: l19 {
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- pma8084_l20: l20 {
- regulator-min-microvolt = <2950000>;
- regulator-max-microvolt = <2950000>;
- regulator-system-load = <200000>;
- regulator-allow-set-load;
- };
-
- pma8084_l21: l21 {
- regulator-min-microvolt = <2950000>;
- regulator-max-microvolt = <2950000>;
- regulator-system-load = <200000>;
- regulator-allow-set-load;
- };
-
- pma8084_l22: l22 {
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3300000>;
- };
-
- pma8084_l23: l23 {
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- };
-
- pma8084_l24: l24 {
- regulator-min-microvolt = <3075000>;
- regulator-max-microvolt = <3075000>;
- };
-
- pma8084_l25: l25 {
- regulator-min-microvolt = <2100000>;
- regulator-max-microvolt = <2100000>;
- };
-
- pma8084_l26: l26 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2050000>;
- };
-
- pma8084_l27: l27 {
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1225000>;
- };
-
- pma8084_lvs1: lvs1 {};
- pma8084_lvs2: lvs2 {};
- pma8084_lvs3: lvs3 {};
- pma8084_lvs4: lvs4 {};
-
- pma8084_5vs1: 5vs1 {};
- };
-};
-
-&sdhc_1 {
- status = "okay";
-
- vmmc-supply = <&pma8084_l20>;
- vqmmc-supply = <&pma8084_s4>;
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc1_on>;
- pinctrl-1 = <&sdc1_off>;
-};
-
-&sdhc_2 {
- status = "okay";
- max-frequency = <100000000>;
- vmmc-supply = <&vreg_wlan>;
- vqmmc-supply = <&pma8084_s4>;
- non-removable;
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc2_on>;
- pinctrl-1 = <&sdc2_off>;
-
- wifi@1 {
- reg = <1>;
- compatible = "brcm,bcm4329-fmac";
-
- interrupt-parent = <&tlmm>;
- interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "host-wake";
-
- pinctrl-names = "default";
- pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
- };
-};
-
-&sdhc_3 {
- status = "okay";
- max-frequency = <100000000>;
- vmmc-supply = <&pma8084_l21>;
- vqmmc-supply = <&pma8084_l13>;
-
- /*
- * cd-gpio is intentionally disabled. If enabled, an SD card
- * present during boot is not initialized correctly. Without
- * cd-gpios the driver resorts to polling, so hotplug works.
- */
- pinctrl-names = "default";
- pinctrl-0 = <&sdc3_on /* &sdhc3_cd_pin */>;
- /* cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; */
-};
-
-&tlmm {
- /* This seems suspicious, but somebody with this device should look into it. */
- blsp2_uart2_pins_active: blsp2-uart2-pins-active-state {
- pins = "gpio45", "gpio46", "gpio47", "gpio48";
- function = "blsp_uart8";
- drive-strength = <8>;
- bias-disable;
- };
-
- blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep-state {
- pins = "gpio45", "gpio46", "gpio47", "gpio48";
- function = "gpio";
- drive-strength = <2>;
- bias-pull-down;
- };
-
- bt_pins: bt-pins-state {
- hostwake-pins {
- pins = "gpio75";
- function = "gpio";
- drive-strength = <16>;
- };
-
- devwake-pins {
- pins = "gpio91";
- function = "gpio";
- drive-strength = <2>;
- };
- };
-
- sdc1_on: sdhc1-on-state {
- clk-pins {
- pins = "sdc1_clk";
- drive-strength = <4>;
- bias-disable;
- };
-
- cmd-data-pins {
- pins = "sdc1_cmd", "sdc1_data";
- drive-strength = <4>;
- bias-pull-up;
- };
- };
-
- sdc3_on: sdc3-on-state {
- pins = "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
- function = "sdc3";
- drive-strength = <8>;
- bias-disable;
- };
-
- sdhc3_cd_pin: sdc3-cd-on-state {
- pins = "gpio62";
- function = "gpio";
-
- drive-strength = <2>;
- bias-disable;
- };
-
- sdc2_on: sdhc2-on-state {
- clk-pins {
- pins = "sdc2_clk";
- drive-strength = <6>;
- bias-disable;
- };
-
- cmd-data-pins {
- pins = "sdc2_cmd", "sdc2_data";
- drive-strength = <6>;
- bias-pull-up;
- };
- };
-
- i2c_touchkey_pins: i2c-touchkey-state {
- pins = "gpio95", "gpio96";
- function = "gpio";
- bias-pull-up;
- };
-
- i2c_led_gpioex_pins: i2c-led-gpioex-state {
- pins = "gpio120", "gpio121";
- function = "gpio";
- bias-pull-down;
- };
-
- gpioex_pin: gpioex-state {
- pins = "gpio145";
- function = "gpio";
- bias-pull-up;
- drive-strength = <2>;
- };
-
- wifi_pin: wifi-state {
- pins = "gpio92";
- function = "gpio";
- bias-pull-down;
- };
-
- panel_te_pin: panel-state {
- pins = "gpio12";
- function = "mdp_vsync";
- drive-strength = <2>;
- bias-disable;
- };
-};
-
-&usb {
- status = "okay";
-
- phys = <&usb_hs1_phy>;
- phy-select = <&tcsr 0xb000 0>;
-
- hnp-disable;
- srp-disable;
- adp-disable;
-};
-
-&usb_hs1_phy {
- status = "okay";
-
- v1p8-supply = <&pma8084_l6>;
- v3p3-supply = <&pma8084_l24>;
-
- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+&i2c_led_gpioex_pins {
+ pins = "gpio120", "gpio121";
};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts
new file mode 100644
index 000000000000..b902e31b16c2
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro-samsung-klte-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy S5 China";
+ compatible = "samsung,kltechn", "samsung,klte", "qcom,msm8974pro", "qcom,msm8974";
+};
+
+&i2c_led_gpio {
+ scl-gpios = <&tlmm 61 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&tlmm 60 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+&i2c_led_gpioex_pins {
+ pins = "gpio60", "gpio61";
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts
new file mode 100644
index 000000000000..2621c5928b6a
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro-sony-xperia-shinano-common.dtsi"
+
+/ {
+ model = "Sony Xperia Z3 Compact";
+ compatible = "sony,xperia-aries", "qcom,msm8974pro", "qcom,msm8974";
+ chassis-type = "handset";
+
+ gpio-keys {
+ key-camera-snapshot {
+ label = "camera_snapshot";
+ gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_CAMERA>;
+ debounce-interval = <15>;
+ };
+
+ key-camera-focus {
+ label = "camera_focus";
+ gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_CAMERA_FOCUS>;
+ debounce-interval = <15>;
+ };
+ };
+};
+
+&gpio_keys_pin_a {
+ pins = "gpio2", "gpio3", "gpio4", "gpio5";
+};
+
+&smbb {
+ usb-charge-current-limit = <1500000>;
+ qcom,fast-charge-safe-current = <2100000>;
+ qcom,fast-charge-current-limit = <1800000>;
+ qcom,fast-charge-safe-voltage = <4400000>;
+ qcom,fast-charge-high-threshold-voltage = <4350000>;
+ qcom,auto-recharge-threshold-voltage = <4280000>;
+ qcom,minimum-input-voltage = <4200000>;
+
+ status = "okay";
+};
+
+&synaptics_touchscreen {
+ vio-supply = <&pm8941_s3>;
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts
index ee94741a26ed..409d1798de34 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts
@@ -1,60 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
-#include "qcom-msm8974pro.dtsi"
-#include "pm8841.dtsi"
-#include "pm8941.dtsi"
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include "qcom-msm8974pro-sony-xperia-shinano-common.dtsi"
/ {
model = "Sony Xperia Z2 Tablet";
compatible = "sony,xperia-castor", "qcom,msm8974pro", "qcom,msm8974";
chassis-type = "tablet";
- aliases {
- serial0 = &blsp1_uart2;
- serial1 = &blsp2_uart1;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_keys_pin_a>;
-
- key-volume-down {
- label = "volume_down";
- gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_VOLUMEDOWN>;
- };
-
- key-camera-snapshot {
- label = "camera_snapshot";
- gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_CAMERA>;
- };
-
- key-camera-focus {
- label = "camera_focus";
- gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_CAMERA_FOCUS>;
- };
-
- key-volume-up {
- label = "volume_up";
- gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- linux,code = <KEY_VOLUMEUP>;
- };
- };
-
vreg_bl_vddio: lcd-backlight-vddio {
compatible = "regulator-fixed";
regulator-name = "vreg_bl_vddio";
@@ -67,107 +18,15 @@
vin-supply = <&pm8941_s3>;
startup-delay-us = <70000>;
- pinctrl-names = "default";
pinctrl-0 = <&lcd_backlight_en_pin_a>;
- };
-
- vreg_vsp: lcd-dcdc-regulator {
- compatible = "regulator-fixed";
- regulator-name = "vreg_vsp";
- regulator-min-microvolt = <5600000>;
- regulator-max-microvolt = <5600000>;
-
- gpio = <&pm8941_gpios 20 GPIO_ACTIVE_HIGH>;
- enable-active-high;
-
- pinctrl-names = "default";
- pinctrl-0 = <&lcd_dcdc_en_pin_a>;
- };
-
- vreg_boost: vreg-boost {
- compatible = "regulator-fixed";
-
- regulator-name = "vreg-boost";
- regulator-min-microvolt = <3150000>;
- regulator-max-microvolt = <3150000>;
-
- regulator-always-on;
- regulator-boot-on;
-
- gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
- enable-active-high;
-
pinctrl-names = "default";
- pinctrl-0 = <&boost_bypass_n_pin>;
};
-
- vreg_vph_pwr: vreg-vph-pwr {
- compatible = "regulator-fixed";
- regulator-name = "vph-pwr";
-
- regulator-min-microvolt = <3600000>;
- regulator-max-microvolt = <3600000>;
-
- regulator-always-on;
- };
-
- vreg_wlan: wlan-regulator {
- compatible = "regulator-fixed";
-
- regulator-name = "wl-reg";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
-
- gpio = <&pm8941_gpios 18 GPIO_ACTIVE_HIGH>;
- enable-active-high;
-
- pinctrl-names = "default";
- pinctrl-0 = <&wlan_regulator_pin>;
- };
-};
-
-&blsp1_uart2 {
- status = "okay";
};
-&blsp2_i2c2 {
- status = "okay";
+&blsp2_i2c5 {
clock-frequency = <355000>;
- synaptics@2c {
- compatible = "syna,rmi4-i2c";
- reg = <0x2c>;
-
- interrupt-parent = <&tlmm>;
- interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- vdd-supply = <&pm8941_l22>;
- vio-supply = <&pm8941_lvs3>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&ts_int_pin>;
-
- syna,startup-delay-ms = <100>;
-
- rmi4-f01@1 {
- reg = <0x1>;
- syna,nosleep-mode = <1>;
- };
-
- rmi4-f11@11 {
- reg = <0x11>;
- syna,sensor-type = <1>;
- touchscreen-inverted-x;
- };
- };
-};
-
-&blsp2_i2c5 {
status = "okay";
- clock-frequency = <355000>;
lp8566_wled: backlight@2c {
compatible = "ti,lp8556";
@@ -182,42 +41,52 @@
rom-addr = /bits/ 8 <0xa0>;
rom-val = /bits/ 8 <0xff>;
};
+
rom-a1h {
rom-addr = /bits/ 8 <0xa1>;
rom-val = /bits/ 8 <0x3f>;
};
+
rom-a2h {
rom-addr = /bits/ 8 <0xa2>;
rom-val = /bits/ 8 <0x20>;
};
+
rom-a3h {
rom-addr = /bits/ 8 <0xa3>;
rom-val = /bits/ 8 <0x5e>;
};
+
rom-a4h {
rom-addr = /bits/ 8 <0xa4>;
rom-val = /bits/ 8 <0x02>;
};
+
rom-a5h {
rom-addr = /bits/ 8 <0xa5>;
rom-val = /bits/ 8 <0x04>;
};
+
rom-a6h {
rom-addr = /bits/ 8 <0xa6>;
rom-val = /bits/ 8 <0x80>;
};
+
rom-a7h {
rom-addr = /bits/ 8 <0xa7>;
rom-val = /bits/ 8 <0xf7>;
};
+
rom-a9h {
rom-addr = /bits/ 8 <0xa9>;
rom-val = /bits/ 8 <0x80>;
};
+
rom-aah {
rom-addr = /bits/ 8 <0xaa>;
rom-val = /bits/ 8 <0x0f>;
};
+
rom-aeh {
rom-addr = /bits/ 8 <0xae>;
rom-val = /bits/ 8 <0x0f>;
@@ -232,8 +101,8 @@
compatible = "brcm,bcm43438-bt";
max-speed = <3000000>;
- pinctrl-names = "default";
pinctrl-0 = <&bt_host_wake_pin>, <&bt_dev_wake_pin>, <&bt_reg_on_pin>;
+ pinctrl-names = "default";
host-wakeup-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
device-wakeup-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
@@ -241,339 +110,26 @@
};
};
-&pm8941_coincell {
- status = "okay";
-
- qcom,rset-ohms = <2100>;
- qcom,vset-millivolts = <3000>;
-};
-
&pm8941_gpios {
- gpio_keys_pin_a: gpio-keys-active-state {
- pins = "gpio2", "gpio5";
- function = "normal";
-
- bias-pull-up;
- power-source = <PM8941_GPIO_S3>;
- };
-
bt_reg_on_pin: bt-reg-on-state {
pins = "gpio16";
function = "normal";
-
output-low;
power-source = <PM8941_GPIO_S3>;
};
-
- wlan_sleep_clk_pin: wl-sleep-clk-state {
- pins = "gpio17";
- function = "func2";
-
- output-high;
- power-source = <PM8941_GPIO_S3>;
- };
-
- wlan_regulator_pin: wl-reg-active-state {
- pins = "gpio18";
- function = "normal";
-
- bias-disable;
- power-source = <PM8941_GPIO_S3>;
- };
-
- lcd_dcdc_en_pin_a: lcd-dcdc-en-active-state {
- pins = "gpio20";
- function = "normal";
-
- bias-disable;
- power-source = <PM8941_GPIO_S3>;
- input-disable;
- output-low;
- };
-
-};
-
-&pm8941_lpg {
- status = "okay";
-
- qcom,power-source = <1>;
-
- multi-led {
- color = <LED_COLOR_ID_RGB>;
- function = LED_FUNCTION_STATUS;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- led@5 {
- reg = <5>;
- color = <LED_COLOR_ID_BLUE>;
- };
-
- led@6 {
- reg = <6>;
- color = <LED_COLOR_ID_GREEN>;
- };
-
- led@7 {
- reg = <7>;
- color = <LED_COLOR_ID_RED>;
- };
- };
-};
-
-&remoteproc_adsp {
- cx-supply = <&pm8841_s2>;
- status = "okay";
-};
-
-&remoteproc_mss {
- cx-supply = <&pm8841_s2>;
- mss-supply = <&pm8841_s3>;
- mx-supply = <&pm8841_s1>;
- pll-supply = <&pm8941_l12>;
- status = "okay";
};
&rpm_requests {
- regulators-0 {
- compatible = "qcom,rpm-pm8841-regulators";
-
- pm8841_s1: s1 {
- regulator-min-microvolt = <675000>;
- regulator-max-microvolt = <1050000>;
- };
-
- pm8841_s2: s2 {
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1050000>;
- };
-
- pm8841_s3: s3 {
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1050000>;
- };
-
- pm8841_s4: s4 {
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1050000>;
- };
- };
-
regulators-1 {
- compatible = "qcom,rpm-pm8941-regulators";
-
- vdd_l1_l3-supply = <&pm8941_s1>;
- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
- vdd_l4_l11-supply = <&pm8941_s1>;
- vdd_l5_l7-supply = <&pm8941_s2>;
- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
- vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
- vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
- vdd_l21-supply = <&vreg_boost>;
-
- pm8941_s1: s1 {
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- pm8941_s2: s2 {
- regulator-min-microvolt = <2150000>;
- regulator-max-microvolt = <2150000>;
- regulator-boot-on;
- };
-
- pm8941_s3: s3 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-system-load = <154000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- pm8941_s4: s4 {
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- };
-
- pm8941_l1: l1 {
- regulator-min-microvolt = <1225000>;
- regulator-max-microvolt = <1225000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- pm8941_l2: l2 {
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- pm8941_l3: l3 {
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- pm8941_l4: l4 {
- regulator-min-microvolt = <1225000>;
- regulator-max-microvolt = <1225000>;
- };
-
- pm8941_l5: l5 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm8941_l6: l6 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- };
-
- pm8941_l7: l7 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- };
-
- pm8941_l8: l8 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm8941_l9: l9 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
-
pm8941_l11: l11 {
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <1350000>;
};
- pm8941_l12: l12 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- pm8941_l13: l13 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- regulator-boot-on;
- };
-
- pm8941_l14: l14 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm8941_l15: l15 {
- regulator-min-microvolt = <2050000>;
- regulator-max-microvolt = <2050000>;
- };
-
- pm8941_l16: l16 {
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- };
-
- pm8941_l17: l17 {
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- };
-
- pm8941_l18: l18 {
- regulator-min-microvolt = <2850000>;
- regulator-max-microvolt = <2850000>;
- };
-
pm8941_l19: l19 {
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
};
-
- pm8941_l20: l20 {
- regulator-min-microvolt = <2950000>;
- regulator-max-microvolt = <2950000>;
- regulator-system-load = <500000>;
- regulator-allow-set-load;
- regulator-boot-on;
- };
-
- pm8941_l21: l21 {
- regulator-min-microvolt = <2950000>;
- regulator-max-microvolt = <2950000>;
- regulator-boot-on;
- };
-
- pm8941_l22: l22 {
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- };
-
- pm8941_l23: l23 {
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- pm8941_l24: l24 {
- regulator-min-microvolt = <3075000>;
- regulator-max-microvolt = <3075000>;
- regulator-boot-on;
- };
-
- pm8941_lvs3: lvs3 {};
- };
-};
-
-&sdhc_1 {
- status = "okay";
-
- vmmc-supply = <&pm8941_l20>;
- vqmmc-supply = <&pm8941_s3>;
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc1_on>;
- pinctrl-1 = <&sdc1_off>;
-};
-
-&sdhc_2 {
- status = "okay";
-
- vmmc-supply = <&pm8941_l21>;
- vqmmc-supply = <&pm8941_l13>;
-
- cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc2_on>;
- pinctrl-1 = <&sdc2_off>;
-};
-
-&sdhc_3 {
- status = "okay";
-
- max-frequency = <100000000>;
- vmmc-supply = <&vreg_wlan>;
- non-removable;
-
- pinctrl-names = "default";
- pinctrl-0 = <&sdc3_on>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- bcrmf@1 {
- compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
- reg = <1>;
-
- brcm,drive-strength = <10>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&wlan_sleep_clk_pin>;
};
};
@@ -591,75 +147,13 @@
status = "okay";
};
-&tlmm {
- lcd_backlight_en_pin_a: lcd-backlight-vddio-state {
- pins = "gpio69";
- function = "gpio";
- drive-strength = <10>;
- output-low;
- bias-disable;
- };
-
- sdc1_on: sdc1-on-state {
- clk-pins {
- pins = "sdc1_clk";
- drive-strength = <16>;
- bias-disable;
- };
-
- cmd-data-pins {
- pins = "sdc1_cmd", "sdc1_data";
- drive-strength = <10>;
- bias-pull-up;
- };
- };
-
- sdc2_on: sdc2-on-state {
- clk-pins {
- pins = "sdc2_clk";
- drive-strength = <6>;
- bias-disable;
- };
-
- cmd-data-pins {
- pins = "sdc2_cmd", "sdc2_data";
- drive-strength = <6>;
- bias-pull-up;
- };
-
- cd-pins {
- pins = "gpio62";
- function = "gpio";
- drive-strength = <2>;
- bias-disable;
- };
- };
-
- sdc3_on: sdc3-on-state {
- clk-pins {
- pins = "gpio40";
- function = "sdc3";
- drive-strength = <10>;
- bias-disable;
- };
-
- cmd-pins {
- pins = "gpio39";
- function = "sdc3";
- drive-strength = <10>;
- bias-pull-up;
- };
-
- data-pins {
- pins = "gpio35", "gpio36", "gpio37", "gpio38";
- function = "sdc3";
- drive-strength = <10>;
- bias-pull-up;
- };
- };
+&synaptics_touchscreen {
+ vio-supply = <&pm8941_lvs3>;
+};
- ts_int_pin: ts-int-pin-state {
- pins = "gpio86";
+&tlmm {
+ bt_dev_wake_pin: bt-dev-wake-state {
+ pins = "gpio96";
function = "gpio";
drive-strength = <2>;
bias-disable;
@@ -673,33 +167,11 @@
output-low;
};
- bt_dev_wake_pin: bt-dev-wake-state {
- pins = "gpio96";
+ lcd_backlight_en_pin_a: lcd-backlight-vddio-state {
+ pins = "gpio69";
function = "gpio";
- drive-strength = <2>;
+ drive-strength = <10>;
+ output-low;
bias-disable;
};
};
-
-&usb {
- status = "okay";
-
- phys = <&usb_hs1_phy>;
- phy-select = <&tcsr 0xb000 0>;
- extcon = <&smbb>, <&usb_id>;
- vbus-supply = <&chg_otg>;
-
- hnp-disable;
- srp-disable;
- adp-disable;
-};
-
-&usb_hs1_phy {
- status = "okay";
-
- v1p8-supply = <&pm8941_l6>;
- v3p3-supply = <&pm8941_l24>;
-
- extcon = <&smbb>;
- qcom,init-seq = /bits/ 8 <0x1 0x64>;
-};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
new file mode 100644
index 000000000000..6af7c71c7158
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
@@ -0,0 +1,541 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro.dtsi"
+#include "pm8841.dtsi"
+#include "pm8941.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+ aliases {
+ mmc0 = &sdhc_1;
+ mmc1 = &sdhc_2;
+ serial0 = &blsp1_uart2;
+ serial1 = &blsp2_uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_pin_a>;
+ pinctrl-names = "default";
+
+ key-volume-down {
+ label = "volume_down";
+ gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <15>;
+ };
+
+ key-volume-up {
+ label = "volume_up";
+ gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ vreg_vsp: lcd-dcdc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_vsp";
+ regulator-min-microvolt = <5600000>;
+ regulator-max-microvolt = <5600000>;
+
+ gpio = <&pm8941_gpios 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&lcd_dcdc_en_pin_a>;
+ pinctrl-names = "default";
+ };
+
+ vreg_boost: vreg-boost {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vreg-boost";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&boost_bypass_n_pin>;
+ };
+
+ vreg_vph_pwr: vreg-vph-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "vph-pwr";
+
+ regulator-min-microvolt = <3600000>;
+ regulator-max-microvolt = <3600000>;
+
+ regulator-always-on;
+ };
+
+ vreg_wlan: wlan-regulator {
+ compatible = "regulator-fixed";
+
+ regulator-name = "wl-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&pm8941_gpios 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&wlan_regulator_pin>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp1_uart2 {
+ status = "okay";
+};
+
+&blsp2_i2c2 {
+ clock-frequency = <355000>;
+
+ status = "okay";
+
+ synaptics_touchscreen: synaptics@2c {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x2c>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd-supply = <&pm8941_l22>;
+ /* vio-supply is set in dts */
+
+ pinctrl-0 = <&ts_int_pin>;
+ pinctrl-names = "default";
+
+ syna,startup-delay-ms = <100>;
+
+ rmi4-f01@1 {
+ reg = <0x1>;
+ syna,nosleep-mode = <1>;
+ };
+
+ rmi4-f11@11 {
+ reg = <0x11>;
+ syna,sensor-type = <1>;
+ touchscreen-inverted-x;
+ };
+ };
+};
+
+&pm8941_coincell {
+ qcom,rset-ohms = <2100>;
+ qcom,vset-millivolts = <3000>;
+
+ status = "okay";
+};
+
+&pm8941_gpios {
+ gpio_keys_pin_a: gpio-keys-active-state {
+ pins = "gpio2", "gpio5";
+ function = "normal";
+ bias-pull-up;
+ power-source = <PM8941_GPIO_S3>;
+ };
+
+ wlan_sleep_clk_pin: wl-sleep-clk-state {
+ pins = "gpio17";
+ function = "func2";
+ output-high;
+ power-source = <PM8941_GPIO_S3>;
+ };
+
+ wlan_regulator_pin: wl-reg-active-state {
+ pins = "gpio18";
+ function = "normal";
+ bias-disable;
+ power-source = <PM8941_GPIO_S3>;
+ };
+
+ lcd_dcdc_en_pin_a: lcd-dcdc-en-active-state {
+ pins = "gpio20";
+ function = "normal";
+ bias-disable;
+ power-source = <PM8941_GPIO_S3>;
+ input-disable;
+ output-low;
+ };
+};
+
+&pm8941_lpg {
+ qcom,power-source = <1>;
+
+ status = "okay";
+
+ multi-led {
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_STATUS;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@5 {
+ reg = <5>;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ led@6 {
+ reg = <6>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@7 {
+ reg = <7>;
+ color = <LED_COLOR_ID_RED>;
+ };
+ };
+};
+
+&pm8941_vib {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ cx-supply = <&pm8841_s2>;
+ status = "okay";
+};
+
+&remoteproc_mss {
+ cx-supply = <&pm8841_s2>;
+ mss-supply = <&pm8841_s3>;
+ mx-supply = <&pm8841_s1>;
+ pll-supply = <&pm8941_l12>;
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators-0 {
+ compatible = "qcom,rpm-pm8841-regulators";
+
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s2: s2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s3: s3 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8841_s4: s4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,rpm-pm8941-regulators";
+
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+ vdd_l5_l7-supply = <&pm8941_s2>;
+ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+ vdd_l21-supply = <&vreg_boost>;
+
+ pm8941_s1: s1 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_s2: s2 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ regulator-boot-on;
+ };
+
+ pm8941_s3: s3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-system-load = <154000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_s4: s4 {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ pm8941_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8941_l3: l3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8941_l4: l4 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8941_l5: l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l7: l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l9: l9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8941_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pm8941_l13: l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-boot-on;
+ };
+
+ pm8941_l14: l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8941_l15: l15 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8941_l16: l16 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ pm8941_l17: l17 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ pm8941_l18: l18 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8941_l20: l20 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <500000>;
+ regulator-allow-set-load;
+ regulator-boot-on;
+ };
+
+ pm8941_l21: l21 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <500000>;
+ regulator-allow-set-load;
+ regulator-boot-on;
+ };
+
+ pm8941_l22: l22 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ pm8941_l23: l23 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ pm8941_l24: l24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ regulator-boot-on;
+ };
+
+ pm8941_lvs3: lvs3 {};
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8941_l20>;
+ vqmmc-supply = <&pm8941_s3>;
+
+ pinctrl-0 = <&sdc1_on>;
+ pinctrl-1 = <&sdc1_off>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+};
+
+&sdhc_2 {
+ vmmc-supply = <&pm8941_l21>;
+ vqmmc-supply = <&pm8941_l13>;
+
+ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&sdc2_on>;
+ pinctrl-1 = <&sdc2_off>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+};
+
+&sdhc_3 {
+ max-frequency = <100000000>;
+ vmmc-supply = <&vreg_wlan>;
+ non-removable;
+
+ pinctrl-0 = <&sdc3_on>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ wifi@1 {
+ compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+
+ brcm,drive-strength = <10>;
+
+ pinctrl-0 = <&wlan_sleep_clk_pin>;
+ pinctrl-names = "default";
+ };
+};
+
+&tlmm {
+ sdc1_on: sdc1-on-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ cmd-data-pins {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ sdc2_on: sdc2-on-state {
+ clk-pins {
+ pins = "sdc2_clk";
+ drive-strength = <6>;
+ bias-disable;
+ };
+
+ cmd-data-pins {
+ pins = "sdc2_cmd", "sdc2_data";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ cd-pins {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ sdc3_on: sdc3-on-state {
+ clk-pins {
+ pins = "gpio40";
+ function = "sdc3";
+ drive-strength = <10>;
+ bias-disable;
+ };
+
+ cmd-pins {
+ pins = "gpio39";
+ function = "sdc3";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+
+ data-pins {
+ pins = "gpio35", "gpio36", "gpio37", "gpio38";
+ function = "sdc3";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ ts_int_pin: ts-int-pin-state {
+ pins = "gpio86";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
+
+&usb {
+ phys = <&usb_hs1_phy>;
+ phy-select = <&tcsr 0xb000 0>;
+ extcon = <&smbb>, <&usb_id>;
+ vbus-supply = <&chg_otg>;
+
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+
+ status = "okay";
+};
+
+&usb_hs1_phy {
+ v1p8-supply = <&pm8941_l6>;
+ v3p3-supply = <&pm8941_l24>;
+
+ extcon = <&smbb>;
+ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts
new file mode 100644
index 000000000000..1ed6e1cc21d5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro-sony-xperia-shinano-common.dtsi"
+
+/ {
+ model = "Sony Xperia Z3";
+ compatible = "sony,xperia-leo", "qcom,msm8974pro", "qcom,msm8974";
+ chassis-type = "handset";
+
+ gpio-keys {
+ key-camera-snapshot {
+ label = "camera_snapshot";
+ gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_CAMERA>;
+ debounce-interval = <15>;
+ };
+
+ key-camera-focus {
+ label = "camera_focus";
+ gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_CAMERA_FOCUS>;
+ debounce-interval = <15>;
+ };
+ };
+};
+
+&gpio_keys_pin_a {
+ pins = "gpio2", "gpio3", "gpio4", "gpio5";
+};
+
+&smbb {
+ usb-charge-current-limit = <1500000>;
+ qcom,fast-charge-safe-current = <3000000>;
+ qcom,fast-charge-current-limit = <2150000>;
+ qcom,fast-charge-safe-voltage = <4400000>;
+ qcom,fast-charge-high-threshold-voltage = <4350000>;
+ qcom,auto-recharge-threshold-voltage = <4280000>;
+ qcom,minimum-input-voltage = <4200000>;
+
+ status = "okay";
+};
+
+&synaptics_touchscreen {
+ vio-supply = <&pm8941_s3>;
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
index edc9aaf828c8..68fa5859d263 100644
--- a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
@@ -378,6 +378,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie_ep: pcie-ep@1c00000 {
diff --git a/arch/arm/boot/dts/renesas/r7s72100.dtsi b/arch/arm/boot/dts/renesas/r7s72100.dtsi
index e6d8da6faffb..08ea4c551ed0 100644
--- a/arch/arm/boot/dts/renesas/r7s72100.dtsi
+++ b/arch/arm/boot/dts/renesas/r7s72100.dtsi
@@ -125,6 +125,7 @@
<GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF0>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -138,6 +139,7 @@
<GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF1>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -151,6 +153,7 @@
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF2>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -164,6 +167,7 @@
<GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF3>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -177,6 +181,7 @@
<GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF4>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -190,6 +195,7 @@
<GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF5>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -203,6 +209,7 @@
<GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF6>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -216,6 +223,7 @@
<GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "bri";
clocks = <&mstp4_clks R7S72100_CLK_SCIF7>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
diff --git a/arch/arm/boot/dts/renesas/r8a73a4.dtsi b/arch/arm/boot/dts/renesas/r8a73a4.dtsi
index ac654ff45d0e..85261684b5d5 100644
--- a/arch/arm/boot/dts/renesas/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a73a4.dtsi
@@ -58,6 +58,33 @@
<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)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
+ };
+
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a73a4", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&mstp1_clks R8A73A4_CLK_TMU0>;
+ clock-names = "fck";
+ power-domains = <&pd_c5>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a73a4", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&mstp1_clks R8A73A4_CLK_TMU3>;
+ clock-names = "fck";
+ power-domains = <&pd_a3r>;
+ status = "disabled";
};
dbsc1: memory-controller@e6790000 {
@@ -654,6 +681,17 @@
};
/* Gate clocks */
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+ clocks = <&cp_clk>, <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A73A4_CLK_TMU0 R8A73A4_CLK_TMU3
+ >;
+ clock-output-names =
+ "tmu0", "tmu3";
+ };
mstp2_clks: mstp2_clks@e6150138 {
compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
diff --git a/arch/arm/boot/dts/renesas/r8a7742.dtsi b/arch/arm/boot/dts/renesas/r8a7742.dtsi
index 16d146db824a..3a5d6b434d09 100644
--- a/arch/arm/boot/dts/renesas/r8a7742.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7742.dtsi
@@ -404,6 +404,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7742",
"renesas,rcar-gen2-thermal";
@@ -1880,6 +1938,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7743.dtsi b/arch/arm/boot/dts/renesas/r8a7743.dtsi
index 2245d19a23bb..8833898d5557 100644
--- a/arch/arm/boot/dts/renesas/r8a7743.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7743.dtsi
@@ -329,6 +329,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7743",
"renesas,rcar-gen2-thermal";
@@ -1788,6 +1846,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7744.dtsi b/arch/arm/boot/dts/renesas/r8a7744.dtsi
index aa13841f9781..c66c1102fb72 100644
--- a/arch/arm/boot/dts/renesas/r8a7744.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7744.dtsi
@@ -329,6 +329,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7744",
"renesas,rcar-gen2-thermal";
@@ -1774,6 +1832,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7745.dtsi b/arch/arm/boot/dts/renesas/r8a7745.dtsi
index 44688b8431c3..6ddde364782b 100644
--- a/arch/arm/boot/dts/renesas/r8a7745.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7745.dtsi
@@ -304,6 +304,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
ipmmu_sy0: iommu@e6280000 {
compatible = "renesas,ipmmu-r8a7745",
"renesas,ipmmu-vmsa";
@@ -1578,6 +1636,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a77470.dtsi b/arch/arm/boot/dts/renesas/r8a77470.dtsi
index a5cf663a0118..a8a12275c98a 100644
--- a/arch/arm/boot/dts/renesas/r8a77470.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a77470.dtsi
@@ -241,6 +241,50 @@
resets = <&cpg 407>;
};
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a77470", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a77470", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a77470", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
icram0: sram@e63a0000 {
compatible = "mmio-sram";
reg = <0 0xe63a0000 0 0x12000>;
@@ -1017,6 +1061,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7790.dtsi b/arch/arm/boot/dts/renesas/r8a7790.dtsi
index 46fb81f5062f..20e4d4c6e748 100644
--- a/arch/arm/boot/dts/renesas/r8a7790.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7790.dtsi
@@ -434,6 +434,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7790",
"renesas,rcar-gen2-thermal",
@@ -1954,6 +2012,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7791.dtsi b/arch/arm/boot/dts/renesas/r8a7791.dtsi
index b9d34147628e..f9c9e1d8f669 100644
--- a/arch/arm/boot/dts/renesas/r8a7791.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7791.dtsi
@@ -351,6 +351,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7791",
"renesas,rcar-gen2-thermal",
@@ -1880,6 +1938,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7792.dtsi b/arch/arm/boot/dts/renesas/r8a7792.dtsi
index ecfab3ff59e8..dd3bc32668b7 100644
--- a/arch/arm/boot/dts/renesas/r8a7792.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7792.dtsi
@@ -351,6 +351,65 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
icram0: sram@e63a0000 {
compatible = "mmio-sram";
reg = <0 0xe63a0000 0 0x12000>;
@@ -931,5 +990,6 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
};
diff --git a/arch/arm/boot/dts/renesas/r8a7793.dtsi b/arch/arm/boot/dts/renesas/r8a7793.dtsi
index f51bf687f4bd..24e66ddf37e0 100644
--- a/arch/arm/boot/dts/renesas/r8a7793.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7793.dtsi
@@ -326,6 +326,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7793",
"renesas,rcar-gen2-thermal",
@@ -1459,6 +1517,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r8a7794.dtsi b/arch/arm/boot/dts/renesas/r8a7794.dtsi
index 371dd4715dde..8e6386a79aea 100644
--- a/arch/arm/boot/dts/renesas/r8a7794.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7794.dtsi
@@ -292,6 +292,64 @@
resets = <&cpg 407>;
};
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@fff60000 {
+ compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+ reg = <0 0xfff60000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 111>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+ resets = <&cpg 111>;
+ status = "disabled";
+ };
+
+ tmu2: timer@fff70000 {
+ compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+ reg = <0 0xfff70000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu3: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+ reg = <0 0xfff80000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
ipmmu_sy0: iommu@e6280000 {
compatible = "renesas,ipmmu-r8a7794",
"renesas,ipmmu-vmsa";
@@ -1426,6 +1484,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/boot/dts/renesas/r9a06g032.dtsi b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
index fa63e1afc4ef..7548291c8d7e 100644
--- a/arch/arm/boot/dts/renesas/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
@@ -316,10 +316,27 @@
data-width = <8>;
};
+ gmac1: ethernet@44000000 {
+ compatible = "renesas,r9a06g032-gmac", "renesas,rzn1-gmac", "snps,dwmac";
+ reg = <0x44000000 0x2000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+ clocks = <&sysctrl R9A06G032_HCLK_GMAC0>;
+ clock-names = "stmmaceth";
+ power-domains = <&sysctrl>;
+ snps,multicast-filter-bins = <256>;
+ snps,perfect-filter-entries = <128>;
+ tx-fifo-depth = <2048>;
+ rx-fifo-depth = <4096>;
+ pcs-handle = <&mii_conv1>;
+ status = "disabled";
+ };
+
gmac2: ethernet@44002000 {
compatible = "renesas,r9a06g032-gmac", "renesas,rzn1-gmac", "snps,dwmac";
reg = <0x44002000 0x2000>;
- interrupt-parent = <&gic>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
@@ -467,6 +484,7 @@
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
usbphy: usb-phy {
diff --git a/arch/arm/boot/dts/rockchip/rk3036.dtsi b/arch/arm/boot/dts/rockchip/rk3036.dtsi
index 04af224005f8..96279d1e02fe 100644
--- a/arch/arm/boot/dts/rockchip/rk3036.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3036.dtsi
@@ -402,6 +402,7 @@
rockchip,grf = <&grf>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_ctl>;
+ #sound-dai-cells = <0>;
status = "disabled";
ports {
diff --git a/arch/arm/boot/dts/rockchip/rk3066a-mk808.dts b/arch/arm/boot/dts/rockchip/rk3066a-mk808.dts
index 06790f05b395..4de9a45c4883 100644
--- a/arch/arm/boot/dts/rockchip/rk3066a-mk808.dts
+++ b/arch/arm/boot/dts/rockchip/rk3066a-mk808.dts
@@ -143,6 +143,14 @@
};
};
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2s0 {
+ status = "okay";
+};
+
&mmc0 {
bus-width = <4>;
cap-mmc-highspeed;
diff --git a/arch/arm/boot/dts/rockchip/rk3066a.dtsi b/arch/arm/boot/dts/rockchip/rk3066a.dtsi
index 30139f21de64..3f6d49459734 100644
--- a/arch/arm/boot/dts/rockchip/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3066a.dtsi
@@ -53,6 +53,22 @@
ports = <&vop0_out>, <&vop1_out>;
};
+ hdmi_sound: hdmi-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "HDMI";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ status = "disabled";
+
+ simple-audio-card,codec {
+ sound-dai = <&hdmi>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0>;
+ };
+ };
+
sram: sram@10080000 {
compatible = "mmio-sram";
reg = <0x10080000 0x10000>;
@@ -128,6 +144,7 @@
pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>;
power-domains = <&power RK3066_PD_VIO>;
rockchip,grf = <&grf>;
+ #sound-dai-cells = <0>;
status = "disabled";
ports {
@@ -879,7 +896,3 @@
&wdt {
compatible = "rockchip,rk3066-wdt", "snps,dw-wdt";
};
-
-&emac {
- compatible = "rockchip,rk3066-emac";
-};
diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index fb98873fd94e..23e633387c24 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -216,6 +216,8 @@
<&cru ACLK_LCDC0>,
<&cru HCLK_LCDC0>,
<&cru PCLK_MIPI>,
+ <&cru PCLK_MIPIPHY>,
+ <&cru SCLK_MIPI_24M>,
<&cru ACLK_RGA>,
<&cru HCLK_RGA>,
<&cru ACLK_VIO0>,
@@ -275,6 +277,43 @@
reg = <0>;
remote-endpoint = <&hdmi_in_vop>;
};
+
+ vop_out_dsi: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dsi_in_vop>;
+ };
+ };
+ };
+
+ dsi: dsi@10110000 {
+ compatible = "rockchip,rk3128-mipi-dsi", "snps,dw-mipi-dsi";
+ reg = <0x10110000 0x4000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_MIPI>;
+ clock-names = "pclk";
+ phys = <&dphy>;
+ phy-names = "dphy";
+ power-domains = <&power RK3128_PD_VIO>;
+ resets = <&cru SRST_VIO_MIPI_DSI>;
+ reset-names = "apb";
+ rockchip,grf = <&grf>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dsi_in: port@0 {
+ reg = <0>;
+
+ dsi_in_vop: endpoint {
+ remote-endpoint = <&vop_out_dsi>;
+ };
+ };
+
+ dsi_out: port@1 {
+ reg = <1>;
+ };
};
};
@@ -360,6 +399,41 @@
status = "disabled";
};
+ i2s_8ch: i2s@10200000 {
+ compatible = "rockchip,rk3128-i2s", "rockchip,rk3066-i2s";
+ reg = <0x10200000 0x1000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S_8CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&pdma 14>, <&pdma 15>;
+ dma-names = "tx", "rx";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ spdif: spdif@10204000 {
+ compatible = "rockchip,rk3128-spdif", "rockchip,rk3066-spdif";
+ reg = <0x10204000 0x1000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF>;
+ clock-names = "mclk", "hclk";
+ dmas = <&pdma 13>;
+ dma-names = "tx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ sfc: spi@1020c000 {
+ compatible = "rockchip,sfc";
+ reg = <0x1020c000 0x8000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_SFC>, <&cru 479>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ status = "disabled";
+ };
+
sdmmc: mmc@10214000 {
compatible = "rockchip,rk3128-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x10214000 0x4000>;
@@ -408,6 +482,21 @@
status = "disabled";
};
+ i2s_2ch: i2s@10220000 {
+ compatible = "rockchip,rk3128-i2s", "rockchip,rk3066-i2s";
+ reg = <0x10220000 0x1000>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S_2CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&pdma 0>, <&pdma 1>;
+ dma-names = "tx", "rx";
+ rockchip,playback-channels = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s_bus>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
nfc: nand-controller@10500000 {
compatible = "rockchip,rk3128-nfc", "rockchip,rk2928-nfc";
reg = <0x10500000 0x4000>;
@@ -477,6 +566,7 @@
pinctrl-names = "default";
pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
power-domains = <&power RK3128_PD_VIO>;
+ #sound-dai-cells = <0>;
status = "disabled";
ports {
@@ -496,6 +586,18 @@
};
};
+ dphy: phy@20038000 {
+ compatible = "rockchip,rk3128-dsi-dphy";
+ reg = <0x20038000 0x4000>;
+ clocks = <&cru SCLK_MIPI_24M>, <&cru PCLK_MIPIPHY>;
+ clock-names = "ref", "pclk";
+ #phy-cells = <0>;
+ power-domains = <&power RK3128_PD_VIO>;
+ resets = <&cru SRST_MIPIPHY_P>;
+ reset-names = "apb";
+ status = "disabled";
+ };
+
timer0: timer@20044000 {
compatible = "rockchip,rk3128-timer", "rockchip,rk3288-timer";
reg = <0x20044000 0x20>;
@@ -1104,6 +1206,32 @@
};
};
+ sfc {
+ sfc_bus2: sfc-bus2 {
+ rockchip,pins = <1 RK_PD0 3 &pcfg_pull_default>,
+ <1 RK_PD1 3 &pcfg_pull_default>;
+ };
+
+ sfc_bus4: sfc-bus4 {
+ rockchip,pins = <1 RK_PD0 3 &pcfg_pull_default>,
+ <1 RK_PD1 3 &pcfg_pull_default>,
+ <1 RK_PD2 3 &pcfg_pull_default>,
+ <1 RK_PD3 3 &pcfg_pull_default>;
+ };
+
+ sfc_clk: sfc-clk {
+ rockchip,pins = <2 RK_PA4 3 &pcfg_pull_none>;
+ };
+
+ sfc_cs0: sfc-cs0 {
+ rockchip,pins = <2 RK_PA2 2 &pcfg_pull_default>;
+ };
+
+ sfc_cs1: sfc-cs1 {
+ rockchip,pins = <2 RK_PA3 2 &pcfg_pull_default>;
+ };
+ };
+
spdif {
spdif_tx: spdif-tx {
rockchip,pins = <3 RK_PD3 1 &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rockchip/rk3xxx.dtsi b/arch/arm/boot/dts/rockchip/rk3xxx.dtsi
index f37137f298d5..e6a78bcf9163 100644
--- a/arch/arm/boot/dts/rockchip/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3xxx.dtsi
@@ -194,17 +194,14 @@
};
emac: ethernet@10204000 {
- compatible = "snps,arc-emac";
+ compatible = "rockchip,rk3066-emac";
reg = <0x10204000 0x3c>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-
- rockchip,grf = <&grf>;
-
clocks = <&cru HCLK_EMAC>, <&cru SCLK_MAC>;
clock-names = "hclk", "macref";
max-speed = <100>;
phy-mode = "rmii";
-
+ rockchip,grf = <&grf>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts b/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts
index 0c2396b8f8db..7707d1b01440 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts
+++ b/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts
@@ -69,8 +69,7 @@
&mdio {
phy: ethernet-phy@0 {
- compatible = "ethernet-phy-id001c.c916",
- "ethernet-phy-ieee802.3-c22";
+ compatible = "ethernet-phy-id001c.c916";
reg = <0x0>;
pinctrl-names = "default";
pinctrl-0 = <&eth_phy_rst>;
diff --git a/arch/arm/boot/dts/samsung/exynos3250.dtsi b/arch/arm/boot/dts/samsung/exynos3250.dtsi
index 3f1015edab43..b6c3826a9424 100644
--- a/arch/arm/boot/dts/samsung/exynos3250.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos3250.dtsi
@@ -826,6 +826,7 @@
samsung,spi-src-clk = <0>;
pinctrl-names = "default";
pinctrl-0 = <&spi0_bus>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -842,6 +843,7 @@
samsung,spi-src-clk = <0>;
pinctrl-names = "default";
pinctrl-0 = <&spi1_bus>;
+ fifo-depth = <64>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/samsung/exynos4.dtsi b/arch/arm/boot/dts/samsung/exynos4.dtsi
index 7f981b5c0d64..ed47d0ce04e1 100644
--- a/arch/arm/boot/dts/samsung/exynos4.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4.dtsi
@@ -621,6 +621,7 @@
clock-names = "spi", "spi_busclk0";
pinctrl-names = "default";
pinctrl-0 = <&spi0_bus>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -636,6 +637,7 @@
clock-names = "spi", "spi_busclk0";
pinctrl-names = "default";
pinctrl-0 = <&spi1_bus>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -651,6 +653,7 @@
clock-names = "spi", "spi_busclk0";
pinctrl-names = "default";
pinctrl-0 = <&spi2_bus>;
+ fifo-depth = <64>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts b/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts
index b566f878ed84..18f4f494093b 100644
--- a/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts
@@ -88,7 +88,7 @@
&keypad {
samsung,keypad-num-rows = <2>;
samsung,keypad-num-columns = <8>;
- linux,keypad-no-autorepeat;
+ linux,input-no-autorepeat;
wakeup-source;
pinctrl-names = "default";
pinctrl-0 = <&keypad_rows &keypad_cols>;
diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
index e5254e32aa8f..9bc05961577d 100644
--- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
@@ -45,6 +45,12 @@
/* Default S-BOOT bootloader loads initramfs here */
linux,initrd-start = <0x42000000>;
linux,initrd-end = <0x42800000>;
+
+ /*
+ * Stock bootloader provides incorrect memory size in ATAG_MEM;
+ * override it here
+ */
+ linux,usable-memory-range = <0x40000000 0x3fc00000>;
};
firmware@204f000 {
diff --git a/arch/arm/boot/dts/samsung/exynos4412-origen.dts b/arch/arm/boot/dts/samsung/exynos4412-origen.dts
index 23b151645d66..10ab7bc90f50 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-origen.dts
@@ -453,7 +453,7 @@
&keypad {
samsung,keypad-num-rows = <3>;
samsung,keypad-num-columns = <2>;
- linux,keypad-no-autorepeat;
+ linux,input-no-autorepeat;
wakeup-source;
pinctrl-0 = <&keypad_rows &keypad_cols>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts b/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts
index 715dfcba1417..c83fb250e664 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts
@@ -69,7 +69,7 @@
&keypad {
samsung,keypad-num-rows = <3>;
samsung,keypad-num-columns = <8>;
- linux,keypad-no-autorepeat;
+ linux,input-no-autorepeat;
wakeup-source;
pinctrl-0 = <&keypad_rows &keypad_cols>;
pinctrl-names = "default";
@@ -105,31 +105,31 @@
linux,code = <6>;
};
- key-A {
+ key-a {
keypad,row = <2>;
keypad,column = <6>;
linux,code = <30>;
};
- key-B {
+ key-b {
keypad,row = <2>;
keypad,column = <7>;
linux,code = <48>;
};
- key-C {
+ key-c {
keypad,row = <0>;
keypad,column = <5>;
linux,code = <46>;
};
- key-D {
+ key-d {
keypad,row = <2>;
keypad,column = <5>;
linux,code = <32>;
};
- key-E {
+ key-e {
keypad,row = <0>;
keypad,column = <7>;
linux,code = <18>;
diff --git a/arch/arm/boot/dts/samsung/exynos5250.dtsi b/arch/arm/boot/dts/samsung/exynos5250.dtsi
index 99c84bebf25a..b9e7c4938818 100644
--- a/arch/arm/boot/dts/samsung/exynos5250.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5250.dtsi
@@ -511,6 +511,7 @@
clock-names = "spi", "spi_busclk0";
pinctrl-names = "default";
pinctrl-0 = <&spi0_bus>;
+ fifo-depth = <256>;
};
spi_1: spi@12d30000 {
@@ -526,6 +527,7 @@
clock-names = "spi", "spi_busclk0";
pinctrl-names = "default";
pinctrl-0 = <&spi1_bus>;
+ fifo-depth = <64>;
};
spi_2: spi@12d40000 {
@@ -541,6 +543,7 @@
clock-names = "spi", "spi_busclk0";
pinctrl-names = "default";
pinctrl-0 = <&spi2_bus>;
+ fifo-depth = <64>;
};
mmc_0: mmc@12200000 {
diff --git a/arch/arm/boot/dts/samsung/exynos5420.dtsi b/arch/arm/boot/dts/samsung/exynos5420.dtsi
index 25ed90374679..196c6d04675a 100644
--- a/arch/arm/boot/dts/samsung/exynos5420.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5420.dtsi
@@ -658,6 +658,7 @@
pinctrl-0 = <&spi0_bus>;
clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
clock-names = "spi", "spi_busclk0";
+ fifo-depth = <256>;
status = "disabled";
};
@@ -674,6 +675,7 @@
pinctrl-0 = <&spi1_bus>;
clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
clock-names = "spi", "spi_busclk0";
+ fifo-depth = <64>;
status = "disabled";
};
@@ -690,6 +692,7 @@
pinctrl-0 = <&spi2_bus>;
clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
clock-names = "spi", "spi_busclk0";
+ fifo-depth = <64>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts b/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
index 9bbbdce9103a..bb019868b996 100644
--- a/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
@@ -185,7 +185,7 @@
samsung,color-depth = <1>;
samsung,link-rate = <0x0a>;
samsung,lane-count = <2>;
- samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+ hpd-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
ports {
port {
diff --git a/arch/arm/boot/dts/samsung/s5pv210.dtsi b/arch/arm/boot/dts/samsung/s5pv210.dtsi
index ed560c9a3aa1..34e8a3d5efa5 100644
--- a/arch/arm/boot/dts/samsung/s5pv210.dtsi
+++ b/arch/arm/boot/dts/samsung/s5pv210.dtsi
@@ -72,7 +72,7 @@
#size-cells = <1>;
ranges;
- onenand: onenand@b0600000 {
+ onenand: nand-controller@b0600000 {
compatible = "samsung,s5pv210-onenand";
reg = <0xb0600000 0x2000>,
<0xb0000000 0x20000>,
@@ -82,7 +82,7 @@
clocks = <&clocks CLK_NANDXL>, <&clocks DOUT_FLASH>;
clock-names = "bus", "onenand";
#address-cells = <1>;
- #size-cells = <1>;
+ #size-cells = <0>;
status = "disabled";
};
@@ -161,6 +161,7 @@
pinctrl-0 = <&spi0_bus>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -177,6 +178,7 @@
pinctrl-0 = <&spi1_bus>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/st/Makefile b/arch/arm/boot/dts/st/Makefile
index 9fedd6776208..015903d09323 100644
--- a/arch/arm/boot/dts/st/Makefile
+++ b/arch/arm/boot/dts/st/Makefile
@@ -29,6 +29,7 @@ dtb-$(CONFIG_ARCH_STM32) += \
stm32h743i-eval.dtb \
stm32h743i-disco.dtb \
stm32h750i-art-pi.dtb \
+ stm32mp135f-dhcor-dhsbc.dtb \
stm32mp135f-dk.dtb \
stm32mp151a-prtt1a.dtb \
stm32mp151a-prtt1c.dtb \
diff --git a/arch/arm/boot/dts/st/stih407-family.dtsi b/arch/arm/boot/dts/st/stih407-family.dtsi
index 29302e74aa1d..35a55aef7f4b 100644
--- a/arch/arm/boot/dts/st/stih407-family.dtsi
+++ b/arch/arm/boot/dts/st/stih407-family.dtsi
@@ -33,7 +33,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
@@ -52,8 +52,9 @@
clock-latency = <100000>;
cpu0-supply = <&pwm_regulator>;
st,syscfg = <&syscfg_core 0x8e0>;
+ #cooling-cells = <2>;
};
- cpu@1 {
+ cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
@@ -66,6 +67,7 @@
1200000 0
800000 0
500000 0>;
+ #cooling-cells = <2>;
};
};
diff --git a/arch/arm/boot/dts/st/stih410.dtsi b/arch/arm/boot/dts/st/stih410.dtsi
index 29e95e9d3229..a69231854f78 100644
--- a/arch/arm/boot/dts/st/stih410.dtsi
+++ b/arch/arm/boot/dts/st/stih410.dtsi
@@ -270,6 +270,7 @@
clock-names = "thermal";
clocks = <&clk_sysin>;
interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
+ #thermal-sensor-cells = <0>;
};
cec@94a087c {
diff --git a/arch/arm/boot/dts/st/stih418.dtsi b/arch/arm/boot/dts/st/stih418.dtsi
index b35b9b7a7ccc..8fb8b3af5e49 100644
--- a/arch/arm/boot/dts/st/stih418.dtsi
+++ b/arch/arm/boot/dts/st/stih418.dtsi
@@ -6,23 +6,26 @@
#include "stih418-clock.dtsi"
#include "stih407-family.dtsi"
#include "stih410-pinctrl.dtsi"
+#include <dt-bindings/thermal/thermal.h>
/ {
cpus {
#address-cells = <1>;
#size-cells = <0>;
- cpu@2 {
+ cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <2>;
/* u-boot puts hpen in SBC dmem at 0xa4 offset */
cpu-release-addr = <0x94100A4>;
+ #cooling-cells = <2>;
};
- cpu@3 {
+ cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <3>;
/* u-boot puts hpen in SBC dmem at 0xa4 offset */
cpu-release-addr = <0x94100A4>;
+ #cooling-cells = <2>;
};
};
@@ -44,6 +47,38 @@
reset-names = "global", "port";
};
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <250>; /* 250ms */
+ polling-delay = <1000>; /* 1000ms */
+
+ thermal-sensors = <&thermal>;
+
+ trips {
+ cpu_crit: cpu-crit {
+ temperature = <95000>; /* 95C */
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ cpu_alert: cpu-alert {
+ temperature = <85000>; /* 85C */
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ };
+
+ cooling-maps {
+ map {
+ trip = <&cpu_alert>;
+ 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>;
+ };
+ };
+ };
+ };
+
soc {
rng11: rng@8a8a000 {
status = "disabled";
@@ -107,12 +142,13 @@
assigned-clock-rates = <200000000>;
};
- thermal@91a0000 {
+ thermal: thermal@91a0000 {
compatible = "st,stih407-thermal";
reg = <0x91a0000 0x28>;
clock-names = "thermal";
clocks = <&clk_sysin>;
interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
+ #thermal-sensor-cells = <0>;
};
};
};
diff --git a/arch/arm/boot/dts/st/stm32f429.dtsi b/arch/arm/boot/dts/st/stm32f429.dtsi
index 8efcda9ef8ae..ad91b74ddd0d 100644
--- a/arch/arm/boot/dts/st/stm32f429.dtsi
+++ b/arch/arm/boot/dts/st/stm32f429.dtsi
@@ -579,6 +579,7 @@
syscfg: syscon@40013800 {
compatible = "st,stm32-syscfg", "syscon";
reg = <0x40013800 0x400>;
+ clocks = <&rcc 0 STM32F4_APB2_CLOCK(SYSCFG)>;
};
exti: interrupt-controller@40013c00 {
diff --git a/arch/arm/boot/dts/st/stm32f746.dtsi b/arch/arm/boot/dts/st/stm32f746.dtsi
index 65c72b6fcc83..2537b3d47e6f 100644
--- a/arch/arm/boot/dts/st/stm32f746.dtsi
+++ b/arch/arm/boot/dts/st/stm32f746.dtsi
@@ -257,23 +257,6 @@
status = "disabled";
};
- can3: can@40003400 {
- compatible = "st,stm32f4-bxcan";
- reg = <0x40003400 0x200>;
- interrupts = <104>, <105>, <106>, <107>;
- interrupt-names = "tx", "rx0", "rx1", "sce";
- resets = <&rcc STM32F7_APB1_RESET(CAN3)>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
- st,gcan = <&gcan3>;
- status = "disabled";
- };
-
- gcan3: gcan@40003600 {
- compatible = "st,stm32f4-gcan", "syscon";
- reg = <0x40003600 0x200>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
- };
-
spi2: spi@40003800 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/st/stm32f769.dtsi b/arch/arm/boot/dts/st/stm32f769.dtsi
index 4e7d9032149c..e8cbb99e81a6 100644
--- a/arch/arm/boot/dts/st/stm32f769.dtsi
+++ b/arch/arm/boot/dts/st/stm32f769.dtsi
@@ -7,6 +7,23 @@
/ {
soc {
+ can3: can@40003400 {
+ compatible = "st,stm32f4-bxcan";
+ reg = <0x40003400 0x200>;
+ interrupts = <104>, <105>, <106>, <107>;
+ interrupt-names = "tx", "rx0", "rx1", "sce";
+ resets = <&rcc STM32F7_APB1_RESET(CAN3)>;
+ clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
+ st,gcan = <&gcan3>;
+ status = "disabled";
+ };
+
+ gcan3: gcan@40003600 {
+ compatible = "st,stm32f4-gcan", "syscon";
+ reg = <0x40003600 0x200>;
+ clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
+ };
+
dsi: dsi@40016c00 {
compatible = "st,stm32-dsi";
reg = <0x40016c00 0x800>;
diff --git a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
index 27e0c3826789..c9f588a65094 100644
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -6,6 +6,14 @@
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
&pinctrl {
+ /omit-if-no-ref/
+ adc1_pins_a: adc1-pins-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 3, ANALOG)>; /* ADC1 in12 */
+ };
+ };
+
+ /omit-if-no-ref/
adc1_usb_cc_pins_a: adc1-usb-cc-pins-0 {
pins {
pinmux = <STM32_PINMUX('F', 12, ANALOG)>, /* ADC1 in6 */
@@ -13,6 +21,241 @@
};
};
+ /omit-if-no-ref/
+ adc1_usb_cc_pins_b: adc1-usb-cc-pins-1 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 5, ANALOG)>, /* ADC1_INP2 */
+ <STM32_PINMUX('F', 13, ANALOG)>; /* ADC1_INP11 */
+ };
+ };
+
+ /omit-if-no-ref/
+ dcmipp_pins_a: dcmi-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 8, AF13)>,/* DCMI_HSYNC */
+ <STM32_PINMUX('G', 9, AF13)>,/* DCMI_VSYNC */
+ <STM32_PINMUX('B', 7, AF14)>,/* DCMI_PIXCLK */
+ <STM32_PINMUX('A', 9, AF13)>,/* DCMI_D0 */
+ <STM32_PINMUX('D', 0, AF13)>,/* DCMI_D1 */
+ <STM32_PINMUX('G', 10, AF13)>,/* DCMI_D2 */
+ <STM32_PINMUX('E', 4, AF13)>,/* DCMI_D3 */
+ <STM32_PINMUX('D', 11, AF14)>,/* DCMI_D4 */
+ <STM32_PINMUX('D', 3, AF13)>,/* DCMI_D5 */
+ <STM32_PINMUX('B', 8, AF13)>,/* DCMI_D6 */
+ <STM32_PINMUX('E', 14, AF13)>;/* DCMI_D7 */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ dcmipp_sleep_pins_a: dcmi-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 8, ANALOG)>,/* DCMI_HSYNC */
+ <STM32_PINMUX('G', 9, ANALOG)>,/* DCMI_VSYNC */
+ <STM32_PINMUX('B', 7, ANALOG)>,/* DCMI_PIXCLK */
+ <STM32_PINMUX('A', 9, ANALOG)>,/* DCMI_D0 */
+ <STM32_PINMUX('D', 0, ANALOG)>,/* DCMI_D1 */
+ <STM32_PINMUX('G', 10, ANALOG)>,/* DCMI_D2 */
+ <STM32_PINMUX('E', 4, ANALOG)>,/* DCMI_D3 */
+ <STM32_PINMUX('D', 11, ANALOG)>,/* DCMI_D4 */
+ <STM32_PINMUX('D', 3, ANALOG)>,/* DCMI_D5 */
+ <STM32_PINMUX('B', 8, ANALOG)>,/* DCMI_D6 */
+ <STM32_PINMUX('E', 14, ANALOG)>;/* DCMI_D7 */
+ };
+ };
+
+ /omit-if-no-ref/
+ eth1_rgmii_pins_a: eth1-rgmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 5, AF10)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('C', 1, AF11)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 7, AF11)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('D', 7, AF10)>; /* ETH_RGMII_RX_CLK */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ eth1_rgmii_sleep_pins_a: eth1-rgmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 5, ANALOG)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('A', 7, ANALOG)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('D', 7, ANALOG)>; /* ETH_RGMII_RX_CLK */
+ };
+ };
+
+ /omit-if-no-ref/
+ eth1_rmii_pins_a: eth1-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, AF11)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, AF10)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ eth1_rmii_sleep_pins_a: eth1-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
+ /omit-if-no-ref/
+ eth2_rgmii_pins_a: eth2-rgmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, AF11)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 11, AF10)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('G', 1, AF10)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 6, AF11)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('F', 6, AF11)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('G', 3, AF10)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('B', 6, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, AF10)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 4, AF11)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('E', 2, AF10)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('H', 6, AF12)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('A', 8, AF11)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 12, AF11)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('H', 11, AF11)>; /* ETH_RGMII_RX_CLK */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ eth2_rgmii_sleep_pins_a: eth2-rgmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 11, ANALOG)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('G', 1, ANALOG)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 6, ANALOG)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('F', 6, ANALOG)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('G', 3, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('B', 6, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('F', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('H', 6, ANALOG)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('A', 8, ANALOG)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 12, ANALOG)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('H', 11, ANALOG)>; /* ETH_RGMII_RX_CLK */
+ };
+ };
+
+ /omit-if-no-ref/
+ eth2_rmii_pins_a: eth2-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, AF10)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, AF13)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, AF10)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, AF10)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, AF11)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ eth2_rmii_sleep_pins_a: eth2-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('F', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
+ /omit-if-no-ref/
+ goodix_pins_a: goodix-0 {
+ /*
+ * touchscreen reset needs to be configured
+ * via the pinctrl not the driver (a pull-down resistor
+ * has been soldered onto the reset line which forces
+ * the touchscreen to reset state).
+ */
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 2, GPIO)>;
+ output-high;
+ bias-pull-up;
+ };
+ /*
+ * Interrupt line must have a pull-down resistor
+ * in order to freeze the i2c address at 0x5D
+ */
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 5, GPIO)>;
+ bias-pull-down;
+ };
+ };
+
+ /omit-if-no-ref/
i2c1_pins_a: i2c1-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
@@ -23,6 +266,7 @@
};
};
+ /omit-if-no-ref/
i2c1_sleep_pins_a: i2c1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, ANALOG)>, /* I2C1_SCL */
@@ -30,6 +274,7 @@
};
};
+ /omit-if-no-ref/
i2c5_pins_a: i2c5-0 {
pins {
pinmux = <STM32_PINMUX('D', 1, AF4)>, /* I2C5_SCL */
@@ -40,6 +285,7 @@
};
};
+ /omit-if-no-ref/
i2c5_sleep_pins_a: i2c5-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 1, ANALOG)>, /* I2C5_SCL */
@@ -47,6 +293,129 @@
};
};
+ /omit-if-no-ref/
+ i2c5_pins_b: i2c5-1 {
+ pins {
+ pinmux = <STM32_PINMUX('D', 1, AF4)>, /* I2C5_SCL */
+ <STM32_PINMUX('E', 13, AF4)>; /* I2C5_SDA */
+ bias-disable;
+ drive-open-drain;
+ slew-rate = <0>;
+ };
+ };
+
+ /omit-if-no-ref/
+ i2c5_sleep_pins_b: i2c5-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('D', 1, ANALOG)>, /* I2C5_SCL */
+ <STM32_PINMUX('E', 13, ANALOG)>; /* I2C5_SDA */
+ };
+ };
+
+ /omit-if-no-ref/
+ ltdc_pins_a: ltdc-0 {
+ pins {
+ pinmux = <STM32_PINMUX('D', 9, AF13)>, /* LCD_CLK */
+ <STM32_PINMUX('C', 6, AF14)>, /* LCD_HSYNC */
+ <STM32_PINMUX('G', 4, AF11)>, /* LCD_VSYNC */
+ <STM32_PINMUX('H', 9, AF11)>, /* LCD_DE */
+ <STM32_PINMUX('G', 7, AF14)>, /* LCD_R2 */
+ <STM32_PINMUX('B', 12, AF13)>, /* LCD_R3 */
+ <STM32_PINMUX('D', 14, AF14)>, /* LCD_R4 */
+ <STM32_PINMUX('E', 7, AF14)>, /* LCD_R5 */
+ <STM32_PINMUX('E', 13, AF14)>, /* LCD_R6 */
+ <STM32_PINMUX('E', 9, AF14)>, /* LCD_R7 */
+ <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+ <STM32_PINMUX('F', 3, AF14)>, /* LCD_G3 */
+ <STM32_PINMUX('D', 5, AF14)>, /* LCD_G4 */
+ <STM32_PINMUX('G', 0, AF14)>, /* LCD_G5 */
+ <STM32_PINMUX('C', 7, AF14)>, /* LCD_G6 */
+ <STM32_PINMUX('A', 15, AF11)>, /* LCD_G7 */
+ <STM32_PINMUX('D', 10, AF14)>, /* LCD_B2 */
+ <STM32_PINMUX('F', 2, AF14)>, /* LCD_B3 */
+ <STM32_PINMUX('H', 14, AF11)>, /* LCD_B4 */
+ <STM32_PINMUX('E', 0, AF14)>, /* LCD_B5 */
+ <STM32_PINMUX('B', 6, AF7)>, /* LCD_B6 */
+ <STM32_PINMUX('F', 1, AF13)>; /* LCD_B7 */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ };
+
+ /omit-if-no-ref/
+ ltdc_sleep_pins_a: ltdc-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('D', 9, ANALOG)>, /* LCD_CLK */
+ <STM32_PINMUX('C', 6, ANALOG)>, /* LCD_HSYNC */
+ <STM32_PINMUX('G', 4, ANALOG)>, /* LCD_VSYNC */
+ <STM32_PINMUX('H', 9, ANALOG)>, /* LCD_DE */
+ <STM32_PINMUX('G', 7, ANALOG)>, /* LCD_R2 */
+ <STM32_PINMUX('B', 12, ANALOG)>, /* LCD_R3 */
+ <STM32_PINMUX('D', 14, ANALOG)>, /* LCD_R4 */
+ <STM32_PINMUX('E', 7, ANALOG)>, /* LCD_R5 */
+ <STM32_PINMUX('E', 13, ANALOG)>, /* LCD_R6 */
+ <STM32_PINMUX('E', 9, ANALOG)>, /* LCD_R7 */
+ <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+ <STM32_PINMUX('F', 3, ANALOG)>, /* LCD_G3 */
+ <STM32_PINMUX('D', 5, ANALOG)>, /* LCD_G4 */
+ <STM32_PINMUX('G', 0, ANALOG)>, /* LCD_G5 */
+ <STM32_PINMUX('C', 7, ANALOG)>, /* LCD_G6 */
+ <STM32_PINMUX('A', 15, ANALOG)>, /* LCD_G7 */
+ <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B2 */
+ <STM32_PINMUX('F', 2, ANALOG)>, /* LCD_B3 */
+ <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_B4 */
+ <STM32_PINMUX('E', 0, ANALOG)>, /* LCD_B5 */
+ <STM32_PINMUX('B', 6, ANALOG)>, /* LCD_B6 */
+ <STM32_PINMUX('F', 1, ANALOG)>; /* LCD_B7 */
+ };
+ };
+
+ /omit-if-no-ref/
+ m_can1_pins_a: m-can1-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 10, AF9)>; /* CAN1_TX */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 0, AF9)>; /* CAN1_RX */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ m_can1_sleep_pins_a: m_can1-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('G', 10, ANALOG)>, /* CAN1_TX */
+ <STM32_PINMUX('D', 0, ANALOG)>; /* CAN1_RX */
+ };
+ };
+
+ /omit-if-no-ref/
+ m_can2_pins_a: m-can2-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 0, AF9)>; /* CAN2_TX */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 0, AF9)>; /* CAN2_RX */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ m_can2_sleep_pins_a: m_can2-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('G', 0, ANALOG)>, /* CAN2_TX */
+ <STM32_PINMUX('E', 0, ANALOG)>; /* CAN2_RX */
+ };
+ };
+
+ /omit-if-no-ref/
mcp23017_pins_a: mcp23017-0 {
pins {
pinmux = <STM32_PINMUX('G', 12, GPIO)>;
@@ -54,6 +423,7 @@
};
};
+ /omit-if-no-ref/
pwm3_pins_a: pwm3-0 {
pins {
pinmux = <STM32_PINMUX('B', 1, AF2)>; /* TIM3_CH4 */
@@ -63,12 +433,14 @@
};
};
+ /omit-if-no-ref/
pwm3_sleep_pins_a: pwm3-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 1, ANALOG)>; /* TIM3_CH4 */
};
};
+ /omit-if-no-ref/
pwm4_pins_a: pwm4-0 {
pins {
pinmux = <STM32_PINMUX('D', 13, AF2)>; /* TIM4_CH2 */
@@ -78,12 +450,31 @@
};
};
+ /omit-if-no-ref/
pwm4_sleep_pins_a: pwm4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 13, ANALOG)>; /* TIM4_CH2 */
};
};
+ /omit-if-no-ref/
+ pwm5_pins_a: pwm5-0 {
+ pins {
+ pinmux = <STM32_PINMUX('H', 12, AF2)>; /* TIM5_CH3 */
+ bias-pull-down;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ };
+
+ /omit-if-no-ref/
+ pwm5_sleep_pins_a: pwm5-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('H', 12, ANALOG)>; /* TIM5_CH3 */
+ };
+ };
+
+ /omit-if-no-ref/
pwm8_pins_a: pwm8-0 {
pins {
pinmux = <STM32_PINMUX('E', 5, AF3)>; /* TIM8_CH3 */
@@ -93,12 +484,31 @@
};
};
+ /omit-if-no-ref/
pwm8_sleep_pins_a: pwm8-sleep-0 {
pins {
pinmux = <STM32_PINMUX('E', 5, ANALOG)>; /* TIM8_CH3 */
};
};
+ /omit-if-no-ref/
+ pwm13_pins_a: pwm13-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 6, AF9)>; /* TIM13_CH1 */
+ bias-pull-down;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ };
+
+ /omit-if-no-ref/
+ pwm13_sleep_pins_a: pwm13-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 6, ANALOG)>; /* TIM13_CH1 */
+ };
+ };
+
+ /omit-if-no-ref/
pwm14_pins_a: pwm14-0 {
pins {
pinmux = <STM32_PINMUX('F', 9, AF9)>; /* TIM14_CH1 */
@@ -108,12 +518,107 @@
};
};
+ /omit-if-no-ref/
pwm14_sleep_pins_a: pwm14-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 9, ANALOG)>; /* TIM14_CH1 */
};
};
+ /omit-if-no-ref/
+ qspi_clk_pins_a: qspi-clk-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <3>;
+ };
+ };
+
+ /omit-if-no-ref/
+ qspi_clk_sleep_pins_a: qspi-clk-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 10, ANALOG)>; /* QSPI_CLK */
+ };
+ };
+
+ /omit-if-no-ref/
+ qspi_bk1_pins_a: qspi-bk1-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
+ <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
+ <STM32_PINMUX('D', 11, AF9)>, /* QSPI_BK1_IO2 */
+ <STM32_PINMUX('H', 7, AF13)>; /* QSPI_BK1_IO3 */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ };
+
+ /omit-if-no-ref/
+ qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 8, ANALOG)>, /* QSPI_BK1_IO0 */
+ <STM32_PINMUX('F', 9, ANALOG)>, /* QSPI_BK1_IO1 */
+ <STM32_PINMUX('D', 11, ANALOG)>, /* QSPI_BK1_IO2 */
+ <STM32_PINMUX('H', 7, ANALOG)>; /* QSPI_BK1_IO3 */
+ };
+ };
+
+ /omit-if-no-ref/
+ qspi_cs1_pins_a: qspi-cs1-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 2, AF9)>; /* QSPI_BK1_NCS */
+ bias-pull-up;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ };
+
+ /omit-if-no-ref/
+ qspi_cs1_sleep_pins_a: qspi-cs1-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 2, ANALOG)>; /* QSPI_BK1_NCS */
+ };
+ };
+
+ /omit-if-no-ref/
+ sai1a_pins_a: sai1a-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 4, AF12)>, /* SAI1_SCK_A */
+ <STM32_PINMUX('D', 6, AF6)>, /* SAI1_SD_A */
+ <STM32_PINMUX('E', 11, AF6)>; /* SAI1_FS_A */
+ slew-rate = <0>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ sai1a_sleep_pins_a: sai1a-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* SAI1_SCK_A */
+ <STM32_PINMUX('D', 6, ANALOG)>, /* SAI1_SD_A */
+ <STM32_PINMUX('E', 11, ANALOG)>; /* SAI1_FS_A */
+ };
+ };
+
+ /omit-if-no-ref/
+ sai1b_pins_a: sai1b-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 0, AF6)>; /* SAI1_SD_B */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ sai1b_sleep_pins_a: sai1b-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 0, ANALOG)>; /* SAI1_SD_B */
+ };
+ };
+
+ /omit-if-no-ref/
sdmmc1_b4_pins_a: sdmmc1-b4-0 {
pins {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -127,6 +632,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -145,6 +651,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
@@ -156,6 +663,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_clk_pins_a: sdmmc1-clk-0 {
pins {
pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
@@ -165,6 +673,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
pins {
pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
@@ -178,6 +687,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
@@ -196,6 +706,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
@@ -207,6 +718,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_clk_pins_a: sdmmc2-clk-0 {
pins {
pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC2_CK */
@@ -216,6 +728,80 @@
};
};
+ /omit-if-no-ref/
+ sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 0, AF10)>, /* SDMMC2_D4 */
+ <STM32_PINMUX('B', 9, AF10)>, /* SDMMC2_D5 */
+ <STM32_PINMUX('C', 6, AF10)>, /* SDMMC2_D6 */
+ <STM32_PINMUX('C', 7, AF10)>; /* SDMMC2_D7 */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ /omit-if-no-ref/
+ sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 0, ANALOG)>, /* SDMMC2_D4 */
+ <STM32_PINMUX('B', 9, ANALOG)>, /* SDMMC2_D5 */
+ <STM32_PINMUX('C', 6, ANALOG)>, /* SDMMC2_D6 */
+ <STM32_PINMUX('C', 7, ANALOG)>; /* SDMMC2_D7 */
+ };
+ };
+
+ /omit-if-no-ref/
+ spi2_pins_a: spi2-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, AF6)>, /* SPI2_SCK */
+ <STM32_PINMUX('H', 10, AF6)>; /* SPI2_MOSI */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 5, AF5)>; /* SPI2_MISO */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ spi2_sleep_pins_a: spi2-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* SPI2_SCK */
+ <STM32_PINMUX('B', 5, ANALOG)>, /* SPI2_MISO */
+ <STM32_PINMUX('H', 10, ANALOG)>; /* SPI2_MOSI */
+ };
+ };
+
+ /omit-if-no-ref/
+ spi3_pins_a: spi3-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 13, AF6)>, /* SPI3_SCK */
+ <STM32_PINMUX('F', 1, AF5)>; /* SPI3_MOSI */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 4, AF5)>; /* SPI3_MISO */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ spi3_sleep_pins_a: spi3-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* SPI3_SCK */
+ <STM32_PINMUX('D', 4, ANALOG)>, /* SPI3_MISO */
+ <STM32_PINMUX('F', 1, ANALOG)>; /* SPI3_MOSI */
+ };
+ };
+
+ /omit-if-no-ref/
spi5_pins_a: spi5-0 {
pins1 {
pinmux = <STM32_PINMUX('H', 7, AF6)>, /* SPI5_SCK */
@@ -231,6 +817,7 @@
};
};
+ /omit-if-no-ref/
spi5_sleep_pins_a: spi5-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 7, ANALOG)>, /* SPI5_SCK */
@@ -239,6 +826,7 @@
};
};
+ /omit-if-no-ref/
stm32g0_intn_pins_a: stm32g0-intn-0 {
pins {
pinmux = <STM32_PINMUX('I', 2, GPIO)>;
@@ -246,6 +834,7 @@
};
};
+ /omit-if-no-ref/
uart4_pins_a: uart4-0 {
pins1 {
pinmux = <STM32_PINMUX('D', 6, AF8)>; /* UART4_TX */
@@ -259,6 +848,7 @@
};
};
+ /omit-if-no-ref/
uart4_idle_pins_a: uart4-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('D', 6, ANALOG)>; /* UART4_TX */
@@ -269,6 +859,7 @@
};
};
+ /omit-if-no-ref/
uart4_sleep_pins_a: uart4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 6, ANALOG)>, /* UART4_TX */
@@ -276,6 +867,84 @@
};
};
+ /omit-if-no-ref/
+ uart4_pins_b: uart4-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('A', 9, AF8)>; /* UART4_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 8, AF8)>; /* UART4_RX */
+ bias-pull-up;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_idle_pins_b: uart4-idle-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('A', 9, ANALOG)>; /* UART4_TX */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 8, AF8)>; /* UART4_RX */
+ bias-pull-up;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_sleep_pins_b: uart4-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 9, ANALOG)>, /* UART4_TX */
+ <STM32_PINMUX('D', 8, ANALOG)>; /* UART4_RX */
+ };
+ };
+
+ /omit-if-no-ref/
+ uart7_pins_a: uart7-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 2, AF8)>, /* UART7_TX */
+ <STM32_PINMUX('B', 12, AF7)>; /* UART7_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 10, AF7)>, /* UART7_RX */
+ <STM32_PINMUX('G', 7, AF8)>; /* UART7_CTS_NSS */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart7_idle_pins_a: uart7-idle-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* UART7_TX */
+ <STM32_PINMUX('G', 7, ANALOG)>; /* UART7_CTS_NSS */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 12, AF7)>; /* UART7_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('E', 10, AF7)>; /* UART7_RX */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart7_sleep_pins_a: uart7-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* UART7_TX */
+ <STM32_PINMUX('B', 12, ANALOG)>, /* UART7_RTS */
+ <STM32_PINMUX('E', 10, ANALOG)>, /* UART7_RX */
+ <STM32_PINMUX('G', 7, ANALOG)>; /* UART7_CTS_NSS */
+ };
+ };
+
+ /omit-if-no-ref/
uart8_pins_a: uart8-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */
@@ -289,6 +958,7 @@
};
};
+ /omit-if-no-ref/
uart8_idle_pins_a: uart8-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 1, ANALOG)>; /* UART8_TX */
@@ -299,6 +969,7 @@
};
};
+ /omit-if-no-ref/
uart8_sleep_pins_a: uart8-sleep-0 {
pins {
pinmux = <STM32_PINMUX('E', 1, ANALOG)>, /* UART8_TX */
@@ -306,6 +977,7 @@
};
};
+ /omit-if-no-ref/
usart1_pins_a: usart1-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 0, AF7)>, /* USART1_TX */
@@ -321,6 +993,7 @@
};
};
+ /omit-if-no-ref/
usart1_idle_pins_a: usart1-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 0, ANALOG)>, /* USART1_TX */
@@ -338,6 +1011,7 @@
};
};
+ /omit-if-no-ref/
usart1_sleep_pins_a: usart1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('C', 0, ANALOG)>, /* USART1_TX */
@@ -347,6 +1021,40 @@
};
};
+ /omit-if-no-ref/
+ usart1_pins_b: usart1-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('C', 0, AF7)>; /* USART1_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 14, AF7)>; /* USART1_RX */
+ bias-pull-up;
+ };
+ };
+
+ /omit-if-no-ref/
+ usart1_idle_pins_b: usart1-idle-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('C', 0, ANALOG)>; /* USART1_TX */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 14, AF7)>; /* USART1_RX */
+ bias-pull-up;
+ };
+ };
+
+ /omit-if-no-ref/
+ usart1_sleep_pins_b: usart1-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 0, ANALOG)>, /* USART1_TX */
+ <STM32_PINMUX('D', 14, ANALOG)>; /* USART1_RX */
+ };
+ };
+
+ /omit-if-no-ref/
usart2_pins_a: usart2-0 {
pins1 {
pinmux = <STM32_PINMUX('H', 12, AF1)>, /* USART2_TX */
@@ -362,6 +1070,7 @@
};
};
+ /omit-if-no-ref/
usart2_idle_pins_a: usart2-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('H', 12, ANALOG)>, /* USART2_TX */
@@ -379,6 +1088,7 @@
};
};
+ /omit-if-no-ref/
usart2_sleep_pins_a: usart2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 12, ANALOG)>, /* USART2_TX */
@@ -387,4 +1097,48 @@
<STM32_PINMUX('E', 11, ANALOG)>; /* USART2_CTS_NSS */
};
};
+
+ /omit-if-no-ref/
+ usart2_pins_b: usart2-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 11, AF1)>, /* USART2_TX */
+ <STM32_PINMUX('A', 1, AF7)>; /* USART2_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 15, AF1)>, /* USART2_RX */
+ <STM32_PINMUX('E', 15, AF3)>; /* USART2_CTS_NSS */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ usart2_idle_pins_b: usart2-idle-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* USART2_TX */
+ <STM32_PINMUX('E', 15, ANALOG)>; /* USART2_CTS_NSS */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('A', 1, AF7)>; /* USART2_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('D', 15, AF1)>; /* USART2_RX */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ usart2_sleep_pins_b: usart2-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* USART2_TX */
+ <STM32_PINMUX('A', 1, ANALOG)>, /* USART2_RTS */
+ <STM32_PINMUX('D', 15, ANALOG)>, /* USART2_RX */
+ <STM32_PINMUX('E', 15, ANALOG)>; /* USART2_CTS_NSS */
+ };
+ };
};
diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index 3900f32da797..e1a764d269d2 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -745,340 +745,6 @@
dma-channels = <16>;
};
- adc_2: adc@48004000 {
- compatible = "st,stm32mp13-adc-core";
- reg = <0x48004000 0x400>;
- interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc ADC2>, <&rcc ADC2_K>;
- clock-names = "bus", "adc";
- interrupt-controller;
- #interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- adc2: adc@0 {
- compatible = "st,stm32mp13-adc";
- #io-channel-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0>;
- interrupt-parent = <&adc_2>;
- interrupts = <0>;
- dmas = <&dmamux1 10 0x400 0x80000001>;
- dma-names = "rx";
- status = "disabled";
-
- channel@13 {
- reg = <13>;
- label = "vrefint";
- };
- channel@14 {
- reg = <14>;
- label = "vddcore";
- };
- channel@16 {
- reg = <16>;
- label = "vddcpu";
- };
- channel@17 {
- reg = <17>;
- label = "vddq_ddr";
- };
- };
- };
-
- usbotg_hs: usb@49000000 {
- compatible = "st,stm32mp15-hsotg", "snps,dwc2";
- reg = <0x49000000 0x40000>;
- clocks = <&rcc USBO_K>;
- clock-names = "otg";
- resets = <&rcc USBO_R>;
- reset-names = "dwc2";
- interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
- g-rx-fifo-size = <512>;
- g-np-tx-fifo-size = <32>;
- g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
- dr_mode = "otg";
- otg-rev = <0x200>;
- usb33d-supply = <&scmi_usb33>;
- status = "disabled";
- };
-
- usart1: serial@4c000000 {
- compatible = "st,stm32h7-uart";
- reg = <0x4c000000 0x400>;
- interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc USART1_K>;
- resets = <&rcc USART1_R>;
- wakeup-source;
- dmas = <&dmamux1 41 0x400 0x5>,
- <&dmamux1 42 0x400 0x1>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- usart2: serial@4c001000 {
- compatible = "st,stm32h7-uart";
- reg = <0x4c001000 0x400>;
- interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc USART2_K>;
- resets = <&rcc USART2_R>;
- wakeup-source;
- dmas = <&dmamux1 43 0x400 0x5>,
- <&dmamux1 44 0x400 0x1>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2s4: audio-controller@4c002000 {
- compatible = "st,stm32h7-i2s";
- reg = <0x4c002000 0x400>;
- #sound-dai-cells = <0>;
- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 83 0x400 0x01>,
- <&dmamux1 84 0x400 0x01>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi4: spi@4c002000 {
- compatible = "st,stm32h7-spi";
- reg = <0x4c002000 0x400>;
- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI4_K>;
- resets = <&rcc SPI4_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- dmas = <&dmamux1 83 0x400 0x01>,
- <&dmamux1 84 0x400 0x01>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi5: spi@4c003000 {
- compatible = "st,stm32h7-spi";
- reg = <0x4c003000 0x400>;
- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI5_K>;
- resets = <&rcc SPI5_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- dmas = <&dmamux1 85 0x400 0x01>,
- <&dmamux1 86 0x400 0x01>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c3: i2c@4c004000 {
- compatible = "st,stm32mp13-i2c";
- reg = <0x4c004000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C3_K>;
- resets = <&rcc I2C3_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- dmas = <&dmamux1 73 0x400 0x1>,
- <&dmamux1 74 0x400 0x1>;
- dma-names = "rx", "tx";
- st,syscfg-fmp = <&syscfg 0x4 0x4>;
- i2c-analog-filter;
- status = "disabled";
- };
-
- i2c4: i2c@4c005000 {
- compatible = "st,stm32mp13-i2c";
- reg = <0x4c005000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C4_K>;
- resets = <&rcc I2C4_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- dmas = <&dmamux1 75 0x400 0x1>,
- <&dmamux1 76 0x400 0x1>;
- dma-names = "rx", "tx";
- st,syscfg-fmp = <&syscfg 0x4 0x8>;
- i2c-analog-filter;
- status = "disabled";
- };
-
- i2c5: i2c@4c006000 {
- compatible = "st,stm32mp13-i2c";
- reg = <0x4c006000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C5_K>;
- resets = <&rcc I2C5_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- dmas = <&dmamux1 115 0x400 0x1>,
- <&dmamux1 116 0x400 0x1>;
- dma-names = "rx", "tx";
- st,syscfg-fmp = <&syscfg 0x4 0x10>;
- i2c-analog-filter;
- status = "disabled";
- };
-
- timers12: timer@4c007000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x4c007000 0x400>;
- interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM12_K>;
- clock-names = "int";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@11 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <11>;
- status = "disabled";
- };
- };
-
- timers13: timer@4c008000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x4c008000 0x400>;
- interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM13_K>;
- clock-names = "int";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@12 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <12>;
- status = "disabled";
- };
- };
-
- timers14: timer@4c009000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x4c009000 0x400>;
- interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM14_K>;
- clock-names = "int";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@13 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <13>;
- status = "disabled";
- };
- };
-
- timers15: timer@4c00a000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x4c00a000 0x400>;
- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM15_K>;
- clock-names = "int";
- dmas = <&dmamux1 105 0x400 0x1>,
- <&dmamux1 106 0x400 0x1>,
- <&dmamux1 107 0x400 0x1>,
- <&dmamux1 108 0x400 0x1>;
- dma-names = "ch1", "up", "trig", "com";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@14 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <14>;
- status = "disabled";
- };
- };
-
- timers16: timer@4c00b000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x4c00b000 0x400>;
- interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM16_K>;
- clock-names = "int";
- dmas = <&dmamux1 109 0x400 0x1>,
- <&dmamux1 110 0x400 0x1>;
- dma-names = "ch1", "up";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@15 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <15>;
- status = "disabled";
- };
- };
-
- timers17: timer@4c00c000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x4c00c000 0x400>;
- interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM17_K>;
- clock-names = "int";
- dmas = <&dmamux1 111 0x400 0x1>,
- <&dmamux1 112 0x400 0x1>;
- dma-names = "ch1", "up";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@16 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <16>;
- status = "disabled";
- };
- };
-
rcc: rcc@50000000 {
compatible = "st,stm32mp13-rcc", "syscon";
reg = <0x50000000 0x1000>;
@@ -1092,80 +758,113 @@
<&scmi_clk CK_SCMI_LSI>;
};
- exti: interrupt-controller@5000d000 {
- compatible = "st,stm32mp13-exti", "syscon";
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x5000d000 0x400>;
- };
-
- syscfg: syscon@50020000 {
- compatible = "st,stm32mp157-syscfg", "syscon";
- reg = <0x50020000 0x400>;
- clocks = <&rcc SYSCFG>;
- };
-
- lptimer2: timer@50021000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-lptimer";
- reg = <0x50021000 0x400>;
- interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM2_K>;
- clock-names = "mux";
- wakeup-source;
+ pwr_regulators: pwr@50001000 {
+ compatible = "st,stm32mp1,pwr-reg";
+ reg = <0x50001000 0x10>;
status = "disabled";
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
+ reg11: reg11 {
+ regulator-name = "reg11";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
};
- trigger@1 {
- compatible = "st,stm32-lptimer-trigger";
- reg = <1>;
- status = "disabled";
+ reg18: reg18 {
+ regulator-name = "reg18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
};
- counter {
- compatible = "st,stm32-lptimer-counter";
- status = "disabled";
- };
-
- timer {
- compatible = "st,stm32-lptimer-timer";
- status = "disabled";
+ usb33: usb33 {
+ regulator-name = "usb33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
};
};
- lptimer3: timer@50022000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-lptimer";
- reg = <0x50022000 0x400>;
- interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM3_K>;
- clock-names = "mux";
- wakeup-source;
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- trigger@2 {
- compatible = "st,stm32-lptimer-trigger";
- reg = <2>;
- status = "disabled";
- };
+ exti: interrupt-controller@5000d000 {
+ compatible = "st,stm32mp1-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000d000 0x400>;
+ interrupts-extended =
+ <&intc GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_0 */
+ <&intc GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_10 */
+ <&intc GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0>, /* EXTI_20 */
+ <&intc GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_30 */
+ <&intc GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>, /* EXTI_40 */
+ <0>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_50 */
+ <0>,
+ <&intc GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>, /* EXTI_60 */
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* EXTI_70 */
+ };
- timer {
- compatible = "st,stm32-lptimer-timer";
- status = "disabled";
- };
+ syscfg: syscon@50020000 {
+ compatible = "st,stm32mp157-syscfg", "syscon";
+ reg = <0x50020000 0x400>;
+ clocks = <&rcc SYSCFG>;
};
lptimer4: timer@50023000 {
@@ -1210,25 +909,6 @@
};
};
- hash: hash@54003000 {
- compatible = "st,stm32mp13-hash";
- reg = <0x54003000 0x400>;
- interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc HASH1>;
- resets = <&rcc HASH1_R>;
- dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
- dma-names = "in";
- status = "disabled";
- };
-
- rng: rng@54004000 {
- compatible = "st,stm32mp13-rng";
- reg = <0x54004000 0x400>;
- clocks = <&rcc RNG1_K>;
- resets = <&rcc RNG1_R>;
- status = "disabled";
- };
-
mdma: dma-controller@58000000 {
compatible = "st,stm32h7-mdma";
reg = <0x58000000 0x1000>;
@@ -1239,82 +919,6 @@
dma-requests = <48>;
};
- fmc: memory-controller@58002000 {
- compatible = "st,stm32mp1-fmc2-ebi";
- reg = <0x58002000 0x1000>;
- 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 */
- #address-cells = <2>;
- #size-cells = <1>;
- clocks = <&rcc FMC_K>;
- resets = <&rcc FMC_R>;
- status = "disabled";
-
- nand-controller@4,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>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&mdma 24 0x2 0x12000a02 0x0 0x0>,
- <&mdma 24 0x2 0x12000a08 0x0 0x0>,
- <&mdma 25 0x2 0x12000a0a 0x0 0x0>;
- dma-names = "tx", "rx", "ecc";
- status = "disabled";
- };
- };
-
- qspi: spi@58003000 {
- compatible = "st,stm32f469-qspi";
- reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
- reg-names = "qspi", "qspi_mm";
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&mdma 26 0x2 0x10100002 0x0 0x0>,
- <&mdma 26 0x2 0x10100008 0x0 0x0>;
- dma-names = "tx", "rx";
- clocks = <&rcc QSPI_K>;
- resets = <&rcc QSPI_R>;
- status = "disabled";
- };
-
- sdmmc1: mmc@58005000 {
- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
- arm,primecell-periphid = <0x20253180>;
- reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
- interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SDMMC1_K>;
- clock-names = "apb_pclk";
- resets = <&rcc SDMMC1_R>;
- cap-sd-highspeed;
- cap-mmc-highspeed;
- max-frequency = <130000000>;
- status = "disabled";
- };
-
- sdmmc2: mmc@58007000 {
- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
- arm,primecell-periphid = <0x20253180>;
- reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SDMMC2_K>;
- clock-names = "apb_pclk";
- resets = <&rcc SDMMC2_R>;
- cap-sd-highspeed;
- cap-mmc-highspeed;
- max-frequency = <130000000>;
- status = "disabled";
- };
-
crc1: crc@58009000 {
compatible = "st,stm32f7-crc";
reg = <0x58009000 0x400>;
@@ -1349,29 +953,6 @@
status = "disabled";
};
- usbphyc: usbphyc@5a006000 {
- #address-cells = <1>;
- #size-cells = <0>;
- #clock-cells = <0>;
- compatible = "st,stm32mp1-usbphyc";
- reg = <0x5a006000 0x1000>;
- clocks = <&rcc USBPHY_K>;
- resets = <&rcc USBPHY_R>;
- vdda1v1-supply = <&scmi_reg11>;
- vdda1v8-supply = <&scmi_reg18>;
- status = "disabled";
-
- usbphyc_port0: usb-phy@0 {
- #phy-cells = <0>;
- reg = <0>;
- };
-
- usbphyc_port1: usb-phy@1 {
- #phy-cells = <1>;
- reg = <1>;
- };
- };
-
rtc: rtc@5c004000 {
compatible = "st,stm32mp1-rtc";
reg = <0x5c004000 0x400>;
@@ -1398,6 +979,593 @@
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
+ ethernet_mac1_address: mac1@e4 {
+ reg = <0xe4 0x6>;
+ };
+ ethernet_mac2_address: mac2@ea {
+ reg = <0xea 0x6>;
+ };
+ };
+
+ etzpc: bus@5c007000 {
+ compatible = "st,stm32-etzpc", "simple-bus";
+ reg = <0x5c007000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #access-controller-cells = <1>;
+ ranges;
+
+ adc_2: adc@48004000 {
+ compatible = "st,stm32mp13-adc-core";
+ reg = <0x48004000 0x400>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc ADC2>, <&rcc ADC2_K>;
+ clock-names = "bus", "adc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&etzpc 33>;
+ status = "disabled";
+
+ adc2: adc@0 {
+ compatible = "st,stm32mp13-adc";
+ #io-channel-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ interrupt-parent = <&adc_2>;
+ interrupts = <0>;
+ dmas = <&dmamux1 10 0x400 0x80000001>;
+ dma-names = "rx";
+ status = "disabled";
+
+ channel@13 {
+ reg = <13>;
+ label = "vrefint";
+ };
+ channel@14 {
+ reg = <14>;
+ label = "vddcore";
+ };
+ channel@16 {
+ reg = <16>;
+ label = "vddcpu";
+ };
+ channel@17 {
+ reg = <17>;
+ label = "vddq_ddr";
+ };
+ };
+ };
+
+ usbotg_hs: usb@49000000 {
+ compatible = "st,stm32mp15-hsotg", "snps,dwc2";
+ reg = <0x49000000 0x40000>;
+ clocks = <&rcc USBO_K>;
+ clock-names = "otg";
+ resets = <&rcc USBO_R>;
+ reset-names = "dwc2";
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ g-rx-fifo-size = <512>;
+ g-np-tx-fifo-size = <32>;
+ g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
+ dr_mode = "otg";
+ otg-rev = <0x200>;
+ usb33d-supply = <&scmi_usb33>;
+ access-controllers = <&etzpc 34>;
+ status = "disabled";
+ };
+
+ usart1: serial@4c000000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4c000000 0x400>;
+ interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART1_K>;
+ resets = <&rcc USART1_R>;
+ wakeup-source;
+ dmas = <&dmamux1 41 0x400 0x5>,
+ <&dmamux1 42 0x400 0x1>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 16>;
+ status = "disabled";
+ };
+
+ usart2: serial@4c001000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4c001000 0x400>;
+ interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART2_K>;
+ resets = <&rcc USART2_R>;
+ wakeup-source;
+ dmas = <&dmamux1 43 0x400 0x5>,
+ <&dmamux1 44 0x400 0x1>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 17>;
+ status = "disabled";
+ };
+
+ i2s4: audio-controller@4c002000 {
+ compatible = "st,stm32h7-i2s";
+ reg = <0x4c002000 0x400>;
+ #sound-dai-cells = <0>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 83 0x400 0x01>,
+ <&dmamux1 84 0x400 0x01>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 13>;
+ status = "disabled";
+ };
+
+ spi4: spi@4c002000 {
+ compatible = "st,stm32h7-spi";
+ reg = <0x4c002000 0x400>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI4_K>;
+ resets = <&rcc SPI4_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmamux1 83 0x400 0x01>,
+ <&dmamux1 84 0x400 0x01>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 18>;
+ status = "disabled";
+ };
+
+ spi5: spi@4c003000 {
+ compatible = "st,stm32h7-spi";
+ reg = <0x4c003000 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI5_K>;
+ resets = <&rcc SPI5_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmamux1 85 0x400 0x01>,
+ <&dmamux1 86 0x400 0x01>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 19>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@4c004000 {
+ compatible = "st,stm32mp13-i2c";
+ reg = <0x4c004000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C3_K>;
+ resets = <&rcc I2C3_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmamux1 73 0x400 0x1>,
+ <&dmamux1 74 0x400 0x1>;
+ dma-names = "rx", "tx";
+ st,syscfg-fmp = <&syscfg 0x4 0x4>;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 20>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@4c005000 {
+ compatible = "st,stm32mp13-i2c";
+ reg = <0x4c005000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C4_K>;
+ resets = <&rcc I2C4_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmamux1 75 0x400 0x1>,
+ <&dmamux1 76 0x400 0x1>;
+ dma-names = "rx", "tx";
+ st,syscfg-fmp = <&syscfg 0x4 0x8>;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 21>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@4c006000 {
+ compatible = "st,stm32mp13-i2c";
+ reg = <0x4c006000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C5_K>;
+ resets = <&rcc I2C5_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmamux1 115 0x400 0x1>,
+ <&dmamux1 116 0x400 0x1>;
+ dma-names = "rx", "tx";
+ st,syscfg-fmp = <&syscfg 0x4 0x10>;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 22>;
+ status = "disabled";
+ };
+
+ timers12: timer@4c007000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x4c007000 0x400>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM12_K>;
+ clock-names = "int";
+ access-controllers = <&etzpc 23>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@11 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <11>;
+ status = "disabled";
+ };
+ };
+
+ timers13: timer@4c008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x4c008000 0x400>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM13_K>;
+ clock-names = "int";
+ access-controllers = <&etzpc 24>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@12 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <12>;
+ status = "disabled";
+ };
+ };
+
+ timers14: timer@4c009000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x4c009000 0x400>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM14_K>;
+ clock-names = "int";
+ access-controllers = <&etzpc 25>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@13 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <13>;
+ status = "disabled";
+ };
+ };
+
+ timers15: timer@4c00a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x4c00a000 0x400>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM15_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 105 0x400 0x1>,
+ <&dmamux1 106 0x400 0x1>,
+ <&dmamux1 107 0x400 0x1>,
+ <&dmamux1 108 0x400 0x1>;
+ dma-names = "ch1", "up", "trig", "com";
+ access-controllers = <&etzpc 26>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@14 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <14>;
+ status = "disabled";
+ };
+ };
+
+ timers16: timer@4c00b000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x4c00b000 0x400>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM16_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 109 0x400 0x1>,
+ <&dmamux1 110 0x400 0x1>;
+ dma-names = "ch1", "up";
+ access-controllers = <&etzpc 27>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@15 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <15>;
+ status = "disabled";
+ };
+ };
+
+ timers17: timer@4c00c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x4c00c000 0x400>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM17_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 111 0x400 0x1>,
+ <&dmamux1 112 0x400 0x1>;
+ dma-names = "ch1", "up";
+ access-controllers = <&etzpc 28>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@16 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <16>;
+ status = "disabled";
+ };
+ };
+
+ lptimer2: timer@50021000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-lptimer";
+ reg = <0x50021000 0x400>;
+ interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM2_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 1>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ trigger@1 {
+ compatible = "st,stm32-lptimer-trigger";
+ reg = <1>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-lptimer-counter";
+ status = "disabled";
+ };
+
+ timer {
+ compatible = "st,stm32-lptimer-timer";
+ status = "disabled";
+ };
+ };
+
+ lptimer3: timer@50022000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-lptimer";
+ reg = <0x50022000 0x400>;
+ interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM3_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 2>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ trigger@2 {
+ compatible = "st,stm32-lptimer-trigger";
+ reg = <2>;
+ status = "disabled";
+ };
+
+ timer {
+ compatible = "st,stm32-lptimer-timer";
+ status = "disabled";
+ };
+ };
+
+ hash: hash@54003000 {
+ compatible = "st,stm32mp13-hash";
+ reg = <0x54003000 0x400>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc HASH1>;
+ resets = <&rcc HASH1_R>;
+ dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
+ dma-names = "in";
+ access-controllers = <&etzpc 41>;
+ status = "disabled";
+ };
+
+ rng: rng@54004000 {
+ compatible = "st,stm32mp13-rng";
+ reg = <0x54004000 0x400>;
+ clocks = <&rcc RNG1_K>;
+ resets = <&rcc RNG1_R>;
+ access-controllers = <&etzpc 40>;
+ status = "disabled";
+ };
+
+ fmc: memory-controller@58002000 {
+ compatible = "st,stm32mp1-fmc2-ebi";
+ reg = <0x58002000 0x1000>;
+ 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 */
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&rcc FMC_K>;
+ resets = <&rcc FMC_R>;
+ access-controllers = <&etzpc 54>;
+ status = "disabled";
+
+ nand-controller@4,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>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdma 24 0x2 0x12000a02 0x0 0x0>,
+ <&mdma 24 0x2 0x12000a08 0x0 0x0>,
+ <&mdma 25 0x2 0x12000a0a 0x0 0x0>;
+ dma-names = "tx", "rx", "ecc";
+ status = "disabled";
+ };
+ };
+
+ qspi: spi@58003000 {
+ compatible = "st,stm32f469-qspi";
+ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+ reg-names = "qspi", "qspi_mm";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdma 26 0x2 0x10100002 0x0 0x0>,
+ <&mdma 26 0x2 0x10100008 0x0 0x0>;
+ dma-names = "tx", "rx";
+ clocks = <&rcc QSPI_K>;
+ resets = <&rcc QSPI_R>;
+ access-controllers = <&etzpc 55>;
+ status = "disabled";
+ };
+
+ sdmmc1: mmc@58005000 {
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x20253180>;
+ reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SDMMC1_K>;
+ clock-names = "apb_pclk";
+ resets = <&rcc SDMMC1_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <130000000>;
+ access-controllers = <&etzpc 50>;
+ status = "disabled";
+ };
+
+ sdmmc2: mmc@58007000 {
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x20253180>;
+ reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SDMMC2_K>;
+ clock-names = "apb_pclk";
+ resets = <&rcc SDMMC2_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <130000000>;
+ access-controllers = <&etzpc 51>;
+ status = "disabled";
+ };
+
+ ethernet1: ethernet@5800a000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800a000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 68 1>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH1MAC>,
+ <&rcc ETH1TX>,
+ <&rcc ETH1RX>,
+ <&rcc ETH1STP>,
+ <&rcc ETH1CK_K>;
+ st,syscon = <&syscfg 0x4 0xff0000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_1>;
+ snps,tso;
+ access-controllers = <&etzpc 48>;
+ status = "disabled";
+
+ stmmac_axi_config_1: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
+
+ usbphyc: usbphyc@5a006000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "st,stm32mp1-usbphyc";
+ reg = <0x5a006000 0x1000>;
+ clocks = <&rcc USBPHY_K>;
+ resets = <&rcc USBPHY_R>;
+ vdda1v1-supply = <&scmi_reg11>;
+ vdda1v8-supply = <&scmi_reg18>;
+ access-controllers = <&etzpc 5>;
+ status = "disabled";
+
+ usbphyc_port0: usb-phy@0 {
+ #phy-cells = <0>;
+ reg = <0>;
+ };
+
+ usbphyc_port1: usb-phy@1 {
+ #phy-cells = <1>;
+ reg = <1>;
+ };
+ };
};
/*
diff --git a/arch/arm/boot/dts/st/stm32mp133.dtsi b/arch/arm/boot/dts/st/stm32mp133.dtsi
index df451c3c2a26..73e470019ce4 100644
--- a/arch/arm/boot/dts/st/stm32mp133.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp133.dtsi
@@ -33,36 +33,70 @@
bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
status = "disabled";
};
+ };
+};
- adc_1: adc@48003000 {
- compatible = "st,stm32mp13-adc-core";
- reg = <0x48003000 0x400>;
- interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc ADC1>, <&rcc ADC1_K>;
- clock-names = "bus", "adc";
- interrupt-controller;
- #interrupt-cells = <1>;
+&etzpc {
+ adc_1: adc@48003000 {
+ compatible = "st,stm32mp13-adc-core";
+ reg = <0x48003000 0x400>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc ADC1>, <&rcc ADC1_K>;
+ clock-names = "bus", "adc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&etzpc 32>;
+ status = "disabled";
+
+ adc1: adc@0 {
+ compatible = "st,stm32mp13-adc";
+ #io-channel-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ reg = <0x0>;
+ interrupt-parent = <&adc_1>;
+ interrupts = <0>;
+ dmas = <&dmamux1 9 0x400 0x80000001>;
+ dma-names = "rx";
status = "disabled";
- adc1: adc@0 {
- compatible = "st,stm32mp13-adc";
- #io-channel-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0>;
- interrupt-parent = <&adc_1>;
- interrupts = <0>;
- dmas = <&dmamux1 9 0x400 0x80000001>;
- dma-names = "rx";
- status = "disabled";
-
- channel@18 {
- reg = <18>;
- label = "vrefint";
- };
+ channel@18 {
+ reg = <18>;
+ label = "vrefint";
};
};
};
+
+ ethernet2: ethernet@5800e000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800e000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH2MAC>,
+ <&rcc ETH2TX>,
+ <&rcc ETH2RX>,
+ <&rcc ETH2STP>,
+ <&rcc ETH2CK_K>;
+ st,syscon = <&syscfg 0x4 0xff000000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_2>;
+ snps,tso;
+ access-controllers = <&etzpc 49>;
+ status = "disabled";
+
+ stmmac_axi_config_2: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/st/stm32mp135.dtsi b/arch/arm/boot/dts/st/stm32mp135.dtsi
index 68d32f9f5314..834a4d545fe4 100644
--- a/arch/arm/boot/dts/st/stm32mp135.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp135.dtsi
@@ -19,5 +19,16 @@
port {
};
};
+
+ ltdc: display-controller@5a001000 {
+ compatible = "st,stm32-ltdc";
+ reg = <0x5a001000 0x400>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LTDC_PX>;
+ clock-names = "lcd";
+ resets = <&scmi_reset RST_SCMI_LTDC>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/st/stm32mp135f-dhcor-dhsbc.dts b/arch/arm/boot/dts/st/stm32mp135f-dhcor-dhsbc.dts
new file mode 100644
index 000000000000..bacb70b4256b
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32mp135f-dhcor-dhsbc.dts
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024 Marek Vasut <marex@denx.de>
+ *
+ * DHCOR STM32MP13 variant:
+ * DHCR-STM32MP135F-C100-R051-EE-F0409-SPI4-RTC-WBT-I-01LG
+ * DHCOR PCB number: 718-100 or newer
+ * DHSBC PCB number: 719-100 or newer
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/st,stm32mp13-regulator.h>
+#include "stm32mp135.dtsi"
+#include "stm32mp13xf.dtsi"
+#include "stm32mp13xx-dhcor-som.dtsi"
+
+/ {
+ model = "DH electronics STM32MP135F DHCOR DHSBC";
+ compatible = "dh,stm32mp135f-dhcor-dhsbc",
+ "dh,stm32mp135f-dhcor-som",
+ "st,stm32mp135";
+
+ aliases {
+ ethernet0 = &ethernet1;
+ ethernet1 = &ethernet2;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&adc_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&adc1_pins_a &adc1_usb_cc_pins_b>;
+ vdda-supply = <&vdd_adc>;
+ vref-supply = <&vdd_adc>;
+ status = "okay";
+
+ adc1: adc@0 {
+ status = "okay";
+
+ /*
+ * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in2 & in11.
+ * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
+ * 5 * (5.1 + 47kOhms) * 5pF => 1.3us.
+ * Use arbitrary margin here (e.g. 5us).
+ *
+ * The pinmux pins must be set as ANALOG, use datasheet
+ * DS13483 Table 7. STM32MP135C/F ball definitions to
+ * find out which 'pin name' maps to which 'additional
+ * functions', which lists the mapping between pin and
+ * ADC channel. In this case, PA5 maps to ADC1_INP2 and
+ * PF13 maps to ADC1_INP11 .
+ */
+ channel@2 {
+ reg = <2>;
+ st,min-sample-time-ns = <5000>;
+ };
+
+ channel@11 {
+ reg = <11>;
+ st,min-sample-time-ns = <5000>;
+ };
+
+ /* Expansion connector: INP12:pin29 */
+ channel@12 {
+ reg = <12>;
+ st,min-sample-time-ns = <5000>;
+ };
+ };
+};
+
+&ethernet1 {
+ phy-handle = <&ethphy1>;
+ phy-mode = "rgmii-id";
+ pinctrl-0 = <&eth1_rgmii_pins_a>;
+ pinctrl-1 = <&eth1_rgmii_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ st,ext-phyclk;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ ethphy1: ethernet-phy@1 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916";
+ interrupt-parent = <&gpiog>;
+ interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+ reg = <1>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <55000>;
+ reset-gpios = <&gpioa 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&ethernet2 {
+ phy-handle = <&ethphy2>;
+ phy-mode = "rgmii-id";
+ pinctrl-0 = <&eth2_rgmii_pins_a>;
+ pinctrl-1 = <&eth2_rgmii_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ st,ext-phyclk;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ ethphy2: ethernet-phy@1 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916";
+ interrupt-parent = <&gpiog>;
+ interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+ reg = <1>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <55000>;
+ reset-gpios = <&gpiog 8 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&gpioa {
+ gpio-line-names = "", "", "", "",
+ "", "DHSBC_USB_PWR_CC1", "", "",
+ "", "", "", "DHSBC_nETH1_RST",
+ "", "DHCOR_HW-CODING_0", "", "";
+};
+
+&gpiob {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "DHCOR_BT_HOST_WAKE",
+ "", "", "", "",
+ "", "DHSBC_nTPM_CS", "", "";
+};
+
+&gpioc {
+ gpio-line-names = "", "", "", "DHSBC_USB_5V_MEAS",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpiod {
+ gpio-line-names = "", "", "", "",
+ "", "DHCOR_RAM-CODING_0", "", "",
+ "", "DHCOR_RAM-CODING_1", "", "",
+ "", "", "", "";
+};
+
+&gpioe {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "",
+ "", "DHSBC_nTPM_RST", "", "",
+ "DHSBC_nTPM_PIRQ", "", "DHCOR_WL_HOST_WAKE", "";
+};
+
+&gpiof {
+ gpio-line-names = "", "", "DHSBC_USB_PWR_nFLT", "",
+ "", "", "", "",
+ "", "", "", "",
+ "DHCOR_WL_REG_ON", "DHSBC_USB_PWR_CC2", "", "";
+};
+
+&gpiog {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "",
+ "DHSBC_nETH2_RST", "DHCOR_BT_DEV_WAKE", "", "",
+ "DHSBC_ETH1_INTB", "", "", "DHSBC_ETH2_INTB";
+};
+
+&gpioi {
+ gpio-line-names = "DHCOR_RTC_nINT", "DHCOR_HW-CODING_1",
+ "DHCOR_BT_REG_ON", "DHCOR_PMIC_nINT",
+ "DHSBC_BOOT0", "DHSBC_BOOT1",
+ "DHSBC_BOOT2", "DHSBC_USB-C_DATA_VBUS";
+};
+
+&i2c1 { /* Expansion connector: SDA:pin27 SCL:pin28 */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c1_pins_a>;
+ pinctrl-1 = <&i2c1_sleep_pins_a>;
+ i2c-scl-rising-time-ns = <96>;
+ i2c-scl-falling-time-ns = <3>;
+ clock-frequency = <400000>;
+ status = "okay";
+ /* spare dmas for other usage */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+};
+
+&i2c5 { /* Expansion connector: SDA:pin3 SCL:pin5 */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c5_pins_b>;
+ pinctrl-1 = <&i2c5_sleep_pins_b>;
+ i2c-scl-rising-time-ns = <96>;
+ i2c-scl-falling-time-ns = <3>;
+ clock-frequency = <400000>;
+ status = "okay";
+ /* spare dmas for other usage */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+};
+
+&m_can1 { /* Expansion connector: TX:pin16 RX:pin18 */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&m_can1_pins_a>;
+ pinctrl-1 = <&m_can1_sleep_pins_a>;
+ status = "okay";
+};
+
+&m_can2 { /* Expansion connector: TX:pin22 RX:pin26 */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&m_can2_pins_a>;
+ pinctrl-1 = <&m_can2_sleep_pins_a>;
+ status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+ status = "okay";
+};
+
+&sai1 { /* Expansion connector: SCK-A:pin12 FS-A:pin35 SD-A:pin38 SD-B:pin40 */
+ clocks = <&rcc SAI1>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
+ clock-names = "pclk", "x8k", "x11k";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sai1a_pins_a &sai1b_pins_a>;
+ pinctrl-1 = <&sai1a_sleep_pins_a &sai1b_sleep_pins_a>;
+};
+
+&scmi_voltd {
+ status = "disabled";
+};
+
+&spi2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&spi2_pins_a>;
+ pinctrl-1 = <&spi2_sleep_pins_a>;
+ cs-gpios = <&gpiob 13 0>;
+ status = "okay";
+
+ st33htph: tpm@0 {
+ compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi";
+ reg = <0>;
+ spi-max-frequency = <24000000>;
+ };
+};
+
+&spi3 { /* Expansion connector: MOSI:pin19 MISO:pin21 SCK:pin22 nCS:pin24 */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&spi3_pins_a>;
+ pinctrl-1 = <&spi3_sleep_pins_a>;
+ cs-gpios = <&gpiof 3 0>;
+ status = "disabled";
+};
+
+&timers5 { /* Expansion connector: CH3:pin31 */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ status = "okay";
+
+ pwm {
+ pinctrl-0 = <&pwm5_pins_a>;
+ pinctrl-1 = <&pwm5_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ status = "okay";
+ };
+ timer@4 {
+ status = "okay";
+ };
+};
+
+&timers13 { /* Expansion connector: CH1:pin32 */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ status = "okay";
+
+ pwm {
+ pinctrl-0 = <&pwm13_pins_a>;
+ pinctrl-1 = <&pwm13_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ status = "okay";
+ };
+ timer@12 {
+ status = "okay";
+ };
+};
+
+&usart1 { /* Expansion connector: RX:pin33 TX:pin37 */
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&usart1_pins_b>;
+ pinctrl-1 = <&usart1_sleep_pins_b>;
+ pinctrl-2 = <&usart1_idle_pins_b>;
+ status = "okay";
+};
+
+&usart2 { /* Expansion connector: RX:pin10 TX:pin8 RTS:pin11 CTS:pin36 */
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&usart2_pins_b>;
+ pinctrl-1 = <&usart2_sleep_pins_b>;
+ pinctrl-2 = <&usart2_idle_pins_b>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh_ehci {
+ phys = <&usbphyc_port0>;
+ status = "okay";
+};
+
+&usbh_ohci {
+ phys = <&usbphyc_port0>;
+ status = "okay";
+};
+
+&usbotg_hs {
+ dr_mode = "peripheral";
+ phys = <&usbphyc_port1 0>;
+ phy-names = "usb2-phy";
+ usb33d-supply = <&usb33>;
+ status = "okay";
+};
+
+&usbphyc {
+ status = "okay";
+ vdda1v1-supply = <&reg11>;
+ vdda1v8-supply = <&reg18>;
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+ st,current-boost-microamp = <1000>;
+ st,decrease-hs-slew-rate;
+ st,tune-hs-dc-level = <2>;
+ st,enable-hs-rftime-reduction;
+ st,trim-hs-current = <11>;
+ st,trim-hs-impedance = <2>;
+ st,tune-squelch-level = <1>;
+ st,enable-hs-rx-gain-eq;
+ st,no-hs-ftime-ctrl;
+ st,no-lsfs-sc;
+ connector {
+ compatible = "usb-a-connector";
+ vbus-supply = <&vbus_sw>;
+ };
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+ st,current-boost-microamp = <1000>;
+ st,decrease-hs-slew-rate;
+ st,tune-hs-dc-level = <2>;
+ st,enable-hs-rftime-reduction;
+ st,trim-hs-current = <11>;
+ st,trim-hs-impedance = <2>;
+ st,tune-squelch-level = <1>;
+ st,enable-hs-rx-gain-eq;
+ st,no-hs-ftime-ctrl;
+ st,no-lsfs-sc;
+ connector {
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
+ vbus-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>;
+ label = "Type-C";
+ self-powered;
+ type = "micro";
+ };
+};
diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index 52171214a308..1af335a39993 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -19,6 +19,7 @@
compatible = "st,stm32mp135f-dk", "st,stm32mp135";
aliases {
+ ethernet0 = &ethernet1;
serial0 = &uart4;
serial1 = &usart1;
serial2 = &uart8;
@@ -29,6 +30,20 @@
stdout-path = "serial0:115200n8";
};
+ clocks {
+ clk_ext_camera: clk-ext-camera {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ clk_mco1: clk-mco1 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
+
memory@c0000000 {
device_type = "memory";
reg = <0xc0000000 0x20000000>;
@@ -66,6 +81,46 @@
default-state = "off";
};
};
+
+ panel_backlight: panel-backlight {
+ compatible = "gpio-backlight";
+ gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>;
+ default-on;
+ status = "okay";
+ };
+
+ panel_rgb: panel-rgb {
+ compatible = "rocktech,rk043fn48h";
+ enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>;
+ backlight = <&panel_backlight>;
+ power-supply = <&scmi_v3v3_sw>;
+ status = "okay";
+
+ width-mm = <105>;
+ height-mm = <67>;
+
+ panel-timing {
+ clock-frequency = <10000000>;
+ hactive = <480>;
+ hback-porch = <43>;
+ hfront-porch = <10>;
+ hsync-len = <1>;
+ hsync-active = <0>;
+ vactive = <272>;
+ vback-porch = <26>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ port {
+ panel_in_rgb: endpoint {
+ remote-endpoint = <&ltdc_out_rgb>;
+ };
+ };
+ };
};
&adc_1 {
@@ -101,6 +156,45 @@
status = "okay";
};
+&dcmipp {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&dcmipp_pins_a>;
+ pinctrl-1 = <&dcmipp_sleep_pins_a>;
+ status = "okay";
+
+ port {
+ dcmipp_0: endpoint {
+ remote-endpoint = <&mipid02_2>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pclk-sample = <0>;
+ };
+ };
+};
+
+&ethernet1 {
+ status = "okay";
+ pinctrl-0 = <&eth1_rmii_pins_a>;
+ pinctrl-1 = <&eth1_rmii_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rmii";
+ phy-handle = <&phy0_eth1>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy0_eth1: ethernet-phy@0 {
+ compatible = "ethernet-phy-id0007.c131";
+ reg = <0>;
+ reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+};
+
&i2c1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c1_pins_a>;
@@ -161,6 +255,76 @@
/* spare dmas for other usage */
/delete-property/dmas;
/delete-property/dma-names;
+
+ stmipi: csi2rx@14 {
+ compatible = "st,st-mipid02";
+ reg = <0x14>;
+ clocks = <&clk_mco1>;
+ clock-names = "xclk";
+ VDDE-supply = <&scmi_v1v8_periph>;
+ VDDIN-supply = <&scmi_v1v8_periph>;
+ reset-gpios = <&mcp23017 2 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+
+ mipid02_0: endpoint {
+ data-lanes = <1 2>;
+ lane-polarities = <0 0 0>;
+ remote-endpoint = <&gc2145_ep>;
+ };
+ };
+ port@2 {
+ reg = <2>;
+
+ mipid02_2: endpoint {
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pclk-sample = <0>;
+ remote-endpoint = <&dcmipp_0>;
+ };
+ };
+ };
+ };
+
+ gc2145: camera@3c {
+ compatible = "galaxycore,gc2145";
+ reg = <0x3c>;
+ clocks = <&clk_ext_camera>;
+ iovdd-supply = <&scmi_v3v3_sw>;
+ avdd-supply = <&scmi_v3v3_sw>;
+ dvdd-supply = <&scmi_v3v3_sw>;
+ powerdown-gpios = <&mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
+ reset-gpios = <&mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
+ status = "okay";
+
+ port {
+ gc2145_ep: endpoint {
+ remote-endpoint = <&mipid02_0>;
+ data-lanes = <1 2>;
+ link-frequencies = /bits/ 64 <120000000 192000000 240000000>;
+ };
+ };
+ };
+
+ goodix: goodix-ts@5d {
+ compatible = "goodix,gt911";
+ reg = <0x5d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&goodix_pins_a>;
+ interrupt-parent = <&gpiof>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ AVDD28-supply = <&scmi_v3v3_sw>;
+ VDDIO-supply = <&scmi_v3v3_sw>;
+ touchscreen-size-x = <480>;
+ touchscreen-size-y = <272>;
+ status = "okay" ;
+ };
};
&iwdg2 {
@@ -168,6 +332,19 @@
status = "okay";
};
+&ltdc {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&ltdc_pins_a>;
+ pinctrl-1 = <&ltdc_sleep_pins_a>;
+ status = "okay";
+
+ port {
+ ltdc_out_rgb: endpoint {
+ remote-endpoint = <&panel_in_rgb>;
+ };
+ };
+};
+
&rtc {
status = "okay";
};
@@ -220,6 +397,7 @@
/delete-property/dma-names;
status = "disabled";
pwm {
+ /* PWM output on pin 7 of the expansion connector (CN8.7) using TIM3_CH4 func */
pinctrl-0 = <&pwm3_pins_a>;
pinctrl-1 = <&pwm3_sleep_pins_a>;
pinctrl-names = "default", "sleep";
@@ -235,6 +413,7 @@
/delete-property/dma-names;
status = "disabled";
pwm {
+ /* PWM output on pin 31 of the expansion connector (CN8.31) using TIM4_CH2 func */
pinctrl-0 = <&pwm4_pins_a>;
pinctrl-1 = <&pwm4_sleep_pins_a>;
pinctrl-names = "default", "sleep";
@@ -250,6 +429,7 @@
/delete-property/dma-names;
status = "disabled";
pwm {
+ /* PWM output on pin 32 of the expansion connector (CN8.32) using TIM8_CH3 func */
pinctrl-0 = <&pwm8_pins_a>;
pinctrl-1 = <&pwm8_sleep_pins_a>;
pinctrl-names = "default", "sleep";
@@ -263,6 +443,7 @@
&timers14 {
status = "disabled";
pwm {
+ /* PWM output on pin 33 of the expansion connector (CN8.33) using TIM14_CH1 func */
pinctrl-0 = <&pwm14_pins_a>;
pinctrl-1 = <&pwm14_sleep_pins_a>;
pinctrl-names = "default", "sleep";
diff --git a/arch/arm/boot/dts/st/stm32mp13xc.dtsi b/arch/arm/boot/dts/st/stm32mp13xc.dtsi
index 4d00e7592882..a8bd5fe6536c 100644
--- a/arch/arm/boot/dts/st/stm32mp13xc.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13xc.dtsi
@@ -4,15 +4,14 @@
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
-/ {
- soc {
- cryp: crypto@54002000 {
- compatible = "st,stm32mp1-cryp";
- reg = <0x54002000 0x400>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc CRYP1>;
- resets = <&rcc CRYP1_R>;
- status = "disabled";
- };
+&etzpc {
+ cryp: crypto@54002000 {
+ compatible = "st,stm32mp1-cryp";
+ reg = <0x54002000 0x400>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CRYP1>;
+ resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 42>;
+ status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/st/stm32mp13xf.dtsi b/arch/arm/boot/dts/st/stm32mp13xf.dtsi
index 4d00e7592882..a8bd5fe6536c 100644
--- a/arch/arm/boot/dts/st/stm32mp13xf.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13xf.dtsi
@@ -4,15 +4,14 @@
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
-/ {
- soc {
- cryp: crypto@54002000 {
- compatible = "st,stm32mp1-cryp";
- reg = <0x54002000 0x400>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc CRYP1>;
- resets = <&rcc CRYP1_R>;
- status = "disabled";
- };
+&etzpc {
+ cryp: crypto@54002000 {
+ compatible = "st,stm32mp1-cryp";
+ reg = <0x54002000 0x400>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CRYP1>;
+ resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 42>;
+ status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi b/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
new file mode 100644
index 000000000000..ddad6497775b
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024 Marek Vasut <marex@denx.de>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/mfd/st,stpmic1.h>
+#include <dt-bindings/regulator/st,stm32mp13-regulator.h>
+#include "stm32mp13-pinctrl.dtsi"
+
+/ {
+ model = "DH electronics STM32MP13xx DHCOR SoM";
+ compatible = "dh,stm32mp131a-dhcor-som",
+ "st,stm32mp131";
+
+ aliases {
+ mmc0 = &sdmmc2;
+ mmc1 = &sdmmc1;
+ serial0 = &uart4;
+ serial1 = &uart7;
+ rtc0 = &rv3032;
+ spi0 = &qspi;
+ };
+
+ memory@c0000000 {
+ device_type = "memory";
+ reg = <0xc0000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ optee@dd000000 {
+ reg = <0xdd000000 0x3000000>;
+ no-map;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpiof 12 GPIO_ACTIVE_LOW>;
+ };
+
+ vin: vin {
+ compatible = "regulator-fixed";
+ regulator-name = "vin";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+};
+
+&i2c3 {
+ i2c-scl-rising-time-ns = <96>;
+ i2c-scl-falling-time-ns = <3>;
+ clock-frequency = <400000>;
+ status = "okay";
+ /* spare dmas for other usage */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupts-extended = <&gpioi 3 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+
+ ldo1-supply = <&vin>;
+ ldo2-supply = <&vin>;
+ ldo3-supply = <&vin>;
+ ldo4-supply = <&vin>;
+ ldo5-supply = <&vin>;
+ ldo6-supply = <&vin>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&bst_out>;
+
+ vddcpu: buck1 { /* VDD_CPU_1V2 */
+ regulator-name = "vddcpu";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 { /* VDD_DDR_1V35 */
+ 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 { /* VDD_3V3_1V8 */
+ regulator-name = "vdd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vddcore: buck4 { /* VDD_CORE_1V2 */
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_adc: ldo1 { /* VDD_ADC_1V8 */
+ regulator-name = "vdd_adc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ interrupts = <IT_CURLIM_LDO1 0>;
+ };
+
+ vdd_ldo2: ldo2 { /* LDO2_OUT_1V8 */
+ regulator-name = "vdd_ldo2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ interrupts = <IT_CURLIM_LDO2 0>;
+ };
+
+ vdd_ldo3: ldo3 { /* LDO3_OUT */
+ regulator-name = "vdd_ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ interrupts = <IT_CURLIM_LDO3 0>;
+ };
+
+ vdd_usb: ldo4 { /* VDD_USB_3V3 */
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ interrupts = <IT_CURLIM_LDO4 0>;
+ };
+
+ vdd_sd: ldo5 { /* VDD_SD_3V3_1V8 */
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ interrupts = <IT_CURLIM_LDO5 0>;
+ };
+
+ vdd_sd2: ldo6 { /* VDD_SD2_3V3_1V8 */
+ regulator-name = "vdd_sd2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ interrupts = <IT_CURLIM_LDO6 0>;
+ };
+
+ vref_ddr: vref_ddr { /* VREF_DDR_0V675 */
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ };
+
+ bst_out: boost { /* BST_OUT_5V2 */
+ regulator-name = "bst_out";
+ };
+
+ 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 = <1>;
+ };
+ };
+
+ onkey {
+ compatible = "st,stpmic1-onkey";
+ interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 1>;
+ interrupt-names = "onkey-falling", "onkey-rising";
+ status = "okay";
+ };
+
+ watchdog {
+ compatible = "st,stpmic1-wdt";
+ status = "disabled";
+ };
+ };
+
+ eeprom0: eeprom@50 {
+ compatible = "atmel,24c256"; /* ST M24256 */
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+
+ rv3032: rtc@51 {
+ compatible = "microcrystal,rv3032";
+ reg = <0x51>;
+ interrupts-extended = <&gpioi 0 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&qspi_clk_pins_a
+ &qspi_bk1_pins_a
+ &qspi_cs1_pins_a>;
+ pinctrl-1 = <&qspi_clk_sleep_pins_a
+ &qspi_bk1_sleep_pins_a
+ &qspi_cs1_sleep_pins_a>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <108000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+/* Console UART */
+&uart4 {
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&uart4_pins_b>;
+ pinctrl-1 = <&uart4_sleep_pins_b>;
+ pinctrl-2 = <&uart4_idle_pins_b>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ status = "okay";
+};
+
+/* Bluetooth */
+&uart7 {
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&uart7_pins_a>;
+ pinctrl-1 = <&uart7_sleep_pins_a>;
+ pinctrl-2 = <&uart7_idle_pins_a>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "infineon,cyw43439-bt", "brcm,bcm4329-bt";
+ max-speed = <3000000>;
+ device-wakeup-gpios = <&gpiog 9 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpioi 2 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+/* SDIO WiFi */
+&sdmmc1 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>;
+ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_clk_pins_a>;
+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
+ bus-width = <4>;
+ cap-power-off-card;
+ keep-power-in-suspend;
+ non-removable;
+ st,neg-edge;
+ vmmc-supply = <&vdd>;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ brcmf: bcrmf@1 { /* muRata 1YN */
+ reg = <1>;
+ compatible = "infineon,cyw43439-fmac", "brcm,bcm4329-fmac";
+ interrupt-parent = <&gpioe>;
+ interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "host-wake";
+ };
+};
+
+/* eMMC */
+&sdmmc2 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a &sdmmc2_clk_pins_a>;
+ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a &sdmmc2_clk_pins_a>;
+ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
+ bus-width = <8>;
+ mmc-ddr-3_3v;
+ no-sd;
+ no-sdio;
+ non-removable;
+ st,neg-edge;
+ vmmc-supply = <&vdd>;
+ vqmmc-supply = <&vdd>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi
index fa4cbd312e5a..4f878ec102c1 100644
--- a/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -50,6 +50,7 @@
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-parent = <&intc>;
+ arm,no-tick-in-suspend;
};
clocks {
@@ -122,1042 +123,6 @@
interrupt-parent = <&intc>;
ranges;
- timers2: timer@40000000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40000000 0x400>;
- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM2_K>;
- clock-names = "int";
- dmas = <&dmamux1 18 0x400 0x1>,
- <&dmamux1 19 0x400 0x1>,
- <&dmamux1 20 0x400 0x1>,
- <&dmamux1 21 0x400 0x1>,
- <&dmamux1 22 0x400 0x1>;
- dma-names = "ch1", "ch2", "ch3", "ch4", "up";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@1 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <1>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-timer-counter";
- status = "disabled";
- };
- };
-
- timers3: timer@40001000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40001000 0x400>;
- interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM3_K>;
- clock-names = "int";
- dmas = <&dmamux1 23 0x400 0x1>,
- <&dmamux1 24 0x400 0x1>,
- <&dmamux1 25 0x400 0x1>,
- <&dmamux1 26 0x400 0x1>,
- <&dmamux1 27 0x400 0x1>,
- <&dmamux1 28 0x400 0x1>;
- dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@2 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <2>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-timer-counter";
- status = "disabled";
- };
- };
-
- timers4: timer@40002000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40002000 0x400>;
- interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM4_K>;
- clock-names = "int";
- dmas = <&dmamux1 29 0x400 0x1>,
- <&dmamux1 30 0x400 0x1>,
- <&dmamux1 31 0x400 0x1>,
- <&dmamux1 32 0x400 0x1>;
- dma-names = "ch1", "ch2", "ch3", "ch4";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@3 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <3>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-timer-counter";
- status = "disabled";
- };
- };
-
- timers5: timer@40003000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40003000 0x400>;
- interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM5_K>;
- clock-names = "int";
- dmas = <&dmamux1 55 0x400 0x1>,
- <&dmamux1 56 0x400 0x1>,
- <&dmamux1 57 0x400 0x1>,
- <&dmamux1 58 0x400 0x1>,
- <&dmamux1 59 0x400 0x1>,
- <&dmamux1 60 0x400 0x1>;
- dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@4 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <4>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-timer-counter";
- status = "disabled";
- };
- };
-
- timers6: timer@40004000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40004000 0x400>;
- interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM6_K>;
- clock-names = "int";
- dmas = <&dmamux1 69 0x400 0x1>;
- dma-names = "up";
- status = "disabled";
-
- timer@5 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <5>;
- status = "disabled";
- };
- };
-
- timers7: timer@40005000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40005000 0x400>;
- interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM7_K>;
- clock-names = "int";
- dmas = <&dmamux1 70 0x400 0x1>;
- dma-names = "up";
- status = "disabled";
-
- timer@6 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <6>;
- status = "disabled";
- };
- };
-
- timers12: timer@40006000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40006000 0x400>;
- interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM12_K>;
- clock-names = "int";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@11 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <11>;
- status = "disabled";
- };
- };
-
- timers13: timer@40007000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40007000 0x400>;
- interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM13_K>;
- clock-names = "int";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@12 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <12>;
- status = "disabled";
- };
- };
-
- timers14: timer@40008000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x40008000 0x400>;
- interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM14_K>;
- clock-names = "int";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@13 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <13>;
- status = "disabled";
- };
- };
-
- lptimer1: timer@40009000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-lptimer";
- reg = <0x40009000 0x400>;
- interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM1_K>;
- clock-names = "mux";
- wakeup-source;
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- trigger@0 {
- compatible = "st,stm32-lptimer-trigger";
- reg = <0>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-lptimer-counter";
- status = "disabled";
- };
- };
-
- spi2: spi@4000b000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32h7-spi";
- reg = <0x4000b000 0x400>;
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI2_K>;
- resets = <&rcc SPI2_R>;
- dmas = <&dmamux1 39 0x400 0x05>,
- <&dmamux1 40 0x400 0x05>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2s2: audio-controller@4000b000 {
- compatible = "st,stm32h7-i2s";
- #sound-dai-cells = <0>;
- reg = <0x4000b000 0x400>;
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 39 0x400 0x01>,
- <&dmamux1 40 0x400 0x01>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi3: spi@4000c000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32h7-spi";
- reg = <0x4000c000 0x400>;
- interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI3_K>;
- resets = <&rcc SPI3_R>;
- dmas = <&dmamux1 61 0x400 0x05>,
- <&dmamux1 62 0x400 0x05>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2s3: audio-controller@4000c000 {
- compatible = "st,stm32h7-i2s";
- #sound-dai-cells = <0>;
- reg = <0x4000c000 0x400>;
- interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 61 0x400 0x01>,
- <&dmamux1 62 0x400 0x01>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spdifrx: audio-controller@4000d000 {
- compatible = "st,stm32h7-spdifrx";
- #sound-dai-cells = <0>;
- reg = <0x4000d000 0x400>;
- clocks = <&rcc SPDIF_K>;
- clock-names = "kclk";
- interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 93 0x400 0x01>,
- <&dmamux1 94 0x400 0x01>;
- dma-names = "rx", "rx-ctrl";
- status = "disabled";
- };
-
- usart2: serial@4000e000 {
- compatible = "st,stm32h7-uart";
- reg = <0x4000e000 0x400>;
- interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc USART2_K>;
- wakeup-source;
- dmas = <&dmamux1 43 0x400 0x15>,
- <&dmamux1 44 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- usart3: serial@4000f000 {
- compatible = "st,stm32h7-uart";
- reg = <0x4000f000 0x400>;
- interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc USART3_K>;
- wakeup-source;
- dmas = <&dmamux1 45 0x400 0x15>,
- <&dmamux1 46 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uart4: serial@40010000 {
- compatible = "st,stm32h7-uart";
- reg = <0x40010000 0x400>;
- interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc UART4_K>;
- wakeup-source;
- dmas = <&dmamux1 63 0x400 0x15>,
- <&dmamux1 64 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uart5: serial@40011000 {
- compatible = "st,stm32h7-uart";
- reg = <0x40011000 0x400>;
- interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc UART5_K>;
- wakeup-source;
- dmas = <&dmamux1 65 0x400 0x15>,
- <&dmamux1 66 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c1: i2c@40012000 {
- compatible = "st,stm32mp15-i2c";
- reg = <0x40012000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C1_K>;
- resets = <&rcc I2C1_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- st,syscfg-fmp = <&syscfg 0x4 0x1>;
- wakeup-source;
- i2c-analog-filter;
- status = "disabled";
- };
-
- i2c2: i2c@40013000 {
- compatible = "st,stm32mp15-i2c";
- reg = <0x40013000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C2_K>;
- resets = <&rcc I2C2_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- st,syscfg-fmp = <&syscfg 0x4 0x2>;
- wakeup-source;
- i2c-analog-filter;
- status = "disabled";
- };
-
- i2c3: i2c@40014000 {
- compatible = "st,stm32mp15-i2c";
- reg = <0x40014000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C3_K>;
- resets = <&rcc I2C3_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- st,syscfg-fmp = <&syscfg 0x4 0x4>;
- wakeup-source;
- i2c-analog-filter;
- status = "disabled";
- };
-
- i2c5: i2c@40015000 {
- compatible = "st,stm32mp15-i2c";
- reg = <0x40015000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C5_K>;
- resets = <&rcc I2C5_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- st,syscfg-fmp = <&syscfg 0x4 0x10>;
- wakeup-source;
- i2c-analog-filter;
- status = "disabled";
- };
-
- cec: cec@40016000 {
- compatible = "st,stm32-cec";
- reg = <0x40016000 0x400>;
- interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc CEC_K>, <&rcc CEC>;
- clock-names = "cec", "hdmi-cec";
- status = "disabled";
- };
-
- dac: dac@40017000 {
- compatible = "st,stm32h7-dac-core";
- reg = <0x40017000 0x400>;
- clocks = <&rcc DAC12>;
- clock-names = "pclk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- dac1: dac@1 {
- compatible = "st,stm32-dac";
- #io-channel-cells = <1>;
- reg = <1>;
- status = "disabled";
- };
-
- dac2: dac@2 {
- compatible = "st,stm32-dac";
- #io-channel-cells = <1>;
- reg = <2>;
- status = "disabled";
- };
- };
-
- uart7: serial@40018000 {
- compatible = "st,stm32h7-uart";
- reg = <0x40018000 0x400>;
- interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc UART7_K>;
- wakeup-source;
- dmas = <&dmamux1 79 0x400 0x15>,
- <&dmamux1 80 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uart8: serial@40019000 {
- compatible = "st,stm32h7-uart";
- reg = <0x40019000 0x400>;
- interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc UART8_K>;
- wakeup-source;
- dmas = <&dmamux1 81 0x400 0x15>,
- <&dmamux1 82 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- timers1: timer@44000000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x44000000 0x400>;
- interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "brk", "up", "trg-com", "cc";
- clocks = <&rcc TIM1_K>;
- clock-names = "int";
- dmas = <&dmamux1 11 0x400 0x1>,
- <&dmamux1 12 0x400 0x1>,
- <&dmamux1 13 0x400 0x1>,
- <&dmamux1 14 0x400 0x1>,
- <&dmamux1 15 0x400 0x1>,
- <&dmamux1 16 0x400 0x1>,
- <&dmamux1 17 0x400 0x1>;
- dma-names = "ch1", "ch2", "ch3", "ch4",
- "up", "trig", "com";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@0 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <0>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-timer-counter";
- status = "disabled";
- };
- };
-
- timers8: timer@44001000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x44001000 0x400>;
- interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "brk", "up", "trg-com", "cc";
- clocks = <&rcc TIM8_K>;
- clock-names = "int";
- dmas = <&dmamux1 47 0x400 0x1>,
- <&dmamux1 48 0x400 0x1>,
- <&dmamux1 49 0x400 0x1>,
- <&dmamux1 50 0x400 0x1>,
- <&dmamux1 51 0x400 0x1>,
- <&dmamux1 52 0x400 0x1>,
- <&dmamux1 53 0x400 0x1>;
- dma-names = "ch1", "ch2", "ch3", "ch4",
- "up", "trig", "com";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@7 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <7>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-timer-counter";
- status = "disabled";
- };
- };
-
- usart6: serial@44003000 {
- compatible = "st,stm32h7-uart";
- reg = <0x44003000 0x400>;
- interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc USART6_K>;
- wakeup-source;
- dmas = <&dmamux1 71 0x400 0x15>,
- <&dmamux1 72 0x400 0x11>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi1: spi@44004000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32h7-spi";
- reg = <0x44004000 0x400>;
- interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI1_K>;
- resets = <&rcc SPI1_R>;
- dmas = <&dmamux1 37 0x400 0x05>,
- <&dmamux1 38 0x400 0x05>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2s1: audio-controller@44004000 {
- compatible = "st,stm32h7-i2s";
- #sound-dai-cells = <0>;
- reg = <0x44004000 0x400>;
- interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 37 0x400 0x01>,
- <&dmamux1 38 0x400 0x01>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi4: spi@44005000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32h7-spi";
- reg = <0x44005000 0x400>;
- interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI4_K>;
- resets = <&rcc SPI4_R>;
- dmas = <&dmamux1 83 0x400 0x05>,
- <&dmamux1 84 0x400 0x05>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- timers15: timer@44006000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x44006000 0x400>;
- interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM15_K>;
- clock-names = "int";
- dmas = <&dmamux1 105 0x400 0x1>,
- <&dmamux1 106 0x400 0x1>,
- <&dmamux1 107 0x400 0x1>,
- <&dmamux1 108 0x400 0x1>;
- dma-names = "ch1", "up", "trig", "com";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@14 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <14>;
- status = "disabled";
- };
- };
-
- timers16: timer@44007000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x44007000 0x400>;
- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM16_K>;
- clock-names = "int";
- dmas = <&dmamux1 109 0x400 0x1>,
- <&dmamux1 110 0x400 0x1>;
- dma-names = "ch1", "up";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
- timer@15 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <15>;
- status = "disabled";
- };
- };
-
- timers17: timer@44008000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-timers";
- reg = <0x44008000 0x400>;
- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "global";
- clocks = <&rcc TIM17_K>;
- clock-names = "int";
- dmas = <&dmamux1 111 0x400 0x1>,
- <&dmamux1 112 0x400 0x1>;
- dma-names = "ch1", "up";
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- timer@16 {
- compatible = "st,stm32h7-timer-trigger";
- reg = <16>;
- status = "disabled";
- };
- };
-
- spi5: spi@44009000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32h7-spi";
- reg = <0x44009000 0x400>;
- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI5_K>;
- resets = <&rcc SPI5_R>;
- dmas = <&dmamux1 85 0x400 0x05>,
- <&dmamux1 86 0x400 0x05>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- sai1: sai@4400a000 {
- compatible = "st,stm32h7-sai";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x4400a000 0x400>;
- reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>;
- interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&rcc SAI1_R>;
- status = "disabled";
-
- sai1a: audio-controller@4400a004 {
- #sound-dai-cells = <0>;
-
- compatible = "st,stm32-sai-sub-a";
- reg = <0x4 0x20>;
- clocks = <&rcc SAI1_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 87 0x400 0x01>;
- status = "disabled";
- };
-
- sai1b: audio-controller@4400a024 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-b";
- reg = <0x24 0x20>;
- clocks = <&rcc SAI1_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 88 0x400 0x01>;
- status = "disabled";
- };
- };
-
- sai2: sai@4400b000 {
- compatible = "st,stm32h7-sai";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x4400b000 0x400>;
- reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
- interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&rcc SAI2_R>;
- status = "disabled";
-
- sai2a: audio-controller@4400b004 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-a";
- reg = <0x4 0x20>;
- clocks = <&rcc SAI2_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 89 0x400 0x01>;
- status = "disabled";
- };
-
- sai2b: audio-controller@4400b024 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-b";
- reg = <0x24 0x20>;
- clocks = <&rcc SAI2_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 90 0x400 0x01>;
- status = "disabled";
- };
- };
-
- sai3: sai@4400c000 {
- compatible = "st,stm32h7-sai";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x4400c000 0x400>;
- reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>;
- interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&rcc SAI3_R>;
- status = "disabled";
-
- sai3a: audio-controller@4400c004 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-a";
- reg = <0x04 0x20>;
- clocks = <&rcc SAI3_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 113 0x400 0x01>;
- status = "disabled";
- };
-
- sai3b: audio-controller@4400c024 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-b";
- reg = <0x24 0x20>;
- clocks = <&rcc SAI3_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 114 0x400 0x01>;
- status = "disabled";
- };
- };
-
- dfsdm: dfsdm@4400d000 {
- compatible = "st,stm32mp1-dfsdm";
- reg = <0x4400d000 0x800>;
- clocks = <&rcc DFSDM_K>;
- clock-names = "dfsdm";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- dfsdm0: filter@0 {
- compatible = "st,stm32-dfsdm-adc";
- #io-channel-cells = <1>;
- reg = <0>;
- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 101 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
-
- dfsdm1: filter@1 {
- compatible = "st,stm32-dfsdm-adc";
- #io-channel-cells = <1>;
- reg = <1>;
- interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 102 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
-
- dfsdm2: filter@2 {
- compatible = "st,stm32-dfsdm-adc";
- #io-channel-cells = <1>;
- reg = <2>;
- interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 103 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
-
- dfsdm3: filter@3 {
- compatible = "st,stm32-dfsdm-adc";
- #io-channel-cells = <1>;
- reg = <3>;
- interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 104 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
-
- dfsdm4: filter@4 {
- compatible = "st,stm32-dfsdm-adc";
- #io-channel-cells = <1>;
- reg = <4>;
- interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 91 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
-
- dfsdm5: filter@5 {
- compatible = "st,stm32-dfsdm-adc";
- #io-channel-cells = <1>;
- reg = <5>;
- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&dmamux1 92 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
- };
-
- dma1: dma-controller@48000000 {
- compatible = "st,stm32-dma";
- reg = <0x48000000 0x400>;
- interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc DMA1>;
- resets = <&rcc DMA1_R>;
- #dma-cells = <4>;
- st,mem2mem;
- dma-requests = <8>;
- };
-
- dma2: dma-controller@48001000 {
- compatible = "st,stm32-dma";
- reg = <0x48001000 0x400>;
- interrupts = <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>,
- <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc DMA2>;
- resets = <&rcc DMA2_R>;
- #dma-cells = <4>;
- st,mem2mem;
- dma-requests = <8>;
- };
-
- dmamux1: dma-router@48002000 {
- compatible = "st,stm32h7-dmamux";
- reg = <0x48002000 0x40>;
- #dma-cells = <3>;
- dma-requests = <128>;
- dma-masters = <&dma1 &dma2>;
- dma-channels = <16>;
- clocks = <&rcc DMAMUX>;
- resets = <&rcc DMAMUX_R>;
- };
-
- adc: adc@48003000 {
- compatible = "st,stm32mp1-adc-core";
- reg = <0x48003000 0x400>;
- interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc ADC12>, <&rcc ADC12_K>;
- clock-names = "bus", "adc";
- interrupt-controller;
- st,syscfg = <&syscfg>;
- #interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- adc1: adc@0 {
- compatible = "st,stm32mp1-adc";
- #io-channel-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0>;
- interrupt-parent = <&adc>;
- interrupts = <0>;
- dmas = <&dmamux1 9 0x400 0x01>;
- dma-names = "rx";
- status = "disabled";
- };
-
- adc2: adc@100 {
- compatible = "st,stm32mp1-adc";
- #io-channel-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x100>;
- interrupt-parent = <&adc>;
- interrupts = <1>;
- dmas = <&dmamux1 10 0x400 0x01>;
- dma-names = "rx";
- nvmem-cells = <&vrefint>;
- nvmem-cell-names = "vrefint";
- status = "disabled";
- channel@13 {
- reg = <13>;
- label = "vrefint";
- };
- channel@14 {
- reg = <14>;
- label = "vddcore";
- };
- };
- };
-
- sdmmc3: mmc@48004000 {
- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
- arm,primecell-periphid = <0x00253180>;
- reg = <0x48004000 0x400>;
- interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SDMMC3_K>;
- clock-names = "apb_pclk";
- resets = <&rcc SDMMC3_R>;
- cap-sd-highspeed;
- cap-mmc-highspeed;
- max-frequency = <120000000>;
- status = "disabled";
- };
-
- usbotg_hs: usb-otg@49000000 {
- compatible = "st,stm32mp15-hsotg", "snps,dwc2";
- reg = <0x49000000 0x10000>;
- clocks = <&rcc USBO_K>, <&usbphyc>;
- clock-names = "otg", "utmi";
- resets = <&rcc USBO_R>;
- reset-names = "dwc2";
- interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
- g-rx-fifo-size = <512>;
- g-np-tx-fifo-size = <32>;
- g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
- dr_mode = "otg";
- otg-rev = <0x200>;
- usb33d-supply = <&usb33>;
- status = "disabled";
- };
-
ipcc: mailbox@4c001000 {
compatible = "st,stm32mp1-ipcc";
#mbox-cells = <1>;
@@ -1172,18 +137,6 @@
status = "disabled";
};
- dcmi: dcmi@4c006000 {
- compatible = "st,stm32-dcmi";
- reg = <0x4c006000 0x400>;
- interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&rcc CAMITF_R>;
- clocks = <&rcc DCMI>;
- clock-names = "mclk";
- dmas = <&dmamux1 75 0x400 0x01>;
- dma-names = "tx";
- status = "disabled";
- };
-
rcc: rcc@50000000 {
compatible = "st,stm32mp1-rcc", "syscon";
reg = <0x50000000 0x1000>;
@@ -1224,6 +177,81 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x5000d000 0x400>;
+ interrupts-extended =
+ <&intc GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_0 */
+ <&intc GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_10 */
+ <&intc GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0>, /* EXTI_20 */
+ <&intc GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_30 */
+ <&intc GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>, /* EXTI_40 */
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_50 */
+ <0>,
+ <&intc GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>, /* EXTI_60 */
+ <&intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_70 */
+ <0>,
+ <0>,
+ <&intc GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
};
syscfg: syscon@50020000 {
@@ -1232,131 +260,6 @@
clocks = <&rcc SYSCFG>;
};
- lptimer2: timer@50021000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-lptimer";
- reg = <0x50021000 0x400>;
- interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM2_K>;
- clock-names = "mux";
- wakeup-source;
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- trigger@1 {
- compatible = "st,stm32-lptimer-trigger";
- reg = <1>;
- status = "disabled";
- };
-
- counter {
- compatible = "st,stm32-lptimer-counter";
- status = "disabled";
- };
- };
-
- lptimer3: timer@50022000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32-lptimer";
- reg = <0x50022000 0x400>;
- interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM3_K>;
- clock-names = "mux";
- wakeup-source;
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- trigger@2 {
- compatible = "st,stm32-lptimer-trigger";
- reg = <2>;
- status = "disabled";
- };
- };
-
- lptimer4: timer@50023000 {
- compatible = "st,stm32-lptimer";
- reg = <0x50023000 0x400>;
- interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM4_K>;
- clock-names = "mux";
- wakeup-source;
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
- };
- };
-
- lptimer5: timer@50024000 {
- compatible = "st,stm32-lptimer";
- reg = <0x50024000 0x400>;
- interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc LPTIM5_K>;
- clock-names = "mux";
- wakeup-source;
- status = "disabled";
-
- pwm {
- compatible = "st,stm32-pwm-lp";
- #pwm-cells = <3>;
- status = "disabled";
- };
- };
-
- vrefbuf: vrefbuf@50025000 {
- compatible = "st,stm32-vrefbuf";
- reg = <0x50025000 0x8>;
- regulator-min-microvolt = <1500000>;
- regulator-max-microvolt = <2500000>;
- clocks = <&rcc VREF>;
- status = "disabled";
- };
-
- sai4: sai@50027000 {
- compatible = "st,stm32h7-sai";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x50027000 0x400>;
- reg = <0x50027000 0x4>, <0x500273f0 0x10>;
- interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&rcc SAI4_R>;
- status = "disabled";
-
- sai4a: audio-controller@50027004 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-a";
- reg = <0x04 0x20>;
- clocks = <&rcc SAI4_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 99 0x400 0x01>;
- status = "disabled";
- };
-
- sai4b: audio-controller@50027024 {
- #sound-dai-cells = <0>;
- compatible = "st,stm32-sai-sub-b";
- reg = <0x24 0x20>;
- clocks = <&rcc SAI4_K>;
- clock-names = "sai_ck";
- dmas = <&dmamux1 100 0x400 0x01>;
- status = "disabled";
- };
- };
-
dts: thermal@50028000 {
compatible = "st,stm32-thermal";
reg = <0x50028000 0x100>;
@@ -1367,26 +270,6 @@
status = "disabled";
};
- hash1: hash@54002000 {
- compatible = "st,stm32f756-hash";
- reg = <0x54002000 0x400>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc HASH1>;
- resets = <&rcc HASH1_R>;
- dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>;
- dma-names = "in";
- dma-maxburst = <2>;
- status = "disabled";
- };
-
- rng1: rng@54003000 {
- compatible = "st,stm32-rng";
- reg = <0x54003000 0x400>;
- clocks = <&rcc RNG1_K>;
- resets = <&rcc RNG1_R>;
- status = "disabled";
- };
-
mdma1: dma-controller@58000000 {
compatible = "st,stm32h7-mdma";
reg = <0x58000000 0x1000>;
@@ -1398,55 +281,6 @@
dma-requests = <48>;
};
- 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 {
- compatible = "st,stm32f469-qspi";
- reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
- reg-names = "qspi", "qspi_mm";
- interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&mdma1 22 0x2 0x10100002 0x0 0x0>,
- <&mdma1 22 0x2 0x10100008 0x0 0x0>;
- dma-names = "tx", "rx";
- clocks = <&rcc QSPI_K>;
- resets = <&rcc QSPI_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
sdmmc1: mmc@58005000 {
compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
@@ -1482,39 +316,6 @@
status = "disabled";
};
- ethernet0: ethernet@5800a000 {
- compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
- reg = <0x5800a000 0x2000>;
- reg-names = "stmmaceth";
- interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "macirq";
- clock-names = "stmmaceth",
- "mac-clk-tx",
- "mac-clk-rx",
- "eth-ck",
- "ptp_ref",
- "ethstp";
- clocks = <&rcc ETHMAC>,
- <&rcc ETHTX>,
- <&rcc ETHRX>,
- <&rcc ETHCK_K>,
- <&rcc ETHPTP_K>,
- <&rcc ETHSTP>;
- st,syscon = <&syscfg 0x4>;
- snps,mixed-burst;
- snps,pbl = <2>;
- snps,en-tx-lpi-clockgating;
- snps,axi-config = <&stmmac_axi_config_0>;
- snps,tso;
- status = "disabled";
-
- stmmac_axi_config_0: stmmac-axi-config {
- snps,wr_osr_lmt = <0x7>;
- snps,rd_osr_lmt = <0x7>;
- snps,blen = <0 0 0 0 16 8 4>;
- };
- };
-
usbh_ohci: usb@5800c000 {
compatible = "generic-ohci";
reg = <0x5800c000 0x1000>;
@@ -1580,45 +381,6 @@
};
};
- usart1: serial@5c000000 {
- compatible = "st,stm32h7-uart";
- reg = <0x5c000000 0x400>;
- interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc USART1_K>;
- wakeup-source;
- status = "disabled";
- };
-
- spi6: spi@5c001000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32h7-spi";
- reg = <0x5c001000 0x400>;
- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc SPI6_K>;
- resets = <&rcc SPI6_R>;
- dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
- <&mdma1 35 0x0 0x40002 0x0 0x0>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c4: i2c@5c002000 {
- compatible = "st,stm32mp15-i2c";
- reg = <0x5c002000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C4_K>;
- resets = <&rcc I2C4_R>;
- #address-cells = <1>;
- #size-cells = <0>;
- st,syscfg-fmp = <&syscfg 0x4 0x8>;
- wakeup-source;
- i2c-analog-filter;
- status = "disabled";
- };
-
rtc: rtc@5c004000 {
compatible = "st,stm32mp1-rtc";
reg = <0x5c004000 0x400>;
@@ -1647,20 +409,1406 @@
};
};
- i2c6: i2c@5c009000 {
- compatible = "st,stm32mp15-i2c";
- reg = <0x5c009000 0x400>;
- interrupt-names = "event", "error";
- interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc I2C6_K>;
- resets = <&rcc I2C6_R>;
+ etzpc: bus@5c007000 {
+ compatible = "st,stm32-etzpc", "simple-bus";
+ reg = <0x5c007000 0x400>;
#address-cells = <1>;
- #size-cells = <0>;
- st,syscfg-fmp = <&syscfg 0x4 0x20>;
- wakeup-source;
- i2c-analog-filter;
- status = "disabled";
+ #size-cells = <1>;
+ #access-controller-cells = <1>;
+ ranges;
+
+ timers2: timer@40000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40000000 0x400>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM2_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 18 0x400 0x1>,
+ <&dmamux1 19 0x400 0x1>,
+ <&dmamux1 20 0x400 0x1>,
+ <&dmamux1 21 0x400 0x1>,
+ <&dmamux1 22 0x400 0x1>;
+ dma-names = "ch1", "ch2", "ch3", "ch4", "up";
+ access-controllers = <&etzpc 16>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@1 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <1>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-timer-counter";
+ status = "disabled";
+ };
+ };
+
+ timers3: timer@40001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40001000 0x400>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM3_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 23 0x400 0x1>,
+ <&dmamux1 24 0x400 0x1>,
+ <&dmamux1 25 0x400 0x1>,
+ <&dmamux1 26 0x400 0x1>,
+ <&dmamux1 27 0x400 0x1>,
+ <&dmamux1 28 0x400 0x1>;
+ dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+ access-controllers = <&etzpc 17>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@2 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <2>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-timer-counter";
+ status = "disabled";
+ };
+ };
+
+ timers4: timer@40002000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40002000 0x400>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM4_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 29 0x400 0x1>,
+ <&dmamux1 30 0x400 0x1>,
+ <&dmamux1 31 0x400 0x1>,
+ <&dmamux1 32 0x400 0x1>;
+ dma-names = "ch1", "ch2", "ch3", "ch4";
+ access-controllers = <&etzpc 18>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@3 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <3>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-timer-counter";
+ status = "disabled";
+ };
+ };
+
+ timers5: timer@40003000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40003000 0x400>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM5_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 55 0x400 0x1>,
+ <&dmamux1 56 0x400 0x1>,
+ <&dmamux1 57 0x400 0x1>,
+ <&dmamux1 58 0x400 0x1>,
+ <&dmamux1 59 0x400 0x1>,
+ <&dmamux1 60 0x400 0x1>;
+ dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+ access-controllers = <&etzpc 19>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@4 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <4>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-timer-counter";
+ status = "disabled";
+ };
+ };
+
+ timers6: timer@40004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40004000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM6_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 69 0x400 0x1>;
+ dma-names = "up";
+ access-controllers = <&etzpc 20>;
+ status = "disabled";
+
+ timer@5 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <5>;
+ status = "disabled";
+ };
+ };
+
+ timers7: timer@40005000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40005000 0x400>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM7_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 70 0x400 0x1>;
+ dma-names = "up";
+ access-controllers = <&etzpc 21>;
+ status = "disabled";
+
+ timer@6 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <6>;
+ status = "disabled";
+ };
+ };
+
+ timers12: timer@40006000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40006000 0x400>;
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM12_K>;
+ clock-names = "int";
+ access-controllers = <&etzpc 22>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@11 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <11>;
+ status = "disabled";
+ };
+ };
+
+ timers13: timer@40007000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40007000 0x400>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM13_K>;
+ clock-names = "int";
+ access-controllers = <&etzpc 23>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@12 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <12>;
+ status = "disabled";
+ };
+ };
+
+ timers14: timer@40008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40008000 0x400>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM14_K>;
+ clock-names = "int";
+ access-controllers = <&etzpc 24>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@13 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <13>;
+ status = "disabled";
+ };
+ };
+
+ lptimer1: timer@40009000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-lptimer";
+ reg = <0x40009000 0x400>;
+ interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM1_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 25>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ trigger@0 {
+ compatible = "st,stm32-lptimer-trigger";
+ reg = <0>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-lptimer-counter";
+ status = "disabled";
+ };
+ };
+
+ i2s2: audio-controller@4000b000 {
+ compatible = "st,stm32h7-i2s";
+ #sound-dai-cells = <0>;
+ reg = <0x4000b000 0x400>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 39 0x400 0x01>,
+ <&dmamux1 40 0x400 0x01>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 27>;
+ status = "disabled";
+ };
+
+ spi2: spi@4000b000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x4000b000 0x400>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI2_K>;
+ resets = <&rcc SPI2_R>;
+ dmas = <&dmamux1 39 0x400 0x05>,
+ <&dmamux1 40 0x400 0x05>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 27>;
+ status = "disabled";
+ };
+
+ i2s3: audio-controller@4000c000 {
+ compatible = "st,stm32h7-i2s";
+ #sound-dai-cells = <0>;
+ reg = <0x4000c000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 61 0x400 0x01>,
+ <&dmamux1 62 0x400 0x01>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 28>;
+ status = "disabled";
+ };
+
+ spi3: spi@4000c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x4000c000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI3_K>;
+ resets = <&rcc SPI3_R>;
+ dmas = <&dmamux1 61 0x400 0x05>,
+ <&dmamux1 62 0x400 0x05>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 28>;
+ status = "disabled";
+ };
+
+ spdifrx: audio-controller@4000d000 {
+ compatible = "st,stm32h7-spdifrx";
+ #sound-dai-cells = <0>;
+ reg = <0x4000d000 0x400>;
+ clocks = <&rcc SPDIF_K>;
+ clock-names = "kclk";
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 93 0x400 0x01>,
+ <&dmamux1 94 0x400 0x01>;
+ dma-names = "rx", "rx-ctrl";
+ access-controllers = <&etzpc 29>;
+ status = "disabled";
+ };
+
+ usart2: serial@4000e000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4000e000 0x400>;
+ interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART2_K>;
+ wakeup-source;
+ dmas = <&dmamux1 43 0x400 0x15>,
+ <&dmamux1 44 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 30>;
+ status = "disabled";
+ };
+
+ usart3: serial@4000f000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4000f000 0x400>;
+ interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART3_K>;
+ wakeup-source;
+ dmas = <&dmamux1 45 0x400 0x15>,
+ <&dmamux1 46 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 31>;
+ status = "disabled";
+ };
+
+ uart4: serial@40010000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40010000 0x400>;
+ interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART4_K>;
+ wakeup-source;
+ dmas = <&dmamux1 63 0x400 0x15>,
+ <&dmamux1 64 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 32>;
+ status = "disabled";
+ };
+
+ uart5: serial@40011000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40011000 0x400>;
+ interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART5_K>;
+ wakeup-source;
+ dmas = <&dmamux1 65 0x400 0x15>,
+ <&dmamux1 66 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 33>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@40012000 {
+ compatible = "st,stm32mp15-i2c";
+ reg = <0x40012000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C1_K>;
+ resets = <&rcc I2C1_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x1>;
+ wakeup-source;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 34>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@40013000 {
+ compatible = "st,stm32mp15-i2c";
+ reg = <0x40013000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C2_K>;
+ resets = <&rcc I2C2_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x2>;
+ wakeup-source;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 35>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@40014000 {
+ compatible = "st,stm32mp15-i2c";
+ reg = <0x40014000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C3_K>;
+ resets = <&rcc I2C3_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x4>;
+ wakeup-source;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 36>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@40015000 {
+ compatible = "st,stm32mp15-i2c";
+ reg = <0x40015000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C5_K>;
+ resets = <&rcc I2C5_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x10>;
+ wakeup-source;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 37>;
+ status = "disabled";
+ };
+
+ cec: cec@40016000 {
+ compatible = "st,stm32-cec";
+ reg = <0x40016000 0x400>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CEC_K>, <&rcc CEC>;
+ clock-names = "cec", "hdmi-cec";
+ access-controllers = <&etzpc 38>;
+ status = "disabled";
+ };
+
+ dac: dac@40017000 {
+ compatible = "st,stm32h7-dac-core";
+ reg = <0x40017000 0x400>;
+ clocks = <&rcc DAC12>;
+ clock-names = "pclk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&etzpc 39>;
+ status = "disabled";
+
+ dac1: dac@1 {
+ compatible = "st,stm32-dac";
+ #io-channel-cells = <1>;
+ reg = <1>;
+ status = "disabled";
+ };
+
+ dac2: dac@2 {
+ compatible = "st,stm32-dac";
+ #io-channel-cells = <1>;
+ reg = <2>;
+ status = "disabled";
+ };
+ };
+
+ uart7: serial@40018000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40018000 0x400>;
+ interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART7_K>;
+ wakeup-source;
+ dmas = <&dmamux1 79 0x400 0x15>,
+ <&dmamux1 80 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 40>;
+ status = "disabled";
+ };
+
+ uart8: serial@40019000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40019000 0x400>;
+ interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART8_K>;
+ wakeup-source;
+ dmas = <&dmamux1 81 0x400 0x15>,
+ <&dmamux1 82 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 41>;
+ status = "disabled";
+ };
+
+ timers1: timer@44000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x44000000 0x400>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "brk", "up", "trg-com", "cc";
+ clocks = <&rcc TIM1_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 11 0x400 0x1>,
+ <&dmamux1 12 0x400 0x1>,
+ <&dmamux1 13 0x400 0x1>,
+ <&dmamux1 14 0x400 0x1>,
+ <&dmamux1 15 0x400 0x1>,
+ <&dmamux1 16 0x400 0x1>,
+ <&dmamux1 17 0x400 0x1>;
+ dma-names = "ch1", "ch2", "ch3", "ch4",
+ "up", "trig", "com";
+ access-controllers = <&etzpc 48>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@0 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <0>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-timer-counter";
+ status = "disabled";
+ };
+ };
+
+ timers8: timer@44001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x44001000 0x400>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "brk", "up", "trg-com", "cc";
+ clocks = <&rcc TIM8_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 47 0x400 0x1>,
+ <&dmamux1 48 0x400 0x1>,
+ <&dmamux1 49 0x400 0x1>,
+ <&dmamux1 50 0x400 0x1>,
+ <&dmamux1 51 0x400 0x1>,
+ <&dmamux1 52 0x400 0x1>,
+ <&dmamux1 53 0x400 0x1>;
+ dma-names = "ch1", "ch2", "ch3", "ch4",
+ "up", "trig", "com";
+ access-controllers = <&etzpc 49>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@7 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <7>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-timer-counter";
+ status = "disabled";
+ };
+ };
+
+ usart6: serial@44003000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x44003000 0x400>;
+ interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART6_K>;
+ wakeup-source;
+ dmas = <&dmamux1 71 0x400 0x15>,
+ <&dmamux1 72 0x400 0x11>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 51>;
+ status = "disabled";
+ };
+
+ i2s1: audio-controller@44004000 {
+ compatible = "st,stm32h7-i2s";
+ #sound-dai-cells = <0>;
+ reg = <0x44004000 0x400>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 37 0x400 0x01>,
+ <&dmamux1 38 0x400 0x01>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 52>;
+ status = "disabled";
+ };
+
+ spi1: spi@44004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x44004000 0x400>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI1_K>;
+ resets = <&rcc SPI1_R>;
+ dmas = <&dmamux1 37 0x400 0x05>,
+ <&dmamux1 38 0x400 0x05>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 52>;
+ status = "disabled";
+ };
+
+ spi4: spi@44005000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x44005000 0x400>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI4_K>;
+ resets = <&rcc SPI4_R>;
+ dmas = <&dmamux1 83 0x400 0x05>,
+ <&dmamux1 84 0x400 0x05>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 53>;
+ status = "disabled";
+ };
+
+ timers15: timer@44006000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x44006000 0x400>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM15_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 105 0x400 0x1>,
+ <&dmamux1 106 0x400 0x1>,
+ <&dmamux1 107 0x400 0x1>,
+ <&dmamux1 108 0x400 0x1>;
+ dma-names = "ch1", "up", "trig", "com";
+ access-controllers = <&etzpc 54>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@14 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <14>;
+ status = "disabled";
+ };
+ };
+
+ timers16: timer@44007000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x44007000 0x400>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM16_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 109 0x400 0x1>,
+ <&dmamux1 110 0x400 0x1>;
+ dma-names = "ch1", "up";
+ access-controllers = <&etzpc 55>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+ timer@15 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <15>;
+ status = "disabled";
+ };
+ };
+
+ timers17: timer@44008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x44008000 0x400>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "global";
+ clocks = <&rcc TIM17_K>;
+ clock-names = "int";
+ dmas = <&dmamux1 111 0x400 0x1>,
+ <&dmamux1 112 0x400 0x1>;
+ dma-names = "ch1", "up";
+ access-controllers = <&etzpc 56>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ timer@16 {
+ compatible = "st,stm32h7-timer-trigger";
+ reg = <16>;
+ status = "disabled";
+ };
+ };
+
+ spi5: spi@44009000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x44009000 0x400>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI5_K>;
+ resets = <&rcc SPI5_R>;
+ dmas = <&dmamux1 85 0x400 0x05>,
+ <&dmamux1 86 0x400 0x05>;
+ dma-names = "rx", "tx";
+ access-controllers = <&etzpc 57>;
+ status = "disabled";
+ };
+
+ sai1: sai@4400a000 {
+ compatible = "st,stm32h7-sai";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4400a000 0x400>;
+ reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rcc SAI1_R>;
+ access-controllers = <&etzpc 58>;
+ status = "disabled";
+
+ sai1a: audio-controller@4400a004 {
+ #sound-dai-cells = <0>;
+
+ compatible = "st,stm32-sai-sub-a";
+ reg = <0x4 0x20>;
+ clocks = <&rcc SAI1_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 87 0x400 0x01>;
+ status = "disabled";
+ };
+
+ sai1b: audio-controller@4400a024 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-b";
+ reg = <0x24 0x20>;
+ clocks = <&rcc SAI1_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 88 0x400 0x01>;
+ status = "disabled";
+ };
+ };
+
+ sai2: sai@4400b000 {
+ compatible = "st,stm32h7-sai";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4400b000 0x400>;
+ reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rcc SAI2_R>;
+ access-controllers = <&etzpc 59>;
+ status = "disabled";
+
+ sai2a: audio-controller@4400b004 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-a";
+ reg = <0x4 0x20>;
+ clocks = <&rcc SAI2_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 89 0x400 0x01>;
+ status = "disabled";
+ };
+
+ sai2b: audio-controller@4400b024 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-b";
+ reg = <0x24 0x20>;
+ clocks = <&rcc SAI2_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 90 0x400 0x01>;
+ status = "disabled";
+ };
+ };
+
+ sai3: sai@4400c000 {
+ compatible = "st,stm32h7-sai";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4400c000 0x400>;
+ reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rcc SAI3_R>;
+ access-controllers = <&etzpc 60>;
+ status = "disabled";
+
+ sai3a: audio-controller@4400c004 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-a";
+ reg = <0x04 0x20>;
+ clocks = <&rcc SAI3_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 113 0x400 0x01>;
+ status = "disabled";
+ };
+
+ sai3b: audio-controller@4400c024 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-b";
+ reg = <0x24 0x20>;
+ clocks = <&rcc SAI3_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 114 0x400 0x01>;
+ status = "disabled";
+ };
+ };
+
+ dfsdm: dfsdm@4400d000 {
+ compatible = "st,stm32mp1-dfsdm";
+ reg = <0x4400d000 0x800>;
+ clocks = <&rcc DFSDM_K>;
+ clock-names = "dfsdm";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&etzpc 61>;
+ status = "disabled";
+
+ dfsdm0: filter@0 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <0>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 101 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm1: filter@1 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <1>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 102 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm2: filter@2 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <2>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 103 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm3: filter@3 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <3>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 104 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm4: filter@4 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <4>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 91 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm5: filter@5 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <5>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 92 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+ };
+
+ dma1: dma-controller@48000000 {
+ compatible = "st,stm32-dma";
+ reg = <0x48000000 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc DMA1>;
+ resets = <&rcc DMA1_R>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ dma-requests = <8>;
+ access-controllers = <&etzpc 88>;
+ };
+
+ dma2: dma-controller@48001000 {
+ compatible = "st,stm32-dma";
+ reg = <0x48001000 0x400>;
+ interrupts = <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>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc DMA2>;
+ resets = <&rcc DMA2_R>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ dma-requests = <8>;
+ access-controllers = <&etzpc 89>;
+ };
+
+ dmamux1: dma-router@48002000 {
+ compatible = "st,stm32h7-dmamux";
+ reg = <0x48002000 0x40>;
+ #dma-cells = <3>;
+ dma-requests = <128>;
+ dma-masters = <&dma1 &dma2>;
+ dma-channels = <16>;
+ clocks = <&rcc DMAMUX>;
+ resets = <&rcc DMAMUX_R>;
+ access-controllers = <&etzpc 90>;
+ };
+
+ adc: adc@48003000 {
+ compatible = "st,stm32mp1-adc-core";
+ reg = <0x48003000 0x400>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc ADC12>, <&rcc ADC12_K>;
+ clock-names = "bus", "adc";
+ interrupt-controller;
+ st,syscfg = <&syscfg>;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&etzpc 72>;
+ status = "disabled";
+
+ adc1: adc@0 {
+ compatible = "st,stm32mp1-adc";
+ #io-channel-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ interrupt-parent = <&adc>;
+ interrupts = <0>;
+ dmas = <&dmamux1 9 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ adc2: adc@100 {
+ compatible = "st,stm32mp1-adc";
+ #io-channel-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x100>;
+ interrupt-parent = <&adc>;
+ interrupts = <1>;
+ dmas = <&dmamux1 10 0x400 0x01>;
+ dma-names = "rx";
+ nvmem-cells = <&vrefint>;
+ nvmem-cell-names = "vrefint";
+ status = "disabled";
+ channel@13 {
+ reg = <13>;
+ label = "vrefint";
+ };
+ channel@14 {
+ reg = <14>;
+ label = "vddcore";
+ };
+ };
+ };
+
+ sdmmc3: mmc@48004000 {
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00253180>;
+ reg = <0x48004000 0x400>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SDMMC3_K>;
+ clock-names = "apb_pclk";
+ resets = <&rcc SDMMC3_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <120000000>;
+ access-controllers = <&etzpc 86>;
+ status = "disabled";
+ };
+
+ usbotg_hs: usb-otg@49000000 {
+ compatible = "st,stm32mp15-hsotg", "snps,dwc2";
+ reg = <0x49000000 0x10000>;
+ clocks = <&rcc USBO_K>, <&usbphyc>;
+ clock-names = "otg", "utmi";
+ resets = <&rcc USBO_R>;
+ reset-names = "dwc2";
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ g-rx-fifo-size = <512>;
+ g-np-tx-fifo-size = <32>;
+ g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
+ dr_mode = "otg";
+ otg-rev = <0x200>;
+ usb33d-supply = <&usb33>;
+ access-controllers = <&etzpc 85>;
+ status = "disabled";
+ };
+
+ dcmi: dcmi@4c006000 {
+ compatible = "st,stm32-dcmi";
+ reg = <0x4c006000 0x400>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rcc CAMITF_R>;
+ clocks = <&rcc DCMI>;
+ clock-names = "mclk";
+ dmas = <&dmamux1 75 0x400 0x01>;
+ dma-names = "tx";
+ access-controllers = <&etzpc 70>;
+ status = "disabled";
+ };
+
+ lptimer2: timer@50021000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-lptimer";
+ reg = <0x50021000 0x400>;
+ interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM2_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 64>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ trigger@1 {
+ compatible = "st,stm32-lptimer-trigger";
+ reg = <1>;
+ status = "disabled";
+ };
+
+ counter {
+ compatible = "st,stm32-lptimer-counter";
+ status = "disabled";
+ };
+ };
+
+ lptimer3: timer@50022000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-lptimer";
+ reg = <0x50022000 0x400>;
+ interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM3_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 65>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ trigger@2 {
+ compatible = "st,stm32-lptimer-trigger";
+ reg = <2>;
+ status = "disabled";
+ };
+ };
+
+ lptimer4: timer@50023000 {
+ compatible = "st,stm32-lptimer";
+ reg = <0x50023000 0x400>;
+ interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM4_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 66>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+ };
+
+ lptimer5: timer@50024000 {
+ compatible = "st,stm32-lptimer";
+ reg = <0x50024000 0x400>;
+ interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc LPTIM5_K>;
+ clock-names = "mux";
+ wakeup-source;
+ access-controllers = <&etzpc 67>;
+ status = "disabled";
+
+ pwm {
+ compatible = "st,stm32-pwm-lp";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+ };
+
+ vrefbuf: vrefbuf@50025000 {
+ compatible = "st,stm32-vrefbuf";
+ reg = <0x50025000 0x8>;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2500000>;
+ clocks = <&rcc VREF>;
+ access-controllers = <&etzpc 69>;
+ status = "disabled";
+ };
+
+ sai4: sai@50027000 {
+ compatible = "st,stm32h7-sai";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x50027000 0x400>;
+ reg = <0x50027000 0x4>, <0x500273f0 0x10>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rcc SAI4_R>;
+ access-controllers = <&etzpc 68>;
+ status = "disabled";
+
+ sai4a: audio-controller@50027004 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-a";
+ reg = <0x04 0x20>;
+ clocks = <&rcc SAI4_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 99 0x400 0x01>;
+ status = "disabled";
+ };
+
+ sai4b: audio-controller@50027024 {
+ #sound-dai-cells = <0>;
+ compatible = "st,stm32-sai-sub-b";
+ reg = <0x24 0x20>;
+ clocks = <&rcc SAI4_K>;
+ clock-names = "sai_ck";
+ dmas = <&dmamux1 100 0x400 0x01>;
+ status = "disabled";
+ };
+ };
+
+ hash1: hash@54002000 {
+ compatible = "st,stm32f756-hash";
+ reg = <0x54002000 0x400>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc HASH1>;
+ resets = <&rcc HASH1_R>;
+ dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>;
+ dma-names = "in";
+ dma-maxburst = <2>;
+ access-controllers = <&etzpc 8>;
+ status = "disabled";
+ };
+
+ rng1: rng@54003000 {
+ compatible = "st,stm32-rng";
+ reg = <0x54003000 0x400>;
+ clocks = <&rcc RNG1_K>;
+ resets = <&rcc RNG1_R>;
+ access-controllers = <&etzpc 7>;
+ status = "disabled";
+ };
+
+ 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>;
+ access-controllers = <&etzpc 91>;
+ 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 {
+ compatible = "st,stm32f469-qspi";
+ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+ reg-names = "qspi", "qspi_mm";
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdma1 22 0x2 0x10100002 0x0 0x0>,
+ <&mdma1 22 0x2 0x10100008 0x0 0x0>;
+ dma-names = "tx", "rx";
+ clocks = <&rcc QSPI_K>;
+ resets = <&rcc QSPI_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&etzpc 92>;
+ status = "disabled";
+ };
+
+ ethernet0: ethernet@5800a000 {
+ compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800a000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "eth-ck",
+ "ptp_ref",
+ "ethstp";
+ clocks = <&rcc ETHMAC>,
+ <&rcc ETHTX>,
+ <&rcc ETHRX>,
+ <&rcc ETHCK_K>,
+ <&rcc ETHPTP_K>,
+ <&rcc ETHSTP>;
+ st,syscon = <&syscfg 0x4>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,en-tx-lpi-clockgating;
+ snps,axi-config = <&stmmac_axi_config_0>;
+ snps,tso;
+ access-controllers = <&etzpc 94>;
+ status = "disabled";
+
+ stmmac_axi_config_0: stmmac-axi-config {
+ snps,wr_osr_lmt = <0x7>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,blen = <0 0 0 0 16 8 4>;
+ };
+ };
+
+ usart1: serial@5c000000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x5c000000 0x400>;
+ interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART1_K>;
+ wakeup-source;
+ access-controllers = <&etzpc 3>;
+ status = "disabled";
+ };
+
+ spi6: spi@5c001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x5c001000 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI6_K>;
+ resets = <&rcc SPI6_R>;
+ dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
+ <&mdma1 35 0x0 0x40002 0x0 0x0>;
+ access-controllers = <&etzpc 4>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c4: i2c@5c002000 {
+ compatible = "st,stm32mp15-i2c";
+ reg = <0x5c002000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C4_K>;
+ resets = <&rcc I2C4_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x8>;
+ wakeup-source;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 5>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@5c009000 {
+ compatible = "st,stm32mp15-i2c";
+ reg = <0x5c009000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C6_K>;
+ resets = <&rcc I2C6_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x20>;
+ wakeup-source;
+ i2c-analog-filter;
+ access-controllers = <&etzpc 12>;
+ status = "disabled";
+ };
};
tamp: tamp@5c00a000 {
diff --git a/arch/arm/boot/dts/st/stm32mp153.dtsi b/arch/arm/boot/dts/st/stm32mp153.dtsi
index 486084e0b80b..4640dafb1598 100644
--- a/arch/arm/boot/dts/st/stm32mp153.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp153.dtsi
@@ -28,32 +28,34 @@
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
};
+};
- soc {
- m_can1: can@4400e000 {
- compatible = "bosch,m_can";
- reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
- reg-names = "m_can", "message_ram";
- interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "int0", "int1";
- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
- clock-names = "hclk", "cclk";
- bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
- status = "disabled";
- };
+&etzpc {
+ m_can1: can@4400e000 {
+ compatible = "bosch,m_can";
+ reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+ clock-names = "hclk", "cclk";
+ bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+ access-controllers = <&etzpc 62>;
+ status = "disabled";
+ };
- m_can2: can@4400f000 {
- compatible = "bosch,m_can";
- reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
- reg-names = "m_can", "message_ram";
- interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "int0", "int1";
- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
- clock-names = "hclk", "cclk";
- bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
- status = "disabled";
- };
+ m_can2: can@4400f000 {
+ compatible = "bosch,m_can";
+ reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+ clock-names = "hclk", "cclk";
+ bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
+ access-controllers = <&etzpc 62>;
+ status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
index 306e1bc2a514..847b360f02fc 100644
--- a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
@@ -62,6 +62,11 @@
reset-names = "mcu_rst", "hold_boot";
};
+&optee {
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+};
+
&rcc {
compatible = "st,stm32mp1-rcc-secure", "syscon";
clock-names = "hse", "hsi", "csi", "lse", "lsi";
diff --git a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
index 956da5f26c1c..43280289759d 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
@@ -68,6 +68,11 @@
reset-names = "mcu_rst", "hold_boot";
};
+&optee {
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+};
+
&rcc {
compatible = "st,stm32mp1-rcc-secure", "syscon";
clock-names = "hse", "hsi", "csi", "lse", "lsi";
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
index 8e4b0db198c2..6f27d794d270 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
@@ -67,6 +67,11 @@
reset-names = "mcu_rst", "hold_boot";
};
+&optee {
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+};
+
&rcc {
compatible = "st,stm32mp1-rcc-secure", "syscon";
clock-names = "hse", "hsi", "csi", "lse", "lsi";
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ed1.dts b/arch/arm/boot/dts/st/stm32mp157c-ed1.dts
index 66ed5f9921ba..9cf5ed111b52 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ed1.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ed1.dts
@@ -10,6 +10,7 @@
#include "stm32mp15-pinctrl.dtsi"
#include "stm32mp15xxaa-pinctrl.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/mfd/st,stpmic1.h>
/ {
@@ -71,6 +72,17 @@
};
};
+ led {
+ compatible = "gpio-leds";
+ led-blue {
+ gpios = <&gpiod 9 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+ };
+
sd_switch: regulator-sd_switch {
compatible = "regulator-gpio";
regulator-name = "sd_switch";
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
index 72b9cab2d990..6ae391bffee5 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
@@ -72,6 +72,11 @@
reset-names = "mcu_rst", "hold_boot";
};
+&optee {
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+};
+
&rcc {
compatible = "st,stm32mp1-rcc-secure", "syscon";
clock-names = "hse", "hsi", "csi", "lse", "lsi";
diff --git a/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts b/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts
index 527c33be66cc..36e6055b5665 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts
@@ -147,11 +147,6 @@
status = "okay";
};
-&pwr_regulators {
- vdd-supply = <&vdd>;
- vdd_3v3_usbfs-supply = <&vdd_usb>;
-};
-
&rtc {
status = "okay";
};
@@ -211,11 +206,3 @@
&usbphyc {
status = "okay";
};
-
-&usbphyc_port0 {
- phy-supply = <&vdd_usb>;
-};
-
-&usbphyc_port1 {
- phy-supply = <&vdd_usb>;
-};
diff --git a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
index cfaf8adde319..c87fd96cbd91 100644
--- a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
@@ -379,11 +379,6 @@ baseboard_eeprom: &sip_eeprom {
};
};
-&pwr_regulators {
- vdd-supply = <&vdd>;
- vdd_3v3_usbfs-supply = <&vdd_usb>;
-};
-
&rtc {
status = "okay";
};
@@ -590,14 +585,6 @@ baseboard_eeprom: &sip_eeprom {
status = "okay";
};
-&usbphyc_port0 {
- phy-supply = <&vdd_usb>;
-};
-
-&usbphyc_port1 {
- phy-supply = <&vdd_usb>;
-};
-
&vrefbuf {
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
diff --git a/arch/arm/boot/dts/st/stm32mp15xc.dtsi b/arch/arm/boot/dts/st/stm32mp15xc.dtsi
index b06a55a2fa18..97465717f932 100644
--- a/arch/arm/boot/dts/st/stm32mp15xc.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xc.dtsi
@@ -4,15 +4,14 @@
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
-/ {
- soc {
- cryp1: cryp@54001000 {
- compatible = "st,stm32mp1-cryp";
- reg = <0x54001000 0x400>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc CRYP1>;
- resets = <&rcc CRYP1_R>;
- status = "disabled";
- };
+&etzpc {
+ cryp1: cryp@54001000 {
+ compatible = "st,stm32mp1-cryp";
+ reg = <0x54001000 0x400>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CRYP1>;
+ resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 9>;
+ status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi
index aeb71c41a734..2022a1fa31ca 100644
--- a/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi
@@ -214,3 +214,16 @@
&rng1 {
status = "okay";
};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+};
diff --git a/arch/arm/boot/dts/ti/davinci/da850-evm.dts b/arch/arm/boot/dts/ti/davinci/da850-evm.dts
index 6c5936278e75..1f5cd35f8b74 100644
--- a/arch/arm/boot/dts/ti/davinci/da850-evm.dts
+++ b/arch/arm/boot/dts/ti/davinci/da850-evm.dts
@@ -65,7 +65,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: 480x272 {
+ timing0: timing-480x272 {
clock-frequency = <9000000>;
hactive = <480>;
vactive = <272>;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
index 790b29ab0fa2..dafe485dfe19 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
@@ -256,11 +256,6 @@
pmmc: system-controller@2921c00 {
compatible = "ti,k2g-sci";
- /*
- * In case of rare platforms that does not use k2g as
- * system master, use /delete-property/
- */
- ti,system-reboot-controller;
mbox-names = "rx", "tx";
mboxes = <&msgmgr 5 2>,
<&msgmgr 0 0>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts
index 56e5d954a490..4b070e634b28 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts
@@ -74,7 +74,7 @@
pinctrl-1 = <&lcd_pins_sleep>;
display-timings {
- 320x240 {
+ timing-320x240 {
hactive = <320>;
vactive = <240>;
hback-porch = <68>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts
index f38f5bff2b96..17574d0d0525 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts
@@ -67,7 +67,7 @@
};
display-timings {
- 240x320p16 {
+ timing-240x320p16 {
clock-frequency = <6500000>;
hactive = <240>;
vactive = <320>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-pepper.dts b/arch/arm/boot/dts/ti/omap/am335x-pepper.dts
index d5a4a21889d1..e7d561a527fd 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-pepper.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-pepper.dts
@@ -202,7 +202,7 @@
};
display-timings {
native-mode = <&timing0>;
- timing0: 480x272 {
+ timing0: timing-480x272 {
clock-frequency = <18400000>;
hactive = <480>;
vactive = <272>;
diff --git a/arch/arm/boot/dts/ti/omap/am33xx.dtsi b/arch/arm/boot/dts/ti/omap/am33xx.dtsi
index 989d5a6edeed..0614ffdc1578 100644
--- a/arch/arm/boot/dts/ti/omap/am33xx.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am33xx.dtsi
@@ -80,7 +80,7 @@
* because the can not be enabled simultaneously on a
* single SoC.
*/
- opp-50-300000000{
+ opp-50-300000000 {
/* OPP50 */
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <950000 931000 969000>;
@@ -88,7 +88,7 @@
opp-suspend;
};
- opp-100-275000000{
+ opp-100-275000000 {
/* OPP100-1 */
opp-hz = /bits/ 64 <275000000>;
opp-microvolt = <1100000 1078000 1122000>;
@@ -96,7 +96,7 @@
opp-suspend;
};
- opp-100-300000000{
+ opp-100-300000000 {
/* OPP100-2 */
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <1100000 1078000 1122000>;
@@ -104,7 +104,7 @@
opp-suspend;
};
- opp-100-500000000{
+ opp-100-500000000 {
/* OPP100-3 */
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <1100000 1078000 1122000>;
diff --git a/arch/arm/boot/dts/ti/omap/am4372.dtsi b/arch/arm/boot/dts/ti/omap/am4372.dtsi
index 5fd1b380ece6..0a1df30f2818 100644
--- a/arch/arm/boot/dts/ti/omap/am4372.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am4372.dtsi
@@ -92,7 +92,7 @@
opp-supported-hw = <0xFF 0x08>;
};
- opp-800000000{
+ opp-800000000 {
/* OPP Turbo */
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1260000 1234800 1285200>;
diff --git a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
index eb1ec85aba28..e6a18954e449 100644
--- a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
+++ b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
@@ -196,7 +196,6 @@
extcon_usb1: extcon_usb1 {
compatible = "linux,extcon-usb-gpio";
- ti,enable-id-detection;
id-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/boot/dts/ti/omap/dra76x.dtsi b/arch/arm/boot/dts/ti/omap/dra76x.dtsi
index 1045eb24aa0d..50a02c393ea2 100644
--- a/arch/arm/boot/dts/ti/omap/dra76x.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra76x.dtsi
@@ -84,35 +84,44 @@
};
&scm_conf_clocks {
- dpll_gmac_h14x2_ctrl_ck: dpll_gmac_h14x2_ctrl_ck@3fc {
- #clock-cells = <0>;
- compatible = "ti,divider-clock";
- clocks = <&dpll_gmac_x2_ck>;
- ti,max-div = <63>;
- reg = <0x03fc>;
- ti,bit-shift = <20>;
- ti,latch-bit = <26>;
- assigned-clocks = <&dpll_gmac_h14x2_ctrl_ck>;
- assigned-clock-rates = <80000000>;
- };
-
- dpll_gmac_h14x2_ctrl_mux_ck: dpll_gmac_h14x2_ctrl_mux_ck@3fc {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clocks = <&dpll_gmac_ck>, <&dpll_gmac_h14x2_ctrl_ck>;
+ /* CTRL_CORE_SMA_SW_0 */
+ clock@3fc {
+ compatible = "ti,clksel";
reg = <0x3fc>;
- ti,bit-shift = <29>;
- ti,latch-bit = <26>;
- assigned-clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
- assigned-clock-parents = <&dpll_gmac_h14x2_ctrl_ck>;
- };
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_gmac_h14x2_ctrl_ck: clock@20 {
+ reg = <20>;
+ clock-output-names = "dpll_gmac_h14x2_ctrl_ck";
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_x2_ck>;
+ ti,max-div = <63>;
+ ti,latch-bit = <26>;
+ assigned-clocks = <&dpll_gmac_h14x2_ctrl_ck>;
+ assigned-clock-rates = <80000000>;
+ #clock-cells = <0>;
+ };
- mcan_clk: mcan_clk@3fc {
- #clock-cells = <0>;
- compatible = "ti,gate-clock";
- clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
- ti,bit-shift = <27>;
- reg = <0x3fc>;
+ mcan_clk: clock@27 {
+ reg = <27>;
+ clock-output-names = "mcan_clk";
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
+ #clock-cells = <0>;
+ };
+
+ dpll_gmac_h14x2_ctrl_mux_ck: clock@29 {
+ reg = <29>;
+ clock-output-names = "dpll_gmac_h14x2_ctrl_mux_ck";
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_gmac_ck>, <&dpll_gmac_h14x2_ctrl_ck>;
+ ti,latch-bit = <26>;
+ assigned-clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
+ assigned-clock-parents = <&dpll_gmac_h14x2_ctrl_ck>;
+ #clock-cells = <0>;
+ };
};
};
diff --git a/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
index 06466d36caa9..04f08b8c64d2 100644
--- a/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
@@ -285,13 +285,21 @@
ti,invert-autoidle-bit;
};
- dpll_core_byp_mux: clock-dpll-core-byp-mux-23@12c {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_core_byp_mux";
- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
- ti,bit-shift = <23>;
- reg = <0x012c>;
+ /* CM_CLKSEL_DPLL_CORE */
+ clock@12c {
+ compatible = "ti,clksel";
+ reg = <0x12c>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_core_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_core_byp_mux";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ #clock-cells = <0>;
+ };
};
dpll_core_ck: clock@120 {
@@ -368,13 +376,21 @@
clock-div = <1>;
};
- dpll_dsp_byp_mux: clock-dpll-dsp-byp-mux-23@240 {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_dsp_byp_mux";
- clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
- ti,bit-shift = <23>;
- reg = <0x0240>;
+ /* CM_CLKSEL_DPLL_DSP */
+ clock@240 {
+ compatible = "ti,clksel";
+ reg = <0x240>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_dsp_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_dsp_byp_mux";
+ clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
+ #clock-cells = <0>;
+ };
};
dpll_dsp_ck: clock@234 {
@@ -410,13 +426,21 @@
clock-div = <1>;
};
- dpll_iva_byp_mux: clock-dpll-iva-byp-mux-23@1ac {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_iva_byp_mux";
- clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
- ti,bit-shift = <23>;
- reg = <0x01ac>;
+ /* CM_CLKSEL_DPLL_IVA */
+ clock@1ac {
+ compatible = "ti,clksel";
+ reg = <0x1ac>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_iva_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_iva_byp_mux";
+ clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
+ #clock-cells = <0>;
+ };
};
dpll_iva_ck: clock@1a0 {
@@ -452,13 +476,21 @@
clock-div = <1>;
};
- dpll_gpu_byp_mux: clock-dpll-gpu-byp-mux-23@2e4 {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_gpu_byp_mux";
- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
- ti,bit-shift = <23>;
- reg = <0x02e4>;
+ /* CM_CLKSEL_DPLL_GPU */
+ clock@2e4 {
+ compatible = "ti,clksel";
+ reg = <0x2e4>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_gpu_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_gpu_byp_mux";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ #clock-cells = <0>;
+ };
};
dpll_gpu_ck: clock@2d8 {
@@ -506,13 +538,21 @@
clock-div = <1>;
};
- dpll_ddr_byp_mux: clock-dpll-ddr-byp-mux-23@21c {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_ddr_byp_mux";
- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
- ti,bit-shift = <23>;
- reg = <0x021c>;
+ /* CM_CLKSEL_DPLL_DDR */
+ clock@21c {
+ compatible = "ti,clksel";
+ reg = <0x21c>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_ddr_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_ddr_byp_mux";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ #clock-cells = <0>;
+ };
};
dpll_ddr_ck: clock@210 {
@@ -535,13 +575,21 @@
ti,invert-autoidle-bit;
};
- dpll_gmac_byp_mux: clock-dpll-gmac-byp-mux-23@2b4 {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_gmac_byp_mux";
- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
- ti,bit-shift = <23>;
- reg = <0x02b4>;
+ /* CM_CLKSEL_DPLL_GMAC */
+ clock@2b4 {
+ compatible = "ti,clksel";
+ reg = <0x2b4>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_gmac_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_gmac_byp_mux";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ #clock-cells = <0>;
+ };
};
dpll_gmac_ck: clock@2a8 {
@@ -618,13 +666,21 @@
clock-div = <1>;
};
- dpll_eve_byp_mux: clock-dpll-eve-byp-mux-23@290 {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_eve_byp_mux";
- clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
- ti,bit-shift = <23>;
- reg = <0x0290>;
+ /* CM_CLKSEL_DPLL_EVE */
+ clock@290 {
+ compatible = "ti,clksel";
+ reg = <0x290>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_eve_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_eve_byp_mux";
+ clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
+ #clock-cells = <0>;
+ };
};
dpll_eve_ck: clock@284 {
@@ -838,15 +894,23 @@
clock-div = <1>;
};
- l3_iclk_div: clock-l3-iclk-div-4@100 {
- #clock-cells = <0>;
- compatible = "ti,divider-clock";
- clock-output-names = "l3_iclk_div";
- ti,max-div = <2>;
- ti,bit-shift = <4>;
- reg = <0x0100>;
- clocks = <&dpll_core_h12x2_ck>;
- ti,index-power-of-two;
+ /* CM_CLKSEL_CORE */
+ clock@100 {
+ compatible = "ti,clksel";
+ reg = <0x100>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ l3_iclk_div: clock@4 {
+ reg = <4>;
+ compatible = "ti,divider-clock";
+ clock-output-names = "l3_iclk_div";
+ ti,max-div = <2>;
+ clocks = <&dpll_core_h12x2_ck>;
+ ti,index-power-of-two;
+ #clock-cells = <0>;
+ };
};
l4_root_clk_div: clock-l4-root-clk-div {
@@ -911,12 +975,21 @@
ti,index-starts-at-one;
};
- abe_dpll_sys_clk_mux: clock-abe-dpll-sys-clk-mux@118 {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "abe_dpll_sys_clk_mux";
- clocks = <&sys_clkin1>, <&sys_clkin2>;
- reg = <0x0118>;
+ /* CM_CLKSEL_ABE_PLL_SYS */
+ clock@118 {
+ compatible = "ti,clksel";
+ reg = <0x118>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ abe_dpll_sys_clk_mux: clock@0 {
+ reg = <0>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "abe_dpll_sys_clk_mux";
+ clocks = <&sys_clkin1>, <&sys_clkin2>;
+ #clock-cells = <0>;
+ };
};
abe_dpll_bypass_clk_mux: clock-abe-dpll-bypass-clk-mux@114 {
@@ -1018,14 +1091,23 @@
ti,index-power-of-two;
};
- dsp_gclk_div: clock-dsp-gclk-div@18c {
- #clock-cells = <0>;
- compatible = "ti,divider-clock";
- clock-output-names = "dsp_gclk_div";
- clocks = <&dpll_dsp_m2_ck>;
- ti,max-div = <64>;
- reg = <0x018c>;
- ti,index-power-of-two;
+ /* CM_CLKSEL_DPLL_USB */
+ clock@18c {
+ compatible = "ti,clksel";
+ reg = <0x18c>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dsp_gclk_div: clock@0 {
+ reg = <0>;
+ compatible = "ti,divider-clock";
+ clock-output-names = "dsp_gclk_div";
+ clocks = <&dpll_dsp_m2_ck>;
+ ti,max-div = <64>;
+ ti,index-power-of-two;
+ #clock-cells = <0>;
+ };
};
gpu_dclk: clock-gpu-dclk@1a0 {
@@ -1326,13 +1408,21 @@
clock-div = <1>;
};
- dpll_per_byp_mux: clock-dpll-per-byp-mux-23@14c {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_per_byp_mux";
- clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
- ti,bit-shift = <23>;
- reg = <0x014c>;
+ /* CM_CLKSEL_DPLL_PER */
+ clock@14c {
+ compatible = "ti,clksel";
+ reg = <0x14c>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_per_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_per_byp_mux";
+ clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
+ #clock-cells = <0>;
+ };
};
dpll_per_ck: clock@140 {
@@ -1364,13 +1454,21 @@
clock-div = <1>;
};
- dpll_usb_byp_mux: clock-dpll-usb-byp-mux-23@18c {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clock-output-names = "dpll_usb_byp_mux";
- clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
- ti,bit-shift = <23>;
- reg = <0x018c>;
+ /* CM_CLKSEL_DPLL_USB */
+ clock@18c {
+ compatible = "ti,clksel";
+ reg = <0x18c>;
+ #clock-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dpll_usb_byp_mux: clock@23 {
+ reg = <23>;
+ compatible = "ti,mux-clock";
+ clock-output-names = "dpll_usb_byp_mux";
+ clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
+ #clock-cells = <0>;
+ };
};
dpll_usb_ck: clock@180 {
diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts
index d33485341251..07c5b963af78 100644
--- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts
+++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts
@@ -754,7 +754,7 @@
ti,current-limit = <100>;
ti,weak-battery-voltage = <3400>;
ti,battery-regulation-voltage = <4200>;
- ti,charge-current = <650>;
+ ti,charge-current = <950>;
ti,termination-current = <100>;
ti,resistor-sense = <68>;
diff --git a/arch/arm/boot/dts/vt8500/vt8500-bv07.dts b/arch/arm/boot/dts/vt8500/vt8500-bv07.dts
index e9f55bd30bd4..38a2da5e2c5d 100644
--- a/arch/arm/boot/dts/vt8500/vt8500-bv07.dts
+++ b/arch/arm/boot/dts/vt8500/vt8500-bv07.dts
@@ -16,7 +16,7 @@
bits-per-pixel = <16>;
display-timings {
native-mode = <&timing0>;
- timing0: 800x480 {
+ timing0: timing-800x480 {
clock-frequency = <0>; /* unused but required */
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/vt8500/vt8500.dtsi b/arch/arm/boot/dts/vt8500/vt8500.dtsi
index b7e09eff5bb2..f23cb5ee11ae 100644
--- a/arch/arm/boot/dts/vt8500/vt8500.dtsi
+++ b/arch/arm/boot/dts/vt8500/vt8500.dtsi
@@ -115,7 +115,7 @@
interrupts = <43>;
};
- uhci@d8007b00 {
+ usb@d8007b00 {
compatible = "platform-uhci";
reg = <0xd8007b00 0x200>;
interrupts = <43>;
diff --git a/arch/arm/boot/dts/vt8500/wm8505-ref.dts b/arch/arm/boot/dts/vt8500/wm8505-ref.dts
index 2d77c087676e..8ce9e2ef0a81 100644
--- a/arch/arm/boot/dts/vt8500/wm8505-ref.dts
+++ b/arch/arm/boot/dts/vt8500/wm8505-ref.dts
@@ -16,7 +16,7 @@
bits-per-pixel = <32>;
display-timings {
native-mode = <&timing0>;
- timing0: 800x480 {
+ timing0: timing-800x480 {
clock-frequency = <0>; /* unused but required */
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/vt8500/wm8505.dtsi b/arch/arm/boot/dts/vt8500/wm8505.dtsi
index 168cd12b07bc..d9e1280372c5 100644
--- a/arch/arm/boot/dts/vt8500/wm8505.dtsi
+++ b/arch/arm/boot/dts/vt8500/wm8505.dtsi
@@ -213,7 +213,7 @@
interrupts = <1>;
};
- uhci@d8007300 {
+ usb@d8007300 {
compatible = "platform-uhci";
reg = <0xd8007300 0x200>;
interrupts = <0>;
diff --git a/arch/arm/boot/dts/vt8500/wm8650-mid.dts b/arch/arm/boot/dts/vt8500/wm8650-mid.dts
index f6a42149a0a0..7977b6c1e8eb 100644
--- a/arch/arm/boot/dts/vt8500/wm8650-mid.dts
+++ b/arch/arm/boot/dts/vt8500/wm8650-mid.dts
@@ -17,7 +17,7 @@
display-timings {
native-mode = <&timing0>;
- timing0: 800x480 {
+ timing0: timing-800x480 {
clock-frequency = <0>; /* unused but required */
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/vt8500/wm8650.dtsi b/arch/arm/boot/dts/vt8500/wm8650.dtsi
index bc057b6f7d16..35d12d77efc0 100644
--- a/arch/arm/boot/dts/vt8500/wm8650.dtsi
+++ b/arch/arm/boot/dts/vt8500/wm8650.dtsi
@@ -185,7 +185,7 @@
interrupts = <43>;
};
- uhci@d8007b00 {
+ usb@d8007b00 {
compatible = "platform-uhci";
reg = <0xd8007b00 0x200>;
interrupts = <43>;
diff --git a/arch/arm/boot/dts/vt8500/wm8750.dtsi b/arch/arm/boot/dts/vt8500/wm8750.dtsi
index 33aeb37491f4..b292f85d4e69 100644
--- a/arch/arm/boot/dts/vt8500/wm8750.dtsi
+++ b/arch/arm/boot/dts/vt8500/wm8750.dtsi
@@ -257,13 +257,13 @@
interrupts = <26>;
};
- uhci@d8007b00 {
+ usb@d8007b00 {
compatible = "platform-uhci";
reg = <0xd8007b00 0x200>;
interrupts = <26>;
};
- uhci@d8008d00 {
+ usb@d8008d00 {
compatible = "platform-uhci";
reg = <0xd8008d00 0x200>;
interrupts = <26>;
diff --git a/arch/arm/boot/dts/vt8500/wm8850-w70v2.dts b/arch/arm/boot/dts/vt8500/wm8850-w70v2.dts
index c7a6fe0ce48f..5d409323b10c 100644
--- a/arch/arm/boot/dts/vt8500/wm8850-w70v2.dts
+++ b/arch/arm/boot/dts/vt8500/wm8850-w70v2.dts
@@ -28,7 +28,7 @@
bits-per-pixel = <16>;
display-timings {
native-mode = <&timing0>;
- timing0: 800x480 {
+ timing0: timing-800x480 {
clock-frequency = <0>; /* unused but required */
hactive = <800>;
vactive = <480>;
diff --git a/arch/arm/boot/dts/vt8500/wm8850.dtsi b/arch/arm/boot/dts/vt8500/wm8850.dtsi
index 65c9271050e6..c61717ebb4f1 100644
--- a/arch/arm/boot/dts/vt8500/wm8850.dtsi
+++ b/arch/arm/boot/dts/vt8500/wm8850.dtsi
@@ -244,13 +244,13 @@
interrupts = <26>;
};
- uhci@d8007b00 {
+ usb@d8007b00 {
compatible = "platform-uhci";
reg = <0xd8007b00 0x200>;
interrupts = <26>;
};
- uhci@d8008d00 {
+ usb@d8008d00 {
compatible = "platform-uhci";
reg = <0xd8008d00 0x200>;
interrupts = <26>;
diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
index 9ec11fac7d8d..34e2c6e31fd1 100755
--- a/arch/arm/boot/install.sh
+++ b/arch/arm/boot/install.sh
@@ -17,6 +17,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ "$(basename $2)" = "zImage" ]; then
# Compressed install
echo "Installing compressed kernel"
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 6d0c9f7268ba..06b0e5fd54a6 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -816,10 +816,10 @@ EXPORT_SYMBOL(locomo_frontlight_set);
* We model this as a regular bus type, and hang devices directly
* off this.
*/
-static int locomo_match(struct device *_dev, struct device_driver *_drv)
+static int locomo_match(struct device *_dev, const struct device_driver *_drv)
{
struct locomo_dev *dev = LOCOMO_DEV(_dev);
- struct locomo_driver *drv = LOCOMO_DRV(_drv);
+ const struct locomo_driver *drv = LOCOMO_DRV(_drv);
return dev->devid == drv->devid;
}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1fbd7363cf11..550978dc3c50 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1339,10 +1339,10 @@ EXPORT_SYMBOL_GPL(sa1111_get_irq);
* We model this as a regular bus type, and hang devices directly
* off this.
*/
-static int sa1111_match(struct device *_dev, struct device_driver *_drv)
+static int sa1111_match(struct device *_dev, const struct device_driver *_drv)
{
struct sa1111_dev *dev = to_sa1111_device(_dev);
- struct sa1111_driver *drv = SA1111_DRV(_drv);
+ const struct sa1111_driver *drv = SA1111_DRV(_drv);
return !!(dev->devid & drv->devid);
}
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 1d53aec4c836..6eabe2313c9a 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -143,6 +143,7 @@ CONFIG_VIDEO_OV2640=m
CONFIG_VIDEO_OV7740=m
CONFIG_DRM=y
CONFIG_DRM_ATMEL_HLCDC=y
+CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_FB_ATMEL=y
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 01b5a5a73f03..42cb1c854118 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -3,7 +3,7 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_EPOLL is not set
CONFIG_ARCH_MULTI_V4=y
# CONFIG_ARCH_MULTI_V7 is not set
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 7327fce87808..333ef55476a3 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -133,6 +133,7 @@ CONFIG_SMSC911X=y
# CONFIG_NET_VENDOR_STMICRO is not set
CONFIG_MICREL_PHY=y
CONFIG_AT803X_PHY=y
+CONFIG_DP83867_PHY=y
CONFIG_CAN_FLEXCAN=y
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
@@ -180,6 +181,7 @@ CONFIG_TOUCHSCREEN_SX8654=y
CONFIG_TOUCHSCREEN_COLIBRI_VF50=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_MMA8450=y
+CONFIG_INPUT_GPIO_BEEPER=m
CONFIG_SERIO_SERPORT=m
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_IMX=y
@@ -211,6 +213,7 @@ CONFIG_GPIO_SIOX=m
CONFIG_GPIO_VF610=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PCF857X=y
CONFIG_GPIO_BD71815=y
CONFIG_GPIO_STMPE=y
@@ -226,6 +229,7 @@ CONFIG_RN5T618_POWER=m
CONFIG_SENSORS_MC13783_ADC=y
CONFIG_SENSORS_GPIO_FAN=y
CONFIG_SENSORS_IIO_HWMON=y
+CONFIG_SENSORS_LM75=m
CONFIG_SENSORS_PWM_FAN=y
CONFIG_SENSORS_SY7636A=y
CONFIG_THERMAL_STATISTICS=y
@@ -282,6 +286,9 @@ CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
+CONFIG_DRM_DISPLAY_CONNECTOR=y
+CONFIG_DRM_LVDS_CODEC=m
+CONFIG_DRM_SII902X=y
CONFIG_DRM_TI_TFP410=y
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
CONFIG_DRM_DW_HDMI_CEC=y
@@ -311,7 +318,6 @@ CONFIG_SND_IMX_SOC=y
CONFIG_SND_SOC_EUKREA_TLV320=y
CONFIG_SND_SOC_IMX_ES8328=y
CONFIG_SND_SOC_IMX_SGTL5000=y
-CONFIG_SND_SOC_IMX_SPDIF=y
CONFIG_SND_SOC_FSL_ASOC_CARD=y
CONFIG_SND_SOC_AC97_CODEC=y
CONFIG_SND_SOC_CS42XX8_I2C=y
@@ -336,6 +342,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_TEST=m
CONFIG_USB_EHSET_TEST_FIXTURE=m
+CONFIG_USB_ONBOARD_DEV=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MXS_PHY=y
CONFIG_USB_GADGET=y
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 59c4835ffc97..c1291ca290b2 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -12,7 +12,7 @@ CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EXPERT=y
CONFIG_PROFILING=y
diff --git a/arch/arm/configs/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig
index d169da9b2824..f55c231e0870 100644
--- a/arch/arm/configs/lpc18xx_defconfig
+++ b/arch/arm/configs/lpc18xx_defconfig
@@ -8,7 +8,7 @@ CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_LZ4 is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_UID16 is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
diff --git a/arch/arm/configs/moxart_defconfig b/arch/arm/configs/moxart_defconfig
index 1d41e73f4903..34d079e03b3c 100644
--- a/arch/arm/configs/moxart_defconfig
+++ b/arch/arm/configs/moxart_defconfig
@@ -6,7 +6,7 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_SIGNALFD is not set
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
diff --git a/arch/arm/configs/mps2_defconfig b/arch/arm/configs/mps2_defconfig
index 3ed73f184d83..e995e50537ef 100644
--- a/arch/arm/configs/mps2_defconfig
+++ b/arch/arm/configs/mps2_defconfig
@@ -5,7 +5,7 @@ CONFIG_LOG_BUF_SHIFT=16
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EXPERT=y
# CONFIG_UID16 is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index b2955dcb5a53..62734530a3d6 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -469,6 +469,7 @@ CONFIG_SPI_XILINX=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPMI=y
CONFIG_PINCTRL_AS3722=y
+CONFIG_PINCTRL_MCP23S08=m
CONFIG_PINCTRL_MICROCHIP_SGPIO=y
CONFIG_PINCTRL_OCELOT=y
CONFIG_PINCTRL_PALMAS=y
@@ -885,7 +886,7 @@ CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_ISP1760=y
CONFIG_USB_HSIC_USB3503=y
-CONFIG_USB_ONBOARD_HUB=m
+CONFIG_USB_ONBOARD_DEV=m
CONFIG_AB8500_USB=y
CONFIG_KEYSTONE_USB_PHY=m
CONFIG_NOP_USB_XCEIV=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 729ea8157e2a..025b595dd837 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -9,7 +9,7 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_SHMEM is not set
# CONFIG_KALLSYMS is not set
CONFIG_PROFILING=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 091e1840933c..56925adfe842 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -139,8 +139,8 @@ CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_RCAR_DU=y
# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set
CONFIG_DRM_SHMOBILE=y
-CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
+CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_LVDS_CODEC=y
CONFIG_DRM_SII902X=y
@@ -235,3 +235,4 @@ CONFIG_CMA_SIZE_MBYTES=64
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_FS=y
+CONFIG_ARM_DEBUG_WX=y
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index b9fe3fbed5ae..3baec075d1ef 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -6,7 +6,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EXPERT=y
# CONFIG_UID16 is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index bddc82f78942..a83d29fed175 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -110,6 +110,7 @@ CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_SIMPLE_BRIDGE=y
+CONFIG_DRM_DW_HDMI=y
CONFIG_DRM_LIMA=y
CONFIG_FB_SIMPLE=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
index 96ad442089bd..cdb6065e04fd 100644
--- a/arch/arm/configs/vexpress_defconfig
+++ b/arch/arm/configs/vexpress_defconfig
@@ -14,7 +14,6 @@ CONFIG_CPUSETS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_PROFILING=y
CONFIG_ARCH_VEXPRESS=y
-CONFIG_ARCH_VEXPRESS_DCSCB=y
CONFIG_ARCH_VEXPRESS_TC2_PM=y
CONFIG_SMP=y
CONFIG_HAVE_ARM_ARCH_TIMER=y
diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
index f00f042ef357..201eb35dde37 100644
--- a/arch/arm/crypto/aes-neonbs-glue.c
+++ b/arch/arm/crypto/aes-neonbs-glue.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("Bit sliced AES using NEON instructions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("ecb(aes)");
diff --git a/arch/arm/crypto/crc32-ce-core.S b/arch/arm/crypto/crc32-ce-core.S
index 3f13a76b9066..88f9edf94e95 100644
--- a/arch/arm/crypto/crc32-ce-core.S
+++ b/arch/arm/crypto/crc32-ce-core.S
@@ -48,6 +48,7 @@
*/
#include <linux/linkage.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
.text
@@ -123,11 +124,12 @@
* uint crc32_pmull_le(unsigned char const *buffer,
* size_t len, uint crc32)
*/
-ENTRY(crc32_pmull_le)
+SYM_FUNC_START(crc32_pmull_le)
adr r3, .Lcrc32_constants
b 0f
+SYM_FUNC_END(crc32_pmull_le)
-ENTRY(crc32c_pmull_le)
+SYM_FUNC_START(crc32c_pmull_le)
adr r3, .Lcrc32c_constants
0: bic LEN, LEN, #15
@@ -236,8 +238,7 @@ fold_64:
vmov r0, s5
bx lr
-ENDPROC(crc32_pmull_le)
-ENDPROC(crc32c_pmull_le)
+SYM_FUNC_END(crc32c_pmull_le)
.macro __crc32, c
subs ip, r2, #8
@@ -296,11 +297,11 @@ ARM_BE8(rev16 r3, r3 )
.endm
.align 5
-ENTRY(crc32_armv8_le)
+SYM_TYPED_FUNC_START(crc32_armv8_le)
__crc32
-ENDPROC(crc32_armv8_le)
+SYM_FUNC_END(crc32_armv8_le)
.align 5
-ENTRY(crc32c_armv8_le)
+SYM_TYPED_FUNC_START(crc32c_armv8_le)
__crc32 c
-ENDPROC(crc32c_armv8_le)
+SYM_FUNC_END(crc32c_armv8_le)
diff --git a/arch/arm/crypto/crc32-ce-glue.c b/arch/arm/crypto/crc32-ce-glue.c
index 2208445808d7..4ff18044af07 100644
--- a/arch/arm/crypto/crc32-ce-glue.c
+++ b/arch/arm/crypto/crc32-ce-glue.c
@@ -241,6 +241,7 @@ module_init(crc32_pmull_mod_init);
module_exit(crc32_pmull_mod_exit);
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("crc32");
MODULE_ALIAS_CRYPTO("crc32c");
diff --git a/arch/arm/crypto/crct10dif-ce-glue.c b/arch/arm/crypto/crct10dif-ce-glue.c
index e9191a8c87b9..79f3b204d8c0 100644
--- a/arch/arm/crypto/crct10dif-ce-glue.c
+++ b/arch/arm/crypto/crct10dif-ce-glue.c
@@ -84,5 +84,6 @@ module_init(crc_t10dif_mod_init);
module_exit(crc_t10dif_mod_exit);
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("crct10dif");
diff --git a/arch/arm/crypto/curve25519-glue.c b/arch/arm/crypto/curve25519-glue.c
index 9bdafd57888c..e7b87e09dd99 100644
--- a/arch/arm/crypto/curve25519-glue.c
+++ b/arch/arm/crypto/curve25519-glue.c
@@ -133,4 +133,5 @@ module_exit(arm_curve25519_exit);
MODULE_ALIAS_CRYPTO("curve25519");
MODULE_ALIAS_CRYPTO("curve25519-neon");
+MODULE_DESCRIPTION("Public key crypto: Curve25519 (NEON-accelerated)");
MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/crypto/poly1305-glue.c b/arch/arm/crypto/poly1305-glue.c
index c31bd8f7c092..8482e302c45a 100644
--- a/arch/arm/crypto/poly1305-glue.c
+++ b/arch/arm/crypto/poly1305-glue.c
@@ -267,6 +267,7 @@ static void __exit arm_poly1305_mod_exit(void)
module_init(arm_poly1305_mod_init);
module_exit(arm_poly1305_mod_exit);
+MODULE_DESCRIPTION("Accelerated Poly1305 transform for ARM");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("poly1305");
MODULE_ALIAS_CRYPTO("poly1305-arm");
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index aebe2c8f6a68..d33c1e24e00b 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -21,6 +21,7 @@
#include <asm/opcodes-virt.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
+#include <asm/pgtable.h>
#include <asm/thread_info.h>
#include <asm/uaccess-asm.h>
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 1075534b0a2e..8ed8b9a24efe 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -283,7 +283,7 @@ void flush_cache_pages(struct vm_area_struct *vma, unsigned long user_addr,
* flush_dcache_page is used when the kernel has written to the page
* cache page at virtual address page->virtual.
*
- * If this page isn't mapped (ie, page_mapping == NULL), or it might
+ * If this page isn't mapped (ie, folio_mapping == NULL), or it might
* have userspace mappings, then we _must_ always clean + invalidate
* the dcache entries associated with the kernel mapping.
*
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index 44667bdb4707..9beb64d30586 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -5,6 +5,7 @@
#include <linux/irqflags.h>
#include <linux/prefetch.h>
#include <asm/barrier.h>
+#include <linux/cmpxchg-emu.h>
#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
/*
@@ -162,7 +163,11 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
prefetchw((const void *)ptr);
switch (size) {
-#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
+#ifdef CONFIG_CPU_V6 /* ARCH == ARMv6 */
+ case 1:
+ oldval = cmpxchg_emu_u8((volatile u8 *)ptr, old, new);
+ break;
+#else /* min ARCH > ARMv6 */
case 1:
do {
asm volatile("@ __cmpxchg1\n"
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 78282ced5038..e408399d5f0e 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -14,6 +14,7 @@
#include <asm/mach/map.h>
#include <asm/mmu_context.h>
#include <asm/ptrace.h>
+#include <asm/uaccess.h>
#ifdef CONFIG_EFI
void efi_init(void);
@@ -25,6 +26,18 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, boo
#define arch_efi_call_virt_setup() efi_virtmap_load()
#define arch_efi_call_virt_teardown() efi_virtmap_unload()
+#ifdef CONFIG_CPU_TTBR0_PAN
+#undef arch_efi_call_virt
+#define arch_efi_call_virt(p, f, args...) ({ \
+ unsigned int flags = uaccess_save_and_enable(); \
+ efi_status_t res = _Generic((p)->f(args), \
+ efi_status_t: (p)->f(args), \
+ default: ((p)->f(args), EFI_ABORTED)); \
+ uaccess_restore(flags); \
+ res; \
+})
+#endif
+
#define ARCH_EFI_IRQ_FLAGS_MASK \
(PSR_J_BIT | PSR_E_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | \
PSR_T_BIT | MODE_MASK)
diff --git a/arch/arm/include/asm/fb.h b/arch/arm/include/asm/fb.h
deleted file mode 100644
index ce20a43c3033..000000000000
--- a/arch/arm/include/asm/fb.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/arm/include/asm/fpu.h b/arch/arm/include/asm/fpu.h
new file mode 100644
index 000000000000..2ae50bdce59b
--- /dev/null
+++ b/arch/arm/include/asm/fpu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 SiFive
+ */
+
+#ifndef __ASM_FPU_H
+#define __ASM_FPU_H
+
+#include <asm/neon.h>
+
+#define kernel_fpu_available() cpu_has_neon()
+#define kernel_fpu_begin() kernel_neon_begin()
+#define kernel_fpu_end() kernel_neon_end()
+
+#endif /* ! __ASM_FPU_H */
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index 724f8dac1e5b..4186fbf7341f 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -118,6 +118,10 @@
# define MULTI_CACHE 1
#endif
+#ifdef CONFIG_CPU_CACHE_NOP
+# define MULTI_CACHE 1
+#endif
+
#if defined(CONFIG_CPU_V7M)
# define MULTI_CACHE 1
#endif
@@ -126,29 +130,15 @@
#error Unknown cache maintenance model
#endif
-#ifndef __ASSEMBLER__
-static inline void nop_flush_icache_all(void) { }
-static inline void nop_flush_kern_cache_all(void) { }
-static inline void nop_flush_kern_cache_louis(void) { }
-static inline void nop_flush_user_cache_all(void) { }
-static inline void nop_flush_user_cache_range(unsigned long a,
- unsigned long b, unsigned int c) { }
-
-static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
-static inline int nop_coherent_user_range(unsigned long a,
- unsigned long b) { return 0; }
-static inline void nop_flush_kern_dcache_area(void *a, size_t s) { }
-
-static inline void nop_dma_flush_range(const void *a, const void *b) { }
-
-static inline void nop_dma_map_area(const void *s, size_t l, int f) { }
-static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
-#endif
-
#ifndef MULTI_CACHE
#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+/* This function only has a dedicated assembly callback on the v7 cache */
+#ifdef CONFIG_CPU_CACHE_V7
#define __cpuc_flush_kern_louis __glue(_CACHE,_flush_kern_cache_louis)
+#else
+#define __cpuc_flush_kern_louis __glue(_CACHE,_flush_kern_cache_all)
+#endif
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
index 9fd9ad5d9202..3190e1e5067a 100644
--- a/arch/arm/include/asm/hardware/locomo.h
+++ b/arch/arm/include/asm/hardware/locomo.h
@@ -189,7 +189,7 @@ struct locomo_driver {
void (*remove)(struct locomo_dev *);
};
-#define LOCOMO_DRV(_d) container_of((_d), struct locomo_driver, drv)
+#define LOCOMO_DRV(_d) container_of_const((_d), struct locomo_driver, drv)
#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name)
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index d8c6f8a99dfa..a815f39b4243 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -404,7 +404,7 @@ struct sa1111_driver {
void (*remove)(struct sa1111_dev *);
};
-#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
+#define SA1111_DRV(_d) container_of_const((_d), struct sa1111_driver, drv)
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
index a30be5505793..87d48e2d90ad 100644
--- a/arch/arm/include/asm/hugetlb-3level.h
+++ b/arch/arm/include/asm/hugetlb-3level.h
@@ -13,12 +13,12 @@
/*
* If our huge pte is non-zero then mark the valid bit.
- * This allows pte_present(huge_ptep_get(ptep)) to return true for non-zero
+ * This allows pte_present(huge_ptep_get(mm,addr,ptep)) to return true for non-zero
* ptes.
* (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes).
*/
#define __HAVE_ARCH_HUGE_PTEP_GET
-static inline pte_t huge_ptep_get(pte_t *ptep)
+static inline pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t retval = *ptep;
if (pte_val(retval))
diff --git a/arch/arm/include/asm/hugetlb.h b/arch/arm/include/asm/hugetlb.h
index a3a82b7158d4..b766c4b373f6 100644
--- a/arch/arm/include/asm/hugetlb.h
+++ b/arch/arm/include/asm/hugetlb.h
@@ -15,10 +15,10 @@
#include <asm/hugetlb-3level.h>
#include <asm-generic/hugetlb.h>
-static inline void arch_clear_hugepage_flags(struct page *page)
+static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
- clear_bit(PG_dcache_clean, &page->flags);
+ clear_bit(PG_dcache_clean, &folio->flags);
}
-#define arch_clear_hugepage_flags arch_clear_hugepage_flags
+#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
#endif /* _ASM_ARM_HUGETLB_H */
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index 62358d3ca0a8..e7f9961c53b2 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -84,6 +84,7 @@ static inline void decode_ctrl_reg(u32 reg,
#define ARM_DSCR_MOE(x) ((x >> 2) & 0xf)
#define ARM_ENTRY_BREAKPOINT 0x1
#define ARM_ENTRY_ASYNC_WATCHPOINT 0x2
+#define ARM_ENTRY_CFI_BREAKPOINT 0x3
#define ARM_ENTRY_SYNC_WATCHPOINT 0xa
/* DSCR monitor/halting bits. */
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index b0a262566eb9..6b5392e20f41 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -213,8 +213,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
#define pmd_pfn(pmd) (__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
-#define pmd_leaf(pmd) (pmd_val(pmd) & 2)
-#define pmd_bad(pmd) (pmd_val(pmd) & 2)
+#define pmd_leaf(pmd) (pmd_val(pmd) & PMD_TYPE_SECT)
+#define pmd_bad(pmd) pmd_leaf(pmd)
#define pmd_present(pmd) (pmd_val(pmd))
#define copy_pmd(pmdpd,pmdps) \
@@ -241,7 +241,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
* define empty stubs for use by pin_page_for_write.
*/
#define pmd_hugewillfault(pmd) (0)
-#define pmd_thp_or_huge(pmd) (0)
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index 2f35b4eddaa8..dfab3e982cbf 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -14,6 +14,7 @@
* + Level 1/2 descriptor
* - common
*/
+#define PUD_TABLE_BIT (_AT(pmdval_t, 1) << 1)
#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0)
@@ -74,6 +75,7 @@
#define PHYS_MASK_SHIFT (40)
#define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1)
+#ifndef CONFIG_CPU_TTBR0_PAN
/*
* TTBR0/TTBR1 split (PAGE_OFFSET):
* 0x40000000: T0SZ = 2, T1SZ = 0 (not used)
@@ -93,5 +95,30 @@
#endif
#define TTBR1_SIZE (((PAGE_OFFSET >> 30) - 1) << 16)
+#else
+/*
+ * With CONFIG_CPU_TTBR0_PAN enabled, TTBR1 is only used during uaccess
+ * disabled regions when TTBR0 is disabled.
+ */
+#define TTBR1_OFFSET 0 /* pointing to swapper_pg_dir */
+#define TTBR1_SIZE 0 /* TTBR1 size controlled via TTBCR.T0SZ */
+#endif
+
+/*
+ * TTBCR register bits.
+ */
+#define TTBCR_EAE (1 << 31)
+#define TTBCR_IMP (1 << 30)
+#define TTBCR_SH1_MASK (3 << 28)
+#define TTBCR_ORGN1_MASK (3 << 26)
+#define TTBCR_IRGN1_MASK (3 << 24)
+#define TTBCR_EPD1 (1 << 23)
+#define TTBCR_A1 (1 << 22)
+#define TTBCR_T1SZ_MASK (7 << 16)
+#define TTBCR_SH0_MASK (3 << 12)
+#define TTBCR_ORGN0_MASK (3 << 10)
+#define TTBCR_IRGN0_MASK (3 << 8)
+#define TTBCR_EPD0 (1 << 7)
+#define TTBCR_T0SZ_MASK (7 << 0)
#endif
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 4b1d9eb3908a..fa5939eb9864 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -112,7 +112,7 @@
#ifndef __ASSEMBLY__
#define pud_none(pud) (!pud_val(pud))
-#define pud_bad(pud) (!(pud_val(pud) & 2))
+#define pud_bad(pud) (!(pud_val(pud) & PUD_TABLE_BIT))
#define pud_present(pud) (pud_val(pud))
#define pmd_table(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
PMD_TYPE_TABLE)
@@ -137,7 +137,7 @@ static inline pmd_t *pud_pgtable(pud_t pud)
return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
}
-#define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
+#define pmd_bad(pmd) (!(pmd_val(pmd) & PMD_TABLE_BIT))
#define copy_pmd(pmdpd,pmdps) \
do { \
@@ -190,7 +190,6 @@ static inline pte_t pte_mkspecial(pte_t pte)
#define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY))
#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd))
-#define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd))
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd))
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 280396483f5d..b4986a23d852 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -178,6 +178,18 @@ extern void cpu_resume(void);
})
#endif
+static inline unsigned int cpu_get_ttbcr(void)
+{
+ unsigned int ttbcr;
+ asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
+ return ttbcr;
+}
+
+static inline void cpu_set_ttbcr(unsigned int ttbcr)
+{
+ asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr) : "memory");
+}
+
#else /*!CONFIG_MMU */
#define cpu_switch_mm(pgd,mm) { }
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 14a38cc67e0b..6eb311fb2da0 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -20,6 +20,7 @@ struct pt_regs {
struct svc_pt_regs {
struct pt_regs regs;
u32 dacr;
+ u32 ttbcr;
};
#define to_svc_pt_regs(r) container_of(r, struct svc_pt_regs, regs)
diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h
index 853c4f81ba4a..ad36b6570067 100644
--- a/arch/arm/include/asm/topology.h
+++ b/arch/arm/include/asm/topology.h
@@ -22,9 +22,9 @@
/* Enable topology flag updates */
#define arch_update_cpu_topology topology_update_cpu_topology
-/* Replace task scheduler's default thermal pressure API */
-#define arch_scale_thermal_pressure topology_get_thermal_pressure
-#define arch_update_thermal_pressure topology_update_thermal_pressure
+/* Replace task scheduler's default HW pressure API */
+#define arch_scale_hw_pressure topology_get_hw_pressure
+#define arch_update_hw_pressure topology_update_hw_pressure
#else
diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h
index 65da32e1f1c1..4bccd895d954 100644
--- a/arch/arm/include/asm/uaccess-asm.h
+++ b/arch/arm/include/asm/uaccess-asm.h
@@ -39,8 +39,9 @@
#endif
.endm
+#if defined(CONFIG_CPU_SW_DOMAIN_PAN)
+
.macro uaccess_disable, tmp, isb=1
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
* Whenever we re-enter userspace, the domains should always be
* set appropriately.
@@ -50,11 +51,9 @@
.if \isb
instr_sync
.endif
-#endif
.endm
.macro uaccess_enable, tmp, isb=1
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
* Whenever we re-enter userspace, the domains should always be
* set appropriately.
@@ -64,15 +63,61 @@
.if \isb
instr_sync
.endif
-#endif
.endm
+#elif defined(CONFIG_CPU_TTBR0_PAN)
+
+ .macro uaccess_disable, tmp, isb=1
+ /*
+ * Disable TTBR0 page table walks (EDP0 = 1), use the reserved ASID
+ * from TTBR1 (A1 = 1) and enable TTBR1 page table walks for kernel
+ * addresses by reducing TTBR0 range to 32MB (T0SZ = 7).
+ */
+ mrc p15, 0, \tmp, c2, c0, 2 @ read TTBCR
+ orr \tmp, \tmp, #TTBCR_EPD0 | TTBCR_T0SZ_MASK
+ orr \tmp, \tmp, #TTBCR_A1
+ mcr p15, 0, \tmp, c2, c0, 2 @ write TTBCR
+ .if \isb
+ instr_sync
+ .endif
+ .endm
+
+ .macro uaccess_enable, tmp, isb=1
+ /*
+ * Enable TTBR0 page table walks (T0SZ = 0, EDP0 = 0) and ASID from
+ * TTBR0 (A1 = 0).
+ */
+ mrc p15, 0, \tmp, c2, c0, 2 @ read TTBCR
+ bic \tmp, \tmp, #TTBCR_EPD0 | TTBCR_T0SZ_MASK
+ bic \tmp, \tmp, #TTBCR_A1
+ mcr p15, 0, \tmp, c2, c0, 2 @ write TTBCR
+ .if \isb
+ instr_sync
+ .endif
+ .endm
+
+#else
+
+ .macro uaccess_disable, tmp, isb=1
+ .endm
+
+ .macro uaccess_enable, tmp, isb=1
+ .endm
+
+#endif
+
#if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS)
#define DACR(x...) x
#else
#define DACR(x...)
#endif
+#ifdef CONFIG_CPU_TTBR0_PAN
+#define PAN(x...) x
+#else
+#define PAN(x...)
+#endif
+
/*
* Save the address limit on entry to a privileged exception.
*
@@ -86,6 +131,8 @@
.macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable
DACR( mrc p15, 0, \tmp0, c3, c0, 0)
DACR( str \tmp0, [sp, #SVC_DACR])
+ PAN( mrc p15, 0, \tmp0, c2, c0, 2)
+ PAN( str \tmp0, [sp, #SVC_TTBCR])
.if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN)
/* kernel=client, user=no access */
mov \tmp2, #DACR_UACCESS_DISABLE
@@ -104,8 +151,11 @@
.macro uaccess_exit, tsk, tmp0, tmp1
DACR( ldr \tmp0, [sp, #SVC_DACR])
DACR( mcr p15, 0, \tmp0, c3, c0, 0)
+ PAN( ldr \tmp0, [sp, #SVC_TTBCR])
+ PAN( mcr p15, 0, \tmp0, c2, c0, 2)
.endm
#undef DACR
+#undef PAN
#endif /* __ASM_UACCESS_ASM_H__ */
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 9556d04387f7..6c9c16d767cf 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -14,6 +14,8 @@
#include <asm/domain.h>
#include <asm/unaligned.h>
#include <asm/unified.h>
+#include <asm/pgtable.h>
+#include <asm/proc-fns.h>
#include <asm/compiler.h>
#include <asm/extable.h>
@@ -24,9 +26,10 @@
* perform such accesses (eg, via list poison values) which could then
* be exploited for priviledge escalation.
*/
+#if defined(CONFIG_CPU_SW_DOMAIN_PAN)
+
static __always_inline unsigned int uaccess_save_and_enable(void)
{
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
unsigned int old_domain = get_domain();
/* Set the current domain access to permit user accesses */
@@ -34,19 +37,49 @@ static __always_inline unsigned int uaccess_save_and_enable(void)
domain_val(DOMAIN_USER, DOMAIN_CLIENT));
return old_domain;
-#else
- return 0;
-#endif
}
static __always_inline void uaccess_restore(unsigned int flags)
{
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/* Restore the user access mask */
set_domain(flags);
-#endif
}
+#elif defined(CONFIG_CPU_TTBR0_PAN)
+
+static __always_inline unsigned int uaccess_save_and_enable(void)
+{
+ unsigned int old_ttbcr = cpu_get_ttbcr();
+
+ /*
+ * Enable TTBR0 page table walks (T0SZ = 0, EDP0 = 0) and ASID from
+ * TTBR0 (A1 = 0).
+ */
+ cpu_set_ttbcr(old_ttbcr & ~(TTBCR_A1 | TTBCR_EPD0 | TTBCR_T0SZ_MASK));
+ isb();
+
+ return old_ttbcr;
+}
+
+static inline void uaccess_restore(unsigned int flags)
+{
+ cpu_set_ttbcr(flags);
+ isb();
+}
+
+#else
+
+static inline unsigned int uaccess_save_and_enable(void)
+{
+ return 0;
+}
+
+static inline void uaccess_restore(unsigned int flags)
+{
+}
+
+#endif
+
/*
* These two are intentionally not defined anywhere - if the kernel
* code generates any references to them, that's a bug.
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 3676e82cf95c..9fb00973c608 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -37,7 +37,6 @@
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
/*
* Unimplemented (or alternatively implemented) syscalls
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 89a77e3f51d2..aaae31b8c4a5 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -78,8 +78,6 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \
- perf_event_v7.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_VDSO) += vdso.o
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 4915662842ff..4853875740d0 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -85,6 +85,7 @@ int main(void)
DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs));
DEFINE(SVC_DACR, offsetof(struct svc_pt_regs, dacr));
+ DEFINE(SVC_TTBCR, offsetof(struct svc_pt_regs, ttbcr));
DEFINE(SVC_REGS_SIZE, sizeof(struct svc_pt_regs));
BLANK();
DEFINE(SIGFRAME_RC3_OFFSET, offsetof(struct sigframe, retcode[3]));
diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index 3e7bcaca5e07..bc598e3d8dd2 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -271,6 +271,10 @@ ENTRY(ftrace_stub)
ret lr
ENDPROC(ftrace_stub)
+ENTRY(ftrace_stub_graph)
+ ret lr
+ENDPROC(ftrace_stub_graph)
+
#ifdef CONFIG_DYNAMIC_FTRACE
__INIT
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index a0b6d1e3812f..e61591f33a6c 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -232,11 +232,24 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
unsigned long old;
if (unlikely(atomic_read(&current->tracing_graph_pause)))
+err_out:
return;
if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) {
- /* FP points one word below parent's top of stack */
- frame_pointer += 4;
+ /*
+ * Usually, the stack frames are contiguous in memory but cases
+ * have been observed where the next stack frame does not live
+ * at 'frame_pointer + 4' as this code used to assume.
+ *
+ * Instead, dereference the field in the stack frame that
+ * stores the SP of the calling frame: to avoid unbounded
+ * recursion, this cannot involve any ftrace instrumented
+ * functions, so use the __get_kernel_nofault() primitive
+ * directly.
+ */
+ __get_kernel_nofault(&frame_pointer,
+ (unsigned long *)(frame_pointer - 8),
+ unsigned long, err_out);
} else {
struct stackframe frame = {
.fp = frame_pointer,
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index dc0fb7a81371..a12efd0f43e8 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -17,6 +17,7 @@
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <linux/smp.h>
+#include <linux/cfi.h>
#include <linux/cpu_pm.h>
#include <linux/coresight.h>
@@ -626,7 +627,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
hw->address &= ~alignment_mask;
hw->ctrl.len <<= offset;
- if (uses_default_overflow_handler(bp)) {
+ if (is_default_overflow_handler(bp)) {
/*
* Mismatch breakpoints are required for single-stepping
* breakpoints.
@@ -798,7 +799,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
* Otherwise, insert a temporary mismatch breakpoint so that
* we can single-step over the watchpoint trigger.
*/
- if (!uses_default_overflow_handler(wp))
+ if (!is_default_overflow_handler(wp))
continue;
step:
enable_single_step(wp, instruction_pointer(regs));
@@ -811,7 +812,7 @@ step:
info->trigger = addr;
pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
perf_bp_event(wp, regs);
- if (uses_default_overflow_handler(wp))
+ if (is_default_overflow_handler(wp))
enable_single_step(wp, instruction_pointer(regs));
}
@@ -886,7 +887,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
info->trigger = addr;
pr_debug("breakpoint fired: address = 0x%x\n", addr);
perf_bp_event(bp, regs);
- if (uses_default_overflow_handler(bp))
+ if (is_default_overflow_handler(bp))
enable_single_step(bp, addr);
goto unlock;
}
@@ -903,6 +904,37 @@ unlock:
watchpoint_single_step_handler(addr);
}
+#ifdef CONFIG_CFI_CLANG
+static void hw_breakpoint_cfi_handler(struct pt_regs *regs)
+{
+ /*
+ * TODO: implementing target and type to pass to CFI using the more
+ * elaborate report_cfi_failure() requires compiler work. To be able
+ * to properly extract target information the compiler needs to
+ * emit a stable instructions sequence for the CFI checks so we can
+ * decode the instructions preceding the trap and figure out which
+ * registers were used.
+ */
+
+ switch (report_cfi_failure_noaddr(regs, instruction_pointer(regs))) {
+ case BUG_TRAP_TYPE_BUG:
+ die("Oops - CFI", regs, 0);
+ break;
+ case BUG_TRAP_TYPE_WARN:
+ /* Skip the breaking instruction */
+ instruction_pointer(regs) += 4;
+ break;
+ default:
+ die("Unknown CFI error", regs, 0);
+ break;
+ }
+}
+#else
+static void hw_breakpoint_cfi_handler(struct pt_regs *regs)
+{
+}
+#endif
+
/*
* Called from either the Data Abort Handler [watchpoint] or the
* Prefetch Abort Handler [breakpoint] with interrupts disabled.
@@ -932,6 +964,9 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
case ARM_ENTRY_SYNC_WATCHPOINT:
watchpoint_handler(addr, fsr, regs);
break;
+ case ARM_ENTRY_CFI_BREAKPOINT:
+ hw_breakpoint_cfi_handler(regs);
+ break;
default:
ret = 1; /* Unhandled fault. */
}
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index fe28fc1f759d..dab42d066d06 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -32,6 +32,7 @@
#include <linux/kallsyms.h>
#include <linux/proc_fs.h>
#include <linux/export.h>
+#include <linux/vmalloc.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/cache-uniphier.h>
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index e74d84f58b77..677f218f7e84 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -12,48 +12,14 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/elf.h>
-#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
-#include <linux/gfp.h>
#include <asm/sections.h>
#include <asm/smp_plat.h>
#include <asm/unwind.h>
#include <asm/opcodes.h>
-#ifdef CONFIG_XIP_KERNEL
-/*
- * The XIP kernel text is mapped in the module area for modules and
- * some other stuff to work without any indirect relocations.
- * MODULES_VADDR is redefined here and not in asm/memory.h to avoid
- * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
- */
-#undef MODULES_VADDR
-#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
-#endif
-
-#ifdef CONFIG_MMU
-void *module_alloc(unsigned long size)
-{
- gfp_t gfp_mask = GFP_KERNEL;
- void *p;
-
- /* Silence the initial allocation */
- if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS))
- gfp_mask |= __GFP_NOWARN;
-
- p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- gfp_mask, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
- if (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || p)
- return p;
- return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
- GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-#endif
-
bool module_init_section(const char *name)
{
return strstarts(name, ".init") ||
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
deleted file mode 100644
index d9fd53841591..000000000000
--- a/arch/arm/kernel/perf_event_v6.c
+++ /dev/null
@@ -1,448 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ARMv6 Performance counter handling code.
- *
- * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
- *
- * ARMv6 has 2 configurable performance counters and a single cycle counter.
- * They all share a single reset bit but can be written to zero so we can use
- * that for a reset.
- *
- * The counters can't be individually enabled or disabled so when we remove
- * one event and replace it with another we could get spurious counts from the
- * wrong event. However, we can take advantage of the fact that the
- * performance counters can export events to the event bus, and the event bus
- * itself can be monitored. This requires that we *don't* export the events to
- * the event bus. The procedure for disabling a configurable counter is:
- * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
- * effectively stops the counter from counting.
- * - disable the counter's interrupt generation (each counter has it's
- * own interrupt enable bit).
- * Once stopped, the counter value can be written as 0 to reset.
- *
- * To enable a counter:
- * - enable the counter's interrupt generation.
- * - set the new event type.
- *
- * Note: the dedicated cycle counter only counts cycles and can't be
- * enabled/disabled independently of the others. When we want to disable the
- * cycle counter, we have to just disable the interrupt reporting and start
- * ignoring that counter. When re-enabling, we have to reset the value and
- * enable the interrupt.
- */
-
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
-
-#include <asm/cputype.h>
-#include <asm/irq_regs.h>
-
-#include <linux/of.h>
-#include <linux/perf/arm_pmu.h>
-#include <linux/platform_device.h>
-
-enum armv6_perf_types {
- ARMV6_PERFCTR_ICACHE_MISS = 0x0,
- ARMV6_PERFCTR_IBUF_STALL = 0x1,
- ARMV6_PERFCTR_DDEP_STALL = 0x2,
- ARMV6_PERFCTR_ITLB_MISS = 0x3,
- ARMV6_PERFCTR_DTLB_MISS = 0x4,
- ARMV6_PERFCTR_BR_EXEC = 0x5,
- ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
- ARMV6_PERFCTR_INSTR_EXEC = 0x7,
- ARMV6_PERFCTR_DCACHE_HIT = 0x9,
- ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
- ARMV6_PERFCTR_DCACHE_MISS = 0xB,
- ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
- ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
- ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
- ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
- ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
- ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
- ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
- ARMV6_PERFCTR_NOP = 0x20,
-};
-
-enum armv6_counters {
- ARMV6_CYCLE_COUNTER = 0,
- ARMV6_COUNTER0,
- ARMV6_COUNTER1,
-};
-
-/*
- * The hardware events that we support. We do support cache operations but
- * we have harvard caches and no way to combine instruction and data
- * accesses/misses in hardware.
- */
-static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6_PERFCTR_IBUF_STALL,
- [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6_PERFCTR_LSU_FULL_STALL,
-};
-
-static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- /*
- * The performance counters don't differentiate between read and write
- * accesses/misses so this isn't strictly correct, but it's the best we
- * can do. Writes and reads get combined.
- */
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
-
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
-
- /*
- * The ARM performance counters can count micro DTLB misses, micro ITLB
- * misses and main TLB misses. There isn't an event for TLB misses, so
- * use the micro misses here and if users want the main TLB misses they
- * can use a raw counter.
- */
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
-};
-
-static inline unsigned long
-armv6_pmcr_read(void)
-{
- u32 val;
- asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
- return val;
-}
-
-static inline void
-armv6_pmcr_write(unsigned long val)
-{
- asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
-}
-
-#define ARMV6_PMCR_ENABLE (1 << 0)
-#define ARMV6_PMCR_CTR01_RESET (1 << 1)
-#define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
-#define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
-#define ARMV6_PMCR_COUNT0_IEN (1 << 4)
-#define ARMV6_PMCR_COUNT1_IEN (1 << 5)
-#define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
-#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
-#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
-#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
-#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
-#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
-#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
-#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
-
-#define ARMV6_PMCR_OVERFLOWED_MASK \
- (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
- ARMV6_PMCR_CCOUNT_OVERFLOW)
-
-static inline int
-armv6_pmcr_has_overflowed(unsigned long pmcr)
-{
- return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
-}
-
-static inline int
-armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
- enum armv6_counters counter)
-{
- int ret = 0;
-
- if (ARMV6_CYCLE_COUNTER == counter)
- ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
- else if (ARMV6_COUNTER0 == counter)
- ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
- else if (ARMV6_COUNTER1 == counter)
- ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
- else
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
-
- return ret;
-}
-
-static inline u64 armv6pmu_read_counter(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int counter = hwc->idx;
- unsigned long value = 0;
-
- if (ARMV6_CYCLE_COUNTER == counter)
- asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
- else if (ARMV6_COUNTER0 == counter)
- asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
- else if (ARMV6_COUNTER1 == counter)
- asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
- else
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
-
- return value;
-}
-
-static inline void armv6pmu_write_counter(struct perf_event *event, u64 value)
-{
- struct hw_perf_event *hwc = &event->hw;
- int counter = hwc->idx;
-
- if (ARMV6_CYCLE_COUNTER == counter)
- asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
- else if (ARMV6_COUNTER0 == counter)
- asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
- else if (ARMV6_COUNTER1 == counter)
- asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
- else
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
-}
-
-static void armv6pmu_enable_event(struct perf_event *event)
-{
- unsigned long val, mask, evt;
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- if (ARMV6_CYCLE_COUNTER == idx) {
- mask = 0;
- evt = ARMV6_PMCR_CCOUNT_IEN;
- } else if (ARMV6_COUNTER0 == idx) {
- mask = ARMV6_PMCR_EVT_COUNT0_MASK;
- evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
- ARMV6_PMCR_COUNT0_IEN;
- } else if (ARMV6_COUNTER1 == idx) {
- mask = ARMV6_PMCR_EVT_COUNT1_MASK;
- evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
- ARMV6_PMCR_COUNT1_IEN;
- } else {
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- /*
- * Mask out the current event and set the counter to count the event
- * that we're interested in.
- */
- val = armv6_pmcr_read();
- val &= ~mask;
- val |= evt;
- armv6_pmcr_write(val);
-}
-
-static irqreturn_t
-armv6pmu_handle_irq(struct arm_pmu *cpu_pmu)
-{
- unsigned long pmcr = armv6_pmcr_read();
- struct perf_sample_data data;
- struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
- struct pt_regs *regs;
- int idx;
-
- if (!armv6_pmcr_has_overflowed(pmcr))
- return IRQ_NONE;
-
- regs = get_irq_regs();
-
- /*
- * The interrupts are cleared by writing the overflow flags back to
- * the control register. All of the other bits don't have any effect
- * if they are rewritten, so write the whole value back.
- */
- armv6_pmcr_write(pmcr);
-
- for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- /* Ignore if we don't have an event. */
- if (!event)
- continue;
-
- /*
- * We have a single interrupt for all counters. Check that
- * each counter has overflowed before we process it.
- */
- if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event);
- perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event))
- continue;
-
- if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(event);
- }
-
- /*
- * 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;
-}
-
-static void armv6pmu_start(struct arm_pmu *cpu_pmu)
-{
- unsigned long val;
-
- val = armv6_pmcr_read();
- val |= ARMV6_PMCR_ENABLE;
- armv6_pmcr_write(val);
-}
-
-static void armv6pmu_stop(struct arm_pmu *cpu_pmu)
-{
- unsigned long val;
-
- val = armv6_pmcr_read();
- val &= ~ARMV6_PMCR_ENABLE;
- armv6_pmcr_write(val);
-}
-
-static int
-armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- /* Always place a cycle counter into the cycle counter. */
- if (ARMV6_PERFCTR_CPU_CYCLES == hwc->config_base) {
- if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
- return -EAGAIN;
-
- return ARMV6_CYCLE_COUNTER;
- } else {
- /*
- * For anything other than a cycle counter, try and use
- * counter0 and counter1.
- */
- if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
- return ARMV6_COUNTER1;
-
- if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
- return ARMV6_COUNTER0;
-
- /* The counters are all in use. */
- return -EAGAIN;
- }
-}
-
-static void armv6pmu_clear_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- clear_bit(event->hw.idx, cpuc->used_mask);
-}
-
-static void armv6pmu_disable_event(struct perf_event *event)
-{
- unsigned long val, mask, evt;
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- if (ARMV6_CYCLE_COUNTER == idx) {
- mask = ARMV6_PMCR_CCOUNT_IEN;
- evt = 0;
- } else if (ARMV6_COUNTER0 == idx) {
- mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
- evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
- } else if (ARMV6_COUNTER1 == idx) {
- mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
- evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
- } else {
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- /*
- * Mask out the current event and set the counter to count the number
- * of ETM bus signal assertion cycles. The external reporting should
- * be disabled and so this should never increment.
- */
- val = armv6_pmcr_read();
- val &= ~mask;
- val |= evt;
- armv6_pmcr_write(val);
-}
-
-static int armv6_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv6_perf_map,
- &armv6_perf_cache_map, 0xFF);
-}
-
-static void armv6pmu_init(struct arm_pmu *cpu_pmu)
-{
- cpu_pmu->handle_irq = armv6pmu_handle_irq;
- cpu_pmu->enable = armv6pmu_enable_event;
- cpu_pmu->disable = armv6pmu_disable_event;
- cpu_pmu->read_counter = armv6pmu_read_counter;
- cpu_pmu->write_counter = armv6pmu_write_counter;
- cpu_pmu->get_event_idx = armv6pmu_get_event_idx;
- cpu_pmu->clear_event_idx = armv6pmu_clear_event_idx;
- cpu_pmu->start = armv6pmu_start;
- cpu_pmu->stop = armv6pmu_stop;
- cpu_pmu->map_event = armv6_map_event;
- cpu_pmu->num_events = 3;
-}
-
-static int armv6_1136_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv6pmu_init(cpu_pmu);
- cpu_pmu->name = "armv6_1136";
- return 0;
-}
-
-static int armv6_1156_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv6pmu_init(cpu_pmu);
- cpu_pmu->name = "armv6_1156";
- return 0;
-}
-
-static int armv6_1176_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv6pmu_init(cpu_pmu);
- cpu_pmu->name = "armv6_1176";
- return 0;
-}
-
-static const struct of_device_id armv6_pmu_of_device_ids[] = {
- {.compatible = "arm,arm1176-pmu", .data = armv6_1176_pmu_init},
- {.compatible = "arm,arm1136-pmu", .data = armv6_1136_pmu_init},
- { /* sentinel value */ }
-};
-
-static const struct pmu_probe_info armv6_pmu_probe_table[] = {
- ARM_PMU_PROBE(ARM_CPU_PART_ARM1136, armv6_1136_pmu_init),
- ARM_PMU_PROBE(ARM_CPU_PART_ARM1156, armv6_1156_pmu_init),
- ARM_PMU_PROBE(ARM_CPU_PART_ARM1176, armv6_1176_pmu_init),
- { /* sentinel value */ }
-};
-
-static int armv6_pmu_device_probe(struct platform_device *pdev)
-{
- return arm_pmu_device_probe(pdev, armv6_pmu_of_device_ids,
- armv6_pmu_probe_table);
-}
-
-static struct platform_driver armv6_pmu_driver = {
- .driver = {
- .name = "armv6-pmu",
- .of_match_table = armv6_pmu_of_device_ids,
- },
- .probe = armv6_pmu_device_probe,
-};
-
-builtin_platform_driver(armv6_pmu_driver);
-#endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
deleted file mode 100644
index a3322e2b3ea4..000000000000
--- a/arch/arm/kernel/perf_event_v7.c
+++ /dev/null
@@ -1,2005 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
- *
- * ARMv7 support: Jean Pihet <jpihet@mvista.com>
- * 2010 (c) MontaVista Software, LLC.
- *
- * Copied from ARMv6 code, with the low level code inspired
- * by the ARMv7 Oprofile code.
- *
- * Cortex-A8 has up to 4 configurable performance counters and
- * a single cycle counter.
- * Cortex-A9 has up to 31 configurable performance counters and
- * a single cycle counter.
- *
- * All counters can be enabled/disabled and IRQ masked separately. The cycle
- * counter and all 4 performance counters together can be reset separately.
- */
-
-#ifdef CONFIG_CPU_V7
-
-#include <asm/cp15.h>
-#include <asm/cputype.h>
-#include <asm/irq_regs.h>
-#include <asm/vfp.h>
-#include "../vfp/vfpinstr.h"
-
-#include <linux/of.h>
-#include <linux/perf/arm_pmu.h>
-#include <linux/platform_device.h>
-
-/*
- * Common ARMv7 event types
- *
- * Note: An implementation may not be able to count all of these events
- * but the encodings are considered to be `reserved' in the case that
- * they are not available.
- */
-#define ARMV7_PERFCTR_PMNC_SW_INCR 0x00
-#define ARMV7_PERFCTR_L1_ICACHE_REFILL 0x01
-#define ARMV7_PERFCTR_ITLB_REFILL 0x02
-#define ARMV7_PERFCTR_L1_DCACHE_REFILL 0x03
-#define ARMV7_PERFCTR_L1_DCACHE_ACCESS 0x04
-#define ARMV7_PERFCTR_DTLB_REFILL 0x05
-#define ARMV7_PERFCTR_MEM_READ 0x06
-#define ARMV7_PERFCTR_MEM_WRITE 0x07
-#define ARMV7_PERFCTR_INSTR_EXECUTED 0x08
-#define ARMV7_PERFCTR_EXC_TAKEN 0x09
-#define ARMV7_PERFCTR_EXC_EXECUTED 0x0A
-#define ARMV7_PERFCTR_CID_WRITE 0x0B
-
-/*
- * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
- * It counts:
- * - all (taken) branch instructions,
- * - instructions that explicitly write the PC,
- * - exception generating instructions.
- */
-#define ARMV7_PERFCTR_PC_WRITE 0x0C
-#define ARMV7_PERFCTR_PC_IMM_BRANCH 0x0D
-#define ARMV7_PERFCTR_PC_PROC_RETURN 0x0E
-#define ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS 0x0F
-#define ARMV7_PERFCTR_PC_BRANCH_MIS_PRED 0x10
-#define ARMV7_PERFCTR_CLOCK_CYCLES 0x11
-#define ARMV7_PERFCTR_PC_BRANCH_PRED 0x12
-
-/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
-#define ARMV7_PERFCTR_MEM_ACCESS 0x13
-#define ARMV7_PERFCTR_L1_ICACHE_ACCESS 0x14
-#define ARMV7_PERFCTR_L1_DCACHE_WB 0x15
-#define ARMV7_PERFCTR_L2_CACHE_ACCESS 0x16
-#define ARMV7_PERFCTR_L2_CACHE_REFILL 0x17
-#define ARMV7_PERFCTR_L2_CACHE_WB 0x18
-#define ARMV7_PERFCTR_BUS_ACCESS 0x19
-#define ARMV7_PERFCTR_MEM_ERROR 0x1A
-#define ARMV7_PERFCTR_INSTR_SPEC 0x1B
-#define ARMV7_PERFCTR_TTBR_WRITE 0x1C
-#define ARMV7_PERFCTR_BUS_CYCLES 0x1D
-
-#define ARMV7_PERFCTR_CPU_CYCLES 0xFF
-
-/* ARMv7 Cortex-A8 specific event types */
-#define ARMV7_A8_PERFCTR_L2_CACHE_ACCESS 0x43
-#define ARMV7_A8_PERFCTR_L2_CACHE_REFILL 0x44
-#define ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS 0x50
-#define ARMV7_A8_PERFCTR_STALL_ISIDE 0x56
-
-/* ARMv7 Cortex-A9 specific event types */
-#define ARMV7_A9_PERFCTR_INSTR_CORE_RENAME 0x68
-#define ARMV7_A9_PERFCTR_STALL_ICACHE 0x60
-#define ARMV7_A9_PERFCTR_STALL_DISPATCH 0x66
-
-/* ARMv7 Cortex-A5 specific event types */
-#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL 0xc2
-#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP 0xc3
-
-/* ARMv7 Cortex-A15 specific event types */
-#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ 0x40
-#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE 0x41
-#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ 0x42
-#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE 0x43
-
-#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ 0x4C
-#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE 0x4D
-
-#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ 0x50
-#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE 0x51
-#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ 0x52
-#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE 0x53
-
-#define ARMV7_A15_PERFCTR_PC_WRITE_SPEC 0x76
-
-/* ARMv7 Cortex-A12 specific event types */
-#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ 0x40
-#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE 0x41
-
-#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ 0x50
-#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE 0x51
-
-#define ARMV7_A12_PERFCTR_PC_WRITE_SPEC 0x76
-
-#define ARMV7_A12_PERFCTR_PF_TLB_REFILL 0xe7
-
-/* ARMv7 Krait specific event types */
-#define KRAIT_PMRESR0_GROUP0 0xcc
-#define KRAIT_PMRESR1_GROUP0 0xd0
-#define KRAIT_PMRESR2_GROUP0 0xd4
-#define KRAIT_VPMRESR0_GROUP0 0xd8
-
-#define KRAIT_PERFCTR_L1_ICACHE_ACCESS 0x10011
-#define KRAIT_PERFCTR_L1_ICACHE_MISS 0x10010
-
-#define KRAIT_PERFCTR_L1_ITLB_ACCESS 0x12222
-#define KRAIT_PERFCTR_L1_DTLB_ACCESS 0x12210
-
-/* ARMv7 Scorpion specific event types */
-#define SCORPION_LPM0_GROUP0 0x4c
-#define SCORPION_LPM1_GROUP0 0x50
-#define SCORPION_LPM2_GROUP0 0x54
-#define SCORPION_L2LPM_GROUP0 0x58
-#define SCORPION_VLPM_GROUP0 0x5c
-
-#define SCORPION_ICACHE_ACCESS 0x10053
-#define SCORPION_ICACHE_MISS 0x10052
-
-#define SCORPION_DTLB_ACCESS 0x12013
-#define SCORPION_DTLB_MISS 0x12012
-
-#define SCORPION_ITLB_MISS 0x12021
-
-/*
- * Cortex-A8 HW events mapping
- *
- * The hardware events that we support. We do support cache operations but
- * we have harvard caches and no way to combine instruction and data
- * accesses/misses in hardware.
- */
-static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
-};
-
-static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- /*
- * The performance counters don't differentiate between read and write
- * accesses/misses so this isn't strictly correct, but it's the best we
- * can do. Writes and reads get combined.
- */
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
-
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
-
- [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
- [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
- [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
- [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Cortex-A9 HW events mapping
- */
-static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
- [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
-};
-
-static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- /*
- * The performance counters don't differentiate between read and write
- * accesses/misses so this isn't strictly correct, but it's the best we
- * can do. Writes and reads get combined.
- */
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
-
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Cortex-A5 HW events mapping
- */
-static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
- [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
-
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
- /*
- * The prefetch counters don't differentiate between the I side and the
- * D side.
- */
- [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
- [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Cortex-A15 HW events mapping
- */
-static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
-};
-
-static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
-
- /*
- * Not all performance counters differentiate between read and write
- * accesses/misses so we're not always strictly correct, but it's the
- * best we can do. Writes and reads get combined in these cases.
- */
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
-
- [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
- [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
- [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
- [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Cortex-A7 HW events mapping
- */
-static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
-};
-
-static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- /*
- * The performance counters don't differentiate between read and write
- * accesses/misses so this isn't strictly correct, but it's the best we
- * can do. Writes and reads get combined.
- */
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
-
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
-
- [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
- [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
- [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
- [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Cortex-A12 HW events mapping
- */
-static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
-};
-
-static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
-
- /*
- * Not all performance counters differentiate between read and write
- * accesses/misses so we're not always strictly correct, but it's the
- * best we can do. Writes and reads get combined in these cases.
- */
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
-
- [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
- [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
- [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
- [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- [C(DTLB)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Krait HW events mapping
- */
-static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
-};
-
-static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
-};
-
-static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- /*
- * The performance counters don't differentiate between read and write
- * accesses/misses so this isn't strictly correct, but it's the best we
- * can do. Writes and reads get combined.
- */
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
-
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = KRAIT_PERFCTR_L1_ICACHE_MISS,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
-
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-/*
- * Scorpion HW events mapping
- */
-static const unsigned scorpion_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
-};
-
-static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
- /*
- * The performance counters don't differentiate between read and write
- * accesses/misses so this isn't strictly correct, but it's the best we
- * can do. Writes and reads get combined.
- */
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = SCORPION_ICACHE_ACCESS,
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_ICACHE_MISS,
- /*
- * Only ITLB misses and DTLB refills are supported. If users want the
- * DTLB refills misses a raw counter must be used.
- */
- [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = SCORPION_DTLB_ACCESS,
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_DTLB_MISS,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = SCORPION_DTLB_ACCESS,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = SCORPION_DTLB_MISS,
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_ITLB_MISS,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = SCORPION_ITLB_MISS,
- [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-7");
-
-static struct attribute *armv7_pmu_format_attrs[] = {
- &format_attr_event.attr,
- NULL,
-};
-
-static struct attribute_group armv7_pmu_format_attr_group = {
- .name = "format",
- .attrs = armv7_pmu_format_attrs,
-};
-
-#define ARMV7_EVENT_ATTR_RESOLVE(m) #m
-#define ARMV7_EVENT_ATTR(name, config) \
- PMU_EVENT_ATTR_STRING(name, armv7_event_attr_##name, \
- "event=" ARMV7_EVENT_ATTR_RESOLVE(config))
-
-ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
-ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
-ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
-ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
-ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
-ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
-ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
-ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
-ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
-ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
-ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
-ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
-ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
-ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
-ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
-ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
-ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
-ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
-ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
-
-static struct attribute *armv7_pmuv1_event_attrs[] = {
- &armv7_event_attr_sw_incr.attr.attr,
- &armv7_event_attr_l1i_cache_refill.attr.attr,
- &armv7_event_attr_l1i_tlb_refill.attr.attr,
- &armv7_event_attr_l1d_cache_refill.attr.attr,
- &armv7_event_attr_l1d_cache.attr.attr,
- &armv7_event_attr_l1d_tlb_refill.attr.attr,
- &armv7_event_attr_ld_retired.attr.attr,
- &armv7_event_attr_st_retired.attr.attr,
- &armv7_event_attr_inst_retired.attr.attr,
- &armv7_event_attr_exc_taken.attr.attr,
- &armv7_event_attr_exc_return.attr.attr,
- &armv7_event_attr_cid_write_retired.attr.attr,
- &armv7_event_attr_pc_write_retired.attr.attr,
- &armv7_event_attr_br_immed_retired.attr.attr,
- &armv7_event_attr_br_return_retired.attr.attr,
- &armv7_event_attr_unaligned_ldst_retired.attr.attr,
- &armv7_event_attr_br_mis_pred.attr.attr,
- &armv7_event_attr_cpu_cycles.attr.attr,
- &armv7_event_attr_br_pred.attr.attr,
- NULL,
-};
-
-static struct attribute_group armv7_pmuv1_events_attr_group = {
- .name = "events",
- .attrs = armv7_pmuv1_event_attrs,
-};
-
-ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
-ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
-ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
-ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
-ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
-ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
-ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
-ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
-ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
-ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
-ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
-
-static struct attribute *armv7_pmuv2_event_attrs[] = {
- &armv7_event_attr_sw_incr.attr.attr,
- &armv7_event_attr_l1i_cache_refill.attr.attr,
- &armv7_event_attr_l1i_tlb_refill.attr.attr,
- &armv7_event_attr_l1d_cache_refill.attr.attr,
- &armv7_event_attr_l1d_cache.attr.attr,
- &armv7_event_attr_l1d_tlb_refill.attr.attr,
- &armv7_event_attr_ld_retired.attr.attr,
- &armv7_event_attr_st_retired.attr.attr,
- &armv7_event_attr_inst_retired.attr.attr,
- &armv7_event_attr_exc_taken.attr.attr,
- &armv7_event_attr_exc_return.attr.attr,
- &armv7_event_attr_cid_write_retired.attr.attr,
- &armv7_event_attr_pc_write_retired.attr.attr,
- &armv7_event_attr_br_immed_retired.attr.attr,
- &armv7_event_attr_br_return_retired.attr.attr,
- &armv7_event_attr_unaligned_ldst_retired.attr.attr,
- &armv7_event_attr_br_mis_pred.attr.attr,
- &armv7_event_attr_cpu_cycles.attr.attr,
- &armv7_event_attr_br_pred.attr.attr,
- &armv7_event_attr_mem_access.attr.attr,
- &armv7_event_attr_l1i_cache.attr.attr,
- &armv7_event_attr_l1d_cache_wb.attr.attr,
- &armv7_event_attr_l2d_cache.attr.attr,
- &armv7_event_attr_l2d_cache_refill.attr.attr,
- &armv7_event_attr_l2d_cache_wb.attr.attr,
- &armv7_event_attr_bus_access.attr.attr,
- &armv7_event_attr_memory_error.attr.attr,
- &armv7_event_attr_inst_spec.attr.attr,
- &armv7_event_attr_ttbr_write_retired.attr.attr,
- &armv7_event_attr_bus_cycles.attr.attr,
- NULL,
-};
-
-static struct attribute_group armv7_pmuv2_events_attr_group = {
- .name = "events",
- .attrs = armv7_pmuv2_event_attrs,
-};
-
-/*
- * Perf Events' indices
- */
-#define ARMV7_IDX_CYCLE_COUNTER 0
-#define ARMV7_IDX_COUNTER0 1
-#define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
- (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
-
-#define ARMV7_MAX_COUNTERS 32
-#define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
-
-/*
- * ARMv7 low level PMNC access
- */
-
-/*
- * Perf Event to low level counters mapping
- */
-#define ARMV7_IDX_TO_COUNTER(x) \
- (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
-
-/*
- * Per-CPU PMNC: config reg
- */
-#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
-#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
-#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
-#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
-#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
-#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
-#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
-#define ARMV7_PMNC_N_MASK 0x1f
-#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
-
-/*
- * FLAG: counters overflow flag status reg
- */
-#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
-#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
-
-/*
- * PMXEVTYPER: Event selection reg
- */
-#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
-#define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
-
-/*
- * Event filters for PMUv2
- */
-#define ARMV7_EXCLUDE_PL1 BIT(31)
-#define ARMV7_EXCLUDE_USER BIT(30)
-#define ARMV7_INCLUDE_HYP BIT(27)
-
-/*
- * Secure debug enable reg
- */
-#define ARMV7_SDER_SUNIDEN BIT(1) /* Permit non-invasive debug */
-
-static inline u32 armv7_pmnc_read(void)
-{
- u32 val;
- asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
- return val;
-}
-
-static inline void armv7_pmnc_write(u32 val)
-{
- val &= ARMV7_PMNC_MASK;
- isb();
- asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
-}
-
-static inline int armv7_pmnc_has_overflowed(u32 pmnc)
-{
- return pmnc & ARMV7_OVERFLOWED_MASK;
-}
-
-static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx)
-{
- return idx >= ARMV7_IDX_CYCLE_COUNTER &&
- idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu);
-}
-
-static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
-{
- return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx));
-}
-
-static inline void armv7_pmnc_select_counter(int idx)
-{
- u32 counter = ARMV7_IDX_TO_COUNTER(idx);
- asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
- isb();
-}
-
-static inline u64 armv7pmu_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;
- u32 value = 0;
-
- if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU%u reading wrong counter %d\n",
- smp_processor_id(), idx);
- } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
- } else {
- armv7_pmnc_select_counter(idx);
- asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
- }
-
- return value;
-}
-
-static inline void armv7pmu_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;
-
- if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU%u writing wrong counter %d\n",
- smp_processor_id(), idx);
- } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
- asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" ((u32)value));
- } else {
- armv7_pmnc_select_counter(idx);
- asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" ((u32)value));
- }
-}
-
-static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
-{
- armv7_pmnc_select_counter(idx);
- val &= ARMV7_EVTYPE_MASK;
- asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
-}
-
-static inline void armv7_pmnc_enable_counter(int idx)
-{
- u32 counter = ARMV7_IDX_TO_COUNTER(idx);
- asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
-}
-
-static inline void armv7_pmnc_disable_counter(int idx)
-{
- u32 counter = ARMV7_IDX_TO_COUNTER(idx);
- asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
-}
-
-static inline void armv7_pmnc_enable_intens(int idx)
-{
- u32 counter = ARMV7_IDX_TO_COUNTER(idx);
- asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
-}
-
-static inline void armv7_pmnc_disable_intens(int idx)
-{
- u32 counter = ARMV7_IDX_TO_COUNTER(idx);
- asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
- isb();
- /* Clear the overflow flag in case an interrupt is pending. */
- asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
- isb();
-}
-
-static inline u32 armv7_pmnc_getreset_flags(void)
-{
- u32 val;
-
- /* Read */
- asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
-
- /* Write to clear flags */
- val &= ARMV7_FLAG_MASK;
- asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
-
- return val;
-}
-
-#ifdef DEBUG
-static void armv7_pmnc_dump_regs(struct arm_pmu *cpu_pmu)
-{
- u32 val;
- unsigned int cnt;
-
- pr_info("PMNC registers dump:\n");
-
- asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
- pr_info("PMNC =0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
- pr_info("CNTENS=0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
- pr_info("INTENS=0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
- pr_info("FLAGS =0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
- pr_info("SELECT=0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
- pr_info("CCNT =0x%08x\n", val);
-
- for (cnt = ARMV7_IDX_COUNTER0;
- cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
- armv7_pmnc_select_counter(cnt);
- asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
- pr_info("CNT[%d] count =0x%08x\n",
- ARMV7_IDX_TO_COUNTER(cnt), val);
- asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
- pr_info("CNT[%d] evtsel=0x%08x\n",
- ARMV7_IDX_TO_COUNTER(cnt), val);
- }
-}
-#endif
-
-static void armv7pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
- int idx = hwc->idx;
-
- if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
- smp_processor_id(), idx);
- return;
- }
-
- /*
- * Enable counter and interrupt, and set the counter to count
- * the event that we're interested in.
- */
-
- /*
- * Disable counter
- */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Set event (if destined for PMNx counters)
- * We only need to set the event for the cycle counter if we
- * have the ability to perform event filtering.
- */
- if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
- armv7_pmnc_write_evtsel(idx, hwc->config_base);
-
- /*
- * Enable interrupt for this counter
- */
- armv7_pmnc_enable_intens(idx);
-
- /*
- * Enable counter
- */
- armv7_pmnc_enable_counter(idx);
-}
-
-static void armv7pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
- int idx = hwc->idx;
-
- if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
- smp_processor_id(), idx);
- return;
- }
-
- /*
- * Disable counter and interrupt
- */
-
- /*
- * Disable counter
- */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Disable interrupt for this counter
- */
- armv7_pmnc_disable_intens(idx);
-}
-
-static irqreturn_t armv7pmu_handle_irq(struct arm_pmu *cpu_pmu)
-{
- u32 pmnc;
- struct perf_sample_data data;
- struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
- struct pt_regs *regs;
- int idx;
-
- /*
- * Get and reset the IRQ flags
- */
- pmnc = armv7_pmnc_getreset_flags();
-
- /*
- * Did an overflow occur?
- */
- if (!armv7_pmnc_has_overflowed(pmnc))
- return IRQ_NONE;
-
- /*
- * Handle the counter(s) overflow(s)
- */
- regs = get_irq_regs();
-
- for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- /* Ignore if we don't have an event. */
- if (!event)
- continue;
-
- /*
- * We have a single interrupt for all counters. Check that
- * each counter has overflowed before we process it.
- */
- if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event);
- perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event))
- continue;
-
- if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(event);
- }
-
- /*
- * 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;
-}
-
-static void armv7pmu_start(struct arm_pmu *cpu_pmu)
-{
- /* Enable all counters */
- armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
-}
-
-static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
-{
- /* Disable all counters */
- armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
-}
-
-static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int idx;
- struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
-
- /* Always place a cycle counter into the cycle counter. */
- if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
- if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
- return -EAGAIN;
-
- return ARMV7_IDX_CYCLE_COUNTER;
- }
-
- /*
- * For anything other than a cycle counter, try and use
- * the events counters
- */
- for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
- if (!test_and_set_bit(idx, cpuc->used_mask))
- return idx;
- }
-
- /* The counters are all in use. */
- return -EAGAIN;
-}
-
-static void armv7pmu_clear_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- clear_bit(event->hw.idx, cpuc->used_mask);
-}
-
-/*
- * Add an event filter to a given event. This will only work for PMUv2 PMUs.
- */
-static int armv7pmu_set_event_filter(struct hw_perf_event *event,
- struct perf_event_attr *attr)
-{
- unsigned long config_base = 0;
-
- if (attr->exclude_idle) {
- pr_debug("ARM performance counters do not support mode exclusion\n");
- return -EOPNOTSUPP;
- }
- if (attr->exclude_user)
- config_base |= ARMV7_EXCLUDE_USER;
- if (attr->exclude_kernel)
- config_base |= ARMV7_EXCLUDE_PL1;
- if (!attr->exclude_hv)
- config_base |= ARMV7_INCLUDE_HYP;
-
- /*
- * Install the filter into config_base as this is used to
- * construct the event type.
- */
- event->config_base = config_base;
-
- return 0;
-}
-
-static void armv7pmu_reset(void *info)
-{
- struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
- u32 idx, nb_cnt = cpu_pmu->num_events, val;
-
- if (cpu_pmu->secure_access) {
- asm volatile("mrc p15, 0, %0, c1, c1, 1" : "=r" (val));
- val |= ARMV7_SDER_SUNIDEN;
- asm volatile("mcr p15, 0, %0, c1, c1, 1" : : "r" (val));
- }
-
- /* The counter and interrupt enable registers are unknown at reset. */
- for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
- armv7_pmnc_disable_counter(idx);
- armv7_pmnc_disable_intens(idx);
- }
-
- /* Initialize & Reset PMNC: C and P bits */
- armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
-}
-
-static int armv7_a8_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a8_perf_map,
- &armv7_a8_perf_cache_map, 0xFF);
-}
-
-static int armv7_a9_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a9_perf_map,
- &armv7_a9_perf_cache_map, 0xFF);
-}
-
-static int armv7_a5_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a5_perf_map,
- &armv7_a5_perf_cache_map, 0xFF);
-}
-
-static int armv7_a15_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a15_perf_map,
- &armv7_a15_perf_cache_map, 0xFF);
-}
-
-static int armv7_a7_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a7_perf_map,
- &armv7_a7_perf_cache_map, 0xFF);
-}
-
-static int armv7_a12_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a12_perf_map,
- &armv7_a12_perf_cache_map, 0xFF);
-}
-
-static int krait_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &krait_perf_map,
- &krait_perf_cache_map, 0xFFFFF);
-}
-
-static int krait_map_event_no_branch(struct perf_event *event)
-{
- return armpmu_map_event(event, &krait_perf_map_no_branch,
- &krait_perf_cache_map, 0xFFFFF);
-}
-
-static int scorpion_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &scorpion_perf_map,
- &scorpion_perf_cache_map, 0xFFFFF);
-}
-
-static void armv7pmu_init(struct arm_pmu *cpu_pmu)
-{
- cpu_pmu->handle_irq = armv7pmu_handle_irq;
- cpu_pmu->enable = armv7pmu_enable_event;
- cpu_pmu->disable = armv7pmu_disable_event;
- cpu_pmu->read_counter = armv7pmu_read_counter;
- cpu_pmu->write_counter = armv7pmu_write_counter;
- cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
- cpu_pmu->clear_event_idx = armv7pmu_clear_event_idx;
- cpu_pmu->start = armv7pmu_start;
- cpu_pmu->stop = armv7pmu_stop;
- cpu_pmu->reset = armv7pmu_reset;
-};
-
-static void armv7_read_num_pmnc_events(void *info)
-{
- int *nb_cnt = info;
-
- /* Read the nb of CNTx counters supported from PMNC */
- *nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
-
- /* Add the CPU cycles counter */
- *nb_cnt += 1;
-}
-
-static int armv7_probe_num_events(struct arm_pmu *arm_pmu)
-{
- return smp_call_function_any(&arm_pmu->supported_cpus,
- armv7_read_num_pmnc_events,
- &arm_pmu->num_events, 1);
-}
-
-static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a8";
- cpu_pmu->map_event = armv7_a8_map_event;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv1_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a9";
- cpu_pmu->map_event = armv7_a9_map_event;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv1_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a5";
- cpu_pmu->map_event = armv7_a5_map_event;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv1_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a15";
- cpu_pmu->map_event = armv7_a15_map_event;
- cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv2_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a7";
- cpu_pmu->map_event = armv7_a7_map_event;
- cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv2_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a12";
- cpu_pmu->map_event = armv7_a12_map_event;
- cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv2_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
-{
- int ret = armv7_a12_pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_cortex_a17";
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
- &armv7_pmuv2_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
- &armv7_pmu_format_attr_group;
- return ret;
-}
-
-/*
- * Krait Performance Monitor Region Event Selection Register (PMRESRn)
- *
- * 31 30 24 16 8 0
- * +--------------------------------+
- * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
- * +--------------------------------+
- * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
- * +--------------------------------+
- * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
- * +--------------------------------+
- * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
- * +--------------------------------+
- * EN | G=3 | G=2 | G=1 | G=0
- *
- * Event Encoding:
- *
- * hwc->config_base = 0xNRCCG
- *
- * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
- * R = region register
- * CC = class of events the group G is choosing from
- * G = group or particular event
- *
- * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
- *
- * A region (R) corresponds to a piece of the CPU (execution unit, instruction
- * unit, etc.) while the event code (CC) corresponds to a particular class of
- * events (interrupts for example). An event code is broken down into
- * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
- * example).
- */
-
-#define KRAIT_EVENT (1 << 16)
-#define VENUM_EVENT (2 << 16)
-#define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
-#define PMRESRn_EN BIT(31)
-
-#define EVENT_REGION(event) (((event) >> 12) & 0xf) /* R */
-#define EVENT_GROUP(event) ((event) & 0xf) /* G */
-#define EVENT_CODE(event) (((event) >> 4) & 0xff) /* CC */
-#define EVENT_VENUM(event) (!!(event & VENUM_EVENT)) /* N=2 */
-#define EVENT_CPU(event) (!!(event & KRAIT_EVENT)) /* N=1 */
-
-static u32 krait_read_pmresrn(int n)
-{
- u32 val;
-
- switch (n) {
- case 0:
- asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
- break;
- case 1:
- asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
- break;
- case 2:
- asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
- break;
- default:
- BUG(); /* Should be validated in krait_pmu_get_event_idx() */
- }
-
- return val;
-}
-
-static void krait_write_pmresrn(int n, u32 val)
-{
- switch (n) {
- case 0:
- asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
- break;
- case 1:
- asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
- break;
- case 2:
- asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
- break;
- default:
- BUG(); /* Should be validated in krait_pmu_get_event_idx() */
- }
-}
-
-static u32 venum_read_pmresr(void)
-{
- u32 val;
- asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
- return val;
-}
-
-static void venum_write_pmresr(u32 val)
-{
- asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
-}
-
-static void venum_pre_pmresr(u32 *venum_orig_val, u32 *fp_orig_val)
-{
- u32 venum_new_val;
- u32 fp_new_val;
-
- BUG_ON(preemptible());
- /* CPACR Enable CP10 and CP11 access */
- *venum_orig_val = get_copro_access();
- venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
- set_copro_access(venum_new_val);
-
- /* Enable FPEXC */
- *fp_orig_val = fmrx(FPEXC);
- fp_new_val = *fp_orig_val | FPEXC_EN;
- fmxr(FPEXC, fp_new_val);
-}
-
-static void venum_post_pmresr(u32 venum_orig_val, u32 fp_orig_val)
-{
- BUG_ON(preemptible());
- /* Restore FPEXC */
- fmxr(FPEXC, fp_orig_val);
- isb();
- /* Restore CPACR */
- set_copro_access(venum_orig_val);
-}
-
-static u32 krait_get_pmresrn_event(unsigned int region)
-{
- static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
- KRAIT_PMRESR1_GROUP0,
- KRAIT_PMRESR2_GROUP0 };
- return pmresrn_table[region];
-}
-
-static void krait_evt_setup(int idx, u32 config_base)
-{
- u32 val;
- u32 mask;
- u32 vval, fval;
- unsigned int region = EVENT_REGION(config_base);
- unsigned int group = EVENT_GROUP(config_base);
- unsigned int code = EVENT_CODE(config_base);
- unsigned int group_shift;
- bool venum_event = EVENT_VENUM(config_base);
-
- group_shift = group * 8;
- mask = 0xff << group_shift;
-
- /* Configure evtsel for the region and group */
- if (venum_event)
- val = KRAIT_VPMRESR0_GROUP0;
- else
- val = krait_get_pmresrn_event(region);
- val += group;
- /* Mix in mode-exclusion bits */
- val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
- armv7_pmnc_write_evtsel(idx, val);
-
- if (venum_event) {
- venum_pre_pmresr(&vval, &fval);
- val = venum_read_pmresr();
- val &= ~mask;
- val |= code << group_shift;
- val |= PMRESRn_EN;
- venum_write_pmresr(val);
- venum_post_pmresr(vval, fval);
- } else {
- val = krait_read_pmresrn(region);
- val &= ~mask;
- val |= code << group_shift;
- val |= PMRESRn_EN;
- krait_write_pmresrn(region, val);
- }
-}
-
-static u32 clear_pmresrn_group(u32 val, int group)
-{
- u32 mask;
- int group_shift;
-
- group_shift = group * 8;
- mask = 0xff << group_shift;
- val &= ~mask;
-
- /* Don't clear enable bit if entire region isn't disabled */
- if (val & ~PMRESRn_EN)
- return val |= PMRESRn_EN;
-
- return 0;
-}
-
-static void krait_clearpmu(u32 config_base)
-{
- u32 val;
- u32 vval, fval;
- unsigned int region = EVENT_REGION(config_base);
- unsigned int group = EVENT_GROUP(config_base);
- bool venum_event = EVENT_VENUM(config_base);
-
- if (venum_event) {
- venum_pre_pmresr(&vval, &fval);
- val = venum_read_pmresr();
- val = clear_pmresrn_group(val, group);
- venum_write_pmresr(val);
- venum_post_pmresr(vval, fval);
- } else {
- val = krait_read_pmresrn(region);
- val = clear_pmresrn_group(val, group);
- krait_write_pmresrn(region, val);
- }
-}
-
-static void krait_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- /* Disable counter and interrupt */
-
- /* Disable counter */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Clear pmresr code (if destined for PMNx counters)
- */
- if (hwc->config_base & KRAIT_EVENT_MASK)
- krait_clearpmu(hwc->config_base);
-
- /* Disable interrupt for this counter */
- armv7_pmnc_disable_intens(idx);
-}
-
-static void krait_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- /*
- * Enable counter and interrupt, and set the counter to count
- * the event that we're interested in.
- */
-
- /* Disable counter */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Set event (if destined for PMNx counters)
- * We set the event for the cycle counter because we
- * have the ability to perform event filtering.
- */
- if (hwc->config_base & KRAIT_EVENT_MASK)
- krait_evt_setup(idx, hwc->config_base);
- else
- armv7_pmnc_write_evtsel(idx, hwc->config_base);
-
- /* Enable interrupt for this counter */
- armv7_pmnc_enable_intens(idx);
-
- /* Enable counter */
- armv7_pmnc_enable_counter(idx);
-}
-
-static void krait_pmu_reset(void *info)
-{
- u32 vval, fval;
- struct arm_pmu *cpu_pmu = info;
- u32 idx, nb_cnt = cpu_pmu->num_events;
-
- armv7pmu_reset(info);
-
- /* Clear all pmresrs */
- krait_write_pmresrn(0, 0);
- krait_write_pmresrn(1, 0);
- krait_write_pmresrn(2, 0);
-
- venum_pre_pmresr(&vval, &fval);
- venum_write_pmresr(0);
- venum_post_pmresr(vval, fval);
-
- /* Reset PMxEVNCTCR to sane default */
- for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
- armv7_pmnc_select_counter(idx);
- asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
- }
-
-}
-
-static int krait_event_to_bit(struct perf_event *event, unsigned int region,
- unsigned int group)
-{
- int bit;
- struct hw_perf_event *hwc = &event->hw;
- struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
-
- if (hwc->config_base & VENUM_EVENT)
- bit = KRAIT_VPMRESR0_GROUP0;
- else
- bit = krait_get_pmresrn_event(region);
- bit -= krait_get_pmresrn_event(0);
- bit += group;
- /*
- * Lower bits are reserved for use by the counters (see
- * armv7pmu_get_event_idx() for more info)
- */
- bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
-
- return bit;
-}
-
-/*
- * We check for column exclusion constraints here.
- * Two events cant use the same group within a pmresr register.
- */
-static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int idx;
- int bit = -1;
- struct hw_perf_event *hwc = &event->hw;
- unsigned int region = EVENT_REGION(hwc->config_base);
- unsigned int code = EVENT_CODE(hwc->config_base);
- unsigned int group = EVENT_GROUP(hwc->config_base);
- bool venum_event = EVENT_VENUM(hwc->config_base);
- bool krait_event = EVENT_CPU(hwc->config_base);
-
- if (venum_event || krait_event) {
- /* Ignore invalid events */
- if (group > 3 || region > 2)
- return -EINVAL;
- if (venum_event && (code & 0xe0))
- return -EINVAL;
-
- bit = krait_event_to_bit(event, region, group);
- if (test_and_set_bit(bit, cpuc->used_mask))
- return -EAGAIN;
- }
-
- idx = armv7pmu_get_event_idx(cpuc, event);
- if (idx < 0 && bit >= 0)
- clear_bit(bit, cpuc->used_mask);
-
- return idx;
-}
-
-static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int bit;
- struct hw_perf_event *hwc = &event->hw;
- unsigned int region = EVENT_REGION(hwc->config_base);
- unsigned int group = EVENT_GROUP(hwc->config_base);
- bool venum_event = EVENT_VENUM(hwc->config_base);
- bool krait_event = EVENT_CPU(hwc->config_base);
-
- armv7pmu_clear_event_idx(cpuc, event);
- if (venum_event || krait_event) {
- bit = krait_event_to_bit(event, region, group);
- clear_bit(bit, cpuc->used_mask);
- }
-}
-
-static int krait_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_krait";
- /* Some early versions of Krait don't support PC write events */
- if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
- "qcom,no-pc-write"))
- cpu_pmu->map_event = krait_map_event_no_branch;
- else
- cpu_pmu->map_event = krait_map_event;
- cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
- cpu_pmu->reset = krait_pmu_reset;
- cpu_pmu->enable = krait_pmu_enable_event;
- cpu_pmu->disable = krait_pmu_disable_event;
- cpu_pmu->get_event_idx = krait_pmu_get_event_idx;
- cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-/*
- * Scorpion Local Performance Monitor Register (LPMn)
- *
- * 31 30 24 16 8 0
- * +--------------------------------+
- * LPM0 | EN | CC | CC | CC | CC | N = 1, R = 0
- * +--------------------------------+
- * LPM1 | EN | CC | CC | CC | CC | N = 1, R = 1
- * +--------------------------------+
- * LPM2 | EN | CC | CC | CC | CC | N = 1, R = 2
- * +--------------------------------+
- * L2LPM | EN | CC | CC | CC | CC | N = 1, R = 3
- * +--------------------------------+
- * VLPM | EN | CC | CC | CC | CC | N = 2, R = ?
- * +--------------------------------+
- * EN | G=3 | G=2 | G=1 | G=0
- *
- *
- * Event Encoding:
- *
- * hwc->config_base = 0xNRCCG
- *
- * N = prefix, 1 for Scorpion CPU (LPMn/L2LPM), 2 for Venum VFP (VLPM)
- * R = region register
- * CC = class of events the group G is choosing from
- * G = group or particular event
- *
- * Example: 0x12021 is a Scorpion CPU event in LPM2's group 1 with code 2
- *
- * A region (R) corresponds to a piece of the CPU (execution unit, instruction
- * unit, etc.) while the event code (CC) corresponds to a particular class of
- * events (interrupts for example). An event code is broken down into
- * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
- * example).
- */
-
-static u32 scorpion_read_pmresrn(int n)
-{
- u32 val;
-
- switch (n) {
- case 0:
- asm volatile("mrc p15, 0, %0, c15, c0, 0" : "=r" (val));
- break;
- case 1:
- asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val));
- break;
- case 2:
- asm volatile("mrc p15, 2, %0, c15, c0, 0" : "=r" (val));
- break;
- case 3:
- asm volatile("mrc p15, 3, %0, c15, c2, 0" : "=r" (val));
- break;
- default:
- BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
- }
-
- return val;
-}
-
-static void scorpion_write_pmresrn(int n, u32 val)
-{
- switch (n) {
- case 0:
- asm volatile("mcr p15, 0, %0, c15, c0, 0" : : "r" (val));
- break;
- case 1:
- asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val));
- break;
- case 2:
- asm volatile("mcr p15, 2, %0, c15, c0, 0" : : "r" (val));
- break;
- case 3:
- asm volatile("mcr p15, 3, %0, c15, c2, 0" : : "r" (val));
- break;
- default:
- BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
- }
-}
-
-static u32 scorpion_get_pmresrn_event(unsigned int region)
-{
- static const u32 pmresrn_table[] = { SCORPION_LPM0_GROUP0,
- SCORPION_LPM1_GROUP0,
- SCORPION_LPM2_GROUP0,
- SCORPION_L2LPM_GROUP0 };
- return pmresrn_table[region];
-}
-
-static void scorpion_evt_setup(int idx, u32 config_base)
-{
- u32 val;
- u32 mask;
- u32 vval, fval;
- unsigned int region = EVENT_REGION(config_base);
- unsigned int group = EVENT_GROUP(config_base);
- unsigned int code = EVENT_CODE(config_base);
- unsigned int group_shift;
- bool venum_event = EVENT_VENUM(config_base);
-
- group_shift = group * 8;
- mask = 0xff << group_shift;
-
- /* Configure evtsel for the region and group */
- if (venum_event)
- val = SCORPION_VLPM_GROUP0;
- else
- val = scorpion_get_pmresrn_event(region);
- val += group;
- /* Mix in mode-exclusion bits */
- val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
- armv7_pmnc_write_evtsel(idx, val);
-
- asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
-
- if (venum_event) {
- venum_pre_pmresr(&vval, &fval);
- val = venum_read_pmresr();
- val &= ~mask;
- val |= code << group_shift;
- val |= PMRESRn_EN;
- venum_write_pmresr(val);
- venum_post_pmresr(vval, fval);
- } else {
- val = scorpion_read_pmresrn(region);
- val &= ~mask;
- val |= code << group_shift;
- val |= PMRESRn_EN;
- scorpion_write_pmresrn(region, val);
- }
-}
-
-static void scorpion_clearpmu(u32 config_base)
-{
- u32 val;
- u32 vval, fval;
- unsigned int region = EVENT_REGION(config_base);
- unsigned int group = EVENT_GROUP(config_base);
- bool venum_event = EVENT_VENUM(config_base);
-
- if (venum_event) {
- venum_pre_pmresr(&vval, &fval);
- val = venum_read_pmresr();
- val = clear_pmresrn_group(val, group);
- venum_write_pmresr(val);
- venum_post_pmresr(vval, fval);
- } else {
- val = scorpion_read_pmresrn(region);
- val = clear_pmresrn_group(val, group);
- scorpion_write_pmresrn(region, val);
- }
-}
-
-static void scorpion_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- /* Disable counter and interrupt */
-
- /* Disable counter */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Clear pmresr code (if destined for PMNx counters)
- */
- if (hwc->config_base & KRAIT_EVENT_MASK)
- scorpion_clearpmu(hwc->config_base);
-
- /* Disable interrupt for this counter */
- armv7_pmnc_disable_intens(idx);
-}
-
-static void scorpion_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- /*
- * Enable counter and interrupt, and set the counter to count
- * the event that we're interested in.
- */
-
- /* Disable counter */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Set event (if destined for PMNx counters)
- * We don't set the event for the cycle counter because we
- * don't have the ability to perform event filtering.
- */
- if (hwc->config_base & KRAIT_EVENT_MASK)
- scorpion_evt_setup(idx, hwc->config_base);
- else if (idx != ARMV7_IDX_CYCLE_COUNTER)
- armv7_pmnc_write_evtsel(idx, hwc->config_base);
-
- /* Enable interrupt for this counter */
- armv7_pmnc_enable_intens(idx);
-
- /* Enable counter */
- armv7_pmnc_enable_counter(idx);
-}
-
-static void scorpion_pmu_reset(void *info)
-{
- u32 vval, fval;
- struct arm_pmu *cpu_pmu = info;
- u32 idx, nb_cnt = cpu_pmu->num_events;
-
- armv7pmu_reset(info);
-
- /* Clear all pmresrs */
- scorpion_write_pmresrn(0, 0);
- scorpion_write_pmresrn(1, 0);
- scorpion_write_pmresrn(2, 0);
- scorpion_write_pmresrn(3, 0);
-
- venum_pre_pmresr(&vval, &fval);
- venum_write_pmresr(0);
- venum_post_pmresr(vval, fval);
-
- /* Reset PMxEVNCTCR to sane default */
- for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
- armv7_pmnc_select_counter(idx);
- asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
- }
-}
-
-static int scorpion_event_to_bit(struct perf_event *event, unsigned int region,
- unsigned int group)
-{
- int bit;
- struct hw_perf_event *hwc = &event->hw;
- struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
-
- if (hwc->config_base & VENUM_EVENT)
- bit = SCORPION_VLPM_GROUP0;
- else
- bit = scorpion_get_pmresrn_event(region);
- bit -= scorpion_get_pmresrn_event(0);
- bit += group;
- /*
- * Lower bits are reserved for use by the counters (see
- * armv7pmu_get_event_idx() for more info)
- */
- bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
-
- return bit;
-}
-
-/*
- * We check for column exclusion constraints here.
- * Two events cant use the same group within a pmresr register.
- */
-static int scorpion_pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int idx;
- int bit = -1;
- struct hw_perf_event *hwc = &event->hw;
- unsigned int region = EVENT_REGION(hwc->config_base);
- unsigned int group = EVENT_GROUP(hwc->config_base);
- bool venum_event = EVENT_VENUM(hwc->config_base);
- bool scorpion_event = EVENT_CPU(hwc->config_base);
-
- if (venum_event || scorpion_event) {
- /* Ignore invalid events */
- if (group > 3 || region > 3)
- return -EINVAL;
-
- bit = scorpion_event_to_bit(event, region, group);
- if (test_and_set_bit(bit, cpuc->used_mask))
- return -EAGAIN;
- }
-
- idx = armv7pmu_get_event_idx(cpuc, event);
- if (idx < 0 && bit >= 0)
- clear_bit(bit, cpuc->used_mask);
-
- return idx;
-}
-
-static void scorpion_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int bit;
- struct hw_perf_event *hwc = &event->hw;
- unsigned int region = EVENT_REGION(hwc->config_base);
- unsigned int group = EVENT_GROUP(hwc->config_base);
- bool venum_event = EVENT_VENUM(hwc->config_base);
- bool scorpion_event = EVENT_CPU(hwc->config_base);
-
- armv7pmu_clear_event_idx(cpuc, event);
- if (venum_event || scorpion_event) {
- bit = scorpion_event_to_bit(event, region, group);
- clear_bit(bit, cpuc->used_mask);
- }
-}
-
-static int scorpion_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_scorpion";
- cpu_pmu->map_event = scorpion_map_event;
- cpu_pmu->reset = scorpion_pmu_reset;
- cpu_pmu->enable = scorpion_pmu_enable_event;
- cpu_pmu->disable = scorpion_pmu_disable_event;
- cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx;
- cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static int scorpion_mp_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "armv7_scorpion_mp";
- cpu_pmu->map_event = scorpion_map_event;
- cpu_pmu->reset = scorpion_pmu_reset;
- cpu_pmu->enable = scorpion_pmu_enable_event;
- cpu_pmu->disable = scorpion_pmu_disable_event;
- cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx;
- cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx;
- return armv7_probe_num_events(cpu_pmu);
-}
-
-static const struct of_device_id armv7_pmu_of_device_ids[] = {
- {.compatible = "arm,cortex-a17-pmu", .data = armv7_a17_pmu_init},
- {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
- {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init},
- {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
- {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
- {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
- {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init},
- {.compatible = "qcom,krait-pmu", .data = krait_pmu_init},
- {.compatible = "qcom,scorpion-pmu", .data = scorpion_pmu_init},
- {.compatible = "qcom,scorpion-mp-pmu", .data = scorpion_mp_pmu_init},
- {},
-};
-
-static const struct pmu_probe_info armv7_pmu_probe_table[] = {
- ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8, armv7_a8_pmu_init),
- ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9, armv7_a9_pmu_init),
- { /* sentinel value */ }
-};
-
-
-static int armv7_pmu_device_probe(struct platform_device *pdev)
-{
- return arm_pmu_device_probe(pdev, armv7_pmu_of_device_ids,
- armv7_pmu_probe_table);
-}
-
-static struct platform_driver armv7_pmu_driver = {
- .driver = {
- .name = "armv7-pmu",
- .of_match_table = armv7_pmu_of_device_ids,
- .suppress_bind_attrs = true,
- },
- .probe = armv7_pmu_device_probe,
-};
-
-builtin_platform_driver(armv7_pmu_driver);
-#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
deleted file mode 100644
index 7a2ba1c689a7..000000000000
--- a/arch/arm/kernel/perf_event_xscale.c
+++ /dev/null
@@ -1,748 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ARMv5 [xscale] Performance counter handling code.
- *
- * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com>
- *
- * Based on the previous xscale OProfile code.
- *
- * There are two variants of the xscale PMU that we support:
- * - xscale1pmu: 2 event counters and a cycle counter
- * - xscale2pmu: 4 event counters and a cycle counter
- * The two variants share event definitions, but have different
- * PMU structures.
- */
-
-#ifdef CONFIG_CPU_XSCALE
-
-#include <asm/cputype.h>
-#include <asm/irq_regs.h>
-
-#include <linux/of.h>
-#include <linux/perf/arm_pmu.h>
-#include <linux/platform_device.h>
-
-enum xscale_perf_types {
- XSCALE_PERFCTR_ICACHE_MISS = 0x00,
- XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01,
- XSCALE_PERFCTR_DATA_STALL = 0x02,
- XSCALE_PERFCTR_ITLB_MISS = 0x03,
- XSCALE_PERFCTR_DTLB_MISS = 0x04,
- XSCALE_PERFCTR_BRANCH = 0x05,
- XSCALE_PERFCTR_BRANCH_MISS = 0x06,
- XSCALE_PERFCTR_INSTRUCTION = 0x07,
- XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08,
- XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
- XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A,
- XSCALE_PERFCTR_DCACHE_MISS = 0x0B,
- XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C,
- XSCALE_PERFCTR_PC_CHANGED = 0x0D,
- XSCALE_PERFCTR_BCU_REQUEST = 0x10,
- XSCALE_PERFCTR_BCU_FULL = 0x11,
- XSCALE_PERFCTR_BCU_DRAIN = 0x12,
- XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14,
- XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15,
- XSCALE_PERFCTR_RMW = 0x16,
- /* XSCALE_PERFCTR_CCNT is not hardware defined */
- XSCALE_PERFCTR_CCNT = 0xFE,
- XSCALE_PERFCTR_UNUSED = 0xFF,
-};
-
-enum xscale_counters {
- XSCALE_CYCLE_COUNTER = 0,
- XSCALE_COUNTER0,
- XSCALE_COUNTER1,
- XSCALE_COUNTER2,
- XSCALE_COUNTER3,
-};
-
-static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
- PERF_MAP_ALL_UNSUPPORTED,
- [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
- [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
- [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = XSCALE_PERFCTR_ICACHE_NO_DELIVER,
-};
-
-static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- PERF_CACHE_MAP_ALL_UNSUPPORTED,
-
- [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
- [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
- [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
-
- [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
-
- [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
- [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
-
- [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
- [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
-};
-
-#define XSCALE_PMU_ENABLE 0x001
-#define XSCALE_PMN_RESET 0x002
-#define XSCALE_CCNT_RESET 0x004
-#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET)
-#define XSCALE_PMU_CNT64 0x008
-
-#define XSCALE1_OVERFLOWED_MASK 0x700
-#define XSCALE1_CCOUNT_OVERFLOW 0x400
-#define XSCALE1_COUNT0_OVERFLOW 0x100
-#define XSCALE1_COUNT1_OVERFLOW 0x200
-#define XSCALE1_CCOUNT_INT_EN 0x040
-#define XSCALE1_COUNT0_INT_EN 0x010
-#define XSCALE1_COUNT1_INT_EN 0x020
-#define XSCALE1_COUNT0_EVT_SHFT 12
-#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT)
-#define XSCALE1_COUNT1_EVT_SHFT 20
-#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT)
-
-static inline u32
-xscale1pmu_read_pmnc(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
- return val;
-}
-
-static inline void
-xscale1pmu_write_pmnc(u32 val)
-{
- /* upper 4bits and 7, 11 are write-as-0 */
- val &= 0xffff77f;
- asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
-}
-
-static inline int
-xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
- enum xscale_counters counter)
-{
- int ret = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
- break;
- case XSCALE_COUNTER0:
- ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
- break;
- case XSCALE_COUNTER1:
- ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
- }
-
- return ret;
-}
-
-static irqreturn_t
-xscale1pmu_handle_irq(struct arm_pmu *cpu_pmu)
-{
- unsigned long pmnc;
- struct perf_sample_data data;
- struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
- struct pt_regs *regs;
- int idx;
-
- /*
- * NOTE: there's an A stepping erratum that states if an overflow
- * bit already exists and another occurs, the previous
- * Overflow bit gets cleared. There's no workaround.
- * Fixed in B stepping or later.
- */
- pmnc = xscale1pmu_read_pmnc();
-
- /*
- * Write the value back to clear the overflow flags. Overflow
- * flags remain in pmnc for use below. We also disable the PMU
- * while we process the interrupt.
- */
- xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
-
- if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
- return IRQ_NONE;
-
- regs = get_irq_regs();
-
- for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- if (!event)
- continue;
-
- if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event);
- perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event))
- continue;
-
- if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(event);
- }
-
- irq_work_run();
-
- /*
- * Re-enable the PMU.
- */
- pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
- xscale1pmu_write_pmnc(pmnc);
-
- return IRQ_HANDLED;
-}
-
-static void xscale1pmu_enable_event(struct perf_event *event)
-{
- unsigned long val, mask, evt;
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- mask = 0;
- evt = XSCALE1_CCOUNT_INT_EN;
- break;
- case XSCALE_COUNTER0:
- mask = XSCALE1_COUNT0_EVT_MASK;
- evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
- XSCALE1_COUNT0_INT_EN;
- break;
- case XSCALE_COUNTER1:
- mask = XSCALE1_COUNT1_EVT_MASK;
- evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
- XSCALE1_COUNT1_INT_EN;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- val = xscale1pmu_read_pmnc();
- val &= ~mask;
- val |= evt;
- xscale1pmu_write_pmnc(val);
-}
-
-static void xscale1pmu_disable_event(struct perf_event *event)
-{
- unsigned long val, mask, evt;
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- mask = XSCALE1_CCOUNT_INT_EN;
- evt = 0;
- break;
- case XSCALE_COUNTER0:
- mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
- evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
- break;
- case XSCALE_COUNTER1:
- mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
- evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- val = xscale1pmu_read_pmnc();
- val &= ~mask;
- val |= evt;
- xscale1pmu_write_pmnc(val);
-}
-
-static int
-xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- if (XSCALE_PERFCTR_CCNT == hwc->config_base) {
- if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
- return -EAGAIN;
-
- return XSCALE_CYCLE_COUNTER;
- } else {
- if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask))
- return XSCALE_COUNTER1;
-
- if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask))
- return XSCALE_COUNTER0;
-
- return -EAGAIN;
- }
-}
-
-static void xscalepmu_clear_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- clear_bit(event->hw.idx, cpuc->used_mask);
-}
-
-static void xscale1pmu_start(struct arm_pmu *cpu_pmu)
-{
- unsigned long val;
-
- val = xscale1pmu_read_pmnc();
- val |= XSCALE_PMU_ENABLE;
- xscale1pmu_write_pmnc(val);
-}
-
-static void xscale1pmu_stop(struct arm_pmu *cpu_pmu)
-{
- unsigned long val;
-
- val = xscale1pmu_read_pmnc();
- val &= ~XSCALE_PMU_ENABLE;
- xscale1pmu_write_pmnc(val);
-}
-
-static inline u64 xscale1pmu_read_counter(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int counter = hwc->idx;
- u32 val = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
- break;
- }
-
- return val;
-}
-
-static inline void xscale1pmu_write_counter(struct perf_event *event, u64 val)
-{
- struct hw_perf_event *hwc = &event->hw;
- int counter = hwc->idx;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
- break;
- }
-}
-
-static int xscale_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &xscale_perf_map,
- &xscale_perf_cache_map, 0xFF);
-}
-
-static int xscale1pmu_init(struct arm_pmu *cpu_pmu)
-{
- cpu_pmu->name = "armv5_xscale1";
- cpu_pmu->handle_irq = xscale1pmu_handle_irq;
- cpu_pmu->enable = xscale1pmu_enable_event;
- cpu_pmu->disable = xscale1pmu_disable_event;
- cpu_pmu->read_counter = xscale1pmu_read_counter;
- cpu_pmu->write_counter = xscale1pmu_write_counter;
- cpu_pmu->get_event_idx = xscale1pmu_get_event_idx;
- cpu_pmu->clear_event_idx = xscalepmu_clear_event_idx;
- cpu_pmu->start = xscale1pmu_start;
- cpu_pmu->stop = xscale1pmu_stop;
- cpu_pmu->map_event = xscale_map_event;
- cpu_pmu->num_events = 3;
-
- return 0;
-}
-
-#define XSCALE2_OVERFLOWED_MASK 0x01f
-#define XSCALE2_CCOUNT_OVERFLOW 0x001
-#define XSCALE2_COUNT0_OVERFLOW 0x002
-#define XSCALE2_COUNT1_OVERFLOW 0x004
-#define XSCALE2_COUNT2_OVERFLOW 0x008
-#define XSCALE2_COUNT3_OVERFLOW 0x010
-#define XSCALE2_CCOUNT_INT_EN 0x001
-#define XSCALE2_COUNT0_INT_EN 0x002
-#define XSCALE2_COUNT1_INT_EN 0x004
-#define XSCALE2_COUNT2_INT_EN 0x008
-#define XSCALE2_COUNT3_INT_EN 0x010
-#define XSCALE2_COUNT0_EVT_SHFT 0
-#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT)
-#define XSCALE2_COUNT1_EVT_SHFT 8
-#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT)
-#define XSCALE2_COUNT2_EVT_SHFT 16
-#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT)
-#define XSCALE2_COUNT3_EVT_SHFT 24
-#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT)
-
-static inline u32
-xscale2pmu_read_pmnc(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
- /* bits 1-2 and 4-23 are read-unpredictable */
- return val & 0xff000009;
-}
-
-static inline void
-xscale2pmu_write_pmnc(u32 val)
-{
- /* bits 4-23 are write-as-0, 24-31 are write ignored */
- val &= 0xf;
- asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
-}
-
-static inline u32
-xscale2pmu_read_overflow_flags(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
- return val;
-}
-
-static inline void
-xscale2pmu_write_overflow_flags(u32 val)
-{
- asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
-}
-
-static inline u32
-xscale2pmu_read_event_select(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
- return val;
-}
-
-static inline void
-xscale2pmu_write_event_select(u32 val)
-{
- asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
-}
-
-static inline u32
-xscale2pmu_read_int_enable(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
- return val;
-}
-
-static void
-xscale2pmu_write_int_enable(u32 val)
-{
- asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
-}
-
-static inline int
-xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
- enum xscale_counters counter)
-{
- int ret = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
- break;
- case XSCALE_COUNTER0:
- ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
- break;
- case XSCALE_COUNTER1:
- ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
- break;
- case XSCALE_COUNTER2:
- ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
- break;
- case XSCALE_COUNTER3:
- ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
- }
-
- return ret;
-}
-
-static irqreturn_t
-xscale2pmu_handle_irq(struct arm_pmu *cpu_pmu)
-{
- unsigned long pmnc, of_flags;
- struct perf_sample_data data;
- struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
- struct pt_regs *regs;
- int idx;
-
- /* Disable the PMU. */
- pmnc = xscale2pmu_read_pmnc();
- xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
-
- /* Check the overflow flag register. */
- of_flags = xscale2pmu_read_overflow_flags();
- if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
- return IRQ_NONE;
-
- /* Clear the overflow bits. */
- xscale2pmu_write_overflow_flags(of_flags);
-
- regs = get_irq_regs();
-
- for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- if (!event)
- continue;
-
- if (!xscale2_pmnc_counter_has_overflowed(of_flags, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event);
- perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event))
- continue;
-
- if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(event);
- }
-
- irq_work_run();
-
- /*
- * Re-enable the PMU.
- */
- pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
- xscale2pmu_write_pmnc(pmnc);
-
- return IRQ_HANDLED;
-}
-
-static void xscale2pmu_enable_event(struct perf_event *event)
-{
- unsigned long ien, evtsel;
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- ien = xscale2pmu_read_int_enable();
- evtsel = xscale2pmu_read_event_select();
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- ien |= XSCALE2_CCOUNT_INT_EN;
- break;
- case XSCALE_COUNTER0:
- ien |= XSCALE2_COUNT0_INT_EN;
- evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
- break;
- case XSCALE_COUNTER1:
- ien |= XSCALE2_COUNT1_INT_EN;
- evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
- break;
- case XSCALE_COUNTER2:
- ien |= XSCALE2_COUNT2_INT_EN;
- evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
- break;
- case XSCALE_COUNTER3:
- ien |= XSCALE2_COUNT3_INT_EN;
- evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- xscale2pmu_write_event_select(evtsel);
- xscale2pmu_write_int_enable(ien);
-}
-
-static void xscale2pmu_disable_event(struct perf_event *event)
-{
- unsigned long ien, evtsel, of_flags;
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- ien = xscale2pmu_read_int_enable();
- evtsel = xscale2pmu_read_event_select();
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- ien &= ~XSCALE2_CCOUNT_INT_EN;
- of_flags = XSCALE2_CCOUNT_OVERFLOW;
- break;
- case XSCALE_COUNTER0:
- ien &= ~XSCALE2_COUNT0_INT_EN;
- evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
- of_flags = XSCALE2_COUNT0_OVERFLOW;
- break;
- case XSCALE_COUNTER1:
- ien &= ~XSCALE2_COUNT1_INT_EN;
- evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
- of_flags = XSCALE2_COUNT1_OVERFLOW;
- break;
- case XSCALE_COUNTER2:
- ien &= ~XSCALE2_COUNT2_INT_EN;
- evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
- of_flags = XSCALE2_COUNT2_OVERFLOW;
- break;
- case XSCALE_COUNTER3:
- ien &= ~XSCALE2_COUNT3_INT_EN;
- evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
- of_flags = XSCALE2_COUNT3_OVERFLOW;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- xscale2pmu_write_event_select(evtsel);
- xscale2pmu_write_int_enable(ien);
- xscale2pmu_write_overflow_flags(of_flags);
-}
-
-static int
-xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int idx = xscale1pmu_get_event_idx(cpuc, event);
- if (idx >= 0)
- goto out;
-
- if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
- idx = XSCALE_COUNTER3;
- else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
- idx = XSCALE_COUNTER2;
-out:
- return idx;
-}
-
-static void xscale2pmu_start(struct arm_pmu *cpu_pmu)
-{
- unsigned long val;
-
- val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
- val |= XSCALE_PMU_ENABLE;
- xscale2pmu_write_pmnc(val);
-}
-
-static void xscale2pmu_stop(struct arm_pmu *cpu_pmu)
-{
- unsigned long val;
-
- val = xscale2pmu_read_pmnc();
- val &= ~XSCALE_PMU_ENABLE;
- xscale2pmu_write_pmnc(val);
-}
-
-static inline u64 xscale2pmu_read_counter(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int counter = hwc->idx;
- u32 val = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER2:
- asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER3:
- asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
- break;
- }
-
- return val;
-}
-
-static inline void xscale2pmu_write_counter(struct perf_event *event, u64 val)
-{
- struct hw_perf_event *hwc = &event->hw;
- int counter = hwc->idx;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER2:
- asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER3:
- asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
- break;
- }
-}
-
-static int xscale2pmu_init(struct arm_pmu *cpu_pmu)
-{
- cpu_pmu->name = "armv5_xscale2";
- cpu_pmu->handle_irq = xscale2pmu_handle_irq;
- cpu_pmu->enable = xscale2pmu_enable_event;
- cpu_pmu->disable = xscale2pmu_disable_event;
- cpu_pmu->read_counter = xscale2pmu_read_counter;
- cpu_pmu->write_counter = xscale2pmu_write_counter;
- cpu_pmu->get_event_idx = xscale2pmu_get_event_idx;
- cpu_pmu->clear_event_idx = xscalepmu_clear_event_idx;
- cpu_pmu->start = xscale2pmu_start;
- cpu_pmu->stop = xscale2pmu_stop;
- cpu_pmu->map_event = xscale_map_event;
- cpu_pmu->num_events = 5;
-
- return 0;
-}
-
-static const struct pmu_probe_info xscale_pmu_probe_table[] = {
- XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V1, xscale1pmu_init),
- XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V2, xscale2pmu_init),
- { /* sentinel value */ }
-};
-
-static int xscale_pmu_device_probe(struct platform_device *pdev)
-{
- return arm_pmu_device_probe(pdev, NULL, xscale_pmu_probe_table);
-}
-
-static struct platform_driver xscale_pmu_driver = {
- .driver = {
- .name = "xscale-pmu",
- },
- .probe = xscale_pmu_device_probe,
-};
-
-builtin_platform_driver(xscale_pmu_driver);
-#endif /* CONFIG_CPU_XSCALE */
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index a86a1d4f3461..93afd1005b43 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -127,6 +127,10 @@ cpu_resume_after_mmu:
instr_sync
#endif
bl cpu_init @ restore the und/abt/irq banked regs
+#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
+ mov r0, sp
+ bl kasan_unpoison_task_stack_below
+#endif
mov r0, #0 @ return zero on success
ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_resume_after_mmu)
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index c3ec3861dd07..58a6441b58c4 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -12,6 +12,7 @@
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/tlbflush.h>
+#include <asm/uaccess.h>
extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid);
extern void cpu_resume_mmu(void);
@@ -27,6 +28,13 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
return -EINVAL;
/*
+ * Needed for the MMU disabling/enabing code to be able to run from
+ * TTBR0 addresses.
+ */
+ if (IS_ENABLED(CONFIG_CPU_TTBR0_PAN))
+ uaccess_save_and_enable();
+
+ /*
* Function graph tracer state gets incosistent when the kernel
* calls functions that never return (aka suspend finishers) hence
* disable graph tracing during their execution.
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index ef0058de432b..2336ee2aa44a 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -42,7 +42,7 @@
* can take this difference into account during load balance. A per cpu
* structure is preferred because each CPU updates its own cpu_capacity field
* during the load balance except for idle cores. One idle core is selected
- * to run the rebalance_domains for all idle cores and the cpu_capacity can be
+ * to run the sched_balance_domains for all idle cores and the cpu_capacity can be
* updated during this sequence.
*/
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 72c82a4d63ac..480e307501bb 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -26,6 +26,7 @@
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
#include <linux/irq.h>
+#include <linux/vmalloc.h>
#include <linux/atomic.h>
#include <asm/cacheflush.h>
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 650404be6768..0ca5aae1bcc3 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -40,8 +40,7 @@ $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S
$(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S
ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
- NEON_FLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
- CFLAGS_xor-neon.o += $(NEON_FLAGS)
+ CFLAGS_xor-neon.o += $(CC_FLAGS_FPU)
obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o
endif
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 6928781e6bee..c289bde04743 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -13,7 +13,8 @@
.text
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+#if defined(CONFIG_CPU_SW_DOMAIN_PAN)
+
.macro save_regs
mrc p15, 0, ip, c3, c0, 0
stmfd sp!, {r1, r2, r4 - r8, ip, lr}
@@ -25,7 +26,23 @@
mcr p15, 0, ip, c3, c0, 0
ret lr
.endm
+
+#elif defined(CONFIG_CPU_TTBR0_PAN)
+
+ .macro save_regs
+ mrc p15, 0, ip, c2, c0, 2 @ read TTBCR
+ stmfd sp!, {r1, r2, r4 - r8, ip, lr}
+ uaccess_enable ip
+ .endm
+
+ .macro load_regs
+ ldmfd sp!, {r1, r2, r4 - r8, ip, lr}
+ mcr p15, 0, ip, c2, c0, 2 @ restore TTBCR
+ ret lr
+ .endm
+
#else
+
.macro save_regs
stmfd sp!, {r1, r2, r4 - r8, lr}
.endm
@@ -33,6 +50,7 @@
.macro load_regs
ldmfd sp!, {r1, r2, r4 - r8, pc}
.endm
+
#endif
.macro load1b, reg1
diff --git a/arch/arm/lib/delay-loop.S b/arch/arm/lib/delay-loop.S
index 3ac05177d097..33b08ca1c242 100644
--- a/arch/arm/lib/delay-loop.S
+++ b/arch/arm/lib/delay-loop.S
@@ -5,6 +5,7 @@
* Copyright (C) 1995, 1996 Russell King
*/
#include <linux/linkage.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/delay.h>
@@ -24,21 +25,26 @@
* HZ <= 1000
*/
-ENTRY(__loop_udelay)
+SYM_TYPED_FUNC_START(__loop_udelay)
ldr r2, .LC1
mul r0, r2, r0 @ r0 = delay_us * UDELAY_MULT
-ENTRY(__loop_const_udelay) @ 0 <= r0 <= 0xfffffaf0
+ b __loop_const_udelay
+SYM_FUNC_END(__loop_udelay)
+
+SYM_TYPED_FUNC_START(__loop_const_udelay) @ 0 <= r0 <= 0xfffffaf0
ldr r2, .LC0
ldr r2, [r2]
umull r1, r0, r2, r0 @ r0-r1 = r0 * loops_per_jiffy
adds r1, r1, #0xffffffff @ rounding up ...
adcs r0, r0, r0 @ and right shift by 31
reteq lr
+ b __loop_delay
+SYM_FUNC_END(__loop_const_udelay)
.align 3
@ Delay routine
-ENTRY(__loop_delay)
+SYM_TYPED_FUNC_START(__loop_delay)
subs r0, r0, #1
#if 0
retls lr
@@ -58,6 +64,4 @@ ENTRY(__loop_delay)
#endif
bhi __loop_delay
ret lr
-ENDPROC(__loop_udelay)
-ENDPROC(__loop_const_udelay)
-ENDPROC(__loop_delay)
+SYM_FUNC_END(__loop_delay)
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 2f6163f05e93..c0ac7796d775 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -56,10 +56,10 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
* to see that it's still huge and whether or not we will
* need to fault on write.
*/
- if (unlikely(pmd_thp_or_huge(*pmd))) {
+ if (unlikely(pmd_leaf(*pmd))) {
ptl = &current->mm->page_table_lock;
spin_lock(ptl);
- if (unlikely(!pmd_thp_or_huge(*pmd)
+ if (unlikely(!pmd_leaf(*pmd)
|| pmd_hugewillfault(*pmd))) {
spin_unlock(ptl);
return 0;
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index 8aa39db095d7..2c5155bd376b 100644
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -61,7 +61,7 @@ static void davinci_pm_suspend(void)
/* Configure sleep count in deep sleep register */
val = __raw_readl(pm_config.deepsleep_reg);
- val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
+ val &= ~DEEPSLEEP_SLEEPCOUNT_MASK;
val |= pm_config.sleepcount;
__raw_writel(val, pm_config.deepsleep_reg);
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 25893d109190..b68cb86dbe4c 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -437,6 +437,7 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
{
*pmu_mmdc = (struct mmdc_pmu) {
.pmu = (struct pmu) {
+ .parent = dev,
.task_ctx_nr = perf_invalid_context,
.attr_groups = attr_groups,
.event_init = mmdc_pmu_event_init,
diff --git a/arch/arm/mach-orion5x/board-d2net.c b/arch/arm/mach-orion5x/board-d2net.c
index 0297e302d7bc..09bf366d05ff 100644
--- a/arch/arm/mach-orion5x/board-d2net.c
+++ b/arch/arm/mach-orion5x/board-d2net.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/leds.h>
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
@@ -55,12 +56,9 @@ static struct gpio_led d2net_leds[] = {
{
.name = "d2net:blue:sata",
.default_trigger = "default-on",
- .gpio = D2NET_GPIO_BLUE_LED_OFF,
- .active_low = 1,
},
{
.name = "d2net:red:fail",
- .gpio = D2NET_GPIO_RED_LED,
},
};
@@ -77,6 +75,17 @@ static struct platform_device d2net_gpio_leds = {
},
};
+static struct gpiod_lookup_table d2net_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", D2NET_GPIO_BLUE_LED_OFF, NULL,
+ 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", D2NET_GPIO_RED_LED, NULL,
+ 1, GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
static void __init d2net_gpio_leds_init(void)
{
int err;
@@ -91,6 +100,7 @@ static void __init d2net_gpio_leds_init(void)
if (err)
pr_err("d2net: failed to configure blue LED blink GPIO\n");
+ gpiod_add_lookup_table(&d2net_leds_gpio_table);
platform_device_register(&d2net_gpio_leds);
}
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index d69259b6b60d..062109efa0ec 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -14,6 +14,7 @@
*
*/
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -254,37 +255,64 @@ error_fail:
static struct gpio_led dns323ab_leds[] = {
{
.name = "power:blue",
- .gpio = DNS323_GPIO_LED_POWER2,
.default_trigger = "default-on",
}, {
.name = "right:amber",
- .gpio = DNS323_GPIO_LED_RIGHT_AMBER,
- .active_low = 1,
}, {
.name = "left:amber",
- .gpio = DNS323_GPIO_LED_LEFT_AMBER,
- .active_low = 1,
},
};
+static struct gpiod_lookup_table dns323a1_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_POWER2, NULL,
+ 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_RIGHT_AMBER, NULL,
+ 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_LEFT_AMBER, NULL,
+ 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+/* B1 is the same but power LED is active high */
+static struct gpiod_lookup_table dns323b1_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_POWER2, NULL,
+ 0, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_RIGHT_AMBER, NULL,
+ 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_LEFT_AMBER, NULL,
+ 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
static struct gpio_led dns323c_leds[] = {
{
.name = "power:blue",
- .gpio = DNS323C_GPIO_LED_POWER,
.default_trigger = "timer",
- .active_low = 1,
}, {
.name = "right:amber",
- .gpio = DNS323C_GPIO_LED_RIGHT_AMBER,
- .active_low = 1,
}, {
.name = "left:amber",
- .gpio = DNS323C_GPIO_LED_LEFT_AMBER,
- .active_low = 1,
},
};
+static struct gpiod_lookup_table dns323c_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_POWER, NULL,
+ 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_RIGHT_AMBER, NULL,
+ 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_LEFT_AMBER, NULL,
+ 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
static struct gpio_led_platform_data dns323ab_led_data = {
.num_leds = ARRAY_SIZE(dns323ab_leds),
@@ -621,16 +649,21 @@ static void __init dns323_init(void)
/* The 5181 power LED is active low and requires
* DNS323_GPIO_LED_POWER1 to also be low.
*/
- dns323ab_leds[0].active_low = 1;
- gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
- gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
- fallthrough;
+ gpiod_add_lookup_table(&dns323a1_leds_gpio_table);
+ gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
+ gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
+ i2c_register_board_info(0, dns323ab_i2c_devices,
+ ARRAY_SIZE(dns323ab_i2c_devices));
+
+ break;
case DNS323_REV_B1:
+ gpiod_add_lookup_table(&dns323b1_leds_gpio_table);
i2c_register_board_info(0, dns323ab_i2c_devices,
ARRAY_SIZE(dns323ab_i2c_devices));
break;
case DNS323_REV_C1:
/* Hookup LEDs & Buttons */
+ gpiod_add_lookup_table(&dns323c_leds_gpio_table);
dns323_gpio_leds.dev.platform_data = &dns323c_led_data;
dns323_button_device.dev.platform_data = &dns323c_button_data;
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
index 2bf8ec75e908..b7327a612835 100644
--- a/arch/arm/mach-orion5x/mv2120-setup.c
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -8,6 +8,7 @@
* License, or (at your option) any later version.
*/
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
@@ -139,34 +140,45 @@ static struct i2c_board_info __initdata mv2120_i2c_rtc = {
static struct gpio_led mv2120_led_pins[] = {
{
.name = "mv2120:blue:health",
- .gpio = 0,
},
{
.name = "mv2120:red:health",
- .gpio = 1,
},
{
.name = "mv2120:led:bright",
- .gpio = 4,
.default_trigger = "default-on",
},
{
.name = "mv2120:led:dimmed",
- .gpio = 5,
},
{
.name = "mv2120:red:sata0",
- .gpio = 8,
- .active_low = 1,
},
{
.name = "mv2120:red:sata1",
- .gpio = 9,
- .active_low = 1,
},
};
+static struct gpiod_lookup_table mv2120_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", 0, NULL,
+ 0, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", 1, NULL,
+ 1, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", 4, NULL,
+ 2, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", 5, NULL,
+ 3, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", 8, NULL,
+ 4, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", 9, NULL,
+ 5, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct gpio_led_platform_data mv2120_led_data = {
.leds = mv2120_led_pins,
.num_leds = ARRAY_SIZE(mv2120_led_pins),
@@ -219,6 +231,7 @@ static void __init mv2120_init(void)
gpio_free(MV2120_GPIO_RTC_IRQ);
}
i2c_register_board_info(0, &mv2120_i2c_rtc, 1);
+ gpiod_add_lookup_table(&mv2120_leds_gpio_table);
platform_device_register(&mv2120_leds);
/* register mv2120 specific power-off method */
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
index 695cc683cd83..6ad9740b426b 100644
--- a/arch/arm/mach-orion5x/net2big-setup.c
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -18,6 +18,7 @@
#include <linux/i2c.h>
#include <linux/ata_platform.h>
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/delay.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -214,19 +215,30 @@ err_free_1:
static struct gpio_led net2big_leds[] = {
{
.name = "net2big:red:power",
- .gpio = NET2BIG_GPIO_PWR_RED_LED,
},
{
.name = "net2big:blue:power",
- .gpio = NET2BIG_GPIO_PWR_BLUE_LED,
},
{
.name = "net2big:red:sata0",
- .gpio = NET2BIG_GPIO_SATA0_RED_LED,
},
{
.name = "net2big:red:sata1",
- .gpio = NET2BIG_GPIO_SATA1_RED_LED,
+ },
+};
+
+static struct gpiod_lookup_table net2big_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_PWR_RED_LED, NULL,
+ 0, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_PWR_BLUE_LED, NULL,
+ 1, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_SATA0_RED_LED, NULL,
+ 2, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_SATA1_RED_LED, NULL,
+ 3, GPIO_ACTIVE_HIGH),
+ { },
},
};
@@ -282,6 +294,7 @@ static void __init net2big_gpio_leds_init(void)
if (err)
pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
+ gpiod_add_lookup_table(&net2big_leds_gpio_table);
platform_device_register(&net2big_gpio_leds);
}
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
index 6f60dc1dfa22..8131982c10d9 100644
--- a/arch/arm/mach-orion5x/ts409-setup.c
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -8,6 +8,7 @@
* Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
*/
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
@@ -168,20 +169,27 @@ static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
static struct gpio_led ts409_led_pins[] = {
{
.name = "ts409:red:sata1",
- .gpio = 4,
- .active_low = 1,
}, {
.name = "ts409:red:sata2",
- .gpio = 5,
- .active_low = 1,
}, {
.name = "ts409:red:sata3",
- .gpio = 6,
- .active_low = 1,
}, {
.name = "ts409:red:sata4",
- .gpio = 7,
- .active_low = 1,
+ },
+};
+
+static struct gpiod_lookup_table ts409_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("orion_gpio0", 4, NULL,
+ 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", 5, NULL,
+ 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", 6, NULL,
+ 2, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("orion_gpio0", 7, NULL,
+ 3, GPIO_ACTIVE_LOW),
+ { },
},
};
@@ -300,6 +308,7 @@ static void __init qnap_ts409_init(void)
if (qnap_ts409_i2c_rtc.irq == 0)
pr_warn("qnap_ts409_init: failed to get RTC IRQ\n");
i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
+ gpiod_add_lookup_table(&ts409_leds_gpio_table);
platform_device_register(&ts409_leds);
/* register tsx09 specific power-off method */
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 661b3fc43275..7695cfce01a1 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -7,7 +7,7 @@
#include <linux/clk-provider.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
-#include <linux/spi/pxa2xx_spi.h>
+#include <linux/gpio-pxa.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/soc/pxa/cpu.h>
@@ -18,6 +18,7 @@
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/mmp_dma.h>
+#include "mfp-pxa2xx.h"
#include "regs-ost.h"
#include "reset.h"
#include "devices.h"
@@ -47,7 +48,7 @@ struct platform_device pxa_device_pmu = {
.num_resources = 1,
};
-static struct resource pxamci_resources[] = {
+static const struct resource pxamci_resources[] = {
[0] = {
.start = 0x41100000,
.end = 0x41100fff,
@@ -60,22 +61,26 @@ static struct resource pxamci_resources[] = {
},
};
-static u64 pxamci_dmamask = 0xffffffffUL;
-
-struct platform_device pxa_device_mci = {
- .name = "pxa2xx-mci",
- .id = 0,
- .dev = {
- .dma_mask = &pxamci_dmamask,
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(pxamci_resources),
- .resource = pxamci_resources,
-};
-
-void __init pxa_set_mci_info(struct pxamci_platform_data *info)
+void __init pxa_set_mci_info(const struct pxamci_platform_data *info,
+ const struct property_entry *props)
{
- pxa_register_device(&pxa_device_mci, info);
+ const struct platform_device_info mci_info = {
+ .name = "pxa2xx-mci",
+ .id = 0,
+ .res = pxamci_resources,
+ .num_res = ARRAY_SIZE(pxamci_resources),
+ .data = info,
+ .size_data = sizeof(*info),
+ .dma_mask = 0xffffffffUL,
+ .properties = props,
+ };
+ struct platform_device *mci_dev;
+ int err;
+
+ mci_dev = platform_device_register_full(&mci_info);
+ err = PTR_ERR_OR_ZERO(mci_dev);
+ if (err)
+ pr_err("Unable to create mci device: %d\n", err);
}
static struct pxa2xx_udc_mach_info pxa_udc_info = {
@@ -628,6 +633,11 @@ struct platform_device pxa27x_device_pwm1 = {
};
#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
+const struct software_node pxa2xx_gpiochip_node = {
+ .name = "gpio-pxa",
+};
+
struct resource pxa_resource_gpio[] = {
{
.start = 0x40e00000,
@@ -651,11 +661,19 @@ struct resource pxa_resource_gpio[] = {
},
};
+static struct pxa_gpio_platform_data pxa2xx_gpio_info = {
+ .irq_base = PXA_GPIO_TO_IRQ(0),
+ .gpio_set_wake = gpio_set_wake,
+};
+
struct platform_device pxa25x_device_gpio = {
.name = "pxa25x-gpio",
.id = -1,
.num_resources = ARRAY_SIZE(pxa_resource_gpio),
.resource = pxa_resource_gpio,
+ .dev = {
+ .platform_data = &pxa2xx_gpio_info,
+ },
};
struct platform_device pxa27x_device_gpio = {
@@ -663,24 +681,11 @@ struct platform_device pxa27x_device_gpio = {
.id = -1,
.num_resources = ARRAY_SIZE(pxa_resource_gpio),
.resource = pxa_resource_gpio,
+ .dev = {
+ .platform_data = &pxa2xx_gpio_info,
+ },
};
-
-/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
- * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
-void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_controller *info)
-{
- struct platform_device *pd;
-
- pd = platform_device_alloc("pxa2xx-spi", id);
- if (pd == NULL) {
- printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n",
- id);
- return;
- }
-
- pd->dev.platform_data = info;
- platform_device_add(pd);
-}
+#endif /* CONFIG_PXA25x || CONFIG_PXA27x */
static struct resource pxa_dma_resource[] = {
[0] = {
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 82c83939017a..72c556ff67db 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -4,7 +4,6 @@
struct mmp_dma_platdata;
extern struct platform_device pxa_device_pmu;
-extern struct platform_device pxa_device_mci;
extern struct platform_device pxa3xx_device_mci2;
extern struct platform_device pxa3xx_device_mci3;
extern struct platform_device pxa25x_device_udc;
@@ -53,8 +52,8 @@ extern struct platform_device pxa_device_asoc_ssp4;
extern struct platform_device pxa25x_device_gpio;
extern struct platform_device pxa27x_device_gpio;
-extern struct platform_device pxa3xx_device_gpio;
-extern struct platform_device pxa93x_device_gpio;
+
+extern const struct software_node pxa2xx_gpiochip_node;
void __init pxa_register_device(struct platform_device *dev, void *data);
void __init pxa2xx_set_dmac_info(struct mmp_dma_platdata *dma_pdata);
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index c9f0f62187bd..efa6faa62a2c 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -90,7 +90,7 @@ static struct pxamci_platform_data gumstix_mci_platform_data = {
static void __init gumstix_mmc_init(void)
{
- pxa_set_mci_info(&gumstix_mci_platform_data);
+ pxa_set_mci_info(&gumstix_mci_platform_data, NULL);
}
#else
static void __init gumstix_mmc_init(void)
@@ -100,26 +100,22 @@ static void __init gumstix_mmc_init(void)
#endif
#ifdef CONFIG_USB_PXA25X
-static struct gpiod_lookup_table gumstix_gpio_vbus_gpiod_table = {
- .dev_id = "gpio-vbus",
- .table = {
- GPIO_LOOKUP("gpio-pxa", GPIO_GUMSTIX_USB_GPIOn,
- "vbus", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("gpio-pxa", GPIO_GUMSTIX_USB_GPIOx,
- "pullup", GPIO_ACTIVE_HIGH),
- { },
- },
+static const struct property_entry spitz_mci_props[] __initconst = {
+ PROPERTY_ENTRY_GPIO("vbus-gpios", &pxa2xx_gpiochip_node,
+ GPIO_GUMSTIX_USB_GPIOn, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("pullup-gpios", &pxa2xx_gpiochip_node,
+ GPIO_GUMSTIX_USB_GPIOx, GPIO_ACTIVE_HIGH),
+ { }
};
-static struct platform_device gumstix_gpio_vbus = {
+static const struct platform_device_info gumstix_gpio_vbus_info __initconst = {
.name = "gpio-vbus",
- .id = -1,
+ .id = PLATFORM_DEVID_NONE,
};
static void __init gumstix_udc_init(void)
{
- gpiod_add_lookup_table(&gumstix_gpio_vbus_gpiod_table);
- platform_device_register(&gumstix_gpio_vbus);
+ platform_device_register_full(&gumstix_gpio_vbus_info);
}
#else
static void gumstix_udc_init(void)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 02712d24be82..03e34841fc00 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -178,12 +178,8 @@ void __init pxa25x_map_io(void)
pxa25x_get_clk_frequency_khz(1);
}
-static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
- .irq_base = PXA_GPIO_TO_IRQ(0),
- .gpio_set_wake = gpio_set_wake,
-};
-
static struct platform_device *pxa25x_devices[] __initdata = {
+ &pxa25x_device_gpio,
&pxa25x_device_udc,
&pxa_device_pmu,
&pxa_device_i2s,
@@ -243,8 +239,8 @@ static int __init pxa25x_init(void)
register_syscore_ops(&pxa2xx_mfp_syscore_ops);
if (!of_have_populated_dt()) {
+ software_node_register(&pxa2xx_gpiochip_node);
pxa2xx_set_dmac_info(&pxa25x_dma_pdata);
- pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
ret = platform_add_devices(pxa25x_devices,
ARRAY_SIZE(pxa25x_devices));
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index d71491e2e1d6..f8382477d629 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -276,12 +276,8 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
pxa_register_device(&pxa27x_device_i2c_power, info);
}
-static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
- .irq_base = PXA_GPIO_TO_IRQ(0),
- .gpio_set_wake = gpio_set_wake,
-};
-
static struct platform_device *devices[] __initdata = {
+ &pxa27x_device_gpio,
&pxa27x_device_udc,
&pxa_device_pmu,
&pxa_device_i2s,
@@ -345,8 +341,7 @@ static int __init pxa27x_init(void)
register_syscore_ops(&pxa2xx_mfp_syscore_ops);
if (!of_have_populated_dt()) {
- pxa_register_device(&pxa27x_device_gpio,
- &pxa27x_gpio_info);
+ software_node_register(&pxa2xx_gpiochip_node);
pxa2xx_set_dmac_info(&pxa27x_dma_pdata);
ret = platform_add_devices(devices,
ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index cc691b199429..452bf7aac1fa 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -14,20 +14,22 @@
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
+#include <linux/gpio/property.h>
#include <linux/leds.h>
#include <linux/i2c.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/pca953x.h>
+#include <linux/property.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/corgi_lcd.h>
-#include <linux/spi/pxa2xx_spi.h>
#include <linux/mtd/sharpsl.h>
#include <linux/mtd/physmap.h>
#include <linux/input-event-codes.h>
#include <linux/input/matrix_keypad.h>
#include <linux/regulator/machine.h>
#include <linux/io.h>
+#include <linux/property.h>
#include <linux/reboot.h>
#include <linux/memblock.h>
@@ -128,6 +130,19 @@ static unsigned long spitz_pin_config[] __initdata = {
GPIO1_GPIO | WAKEUP_ON_EDGE_FALL, /* SPITZ_GPIO_RESET */
};
+static const struct software_node spitz_scoop_1_gpiochip_node = {
+ .name = "sharp-scoop.0",
+};
+
+/* Only on Spitz */
+static const struct software_node spitz_scoop_2_gpiochip_node = {
+ .name = "sharp-scoop.1",
+};
+
+/* Only on Akita */
+static const struct software_node akita_max7310_gpiochip_node = {
+ .name = "i2c-max7310",
+};
/******************************************************************************
* Scoop GPIO expander
@@ -452,35 +467,64 @@ static inline void spitz_keys_init(void) {}
* LEDs
******************************************************************************/
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-static struct gpio_led spitz_gpio_leds[] = {
- {
- .name = "spitz:amber:charge",
- .default_trigger = "sharpsl-charge",
- .gpio = SPITZ_GPIO_LED_ORANGE,
- },
- {
- .name = "spitz:green:hddactivity",
- .default_trigger = "disk-activity",
- .gpio = SPITZ_GPIO_LED_GREEN,
- },
+static const struct software_node spitz_gpio_leds_node = {
+ .name = "spitz-leds",
};
-static struct gpio_led_platform_data spitz_gpio_leds_info = {
- .leds = spitz_gpio_leds,
- .num_leds = ARRAY_SIZE(spitz_gpio_leds),
+static const struct property_entry spitz_orange_led_props[] = {
+ PROPERTY_ENTRY_STRING("linux,default-trigger", "sharpsl-charge"),
+ PROPERTY_ENTRY_GPIO("gpios",
+ &spitz_scoop_1_gpiochip_node, 6, GPIO_ACTIVE_HIGH),
+ { }
};
-static struct platform_device spitz_led_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &spitz_gpio_leds_info,
- },
+static const struct software_node spitz_orange_led_node = {
+ .name = "spitz:amber:charge",
+ .parent = &spitz_gpio_leds_node,
+ .properties = spitz_orange_led_props,
+};
+
+static const struct property_entry spitz_green_led_props[] = {
+ PROPERTY_ENTRY_STRING("linux,default-trigger", "disk-activity"),
+ PROPERTY_ENTRY_GPIO("gpios",
+ &spitz_scoop_1_gpiochip_node, 0, GPIO_ACTIVE_HIGH),
+ { }
+};
+
+static const struct software_node spitz_green_led_node = {
+ .name = "spitz:green:hddactivity",
+ .parent = &spitz_gpio_leds_node,
+ .properties = spitz_green_led_props,
+};
+
+static const struct software_node *spitz_gpio_leds_swnodes[] = {
+ &spitz_gpio_leds_node,
+ &spitz_orange_led_node,
+ &spitz_green_led_node,
+ NULL
};
static void __init spitz_leds_init(void)
{
- platform_device_register(&spitz_led_device);
+ struct platform_device_info led_info = {
+ .name = "leds-gpio",
+ .id = PLATFORM_DEVID_NONE,
+ };
+ struct platform_device *led_dev;
+ int err;
+
+ err = software_node_register_node_group(spitz_gpio_leds_swnodes);
+ if (err) {
+ pr_err("failed to register LED software nodes: %d\n", err);
+ return;
+ }
+
+ led_info.fwnode = software_node_fwnode(&spitz_gpio_leds_node);
+
+ led_dev = platform_device_register_full(&led_info);
+ err = PTR_ERR_OR_ZERO(led_dev);
+ if (err)
+ pr_err("failed to create LED device: %d\n", err);
}
#else
static inline void spitz_leds_init(void) {}
@@ -490,53 +534,43 @@ static inline void spitz_leds_init(void) {}
* SSP Devices
******************************************************************************/
#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
-static void spitz_ads7846_wait_for_hsync(void)
-{
- while (gpio_get_value(SPITZ_GPIO_HSYNC))
- cpu_relax();
- while (!gpio_get_value(SPITZ_GPIO_HSYNC))
- cpu_relax();
-}
+static const struct property_entry spitz_ads7846_props[] = {
+ PROPERTY_ENTRY_STRING("compatible", "ti,ads7846"),
+ PROPERTY_ENTRY_U32("touchscreen-max-pressure", 1024),
+ PROPERTY_ENTRY_U16("ti,x-plate-ohms", 419),
+ PROPERTY_ENTRY_U16("ti,y-plate-ohms", 486),
+ PROPERTY_ENTRY_U16("ti,vref-delay-usecs", 100),
+ PROPERTY_ENTRY_GPIO("pendown-gpios", &pxa2xx_gpiochip_node,
+ SPITZ_GPIO_TP_INT, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("ti,hsync-gpios", &pxa2xx_gpiochip_node,
+ SPITZ_GPIO_HSYNC, GPIO_ACTIVE_LOW),
+ { }
+};
-static struct ads7846_platform_data spitz_ads7846_info = {
- .model = 7846,
- .vref_delay_usecs = 100,
- .x_plate_ohms = 419,
- .y_plate_ohms = 486,
- .pressure_max = 1024,
- .wait_for_sync = spitz_ads7846_wait_for_hsync,
+static const struct software_node spitz_ads7846_swnode = {
+ .name = "ads7846",
+ .properties = spitz_ads7846_props,
};
-static struct gpiod_lookup_table spitz_ads7846_gpio_table = {
- .dev_id = "spi2.0",
- .table = {
- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_TP_INT,
- "pendown", GPIO_ACTIVE_LOW),
- { }
- },
+static const struct property_entry spitz_lcdcon_props[] = {
+ PROPERTY_ENTRY_GPIO("BL_CONT-gpios",
+ &spitz_scoop_2_gpiochip_node, 6, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("BL_ON-gpios",
+ &spitz_scoop_2_gpiochip_node, 7, GPIO_ACTIVE_HIGH),
+ { }
};
-static struct gpiod_lookup_table spitz_lcdcon_gpio_table = {
- .dev_id = "spi2.1",
- .table = {
- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_CONT,
- "BL_CONT", GPIO_ACTIVE_LOW),
- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_ON,
- "BL_ON", GPIO_ACTIVE_HIGH),
- { },
- },
+static const struct property_entry akita_lcdcon_props[] = {
+ PROPERTY_ENTRY_GPIO("BL_ON-gpios",
+ &akita_max7310_gpiochip_node, 3, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("BL_CONT-gpios",
+ &akita_max7310_gpiochip_node, 4, GPIO_ACTIVE_LOW),
+ { }
};
-static struct gpiod_lookup_table akita_lcdcon_gpio_table = {
- .dev_id = "spi2.1",
- .table = {
- GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_CONT,
- "BL_CONT", GPIO_ACTIVE_LOW),
- GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_ON,
- "BL_ON", GPIO_ACTIVE_HIGH),
- { },
- },
+static struct software_node spitz_lcdcon_node = {
+ .name = "spitz-lcdcon",
};
static struct corgi_lcd_platform_data spitz_lcdcon_info = {
@@ -553,7 +587,7 @@ static struct spi_board_info spitz_spi_devices[] = {
.max_speed_hz = 1200000,
.bus_num = 2,
.chip_select = 0,
- .platform_data = &spitz_ads7846_info,
+ .swnode = &spitz_ads7846_swnode,
.irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
}, {
.modalias = "corgi-lcd",
@@ -561,6 +595,7 @@ static struct spi_board_info spitz_spi_devices[] = {
.bus_num = 2,
.chip_select = 1,
.platform_data = &spitz_lcdcon_info,
+ .swnode = &spitz_lcdcon_node,
}, {
.modalias = "max1111",
.max_speed_hz = 450000,
@@ -569,30 +604,40 @@ static struct spi_board_info spitz_spi_devices[] = {
},
};
-static struct pxa2xx_spi_controller spitz_spi_info = {
- .num_chipselect = 3,
+static const struct software_node_ref_args spitz_spi_gpio_refs[] = {
+ SOFTWARE_NODE_REFERENCE(&pxa2xx_gpiochip_node, SPITZ_GPIO_ADS7846_CS,
+ GPIO_ACTIVE_LOW),
+ SOFTWARE_NODE_REFERENCE(&pxa2xx_gpiochip_node, SPITZ_GPIO_LCDCON_CS,
+ GPIO_ACTIVE_LOW),
+ SOFTWARE_NODE_REFERENCE(&pxa2xx_gpiochip_node, SPITZ_GPIO_MAX1111_CS,
+ GPIO_ACTIVE_LOW),
};
-static struct gpiod_lookup_table spitz_spi_gpio_table = {
- .dev_id = "spi2",
- .table = {
- GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
- { },
- },
+static const struct property_entry spitz_spi_properties[] = {
+ PROPERTY_ENTRY_REF_ARRAY("gpios", spitz_spi_gpio_refs),
+ { }
+};
+
+static const struct platform_device_info spitz_spi_device_info = {
+ .name = "pxa2xx-spi",
+ /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1 */
+ .id = 2,
+ .properties = spitz_spi_properties,
};
static void __init spitz_spi_init(void)
{
- if (machine_is_akita())
- gpiod_add_lookup_table(&akita_lcdcon_gpio_table);
- else
- gpiod_add_lookup_table(&spitz_lcdcon_gpio_table);
+ struct platform_device *pd;
+ int err;
- gpiod_add_lookup_table(&spitz_ads7846_gpio_table);
- gpiod_add_lookup_table(&spitz_spi_gpio_table);
- pxa2xx_set_spi_info(2, &spitz_spi_info);
+ pd = platform_device_register_full(&spitz_spi_device_info);
+ err = PTR_ERR_OR_ZERO(pd);
+ if (err)
+ pr_err("pxa2xx-spi: failed to instantiate SPI controller: %d\n",
+ err);
+
+ spitz_lcdcon_node.properties = machine_is_akita() ?
+ akita_lcdcon_props : spitz_lcdcon_props;
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
}
#else
@@ -625,21 +670,17 @@ static struct pxamci_platform_data spitz_mci_platform_data = {
.setpower = spitz_mci_setpower,
};
-static struct gpiod_lookup_table spitz_mci_gpio_table = {
- .dev_id = "pxa2xx-mci.0",
- .table = {
- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_nSD_DETECT,
- "cd", GPIO_ACTIVE_LOW),
- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_nSD_WP,
- "wp", GPIO_ACTIVE_LOW),
- { },
- },
+static const struct property_entry spitz_mci_props[] __initconst = {
+ PROPERTY_ENTRY_GPIO("cd-gpios", &pxa2xx_gpiochip_node,
+ SPITZ_GPIO_nSD_DETECT, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("wp-gpios", &pxa2xx_gpiochip_node,
+ SPITZ_GPIO_nSD_WP, GPIO_ACTIVE_LOW),
+ { }
};
static void __init spitz_mmc_init(void)
{
- gpiod_add_lookup_table(&spitz_mci_gpio_table);
- pxa_set_mci_info(&spitz_mci_platform_data);
+ pxa_set_mci_info(&spitz_mci_platform_data, spitz_mci_props);
}
#else
static inline void spitz_mmc_init(void) {}
@@ -938,30 +979,24 @@ static void __init spitz_i2c_init(void)
static inline void spitz_i2c_init(void) {}
#endif
-static struct gpiod_lookup_table spitz_audio_gpio_table = {
- .dev_id = "spitz-audio",
- .table = {
- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_L - SPITZ_SCP_GPIO_BASE,
- "mute-l", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_R - SPITZ_SCP_GPIO_BASE,
- "mute-r", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("sharp-scoop.1", SPITZ_GPIO_MIC_BIAS - SPITZ_SCP2_GPIO_BASE,
- "mic", GPIO_ACTIVE_HIGH),
- { },
- },
+static const struct property_entry spitz_audio_props[] = {
+ PROPERTY_ENTRY_GPIO("mute-l-gpios", &spitz_scoop_1_gpiochip_node, 3,
+ GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("mute-r-gpios", &spitz_scoop_1_gpiochip_node, 4,
+ GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("mic-gpios", &spitz_scoop_2_gpiochip_node, 8,
+ GPIO_ACTIVE_HIGH),
+ { }
};
-static struct gpiod_lookup_table akita_audio_gpio_table = {
- .dev_id = "spitz-audio",
- .table = {
- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_L - SPITZ_SCP_GPIO_BASE,
- "mute-l", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_R - SPITZ_SCP_GPIO_BASE,
- "mute-r", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("i2c-max7310", AKITA_GPIO_MIC_BIAS - AKITA_IOEXP_GPIO_BASE,
- "mic", GPIO_ACTIVE_HIGH),
- { },
- },
+static const struct property_entry akita_audio_props[] = {
+ PROPERTY_ENTRY_GPIO("mute-l-gpios", &spitz_scoop_1_gpiochip_node, 3,
+ GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("mute-r-gpios", &spitz_scoop_1_gpiochip_node, 4,
+ GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("mic-gpios", &akita_max7310_gpiochip_node, 2,
+ GPIO_ACTIVE_HIGH),
+ { }
};
/******************************************************************************
@@ -969,12 +1004,14 @@ static struct gpiod_lookup_table akita_audio_gpio_table = {
******************************************************************************/
static inline void spitz_audio_init(void)
{
- if (machine_is_akita())
- gpiod_add_lookup_table(&akita_audio_gpio_table);
- else
- gpiod_add_lookup_table(&spitz_audio_gpio_table);
-
- platform_device_register_simple("spitz-audio", -1, NULL, 0);
+ struct platform_device_info audio_info = {
+ .name = "spitz-audio",
+ .id = PLATFORM_DEVID_NONE,
+ .properties = machine_is_akita() ?
+ akita_audio_props : spitz_audio_props,
+ };
+
+ platform_device_register_full(&audio_info);
}
/******************************************************************************
@@ -997,6 +1034,12 @@ static void spitz_restart(enum reboot_mode mode, const char *cmd)
static void __init spitz_init(void)
{
+ software_node_register(&spitz_scoop_1_gpiochip_node);
+ if (machine_is_akita())
+ software_node_register(&akita_max7310_gpiochip_node);
+ else
+ software_node_register(&spitz_scoop_2_gpiochip_node);
+
init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
pm_power_off = spitz_poweroff;
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 8bc4ea51a0c1..03b4b347f11a 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -35,18 +35,20 @@
static int spitz_last_ac_status;
-static struct gpio spitz_charger_gpios[] = {
- { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" },
- { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" },
- { SPITZ_GPIO_AC_IN, GPIOF_IN, "Charger Detection" },
- { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
- { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" },
- { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" },
-};
-
static void spitz_charger_init(void)
{
- gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
+ gpio_request(SPITZ_GPIO_KEY_INT, "Keyboard Interrupt");
+ gpio_direction_input(SPITZ_GPIO_KEY_INT);
+ gpio_request(SPITZ_GPIO_SYNC, "Sync");
+ gpio_direction_input(SPITZ_GPIO_SYNC);
+ gpio_request(SPITZ_GPIO_AC_IN, "Charger Detection");
+ gpio_direction_input(SPITZ_GPIO_AC_IN);
+ gpio_request(SPITZ_GPIO_ADC_TEMP_ON, "ADC Temp On");
+ gpio_direction_output(SPITZ_GPIO_ADC_TEMP_ON, 0);
+ gpio_request(SPITZ_GPIO_JK_B, "JK B");
+ gpio_direction_output(SPITZ_GPIO_JK_B, 0);
+ gpio_request(SPITZ_GPIO_CHRG_ON, "Charger On");
+ gpio_direction_output(SPITZ_GPIO_CHRG_ON, 0);
}
static void spitz_measure_temp(int on)
diff --git a/arch/arm/mach-s3c/Makefile b/arch/arm/mach-s3c/Makefile
index 713827bef831..988c49672715 100644
--- a/arch/arm/mach-s3c/Makefile
+++ b/arch/arm/mach-s3c/Makefile
@@ -2,7 +2,7 @@
#
# Copyright 2009 Simtec Electronics
-include $(srctree)/$(src)/Makefile.s3c64xx
+include $(src)/Makefile.s3c64xx
# Objects we always build independent of SoC choice
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 5e25dfa752e9..1cfc0b1fa41c 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -20,16 +20,6 @@
#include "generic.h"
-/*
- * helper for sa1100fb
- */
-static struct gpio h3600_lcd_gpio[] = {
- { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD power" },
- { H3600_EGPIO_LCD_PCI, GPIOF_OUT_INIT_LOW, "LCD control" },
- { H3600_EGPIO_LCD_5V_ON, GPIOF_OUT_INIT_LOW, "LCD 5v" },
- { H3600_EGPIO_LVDD_ON, GPIOF_OUT_INIT_LOW, "LCD 9v/-6.5v" },
-};
-
static bool h3600_lcd_request(void)
{
static bool h3600_lcd_ok;
@@ -38,7 +28,42 @@ static bool h3600_lcd_request(void)
if (h3600_lcd_ok)
return true;
- rc = gpio_request_array(h3600_lcd_gpio, ARRAY_SIZE(h3600_lcd_gpio));
+ rc = gpio_request(H3XXX_EGPIO_LCD_ON, "LCD power");
+ if (rc)
+ goto out;
+ rc = gpio_direction_output(H3XXX_EGPIO_LCD_ON, 0);
+ if (rc)
+ goto out_free_on;
+ rc = gpio_request(H3600_EGPIO_LCD_PCI, "LCD control");
+ if (rc)
+ goto out_free_on;
+ rc = gpio_direction_output(H3600_EGPIO_LCD_PCI, 0);
+ if (rc)
+ goto out_free_pci;
+ rc = gpio_request(H3600_EGPIO_LCD_5V_ON, "LCD 5v");
+ if (rc)
+ goto out_free_pci;
+ rc = gpio_direction_output(H3600_EGPIO_LCD_5V_ON, 0);
+ if (rc)
+ goto out_free_5v_on;
+ rc = gpio_request(H3600_EGPIO_LVDD_ON, "LCD 9v/-6.5v");
+ if (rc)
+ goto out_free_5v_on;
+ rc = gpio_direction_output(H3600_EGPIO_LVDD_ON, 0);
+ if (rc)
+ goto out_free_lvdd_on;
+
+ goto out;
+
+out_free_lvdd_on:
+ gpio_free(H3600_EGPIO_LVDD_ON);
+out_free_5v_on:
+ gpio_free(H3600_EGPIO_LCD_5V_ON);
+out_free_pci:
+ gpio_free(H3600_EGPIO_LCD_PCI);
+out_free_on:
+ gpio_free(H3XXX_EGPIO_LCD_ON);
+out:
if (rc)
pr_err("%s: can't request GPIOs\n", __func__);
else
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
index 98145031586f..630b992f32b1 100644
--- a/arch/arm/mach-stm32/Kconfig
+++ b/arch/arm/mach-stm32/Kconfig
@@ -11,7 +11,8 @@ menuconfig ARCH_STM32
select CLKSRC_STM32
select PINCTRL
select RESET_CONTROLLER
- select STM32_EXTI
+ select STM32_EXTI if ARM_SINGLE_ARMV7M
+ select STM32_FIREWALL
help
Support for STMicroelectronics STM32 processors.
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index 18d37f90cdfe..3ec810b6f1a7 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -8,35 +8,49 @@
* Copyright (C) 2010 Google, Inc.
*/
-#include <linux/property.h>
+#include <linux/err.h>
#include <linux/gpio/machine.h>
+#include <linux/gpio/property.h>
#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/property.h>
#include "board.h"
-static struct property_entry wifi_rfkill_prop[] __initdata = {
- PROPERTY_ENTRY_STRING("name", "wifi_rfkill"),
- PROPERTY_ENTRY_STRING("type", "wlan"),
- { },
+static const struct software_node tegra_gpiochip_node = {
+ .name = "tegra-gpio",
};
-static struct platform_device wifi_rfkill_device = {
- .name = "rfkill_gpio",
- .id = -1,
+static const struct property_entry wifi_rfkill_prop[] __initconst = {
+ PROPERTY_ENTRY_STRING("name", "wifi_rfkill"),
+ PROPERTY_ENTRY_STRING("type", "wlan"),
+ PROPERTY_ENTRY_GPIO("reset-gpios",
+ &tegra_gpiochip_node, 25, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("shutdown-gpios",
+ &tegra_gpiochip_node, 85, GPIO_ACTIVE_HIGH),
+ { }
};
-static struct gpiod_lookup_table wifi_gpio_lookup = {
- .dev_id = "rfkill_gpio",
- .table = {
- GPIO_LOOKUP("tegra-gpio", 25, "reset", 0),
- GPIO_LOOKUP("tegra-gpio", 85, "shutdown", 0),
- { },
- },
+static const struct platform_device_info wifi_rfkill_info __initconst = {
+ .name = "rfkill_gpio",
+ .id = PLATFORM_DEVID_NONE,
+ .properties = wifi_rfkill_prop,
};
void __init tegra_paz00_wifikill_init(void)
{
- device_create_managed_software_node(&wifi_rfkill_device.dev, wifi_rfkill_prop, NULL);
- gpiod_add_lookup_table(&wifi_gpio_lookup);
- platform_device_register(&wifi_rfkill_device);
+ struct platform_device *pd;
+ int err;
+
+ err = software_node_register(&tegra_gpiochip_node);
+ if (err) {
+ pr_err("failed to register %s node: %d\n",
+ tegra_gpiochip_node.name, err);
+ return;
+ }
+
+ pd = platform_device_register_full(&wifi_rfkill_info);
+ err = PTR_ERR_OR_ZERO(pd);
+ if (err)
+ pr_err("failed to register WiFi rfkill device: %d\n", err);
}
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index e029270c2687..513618078440 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -278,15 +278,6 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
build a working kernel, you must also enable relevant core
tile support or Flattened Device Tree based support options.
-config ARCH_VEXPRESS_DCSCB
- bool "Dual Cluster System Control Block (DCSCB) support"
- depends on MCPM
- select ARM_CCI400_PORT_CTRL
- help
- Support for the Dual Cluster System Configuration Block (DCSCB).
- This is needed to provide CPU and cluster power management
- on RTSM implementing big.LITTLE.
-
config ARCH_VEXPRESS_SPC
bool "Versatile Express Serial Power Controller (SPC)"
select PM_OPP
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
index 27d712bcf1af..d819fb2fc450 100644
--- a/arch/arm/mach-versatile/Makefile
+++ b/arch/arm/mach-versatile/Makefile
@@ -16,9 +16,6 @@ obj-$(CONFIG_ARCH_REALVIEW) += realview.o
# vexpress
obj-$(CONFIG_ARCH_VEXPRESS) := v2m.o
-obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
-CFLAGS_dcscb.o += -march=armv7-a
-CFLAGS_REMOVE_dcscb.o = -pg
obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
CFLAGS_REMOVE_spc.o = -pg
obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
diff --git a/arch/arm/mach-versatile/dcscb.c b/arch/arm/mach-versatile/dcscb.c
deleted file mode 100644
index d8797350996d..000000000000
--- a/arch/arm/mach-versatile/dcscb.c
+++ /dev/null
@@ -1,173 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * dcscb.c - Dual Cluster System Configuration Block
- *
- * Created by: Nicolas Pitre, May 2012
- * Copyright: (C) 2012-2013 Linaro Limited
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/errno.h>
-#include <linux/of_address.h>
-#include <linux/vexpress.h>
-#include <linux/arm-cci.h>
-
-#include <asm/mcpm.h>
-#include <asm/proc-fns.h>
-#include <asm/cacheflush.h>
-#include <asm/cputype.h>
-#include <asm/cp15.h>
-
-#include "vexpress.h"
-
-#define RST_HOLD0 0x0
-#define RST_HOLD1 0x4
-#define SYS_SWRESET 0x8
-#define RST_STAT0 0xc
-#define RST_STAT1 0x10
-#define EAG_CFG_R 0x20
-#define EAG_CFG_W 0x24
-#define KFC_CFG_R 0x28
-#define KFC_CFG_W 0x2c
-#define DCS_CFG_R 0x30
-
-static void __iomem *dcscb_base;
-static int dcscb_allcpus_mask[2];
-
-static int dcscb_cpu_powerup(unsigned int cpu, unsigned int cluster)
-{
- unsigned int rst_hold, cpumask = (1 << cpu);
-
- pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
- if (cluster >= 2 || !(cpumask & dcscb_allcpus_mask[cluster]))
- return -EINVAL;
-
- rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
- rst_hold &= ~(cpumask | (cpumask << 4));
- writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
- return 0;
-}
-
-static int dcscb_cluster_powerup(unsigned int cluster)
-{
- unsigned int rst_hold;
-
- pr_debug("%s: cluster %u\n", __func__, cluster);
- if (cluster >= 2)
- return -EINVAL;
-
- /* remove cluster reset and add individual CPU's reset */
- rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
- rst_hold &= ~(1 << 8);
- rst_hold |= dcscb_allcpus_mask[cluster];
- writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
- return 0;
-}
-
-static void dcscb_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
-{
- unsigned int rst_hold;
-
- pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
- BUG_ON(cluster >= 2 || !((1 << cpu) & dcscb_allcpus_mask[cluster]));
-
- rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
- rst_hold |= (1 << cpu);
- writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
-}
-
-static void dcscb_cluster_powerdown_prepare(unsigned int cluster)
-{
- unsigned int rst_hold;
-
- pr_debug("%s: cluster %u\n", __func__, cluster);
- BUG_ON(cluster >= 2);
-
- rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
- rst_hold |= (1 << 8);
- writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
-}
-
-static void dcscb_cpu_cache_disable(void)
-{
- /* Disable and flush the local CPU cache. */
- v7_exit_coherency_flush(louis);
-}
-
-static void dcscb_cluster_cache_disable(void)
-{
- /* Flush all cache levels for this cluster. */
- v7_exit_coherency_flush(all);
-
- /*
- * A full outer cache flush could be needed at this point
- * on platforms with such a cache, depending on where the
- * outer cache sits. In some cases the notion of a "last
- * cluster standing" would need to be implemented if the
- * outer cache is shared across clusters. In any case, when
- * the outer cache needs flushing, there is no concurrent
- * access to the cache controller to worry about and no
- * special locking besides what is already provided by the
- * MCPM state machinery is needed.
- */
-
- /*
- * Disable cluster-level coherency by masking
- * incoming snoops and DVM messages:
- */
- cci_disable_port_by_cpu(read_cpuid_mpidr());
-}
-
-static const struct mcpm_platform_ops dcscb_power_ops = {
- .cpu_powerup = dcscb_cpu_powerup,
- .cluster_powerup = dcscb_cluster_powerup,
- .cpu_powerdown_prepare = dcscb_cpu_powerdown_prepare,
- .cluster_powerdown_prepare = dcscb_cluster_powerdown_prepare,
- .cpu_cache_disable = dcscb_cpu_cache_disable,
- .cluster_cache_disable = dcscb_cluster_cache_disable,
-};
-
-extern void dcscb_power_up_setup(unsigned int affinity_level);
-
-static int __init dcscb_init(void)
-{
- struct device_node *node;
- unsigned int cfg;
- int ret;
-
- if (!cci_probed())
- return -ENODEV;
-
- node = of_find_compatible_node(NULL, NULL, "arm,rtsm,dcscb");
- if (!node)
- return -ENODEV;
- dcscb_base = of_iomap(node, 0);
- of_node_put(node);
- if (!dcscb_base)
- return -EADDRNOTAVAIL;
- cfg = readl_relaxed(dcscb_base + DCS_CFG_R);
- dcscb_allcpus_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1;
- dcscb_allcpus_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1;
-
- ret = mcpm_platform_register(&dcscb_power_ops);
- if (!ret)
- ret = mcpm_sync_init(dcscb_power_up_setup);
- if (ret) {
- iounmap(dcscb_base);
- return ret;
- }
-
- pr_info("VExpress DCSCB support installed\n");
-
- /*
- * Future entries into the kernel can now go
- * through the cluster entry vectors.
- */
- vexpress_flags_set(__pa_symbol(mcpm_entry_point));
-
- return 0;
-}
-
-early_initcall(dcscb_init);
diff --git a/arch/arm/mach-versatile/dcscb_setup.S b/arch/arm/mach-versatile/dcscb_setup.S
deleted file mode 100644
index 92d1fd9d7f6a..000000000000
--- a/arch/arm/mach-versatile/dcscb_setup.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Created by: Dave Martin, 2012-06-22
- * Copyright: (C) 2012-2013 Linaro Limited
- */
-
-#include <linux/linkage.h>
-
-
-ENTRY(dcscb_power_up_setup)
-
- cmp r0, #0 @ check affinity level
- beq 2f
-
-/*
- * Enable cluster-level coherency, in preparation for turning on the MMU.
- * The ACTLR SMP bit does not need to be set here, because cpu_resume()
- * already restores that.
- *
- * A15/A7 may not require explicit L2 invalidation on reset, dependent
- * on hardware integration decisions.
- * For now, this code assumes that L2 is either already invalidated,
- * or invalidation is not required.
- */
-
- b cci_enable_port_for_self
-
-2: @ Implementation-specific local CPU setup operations should go here,
- @ if any. In this case, there is nothing to do.
-
- bx lr
-
-ENDPROC(dcscb_power_up_setup)
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 71b858c9b10c..a195cd1d3e6d 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -21,7 +21,6 @@ KASAN_SANITIZE_physaddr.o := n
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_ARM_PV_FIXUP) += pv-fixup-asm.o
obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o
@@ -45,6 +44,7 @@ obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o
obj-$(CONFIG_CPU_CACHE_NOP) += cache-nop.o
obj-$(CONFIG_CPU_CACHE_V7M) += cache-v7m.o
+obj-y += cache.o
obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o
@@ -62,6 +62,7 @@ obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions
obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o
obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o
obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o
+obj-y += tlb.o
obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o
obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_CPU_V6) += proc-v6.o
obj-$(CONFIG_CPU_V6K) += proc-v6.o
obj-$(CONFIG_CPU_V7) += proc-v7.o proc-v7-bugs.o
obj-$(CONFIG_CPU_V7M) += proc-v7m.o
+obj-$(CONFIG_CFI_CLANG) += proc.o
obj-$(CONFIG_OUTER_CACHE) += l2c-common.o
obj-$(CONFIG_CACHE_B15_RAC) += cache-b15-rac.o
diff --git a/arch/arm/mm/cache-b15-rac.c b/arch/arm/mm/cache-b15-rac.c
index 9c1172f26885..6f63b90f9e1a 100644
--- a/arch/arm/mm/cache-b15-rac.c
+++ b/arch/arm/mm/cache-b15-rac.c
@@ -5,6 +5,7 @@
* Copyright (C) 2015-2016 Broadcom
*/
+#include <linux/cfi_types.h>
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/io.h>
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 71c64e92dead..4a3668b52a2d 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -12,6 +12,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/page.h>
@@ -39,11 +40,11 @@
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(fa_flush_icache_all)
+SYM_TYPED_FUNC_START(fa_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(fa_flush_icache_all)
+SYM_FUNC_END(fa_flush_icache_all)
/*
* flush_user_cache_all()
@@ -51,14 +52,14 @@ ENDPROC(fa_flush_icache_all)
* Clean and invalidate all cache entries in a particular address
* space.
*/
-ENTRY(fa_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(fa_flush_user_cache_all, fa_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(fa_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(fa_flush_kern_cache_all)
mov ip, #0
mov r2, #VM_EXEC
__flush_whole_cache:
@@ -69,6 +70,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(fa_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -80,7 +82,7 @@ __flush_whole_cache:
* - end - end address (exclusive, page aligned)
* - flags - vma_area_struct flags describing address space
*/
-ENTRY(fa_flush_user_cache_range)
+SYM_TYPED_FUNC_START(fa_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT @ total size >= limit?
@@ -97,6 +99,7 @@ ENTRY(fa_flush_user_cache_range)
mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(fa_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -108,8 +111,11 @@ ENTRY(fa_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(fa_coherent_kern_range)
- /* fall through */
+SYM_TYPED_FUNC_START(fa_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b fa_coherent_user_range
+#endif
+SYM_FUNC_END(fa_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -121,7 +127,7 @@ ENTRY(fa_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(fa_coherent_user_range)
+SYM_TYPED_FUNC_START(fa_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -133,6 +139,7 @@ ENTRY(fa_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(fa_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -143,7 +150,7 @@ ENTRY(fa_coherent_user_range)
* - addr - kernel address
* - size - size of region
*/
-ENTRY(fa_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(fa_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
add r0, r0, #CACHE_DLINESIZE
@@ -153,6 +160,7 @@ ENTRY(fa_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
ret lr
+SYM_FUNC_END(fa_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -203,7 +211,7 @@ fa_dma_clean_range:
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(fa_dma_flush_range)
+SYM_TYPED_FUNC_START(fa_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -212,6 +220,7 @@ ENTRY(fa_dma_flush_range)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
ret lr
+SYM_FUNC_END(fa_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -219,13 +228,13 @@ ENTRY(fa_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(fa_dma_map_area)
+SYM_TYPED_FUNC_START(fa_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq fa_dma_clean_range
bcs fa_dma_inv_range
b fa_dma_flush_range
-ENDPROC(fa_dma_map_area)
+SYM_FUNC_END(fa_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -233,14 +242,6 @@ ENDPROC(fa_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(fa_dma_unmap_area)
+SYM_TYPED_FUNC_START(fa_dma_unmap_area)
ret lr
-ENDPROC(fa_dma_unmap_area)
-
- .globl fa_flush_kern_cache_louis
- .equ fa_flush_kern_cache_louis, fa_flush_kern_cache_all
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions fa
+SYM_FUNC_END(fa_dma_unmap_area)
diff --git a/arch/arm/mm/cache-nop.S b/arch/arm/mm/cache-nop.S
index 72d939ef8798..f68dde2014ee 100644
--- a/arch/arm/mm/cache-nop.S
+++ b/arch/arm/mm/cache-nop.S
@@ -1,47 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include "proc-macros.S"
-ENTRY(nop_flush_icache_all)
+/*
+ * These are all open-coded instead of aliased, to make clear
+ * what is going on here: all functions are stubbed out.
+ */
+SYM_TYPED_FUNC_START(nop_flush_icache_all)
ret lr
-ENDPROC(nop_flush_icache_all)
+SYM_FUNC_END(nop_flush_icache_all)
- .globl nop_flush_kern_cache_all
- .equ nop_flush_kern_cache_all, nop_flush_icache_all
-
- .globl nop_flush_kern_cache_louis
- .equ nop_flush_kern_cache_louis, nop_flush_icache_all
+SYM_TYPED_FUNC_START(nop_flush_kern_cache_all)
+ ret lr
+SYM_FUNC_END(nop_flush_kern_cache_all)
- .globl nop_flush_user_cache_all
- .equ nop_flush_user_cache_all, nop_flush_icache_all
+SYM_TYPED_FUNC_START(nop_flush_user_cache_all)
+ ret lr
+SYM_FUNC_END(nop_flush_user_cache_all)
- .globl nop_flush_user_cache_range
- .equ nop_flush_user_cache_range, nop_flush_icache_all
+SYM_TYPED_FUNC_START(nop_flush_user_cache_range)
+ ret lr
+SYM_FUNC_END(nop_flush_user_cache_range)
- .globl nop_coherent_kern_range
- .equ nop_coherent_kern_range, nop_flush_icache_all
+SYM_TYPED_FUNC_START(nop_coherent_kern_range)
+ ret lr
+SYM_FUNC_END(nop_coherent_kern_range)
-ENTRY(nop_coherent_user_range)
+SYM_TYPED_FUNC_START(nop_coherent_user_range)
mov r0, 0
ret lr
-ENDPROC(nop_coherent_user_range)
-
- .globl nop_flush_kern_dcache_area
- .equ nop_flush_kern_dcache_area, nop_flush_icache_all
+SYM_FUNC_END(nop_coherent_user_range)
- .globl nop_dma_flush_range
- .equ nop_dma_flush_range, nop_flush_icache_all
-
- .globl nop_dma_map_area
- .equ nop_dma_map_area, nop_flush_icache_all
+SYM_TYPED_FUNC_START(nop_flush_kern_dcache_area)
+ ret lr
+SYM_FUNC_END(nop_flush_kern_dcache_area)
- .globl nop_dma_unmap_area
- .equ nop_dma_unmap_area, nop_flush_icache_all
+SYM_TYPED_FUNC_START(nop_dma_flush_range)
+ ret lr
+SYM_FUNC_END(nop_dma_flush_range)
- __INITDATA
+SYM_TYPED_FUNC_START(nop_dma_map_area)
+ ret lr
+SYM_FUNC_END(nop_dma_map_area)
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions nop
+SYM_TYPED_FUNC_START(nop_dma_unmap_area)
+ ret lr
+SYM_FUNC_END(nop_dma_unmap_area)
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index 7787057e4990..0e94e5193dbd 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -6,6 +6,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/page.h>
#include "proc-macros.S"
@@ -15,9 +16,9 @@
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(v4_flush_icache_all)
+SYM_TYPED_FUNC_START(v4_flush_icache_all)
ret lr
-ENDPROC(v4_flush_icache_all)
+SYM_FUNC_END(v4_flush_icache_all)
/*
* flush_user_cache_all()
@@ -27,21 +28,22 @@ ENDPROC(v4_flush_icache_all)
*
* - mm - mm_struct describing address space
*/
-ENTRY(v4_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(v4_flush_user_cache_all, v4_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(v4_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(v4_flush_kern_cache_all)
#ifdef CONFIG_CPU_CP15
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 @ flush ID cache
ret lr
#else
- /* FALLTHROUGH */
+ ret lr
#endif
+SYM_FUNC_END(v4_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -53,14 +55,15 @@ ENTRY(v4_flush_kern_cache_all)
* - end - end address (exclusive, may not be aligned)
* - flags - vma_area_struct flags describing address space
*/
-ENTRY(v4_flush_user_cache_range)
+SYM_TYPED_FUNC_START(v4_flush_user_cache_range)
#ifdef CONFIG_CPU_CP15
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ flush ID cache
ret lr
#else
- /* FALLTHROUGH */
+ ret lr
#endif
+SYM_FUNC_END(v4_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -72,8 +75,9 @@ ENTRY(v4_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(v4_coherent_kern_range)
+ ret lr
+SYM_FUNC_END(v4_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -85,9 +89,10 @@ ENTRY(v4_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4_coherent_user_range)
+SYM_TYPED_FUNC_START(v4_coherent_user_range)
mov r0, #0
ret lr
+SYM_FUNC_END(v4_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -98,8 +103,11 @@ ENTRY(v4_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(v4_flush_kern_dcache_area)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(v4_flush_kern_dcache_area)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v4_dma_flush_range
+#endif
+SYM_FUNC_END(v4_flush_kern_dcache_area)
/*
* dma_flush_range(start, end)
@@ -109,12 +117,13 @@ ENTRY(v4_flush_kern_dcache_area)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4_dma_flush_range)
+SYM_TYPED_FUNC_START(v4_dma_flush_range)
#ifdef CONFIG_CPU_CP15
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 @ flush ID cache
#endif
ret lr
+SYM_FUNC_END(v4_dma_flush_range)
/*
* dma_unmap_area(start, size, dir)
@@ -122,10 +131,11 @@ ENTRY(v4_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v4_dma_unmap_area)
+SYM_TYPED_FUNC_START(v4_dma_unmap_area)
teq r2, #DMA_TO_DEVICE
bne v4_dma_flush_range
- /* FALLTHROUGH */
+ ret lr
+SYM_FUNC_END(v4_dma_unmap_area)
/*
* dma_map_area(start, size, dir)
@@ -133,15 +143,6 @@ ENTRY(v4_dma_unmap_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v4_dma_map_area)
+SYM_TYPED_FUNC_START(v4_dma_map_area)
ret lr
-ENDPROC(v4_dma_unmap_area)
-ENDPROC(v4_dma_map_area)
-
- .globl v4_flush_kern_cache_louis
- .equ v4_flush_kern_cache_louis, v4_flush_kern_cache_all
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions v4
+SYM_FUNC_END(v4_dma_map_area)
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index ad382cee0fdb..ce55a2eef5da 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -6,6 +6,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/page.h>
#include "proc-macros.S"
@@ -53,11 +54,11 @@ flush_base:
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(v4wb_flush_icache_all)
+SYM_TYPED_FUNC_START(v4wb_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(v4wb_flush_icache_all)
+SYM_FUNC_END(v4wb_flush_icache_all)
/*
* flush_user_cache_all()
@@ -65,14 +66,14 @@ ENDPROC(v4wb_flush_icache_all)
* Clean and invalidate all cache entries in a particular address
* space.
*/
-ENTRY(v4wb_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(v4wb_flush_user_cache_all, v4wb_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(v4wb_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(v4wb_flush_kern_cache_all)
mov ip, #0
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
__flush_whole_cache:
@@ -93,6 +94,7 @@ __flush_whole_cache:
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
ret lr
+SYM_FUNC_END(v4wb_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -104,7 +106,7 @@ __flush_whole_cache:
* - end - end address (exclusive, page aligned)
* - flags - vma_area_struct flags describing address space
*/
-ENTRY(v4wb_flush_user_cache_range)
+SYM_TYPED_FUNC_START(v4wb_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
tst r2, #VM_EXEC @ executable region?
@@ -121,6 +123,7 @@ ENTRY(v4wb_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
ret lr
+SYM_FUNC_END(v4wb_flush_user_cache_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -131,9 +134,12 @@ ENTRY(v4wb_flush_user_cache_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(v4wb_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(v4wb_flush_kern_dcache_area)
add r1, r0, r1
- /* fall through */
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v4wb_coherent_user_range
+#endif
+SYM_FUNC_END(v4wb_flush_kern_dcache_area)
/*
* coherent_kern_range(start, end)
@@ -145,8 +151,11 @@ ENTRY(v4wb_flush_kern_dcache_area)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4wb_coherent_kern_range)
- /* fall through */
+SYM_TYPED_FUNC_START(v4wb_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v4wb_coherent_user_range
+#endif
+SYM_FUNC_END(v4wb_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -158,7 +167,7 @@ ENTRY(v4wb_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4wb_coherent_user_range)
+SYM_TYPED_FUNC_START(v4wb_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
@@ -169,7 +178,7 @@ ENTRY(v4wb_coherent_user_range)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
-
+SYM_FUNC_END(v4wb_coherent_user_range)
/*
* dma_inv_range(start, end)
@@ -231,13 +240,13 @@ v4wb_dma_clean_range:
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v4wb_dma_map_area)
+SYM_TYPED_FUNC_START(v4wb_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq v4wb_dma_clean_range
bcs v4wb_dma_inv_range
b v4wb_dma_flush_range
-ENDPROC(v4wb_dma_map_area)
+SYM_FUNC_END(v4wb_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -245,14 +254,6 @@ ENDPROC(v4wb_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v4wb_dma_unmap_area)
+SYM_TYPED_FUNC_START(v4wb_dma_unmap_area)
ret lr
-ENDPROC(v4wb_dma_unmap_area)
-
- .globl v4wb_flush_kern_cache_louis
- .equ v4wb_flush_kern_cache_louis, v4wb_flush_kern_cache_all
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions v4wb
+SYM_FUNC_END(v4wb_dma_unmap_area)
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index 0b290c25a99d..a97dc267b3b0 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -10,6 +10,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/page.h>
#include "proc-macros.S"
@@ -43,11 +44,11 @@
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(v4wt_flush_icache_all)
+SYM_TYPED_FUNC_START(v4wt_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(v4wt_flush_icache_all)
+SYM_FUNC_END(v4wt_flush_icache_all)
/*
* flush_user_cache_all()
@@ -55,14 +56,14 @@ ENDPROC(v4wt_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(v4wt_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(v4wt_flush_user_cache_all, v4wt_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(v4wt_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(v4wt_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -70,6 +71,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
ret lr
+SYM_FUNC_END(v4wt_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -81,7 +83,7 @@ __flush_whole_cache:
* - end - end address (exclusive, page aligned)
* - flags - vma_area_struct flags describing address space
*/
-ENTRY(v4wt_flush_user_cache_range)
+SYM_TYPED_FUNC_START(v4wt_flush_user_cache_range)
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
bhs __flush_whole_cache
@@ -93,6 +95,7 @@ ENTRY(v4wt_flush_user_cache_range)
cmp r0, r1
blo 1b
ret lr
+SYM_FUNC_END(v4wt_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -104,8 +107,11 @@ ENTRY(v4wt_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4wt_coherent_kern_range)
- /* FALLTRHOUGH */
+SYM_TYPED_FUNC_START(v4wt_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v4wt_coherent_user_range
+#endif
+SYM_FUNC_END(v4wt_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -117,7 +123,7 @@ ENTRY(v4wt_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(v4wt_coherent_user_range)
+SYM_TYPED_FUNC_START(v4wt_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
add r0, r0, #CACHE_DLINESIZE
@@ -125,6 +131,7 @@ ENTRY(v4wt_coherent_user_range)
blo 1b
mov r0, #0
ret lr
+SYM_FUNC_END(v4wt_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -135,11 +142,12 @@ ENTRY(v4wt_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(v4wt_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(v4wt_flush_kern_dcache_area)
mov r2, #0
mcr p15, 0, r2, c7, c5, 0 @ invalidate I cache
add r1, r0, r1
- /* fallthrough */
+ b v4wt_dma_inv_range
+SYM_FUNC_END(v4wt_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -167,9 +175,10 @@ v4wt_dma_inv_range:
*
* - start - virtual start address
* - end - virtual end address
- */
- .globl v4wt_dma_flush_range
- .equ v4wt_dma_flush_range, v4wt_dma_inv_range
+*/
+SYM_TYPED_FUNC_START(v4wt_dma_flush_range)
+ b v4wt_dma_inv_range
+SYM_FUNC_END(v4wt_dma_flush_range)
/*
* dma_unmap_area(start, size, dir)
@@ -177,11 +186,12 @@ v4wt_dma_inv_range:
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v4wt_dma_unmap_area)
+SYM_TYPED_FUNC_START(v4wt_dma_unmap_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
bne v4wt_dma_inv_range
- /* FALLTHROUGH */
+ ret lr
+SYM_FUNC_END(v4wt_dma_unmap_area)
/*
* dma_map_area(start, size, dir)
@@ -189,15 +199,6 @@ ENTRY(v4wt_dma_unmap_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v4wt_dma_map_area)
+SYM_TYPED_FUNC_START(v4wt_dma_map_area)
ret lr
-ENDPROC(v4wt_dma_unmap_area)
-ENDPROC(v4wt_dma_map_area)
-
- .globl v4wt_flush_kern_cache_louis
- .equ v4wt_flush_kern_cache_louis, v4wt_flush_kern_cache_all
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions v4wt
+SYM_FUNC_END(v4wt_dma_map_area)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 44211d8a296f..9f415476e218 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -8,6 +8,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/errno.h>
#include <asm/unwind.h>
@@ -34,7 +35,7 @@
* r0 - set to 0
* r1 - corrupted
*/
-ENTRY(v6_flush_icache_all)
+SYM_TYPED_FUNC_START(v6_flush_icache_all)
mov r0, #0
#ifdef CONFIG_ARM_ERRATA_411920
mrs r1, cpsr
@@ -51,7 +52,7 @@ ENTRY(v6_flush_icache_all)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I-cache
#endif
ret lr
-ENDPROC(v6_flush_icache_all)
+SYM_FUNC_END(v6_flush_icache_all)
/*
* v6_flush_cache_all()
@@ -60,7 +61,7 @@ ENDPROC(v6_flush_icache_all)
*
* It is assumed that:
*/
-ENTRY(v6_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(v6_flush_kern_cache_all)
mov r0, #0
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate
@@ -73,6 +74,7 @@ ENTRY(v6_flush_kern_cache_all)
mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate
#endif
ret lr
+SYM_FUNC_END(v6_flush_kern_cache_all)
/*
* v6_flush_cache_all()
@@ -81,8 +83,9 @@ ENTRY(v6_flush_kern_cache_all)
*
* - mm - mm_struct describing address space
*/
-ENTRY(v6_flush_user_cache_all)
- /*FALLTHROUGH*/
+SYM_TYPED_FUNC_START(v6_flush_user_cache_all)
+ ret lr
+SYM_FUNC_END(v6_flush_user_cache_all)
/*
* v6_flush_cache_range(start, end, flags)
@@ -96,8 +99,9 @@ ENTRY(v6_flush_user_cache_all)
* It is assumed that:
* - we have a VIPT cache.
*/
-ENTRY(v6_flush_user_cache_range)
+SYM_TYPED_FUNC_START(v6_flush_user_cache_range)
ret lr
+SYM_FUNC_END(v6_flush_user_cache_range)
/*
* v6_coherent_kern_range(start,end)
@@ -112,8 +116,11 @@ ENTRY(v6_flush_user_cache_range)
* It is assumed that:
* - the Icache does not read data from the write buffer
*/
-ENTRY(v6_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(v6_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v6_coherent_user_range
+#endif
+SYM_FUNC_END(v6_coherent_kern_range)
/*
* v6_coherent_user_range(start,end)
@@ -128,7 +135,7 @@ ENTRY(v6_coherent_kern_range)
* It is assumed that:
* - the Icache does not read data from the write buffer
*/
-ENTRY(v6_coherent_user_range)
+SYM_TYPED_FUNC_START(v6_coherent_user_range)
UNWIND(.fnstart )
#ifdef HARVARD_CACHE
bic r0, r0, #CACHE_LINE_SIZE - 1
@@ -159,8 +166,7 @@ ENTRY(v6_coherent_user_range)
mov r0, #-EFAULT
ret lr
UNWIND(.fnend )
-ENDPROC(v6_coherent_user_range)
-ENDPROC(v6_coherent_kern_range)
+SYM_FUNC_END(v6_coherent_user_range)
/*
* v6_flush_kern_dcache_area(void *addr, size_t size)
@@ -171,7 +177,7 @@ ENDPROC(v6_coherent_kern_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(v6_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(v6_flush_kern_dcache_area)
add r1, r0, r1
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
@@ -188,7 +194,7 @@ ENTRY(v6_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c10, 4
#endif
ret lr
-
+SYM_FUNC_END(v6_flush_kern_dcache_area)
/*
* v6_dma_inv_range(start,end)
@@ -253,7 +259,7 @@ v6_dma_clean_range:
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(v6_dma_flush_range)
+SYM_TYPED_FUNC_START(v6_dma_flush_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
#ifdef HARVARD_CACHE
@@ -267,6 +273,7 @@ ENTRY(v6_dma_flush_range)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
ret lr
+SYM_FUNC_END(v6_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -274,12 +281,12 @@ ENTRY(v6_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v6_dma_map_area)
+SYM_TYPED_FUNC_START(v6_dma_map_area)
add r1, r1, r0
teq r2, #DMA_FROM_DEVICE
beq v6_dma_inv_range
b v6_dma_clean_range
-ENDPROC(v6_dma_map_area)
+SYM_FUNC_END(v6_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -287,17 +294,9 @@ ENDPROC(v6_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v6_dma_unmap_area)
+SYM_TYPED_FUNC_START(v6_dma_unmap_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
bne v6_dma_inv_range
ret lr
-ENDPROC(v6_dma_unmap_area)
-
- .globl v6_flush_kern_cache_louis
- .equ v6_flush_kern_cache_louis, v6_flush_kern_cache_all
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions v6
+SYM_FUNC_END(v6_dma_unmap_area)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 127afe2096ba..201ca05436fa 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -9,6 +9,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/errno.h>
#include <asm/unwind.h>
@@ -80,12 +81,12 @@ ENDPROC(v7_invalidate_l1)
* Registers:
* r0 - set to 0
*/
-ENTRY(v7_flush_icache_all)
+SYM_TYPED_FUNC_START(v7_flush_icache_all)
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
ret lr
-ENDPROC(v7_flush_icache_all)
+SYM_FUNC_END(v7_flush_icache_all)
/*
* v7_flush_dcache_louis()
@@ -193,7 +194,7 @@ ENDPROC(v7_flush_dcache_all)
* unification in a single instruction.
*
*/
-ENTRY(v7_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(v7_flush_kern_cache_all)
stmfd sp!, {r4-r6, r9-r10, lr}
bl v7_flush_dcache_all
mov r0, #0
@@ -201,7 +202,7 @@ ENTRY(v7_flush_kern_cache_all)
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
ldmfd sp!, {r4-r6, r9-r10, lr}
ret lr
-ENDPROC(v7_flush_kern_cache_all)
+SYM_FUNC_END(v7_flush_kern_cache_all)
/*
* v7_flush_kern_cache_louis(void)
@@ -209,7 +210,7 @@ ENDPROC(v7_flush_kern_cache_all)
* Flush the data cache up to Level of Unification Inner Shareable.
* Invalidate the I-cache to the point of unification.
*/
-ENTRY(v7_flush_kern_cache_louis)
+SYM_TYPED_FUNC_START(v7_flush_kern_cache_louis)
stmfd sp!, {r4-r6, r9-r10, lr}
bl v7_flush_dcache_louis
mov r0, #0
@@ -217,7 +218,7 @@ ENTRY(v7_flush_kern_cache_louis)
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
ldmfd sp!, {r4-r6, r9-r10, lr}
ret lr
-ENDPROC(v7_flush_kern_cache_louis)
+SYM_FUNC_END(v7_flush_kern_cache_louis)
/*
* v7_flush_cache_all()
@@ -226,8 +227,9 @@ ENDPROC(v7_flush_kern_cache_louis)
*
* - mm - mm_struct describing address space
*/
-ENTRY(v7_flush_user_cache_all)
- /*FALLTHROUGH*/
+SYM_TYPED_FUNC_START(v7_flush_user_cache_all)
+ ret lr
+SYM_FUNC_END(v7_flush_user_cache_all)
/*
* v7_flush_cache_range(start, end, flags)
@@ -241,10 +243,9 @@ ENTRY(v7_flush_user_cache_all)
* It is assumed that:
* - we have a VIPT cache.
*/
-ENTRY(v7_flush_user_cache_range)
+SYM_TYPED_FUNC_START(v7_flush_user_cache_range)
ret lr
-ENDPROC(v7_flush_user_cache_all)
-ENDPROC(v7_flush_user_cache_range)
+SYM_FUNC_END(v7_flush_user_cache_range)
/*
* v7_coherent_kern_range(start,end)
@@ -259,8 +260,11 @@ ENDPROC(v7_flush_user_cache_range)
* It is assumed that:
* - the Icache does not read data from the write buffer
*/
-ENTRY(v7_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(v7_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v7_coherent_user_range
+#endif
+SYM_FUNC_END(v7_coherent_kern_range)
/*
* v7_coherent_user_range(start,end)
@@ -275,7 +279,7 @@ ENTRY(v7_coherent_kern_range)
* It is assumed that:
* - the Icache does not read data from the write buffer
*/
-ENTRY(v7_coherent_user_range)
+SYM_TYPED_FUNC_START(v7_coherent_user_range)
UNWIND(.fnstart )
dcache_line_size r2, r3
sub r3, r2, #1
@@ -321,8 +325,7 @@ ENTRY(v7_coherent_user_range)
mov r0, #-EFAULT
ret lr
UNWIND(.fnend )
-ENDPROC(v7_coherent_kern_range)
-ENDPROC(v7_coherent_user_range)
+SYM_FUNC_END(v7_coherent_user_range)
/*
* v7_flush_kern_dcache_area(void *addr, size_t size)
@@ -333,7 +336,7 @@ ENDPROC(v7_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(v7_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(v7_flush_kern_dcache_area)
dcache_line_size r2, r3
add r1, r0, r1
sub r3, r2, #1
@@ -349,7 +352,7 @@ ENTRY(v7_flush_kern_dcache_area)
blo 1b
dsb st
ret lr
-ENDPROC(v7_flush_kern_dcache_area)
+SYM_FUNC_END(v7_flush_kern_dcache_area)
/*
* v7_dma_inv_range(start,end)
@@ -413,7 +416,7 @@ ENDPROC(v7_dma_clean_range)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(v7_dma_flush_range)
+SYM_TYPED_FUNC_START(v7_dma_flush_range)
dcache_line_size r2, r3
sub r3, r2, #1
bic r0, r0, r3
@@ -428,7 +431,7 @@ ENTRY(v7_dma_flush_range)
blo 1b
dsb st
ret lr
-ENDPROC(v7_dma_flush_range)
+SYM_FUNC_END(v7_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -436,12 +439,12 @@ ENDPROC(v7_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v7_dma_map_area)
+SYM_TYPED_FUNC_START(v7_dma_map_area)
add r1, r1, r0
teq r2, #DMA_FROM_DEVICE
beq v7_dma_inv_range
b v7_dma_clean_range
-ENDPROC(v7_dma_map_area)
+SYM_FUNC_END(v7_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -449,34 +452,9 @@ ENDPROC(v7_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v7_dma_unmap_area)
+SYM_TYPED_FUNC_START(v7_dma_unmap_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
bne v7_dma_inv_range
ret lr
-ENDPROC(v7_dma_unmap_area)
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions v7
-
- /* The Broadcom Brahma-B15 read-ahead cache requires some modifications
- * to the v7_cache_fns, we only override the ones we need
- */
-#ifndef CONFIG_CACHE_B15_RAC
- globl_equ b15_flush_kern_cache_all, v7_flush_kern_cache_all
-#endif
- globl_equ b15_flush_icache_all, v7_flush_icache_all
- globl_equ b15_flush_kern_cache_louis, v7_flush_kern_cache_louis
- globl_equ b15_flush_user_cache_all, v7_flush_user_cache_all
- globl_equ b15_flush_user_cache_range, v7_flush_user_cache_range
- globl_equ b15_coherent_kern_range, v7_coherent_kern_range
- globl_equ b15_coherent_user_range, v7_coherent_user_range
- globl_equ b15_flush_kern_dcache_area, v7_flush_kern_dcache_area
-
- globl_equ b15_dma_map_area, v7_dma_map_area
- globl_equ b15_dma_unmap_area, v7_dma_unmap_area
- globl_equ b15_dma_flush_range, v7_dma_flush_range
-
- define_cache_functions b15
+SYM_FUNC_END(v7_dma_unmap_area)
diff --git a/arch/arm/mm/cache-v7m.S b/arch/arm/mm/cache-v7m.S
index eb60b5e5e2ad..14d719eba729 100644
--- a/arch/arm/mm/cache-v7m.S
+++ b/arch/arm/mm/cache-v7m.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/errno.h>
#include <asm/unwind.h>
@@ -159,10 +160,10 @@ ENDPROC(v7m_invalidate_l1)
* Registers:
* r0 - set to 0
*/
-ENTRY(v7m_flush_icache_all)
+SYM_TYPED_FUNC_START(v7m_flush_icache_all)
invalidate_icache r0
ret lr
-ENDPROC(v7m_flush_icache_all)
+SYM_FUNC_END(v7m_flush_icache_all)
/*
* v7m_flush_dcache_all()
@@ -236,13 +237,13 @@ ENDPROC(v7m_flush_dcache_all)
* unification in a single instruction.
*
*/
-ENTRY(v7m_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(v7m_flush_kern_cache_all)
stmfd sp!, {r4-r7, r9-r11, lr}
bl v7m_flush_dcache_all
invalidate_icache r0
ldmfd sp!, {r4-r7, r9-r11, lr}
ret lr
-ENDPROC(v7m_flush_kern_cache_all)
+SYM_FUNC_END(v7m_flush_kern_cache_all)
/*
* v7m_flush_cache_all()
@@ -251,8 +252,9 @@ ENDPROC(v7m_flush_kern_cache_all)
*
* - mm - mm_struct describing address space
*/
-ENTRY(v7m_flush_user_cache_all)
- /*FALLTHROUGH*/
+SYM_TYPED_FUNC_START(v7m_flush_user_cache_all)
+ ret lr
+SYM_FUNC_END(v7m_flush_user_cache_all)
/*
* v7m_flush_cache_range(start, end, flags)
@@ -266,10 +268,9 @@ ENTRY(v7m_flush_user_cache_all)
* It is assumed that:
* - we have a VIPT cache.
*/
-ENTRY(v7m_flush_user_cache_range)
+SYM_TYPED_FUNC_START(v7m_flush_user_cache_range)
ret lr
-ENDPROC(v7m_flush_user_cache_all)
-ENDPROC(v7m_flush_user_cache_range)
+SYM_FUNC_END(v7m_flush_user_cache_range)
/*
* v7m_coherent_kern_range(start,end)
@@ -284,8 +285,11 @@ ENDPROC(v7m_flush_user_cache_range)
* It is assumed that:
* - the Icache does not read data from the write buffer
*/
-ENTRY(v7m_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(v7m_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b v7m_coherent_user_range
+#endif
+SYM_FUNC_END(v7m_coherent_kern_range)
/*
* v7m_coherent_user_range(start,end)
@@ -300,7 +304,7 @@ ENTRY(v7m_coherent_kern_range)
* It is assumed that:
* - the Icache does not read data from the write buffer
*/
-ENTRY(v7m_coherent_user_range)
+SYM_TYPED_FUNC_START(v7m_coherent_user_range)
UNWIND(.fnstart )
dcache_line_size r2, r3
sub r3, r2, #1
@@ -328,8 +332,7 @@ ENTRY(v7m_coherent_user_range)
isb
ret lr
UNWIND(.fnend )
-ENDPROC(v7m_coherent_kern_range)
-ENDPROC(v7m_coherent_user_range)
+SYM_FUNC_END(v7m_coherent_user_range)
/*
* v7m_flush_kern_dcache_area(void *addr, size_t size)
@@ -340,7 +343,7 @@ ENDPROC(v7m_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(v7m_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(v7m_flush_kern_dcache_area)
dcache_line_size r2, r3
add r1, r0, r1
sub r3, r2, #1
@@ -352,7 +355,7 @@ ENTRY(v7m_flush_kern_dcache_area)
blo 1b
dsb st
ret lr
-ENDPROC(v7m_flush_kern_dcache_area)
+SYM_FUNC_END(v7m_flush_kern_dcache_area)
/*
* v7m_dma_inv_range(start,end)
@@ -408,7 +411,7 @@ ENDPROC(v7m_dma_clean_range)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(v7m_dma_flush_range)
+SYM_TYPED_FUNC_START(v7m_dma_flush_range)
dcache_line_size r2, r3
sub r3, r2, #1
bic r0, r0, r3
@@ -419,7 +422,7 @@ ENTRY(v7m_dma_flush_range)
blo 1b
dsb st
ret lr
-ENDPROC(v7m_dma_flush_range)
+SYM_FUNC_END(v7m_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -427,12 +430,12 @@ ENDPROC(v7m_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v7m_dma_map_area)
+SYM_TYPED_FUNC_START(v7m_dma_map_area)
add r1, r1, r0
teq r2, #DMA_FROM_DEVICE
beq v7m_dma_inv_range
b v7m_dma_clean_range
-ENDPROC(v7m_dma_map_area)
+SYM_FUNC_END(v7m_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -440,17 +443,9 @@ ENDPROC(v7m_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(v7m_dma_unmap_area)
+SYM_TYPED_FUNC_START(v7m_dma_unmap_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
bne v7m_dma_inv_range
ret lr
-ENDPROC(v7m_dma_unmap_area)
-
- .globl v7m_flush_kern_cache_louis
- .equ v7m_flush_kern_cache_louis, v7m_flush_kern_cache_all
-
- __INITDATA
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions v7m
+SYM_FUNC_END(v7m_dma_unmap_area)
diff --git a/arch/arm/mm/cache.c b/arch/arm/mm/cache.c
new file mode 100644
index 000000000000..e6fbc599c9ed
--- /dev/null
+++ b/arch/arm/mm/cache.c
@@ -0,0 +1,663 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file defines C prototypes for the low-level cache assembly functions
+ * and populates a vtable for each selected ARM CPU cache type.
+ */
+
+#include <linux/types.h>
+#include <asm/cacheflush.h>
+
+#ifdef CONFIG_CPU_CACHE_V4
+void v4_flush_icache_all(void);
+void v4_flush_kern_cache_all(void);
+void v4_flush_user_cache_all(void);
+void v4_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void v4_coherent_kern_range(unsigned long, unsigned long);
+int v4_coherent_user_range(unsigned long, unsigned long);
+void v4_flush_kern_dcache_area(void *, size_t);
+void v4_dma_map_area(const void *, size_t, int);
+void v4_dma_unmap_area(const void *, size_t, int);
+void v4_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns v4_cache_fns __initconst = {
+ .flush_icache_all = v4_flush_icache_all,
+ .flush_kern_all = v4_flush_kern_cache_all,
+ .flush_kern_louis = v4_flush_kern_cache_all,
+ .flush_user_all = v4_flush_user_cache_all,
+ .flush_user_range = v4_flush_user_cache_range,
+ .coherent_kern_range = v4_coherent_kern_range,
+ .coherent_user_range = v4_coherent_user_range,
+ .flush_kern_dcache_area = v4_flush_kern_dcache_area,
+ .dma_map_area = v4_dma_map_area,
+ .dma_unmap_area = v4_dma_unmap_area,
+ .dma_flush_range = v4_dma_flush_range,
+};
+#endif
+
+/* V4 write-back cache "V4WB" */
+#ifdef CONFIG_CPU_CACHE_V4WB
+void v4wb_flush_icache_all(void);
+void v4wb_flush_kern_cache_all(void);
+void v4wb_flush_user_cache_all(void);
+void v4wb_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void v4wb_coherent_kern_range(unsigned long, unsigned long);
+int v4wb_coherent_user_range(unsigned long, unsigned long);
+void v4wb_flush_kern_dcache_area(void *, size_t);
+void v4wb_dma_map_area(const void *, size_t, int);
+void v4wb_dma_unmap_area(const void *, size_t, int);
+void v4wb_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns v4wb_cache_fns __initconst = {
+ .flush_icache_all = v4wb_flush_icache_all,
+ .flush_kern_all = v4wb_flush_kern_cache_all,
+ .flush_kern_louis = v4wb_flush_kern_cache_all,
+ .flush_user_all = v4wb_flush_user_cache_all,
+ .flush_user_range = v4wb_flush_user_cache_range,
+ .coherent_kern_range = v4wb_coherent_kern_range,
+ .coherent_user_range = v4wb_coherent_user_range,
+ .flush_kern_dcache_area = v4wb_flush_kern_dcache_area,
+ .dma_map_area = v4wb_dma_map_area,
+ .dma_unmap_area = v4wb_dma_unmap_area,
+ .dma_flush_range = v4wb_dma_flush_range,
+};
+#endif
+
+/* V4 write-through cache "V4WT" */
+#ifdef CONFIG_CPU_CACHE_V4WT
+void v4wt_flush_icache_all(void);
+void v4wt_flush_kern_cache_all(void);
+void v4wt_flush_user_cache_all(void);
+void v4wt_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void v4wt_coherent_kern_range(unsigned long, unsigned long);
+int v4wt_coherent_user_range(unsigned long, unsigned long);
+void v4wt_flush_kern_dcache_area(void *, size_t);
+void v4wt_dma_map_area(const void *, size_t, int);
+void v4wt_dma_unmap_area(const void *, size_t, int);
+void v4wt_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns v4wt_cache_fns __initconst = {
+ .flush_icache_all = v4wt_flush_icache_all,
+ .flush_kern_all = v4wt_flush_kern_cache_all,
+ .flush_kern_louis = v4wt_flush_kern_cache_all,
+ .flush_user_all = v4wt_flush_user_cache_all,
+ .flush_user_range = v4wt_flush_user_cache_range,
+ .coherent_kern_range = v4wt_coherent_kern_range,
+ .coherent_user_range = v4wt_coherent_user_range,
+ .flush_kern_dcache_area = v4wt_flush_kern_dcache_area,
+ .dma_map_area = v4wt_dma_map_area,
+ .dma_unmap_area = v4wt_dma_unmap_area,
+ .dma_flush_range = v4wt_dma_flush_range,
+};
+#endif
+
+/* Faraday FA526 cache */
+#ifdef CONFIG_CPU_CACHE_FA
+void fa_flush_icache_all(void);
+void fa_flush_kern_cache_all(void);
+void fa_flush_user_cache_all(void);
+void fa_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void fa_coherent_kern_range(unsigned long, unsigned long);
+int fa_coherent_user_range(unsigned long, unsigned long);
+void fa_flush_kern_dcache_area(void *, size_t);
+void fa_dma_map_area(const void *, size_t, int);
+void fa_dma_unmap_area(const void *, size_t, int);
+void fa_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns fa_cache_fns __initconst = {
+ .flush_icache_all = fa_flush_icache_all,
+ .flush_kern_all = fa_flush_kern_cache_all,
+ .flush_kern_louis = fa_flush_kern_cache_all,
+ .flush_user_all = fa_flush_user_cache_all,
+ .flush_user_range = fa_flush_user_cache_range,
+ .coherent_kern_range = fa_coherent_kern_range,
+ .coherent_user_range = fa_coherent_user_range,
+ .flush_kern_dcache_area = fa_flush_kern_dcache_area,
+ .dma_map_area = fa_dma_map_area,
+ .dma_unmap_area = fa_dma_unmap_area,
+ .dma_flush_range = fa_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_CACHE_V6
+void v6_flush_icache_all(void);
+void v6_flush_kern_cache_all(void);
+void v6_flush_user_cache_all(void);
+void v6_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void v6_coherent_kern_range(unsigned long, unsigned long);
+int v6_coherent_user_range(unsigned long, unsigned long);
+void v6_flush_kern_dcache_area(void *, size_t);
+void v6_dma_map_area(const void *, size_t, int);
+void v6_dma_unmap_area(const void *, size_t, int);
+void v6_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns v6_cache_fns __initconst = {
+ .flush_icache_all = v6_flush_icache_all,
+ .flush_kern_all = v6_flush_kern_cache_all,
+ .flush_kern_louis = v6_flush_kern_cache_all,
+ .flush_user_all = v6_flush_user_cache_all,
+ .flush_user_range = v6_flush_user_cache_range,
+ .coherent_kern_range = v6_coherent_kern_range,
+ .coherent_user_range = v6_coherent_user_range,
+ .flush_kern_dcache_area = v6_flush_kern_dcache_area,
+ .dma_map_area = v6_dma_map_area,
+ .dma_unmap_area = v6_dma_unmap_area,
+ .dma_flush_range = v6_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_CACHE_V7
+void v7_flush_icache_all(void);
+void v7_flush_kern_cache_all(void);
+void v7_flush_kern_cache_louis(void);
+void v7_flush_user_cache_all(void);
+void v7_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void v7_coherent_kern_range(unsigned long, unsigned long);
+int v7_coherent_user_range(unsigned long, unsigned long);
+void v7_flush_kern_dcache_area(void *, size_t);
+void v7_dma_map_area(const void *, size_t, int);
+void v7_dma_unmap_area(const void *, size_t, int);
+void v7_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns v7_cache_fns __initconst = {
+ .flush_icache_all = v7_flush_icache_all,
+ .flush_kern_all = v7_flush_kern_cache_all,
+ .flush_kern_louis = v7_flush_kern_cache_louis,
+ .flush_user_all = v7_flush_user_cache_all,
+ .flush_user_range = v7_flush_user_cache_range,
+ .coherent_kern_range = v7_coherent_kern_range,
+ .coherent_user_range = v7_coherent_user_range,
+ .flush_kern_dcache_area = v7_flush_kern_dcache_area,
+ .dma_map_area = v7_dma_map_area,
+ .dma_unmap_area = v7_dma_unmap_area,
+ .dma_flush_range = v7_dma_flush_range,
+};
+
+/* Special quirky cache flush function for Broadcom B15 v7 caches */
+void b15_flush_kern_cache_all(void);
+
+struct cpu_cache_fns b15_cache_fns __initconst = {
+ .flush_icache_all = v7_flush_icache_all,
+#ifdef CONFIG_CACHE_B15_RAC
+ .flush_kern_all = b15_flush_kern_cache_all,
+#else
+ .flush_kern_all = v7_flush_kern_cache_all,
+#endif
+ .flush_kern_louis = v7_flush_kern_cache_louis,
+ .flush_user_all = v7_flush_user_cache_all,
+ .flush_user_range = v7_flush_user_cache_range,
+ .coherent_kern_range = v7_coherent_kern_range,
+ .coherent_user_range = v7_coherent_user_range,
+ .flush_kern_dcache_area = v7_flush_kern_dcache_area,
+ .dma_map_area = v7_dma_map_area,
+ .dma_unmap_area = v7_dma_unmap_area,
+ .dma_flush_range = v7_dma_flush_range,
+};
+#endif
+
+/* The NOP cache is just a set of dummy stubs that by definition does nothing */
+#ifdef CONFIG_CPU_CACHE_NOP
+void nop_flush_icache_all(void);
+void nop_flush_kern_cache_all(void);
+void nop_flush_user_cache_all(void);
+void nop_flush_user_cache_range(unsigned long start, unsigned long end, unsigned int flags);
+void nop_coherent_kern_range(unsigned long start, unsigned long end);
+int nop_coherent_user_range(unsigned long, unsigned long);
+void nop_flush_kern_dcache_area(void *kaddr, size_t size);
+void nop_dma_map_area(const void *start, size_t size, int flags);
+void nop_dma_unmap_area(const void *start, size_t size, int flags);
+void nop_dma_flush_range(const void *start, const void *end);
+
+struct cpu_cache_fns nop_cache_fns __initconst = {
+ .flush_icache_all = nop_flush_icache_all,
+ .flush_kern_all = nop_flush_kern_cache_all,
+ .flush_kern_louis = nop_flush_kern_cache_all,
+ .flush_user_all = nop_flush_user_cache_all,
+ .flush_user_range = nop_flush_user_cache_range,
+ .coherent_kern_range = nop_coherent_kern_range,
+ .coherent_user_range = nop_coherent_user_range,
+ .flush_kern_dcache_area = nop_flush_kern_dcache_area,
+ .dma_map_area = nop_dma_map_area,
+ .dma_unmap_area = nop_dma_unmap_area,
+ .dma_flush_range = nop_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_CACHE_V7M
+void v7m_flush_icache_all(void);
+void v7m_flush_kern_cache_all(void);
+void v7m_flush_user_cache_all(void);
+void v7m_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void v7m_coherent_kern_range(unsigned long, unsigned long);
+int v7m_coherent_user_range(unsigned long, unsigned long);
+void v7m_flush_kern_dcache_area(void *, size_t);
+void v7m_dma_map_area(const void *, size_t, int);
+void v7m_dma_unmap_area(const void *, size_t, int);
+void v7m_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns v7m_cache_fns __initconst = {
+ .flush_icache_all = v7m_flush_icache_all,
+ .flush_kern_all = v7m_flush_kern_cache_all,
+ .flush_kern_louis = v7m_flush_kern_cache_all,
+ .flush_user_all = v7m_flush_user_cache_all,
+ .flush_user_range = v7m_flush_user_cache_range,
+ .coherent_kern_range = v7m_coherent_kern_range,
+ .coherent_user_range = v7m_coherent_user_range,
+ .flush_kern_dcache_area = v7m_flush_kern_dcache_area,
+ .dma_map_area = v7m_dma_map_area,
+ .dma_unmap_area = v7m_dma_unmap_area,
+ .dma_flush_range = v7m_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM1020
+void arm1020_flush_icache_all(void);
+void arm1020_flush_kern_cache_all(void);
+void arm1020_flush_user_cache_all(void);
+void arm1020_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm1020_coherent_kern_range(unsigned long, unsigned long);
+int arm1020_coherent_user_range(unsigned long, unsigned long);
+void arm1020_flush_kern_dcache_area(void *, size_t);
+void arm1020_dma_map_area(const void *, size_t, int);
+void arm1020_dma_unmap_area(const void *, size_t, int);
+void arm1020_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm1020_cache_fns __initconst = {
+ .flush_icache_all = arm1020_flush_icache_all,
+ .flush_kern_all = arm1020_flush_kern_cache_all,
+ .flush_kern_louis = arm1020_flush_kern_cache_all,
+ .flush_user_all = arm1020_flush_user_cache_all,
+ .flush_user_range = arm1020_flush_user_cache_range,
+ .coherent_kern_range = arm1020_coherent_kern_range,
+ .coherent_user_range = arm1020_coherent_user_range,
+ .flush_kern_dcache_area = arm1020_flush_kern_dcache_area,
+ .dma_map_area = arm1020_dma_map_area,
+ .dma_unmap_area = arm1020_dma_unmap_area,
+ .dma_flush_range = arm1020_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM1020E
+void arm1020e_flush_icache_all(void);
+void arm1020e_flush_kern_cache_all(void);
+void arm1020e_flush_user_cache_all(void);
+void arm1020e_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm1020e_coherent_kern_range(unsigned long, unsigned long);
+int arm1020e_coherent_user_range(unsigned long, unsigned long);
+void arm1020e_flush_kern_dcache_area(void *, size_t);
+void arm1020e_dma_map_area(const void *, size_t, int);
+void arm1020e_dma_unmap_area(const void *, size_t, int);
+void arm1020e_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm1020e_cache_fns __initconst = {
+ .flush_icache_all = arm1020e_flush_icache_all,
+ .flush_kern_all = arm1020e_flush_kern_cache_all,
+ .flush_kern_louis = arm1020e_flush_kern_cache_all,
+ .flush_user_all = arm1020e_flush_user_cache_all,
+ .flush_user_range = arm1020e_flush_user_cache_range,
+ .coherent_kern_range = arm1020e_coherent_kern_range,
+ .coherent_user_range = arm1020e_coherent_user_range,
+ .flush_kern_dcache_area = arm1020e_flush_kern_dcache_area,
+ .dma_map_area = arm1020e_dma_map_area,
+ .dma_unmap_area = arm1020e_dma_unmap_area,
+ .dma_flush_range = arm1020e_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM1022
+void arm1022_flush_icache_all(void);
+void arm1022_flush_kern_cache_all(void);
+void arm1022_flush_user_cache_all(void);
+void arm1022_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm1022_coherent_kern_range(unsigned long, unsigned long);
+int arm1022_coherent_user_range(unsigned long, unsigned long);
+void arm1022_flush_kern_dcache_area(void *, size_t);
+void arm1022_dma_map_area(const void *, size_t, int);
+void arm1022_dma_unmap_area(const void *, size_t, int);
+void arm1022_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm1022_cache_fns __initconst = {
+ .flush_icache_all = arm1022_flush_icache_all,
+ .flush_kern_all = arm1022_flush_kern_cache_all,
+ .flush_kern_louis = arm1022_flush_kern_cache_all,
+ .flush_user_all = arm1022_flush_user_cache_all,
+ .flush_user_range = arm1022_flush_user_cache_range,
+ .coherent_kern_range = arm1022_coherent_kern_range,
+ .coherent_user_range = arm1022_coherent_user_range,
+ .flush_kern_dcache_area = arm1022_flush_kern_dcache_area,
+ .dma_map_area = arm1022_dma_map_area,
+ .dma_unmap_area = arm1022_dma_unmap_area,
+ .dma_flush_range = arm1022_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM1026
+void arm1026_flush_icache_all(void);
+void arm1026_flush_kern_cache_all(void);
+void arm1026_flush_user_cache_all(void);
+void arm1026_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm1026_coherent_kern_range(unsigned long, unsigned long);
+int arm1026_coherent_user_range(unsigned long, unsigned long);
+void arm1026_flush_kern_dcache_area(void *, size_t);
+void arm1026_dma_map_area(const void *, size_t, int);
+void arm1026_dma_unmap_area(const void *, size_t, int);
+void arm1026_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm1026_cache_fns __initconst = {
+ .flush_icache_all = arm1026_flush_icache_all,
+ .flush_kern_all = arm1026_flush_kern_cache_all,
+ .flush_kern_louis = arm1026_flush_kern_cache_all,
+ .flush_user_all = arm1026_flush_user_cache_all,
+ .flush_user_range = arm1026_flush_user_cache_range,
+ .coherent_kern_range = arm1026_coherent_kern_range,
+ .coherent_user_range = arm1026_coherent_user_range,
+ .flush_kern_dcache_area = arm1026_flush_kern_dcache_area,
+ .dma_map_area = arm1026_dma_map_area,
+ .dma_unmap_area = arm1026_dma_unmap_area,
+ .dma_flush_range = arm1026_dma_flush_range,
+};
+#endif
+
+#if defined(CONFIG_CPU_ARM920T) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
+void arm920_flush_icache_all(void);
+void arm920_flush_kern_cache_all(void);
+void arm920_flush_user_cache_all(void);
+void arm920_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm920_coherent_kern_range(unsigned long, unsigned long);
+int arm920_coherent_user_range(unsigned long, unsigned long);
+void arm920_flush_kern_dcache_area(void *, size_t);
+void arm920_dma_map_area(const void *, size_t, int);
+void arm920_dma_unmap_area(const void *, size_t, int);
+void arm920_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm920_cache_fns __initconst = {
+ .flush_icache_all = arm920_flush_icache_all,
+ .flush_kern_all = arm920_flush_kern_cache_all,
+ .flush_kern_louis = arm920_flush_kern_cache_all,
+ .flush_user_all = arm920_flush_user_cache_all,
+ .flush_user_range = arm920_flush_user_cache_range,
+ .coherent_kern_range = arm920_coherent_kern_range,
+ .coherent_user_range = arm920_coherent_user_range,
+ .flush_kern_dcache_area = arm920_flush_kern_dcache_area,
+ .dma_map_area = arm920_dma_map_area,
+ .dma_unmap_area = arm920_dma_unmap_area,
+ .dma_flush_range = arm920_dma_flush_range,
+};
+#endif
+
+#if defined(CONFIG_CPU_ARM922T) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
+void arm922_flush_icache_all(void);
+void arm922_flush_kern_cache_all(void);
+void arm922_flush_user_cache_all(void);
+void arm922_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm922_coherent_kern_range(unsigned long, unsigned long);
+int arm922_coherent_user_range(unsigned long, unsigned long);
+void arm922_flush_kern_dcache_area(void *, size_t);
+void arm922_dma_map_area(const void *, size_t, int);
+void arm922_dma_unmap_area(const void *, size_t, int);
+void arm922_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm922_cache_fns __initconst = {
+ .flush_icache_all = arm922_flush_icache_all,
+ .flush_kern_all = arm922_flush_kern_cache_all,
+ .flush_kern_louis = arm922_flush_kern_cache_all,
+ .flush_user_all = arm922_flush_user_cache_all,
+ .flush_user_range = arm922_flush_user_cache_range,
+ .coherent_kern_range = arm922_coherent_kern_range,
+ .coherent_user_range = arm922_coherent_user_range,
+ .flush_kern_dcache_area = arm922_flush_kern_dcache_area,
+ .dma_map_area = arm922_dma_map_area,
+ .dma_unmap_area = arm922_dma_unmap_area,
+ .dma_flush_range = arm922_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM925T
+void arm925_flush_icache_all(void);
+void arm925_flush_kern_cache_all(void);
+void arm925_flush_user_cache_all(void);
+void arm925_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm925_coherent_kern_range(unsigned long, unsigned long);
+int arm925_coherent_user_range(unsigned long, unsigned long);
+void arm925_flush_kern_dcache_area(void *, size_t);
+void arm925_dma_map_area(const void *, size_t, int);
+void arm925_dma_unmap_area(const void *, size_t, int);
+void arm925_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm925_cache_fns __initconst = {
+ .flush_icache_all = arm925_flush_icache_all,
+ .flush_kern_all = arm925_flush_kern_cache_all,
+ .flush_kern_louis = arm925_flush_kern_cache_all,
+ .flush_user_all = arm925_flush_user_cache_all,
+ .flush_user_range = arm925_flush_user_cache_range,
+ .coherent_kern_range = arm925_coherent_kern_range,
+ .coherent_user_range = arm925_coherent_user_range,
+ .flush_kern_dcache_area = arm925_flush_kern_dcache_area,
+ .dma_map_area = arm925_dma_map_area,
+ .dma_unmap_area = arm925_dma_unmap_area,
+ .dma_flush_range = arm925_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM926T
+void arm926_flush_icache_all(void);
+void arm926_flush_kern_cache_all(void);
+void arm926_flush_user_cache_all(void);
+void arm926_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm926_coherent_kern_range(unsigned long, unsigned long);
+int arm926_coherent_user_range(unsigned long, unsigned long);
+void arm926_flush_kern_dcache_area(void *, size_t);
+void arm926_dma_map_area(const void *, size_t, int);
+void arm926_dma_unmap_area(const void *, size_t, int);
+void arm926_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm926_cache_fns __initconst = {
+ .flush_icache_all = arm926_flush_icache_all,
+ .flush_kern_all = arm926_flush_kern_cache_all,
+ .flush_kern_louis = arm926_flush_kern_cache_all,
+ .flush_user_all = arm926_flush_user_cache_all,
+ .flush_user_range = arm926_flush_user_cache_range,
+ .coherent_kern_range = arm926_coherent_kern_range,
+ .coherent_user_range = arm926_coherent_user_range,
+ .flush_kern_dcache_area = arm926_flush_kern_dcache_area,
+ .dma_map_area = arm926_dma_map_area,
+ .dma_unmap_area = arm926_dma_unmap_area,
+ .dma_flush_range = arm926_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM940T
+void arm940_flush_icache_all(void);
+void arm940_flush_kern_cache_all(void);
+void arm940_flush_user_cache_all(void);
+void arm940_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm940_coherent_kern_range(unsigned long, unsigned long);
+int arm940_coherent_user_range(unsigned long, unsigned long);
+void arm940_flush_kern_dcache_area(void *, size_t);
+void arm940_dma_map_area(const void *, size_t, int);
+void arm940_dma_unmap_area(const void *, size_t, int);
+void arm940_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm940_cache_fns __initconst = {
+ .flush_icache_all = arm940_flush_icache_all,
+ .flush_kern_all = arm940_flush_kern_cache_all,
+ .flush_kern_louis = arm940_flush_kern_cache_all,
+ .flush_user_all = arm940_flush_user_cache_all,
+ .flush_user_range = arm940_flush_user_cache_range,
+ .coherent_kern_range = arm940_coherent_kern_range,
+ .coherent_user_range = arm940_coherent_user_range,
+ .flush_kern_dcache_area = arm940_flush_kern_dcache_area,
+ .dma_map_area = arm940_dma_map_area,
+ .dma_unmap_area = arm940_dma_unmap_area,
+ .dma_flush_range = arm940_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_ARM946E
+void arm946_flush_icache_all(void);
+void arm946_flush_kern_cache_all(void);
+void arm946_flush_user_cache_all(void);
+void arm946_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void arm946_coherent_kern_range(unsigned long, unsigned long);
+int arm946_coherent_user_range(unsigned long, unsigned long);
+void arm946_flush_kern_dcache_area(void *, size_t);
+void arm946_dma_map_area(const void *, size_t, int);
+void arm946_dma_unmap_area(const void *, size_t, int);
+void arm946_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns arm946_cache_fns __initconst = {
+ .flush_icache_all = arm946_flush_icache_all,
+ .flush_kern_all = arm946_flush_kern_cache_all,
+ .flush_kern_louis = arm946_flush_kern_cache_all,
+ .flush_user_all = arm946_flush_user_cache_all,
+ .flush_user_range = arm946_flush_user_cache_range,
+ .coherent_kern_range = arm946_coherent_kern_range,
+ .coherent_user_range = arm946_coherent_user_range,
+ .flush_kern_dcache_area = arm946_flush_kern_dcache_area,
+ .dma_map_area = arm946_dma_map_area,
+ .dma_unmap_area = arm946_dma_unmap_area,
+ .dma_flush_range = arm946_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_XSCALE
+void xscale_flush_icache_all(void);
+void xscale_flush_kern_cache_all(void);
+void xscale_flush_user_cache_all(void);
+void xscale_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void xscale_coherent_kern_range(unsigned long, unsigned long);
+int xscale_coherent_user_range(unsigned long, unsigned long);
+void xscale_flush_kern_dcache_area(void *, size_t);
+void xscale_dma_map_area(const void *, size_t, int);
+void xscale_dma_unmap_area(const void *, size_t, int);
+void xscale_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns xscale_cache_fns __initconst = {
+ .flush_icache_all = xscale_flush_icache_all,
+ .flush_kern_all = xscale_flush_kern_cache_all,
+ .flush_kern_louis = xscale_flush_kern_cache_all,
+ .flush_user_all = xscale_flush_user_cache_all,
+ .flush_user_range = xscale_flush_user_cache_range,
+ .coherent_kern_range = xscale_coherent_kern_range,
+ .coherent_user_range = xscale_coherent_user_range,
+ .flush_kern_dcache_area = xscale_flush_kern_dcache_area,
+ .dma_map_area = xscale_dma_map_area,
+ .dma_unmap_area = xscale_dma_unmap_area,
+ .dma_flush_range = xscale_dma_flush_range,
+};
+
+/* The 80200 A0 and A1 need a special quirk for dma_map_area() */
+void xscale_80200_A0_A1_dma_map_area(const void *, size_t, int);
+
+struct cpu_cache_fns xscale_80200_A0_A1_cache_fns __initconst = {
+ .flush_icache_all = xscale_flush_icache_all,
+ .flush_kern_all = xscale_flush_kern_cache_all,
+ .flush_kern_louis = xscale_flush_kern_cache_all,
+ .flush_user_all = xscale_flush_user_cache_all,
+ .flush_user_range = xscale_flush_user_cache_range,
+ .coherent_kern_range = xscale_coherent_kern_range,
+ .coherent_user_range = xscale_coherent_user_range,
+ .flush_kern_dcache_area = xscale_flush_kern_dcache_area,
+ .dma_map_area = xscale_80200_A0_A1_dma_map_area,
+ .dma_unmap_area = xscale_dma_unmap_area,
+ .dma_flush_range = xscale_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_XSC3
+void xsc3_flush_icache_all(void);
+void xsc3_flush_kern_cache_all(void);
+void xsc3_flush_user_cache_all(void);
+void xsc3_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void xsc3_coherent_kern_range(unsigned long, unsigned long);
+int xsc3_coherent_user_range(unsigned long, unsigned long);
+void xsc3_flush_kern_dcache_area(void *, size_t);
+void xsc3_dma_map_area(const void *, size_t, int);
+void xsc3_dma_unmap_area(const void *, size_t, int);
+void xsc3_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns xsc3_cache_fns __initconst = {
+ .flush_icache_all = xsc3_flush_icache_all,
+ .flush_kern_all = xsc3_flush_kern_cache_all,
+ .flush_kern_louis = xsc3_flush_kern_cache_all,
+ .flush_user_all = xsc3_flush_user_cache_all,
+ .flush_user_range = xsc3_flush_user_cache_range,
+ .coherent_kern_range = xsc3_coherent_kern_range,
+ .coherent_user_range = xsc3_coherent_user_range,
+ .flush_kern_dcache_area = xsc3_flush_kern_dcache_area,
+ .dma_map_area = xsc3_dma_map_area,
+ .dma_unmap_area = xsc3_dma_unmap_area,
+ .dma_flush_range = xsc3_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_MOHAWK
+void mohawk_flush_icache_all(void);
+void mohawk_flush_kern_cache_all(void);
+void mohawk_flush_user_cache_all(void);
+void mohawk_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void mohawk_coherent_kern_range(unsigned long, unsigned long);
+int mohawk_coherent_user_range(unsigned long, unsigned long);
+void mohawk_flush_kern_dcache_area(void *, size_t);
+void mohawk_dma_map_area(const void *, size_t, int);
+void mohawk_dma_unmap_area(const void *, size_t, int);
+void mohawk_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns mohawk_cache_fns __initconst = {
+ .flush_icache_all = mohawk_flush_icache_all,
+ .flush_kern_all = mohawk_flush_kern_cache_all,
+ .flush_kern_louis = mohawk_flush_kern_cache_all,
+ .flush_user_all = mohawk_flush_user_cache_all,
+ .flush_user_range = mohawk_flush_user_cache_range,
+ .coherent_kern_range = mohawk_coherent_kern_range,
+ .coherent_user_range = mohawk_coherent_user_range,
+ .flush_kern_dcache_area = mohawk_flush_kern_dcache_area,
+ .dma_map_area = mohawk_dma_map_area,
+ .dma_unmap_area = mohawk_dma_unmap_area,
+ .dma_flush_range = mohawk_dma_flush_range,
+};
+#endif
+
+#ifdef CONFIG_CPU_FEROCEON
+void feroceon_flush_icache_all(void);
+void feroceon_flush_kern_cache_all(void);
+void feroceon_flush_user_cache_all(void);
+void feroceon_flush_user_cache_range(unsigned long, unsigned long, unsigned int);
+void feroceon_coherent_kern_range(unsigned long, unsigned long);
+int feroceon_coherent_user_range(unsigned long, unsigned long);
+void feroceon_flush_kern_dcache_area(void *, size_t);
+void feroceon_dma_map_area(const void *, size_t, int);
+void feroceon_dma_unmap_area(const void *, size_t, int);
+void feroceon_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns feroceon_cache_fns __initconst = {
+ .flush_icache_all = feroceon_flush_icache_all,
+ .flush_kern_all = feroceon_flush_kern_cache_all,
+ .flush_kern_louis = feroceon_flush_kern_cache_all,
+ .flush_user_all = feroceon_flush_user_cache_all,
+ .flush_user_range = feroceon_flush_user_cache_range,
+ .coherent_kern_range = feroceon_coherent_kern_range,
+ .coherent_user_range = feroceon_coherent_user_range,
+ .flush_kern_dcache_area = feroceon_flush_kern_dcache_area,
+ .dma_map_area = feroceon_dma_map_area,
+ .dma_unmap_area = feroceon_dma_unmap_area,
+ .dma_flush_range = feroceon_dma_flush_range,
+};
+
+void feroceon_range_flush_kern_dcache_area(void *, size_t);
+void feroceon_range_dma_map_area(const void *, size_t, int);
+void feroceon_range_dma_flush_range(const void *, const void *);
+
+struct cpu_cache_fns feroceon_range_cache_fns __initconst = {
+ .flush_icache_all = feroceon_flush_icache_all,
+ .flush_kern_all = feroceon_flush_kern_cache_all,
+ .flush_kern_louis = feroceon_flush_kern_cache_all,
+ .flush_user_all = feroceon_flush_user_cache_all,
+ .flush_user_range = feroceon_flush_user_cache_range,
+ .coherent_kern_range = feroceon_coherent_kern_range,
+ .coherent_user_range = feroceon_coherent_user_range,
+ .flush_kern_dcache_area = feroceon_range_flush_kern_dcache_area,
+ .dma_map_area = feroceon_range_dma_map_area,
+ .dma_unmap_area = feroceon_dma_unmap_area,
+ .dma_flush_range = feroceon_range_dma_flush_range,
+};
+#endif
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index b94850b57995..97db5397c320 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -33,8 +33,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
}
}
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
{
if (IS_ENABLED(CONFIG_CPU_V7M)) {
/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f68db05eba29..5adf1769eee4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1709,11 +1709,15 @@ void arm_iommu_detach_device(struct device *dev)
}
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
-static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+static void arm_setup_iommu_dma_ops(struct device *dev)
{
struct dma_iommu_mapping *mapping;
+ u64 dma_base = 0, size = 1ULL << 32;
+ if (dev->dma_range_map) {
+ dma_base = dma_range_map_min(dev->dma_range_map);
+ size = dma_range_map_max(dev->dma_range_map) - dma_base;
+ }
mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
if (IS_ERR(mapping)) {
pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
@@ -1744,8 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
#else
-static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+static void arm_setup_iommu_dma_ops(struct device *dev)
{
}
@@ -1753,8 +1756,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
#endif /* CONFIG_ARM_DMA_USE_IOMMU */
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
{
/*
* Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1774,7 +1776,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
return;
if (device_iommu_mapped(dev))
- arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
+ arm_setup_iommu_dma_ops(dev);
xen_setup_dma_ops(dev);
dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 439dc6a26bb9..ab01b51de559 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -25,6 +25,8 @@
#include "fault.h"
+#ifdef CONFIG_MMU
+
bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{
unsigned long addr = (unsigned long)unsafe_src;
@@ -32,8 +34,6 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
return addr >= TASK_SIZE && ULONG_MAX - addr >= size;
}
-#ifdef CONFIG_MMU
-
/*
* This is useful to dump out the page tables associated with
* 'addr' in mm 'mm'.
@@ -226,9 +226,6 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
}
#ifdef CONFIG_MMU
-#define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000)
-#define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000)
-
static inline bool is_permission_fault(unsigned int fsr)
{
int fs = fsr_fs(fsr);
@@ -242,6 +239,27 @@ static inline bool is_permission_fault(unsigned int fsr)
return false;
}
+#ifdef CONFIG_CPU_TTBR0_PAN
+static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
+{
+ struct svc_pt_regs *svcregs;
+
+ /* If we are in user mode: permission granted */
+ if (user_mode(regs))
+ return true;
+
+ /* uaccess state saved above pt_regs on SVC exception entry */
+ svcregs = to_svc_pt_regs(regs);
+
+ return !(svcregs->ttbcr & TTBCR_EPD0);
+}
+#else
+static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
+{
+ return true;
+}
+#endif
+
static int __kprobes
do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
@@ -285,6 +303,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
+ /*
+ * Privileged access aborts with CONFIG_CPU_TTBR0_PAN enabled are
+ * routed via the translation fault mechanism. Check whether uaccess
+ * is disabled while in kernel mode.
+ */
+ if (!ttbr0_usermode_access_allowed(regs))
+ goto no_context;
+
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;
@@ -294,7 +320,10 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (!(vma->vm_flags & vm_flags)) {
vma_end_read(vma);
- goto lock_mmap;
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ fault = 0;
+ code = SEGV_ACCERR;
+ goto bad_area;
}
fault = handle_mm_fault(vma, addr, flags | FAULT_FLAG_VMA_LOCK, regs);
if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
@@ -319,7 +348,8 @@ lock_mmap:
retry:
vma = lock_mm_and_find_vma(mm, addr, regs);
if (unlikely(!vma)) {
- fault = VM_FAULT_BADMAP;
+ fault = 0;
+ code = SEGV_MAPERR;
goto bad_area;
}
@@ -327,10 +357,14 @@ retry:
* ok, we have a good vm_area for this memory access, check the
* permissions on the VMA allow for the fault which occurred.
*/
- if (!(vma->vm_flags & vm_flags))
- fault = VM_FAULT_BADACCESS;
- else
- fault = handle_mm_fault(vma, addr & PAGE_MASK, flags, regs);
+ if (!(vma->vm_flags & vm_flags)) {
+ mmap_read_unlock(mm);
+ fault = 0;
+ code = SEGV_ACCERR;
+ goto bad_area;
+ }
+
+ fault = handle_mm_fault(vma, addr & PAGE_MASK, flags, regs);
/* If we need to retry but a fatal signal is pending, handle the
* signal first. We do not need to release the mmap_lock because
@@ -356,12 +390,11 @@ retry:
mmap_read_unlock(mm);
done:
- /*
- * Handle the "normal" case first - VM_FAULT_MAJOR
- */
- if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
+ /* Handle the "normal" case first */
+ if (likely(!(fault & VM_FAULT_ERROR)))
return 0;
+ code = SEGV_MAPERR;
bad_area:
/*
* If we are in kernel mode at this point, we
@@ -393,8 +426,6 @@ bad_area:
* isn't in our memory map..
*/
sig = SIGSEGV;
- code = fault == VM_FAULT_BADACCESS ?
- SEGV_ACCERR : SEGV_MAPERR;
}
__do_user_fault(addr, fsr, sig, code, regs);
diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c
deleted file mode 100644
index dd7a0277c5c0..000000000000
--- a/arch/arm/mm/hugetlbpage.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mm/hugetlbpage.c
- *
- * Copyright (C) 2012 ARM Ltd.
- *
- * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's patches
- */
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/hugetlb.h>
-#include <linux/pagemap.h>
-#include <linux/err.h>
-#include <linux/sysctl.h>
-#include <asm/mman.h>
-#include <asm/tlb.h>
-#include <asm/tlbflush.h>
-
-/*
- * On ARM, huge pages are backed by pmd's rather than pte's, so we do a lot
- * of type casting from pmd_t * to pte_t *.
- */
-
-int pud_huge(pud_t pud)
-{
- return 0;
-}
-
-int pmd_huge(pmd_t pmd)
-{
- return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
-}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index e8c6f4be0ce1..5345d218899a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -22,6 +22,7 @@
#include <linux/sizes.h>
#include <linux/stop_machine.h>
#include <linux/swiotlb.h>
+#include <linux/execmem.h>
#include <asm/cp15.h>
#include <asm/mach-types.h>
@@ -486,3 +487,47 @@ void free_initrd_mem(unsigned long start, unsigned long end)
free_reserved_area((void *)start, (void *)end, -1, "initrd");
}
#endif
+
+#ifdef CONFIG_EXECMEM
+
+#ifdef CONFIG_XIP_KERNEL
+/*
+ * The XIP kernel text is mapped in the module area for modules and
+ * some other stuff to work without any indirect relocations.
+ * MODULES_VADDR is redefined here and not in asm/memory.h to avoid
+ * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
+ */
+#undef MODULES_VADDR
+#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
+#endif
+
+#ifdef CONFIG_MMU
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ unsigned long fallback_start = 0, fallback_end = 0;
+
+ if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS)) {
+ fallback_start = VMALLOC_START;
+ fallback_end = VMALLOC_END;
+ }
+
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = MODULES_VADDR,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL_EXEC,
+ .alignment = 1,
+ .fallback_start = fallback_start,
+ .fallback_end = fallback_end,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_MMU */
+
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index a0f8a0ca0788..d65d0e6ed10a 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -34,7 +34,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct vm_area_struct *vma;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/*
* We only need to do colour alignment if either the I or D
@@ -68,7 +68,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- info.flags = 0;
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
@@ -87,7 +86,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long addr = addr0;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/*
* We only need to do colour alignment if either the I or D
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index c24e29c0b9a4..3f774856ca67 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1687,9 +1687,8 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
*/
cr = get_cr();
set_cr(cr & ~(CR_I | CR_C));
- asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
- asm volatile("mcr p15, 0, %0, c2, c0, 2"
- : : "r" (ttbcr & ~(3 << 8 | 3 << 10)));
+ ttbcr = cpu_get_ttbcr();
+ cpu_set_ttbcr(ttbcr & ~(3 << 8 | 3 << 10));
flush_cache_all();
/*
@@ -1701,7 +1700,7 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
lpae_pgtables_remap(offset, pa_pgd);
/* Re-enable the caches and cacheable TLB walks */
- asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));
+ cpu_set_ttbcr(ttbcr);
set_cr(cr);
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 6837cf7a4812..d0ce3414a13e 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -56,18 +57,20 @@
/*
* cpu_arm1020_proc_init()
*/
-ENTRY(cpu_arm1020_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm1020_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm1020_proc_init)
/*
* cpu_arm1020_proc_fin()
*/
-ENTRY(cpu_arm1020_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm1020_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm1020_proc_fin)
/*
* cpu_arm1020_reset(loc)
@@ -80,7 +83,7 @@ ENTRY(cpu_arm1020_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm1020_reset)
+SYM_TYPED_FUNC_START(cpu_arm1020_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -92,16 +95,17 @@ ENTRY(cpu_arm1020_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm1020_reset)
+SYM_FUNC_END(cpu_arm1020_reset)
.popsection
/*
* cpu_arm1020_do_idle()
*/
.align 5
-ENTRY(cpu_arm1020_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm1020_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_arm1020_do_idle)
/* ================================= CACHE ================================ */
@@ -112,13 +116,13 @@ ENTRY(cpu_arm1020_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm1020_flush_icache_all)
+SYM_TYPED_FUNC_START(arm1020_flush_icache_all)
#ifndef CONFIG_CPU_ICACHE_DISABLE
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
#endif
ret lr
-ENDPROC(arm1020_flush_icache_all)
+SYM_FUNC_END(arm1020_flush_icache_all)
/*
* flush_user_cache_all()
@@ -126,14 +130,14 @@ ENDPROC(arm1020_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(arm1020_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm1020_flush_user_cache_all, arm1020_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm1020_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm1020_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -154,6 +158,7 @@ __flush_whole_cache:
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -165,7 +170,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags for this space
*/
-ENTRY(arm1020_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm1020_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -185,6 +190,7 @@ ENTRY(arm1020_flush_user_cache_range)
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -196,8 +202,11 @@ ENTRY(arm1020_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1020_coherent_kern_range)
- /* FALLTRHOUGH */
+SYM_TYPED_FUNC_START(arm1020_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm1020_coherent_user_range
+#endif
+SYM_FUNC_END(arm1020_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -209,7 +218,7 @@ ENTRY(arm1020_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1020_coherent_user_range)
+SYM_TYPED_FUNC_START(arm1020_coherent_user_range)
mov ip, #0
bic r0, r0, #CACHE_DLINESIZE - 1
mcr p15, 0, ip, c7, c10, 4
@@ -227,6 +236,7 @@ ENTRY(arm1020_coherent_user_range)
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm1020_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -237,7 +247,7 @@ ENTRY(arm1020_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm1020_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm1020_flush_kern_dcache_area)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
add r1, r0, r1
@@ -249,6 +259,7 @@ ENTRY(arm1020_flush_kern_dcache_area)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -314,7 +325,7 @@ arm1020_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1020_dma_flush_range)
+SYM_TYPED_FUNC_START(arm1020_dma_flush_range)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CACHE_DLINESIZE - 1
@@ -327,6 +338,7 @@ ENTRY(arm1020_dma_flush_range)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -334,13 +346,13 @@ ENTRY(arm1020_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1020_dma_map_area)
+SYM_TYPED_FUNC_START(arm1020_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm1020_dma_clean_range
bcs arm1020_dma_inv_range
b arm1020_dma_flush_range
-ENDPROC(arm1020_dma_map_area)
+SYM_FUNC_END(arm1020_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -348,18 +360,12 @@ ENDPROC(arm1020_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1020_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm1020_dma_unmap_area)
ret lr
-ENDPROC(arm1020_dma_unmap_area)
-
- .globl arm1020_flush_kern_cache_louis
- .equ arm1020_flush_kern_cache_louis, arm1020_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm1020
+SYM_FUNC_END(arm1020_dma_unmap_area)
.align 5
-ENTRY(cpu_arm1020_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm1020_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_DISABLE
mov ip, #0
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -369,6 +375,7 @@ ENTRY(cpu_arm1020_dcache_clean_area)
bhi 1b
#endif
ret lr
+SYM_FUNC_END(cpu_arm1020_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -380,7 +387,7 @@ ENTRY(cpu_arm1020_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm1020_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm1020_switch_mm)
#ifdef CONFIG_MMU
#ifndef CONFIG_CPU_DCACHE_DISABLE
mcr p15, 0, r3, c7, c10, 4
@@ -408,14 +415,15 @@ ENTRY(cpu_arm1020_switch_mm)
mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
#endif /* CONFIG_MMU */
ret lr
-
+SYM_FUNC_END(cpu_arm1020_switch_mm)
+
/*
* cpu_arm1020_set_pte(ptep, pte)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1020_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm1020_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -426,6 +434,7 @@ ENTRY(cpu_arm1020_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif /* CONFIG_MMU */
ret lr
+SYM_FUNC_END(cpu_arm1020_set_pte_ext)
.type __arm1020_setup, #function
__arm1020_setup:
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index df49b10250b8..64f031bf6eff 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -56,18 +57,20 @@
/*
* cpu_arm1020e_proc_init()
*/
-ENTRY(cpu_arm1020e_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm1020e_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm1020e_proc_init)
/*
* cpu_arm1020e_proc_fin()
*/
-ENTRY(cpu_arm1020e_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm1020e_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm1020e_proc_fin)
/*
* cpu_arm1020e_reset(loc)
@@ -80,7 +83,7 @@ ENTRY(cpu_arm1020e_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm1020e_reset)
+SYM_TYPED_FUNC_START(cpu_arm1020e_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -92,16 +95,17 @@ ENTRY(cpu_arm1020e_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm1020e_reset)
+SYM_FUNC_END(cpu_arm1020e_reset)
.popsection
/*
* cpu_arm1020e_do_idle()
*/
.align 5
-ENTRY(cpu_arm1020e_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm1020e_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_arm1020e_do_idle)
/* ================================= CACHE ================================ */
@@ -112,13 +116,13 @@ ENTRY(cpu_arm1020e_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm1020e_flush_icache_all)
+SYM_TYPED_FUNC_START(arm1020e_flush_icache_all)
#ifndef CONFIG_CPU_ICACHE_DISABLE
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
#endif
ret lr
-ENDPROC(arm1020e_flush_icache_all)
+SYM_FUNC_END(arm1020e_flush_icache_all)
/*
* flush_user_cache_all()
@@ -126,14 +130,14 @@ ENDPROC(arm1020e_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(arm1020e_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm1020e_flush_user_cache_all, arm1020e_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm1020e_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm1020e_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -153,6 +157,7 @@ __flush_whole_cache:
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020e_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -164,7 +169,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags for this space
*/
-ENTRY(arm1020e_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm1020e_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -182,6 +187,7 @@ ENTRY(arm1020e_flush_user_cache_range)
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020e_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -193,8 +199,12 @@ ENTRY(arm1020e_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1020e_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm1020e_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm1020e_coherent_user_range
+#endif
+SYM_FUNC_END(arm1020e_coherent_kern_range)
+
/*
* coherent_user_range(start, end)
*
@@ -205,7 +215,7 @@ ENTRY(arm1020e_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1020e_coherent_user_range)
+SYM_TYPED_FUNC_START(arm1020e_coherent_user_range)
mov ip, #0
bic r0, r0, #CACHE_DLINESIZE - 1
1:
@@ -221,6 +231,7 @@ ENTRY(arm1020e_coherent_user_range)
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm1020e_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -231,7 +242,7 @@ ENTRY(arm1020e_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm1020e_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm1020e_flush_kern_dcache_area)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
add r1, r0, r1
@@ -242,6 +253,7 @@ ENTRY(arm1020e_flush_kern_dcache_area)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020e_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -302,7 +314,7 @@ arm1020e_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1020e_dma_flush_range)
+SYM_TYPED_FUNC_START(arm1020e_dma_flush_range)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CACHE_DLINESIZE - 1
@@ -313,6 +325,7 @@ ENTRY(arm1020e_dma_flush_range)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1020e_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -320,13 +333,13 @@ ENTRY(arm1020e_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1020e_dma_map_area)
+SYM_TYPED_FUNC_START(arm1020e_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm1020e_dma_clean_range
bcs arm1020e_dma_inv_range
b arm1020e_dma_flush_range
-ENDPROC(arm1020e_dma_map_area)
+SYM_FUNC_END(arm1020e_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -334,18 +347,12 @@ ENDPROC(arm1020e_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1020e_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm1020e_dma_unmap_area)
ret lr
-ENDPROC(arm1020e_dma_unmap_area)
-
- .globl arm1020e_flush_kern_cache_louis
- .equ arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm1020e
+SYM_FUNC_END(arm1020e_dma_unmap_area)
.align 5
-ENTRY(cpu_arm1020e_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm1020e_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_DISABLE
mov ip, #0
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -354,6 +361,7 @@ ENTRY(cpu_arm1020e_dcache_clean_area)
bhi 1b
#endif
ret lr
+SYM_FUNC_END(cpu_arm1020e_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -365,7 +373,7 @@ ENTRY(cpu_arm1020e_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm1020e_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm1020e_switch_mm)
#ifdef CONFIG_MMU
#ifndef CONFIG_CPU_DCACHE_DISABLE
mcr p15, 0, r3, c7, c10, 4
@@ -392,14 +400,15 @@ ENTRY(cpu_arm1020e_switch_mm)
mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
-
+SYM_FUNC_END(cpu_arm1020e_switch_mm)
+
/*
* cpu_arm1020e_set_pte(ptep, pte)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1020e_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm1020e_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -408,6 +417,7 @@ ENTRY(cpu_arm1020e_set_pte_ext)
#endif
#endif /* CONFIG_MMU */
ret lr
+SYM_FUNC_END(cpu_arm1020e_set_pte_ext)
.type __arm1020e_setup, #function
__arm1020e_setup:
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index e89ce467f672..42ed5ed07252 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -56,18 +57,20 @@
/*
* cpu_arm1022_proc_init()
*/
-ENTRY(cpu_arm1022_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm1022_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm1022_proc_init)
/*
* cpu_arm1022_proc_fin()
*/
-ENTRY(cpu_arm1022_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm1022_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm1022_proc_fin)
/*
* cpu_arm1022_reset(loc)
@@ -80,7 +83,7 @@ ENTRY(cpu_arm1022_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm1022_reset)
+SYM_TYPED_FUNC_START(cpu_arm1022_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -92,16 +95,17 @@ ENTRY(cpu_arm1022_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm1022_reset)
+SYM_FUNC_END(cpu_arm1022_reset)
.popsection
/*
* cpu_arm1022_do_idle()
*/
.align 5
-ENTRY(cpu_arm1022_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm1022_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_arm1022_do_idle)
/* ================================= CACHE ================================ */
@@ -112,13 +116,13 @@ ENTRY(cpu_arm1022_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm1022_flush_icache_all)
+SYM_TYPED_FUNC_START(arm1022_flush_icache_all)
#ifndef CONFIG_CPU_ICACHE_DISABLE
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
#endif
ret lr
-ENDPROC(arm1022_flush_icache_all)
+SYM_FUNC_END(arm1022_flush_icache_all)
/*
* flush_user_cache_all()
@@ -126,14 +130,14 @@ ENDPROC(arm1022_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(arm1022_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm1022_flush_user_cache_all, arm1022_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm1022_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm1022_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -152,6 +156,7 @@ __flush_whole_cache:
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1022_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -163,7 +168,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags for this space
*/
-ENTRY(arm1022_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm1022_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -181,6 +186,7 @@ ENTRY(arm1022_flush_user_cache_range)
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1022_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -192,8 +198,11 @@ ENTRY(arm1022_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1022_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm1022_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm1022_coherent_user_range
+#endif
+SYM_FUNC_END(arm1022_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -205,7 +214,7 @@ ENTRY(arm1022_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1022_coherent_user_range)
+SYM_TYPED_FUNC_START(arm1022_coherent_user_range)
mov ip, #0
bic r0, r0, #CACHE_DLINESIZE - 1
1:
@@ -221,6 +230,7 @@ ENTRY(arm1022_coherent_user_range)
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm1022_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -231,7 +241,7 @@ ENTRY(arm1022_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm1022_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm1022_flush_kern_dcache_area)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
add r1, r0, r1
@@ -242,6 +252,7 @@ ENTRY(arm1022_flush_kern_dcache_area)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1022_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -302,7 +313,7 @@ arm1022_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1022_dma_flush_range)
+SYM_TYPED_FUNC_START(arm1022_dma_flush_range)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CACHE_DLINESIZE - 1
@@ -313,6 +324,7 @@ ENTRY(arm1022_dma_flush_range)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1022_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -320,13 +332,13 @@ ENTRY(arm1022_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1022_dma_map_area)
+SYM_TYPED_FUNC_START(arm1022_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm1022_dma_clean_range
bcs arm1022_dma_inv_range
b arm1022_dma_flush_range
-ENDPROC(arm1022_dma_map_area)
+SYM_FUNC_END(arm1022_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -334,18 +346,12 @@ ENDPROC(arm1022_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1022_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm1022_dma_unmap_area)
ret lr
-ENDPROC(arm1022_dma_unmap_area)
-
- .globl arm1022_flush_kern_cache_louis
- .equ arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm1022
+SYM_FUNC_END(arm1022_dma_unmap_area)
.align 5
-ENTRY(cpu_arm1022_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm1022_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_DISABLE
mov ip, #0
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -354,6 +360,7 @@ ENTRY(cpu_arm1022_dcache_clean_area)
bhi 1b
#endif
ret lr
+SYM_FUNC_END(cpu_arm1022_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -365,7 +372,7 @@ ENTRY(cpu_arm1022_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm1022_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm1022_switch_mm)
#ifdef CONFIG_MMU
#ifndef CONFIG_CPU_DCACHE_DISABLE
mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
@@ -385,14 +392,15 @@ ENTRY(cpu_arm1022_switch_mm)
mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
-
+SYM_FUNC_END(cpu_arm1022_switch_mm)
+
/*
* cpu_arm1022_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1022_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm1022_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -401,6 +409,7 @@ ENTRY(cpu_arm1022_set_pte_ext)
#endif
#endif /* CONFIG_MMU */
ret lr
+SYM_FUNC_END(cpu_arm1022_set_pte_ext)
.type __arm1022_setup, #function
__arm1022_setup:
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 7fdd1a205e8e..b3ae62cd553a 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -56,18 +57,20 @@
/*
* cpu_arm1026_proc_init()
*/
-ENTRY(cpu_arm1026_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm1026_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm1026_proc_init)
/*
* cpu_arm1026_proc_fin()
*/
-ENTRY(cpu_arm1026_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm1026_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm1026_proc_fin)
/*
* cpu_arm1026_reset(loc)
@@ -80,7 +83,7 @@ ENTRY(cpu_arm1026_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm1026_reset)
+SYM_TYPED_FUNC_START(cpu_arm1026_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -92,16 +95,17 @@ ENTRY(cpu_arm1026_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm1026_reset)
+SYM_FUNC_END(cpu_arm1026_reset)
.popsection
/*
* cpu_arm1026_do_idle()
*/
.align 5
-ENTRY(cpu_arm1026_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm1026_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_arm1026_do_idle)
/* ================================= CACHE ================================ */
@@ -112,13 +116,13 @@ ENTRY(cpu_arm1026_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm1026_flush_icache_all)
+SYM_TYPED_FUNC_START(arm1026_flush_icache_all)
#ifndef CONFIG_CPU_ICACHE_DISABLE
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
#endif
ret lr
-ENDPROC(arm1026_flush_icache_all)
+SYM_FUNC_END(arm1026_flush_icache_all)
/*
* flush_user_cache_all()
@@ -126,14 +130,14 @@ ENDPROC(arm1026_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(arm1026_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm1026_flush_user_cache_all, arm1026_flush_kern_cache_all)
+
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm1026_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm1026_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -147,6 +151,7 @@ __flush_whole_cache:
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1026_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -158,7 +163,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags for this space
*/
-ENTRY(arm1026_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm1026_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -176,6 +181,7 @@ ENTRY(arm1026_flush_user_cache_range)
#endif
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1026_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -187,8 +193,12 @@ ENTRY(arm1026_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1026_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm1026_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm1026_coherent_user_range
+#endif
+SYM_FUNC_END(arm1026_coherent_kern_range)
+
/*
* coherent_user_range(start, end)
*
@@ -199,7 +209,7 @@ ENTRY(arm1026_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1026_coherent_user_range)
+SYM_TYPED_FUNC_START(arm1026_coherent_user_range)
mov ip, #0
bic r0, r0, #CACHE_DLINESIZE - 1
1:
@@ -215,6 +225,7 @@ ENTRY(arm1026_coherent_user_range)
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm1026_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -225,7 +236,7 @@ ENTRY(arm1026_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm1026_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm1026_flush_kern_dcache_area)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
add r1, r0, r1
@@ -236,6 +247,7 @@ ENTRY(arm1026_flush_kern_dcache_area)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1026_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -296,7 +308,7 @@ arm1026_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm1026_dma_flush_range)
+SYM_TYPED_FUNC_START(arm1026_dma_flush_range)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CACHE_DLINESIZE - 1
@@ -307,6 +319,7 @@ ENTRY(arm1026_dma_flush_range)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm1026_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -314,13 +327,13 @@ ENTRY(arm1026_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1026_dma_map_area)
+SYM_TYPED_FUNC_START(arm1026_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm1026_dma_clean_range
bcs arm1026_dma_inv_range
b arm1026_dma_flush_range
-ENDPROC(arm1026_dma_map_area)
+SYM_FUNC_END(arm1026_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -328,18 +341,12 @@ ENDPROC(arm1026_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm1026_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm1026_dma_unmap_area)
ret lr
-ENDPROC(arm1026_dma_unmap_area)
-
- .globl arm1026_flush_kern_cache_louis
- .equ arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm1026
+SYM_FUNC_END(arm1026_dma_unmap_area)
.align 5
-ENTRY(cpu_arm1026_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm1026_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_DISABLE
mov ip, #0
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -348,6 +355,7 @@ ENTRY(cpu_arm1026_dcache_clean_area)
bhi 1b
#endif
ret lr
+SYM_FUNC_END(cpu_arm1026_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -359,7 +367,7 @@ ENTRY(cpu_arm1026_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm1026_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm1026_switch_mm)
#ifdef CONFIG_MMU
mov r1, #0
#ifndef CONFIG_CPU_DCACHE_DISABLE
@@ -374,14 +382,15 @@ ENTRY(cpu_arm1026_switch_mm)
mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
-
+SYM_FUNC_END(cpu_arm1026_switch_mm)
+
/*
* cpu_arm1026_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1026_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm1026_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -390,6 +399,7 @@ ENTRY(cpu_arm1026_set_pte_ext)
#endif
#endif /* CONFIG_MMU */
ret lr
+SYM_FUNC_END(cpu_arm1026_set_pte_ext)
.type __arm1026_setup, #function
__arm1026_setup:
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 3b687e6dd9fd..59732c334e1d 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -20,6 +20,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -35,24 +36,30 @@
*
* Notes : This processor does not require these
*/
-ENTRY(cpu_arm720_dcache_clean_area)
-ENTRY(cpu_arm720_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm720_dcache_clean_area)
ret lr
+SYM_FUNC_END(cpu_arm720_dcache_clean_area)
-ENTRY(cpu_arm720_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm720_proc_init)
+ ret lr
+SYM_FUNC_END(cpu_arm720_proc_init)
+
+SYM_TYPED_FUNC_START(cpu_arm720_proc_fin)
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm720_proc_fin)
/*
* Function: arm720_proc_do_idle(void)
* Params : r0 = unused
* Purpose : put the processor in proper idle mode
*/
-ENTRY(cpu_arm720_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm720_do_idle)
ret lr
+SYM_FUNC_END(cpu_arm720_do_idle)
/*
* Function: arm720_switch_mm(unsigned long pgd_phys)
@@ -60,7 +67,7 @@ ENTRY(cpu_arm720_do_idle)
* Purpose : Perform a task switch, saving the old process' state and restoring
* the new.
*/
-ENTRY(cpu_arm720_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm720_switch_mm)
#ifdef CONFIG_MMU
mov r1, #0
mcr p15, 0, r1, c7, c7, 0 @ invalidate cache
@@ -68,6 +75,7 @@ ENTRY(cpu_arm720_switch_mm)
mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4)
#endif
ret lr
+SYM_FUNC_END(cpu_arm720_switch_mm)
/*
* Function: arm720_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
@@ -76,11 +84,12 @@ ENTRY(cpu_arm720_switch_mm)
* Purpose : Set a PTE and flush it out of any WB cache
*/
.align 5
-ENTRY(cpu_arm720_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm720_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext wc_disable=0
#endif
ret lr
+SYM_FUNC_END(cpu_arm720_set_pte_ext)
/*
* Function: arm720_reset
@@ -88,7 +97,7 @@ ENTRY(cpu_arm720_set_pte_ext)
* Notes : This sets up everything for a reset
*/
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm720_reset)
+SYM_TYPED_FUNC_START(cpu_arm720_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
#ifdef CONFIG_MMU
@@ -99,7 +108,7 @@ ENTRY(cpu_arm720_reset)
bic ip, ip, #0x2100 @ ..v....s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm720_reset)
+SYM_FUNC_END(cpu_arm720_reset)
.popsection
.type __arm710_setup, #function
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index f2ec3bc60874..78854df63964 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -6,6 +6,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -24,21 +25,32 @@
*
* These are not required.
*/
-ENTRY(cpu_arm740_proc_init)
-ENTRY(cpu_arm740_do_idle)
-ENTRY(cpu_arm740_dcache_clean_area)
-ENTRY(cpu_arm740_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm740_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm740_proc_init)
+
+SYM_TYPED_FUNC_START(cpu_arm740_do_idle)
+ ret lr
+SYM_FUNC_END(cpu_arm740_do_idle)
+
+SYM_TYPED_FUNC_START(cpu_arm740_dcache_clean_area)
+ ret lr
+SYM_FUNC_END(cpu_arm740_dcache_clean_area)
+
+SYM_TYPED_FUNC_START(cpu_arm740_switch_mm)
+ ret lr
+SYM_FUNC_END(cpu_arm740_switch_mm)
/*
* cpu_arm740_proc_fin()
*/
-ENTRY(cpu_arm740_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm740_proc_fin)
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x3f000000 @ bank/f/lock/s
bic r0, r0, #0x0000000c @ w-buffer/cache
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm740_proc_fin)
/*
* cpu_arm740_reset(loc)
@@ -46,14 +58,14 @@ ENTRY(cpu_arm740_proc_fin)
* Notes : This sets up everything for a reset
*/
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm740_reset)
+SYM_TYPED_FUNC_START(cpu_arm740_reset)
mov ip, #0
mcr p15, 0, ip, c7, c0, 0 @ invalidate cache
mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
bic ip, ip, #0x0000000c @ ............wc..
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm740_reset)
+SYM_FUNC_END(cpu_arm740_reset)
.popsection
.type __arm740_setup, #function
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 01bbe7576c1c..baa3d4472147 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -6,6 +6,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -23,18 +24,29 @@
* cpu_arm7tdmi_switch_mm()
*
* These are not required.
- */
-ENTRY(cpu_arm7tdmi_proc_init)
-ENTRY(cpu_arm7tdmi_do_idle)
-ENTRY(cpu_arm7tdmi_dcache_clean_area)
-ENTRY(cpu_arm7tdmi_switch_mm)
- ret lr
+*/
+SYM_TYPED_FUNC_START(cpu_arm7tdmi_proc_init)
+ ret lr
+SYM_FUNC_END(cpu_arm7tdmi_proc_init)
+
+SYM_TYPED_FUNC_START(cpu_arm7tdmi_do_idle)
+ ret lr
+SYM_FUNC_END(cpu_arm7tdmi_do_idle)
+
+SYM_TYPED_FUNC_START(cpu_arm7tdmi_dcache_clean_area)
+ ret lr
+SYM_FUNC_END(cpu_arm7tdmi_dcache_clean_area)
+
+SYM_TYPED_FUNC_START(cpu_arm7tdmi_switch_mm)
+ ret lr
+SYM_FUNC_END(cpu_arm7tdmi_switch_mm)
/*
* cpu_arm7tdmi_proc_fin()
- */
-ENTRY(cpu_arm7tdmi_proc_fin)
- ret lr
+*/
+SYM_TYPED_FUNC_START(cpu_arm7tdmi_proc_fin)
+ ret lr
+SYM_FUNC_END(cpu_arm7tdmi_proc_fin)
/*
* Function: cpu_arm7tdmi_reset(loc)
@@ -42,9 +54,9 @@ ENTRY(cpu_arm7tdmi_proc_fin)
* Purpose : Sets up everything for a reset and jump to the location for soft reset.
*/
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm7tdmi_reset)
+SYM_TYPED_FUNC_START(cpu_arm7tdmi_reset)
ret r0
-ENDPROC(cpu_arm7tdmi_reset)
+SYM_FUNC_END(cpu_arm7tdmi_reset)
.popsection
.type __arm7tdmi_setup, #function
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index a234cd8ba5e6..a30df54ad5fa 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -13,6 +13,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -48,18 +49,20 @@
/*
* cpu_arm920_proc_init()
*/
-ENTRY(cpu_arm920_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm920_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm920_proc_init)
/*
* cpu_arm920_proc_fin()
*/
-ENTRY(cpu_arm920_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm920_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm920_proc_fin)
/*
* cpu_arm920_reset(loc)
@@ -72,7 +75,7 @@ ENTRY(cpu_arm920_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm920_reset)
+SYM_TYPED_FUNC_START(cpu_arm920_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -84,17 +87,17 @@ ENTRY(cpu_arm920_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm920_reset)
+SYM_FUNC_END(cpu_arm920_reset)
.popsection
/*
* cpu_arm920_do_idle()
*/
.align 5
-ENTRY(cpu_arm920_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm920_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
-
+SYM_FUNC_END(cpu_arm920_do_idle)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -103,11 +106,11 @@ ENTRY(cpu_arm920_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm920_flush_icache_all)
+SYM_TYPED_FUNC_START(arm920_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(arm920_flush_icache_all)
+SYM_FUNC_END(arm920_flush_icache_all)
/*
* flush_user_cache_all()
@@ -115,15 +118,14 @@ ENDPROC(arm920_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(arm920_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm920_flush_user_cache_all, arm920_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm920_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm920_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -138,6 +140,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm920_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -149,7 +152,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags for address space
*/
-ENTRY(arm920_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm920_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -164,6 +167,7 @@ ENTRY(arm920_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm920_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -175,8 +179,11 @@ ENTRY(arm920_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm920_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm920_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm920_coherent_user_range
+#endif
+SYM_FUNC_END(arm920_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -188,7 +195,7 @@ ENTRY(arm920_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm920_coherent_user_range)
+SYM_TYPED_FUNC_START(arm920_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -198,6 +205,7 @@ ENTRY(arm920_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm920_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -208,7 +216,7 @@ ENTRY(arm920_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm920_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm920_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -218,6 +226,7 @@ ENTRY(arm920_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm920_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -272,7 +281,7 @@ arm920_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm920_dma_flush_range)
+SYM_TYPED_FUNC_START(arm920_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -280,6 +289,7 @@ ENTRY(arm920_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm920_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -287,13 +297,13 @@ ENTRY(arm920_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm920_dma_map_area)
+SYM_TYPED_FUNC_START(arm920_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm920_dma_clean_range
bcs arm920_dma_inv_range
b arm920_dma_flush_range
-ENDPROC(arm920_dma_map_area)
+SYM_FUNC_END(arm920_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -301,24 +311,20 @@ ENDPROC(arm920_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm920_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm920_dma_unmap_area)
ret lr
-ENDPROC(arm920_dma_unmap_area)
+SYM_FUNC_END(arm920_dma_unmap_area)
- .globl arm920_flush_kern_cache_louis
- .equ arm920_flush_kern_cache_louis, arm920_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm920
-#endif
+#endif /* !CONFIG_CPU_DCACHE_WRITETHROUGH */
-ENTRY(cpu_arm920_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm920_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
subs r1, r1, #CACHE_DLINESIZE
bhi 1b
ret lr
+SYM_FUNC_END(cpu_arm920_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -330,7 +336,7 @@ ENTRY(cpu_arm920_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm920_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm920_switch_mm)
#ifdef CONFIG_MMU
mov ip, #0
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -354,6 +360,7 @@ ENTRY(cpu_arm920_switch_mm)
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
+SYM_FUNC_END(cpu_arm920_switch_mm)
/*
* cpu_arm920_set_pte(ptep, pte, ext)
@@ -361,7 +368,7 @@ ENTRY(cpu_arm920_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm920_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm920_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -369,21 +376,22 @@ ENTRY(cpu_arm920_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
ret lr
+SYM_FUNC_END(cpu_arm920_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
.globl cpu_arm920_suspend_size
.equ cpu_arm920_suspend_size, 4 * 3
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_arm920_do_suspend)
+SYM_TYPED_FUNC_START(cpu_arm920_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
mrc p15, 0, r6, c1, c0, 0 @ Control register
stmia r0, {r4 - r6}
ldmfd sp!, {r4 - r6, pc}
-ENDPROC(cpu_arm920_do_suspend)
+SYM_FUNC_END(cpu_arm920_do_suspend)
-ENTRY(cpu_arm920_do_resume)
+SYM_TYPED_FUNC_START(cpu_arm920_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
@@ -393,7 +401,7 @@ ENTRY(cpu_arm920_do_resume)
mcr p15, 0, r1, c2, c0, 0 @ TTB address
mov r0, r6 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_arm920_do_resume)
+SYM_FUNC_END(cpu_arm920_do_resume)
#endif
.type __arm920_setup, #function
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 53c029dcfd83..aac4e048100d 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -14,6 +14,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -50,18 +51,20 @@
/*
* cpu_arm922_proc_init()
*/
-ENTRY(cpu_arm922_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm922_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm922_proc_init)
/*
* cpu_arm922_proc_fin()
*/
-ENTRY(cpu_arm922_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm922_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm922_proc_fin)
/*
* cpu_arm922_reset(loc)
@@ -74,7 +77,7 @@ ENTRY(cpu_arm922_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm922_reset)
+SYM_TYPED_FUNC_START(cpu_arm922_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -86,17 +89,17 @@ ENTRY(cpu_arm922_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm922_reset)
+SYM_FUNC_END(cpu_arm922_reset)
.popsection
/*
* cpu_arm922_do_idle()
*/
.align 5
-ENTRY(cpu_arm922_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm922_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
-
+SYM_FUNC_END(cpu_arm922_do_idle)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -105,11 +108,11 @@ ENTRY(cpu_arm922_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm922_flush_icache_all)
+SYM_TYPED_FUNC_START(arm922_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(arm922_flush_icache_all)
+SYM_FUNC_END(arm922_flush_icache_all)
/*
* flush_user_cache_all()
@@ -117,15 +120,14 @@ ENDPROC(arm922_flush_icache_all)
* Clean and invalidate all cache entries in a particular
* address space.
*/
-ENTRY(arm922_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm922_flush_user_cache_all, arm922_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm922_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm922_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -140,6 +142,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm922_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -151,7 +154,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags describing address space
*/
-ENTRY(arm922_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm922_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -166,6 +169,7 @@ ENTRY(arm922_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm922_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -177,8 +181,11 @@ ENTRY(arm922_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm922_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm922_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm922_coherent_user_range
+#endif
+SYM_FUNC_END(arm922_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -190,7 +197,7 @@ ENTRY(arm922_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm922_coherent_user_range)
+SYM_TYPED_FUNC_START(arm922_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -200,6 +207,7 @@ ENTRY(arm922_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm922_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -210,7 +218,7 @@ ENTRY(arm922_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm922_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm922_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -220,6 +228,7 @@ ENTRY(arm922_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm922_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -274,7 +283,7 @@ arm922_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm922_dma_flush_range)
+SYM_TYPED_FUNC_START(arm922_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -282,6 +291,7 @@ ENTRY(arm922_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm922_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -289,13 +299,13 @@ ENTRY(arm922_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm922_dma_map_area)
+SYM_TYPED_FUNC_START(arm922_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm922_dma_clean_range
bcs arm922_dma_inv_range
b arm922_dma_flush_range
-ENDPROC(arm922_dma_map_area)
+SYM_FUNC_END(arm922_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -303,19 +313,13 @@ ENDPROC(arm922_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm922_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm922_dma_unmap_area)
ret lr
-ENDPROC(arm922_dma_unmap_area)
-
- .globl arm922_flush_kern_cache_louis
- .equ arm922_flush_kern_cache_louis, arm922_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm922
-#endif
+SYM_FUNC_END(arm922_dma_unmap_area)
+#endif /* !CONFIG_CPU_DCACHE_WRITETHROUGH */
-ENTRY(cpu_arm922_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm922_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
@@ -323,6 +327,7 @@ ENTRY(cpu_arm922_dcache_clean_area)
bhi 1b
#endif
ret lr
+SYM_FUNC_END(cpu_arm922_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -334,7 +339,7 @@ ENTRY(cpu_arm922_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm922_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm922_switch_mm)
#ifdef CONFIG_MMU
mov ip, #0
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -358,6 +363,7 @@ ENTRY(cpu_arm922_switch_mm)
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
+SYM_FUNC_END(cpu_arm922_switch_mm)
/*
* cpu_arm922_set_pte_ext(ptep, pte, ext)
@@ -365,7 +371,7 @@ ENTRY(cpu_arm922_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm922_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm922_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -373,6 +379,7 @@ ENTRY(cpu_arm922_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif /* CONFIG_MMU */
ret lr
+SYM_FUNC_END(cpu_arm922_set_pte_ext)
.type __arm922_setup, #function
__arm922_setup:
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 0bfad62ea858..035941faeb2e 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -37,6 +37,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -71,18 +72,20 @@
/*
* cpu_arm925_proc_init()
*/
-ENTRY(cpu_arm925_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm925_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm925_proc_init)
/*
* cpu_arm925_proc_fin()
*/
-ENTRY(cpu_arm925_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm925_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm925_proc_fin)
/*
* cpu_arm925_reset(loc)
@@ -95,14 +98,14 @@ ENTRY(cpu_arm925_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm925_reset)
+SYM_TYPED_FUNC_START(cpu_arm925_reset)
/* Send software reset to MPU and DSP */
mov ip, #0xff000000
orr ip, ip, #0x00fe0000
orr ip, ip, #0x0000ce00
mov r4, #1
strh r4, [ip, #0x10]
-ENDPROC(cpu_arm925_reset)
+SYM_FUNC_END(cpu_arm925_reset)
.popsection
mov ip, #0
@@ -123,7 +126,7 @@ ENDPROC(cpu_arm925_reset)
* Called with IRQs disabled
*/
.align 10
-ENTRY(cpu_arm925_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm925_do_idle)
mov r0, #0
mrc p15, 0, r1, c1, c0, 0 @ Read control register
mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
@@ -132,17 +135,18 @@ ENTRY(cpu_arm925_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable
ret lr
+SYM_FUNC_END(cpu_arm925_do_idle)
/*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm925_flush_icache_all)
+SYM_TYPED_FUNC_START(arm925_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(arm925_flush_icache_all)
+SYM_FUNC_END(arm925_flush_icache_all)
/*
* flush_user_cache_all()
@@ -150,15 +154,14 @@ ENDPROC(arm925_flush_icache_all)
* Clean and invalidate all cache entries in a particular
* address space.
*/
-ENTRY(arm925_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm925_flush_user_cache_all, arm925_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm925_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm925_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -175,6 +178,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm925_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -186,7 +190,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags describing address space
*/
-ENTRY(arm925_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm925_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -212,6 +216,7 @@ ENTRY(arm925_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm925_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -223,8 +228,11 @@ ENTRY(arm925_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm925_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm925_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm925_coherent_user_range
+#endif
+SYM_FUNC_END(arm925_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -236,7 +244,7 @@ ENTRY(arm925_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm925_coherent_user_range)
+SYM_TYPED_FUNC_START(arm925_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -246,6 +254,7 @@ ENTRY(arm925_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm925_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -256,7 +265,7 @@ ENTRY(arm925_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm925_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm925_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -266,6 +275,7 @@ ENTRY(arm925_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm925_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -324,7 +334,7 @@ arm925_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm925_dma_flush_range)
+SYM_TYPED_FUNC_START(arm925_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1:
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -337,6 +347,7 @@ ENTRY(arm925_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm925_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -344,13 +355,13 @@ ENTRY(arm925_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm925_dma_map_area)
+SYM_TYPED_FUNC_START(arm925_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm925_dma_clean_range
bcs arm925_dma_inv_range
b arm925_dma_flush_range
-ENDPROC(arm925_dma_map_area)
+SYM_FUNC_END(arm925_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -358,17 +369,11 @@ ENDPROC(arm925_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm925_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm925_dma_unmap_area)
ret lr
-ENDPROC(arm925_dma_unmap_area)
-
- .globl arm925_flush_kern_cache_louis
- .equ arm925_flush_kern_cache_louis, arm925_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm925
+SYM_FUNC_END(arm925_dma_unmap_area)
-ENTRY(cpu_arm925_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm925_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
@@ -377,6 +382,7 @@ ENTRY(cpu_arm925_dcache_clean_area)
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_arm925_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -388,7 +394,7 @@ ENTRY(cpu_arm925_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm925_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm925_switch_mm)
#ifdef CONFIG_MMU
mov ip, #0
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -406,6 +412,7 @@ ENTRY(cpu_arm925_switch_mm)
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
+SYM_FUNC_END(cpu_arm925_switch_mm)
/*
* cpu_arm925_set_pte_ext(ptep, pte, ext)
@@ -413,7 +420,7 @@ ENTRY(cpu_arm925_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm925_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm925_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -423,6 +430,7 @@ ENTRY(cpu_arm925_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif /* CONFIG_MMU */
ret lr
+SYM_FUNC_END(cpu_arm925_set_pte_ext)
.type __arm925_setup, #function
__arm925_setup:
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 0487a2c3439b..6f43d6af2d9a 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -13,6 +13,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -40,18 +41,20 @@
/*
* cpu_arm926_proc_init()
*/
-ENTRY(cpu_arm926_proc_init)
+SYM_TYPED_FUNC_START(cpu_arm926_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm926_proc_init)
/*
* cpu_arm926_proc_fin()
*/
-ENTRY(cpu_arm926_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm926_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm926_proc_fin)
/*
* cpu_arm926_reset(loc)
@@ -64,7 +67,7 @@ ENTRY(cpu_arm926_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm926_reset)
+SYM_TYPED_FUNC_START(cpu_arm926_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -76,7 +79,7 @@ ENTRY(cpu_arm926_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm926_reset)
+SYM_FUNC_END(cpu_arm926_reset)
.popsection
/*
@@ -85,7 +88,7 @@ ENDPROC(cpu_arm926_reset)
* Called with IRQs disabled
*/
.align 10
-ENTRY(cpu_arm926_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm926_do_idle)
mov r0, #0
mrc p15, 0, r1, c1, c0, 0 @ Read control register
mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
@@ -98,17 +101,18 @@ ENTRY(cpu_arm926_do_idle)
mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable
msr cpsr_c, r3 @ Restore FIQ state
ret lr
+SYM_FUNC_END(cpu_arm926_do_idle)
/*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm926_flush_icache_all)
+SYM_TYPED_FUNC_START(arm926_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(arm926_flush_icache_all)
+SYM_FUNC_END(arm926_flush_icache_all)
/*
* flush_user_cache_all()
@@ -116,15 +120,14 @@ ENDPROC(arm926_flush_icache_all)
* Clean and invalidate all cache entries in a particular
* address space.
*/
-ENTRY(arm926_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm926_flush_user_cache_all, arm926_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm926_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm926_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -138,6 +141,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm926_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -149,7 +153,7 @@ __flush_whole_cache:
* - end - end address (exclusive)
* - flags - vm_flags describing address space
*/
-ENTRY(arm926_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm926_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -175,6 +179,7 @@ ENTRY(arm926_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm926_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -186,8 +191,11 @@ ENTRY(arm926_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm926_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm926_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm926_coherent_user_range
+#endif
+SYM_FUNC_END(arm926_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -199,7 +207,7 @@ ENTRY(arm926_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm926_coherent_user_range)
+SYM_TYPED_FUNC_START(arm926_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -209,6 +217,7 @@ ENTRY(arm926_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm926_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -219,7 +228,7 @@ ENTRY(arm926_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm926_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm926_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -229,6 +238,7 @@ ENTRY(arm926_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm926_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -287,7 +297,7 @@ arm926_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm926_dma_flush_range)
+SYM_TYPED_FUNC_START(arm926_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1:
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -300,6 +310,7 @@ ENTRY(arm926_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm926_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -307,13 +318,13 @@ ENTRY(arm926_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm926_dma_map_area)
+SYM_TYPED_FUNC_START(arm926_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm926_dma_clean_range
bcs arm926_dma_inv_range
b arm926_dma_flush_range
-ENDPROC(arm926_dma_map_area)
+SYM_FUNC_END(arm926_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -321,17 +332,11 @@ ENDPROC(arm926_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm926_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm926_dma_unmap_area)
ret lr
-ENDPROC(arm926_dma_unmap_area)
-
- .globl arm926_flush_kern_cache_louis
- .equ arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
+SYM_FUNC_END(arm926_dma_unmap_area)
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm926
-
-ENTRY(cpu_arm926_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm926_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
@@ -340,6 +345,7 @@ ENTRY(cpu_arm926_dcache_clean_area)
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_arm926_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -351,7 +357,8 @@ ENTRY(cpu_arm926_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_arm926_switch_mm)
+
+SYM_TYPED_FUNC_START(cpu_arm926_switch_mm)
#ifdef CONFIG_MMU
mov ip, #0
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -367,6 +374,7 @@ ENTRY(cpu_arm926_switch_mm)
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
#endif
ret lr
+SYM_FUNC_END(cpu_arm926_switch_mm)
/*
* cpu_arm926_set_pte_ext(ptep, pte, ext)
@@ -374,7 +382,7 @@ ENTRY(cpu_arm926_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm926_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_arm926_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -384,21 +392,22 @@ ENTRY(cpu_arm926_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
ret lr
+SYM_FUNC_END(cpu_arm926_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
.globl cpu_arm926_suspend_size
.equ cpu_arm926_suspend_size, 4 * 3
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_arm926_do_suspend)
+SYM_TYPED_FUNC_START(cpu_arm926_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
mrc p15, 0, r6, c1, c0, 0 @ Control register
stmia r0, {r4 - r6}
ldmfd sp!, {r4 - r6, pc}
-ENDPROC(cpu_arm926_do_suspend)
+SYM_FUNC_END(cpu_arm926_do_suspend)
-ENTRY(cpu_arm926_do_resume)
+SYM_TYPED_FUNC_START(cpu_arm926_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
@@ -408,7 +417,7 @@ ENTRY(cpu_arm926_do_resume)
mcr p15, 0, r1, c2, c0, 0 @ TTB address
mov r0, r6 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_arm926_do_resume)
+SYM_FUNC_END(cpu_arm926_do_resume)
#endif
.type __arm926_setup, #function
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index cf9bfcc825ca..0d30bb25c42b 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -6,6 +6,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -25,19 +26,24 @@
*
* These are not required.
*/
-ENTRY(cpu_arm940_proc_init)
-ENTRY(cpu_arm940_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm940_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm940_proc_init)
+
+SYM_TYPED_FUNC_START(cpu_arm940_switch_mm)
+ ret lr
+SYM_FUNC_END(cpu_arm940_switch_mm)
/*
* cpu_arm940_proc_fin()
*/
-ENTRY(cpu_arm940_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm940_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x00001000 @ i-cache
bic r0, r0, #0x00000004 @ d-cache
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm940_proc_fin)
/*
* cpu_arm940_reset(loc)
@@ -45,7 +51,7 @@ ENTRY(cpu_arm940_proc_fin)
* Notes : This sets up everything for a reset
*/
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm940_reset)
+SYM_TYPED_FUNC_START(cpu_arm940_reset)
mov ip, #0
mcr p15, 0, ip, c7, c5, 0 @ flush I cache
mcr p15, 0, ip, c7, c6, 0 @ flush D cache
@@ -55,42 +61,43 @@ ENTRY(cpu_arm940_reset)
bic ip, ip, #0x00001000 @ i-cache
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm940_reset)
+SYM_FUNC_END(cpu_arm940_reset)
.popsection
/*
* cpu_arm940_do_idle()
*/
.align 5
-ENTRY(cpu_arm940_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm940_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_arm940_do_idle)
/*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm940_flush_icache_all)
+SYM_TYPED_FUNC_START(arm940_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(arm940_flush_icache_all)
+SYM_FUNC_END(arm940_flush_icache_all)
/*
* flush_user_cache_all()
*/
-ENTRY(arm940_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm940_flush_user_cache_all, arm940_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm940_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm940_flush_kern_cache_all)
mov r2, #VM_EXEC
- /* FALLTHROUGH */
+ b arm940_flush_user_cache_range
+SYM_FUNC_END(arm940_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -102,7 +109,7 @@ ENTRY(arm940_flush_kern_cache_all)
* - end - end address (exclusive)
* - flags - vm_flags describing address space
*/
-ENTRY(arm940_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm940_flush_user_cache_range)
mov ip, #0
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
mcr p15, 0, ip, c7, c6, 0 @ flush D cache
@@ -119,6 +126,7 @@ ENTRY(arm940_flush_user_cache_range)
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm940_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -130,8 +138,9 @@ ENTRY(arm940_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm940_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm940_coherent_kern_range)
+ b arm940_flush_kern_dcache_area
+SYM_FUNC_END(arm940_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -143,8 +152,11 @@ ENTRY(arm940_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm940_coherent_user_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm940_coherent_user_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm940_flush_kern_dcache_area
+#endif
+SYM_FUNC_END(arm940_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -155,7 +167,7 @@ ENTRY(arm940_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(arm940_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm940_flush_kern_dcache_area)
mov r0, #0
mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
@@ -167,6 +179,7 @@ ENTRY(arm940_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm940_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -199,7 +212,7 @@ arm940_dma_inv_range:
* - end - virtual end address
*/
arm940_dma_clean_range:
-ENTRY(cpu_arm940_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm940_dcache_clean_area)
mov ip, #0
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
@@ -212,6 +225,7 @@ ENTRY(cpu_arm940_dcache_clean_area)
#endif
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_arm940_dcache_clean_area)
/*
* dma_flush_range(start, end)
@@ -222,7 +236,7 @@ ENTRY(cpu_arm940_dcache_clean_area)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm940_dma_flush_range)
+SYM_TYPED_FUNC_START(arm940_dma_flush_range)
mov ip, #0
mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
@@ -238,6 +252,7 @@ ENTRY(arm940_dma_flush_range)
bcs 1b @ segments 7 to 0
mcr p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm940_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -245,13 +260,13 @@ ENTRY(arm940_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm940_dma_map_area)
+SYM_TYPED_FUNC_START(arm940_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm940_dma_clean_range
bcs arm940_dma_inv_range
b arm940_dma_flush_range
-ENDPROC(arm940_dma_map_area)
+SYM_FUNC_END(arm940_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -259,15 +274,9 @@ ENDPROC(arm940_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm940_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm940_dma_unmap_area)
ret lr
-ENDPROC(arm940_dma_unmap_area)
-
- .globl arm940_flush_kern_cache_louis
- .equ arm940_flush_kern_cache_louis, arm940_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm940
+SYM_FUNC_END(arm940_dma_unmap_area)
.type __arm940_setup, #function
__arm940_setup:
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 6fb3898ad1cd..27750ace2ced 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -8,6 +8,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -32,19 +33,24 @@
*
* These are not required.
*/
-ENTRY(cpu_arm946_proc_init)
-ENTRY(cpu_arm946_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm946_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm946_proc_init)
+
+SYM_TYPED_FUNC_START(cpu_arm946_switch_mm)
+ ret lr
+SYM_FUNC_END(cpu_arm946_switch_mm)
/*
* cpu_arm946_proc_fin()
*/
-ENTRY(cpu_arm946_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm946_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x00001000 @ i-cache
bic r0, r0, #0x00000004 @ d-cache
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_arm946_proc_fin)
/*
* cpu_arm946_reset(loc)
@@ -52,7 +58,7 @@ ENTRY(cpu_arm946_proc_fin)
* Notes : This sets up everything for a reset
*/
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm946_reset)
+SYM_TYPED_FUNC_START(cpu_arm946_reset)
mov ip, #0
mcr p15, 0, ip, c7, c5, 0 @ flush I cache
mcr p15, 0, ip, c7, c6, 0 @ flush D cache
@@ -62,40 +68,40 @@ ENTRY(cpu_arm946_reset)
bic ip, ip, #0x00001000 @ i-cache
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_arm946_reset)
+SYM_FUNC_END(cpu_arm946_reset)
.popsection
/*
* cpu_arm946_do_idle()
*/
.align 5
-ENTRY(cpu_arm946_do_idle)
+SYM_TYPED_FUNC_START(cpu_arm946_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_arm946_do_idle)
/*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(arm946_flush_icache_all)
+SYM_TYPED_FUNC_START(arm946_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(arm946_flush_icache_all)
+SYM_FUNC_END(arm946_flush_icache_all)
/*
* flush_user_cache_all()
*/
-ENTRY(arm946_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(arm946_flush_user_cache_all, arm946_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(arm946_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(arm946_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -114,6 +120,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm946_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -126,7 +133,7 @@ __flush_whole_cache:
* - flags - vm_flags describing address space
* (same as arm926)
*/
-ENTRY(arm946_flush_user_cache_range)
+SYM_TYPED_FUNC_START(arm946_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -153,6 +160,7 @@ ENTRY(arm946_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm946_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -164,8 +172,11 @@ ENTRY(arm946_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(arm946_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(arm946_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b arm946_coherent_user_range
+#endif
+SYM_FUNC_END(arm946_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -178,7 +189,7 @@ ENTRY(arm946_coherent_kern_range)
* - end - virtual end address
* (same as arm926)
*/
-ENTRY(arm946_coherent_user_range)
+SYM_TYPED_FUNC_START(arm946_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -188,6 +199,7 @@ ENTRY(arm946_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(arm946_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -199,7 +211,7 @@ ENTRY(arm946_coherent_user_range)
* - size - region size
* (same as arm926)
*/
-ENTRY(arm946_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(arm946_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -209,6 +221,7 @@ ENTRY(arm946_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm946_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -268,7 +281,7 @@ arm946_dma_clean_range:
*
* (same as arm926)
*/
-ENTRY(arm946_dma_flush_range)
+SYM_TYPED_FUNC_START(arm946_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1:
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -281,6 +294,7 @@ ENTRY(arm946_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(arm946_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -288,13 +302,13 @@ ENTRY(arm946_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm946_dma_map_area)
+SYM_TYPED_FUNC_START(arm946_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq arm946_dma_clean_range
bcs arm946_dma_inv_range
b arm946_dma_flush_range
-ENDPROC(arm946_dma_map_area)
+SYM_FUNC_END(arm946_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -302,17 +316,11 @@ ENDPROC(arm946_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(arm946_dma_unmap_area)
+SYM_TYPED_FUNC_START(arm946_dma_unmap_area)
ret lr
-ENDPROC(arm946_dma_unmap_area)
-
- .globl arm946_flush_kern_cache_louis
- .equ arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions arm946
+SYM_FUNC_END(arm946_dma_unmap_area)
-ENTRY(cpu_arm946_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_arm946_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
@@ -321,6 +329,7 @@ ENTRY(cpu_arm946_dcache_clean_area)
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_arm946_dcache_clean_area)
.type __arm946_setup, #function
__arm946_setup:
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index a054c0e9c034..c480a8400eff 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -6,6 +6,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -24,17 +25,28 @@
*
* These are not required.
*/
-ENTRY(cpu_arm9tdmi_proc_init)
-ENTRY(cpu_arm9tdmi_do_idle)
-ENTRY(cpu_arm9tdmi_dcache_clean_area)
-ENTRY(cpu_arm9tdmi_switch_mm)
+SYM_TYPED_FUNC_START(cpu_arm9tdmi_proc_init)
ret lr
+SYM_FUNC_END(cpu_arm9tdmi_proc_init)
+
+SYM_TYPED_FUNC_START(cpu_arm9tdmi_do_idle)
+ ret lr
+SYM_FUNC_END(cpu_arm9tdmi_do_idle)
+
+SYM_TYPED_FUNC_START(cpu_arm9tdmi_dcache_clean_area)
+ ret lr
+SYM_FUNC_END(cpu_arm9tdmi_dcache_clean_area)
+
+SYM_TYPED_FUNC_START(cpu_arm9tdmi_switch_mm)
+ ret lr
+SYM_FUNC_END(cpu_arm9tdmi_switch_mm)
/*
* cpu_arm9tdmi_proc_fin()
*/
-ENTRY(cpu_arm9tdmi_proc_fin)
+SYM_TYPED_FUNC_START(cpu_arm9tdmi_proc_fin)
ret lr
+SYM_FUNC_END(cpu_arm9tdmi_proc_fin)
/*
* Function: cpu_arm9tdmi_reset(loc)
@@ -42,9 +54,9 @@ ENTRY(cpu_arm9tdmi_proc_fin)
* Purpose : Sets up everything for a reset and jump to the location for soft reset.
*/
.pushsection .idmap.text, "ax"
-ENTRY(cpu_arm9tdmi_reset)
+SYM_TYPED_FUNC_START(cpu_arm9tdmi_reset)
ret r0
-ENDPROC(cpu_arm9tdmi_reset)
+SYM_FUNC_END(cpu_arm9tdmi_reset)
.popsection
.type __arm9tdmi_setup, #function
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 2c73e0d47d08..7c16ccac8a05 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -26,13 +27,14 @@
/*
* cpu_fa526_proc_init()
*/
-ENTRY(cpu_fa526_proc_init)
+SYM_TYPED_FUNC_START(cpu_fa526_proc_init)
ret lr
+SYM_FUNC_END(cpu_fa526_proc_init)
/*
* cpu_fa526_proc_fin()
*/
-ENTRY(cpu_fa526_proc_fin)
+SYM_TYPED_FUNC_START(cpu_fa526_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
@@ -40,6 +42,7 @@ ENTRY(cpu_fa526_proc_fin)
nop
nop
ret lr
+SYM_FUNC_END(cpu_fa526_proc_fin)
/*
* cpu_fa526_reset(loc)
@@ -52,7 +55,7 @@ ENTRY(cpu_fa526_proc_fin)
*/
.align 4
.pushsection .idmap.text, "ax"
-ENTRY(cpu_fa526_reset)
+SYM_TYPED_FUNC_START(cpu_fa526_reset)
/* TODO: Use CP8 if possible... */
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
@@ -68,24 +71,25 @@ ENTRY(cpu_fa526_reset)
nop
nop
ret r0
-ENDPROC(cpu_fa526_reset)
+SYM_FUNC_END(cpu_fa526_reset)
.popsection
/*
* cpu_fa526_do_idle()
*/
.align 4
-ENTRY(cpu_fa526_do_idle)
+SYM_TYPED_FUNC_START(cpu_fa526_do_idle)
ret lr
+SYM_FUNC_END(cpu_fa526_do_idle)
-
-ENTRY(cpu_fa526_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_fa526_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
subs r1, r1, #CACHE_DLINESIZE
bhi 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_fa526_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -97,7 +101,7 @@ ENTRY(cpu_fa526_dcache_clean_area)
* pgd: new page tables
*/
.align 4
-ENTRY(cpu_fa526_switch_mm)
+SYM_TYPED_FUNC_START(cpu_fa526_switch_mm)
#ifdef CONFIG_MMU
mov ip, #0
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -113,6 +117,7 @@ ENTRY(cpu_fa526_switch_mm)
mcr p15, 0, ip, c8, c7, 0 @ invalidate UTLB
#endif
ret lr
+SYM_FUNC_END(cpu_fa526_switch_mm)
/*
* cpu_fa526_set_pte_ext(ptep, pte, ext)
@@ -120,7 +125,7 @@ ENTRY(cpu_fa526_switch_mm)
* Set a PTE and flush it out
*/
.align 4
-ENTRY(cpu_fa526_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_fa526_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -129,6 +134,7 @@ ENTRY(cpu_fa526_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
ret lr
+SYM_FUNC_END(cpu_fa526_set_pte_ext)
.type __fa526_setup, #function
__fa526_setup:
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 072ff9b451f8..f67b2ffac854 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -8,6 +8,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -43,7 +44,7 @@ __cache_params:
/*
* cpu_feroceon_proc_init()
*/
-ENTRY(cpu_feroceon_proc_init)
+SYM_TYPED_FUNC_START(cpu_feroceon_proc_init)
mrc p15, 0, r0, c0, c0, 1 @ read cache type register
ldr r1, __cache_params
mov r2, #(16 << 5)
@@ -61,11 +62,12 @@ ENTRY(cpu_feroceon_proc_init)
str_l r1, VFP_arch_feroceon, r2
#endif
ret lr
+SYM_FUNC_END(cpu_feroceon_proc_init)
/*
* cpu_feroceon_proc_fin()
*/
-ENTRY(cpu_feroceon_proc_fin)
+SYM_TYPED_FUNC_START(cpu_feroceon_proc_fin)
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
mov r0, #0
@@ -78,6 +80,7 @@ ENTRY(cpu_feroceon_proc_fin)
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_feroceon_proc_fin)
/*
* cpu_feroceon_reset(loc)
@@ -90,7 +93,7 @@ ENTRY(cpu_feroceon_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_feroceon_reset)
+SYM_TYPED_FUNC_START(cpu_feroceon_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -102,7 +105,7 @@ ENTRY(cpu_feroceon_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_feroceon_reset)
+SYM_FUNC_END(cpu_feroceon_reset)
.popsection
/*
@@ -111,22 +114,23 @@ ENDPROC(cpu_feroceon_reset)
* Called with IRQs disabled
*/
.align 5
-ENTRY(cpu_feroceon_do_idle)
+SYM_TYPED_FUNC_START(cpu_feroceon_do_idle)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
ret lr
+SYM_FUNC_END(cpu_feroceon_do_idle)
/*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(feroceon_flush_icache_all)
+SYM_TYPED_FUNC_START(feroceon_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(feroceon_flush_icache_all)
+SYM_FUNC_END(feroceon_flush_icache_all)
/*
* flush_user_cache_all()
@@ -135,15 +139,14 @@ ENDPROC(feroceon_flush_icache_all)
* address space.
*/
.align 5
-ENTRY(feroceon_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(feroceon_flush_user_cache_all, feroceon_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(feroceon_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(feroceon_flush_kern_cache_all)
mov r2, #VM_EXEC
__flush_whole_cache:
@@ -161,6 +164,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(feroceon_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -173,7 +177,7 @@ __flush_whole_cache:
* - flags - vm_flags describing address space
*/
.align 5
-ENTRY(feroceon_flush_user_cache_range)
+SYM_TYPED_FUNC_START(feroceon_flush_user_cache_range)
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
bgt __flush_whole_cache
@@ -190,6 +194,7 @@ ENTRY(feroceon_flush_user_cache_range)
mov ip, #0
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(feroceon_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -202,8 +207,11 @@ ENTRY(feroceon_flush_user_cache_range)
* - end - virtual end address
*/
.align 5
-ENTRY(feroceon_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(feroceon_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b feroceon_coherent_user_range
+#endif
+SYM_FUNC_END(feroceon_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -215,7 +223,7 @@ ENTRY(feroceon_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(feroceon_coherent_user_range)
+SYM_TYPED_FUNC_START(feroceon_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -225,6 +233,7 @@ ENTRY(feroceon_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(feroceon_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -236,7 +245,7 @@ ENTRY(feroceon_coherent_user_range)
* - size - region size
*/
.align 5
-ENTRY(feroceon_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(feroceon_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -246,9 +255,10 @@ ENTRY(feroceon_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(feroceon_flush_kern_dcache_area)
.align 5
-ENTRY(feroceon_range_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(feroceon_range_flush_kern_dcache_area)
mrs r2, cpsr
add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive
orr r3, r2, #PSR_I_BIT
@@ -260,6 +270,7 @@ ENTRY(feroceon_range_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(feroceon_range_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -346,7 +357,7 @@ feroceon_range_dma_clean_range:
* - end - virtual end address
*/
.align 5
-ENTRY(feroceon_dma_flush_range)
+SYM_TYPED_FUNC_START(feroceon_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -354,9 +365,10 @@ ENTRY(feroceon_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(feroceon_dma_flush_range)
.align 5
-ENTRY(feroceon_range_dma_flush_range)
+SYM_TYPED_FUNC_START(feroceon_range_dma_flush_range)
mrs r2, cpsr
cmp r1, r0
subne r1, r1, #1 @ top address is inclusive
@@ -367,6 +379,7 @@ ENTRY(feroceon_range_dma_flush_range)
msr cpsr_c, r2 @ restore interrupts
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(feroceon_range_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -374,13 +387,13 @@ ENTRY(feroceon_range_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(feroceon_dma_map_area)
+SYM_TYPED_FUNC_START(feroceon_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq feroceon_dma_clean_range
bcs feroceon_dma_inv_range
b feroceon_dma_flush_range
-ENDPROC(feroceon_dma_map_area)
+SYM_FUNC_END(feroceon_dma_map_area)
/*
* dma_map_area(start, size, dir)
@@ -388,13 +401,13 @@ ENDPROC(feroceon_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(feroceon_range_dma_map_area)
+SYM_TYPED_FUNC_START(feroceon_range_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq feroceon_range_dma_clean_range
bcs feroceon_range_dma_inv_range
b feroceon_range_dma_flush_range
-ENDPROC(feroceon_range_dma_map_area)
+SYM_FUNC_END(feroceon_range_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -402,39 +415,12 @@ ENDPROC(feroceon_range_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(feroceon_dma_unmap_area)
+SYM_TYPED_FUNC_START(feroceon_dma_unmap_area)
ret lr
-ENDPROC(feroceon_dma_unmap_area)
-
- .globl feroceon_flush_kern_cache_louis
- .equ feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions feroceon
-
-.macro range_alias basename
- .globl feroceon_range_\basename
- .type feroceon_range_\basename , %function
- .equ feroceon_range_\basename , feroceon_\basename
-.endm
-
-/*
- * Most of the cache functions are unchanged for this case.
- * Export suitable alias symbols for the unchanged functions:
- */
- range_alias flush_icache_all
- range_alias flush_user_cache_all
- range_alias flush_kern_cache_all
- range_alias flush_kern_cache_louis
- range_alias flush_user_cache_range
- range_alias coherent_kern_range
- range_alias coherent_user_range
- range_alias dma_unmap_area
-
- define_cache_functions feroceon_range
+SYM_FUNC_END(feroceon_dma_unmap_area)
.align 5
-ENTRY(cpu_feroceon_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_feroceon_dcache_clean_area)
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
mov r2, r0
@@ -453,6 +439,7 @@ ENTRY(cpu_feroceon_dcache_clean_area)
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_feroceon_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -464,7 +451,7 @@ ENTRY(cpu_feroceon_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_feroceon_switch_mm)
+SYM_TYPED_FUNC_START(cpu_feroceon_switch_mm)
#ifdef CONFIG_MMU
/*
* Note: we wish to call __flush_whole_cache but we need to preserve
@@ -485,6 +472,7 @@ ENTRY(cpu_feroceon_switch_mm)
#else
ret lr
#endif
+SYM_FUNC_END(cpu_feroceon_switch_mm)
/*
* cpu_feroceon_set_pte_ext(ptep, pte, ext)
@@ -492,7 +480,7 @@ ENTRY(cpu_feroceon_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_feroceon_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_feroceon_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext wc_disable=0
mov r0, r0
@@ -504,21 +492,22 @@ ENTRY(cpu_feroceon_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
ret lr
+SYM_FUNC_END(cpu_feroceon_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/mm/proc-arm926.S */
.globl cpu_feroceon_suspend_size
.equ cpu_feroceon_suspend_size, 4 * 3
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_feroceon_do_suspend)
+SYM_TYPED_FUNC_START(cpu_feroceon_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
mrc p15, 0, r6, c1, c0, 0 @ Control register
stmia r0, {r4 - r6}
ldmfd sp!, {r4 - r6, pc}
-ENDPROC(cpu_feroceon_do_suspend)
+SYM_FUNC_END(cpu_feroceon_do_suspend)
-ENTRY(cpu_feroceon_do_resume)
+SYM_TYPED_FUNC_START(cpu_feroceon_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
@@ -528,7 +517,7 @@ ENTRY(cpu_feroceon_do_resume)
mcr p15, 0, r1, c2, c0, 0 @ TTB address
mov r0, r6 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_feroceon_do_resume)
+SYM_FUNC_END(cpu_feroceon_do_resume)
#endif
.type __feroceon_setup, #function
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index e43f6d716b4b..e388c4cc0c44 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -320,39 +320,6 @@ ENTRY(\name\()_processor_functions)
#endif
.endm
-.macro define_cache_functions name:req
- .align 2
- .type \name\()_cache_fns, #object
-ENTRY(\name\()_cache_fns)
- .long \name\()_flush_icache_all
- .long \name\()_flush_kern_cache_all
- .long \name\()_flush_kern_cache_louis
- .long \name\()_flush_user_cache_all
- .long \name\()_flush_user_cache_range
- .long \name\()_coherent_kern_range
- .long \name\()_coherent_user_range
- .long \name\()_flush_kern_dcache_area
- .long \name\()_dma_map_area
- .long \name\()_dma_unmap_area
- .long \name\()_dma_flush_range
- .size \name\()_cache_fns, . - \name\()_cache_fns
-.endm
-
-.macro define_tlb_functions name:req, flags_up:req, flags_smp
- .type \name\()_tlb_fns, #object
- .align 2
-ENTRY(\name\()_tlb_fns)
- .long \name\()_flush_user_tlb_range
- .long \name\()_flush_kern_tlb_range
- .ifnb \flags_smp
- ALT_SMP(.long \flags_smp )
- ALT_UP(.long \flags_up )
- .else
- .long \flags_up
- .endif
- .size \name\()_tlb_fns, . - \name\()_tlb_fns
-.endm
-
.macro globl_equ x, y
.globl \x
.equ \x, \y
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 1645ccaffe96..8e9f38da863a 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -9,6 +9,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -31,18 +32,20 @@
/*
* cpu_mohawk_proc_init()
*/
-ENTRY(cpu_mohawk_proc_init)
+SYM_TYPED_FUNC_START(cpu_mohawk_proc_init)
ret lr
+SYM_FUNC_END(cpu_mohawk_proc_init)
/*
* cpu_mohawk_proc_fin()
*/
-ENTRY(cpu_mohawk_proc_fin)
+SYM_TYPED_FUNC_START(cpu_mohawk_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...iz...........
bic r0, r0, #0x0006 @ .............ca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_mohawk_proc_fin)
/*
* cpu_mohawk_reset(loc)
@@ -57,7 +60,7 @@ ENTRY(cpu_mohawk_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_mohawk_reset)
+SYM_TYPED_FUNC_START(cpu_mohawk_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -67,7 +70,7 @@ ENTRY(cpu_mohawk_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_mohawk_reset)
+SYM_FUNC_END(cpu_mohawk_reset)
.popsection
/*
@@ -76,22 +79,23 @@ ENDPROC(cpu_mohawk_reset)
* Called with IRQs disabled
*/
.align 5
-ENTRY(cpu_mohawk_do_idle)
+SYM_TYPED_FUNC_START(cpu_mohawk_do_idle)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
ret lr
+SYM_FUNC_END(cpu_mohawk_do_idle)
/*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(mohawk_flush_icache_all)
+SYM_TYPED_FUNC_START(mohawk_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(mohawk_flush_icache_all)
+SYM_FUNC_END(mohawk_flush_icache_all)
/*
* flush_user_cache_all()
@@ -99,15 +103,14 @@ ENDPROC(mohawk_flush_icache_all)
* Clean and invalidate all cache entries in a particular
* address space.
*/
-ENTRY(mohawk_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(mohawk_flush_user_cache_all, mohawk_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(mohawk_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(mohawk_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -116,6 +119,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 0 @ drain write buffer
ret lr
+SYM_FUNC_END(mohawk_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, flags)
@@ -129,7 +133,7 @@ __flush_whole_cache:
*
* (same as arm926)
*/
-ENTRY(mohawk_flush_user_cache_range)
+SYM_TYPED_FUNC_START(mohawk_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #CACHE_DLIMIT
@@ -146,6 +150,7 @@ ENTRY(mohawk_flush_user_cache_range)
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(mohawk_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -157,8 +162,11 @@ ENTRY(mohawk_flush_user_cache_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(mohawk_coherent_kern_range)
- /* FALLTHROUGH */
+SYM_TYPED_FUNC_START(mohawk_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b mohawk_coherent_user_range
+#endif
+SYM_FUNC_END(mohawk_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -172,7 +180,7 @@ ENTRY(mohawk_coherent_kern_range)
*
* (same as arm926)
*/
-ENTRY(mohawk_coherent_user_range)
+SYM_TYPED_FUNC_START(mohawk_coherent_user_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
@@ -182,6 +190,7 @@ ENTRY(mohawk_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov r0, #0
ret lr
+SYM_FUNC_END(mohawk_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -192,7 +201,7 @@ ENTRY(mohawk_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(mohawk_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(mohawk_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
@@ -202,6 +211,7 @@ ENTRY(mohawk_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(mohawk_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -256,7 +266,7 @@ mohawk_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(mohawk_dma_flush_range)
+SYM_TYPED_FUNC_START(mohawk_dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1:
mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
@@ -265,6 +275,7 @@ ENTRY(mohawk_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(mohawk_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -272,13 +283,13 @@ ENTRY(mohawk_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(mohawk_dma_map_area)
+SYM_TYPED_FUNC_START(mohawk_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq mohawk_dma_clean_range
bcs mohawk_dma_inv_range
b mohawk_dma_flush_range
-ENDPROC(mohawk_dma_map_area)
+SYM_FUNC_END(mohawk_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -286,23 +297,18 @@ ENDPROC(mohawk_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(mohawk_dma_unmap_area)
+SYM_TYPED_FUNC_START(mohawk_dma_unmap_area)
ret lr
-ENDPROC(mohawk_dma_unmap_area)
-
- .globl mohawk_flush_kern_cache_louis
- .equ mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions mohawk
+SYM_FUNC_END(mohawk_dma_unmap_area)
-ENTRY(cpu_mohawk_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_mohawk_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
subs r1, r1, #CACHE_DLINESIZE
bhi 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
+SYM_FUNC_END(cpu_mohawk_dcache_clean_area)
/*
* cpu_mohawk_switch_mm(pgd)
@@ -312,7 +318,7 @@ ENTRY(cpu_mohawk_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_mohawk_switch_mm)
+SYM_TYPED_FUNC_START(cpu_mohawk_switch_mm)
mov ip, #0
mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
@@ -321,6 +327,7 @@ ENTRY(cpu_mohawk_switch_mm)
mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
ret lr
+SYM_FUNC_END(cpu_mohawk_switch_mm)
/*
* cpu_mohawk_set_pte_ext(ptep, pte, ext)
@@ -328,7 +335,7 @@ ENTRY(cpu_mohawk_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_mohawk_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_mohawk_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
@@ -336,11 +343,12 @@ ENTRY(cpu_mohawk_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
ret lr
#endif
+SYM_FUNC_END(cpu_mohawk_set_pte_ext)
.globl cpu_mohawk_suspend_size
.equ cpu_mohawk_suspend_size, 4 * 6
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_mohawk_do_suspend)
+SYM_TYPED_FUNC_START(cpu_mohawk_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
@@ -351,9 +359,9 @@ ENTRY(cpu_mohawk_do_suspend)
bic r4, r4, #2 @ clear frequency change bit
stmia r0, {r4 - r9} @ store cp regs
ldmia sp!, {r4 - r9, pc}
-ENDPROC(cpu_mohawk_do_suspend)
+SYM_FUNC_END(cpu_mohawk_do_suspend)
-ENTRY(cpu_mohawk_do_resume)
+SYM_TYPED_FUNC_START(cpu_mohawk_do_resume)
ldmia r0, {r4 - r9} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
@@ -369,7 +377,7 @@ ENTRY(cpu_mohawk_do_resume)
mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
mov r0, r9 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_mohawk_do_resume)
+SYM_FUNC_END(cpu_mohawk_do_resume)
#endif
.type __mohawk_setup, #function
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 4071f7a61cb6..3da76fab8ac3 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -12,6 +12,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -32,15 +33,16 @@
/*
* cpu_sa110_proc_init()
*/
-ENTRY(cpu_sa110_proc_init)
+SYM_TYPED_FUNC_START(cpu_sa110_proc_init)
mov r0, #0
mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
ret lr
+SYM_FUNC_END(cpu_sa110_proc_init)
/*
* cpu_sa110_proc_fin()
*/
-ENTRY(cpu_sa110_proc_fin)
+SYM_TYPED_FUNC_START(cpu_sa110_proc_fin)
mov r0, #0
mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
@@ -48,6 +50,7 @@ ENTRY(cpu_sa110_proc_fin)
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_sa110_proc_fin)
/*
* cpu_sa110_reset(loc)
@@ -60,7 +63,7 @@ ENTRY(cpu_sa110_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_sa110_reset)
+SYM_TYPED_FUNC_START(cpu_sa110_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -72,7 +75,7 @@ ENTRY(cpu_sa110_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_sa110_reset)
+SYM_FUNC_END(cpu_sa110_reset)
.popsection
/*
@@ -88,7 +91,7 @@ ENDPROC(cpu_sa110_reset)
*/
.align 5
-ENTRY(cpu_sa110_do_idle)
+SYM_TYPED_FUNC_START(cpu_sa110_do_idle)
mcr p15, 0, ip, c15, c2, 2 @ disable clock switching
ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc
ldr r1, [r1, #0] @ force switch to MCLK
@@ -101,6 +104,7 @@ ENTRY(cpu_sa110_do_idle)
mov r0, r0 @ safety
mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
ret lr
+SYM_FUNC_END(cpu_sa110_do_idle)
/* ================================= CACHE ================================ */
@@ -113,12 +117,13 @@ ENTRY(cpu_sa110_do_idle)
* addr: cache-unaligned virtual address
*/
.align 5
-ENTRY(cpu_sa110_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_sa110_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #DCACHELINESIZE
subs r1, r1, #DCACHELINESIZE
bhi 1b
ret lr
+SYM_FUNC_END(cpu_sa110_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -130,7 +135,7 @@ ENTRY(cpu_sa110_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_sa110_switch_mm)
+SYM_TYPED_FUNC_START(cpu_sa110_switch_mm)
#ifdef CONFIG_MMU
str lr, [sp, #-4]!
bl v4wb_flush_kern_cache_all @ clears IP
@@ -140,6 +145,7 @@ ENTRY(cpu_sa110_switch_mm)
#else
ret lr
#endif
+SYM_FUNC_END(cpu_sa110_switch_mm)
/*
* cpu_sa110_set_pte_ext(ptep, pte, ext)
@@ -147,7 +153,7 @@ ENTRY(cpu_sa110_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_sa110_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_sa110_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext wc_disable=0
mov r0, r0
@@ -155,6 +161,7 @@ ENTRY(cpu_sa110_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
ret lr
+SYM_FUNC_END(cpu_sa110_set_pte_ext)
.type __sa110_setup, #function
__sa110_setup:
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index e723bd4119d3..7c496195e440 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -17,6 +17,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
@@ -36,11 +37,12 @@
/*
* cpu_sa1100_proc_init()
*/
-ENTRY(cpu_sa1100_proc_init)
+SYM_TYPED_FUNC_START(cpu_sa1100_proc_init)
mov r0, #0
mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland
ret lr
+SYM_FUNC_END(cpu_sa1100_proc_init)
/*
* cpu_sa1100_proc_fin()
@@ -49,13 +51,14 @@ ENTRY(cpu_sa1100_proc_init)
* - Disable interrupts
* - Clean and turn off caches.
*/
-ENTRY(cpu_sa1100_proc_fin)
+SYM_TYPED_FUNC_START(cpu_sa1100_proc_fin)
mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_sa1100_proc_fin)
/*
* cpu_sa1100_reset(loc)
@@ -68,7 +71,7 @@ ENTRY(cpu_sa1100_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_sa1100_reset)
+SYM_TYPED_FUNC_START(cpu_sa1100_reset)
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
mcr p15, 0, ip, c7, c10, 4 @ drain WB
@@ -80,7 +83,7 @@ ENTRY(cpu_sa1100_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
ret r0
-ENDPROC(cpu_sa1100_reset)
+SYM_FUNC_END(cpu_sa1100_reset)
.popsection
/*
@@ -95,7 +98,7 @@ ENDPROC(cpu_sa1100_reset)
* 3 = switch to fast processor clock
*/
.align 5
-ENTRY(cpu_sa1100_do_idle)
+SYM_TYPED_FUNC_START(cpu_sa1100_do_idle)
mov r0, r0 @ 4 nop padding
mov r0, r0
mov r0, r0
@@ -111,6 +114,7 @@ ENTRY(cpu_sa1100_do_idle)
mov r0, r0 @ safety
mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
ret lr
+SYM_FUNC_END(cpu_sa1100_do_idle)
/* ================================= CACHE ================================ */
@@ -123,12 +127,13 @@ ENTRY(cpu_sa1100_do_idle)
* addr: cache-unaligned virtual address
*/
.align 5
-ENTRY(cpu_sa1100_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_sa1100_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #DCACHELINESIZE
subs r1, r1, #DCACHELINESIZE
bhi 1b
ret lr
+SYM_FUNC_END(cpu_sa1100_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -140,7 +145,7 @@ ENTRY(cpu_sa1100_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_sa1100_switch_mm)
+SYM_TYPED_FUNC_START(cpu_sa1100_switch_mm)
#ifdef CONFIG_MMU
str lr, [sp, #-4]!
bl v4wb_flush_kern_cache_all @ clears IP
@@ -151,6 +156,7 @@ ENTRY(cpu_sa1100_switch_mm)
#else
ret lr
#endif
+SYM_FUNC_END(cpu_sa1100_switch_mm)
/*
* cpu_sa1100_set_pte_ext(ptep, pte, ext)
@@ -158,7 +164,7 @@ ENTRY(cpu_sa1100_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_sa1100_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_sa1100_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext wc_disable=0
mov r0, r0
@@ -166,20 +172,21 @@ ENTRY(cpu_sa1100_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
ret lr
+SYM_FUNC_END(cpu_sa1100_set_pte_ext)
.globl cpu_sa1100_suspend_size
.equ cpu_sa1100_suspend_size, 4 * 3
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_sa1100_do_suspend)
+SYM_TYPED_FUNC_START(cpu_sa1100_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c3, c0, 0 @ domain ID
mrc p15, 0, r5, c13, c0, 0 @ PID
mrc p15, 0, r6, c1, c0, 0 @ control reg
stmia r0, {r4 - r6} @ store cp regs
ldmfd sp!, {r4 - r6, pc}
-ENDPROC(cpu_sa1100_do_suspend)
+SYM_FUNC_END(cpu_sa1100_do_suspend)
-ENTRY(cpu_sa1100_do_resume)
+SYM_TYPED_FUNC_START(cpu_sa1100_do_resume)
ldmia r0, {r4 - r6} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs
@@ -192,7 +199,7 @@ ENTRY(cpu_sa1100_do_resume)
mcr p15, 0, r5, c13, c0, 0 @ PID
mov r0, r6 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_sa1100_do_resume)
+SYM_FUNC_END(cpu_sa1100_do_resume)
#endif
.type __sa1100_setup, #function
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 203dff89ab1a..90a01f5950b9 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -8,6 +8,7 @@
* This is the "shell" of the ARMv6 processor support.
*/
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/linkage.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
@@ -34,15 +35,17 @@
.arch armv6
-ENTRY(cpu_v6_proc_init)
+SYM_TYPED_FUNC_START(cpu_v6_proc_init)
ret lr
+SYM_FUNC_END(cpu_v6_proc_init)
-ENTRY(cpu_v6_proc_fin)
+SYM_TYPED_FUNC_START(cpu_v6_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x0006 @ .............ca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_v6_proc_fin)
/*
* cpu_v6_reset(loc)
@@ -55,14 +58,14 @@ ENTRY(cpu_v6_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_v6_reset)
+SYM_TYPED_FUNC_START(cpu_v6_reset)
mrc p15, 0, r1, c1, c0, 0 @ ctrl register
bic r1, r1, #0x1 @ ...............m
mcr p15, 0, r1, c1, c0, 0 @ disable MMU
mov r1, #0
mcr p15, 0, r1, c7, c5, 4 @ ISB
ret r0
-ENDPROC(cpu_v6_reset)
+SYM_FUNC_END(cpu_v6_reset)
.popsection
/*
@@ -72,18 +75,20 @@ ENDPROC(cpu_v6_reset)
*
* IRQs are already disabled.
*/
-ENTRY(cpu_v6_do_idle)
+SYM_TYPED_FUNC_START(cpu_v6_do_idle)
mov r1, #0
mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode
mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt
ret lr
+SYM_FUNC_END(cpu_v6_do_idle)
-ENTRY(cpu_v6_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_v6_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #D_CACHE_LINE_SIZE
subs r1, r1, #D_CACHE_LINE_SIZE
bhi 1b
ret lr
+SYM_FUNC_END(cpu_v6_dcache_clean_area)
/*
* cpu_v6_switch_mm(pgd_phys, tsk)
@@ -95,7 +100,7 @@ ENTRY(cpu_v6_dcache_clean_area)
* It is assumed that:
* - we are not using split page tables
*/
-ENTRY(cpu_v6_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v6_switch_mm)
#ifdef CONFIG_MMU
mov r2, #0
mmid r1, r1 @ get mm->context.id
@@ -113,6 +118,7 @@ ENTRY(cpu_v6_switch_mm)
mcr p15, 0, r1, c13, c0, 1 @ set context ID
#endif
ret lr
+SYM_FUNC_END(cpu_v6_switch_mm)
/*
* cpu_v6_set_pte_ext(ptep, pte, ext)
@@ -126,17 +132,18 @@ ENTRY(cpu_v6_switch_mm)
*/
armv6_mt_table cpu_v6
-ENTRY(cpu_v6_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_v6_set_pte_ext)
#ifdef CONFIG_MMU
armv6_set_pte_ext cpu_v6
#endif
ret lr
+SYM_FUNC_END(cpu_v6_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
.globl cpu_v6_suspend_size
.equ cpu_v6_suspend_size, 4 * 6
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_v6_do_suspend)
+SYM_TYPED_FUNC_START(cpu_v6_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
#ifdef CONFIG_MMU
@@ -148,9 +155,9 @@ ENTRY(cpu_v6_do_suspend)
mrc p15, 0, r9, c1, c0, 0 @ control register
stmia r0, {r4 - r9}
ldmfd sp!, {r4- r9, pc}
-ENDPROC(cpu_v6_do_suspend)
+SYM_FUNC_END(cpu_v6_do_suspend)
-ENTRY(cpu_v6_do_resume)
+SYM_TYPED_FUNC_START(cpu_v6_do_resume)
mov ip, #0
mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
@@ -172,7 +179,7 @@ ENTRY(cpu_v6_do_resume)
mcr p15, 0, ip, c7, c5, 4 @ ISB
mov r0, r9 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_v6_do_resume)
+SYM_FUNC_END(cpu_v6_do_resume)
#endif
string cpu_v6_name, "ARMv6-compatible processor"
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 0a3083ad19c2..1007702fcaf3 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -40,7 +40,7 @@
* even on Cortex-A8 revisions not affected by 430973.
* If IBE is not set, the flush BTAC/BTB won't do anything.
*/
-ENTRY(cpu_v7_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v7_switch_mm)
#ifdef CONFIG_MMU
mmid r1, r1 @ get mm->context.id
ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
@@ -59,7 +59,7 @@ ENTRY(cpu_v7_switch_mm)
isb
#endif
bx lr
-ENDPROC(cpu_v7_switch_mm)
+SYM_FUNC_END(cpu_v7_switch_mm)
/*
* cpu_v7_set_pte_ext(ptep, pte)
@@ -71,7 +71,7 @@ ENDPROC(cpu_v7_switch_mm)
* - pte - PTE value to store
* - ext - value for extended PTE bits
*/
-ENTRY(cpu_v7_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_v7_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0] @ linux version
@@ -106,7 +106,7 @@ ENTRY(cpu_v7_set_pte_ext)
ALT_UP (mcr p15, 0, r0, c7, c10, 1) @ flush_pte
#endif
bx lr
-ENDPROC(cpu_v7_set_pte_ext)
+SYM_FUNC_END(cpu_v7_set_pte_ext)
/*
* Memory region attributes with SCTLR.TRE=1
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 131984462d0d..bdabc15cde56 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -42,7 +42,7 @@
* Set the translation table base pointer to be pgd_phys (physical address of
* the new TTB).
*/
-ENTRY(cpu_v7_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v7_switch_mm)
#ifdef CONFIG_MMU
mmid r2, r2
asid r2, r2
@@ -51,7 +51,7 @@ ENTRY(cpu_v7_switch_mm)
isb
#endif
ret lr
-ENDPROC(cpu_v7_switch_mm)
+SYM_FUNC_END(cpu_v7_switch_mm)
#ifdef __ARMEB__
#define rl r3
@@ -68,7 +68,7 @@ ENDPROC(cpu_v7_switch_mm)
* - ptep - pointer to level 3 translation table entry
* - pte - PTE value to store (64-bit in r2 and r3)
*/
-ENTRY(cpu_v7_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_v7_set_pte_ext)
#ifdef CONFIG_MMU
tst rl, #L_PTE_VALID
beq 1f
@@ -87,7 +87,7 @@ ENTRY(cpu_v7_set_pte_ext)
ALT_UP (mcr p15, 0, r0, c7, c10, 1) @ flush_pte
#endif
ret lr
-ENDPROC(cpu_v7_set_pte_ext)
+SYM_FUNC_END(cpu_v7_set_pte_ext)
/*
* Memory region attributes for LPAE (defined in pgtable-3level.h):
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 193c7aeb6703..5fb9a6aecb00 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -7,6 +7,7 @@
* This is the "shell" of the ARMv7 processor support.
*/
#include <linux/arm-smccc.h>
+#include <linux/cfi_types.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/pgtable.h>
@@ -26,17 +27,17 @@
.arch armv7-a
-ENTRY(cpu_v7_proc_init)
+SYM_TYPED_FUNC_START(cpu_v7_proc_init)
ret lr
-ENDPROC(cpu_v7_proc_init)
+SYM_FUNC_END(cpu_v7_proc_init)
-ENTRY(cpu_v7_proc_fin)
+SYM_TYPED_FUNC_START(cpu_v7_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x0006 @ .............ca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
-ENDPROC(cpu_v7_proc_fin)
+SYM_FUNC_END(cpu_v7_proc_fin)
/*
* cpu_v7_reset(loc, hyp)
@@ -53,7 +54,7 @@ ENDPROC(cpu_v7_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_v7_reset)
+SYM_TYPED_FUNC_START(cpu_v7_reset)
mrc p15, 0, r2, c1, c0, 0 @ ctrl register
bic r2, r2, #0x1 @ ...............m
THUMB( bic r2, r2, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
@@ -64,7 +65,7 @@ ENTRY(cpu_v7_reset)
bne __hyp_soft_restart
#endif
bx r0
-ENDPROC(cpu_v7_reset)
+SYM_FUNC_END(cpu_v7_reset)
.popsection
/*
@@ -74,13 +75,13 @@ ENDPROC(cpu_v7_reset)
*
* IRQs are already disabled.
*/
-ENTRY(cpu_v7_do_idle)
+SYM_TYPED_FUNC_START(cpu_v7_do_idle)
dsb @ WFI may enter a low-power mode
wfi
ret lr
-ENDPROC(cpu_v7_do_idle)
+SYM_FUNC_END(cpu_v7_do_idle)
-ENTRY(cpu_v7_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_v7_dcache_clean_area)
ALT_SMP(W(nop)) @ MP extensions imply L1 PTW
ALT_UP_B(1f)
ret lr
@@ -91,38 +92,39 @@ ENTRY(cpu_v7_dcache_clean_area)
bhi 2b
dsb ishst
ret lr
-ENDPROC(cpu_v7_dcache_clean_area)
+SYM_FUNC_END(cpu_v7_dcache_clean_area)
#ifdef CONFIG_ARM_PSCI
.arch_extension sec
-ENTRY(cpu_v7_smc_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v7_smc_switch_mm)
stmfd sp!, {r0 - r3}
movw r0, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1
movt r0, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1
smc #0
ldmfd sp!, {r0 - r3}
b cpu_v7_switch_mm
-ENDPROC(cpu_v7_smc_switch_mm)
+SYM_FUNC_END(cpu_v7_smc_switch_mm)
.arch_extension virt
-ENTRY(cpu_v7_hvc_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v7_hvc_switch_mm)
stmfd sp!, {r0 - r3}
movw r0, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1
movt r0, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1
hvc #0
ldmfd sp!, {r0 - r3}
b cpu_v7_switch_mm
-ENDPROC(cpu_v7_hvc_switch_mm)
+SYM_FUNC_END(cpu_v7_hvc_switch_mm)
#endif
-ENTRY(cpu_v7_iciallu_switch_mm)
+
+SYM_TYPED_FUNC_START(cpu_v7_iciallu_switch_mm)
mov r3, #0
mcr p15, 0, r3, c7, c5, 0 @ ICIALLU
b cpu_v7_switch_mm
-ENDPROC(cpu_v7_iciallu_switch_mm)
-ENTRY(cpu_v7_bpiall_switch_mm)
+SYM_FUNC_END(cpu_v7_iciallu_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v7_bpiall_switch_mm)
mov r3, #0
mcr p15, 0, r3, c7, c5, 6 @ flush BTAC/BTB
b cpu_v7_switch_mm
-ENDPROC(cpu_v7_bpiall_switch_mm)
+SYM_FUNC_END(cpu_v7_bpiall_switch_mm)
string cpu_v7_name, "ARMv7 Processor"
.align
@@ -131,7 +133,7 @@ ENDPROC(cpu_v7_bpiall_switch_mm)
.globl cpu_v7_suspend_size
.equ cpu_v7_suspend_size, 4 * 9
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_v7_do_suspend)
+SYM_TYPED_FUNC_START(cpu_v7_do_suspend)
stmfd sp!, {r4 - r11, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID
@@ -150,9 +152,9 @@ ENTRY(cpu_v7_do_suspend)
mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
stmia r0, {r5 - r11}
ldmfd sp!, {r4 - r11, pc}
-ENDPROC(cpu_v7_do_suspend)
+SYM_FUNC_END(cpu_v7_do_suspend)
-ENTRY(cpu_v7_do_resume)
+SYM_TYPED_FUNC_START(cpu_v7_do_resume)
mov ip, #0
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
@@ -186,22 +188,22 @@ ENTRY(cpu_v7_do_resume)
dsb
mov r0, r8 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_v7_do_resume)
+SYM_FUNC_END(cpu_v7_do_resume)
#endif
.globl cpu_ca9mp_suspend_size
.equ cpu_ca9mp_suspend_size, cpu_v7_suspend_size + 4 * 2
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_ca9mp_do_suspend)
+SYM_TYPED_FUNC_START(cpu_ca9mp_do_suspend)
stmfd sp!, {r4 - r5}
mrc p15, 0, r4, c15, c0, 1 @ Diagnostic register
mrc p15, 0, r5, c15, c0, 0 @ Power register
stmia r0!, {r4 - r5}
ldmfd sp!, {r4 - r5}
b cpu_v7_do_suspend
-ENDPROC(cpu_ca9mp_do_suspend)
+SYM_FUNC_END(cpu_ca9mp_do_suspend)
-ENTRY(cpu_ca9mp_do_resume)
+SYM_TYPED_FUNC_START(cpu_ca9mp_do_resume)
ldmia r0!, {r4 - r5}
mrc p15, 0, r10, c15, c0, 1 @ Read Diagnostic register
teq r4, r10 @ Already restored?
@@ -210,7 +212,7 @@ ENTRY(cpu_ca9mp_do_resume)
teq r5, r10 @ Already restored?
mcrne p15, 0, r5, c15, c0, 0 @ No, so restore it
b cpu_v7_do_resume
-ENDPROC(cpu_ca9mp_do_resume)
+SYM_FUNC_END(cpu_ca9mp_do_resume)
#endif
#ifdef CONFIG_CPU_PJ4B
@@ -220,18 +222,18 @@ ENDPROC(cpu_ca9mp_do_resume)
globl_equ cpu_pj4b_proc_fin, cpu_v7_proc_fin
globl_equ cpu_pj4b_reset, cpu_v7_reset
#ifdef CONFIG_PJ4B_ERRATA_4742
-ENTRY(cpu_pj4b_do_idle)
+SYM_TYPED_FUNC_START(cpu_pj4b_do_idle)
dsb @ WFI may enter a low-power mode
wfi
dsb @barrier
ret lr
-ENDPROC(cpu_pj4b_do_idle)
+SYM_FUNC_END(cpu_pj4b_do_idle)
#else
globl_equ cpu_pj4b_do_idle, cpu_v7_do_idle
#endif
globl_equ cpu_pj4b_dcache_clean_area, cpu_v7_dcache_clean_area
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_pj4b_do_suspend)
+SYM_TYPED_FUNC_START(cpu_pj4b_do_suspend)
stmfd sp!, {r6 - r10}
mrc p15, 1, r6, c15, c1, 0 @ save CP15 - extra features
mrc p15, 1, r7, c15, c2, 0 @ save CP15 - Aux Func Modes Ctrl 0
@@ -241,9 +243,9 @@ ENTRY(cpu_pj4b_do_suspend)
stmia r0!, {r6 - r10}
ldmfd sp!, {r6 - r10}
b cpu_v7_do_suspend
-ENDPROC(cpu_pj4b_do_suspend)
+SYM_FUNC_END(cpu_pj4b_do_suspend)
-ENTRY(cpu_pj4b_do_resume)
+SYM_TYPED_FUNC_START(cpu_pj4b_do_resume)
ldmia r0!, {r6 - r10}
mcr p15, 1, r6, c15, c1, 0 @ restore CP15 - extra features
mcr p15, 1, r7, c15, c2, 0 @ restore CP15 - Aux Func Modes Ctrl 0
@@ -251,7 +253,7 @@ ENTRY(cpu_pj4b_do_resume)
mcr p15, 1, r9, c15, c1, 1 @ restore CP15 - Aux Debug Modes Ctrl 1
mcr p15, 0, r10, c9, c14, 0 @ restore CP15 - PMC
b cpu_v7_do_resume
-ENDPROC(cpu_pj4b_do_resume)
+SYM_FUNC_END(cpu_pj4b_do_resume)
#endif
.globl cpu_pj4b_suspend_size
.equ cpu_pj4b_suspend_size, cpu_v7_suspend_size + 4 * 5
diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
index d65a12f851a9..d4675603593b 100644
--- a/arch/arm/mm/proc-v7m.S
+++ b/arch/arm/mm/proc-v7m.S
@@ -8,18 +8,19 @@
* This is the "shell" of the ARMv7-M processor support.
*/
#include <linux/linkage.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/page.h>
#include <asm/v7m.h>
#include "proc-macros.S"
-ENTRY(cpu_v7m_proc_init)
+SYM_TYPED_FUNC_START(cpu_v7m_proc_init)
ret lr
-ENDPROC(cpu_v7m_proc_init)
+SYM_FUNC_END(cpu_v7m_proc_init)
-ENTRY(cpu_v7m_proc_fin)
+SYM_TYPED_FUNC_START(cpu_v7m_proc_fin)
ret lr
-ENDPROC(cpu_v7m_proc_fin)
+SYM_FUNC_END(cpu_v7m_proc_fin)
/*
* cpu_v7m_reset(loc)
@@ -31,9 +32,9 @@ ENDPROC(cpu_v7m_proc_fin)
* - loc - location to jump to for soft reset
*/
.align 5
-ENTRY(cpu_v7m_reset)
+SYM_TYPED_FUNC_START(cpu_v7m_reset)
ret r0
-ENDPROC(cpu_v7m_reset)
+SYM_FUNC_END(cpu_v7m_reset)
/*
* cpu_v7m_do_idle()
@@ -42,36 +43,36 @@ ENDPROC(cpu_v7m_reset)
*
* IRQs are already disabled.
*/
-ENTRY(cpu_v7m_do_idle)
+SYM_TYPED_FUNC_START(cpu_v7m_do_idle)
wfi
ret lr
-ENDPROC(cpu_v7m_do_idle)
+SYM_FUNC_END(cpu_v7m_do_idle)
-ENTRY(cpu_v7m_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_v7m_dcache_clean_area)
ret lr
-ENDPROC(cpu_v7m_dcache_clean_area)
+SYM_FUNC_END(cpu_v7m_dcache_clean_area)
/*
* There is no MMU, so here is nothing to do.
*/
-ENTRY(cpu_v7m_switch_mm)
+SYM_TYPED_FUNC_START(cpu_v7m_switch_mm)
ret lr
-ENDPROC(cpu_v7m_switch_mm)
+SYM_FUNC_END(cpu_v7m_switch_mm)
.globl cpu_v7m_suspend_size
.equ cpu_v7m_suspend_size, 0
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_v7m_do_suspend)
+SYM_TYPED_FUNC_START(cpu_v7m_do_suspend)
ret lr
-ENDPROC(cpu_v7m_do_suspend)
+SYM_FUNC_END(cpu_v7m_do_suspend)
-ENTRY(cpu_v7m_do_resume)
+SYM_TYPED_FUNC_START(cpu_v7m_do_resume)
ret lr
-ENDPROC(cpu_v7m_do_resume)
+SYM_FUNC_END(cpu_v7m_do_resume)
#endif
-ENTRY(cpu_cm7_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_cm7_dcache_clean_area)
dcache_line_size r2, r3
movw r3, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC
movt r3, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC
@@ -82,16 +83,16 @@ ENTRY(cpu_cm7_dcache_clean_area)
bhi 1b
dsb
ret lr
-ENDPROC(cpu_cm7_dcache_clean_area)
+SYM_FUNC_END(cpu_cm7_dcache_clean_area)
-ENTRY(cpu_cm7_proc_fin)
+SYM_TYPED_FUNC_START(cpu_cm7_proc_fin)
movw r2, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
movt r2, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
ldr r0, [r2]
bic r0, r0, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC)
str r0, [r2]
ret lr
-ENDPROC(cpu_cm7_proc_fin)
+SYM_FUNC_END(cpu_cm7_proc_fin)
.section ".init.text", "ax"
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index a17afe7e195a..14927b380452 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -23,6 +23,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -79,18 +80,20 @@
*
* Nothing too exciting at the moment
*/
-ENTRY(cpu_xsc3_proc_init)
+SYM_TYPED_FUNC_START(cpu_xsc3_proc_init)
ret lr
+SYM_FUNC_END(cpu_xsc3_proc_init)
/*
* cpu_xsc3_proc_fin()
*/
-ENTRY(cpu_xsc3_proc_fin)
+SYM_TYPED_FUNC_START(cpu_xsc3_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...IZ...........
bic r0, r0, #0x0006 @ .............CA.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_xsc3_proc_fin)
/*
* cpu_xsc3_reset(loc)
@@ -103,7 +106,7 @@ ENTRY(cpu_xsc3_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_xsc3_reset)
+SYM_TYPED_FUNC_START(cpu_xsc3_reset)
mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
msr cpsr_c, r1 @ reset CPSR
mrc p15, 0, r1, c1, c0, 0 @ ctrl register
@@ -117,7 +120,7 @@ ENTRY(cpu_xsc3_reset)
@ already containing those two last instructions to survive.
mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
ret r0
-ENDPROC(cpu_xsc3_reset)
+SYM_FUNC_END(cpu_xsc3_reset)
.popsection
/*
@@ -132,10 +135,11 @@ ENDPROC(cpu_xsc3_reset)
*/
.align 5
-ENTRY(cpu_xsc3_do_idle)
+SYM_TYPED_FUNC_START(cpu_xsc3_do_idle)
mov r0, #1
mcr p14, 0, r0, c7, c0, 0 @ go to idle
ret lr
+SYM_FUNC_END(cpu_xsc3_do_idle)
/* ================================= CACHE ================================ */
@@ -144,11 +148,11 @@ ENTRY(cpu_xsc3_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(xsc3_flush_icache_all)
+SYM_TYPED_FUNC_START(xsc3_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(xsc3_flush_icache_all)
+SYM_FUNC_END(xsc3_flush_icache_all)
/*
* flush_user_cache_all()
@@ -156,15 +160,14 @@ ENDPROC(xsc3_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(xsc3_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(xsc3_flush_user_cache_all, xsc3_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(xsc3_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(xsc3_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -174,6 +177,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(xsc3_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, vm_flags)
@@ -186,7 +190,7 @@ __flush_whole_cache:
* - vma - vma_area_struct describing address space
*/
.align 5
-ENTRY(xsc3_flush_user_cache_range)
+SYM_TYPED_FUNC_START(xsc3_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #MAX_AREA_SIZE
@@ -203,6 +207,7 @@ ENTRY(xsc3_flush_user_cache_range)
mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(xsc3_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -217,9 +222,13 @@ ENTRY(xsc3_flush_user_cache_range)
* Note: single I-cache line invalidation isn't used here since
* it also trashes the mini I-cache used by JTAG debuggers.
*/
-ENTRY(xsc3_coherent_kern_range)
-/* FALLTHROUGH */
-ENTRY(xsc3_coherent_user_range)
+SYM_TYPED_FUNC_START(xsc3_coherent_kern_range)
+#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
+ b xsc3_coherent_user_range
+#endif
+SYM_FUNC_END(xsc3_coherent_kern_range)
+
+SYM_TYPED_FUNC_START(xsc3_coherent_user_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
add r0, r0, #CACHELINESIZE
@@ -230,6 +239,7 @@ ENTRY(xsc3_coherent_user_range)
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(xsc3_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -240,7 +250,7 @@ ENTRY(xsc3_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(xsc3_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(xsc3_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
add r0, r0, #CACHELINESIZE
@@ -251,6 +261,7 @@ ENTRY(xsc3_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
ret lr
+SYM_FUNC_END(xsc3_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -301,7 +312,7 @@ xsc3_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(xsc3_dma_flush_range)
+SYM_TYPED_FUNC_START(xsc3_dma_flush_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
add r0, r0, #CACHELINESIZE
@@ -309,6 +320,7 @@ ENTRY(xsc3_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
ret lr
+SYM_FUNC_END(xsc3_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -316,13 +328,13 @@ ENTRY(xsc3_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xsc3_dma_map_area)
+SYM_TYPED_FUNC_START(xsc3_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq xsc3_dma_clean_range
bcs xsc3_dma_inv_range
b xsc3_dma_flush_range
-ENDPROC(xsc3_dma_map_area)
+SYM_FUNC_END(xsc3_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -330,22 +342,17 @@ ENDPROC(xsc3_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xsc3_dma_unmap_area)
+SYM_TYPED_FUNC_START(xsc3_dma_unmap_area)
ret lr
-ENDPROC(xsc3_dma_unmap_area)
-
- .globl xsc3_flush_kern_cache_louis
- .equ xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions xsc3
+SYM_FUNC_END(xsc3_dma_unmap_area)
-ENTRY(cpu_xsc3_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_xsc3_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
add r0, r0, #CACHELINESIZE
subs r1, r1, #CACHELINESIZE
bhi 1b
ret lr
+SYM_FUNC_END(cpu_xsc3_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -357,7 +364,7 @@ ENTRY(cpu_xsc3_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_xsc3_switch_mm)
+SYM_TYPED_FUNC_START(cpu_xsc3_switch_mm)
clean_d_cache r1, r2
mcr p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
mcr p15, 0, ip, c7, c10, 4 @ data write barrier
@@ -366,6 +373,7 @@ ENTRY(cpu_xsc3_switch_mm)
mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
cpwait_ret lr, ip
+SYM_FUNC_END(cpu_xsc3_switch_mm)
/*
* cpu_xsc3_set_pte_ext(ptep, pte, ext)
@@ -391,7 +399,7 @@ cpu_xsc3_mt_table:
.long 0x00 @ unused
.align 5
-ENTRY(cpu_xsc3_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_xsc3_set_pte_ext)
xscale_set_pte_ext_prologue
tst r1, #L_PTE_SHARED @ shared?
@@ -404,6 +412,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
xscale_set_pte_ext_epilogue
ret lr
+SYM_FUNC_END(cpu_xsc3_set_pte_ext)
.ltorg
.align
@@ -411,7 +420,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
.globl cpu_xsc3_suspend_size
.equ cpu_xsc3_suspend_size, 4 * 6
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_xsc3_do_suspend)
+SYM_TYPED_FUNC_START(cpu_xsc3_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
@@ -422,9 +431,9 @@ ENTRY(cpu_xsc3_do_suspend)
bic r4, r4, #2 @ clear frequency change bit
stmia r0, {r4 - r9} @ store cp regs
ldmia sp!, {r4 - r9, pc}
-ENDPROC(cpu_xsc3_do_suspend)
+SYM_FUNC_END(cpu_xsc3_do_suspend)
-ENTRY(cpu_xsc3_do_resume)
+SYM_TYPED_FUNC_START(cpu_xsc3_do_resume)
ldmia r0, {r4 - r9} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
@@ -440,7 +449,7 @@ ENTRY(cpu_xsc3_do_resume)
mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
mov r0, r9 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_xsc3_do_resume)
+SYM_FUNC_END(cpu_xsc3_do_resume)
#endif
.type __xsc3_setup, #function
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index d82590aa71c0..d8462df8020b 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -19,6 +19,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <linux/pgtable.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
@@ -111,22 +112,24 @@ clean_addr: .word CLEAN_ADDR
*
* Nothing too exciting at the moment
*/
-ENTRY(cpu_xscale_proc_init)
+SYM_TYPED_FUNC_START(cpu_xscale_proc_init)
@ enable write buffer coalescing. Some bootloader disable it
mrc p15, 0, r1, c1, c0, 1
bic r1, r1, #1
mcr p15, 0, r1, c1, c0, 1
ret lr
+SYM_FUNC_END(cpu_xscale_proc_init)
/*
* cpu_xscale_proc_fin()
*/
-ENTRY(cpu_xscale_proc_fin)
+SYM_TYPED_FUNC_START(cpu_xscale_proc_fin)
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...IZ...........
bic r0, r0, #0x0006 @ .............CA.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ret lr
+SYM_FUNC_END(cpu_xscale_proc_fin)
/*
* cpu_xscale_reset(loc)
@@ -141,7 +144,7 @@ ENTRY(cpu_xscale_proc_fin)
*/
.align 5
.pushsection .idmap.text, "ax"
-ENTRY(cpu_xscale_reset)
+SYM_TYPED_FUNC_START(cpu_xscale_reset)
mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
msr cpsr_c, r1 @ reset CPSR
mcr p15, 0, r1, c10, c4, 1 @ unlock I-TLB
@@ -159,7 +162,7 @@ ENTRY(cpu_xscale_reset)
@ already containing those two last instructions to survive.
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
ret r0
-ENDPROC(cpu_xscale_reset)
+SYM_FUNC_END(cpu_xscale_reset)
.popsection
/*
@@ -174,10 +177,11 @@ ENDPROC(cpu_xscale_reset)
*/
.align 5
-ENTRY(cpu_xscale_do_idle)
+SYM_TYPED_FUNC_START(cpu_xscale_do_idle)
mov r0, #1
mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE
ret lr
+SYM_FUNC_END(cpu_xscale_do_idle)
/* ================================= CACHE ================================ */
@@ -186,11 +190,11 @@ ENTRY(cpu_xscale_do_idle)
*
* Unconditionally clean and invalidate the entire icache.
*/
-ENTRY(xscale_flush_icache_all)
+SYM_TYPED_FUNC_START(xscale_flush_icache_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
ret lr
-ENDPROC(xscale_flush_icache_all)
+SYM_FUNC_END(xscale_flush_icache_all)
/*
* flush_user_cache_all()
@@ -198,15 +202,14 @@ ENDPROC(xscale_flush_icache_all)
* Invalidate all cache entries in a particular address
* space.
*/
-ENTRY(xscale_flush_user_cache_all)
- /* FALLTHROUGH */
+SYM_FUNC_ALIAS(xscale_flush_user_cache_all, xscale_flush_kern_cache_all)
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
-ENTRY(xscale_flush_kern_cache_all)
+SYM_TYPED_FUNC_START(xscale_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
@@ -215,6 +218,7 @@ __flush_whole_cache:
mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
ret lr
+SYM_FUNC_END(xscale_flush_kern_cache_all)
/*
* flush_user_cache_range(start, end, vm_flags)
@@ -227,7 +231,7 @@ __flush_whole_cache:
* - vma - vma_area_struct describing address space
*/
.align 5
-ENTRY(xscale_flush_user_cache_range)
+SYM_TYPED_FUNC_START(xscale_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #MAX_AREA_SIZE
@@ -244,6 +248,7 @@ ENTRY(xscale_flush_user_cache_range)
mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB
mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
ret lr
+SYM_FUNC_END(xscale_flush_user_cache_range)
/*
* coherent_kern_range(start, end)
@@ -258,7 +263,7 @@ ENTRY(xscale_flush_user_cache_range)
* Note: single I-cache line invalidation isn't used here since
* it also trashes the mini I-cache used by JTAG debuggers.
*/
-ENTRY(xscale_coherent_kern_range)
+SYM_TYPED_FUNC_START(xscale_coherent_kern_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHELINESIZE
@@ -268,6 +273,7 @@ ENTRY(xscale_coherent_kern_range)
mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB
mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
ret lr
+SYM_FUNC_END(xscale_coherent_kern_range)
/*
* coherent_user_range(start, end)
@@ -279,7 +285,7 @@ ENTRY(xscale_coherent_kern_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(xscale_coherent_user_range)
+SYM_TYPED_FUNC_START(xscale_coherent_user_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache entry
@@ -290,6 +296,7 @@ ENTRY(xscale_coherent_user_range)
mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB
mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
ret lr
+SYM_FUNC_END(xscale_coherent_user_range)
/*
* flush_kern_dcache_area(void *addr, size_t size)
@@ -300,7 +307,7 @@ ENTRY(xscale_coherent_user_range)
* - addr - kernel address
* - size - region size
*/
-ENTRY(xscale_flush_kern_dcache_area)
+SYM_TYPED_FUNC_START(xscale_flush_kern_dcache_area)
add r1, r0, r1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
@@ -311,6 +318,7 @@ ENTRY(xscale_flush_kern_dcache_area)
mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB
mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
ret lr
+SYM_FUNC_END(xscale_flush_kern_dcache_area)
/*
* dma_inv_range(start, end)
@@ -361,7 +369,7 @@ xscale_dma_clean_range:
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(xscale_dma_flush_range)
+SYM_TYPED_FUNC_START(xscale_dma_flush_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
@@ -370,6 +378,7 @@ ENTRY(xscale_dma_flush_range)
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
ret lr
+SYM_FUNC_END(xscale_dma_flush_range)
/*
* dma_map_area(start, size, dir)
@@ -377,13 +386,27 @@ ENTRY(xscale_dma_flush_range)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xscale_dma_map_area)
+SYM_TYPED_FUNC_START(xscale_dma_map_area)
add r1, r1, r0
cmp r2, #DMA_TO_DEVICE
beq xscale_dma_clean_range
bcs xscale_dma_inv_range
b xscale_dma_flush_range
-ENDPROC(xscale_dma_map_area)
+SYM_FUNC_END(xscale_dma_map_area)
+
+/*
+ * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
+ * clear the dirty bits, which means that if we invalidate a dirty line,
+ * the dirty data can still be written back to external memory later on.
+ *
+ * The recommended workaround is to always do a clean D-cache line before
+ * doing an invalidate D-cache line, so on the affected processors,
+ * dma_inv_range() is implemented as dma_flush_range().
+ *
+ * See erratum #25 of "Intel 80200 Processor Specification Update",
+ * revision January 22, 2003, available at:
+ * http://www.intel.com/design/iio/specupdt/273415.htm
+ */
/*
* dma_map_area(start, size, dir)
@@ -391,12 +414,12 @@ ENDPROC(xscale_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xscale_80200_A0_A1_dma_map_area)
+SYM_TYPED_FUNC_START(xscale_80200_A0_A1_dma_map_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
beq xscale_dma_clean_range
b xscale_dma_flush_range
-ENDPROC(xscale_80200_A0_A1_dma_map_area)
+SYM_FUNC_END(xscale_80200_A0_A1_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -404,59 +427,17 @@ ENDPROC(xscale_80200_A0_A1_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xscale_dma_unmap_area)
+SYM_TYPED_FUNC_START(xscale_dma_unmap_area)
ret lr
-ENDPROC(xscale_dma_unmap_area)
-
- .globl xscale_flush_kern_cache_louis
- .equ xscale_flush_kern_cache_louis, xscale_flush_kern_cache_all
+SYM_FUNC_END(xscale_dma_unmap_area)
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions xscale
-
-/*
- * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
- * clear the dirty bits, which means that if we invalidate a dirty line,
- * the dirty data can still be written back to external memory later on.
- *
- * The recommended workaround is to always do a clean D-cache line before
- * doing an invalidate D-cache line, so on the affected processors,
- * dma_inv_range() is implemented as dma_flush_range().
- *
- * See erratum #25 of "Intel 80200 Processor Specification Update",
- * revision January 22, 2003, available at:
- * http://www.intel.com/design/iio/specupdt/273415.htm
- */
-.macro a0_alias basename
- .globl xscale_80200_A0_A1_\basename
- .type xscale_80200_A0_A1_\basename , %function
- .equ xscale_80200_A0_A1_\basename , xscale_\basename
-.endm
-
-/*
- * Most of the cache functions are unchanged for these processor revisions.
- * Export suitable alias symbols for the unchanged functions:
- */
- a0_alias flush_icache_all
- a0_alias flush_user_cache_all
- a0_alias flush_kern_cache_all
- a0_alias flush_kern_cache_louis
- a0_alias flush_user_cache_range
- a0_alias coherent_kern_range
- a0_alias coherent_user_range
- a0_alias flush_kern_dcache_area
- a0_alias dma_flush_range
- a0_alias dma_unmap_area
-
- @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
- define_cache_functions xscale_80200_A0_A1
-
-ENTRY(cpu_xscale_dcache_clean_area)
+SYM_TYPED_FUNC_START(cpu_xscale_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHELINESIZE
subs r1, r1, #CACHELINESIZE
bhi 1b
ret lr
+SYM_FUNC_END(cpu_xscale_dcache_clean_area)
/* =============================== PageTable ============================== */
@@ -468,13 +449,14 @@ ENTRY(cpu_xscale_dcache_clean_area)
* pgd: new page tables
*/
.align 5
-ENTRY(cpu_xscale_switch_mm)
+SYM_TYPED_FUNC_START(cpu_xscale_switch_mm)
clean_d_cache r1, r2
mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
cpwait_ret lr, ip
+SYM_FUNC_END(cpu_xscale_switch_mm)
/*
* cpu_xscale_set_pte_ext(ptep, pte, ext)
@@ -502,7 +484,7 @@ cpu_xscale_mt_table:
.long 0x00 @ unused
.align 5
-ENTRY(cpu_xscale_set_pte_ext)
+SYM_TYPED_FUNC_START(cpu_xscale_set_pte_ext)
xscale_set_pte_ext_prologue
@
@@ -520,6 +502,7 @@ ENTRY(cpu_xscale_set_pte_ext)
xscale_set_pte_ext_epilogue
ret lr
+SYM_FUNC_END(cpu_xscale_set_pte_ext)
.ltorg
.align
@@ -527,7 +510,7 @@ ENTRY(cpu_xscale_set_pte_ext)
.globl cpu_xscale_suspend_size
.equ cpu_xscale_suspend_size, 4 * 6
#ifdef CONFIG_ARM_CPU_SUSPEND
-ENTRY(cpu_xscale_do_suspend)
+SYM_TYPED_FUNC_START(cpu_xscale_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
@@ -538,9 +521,9 @@ ENTRY(cpu_xscale_do_suspend)
bic r4, r4, #2 @ clear frequency change bit
stmia r0, {r4 - r9} @ store cp regs
ldmfd sp!, {r4 - r9, pc}
-ENDPROC(cpu_xscale_do_suspend)
+SYM_FUNC_END(cpu_xscale_do_suspend)
-ENTRY(cpu_xscale_do_resume)
+SYM_TYPED_FUNC_START(cpu_xscale_do_resume)
ldmia r0, {r4 - r9} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
@@ -553,7 +536,7 @@ ENTRY(cpu_xscale_do_resume)
mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
mov r0, r9 @ control register
b cpu_resume_mmu
-ENDPROC(cpu_xscale_do_resume)
+SYM_FUNC_END(cpu_xscale_do_resume)
#endif
.type __xscale_setup, #function
diff --git a/arch/arm/mm/proc.c b/arch/arm/mm/proc.c
new file mode 100644
index 000000000000..bdbbf65d1b36
--- /dev/null
+++ b/arch/arm/mm/proc.c
@@ -0,0 +1,500 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file defines C prototypes for the low-level processor assembly functions
+ * and creates a reference for CFI. This needs to be done for every assembly
+ * processor ("proc") function that is called from C but does not have a
+ * corresponding C implementation.
+ *
+ * Processors are listed in the order they appear in the Makefile.
+ *
+ * Functions are listed if and only if they see use on the target CPU, and in
+ * the order they are defined in struct processor.
+ */
+#include <asm/proc-fns.h>
+
+#ifdef CONFIG_CPU_ARM7TDMI
+void cpu_arm7tdmi_proc_init(void);
+__ADDRESSABLE(cpu_arm7tdmi_proc_init);
+void cpu_arm7tdmi_proc_fin(void);
+__ADDRESSABLE(cpu_arm7tdmi_proc_fin);
+void cpu_arm7tdmi_reset(void);
+__ADDRESSABLE(cpu_arm7tdmi_reset);
+int cpu_arm7tdmi_do_idle(void);
+__ADDRESSABLE(cpu_arm7tdmi_do_idle);
+void cpu_arm7tdmi_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm7tdmi_dcache_clean_area);
+void cpu_arm7tdmi_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm7tdmi_switch_mm);
+#endif
+
+#ifdef CONFIG_CPU_ARM720T
+void cpu_arm720_proc_init(void);
+__ADDRESSABLE(cpu_arm720_proc_init);
+void cpu_arm720_proc_fin(void);
+__ADDRESSABLE(cpu_arm720_proc_fin);
+void cpu_arm720_reset(void);
+__ADDRESSABLE(cpu_arm720_reset);
+int cpu_arm720_do_idle(void);
+__ADDRESSABLE(cpu_arm720_do_idle);
+void cpu_arm720_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm720_dcache_clean_area);
+void cpu_arm720_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm720_switch_mm);
+void cpu_arm720_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm720_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM740T
+void cpu_arm740_proc_init(void);
+__ADDRESSABLE(cpu_arm740_proc_init);
+void cpu_arm740_proc_fin(void);
+__ADDRESSABLE(cpu_arm740_proc_fin);
+void cpu_arm740_reset(void);
+__ADDRESSABLE(cpu_arm740_reset);
+int cpu_arm740_do_idle(void);
+__ADDRESSABLE(cpu_arm740_do_idle);
+void cpu_arm740_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm740_dcache_clean_area);
+void cpu_arm740_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm740_switch_mm);
+#endif
+
+#ifdef CONFIG_CPU_ARM9TDMI
+void cpu_arm9tdmi_proc_init(void);
+__ADDRESSABLE(cpu_arm9tdmi_proc_init);
+void cpu_arm9tdmi_proc_fin(void);
+__ADDRESSABLE(cpu_arm9tdmi_proc_fin);
+void cpu_arm9tdmi_reset(void);
+__ADDRESSABLE(cpu_arm9tdmi_reset);
+int cpu_arm9tdmi_do_idle(void);
+__ADDRESSABLE(cpu_arm9tdmi_do_idle);
+void cpu_arm9tdmi_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm9tdmi_dcache_clean_area);
+void cpu_arm9tdmi_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm9tdmi_switch_mm);
+#endif
+
+#ifdef CONFIG_CPU_ARM920T
+void cpu_arm920_proc_init(void);
+__ADDRESSABLE(cpu_arm920_proc_init);
+void cpu_arm920_proc_fin(void);
+__ADDRESSABLE(cpu_arm920_proc_fin);
+void cpu_arm920_reset(void);
+__ADDRESSABLE(cpu_arm920_reset);
+int cpu_arm920_do_idle(void);
+__ADDRESSABLE(cpu_arm920_do_idle);
+void cpu_arm920_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm920_dcache_clean_area);
+void cpu_arm920_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm920_switch_mm);
+void cpu_arm920_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm920_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_arm920_do_suspend(void *);
+__ADDRESSABLE(cpu_arm920_do_suspend);
+void cpu_arm920_do_resume(void *);
+__ADDRESSABLE(cpu_arm920_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_ARM920T */
+
+#ifdef CONFIG_CPU_ARM922T
+void cpu_arm922_proc_init(void);
+__ADDRESSABLE(cpu_arm922_proc_init);
+void cpu_arm922_proc_fin(void);
+__ADDRESSABLE(cpu_arm922_proc_fin);
+void cpu_arm922_reset(void);
+__ADDRESSABLE(cpu_arm922_reset);
+int cpu_arm922_do_idle(void);
+__ADDRESSABLE(cpu_arm922_do_idle);
+void cpu_arm922_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm922_dcache_clean_area);
+void cpu_arm922_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm922_switch_mm);
+void cpu_arm922_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm922_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM925T
+void cpu_arm925_proc_init(void);
+__ADDRESSABLE(cpu_arm925_proc_init);
+void cpu_arm925_proc_fin(void);
+__ADDRESSABLE(cpu_arm925_proc_fin);
+void cpu_arm925_reset(void);
+__ADDRESSABLE(cpu_arm925_reset);
+int cpu_arm925_do_idle(void);
+__ADDRESSABLE(cpu_arm925_do_idle);
+void cpu_arm925_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm925_dcache_clean_area);
+void cpu_arm925_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm925_switch_mm);
+void cpu_arm925_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm925_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM926T
+void cpu_arm926_proc_init(void);
+__ADDRESSABLE(cpu_arm926_proc_init);
+void cpu_arm926_proc_fin(void);
+__ADDRESSABLE(cpu_arm926_proc_fin);
+void cpu_arm926_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_arm926_reset);
+int cpu_arm926_do_idle(void);
+__ADDRESSABLE(cpu_arm926_do_idle);
+void cpu_arm926_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm926_dcache_clean_area);
+void cpu_arm926_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm926_switch_mm);
+void cpu_arm926_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm926_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_arm926_do_suspend(void *);
+__ADDRESSABLE(cpu_arm926_do_suspend);
+void cpu_arm926_do_resume(void *);
+__ADDRESSABLE(cpu_arm926_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_ARM926T */
+
+#ifdef CONFIG_CPU_ARM940T
+void cpu_arm940_proc_init(void);
+__ADDRESSABLE(cpu_arm940_proc_init);
+void cpu_arm940_proc_fin(void);
+__ADDRESSABLE(cpu_arm940_proc_fin);
+void cpu_arm940_reset(void);
+__ADDRESSABLE(cpu_arm940_reset);
+int cpu_arm940_do_idle(void);
+__ADDRESSABLE(cpu_arm940_do_idle);
+void cpu_arm940_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm940_dcache_clean_area);
+void cpu_arm940_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm940_switch_mm);
+#endif
+
+#ifdef CONFIG_CPU_ARM946E
+void cpu_arm946_proc_init(void);
+__ADDRESSABLE(cpu_arm946_proc_init);
+void cpu_arm946_proc_fin(void);
+__ADDRESSABLE(cpu_arm946_proc_fin);
+void cpu_arm946_reset(void);
+__ADDRESSABLE(cpu_arm946_reset);
+int cpu_arm946_do_idle(void);
+__ADDRESSABLE(cpu_arm946_do_idle);
+void cpu_arm946_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm946_dcache_clean_area);
+void cpu_arm946_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm946_switch_mm);
+#endif
+
+#ifdef CONFIG_CPU_FA526
+void cpu_fa526_proc_init(void);
+__ADDRESSABLE(cpu_fa526_proc_init);
+void cpu_fa526_proc_fin(void);
+__ADDRESSABLE(cpu_fa526_proc_fin);
+void cpu_fa526_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_fa526_reset);
+int cpu_fa526_do_idle(void);
+__ADDRESSABLE(cpu_fa526_do_idle);
+void cpu_fa526_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_fa526_dcache_clean_area);
+void cpu_fa526_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_fa526_switch_mm);
+void cpu_fa526_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_fa526_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM1020
+void cpu_arm1020_proc_init(void);
+__ADDRESSABLE(cpu_arm1020_proc_init);
+void cpu_arm1020_proc_fin(void);
+__ADDRESSABLE(cpu_arm1020_proc_fin);
+void cpu_arm1020_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_arm1020_reset);
+int cpu_arm1020_do_idle(void);
+__ADDRESSABLE(cpu_arm1020_do_idle);
+void cpu_arm1020_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm1020_dcache_clean_area);
+void cpu_arm1020_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm1020_switch_mm);
+void cpu_arm1020_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm1020_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM1020E
+void cpu_arm1020e_proc_init(void);
+__ADDRESSABLE(cpu_arm1020e_proc_init);
+void cpu_arm1020e_proc_fin(void);
+__ADDRESSABLE(cpu_arm1020e_proc_fin);
+void cpu_arm1020e_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_arm1020e_reset);
+int cpu_arm1020e_do_idle(void);
+__ADDRESSABLE(cpu_arm1020e_do_idle);
+void cpu_arm1020e_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm1020e_dcache_clean_area);
+void cpu_arm1020e_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm1020e_switch_mm);
+void cpu_arm1020e_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm1020e_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM1022
+void cpu_arm1022_proc_init(void);
+__ADDRESSABLE(cpu_arm1022_proc_init);
+void cpu_arm1022_proc_fin(void);
+__ADDRESSABLE(cpu_arm1022_proc_fin);
+void cpu_arm1022_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_arm1022_reset);
+int cpu_arm1022_do_idle(void);
+__ADDRESSABLE(cpu_arm1022_do_idle);
+void cpu_arm1022_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm1022_dcache_clean_area);
+void cpu_arm1022_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm1022_switch_mm);
+void cpu_arm1022_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm1022_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_ARM1026
+void cpu_arm1026_proc_init(void);
+__ADDRESSABLE(cpu_arm1026_proc_init);
+void cpu_arm1026_proc_fin(void);
+__ADDRESSABLE(cpu_arm1026_proc_fin);
+void cpu_arm1026_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_arm1026_reset);
+int cpu_arm1026_do_idle(void);
+__ADDRESSABLE(cpu_arm1026_do_idle);
+void cpu_arm1026_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_arm1026_dcache_clean_area);
+void cpu_arm1026_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_arm1026_switch_mm);
+void cpu_arm1026_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_arm1026_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_SA110
+void cpu_sa110_proc_init(void);
+__ADDRESSABLE(cpu_sa110_proc_init);
+void cpu_sa110_proc_fin(void);
+__ADDRESSABLE(cpu_sa110_proc_fin);
+void cpu_sa110_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_sa110_reset);
+int cpu_sa110_do_idle(void);
+__ADDRESSABLE(cpu_sa110_do_idle);
+void cpu_sa110_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_sa110_dcache_clean_area);
+void cpu_sa110_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_sa110_switch_mm);
+void cpu_sa110_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_sa110_set_pte_ext);
+#endif
+
+#ifdef CONFIG_CPU_SA1100
+void cpu_sa1100_proc_init(void);
+__ADDRESSABLE(cpu_sa1100_proc_init);
+void cpu_sa1100_proc_fin(void);
+__ADDRESSABLE(cpu_sa1100_proc_fin);
+void cpu_sa1100_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_sa1100_reset);
+int cpu_sa1100_do_idle(void);
+__ADDRESSABLE(cpu_sa1100_do_idle);
+void cpu_sa1100_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_sa1100_dcache_clean_area);
+void cpu_sa1100_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_sa1100_switch_mm);
+void cpu_sa1100_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_sa1100_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_sa1100_do_suspend(void *);
+__ADDRESSABLE(cpu_sa1100_do_suspend);
+void cpu_sa1100_do_resume(void *);
+__ADDRESSABLE(cpu_sa1100_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_SA1100 */
+
+#ifdef CONFIG_CPU_XSCALE
+void cpu_xscale_proc_init(void);
+__ADDRESSABLE(cpu_xscale_proc_init);
+void cpu_xscale_proc_fin(void);
+__ADDRESSABLE(cpu_xscale_proc_fin);
+void cpu_xscale_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_xscale_reset);
+int cpu_xscale_do_idle(void);
+__ADDRESSABLE(cpu_xscale_do_idle);
+void cpu_xscale_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_xscale_dcache_clean_area);
+void cpu_xscale_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_xscale_switch_mm);
+void cpu_xscale_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_xscale_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_xscale_do_suspend(void *);
+__ADDRESSABLE(cpu_xscale_do_suspend);
+void cpu_xscale_do_resume(void *);
+__ADDRESSABLE(cpu_xscale_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_XSCALE */
+
+#ifdef CONFIG_CPU_XSC3
+void cpu_xsc3_proc_init(void);
+__ADDRESSABLE(cpu_xsc3_proc_init);
+void cpu_xsc3_proc_fin(void);
+__ADDRESSABLE(cpu_xsc3_proc_fin);
+void cpu_xsc3_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_xsc3_reset);
+int cpu_xsc3_do_idle(void);
+__ADDRESSABLE(cpu_xsc3_do_idle);
+void cpu_xsc3_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_xsc3_dcache_clean_area);
+void cpu_xsc3_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_xsc3_switch_mm);
+void cpu_xsc3_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_xsc3_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_xsc3_do_suspend(void *);
+__ADDRESSABLE(cpu_xsc3_do_suspend);
+void cpu_xsc3_do_resume(void *);
+__ADDRESSABLE(cpu_xsc3_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_XSC3 */
+
+#ifdef CONFIG_CPU_MOHAWK
+void cpu_mohawk_proc_init(void);
+__ADDRESSABLE(cpu_mohawk_proc_init);
+void cpu_mohawk_proc_fin(void);
+__ADDRESSABLE(cpu_mohawk_proc_fin);
+void cpu_mohawk_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_mohawk_reset);
+int cpu_mohawk_do_idle(void);
+__ADDRESSABLE(cpu_mohawk_do_idle);
+void cpu_mohawk_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_mohawk_dcache_clean_area);
+void cpu_mohawk_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_mohawk_switch_mm);
+void cpu_mohawk_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_mohawk_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_mohawk_do_suspend(void *);
+__ADDRESSABLE(cpu_mohawk_do_suspend);
+void cpu_mohawk_do_resume(void *);
+__ADDRESSABLE(cpu_mohawk_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_MOHAWK */
+
+#ifdef CONFIG_CPU_FEROCEON
+void cpu_feroceon_proc_init(void);
+__ADDRESSABLE(cpu_feroceon_proc_init);
+void cpu_feroceon_proc_fin(void);
+__ADDRESSABLE(cpu_feroceon_proc_fin);
+void cpu_feroceon_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_feroceon_reset);
+int cpu_feroceon_do_idle(void);
+__ADDRESSABLE(cpu_feroceon_do_idle);
+void cpu_feroceon_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_feroceon_dcache_clean_area);
+void cpu_feroceon_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_feroceon_switch_mm);
+void cpu_feroceon_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_feroceon_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_feroceon_do_suspend(void *);
+__ADDRESSABLE(cpu_feroceon_do_suspend);
+void cpu_feroceon_do_resume(void *);
+__ADDRESSABLE(cpu_feroceon_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_FEROCEON */
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+void cpu_v6_proc_init(void);
+__ADDRESSABLE(cpu_v6_proc_init);
+void cpu_v6_proc_fin(void);
+__ADDRESSABLE(cpu_v6_proc_fin);
+void cpu_v6_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_v6_reset);
+int cpu_v6_do_idle(void);
+__ADDRESSABLE(cpu_v6_do_idle);
+void cpu_v6_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_v6_dcache_clean_area);
+void cpu_v6_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_v6_switch_mm);
+void cpu_v6_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_v6_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_v6_do_suspend(void *);
+__ADDRESSABLE(cpu_v6_do_suspend);
+void cpu_v6_do_resume(void *);
+__ADDRESSABLE(cpu_v6_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CPU_V6 */
+
+#ifdef CONFIG_CPU_V7
+void cpu_v7_proc_init(void);
+__ADDRESSABLE(cpu_v7_proc_init);
+void cpu_v7_proc_fin(void);
+__ADDRESSABLE(cpu_v7_proc_fin);
+void cpu_v7_reset(void);
+__ADDRESSABLE(cpu_v7_reset);
+int cpu_v7_do_idle(void);
+__ADDRESSABLE(cpu_v7_do_idle);
+#ifdef CONFIG_PJ4B_ERRATA_4742
+int cpu_pj4b_do_idle(void);
+__ADDRESSABLE(cpu_pj4b_do_idle);
+#endif
+void cpu_v7_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_v7_dcache_clean_area);
+void cpu_v7_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+/* Special switch_mm() callbacks to work around bugs in v7 */
+__ADDRESSABLE(cpu_v7_switch_mm);
+void cpu_v7_iciallu_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_v7_iciallu_switch_mm);
+void cpu_v7_bpiall_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_v7_bpiall_switch_mm);
+#ifdef CONFIG_ARM_LPAE
+void cpu_v7_set_pte_ext(pte_t *ptep, pte_t pte);
+#else
+void cpu_v7_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+#endif
+__ADDRESSABLE(cpu_v7_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_v7_do_suspend(void *);
+__ADDRESSABLE(cpu_v7_do_suspend);
+void cpu_v7_do_resume(void *);
+__ADDRESSABLE(cpu_v7_do_resume);
+/* Special versions of suspend and resume for the CA9MP cores */
+void cpu_ca9mp_do_suspend(void *);
+__ADDRESSABLE(cpu_ca9mp_do_suspend);
+void cpu_ca9mp_do_resume(void *);
+__ADDRESSABLE(cpu_ca9mp_do_resume);
+/* Special versions of suspend and resume for the Marvell PJ4B cores */
+#ifdef CONFIG_CPU_PJ4B
+void cpu_pj4b_do_suspend(void *);
+__ADDRESSABLE(cpu_pj4b_do_suspend);
+void cpu_pj4b_do_resume(void *);
+__ADDRESSABLE(cpu_pj4b_do_resume);
+#endif /* CONFIG_CPU_PJ4B */
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+#endif /* CONFIG_CPU_V7 */
+
+#ifdef CONFIG_CPU_V7M
+void cpu_v7m_proc_init(void);
+__ADDRESSABLE(cpu_v7m_proc_init);
+void cpu_v7m_proc_fin(void);
+__ADDRESSABLE(cpu_v7m_proc_fin);
+void cpu_v7m_reset(unsigned long addr, bool hvc);
+__ADDRESSABLE(cpu_v7m_reset);
+int cpu_v7m_do_idle(void);
+__ADDRESSABLE(cpu_v7m_do_idle);
+void cpu_v7m_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_v7m_dcache_clean_area);
+void cpu_v7m_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
+__ADDRESSABLE(cpu_v7m_switch_mm);
+void cpu_v7m_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+__ADDRESSABLE(cpu_v7m_set_pte_ext);
+#ifdef CONFIG_ARM_CPU_SUSPEND
+void cpu_v7m_do_suspend(void *);
+__ADDRESSABLE(cpu_v7m_do_suspend);
+void cpu_v7m_do_resume(void *);
+__ADDRESSABLE(cpu_v7m_do_resume);
+#endif /* CONFIG_ARM_CPU_SUSPEND */
+void cpu_cm7_proc_fin(void);
+__ADDRESSABLE(cpu_cm7_proc_fin);
+void cpu_cm7_dcache_clean_area(void *addr, int size);
+__ADDRESSABLE(cpu_cm7_dcache_clean_area);
+#endif /* CONFIG_CPU_V7M */
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S
index def6161ec452..85a6fe766b21 100644
--- a/arch/arm/mm/tlb-fa.S
+++ b/arch/arm/mm/tlb-fa.S
@@ -15,6 +15,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -31,7 +32,7 @@
* - mm - mm_struct describing address space
*/
.align 4
-ENTRY(fa_flush_user_tlb_range)
+SYM_TYPED_FUNC_START(fa_flush_user_tlb_range)
vma_vm_mm ip, r2
act_mm r3 @ get current->active_mm
eors r3, ip, r3 @ == mm ?
@@ -46,9 +47,10 @@ ENTRY(fa_flush_user_tlb_range)
blo 1b
mcr p15, 0, r3, c7, c10, 4 @ data write barrier
ret lr
+SYM_FUNC_END(fa_flush_user_tlb_range)
-ENTRY(fa_flush_kern_tlb_range)
+SYM_TYPED_FUNC_START(fa_flush_kern_tlb_range)
mov r3, #0
mcr p15, 0, r3, c7, c10, 4 @ drain WB
bic r0, r0, #0x0ff
@@ -60,8 +62,4 @@ ENTRY(fa_flush_kern_tlb_range)
mcr p15, 0, r3, c7, c10, 4 @ data write barrier
mcr p15, 0, r3, c7, c5, 4 @ prefetch flush (isb)
ret lr
-
- __INITDATA
-
- /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
- define_tlb_functions fa, fa_tlb_flags
+SYM_FUNC_END(fa_flush_kern_tlb_range)
diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
index b962b4e75158..09ff69008d94 100644
--- a/arch/arm/mm/tlb-v4.S
+++ b/arch/arm/mm/tlb-v4.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -27,7 +28,7 @@
* - mm - mm_struct describing address space
*/
.align 5
-ENTRY(v4_flush_user_tlb_range)
+SYM_TYPED_FUNC_START(v4_flush_user_tlb_range)
vma_vm_mm ip, r2
act_mm r3 @ get current->active_mm
eors r3, ip, r3 @ == mm ?
@@ -40,6 +41,7 @@ ENTRY(v4_flush_user_tlb_range)
cmp r0, r1
blo 1b
ret lr
+SYM_FUNC_END(v4_flush_user_tlb_range)
/*
* v4_flush_kern_tlb_range(start, end)
@@ -50,10 +52,11 @@ ENTRY(v4_flush_user_tlb_range)
* - start - virtual address (may not be aligned)
* - end - virtual address (may not be aligned)
*/
+#ifdef CONFIG_CFI_CLANG
+SYM_TYPED_FUNC_START(v4_flush_kern_tlb_range)
+ b .v4_flush_kern_tlb_range
+SYM_FUNC_END(v4_flush_kern_tlb_range)
+#else
.globl v4_flush_kern_tlb_range
.equ v4_flush_kern_tlb_range, .v4_flush_kern_tlb_range
-
- __INITDATA
-
- /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
- define_tlb_functions v4, v4_tlb_flags
+#endif
diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
index 9348bba7586a..04e46c359e75 100644
--- a/arch/arm/mm/tlb-v4wb.S
+++ b/arch/arm/mm/tlb-v4wb.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -27,7 +28,7 @@
* - mm - mm_struct describing address space
*/
.align 5
-ENTRY(v4wb_flush_user_tlb_range)
+SYM_TYPED_FUNC_START(v4wb_flush_user_tlb_range)
vma_vm_mm ip, r2
act_mm r3 @ get current->active_mm
eors r3, ip, r3 @ == mm ?
@@ -43,6 +44,7 @@ ENTRY(v4wb_flush_user_tlb_range)
cmp r0, r1
blo 1b
ret lr
+SYM_FUNC_END(v4wb_flush_user_tlb_range)
/*
* v4_flush_kern_tlb_range(start, end)
@@ -53,7 +55,7 @@ ENTRY(v4wb_flush_user_tlb_range)
* - start - virtual address (may not be aligned)
* - end - virtual address (may not be aligned)
*/
-ENTRY(v4wb_flush_kern_tlb_range)
+SYM_TYPED_FUNC_START(v4wb_flush_kern_tlb_range)
mov r3, #0
mcr p15, 0, r3, c7, c10, 4 @ drain WB
bic r0, r0, #0x0ff
@@ -64,8 +66,4 @@ ENTRY(v4wb_flush_kern_tlb_range)
cmp r0, r1
blo 1b
ret lr
-
- __INITDATA
-
- /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
- define_tlb_functions v4wb, v4wb_tlb_flags
+SYM_FUNC_END(v4wb_flush_kern_tlb_range)
diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S
index d4f9040a4111..502dfe5628a3 100644
--- a/arch/arm/mm/tlb-v4wbi.S
+++ b/arch/arm/mm/tlb-v4wbi.S
@@ -11,6 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -26,7 +27,7 @@
* - mm - mm_struct describing address space
*/
.align 5
-ENTRY(v4wbi_flush_user_tlb_range)
+SYM_TYPED_FUNC_START(v4wbi_flush_user_tlb_range)
vma_vm_mm ip, r2
act_mm r3 @ get current->active_mm
eors r3, ip, r3 @ == mm ?
@@ -43,8 +44,9 @@ ENTRY(v4wbi_flush_user_tlb_range)
cmp r0, r1
blo 1b
ret lr
+SYM_FUNC_END(v4wbi_flush_user_tlb_range)
-ENTRY(v4wbi_flush_kern_tlb_range)
+SYM_TYPED_FUNC_START(v4wbi_flush_kern_tlb_range)
mov r3, #0
mcr p15, 0, r3, c7, c10, 4 @ drain WB
bic r0, r0, #0x0ff
@@ -55,8 +57,4 @@ ENTRY(v4wbi_flush_kern_tlb_range)
cmp r0, r1
blo 1b
ret lr
-
- __INITDATA
-
- /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
- define_tlb_functions v4wbi, v4wbi_tlb_flags
+SYM_FUNC_END(v4wbi_flush_kern_tlb_range)
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
index 1d91e49b2c2d..8256a67ac654 100644
--- a/arch/arm/mm/tlb-v6.S
+++ b/arch/arm/mm/tlb-v6.S
@@ -9,6 +9,7 @@
*/
#include <linux/init.h>
#include <linux/linkage.h>
+#include <linux/cfi_types.h>
#include <asm/asm-offsets.h>
#include <asm/assembler.h>
#include <asm/page.h>
@@ -32,7 +33,7 @@
* - the "Invalidate single entry" instruction will invalidate
* both the I and the D TLBs on Harvard-style TLBs
*/
-ENTRY(v6wbi_flush_user_tlb_range)
+SYM_TYPED_FUNC_START(v6wbi_flush_user_tlb_range)
vma_vm_mm r3, r2 @ get vma->vm_mm
mov ip, #0
mmid r3, r3 @ get vm_mm->context.id
@@ -56,6 +57,7 @@ ENTRY(v6wbi_flush_user_tlb_range)
blo 1b
mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier
ret lr
+SYM_FUNC_END(v6wbi_flush_user_tlb_range)
/*
* v6wbi_flush_kern_tlb_range(start,end)
@@ -65,7 +67,7 @@ ENTRY(v6wbi_flush_user_tlb_range)
* - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned)
*/
-ENTRY(v6wbi_flush_kern_tlb_range)
+SYM_TYPED_FUNC_START(v6wbi_flush_kern_tlb_range)
mov r2, #0
mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
mov r0, r0, lsr #PAGE_SHIFT @ align address
@@ -85,8 +87,4 @@ ENTRY(v6wbi_flush_kern_tlb_range)
mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier
mcr p15, 0, r2, c7, c5, 4 @ prefetch flush (isb)
ret lr
-
- __INIT
-
- /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
- define_tlb_functions v6wbi, v6wbi_tlb_flags
+SYM_FUNC_END(v6wbi_flush_kern_tlb_range)
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index 35fd6d4f0d03..f1aa0764a2cc 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -10,6 +10,7 @@
*/
#include <linux/init.h>
#include <linux/linkage.h>
+#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
@@ -31,7 +32,7 @@
* - the "Invalidate single entry" instruction will invalidate
* both the I and the D TLBs on Harvard-style TLBs
*/
-ENTRY(v7wbi_flush_user_tlb_range)
+SYM_TYPED_FUNC_START(v7wbi_flush_user_tlb_range)
vma_vm_mm r3, r2 @ get vma->vm_mm
mmid r3, r3 @ get vm_mm->context.id
dsb ish
@@ -57,7 +58,7 @@ ENTRY(v7wbi_flush_user_tlb_range)
blo 1b
dsb ish
ret lr
-ENDPROC(v7wbi_flush_user_tlb_range)
+SYM_FUNC_END(v7wbi_flush_user_tlb_range)
/*
* v7wbi_flush_kern_tlb_range(start,end)
@@ -67,7 +68,7 @@ ENDPROC(v7wbi_flush_user_tlb_range)
* - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned)
*/
-ENTRY(v7wbi_flush_kern_tlb_range)
+SYM_TYPED_FUNC_START(v7wbi_flush_kern_tlb_range)
dsb ish
mov r0, r0, lsr #PAGE_SHIFT @ align address
mov r1, r1, lsr #PAGE_SHIFT
@@ -86,9 +87,4 @@ ENTRY(v7wbi_flush_kern_tlb_range)
dsb ish
isb
ret lr
-ENDPROC(v7wbi_flush_kern_tlb_range)
-
- __INIT
-
- /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
- define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp
+SYM_FUNC_END(v7wbi_flush_kern_tlb_range)
diff --git a/arch/arm/mm/tlb.c b/arch/arm/mm/tlb.c
new file mode 100644
index 000000000000..42359793120b
--- /dev/null
+++ b/arch/arm/mm/tlb.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2024 Google LLC
+// Author: Ard Biesheuvel <ardb@google.com>
+
+#include <linux/types.h>
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_CPU_TLB_V4WT
+void v4_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+void v4_flush_kern_tlb_range(unsigned long, unsigned long);
+
+struct cpu_tlb_fns v4_tlb_fns __initconst = {
+ .flush_user_range = v4_flush_user_tlb_range,
+ .flush_kern_range = v4_flush_kern_tlb_range,
+ .tlb_flags = v4_tlb_flags,
+};
+#endif
+
+#ifdef CONFIG_CPU_TLB_V4WB
+void v4wb_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+void v4wb_flush_kern_tlb_range(unsigned long, unsigned long);
+
+struct cpu_tlb_fns v4wb_tlb_fns __initconst = {
+ .flush_user_range = v4wb_flush_user_tlb_range,
+ .flush_kern_range = v4wb_flush_kern_tlb_range,
+ .tlb_flags = v4wb_tlb_flags,
+};
+#endif
+
+#if defined(CONFIG_CPU_TLB_V4WBI) || defined(CONFIG_CPU_TLB_FEROCEON)
+void v4wbi_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+void v4wbi_flush_kern_tlb_range(unsigned long, unsigned long);
+
+struct cpu_tlb_fns v4wbi_tlb_fns __initconst = {
+ .flush_user_range = v4wbi_flush_user_tlb_range,
+ .flush_kern_range = v4wbi_flush_kern_tlb_range,
+ .tlb_flags = v4wbi_tlb_flags,
+};
+#endif
+
+#ifdef CONFIG_CPU_TLB_V6
+void v6wbi_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+void v6wbi_flush_kern_tlb_range(unsigned long, unsigned long);
+
+struct cpu_tlb_fns v6wbi_tlb_fns __initconst = {
+ .flush_user_range = v6wbi_flush_user_tlb_range,
+ .flush_kern_range = v6wbi_flush_kern_tlb_range,
+ .tlb_flags = v6wbi_tlb_flags,
+};
+#endif
+
+#ifdef CONFIG_CPU_TLB_V7
+void v7wbi_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+void v7wbi_flush_kern_tlb_range(unsigned long, unsigned long);
+
+struct cpu_tlb_fns v7wbi_tlb_fns __initconst = {
+ .flush_user_range = v7wbi_flush_user_tlb_range,
+ .flush_kern_range = v7wbi_flush_kern_tlb_range,
+ .tlb_flags = IS_ENABLED(CONFIG_SMP) ? v7wbi_tlb_flags_smp
+ : v7wbi_tlb_flags_up,
+};
+
+#ifdef CONFIG_SMP_ON_UP
+/* This will be run-time patched so the offset better be right */
+static_assert(offsetof(struct cpu_tlb_fns, tlb_flags) == 8);
+
+asm(" .pushsection \".alt.smp.init\", \"a\" \n" \
+ " .align 2 \n" \
+ " .long v7wbi_tlb_fns + 8 - . \n" \
+ " .long " __stringify(v7wbi_tlb_flags_up) " \n" \
+ " .popsection \n");
+#endif
+#endif
+
+#ifdef CONFIG_CPU_TLB_FA
+void fa_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+void fa_flush_kern_tlb_range(unsigned long, unsigned long);
+
+struct cpu_tlb_fns fa_tlb_fns __initconst = {
+ .flush_user_range = fa_flush_user_tlb_range,
+ .flush_kern_range = fa_flush_kern_tlb_range,
+ .tlb_flags = fa_tlb_flags,
+};
+#endif
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index 72b5cd697f5d..deeb8f292454 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -2252,28 +2252,21 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
/* If building the body of the JITed code fails somehow,
* we fall back to the interpretation.
*/
- if (build_body(&ctx) < 0) {
- image_ptr = NULL;
- bpf_jit_binary_free(header);
- prog = orig_prog;
- goto out_imms;
- }
+ if (build_body(&ctx) < 0)
+ goto out_free;
build_epilogue(&ctx);
/* 3.) Extra pass to validate JITed Code */
- if (validate_code(&ctx)) {
- image_ptr = NULL;
- bpf_jit_binary_free(header);
- prog = orig_prog;
- goto out_imms;
- }
+ if (validate_code(&ctx))
+ goto out_free;
flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx));
if (bpf_jit_enable > 1)
/* there are 2 passes here */
bpf_jit_dump(prog->len, image_size, 2, ctx.target);
- bpf_jit_binary_lock_ro(header);
+ if (bpf_jit_binary_lock_ro(header))
+ goto out_free;
prog->bpf_func = (void *)ctx.target;
prog->jited = 1;
prog->jited_len = image_size;
@@ -2290,5 +2283,11 @@ out:
bpf_jit_prog_release_other(prog, prog == orig_prog ?
tmp : orig_prog);
return prog;
+
+out_free:
+ image_ptr = NULL;
+ bpf_jit_binary_free(header);
+ prog = orig_prog;
+ goto out_imms;
}
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
index 830b0be038c6..e8c7580df8ca 100644
--- a/arch/arm/plat-orion/Makefile
+++ b/arch/arm/plat-orion/Makefile
@@ -2,7 +2,7 @@
#
# Makefile for the linux kernel.
#
-ccflags-y := -I$(srctree)/$(src)/include
+ccflags-y := -I$(src)/include
orion-gpio-$(CONFIG_GPIOLIB) += gpio.o
obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index 81f13bdf32f2..28b6da8ac5f6 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -9,7 +9,7 @@ gen := arch/$(ARCH)/include/generated
kapi := $(gen)/asm
uapi := $(gen)/uapi/asm
syshdr := $(srctree)/scripts/syscallhdr.sh
-sysnr := $(srctree)/$(src)/syscallnr.sh
+sysnr := $(src)/syscallnr.sh
systbl := $(srctree)/scripts/syscalltbl.sh
syscall := $(src)/syscall.tbl
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index b6c9e01e14f5..23c98203c40f 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# Linux system call numbers and entry vectors
#
@@ -475,3 +476,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
index d761bd2e2f40..01067a2bc43b 100644
--- a/arch/arm/vdso/Makefile
+++ b/arch/arm/vdso/Makefile
@@ -33,15 +33,6 @@ else
CFLAGS_vgettimeofday.o = -O2 -include $(c-gettimeofday-y)
endif
-# Disable gcov profiling for VDSO code
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-
-KASAN_SANITIZE := n
-
# Force dependency
$(obj)/vdso.o : $(obj)/vdso.so
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
index 309648c17f48..9da57a5b81c7 100644
--- a/arch/arm/xen/p2m.c
+++ b/arch/arm/xen/p2m.c
@@ -109,7 +109,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
* immediate unmapping.
*/
map_ops[i].status = GNTST_general_error;
- unmap.host_addr = map_ops[i].host_addr,
+ unmap.host_addr = map_ops[i].host_addr;
unmap.handle = map_ops[i].handle;
map_ops[i].handle = INVALID_GRANT_HANDLE;
if (map_ops[i].flags & GNTMAP_device_map)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7b11c98b3e84..ae527d1d409f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -5,6 +5,7 @@ config ARM64
select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI
select ACPI_GTDT if ACPI
+ select ACPI_HOTPLUG_CPU if ACPI_PROCESSOR && HOTPLUG_CPU
select ACPI_IORT if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ACPI_MCFG if (ACPI && PCI)
@@ -30,6 +31,7 @@ config ARM64
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
+ select ARCH_HAS_KERNEL_FPU_SUPPORT if KERNEL_MODE_NEON
select ARCH_HAS_KEEPINITRD
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
@@ -46,7 +48,6 @@ config ARM64
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYSCALL_WRAPPER
- select ARCH_HAS_TEARDOWN_DMA_OPS if IOMMU_SUPPORT
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_ZONE_DMA_SET if EXPERT
select ARCH_HAVE_ELF_PROT
@@ -105,6 +106,7 @@ config ARM64
select ARCH_WANT_FRAME_POINTERS
select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
select ARCH_WANT_LD_ORPHAN_WARN
+ select ARCH_WANTS_EXECMEM_LATE if EXECMEM
select ARCH_WANTS_NO_INSTR
select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
select ARCH_HAS_UBSAN
@@ -166,9 +168,9 @@ config ARM64
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN
- select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
- select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN
- select HAVE_ARCH_KASAN_HW_TAGS if (HAVE_ARCH_KASAN && ARM64_MTE)
+ select HAVE_ARCH_KASAN_VMALLOC
+ select HAVE_ARCH_KASAN_SW_TAGS
+ select HAVE_ARCH_KASAN_HW_TAGS if ARM64_MTE
# Some instrumentation may be unsound, hence EXPERT
select HAVE_ARCH_KCSAN if EXPERT
select HAVE_ARCH_KFENCE
@@ -205,12 +207,12 @@ config ARM64
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_EFFICIENT_UNALIGNED_ACCESS
- select HAVE_FAST_GUP
+ select HAVE_GUP_FAST
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_ERROR_INJECTION
- select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_FUNCTION_GRAPH_RETVAL
select HAVE_GCC_PLUGINS
select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && \
HW_PERF_EVENTS && HAVE_PERF_EVENTS_NMI
@@ -255,9 +257,11 @@ config ARM64
select SYSCTL_EXCEPTION_TRACE
select THREAD_INFO_IN_TASK
select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
+ select HAVE_ARCH_USERFAULTFD_WP if USERFAULTFD
select TRACE_IRQFLAGS_SUPPORT
select TRACE_IRQFLAGS_NMI_SUPPORT
select HAVE_SOFTIRQ_ON_OWN_STACK
+ select USER_STACKTRACE_SUPPORT
help
ARM 64-bit (AArch64) Linux support.
@@ -378,7 +382,7 @@ config BROKEN_GAS_INST
config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
bool
- # Clang's __builtin_return_adddress() strips the PAC since 12.0.0
+ # Clang's __builtin_return_address() strips the PAC since 12.0.0
# https://github.com/llvm/llvm-project/commit/2a96f47c5ffca84cd774ad402cacd137f4bf45e2
default y if CC_IS_CLANG
# GCC's __builtin_return_address() strips the PAC since 11.1.0,
@@ -1064,6 +1068,34 @@ config ARM64_ERRATUM_3117295
If unsure, say Y.
+config ARM64_ERRATUM_3194386
+ bool "Cortex-{A720,X4,X925}/Neoverse-V3: workaround for MSR SSBS not self-synchronizing"
+ default y
+ help
+ This option adds the workaround for the following errata:
+
+ * ARM Cortex-A710 erratam 3324338
+ * ARM Cortex-A720 erratum 3456091
+ * ARM Cortex-X2 erratum 3324338
+ * ARM Cortex-X3 erratum 3324335
+ * ARM Cortex-X4 erratum 3194386
+ * ARM Cortex-X925 erratum 3324334
+ * ARM Neoverse N2 erratum 3324339
+ * ARM Neoverse V2 erratum 3324336
+ * ARM Neoverse-V3 erratum 3312417
+
+ On affected cores "MSR SSBS, #0" instructions may not affect
+ subsequent speculative instructions, which may permit unexepected
+ speculative store bypassing.
+
+ Work around this problem by placing a speculation barrier after
+ kernel changes to SSBS. The presence of the SSBS special-purpose
+ register is hidden from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such
+ that userspace will use the PR_SPEC_STORE_BYPASS prctl to change
+ SSBS.
+
+ If unsure, say Y.
+
config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313"
default y
@@ -1604,6 +1636,7 @@ config RODATA_FULL_DEFAULT_ENABLED
config ARM64_SW_TTBR0_PAN
bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
+ depends on !KCSAN
help
Enabling this option prevents the kernel from accessing
user-space memory directly by pointing TTBR0_EL1 to a reserved
@@ -2257,7 +2290,8 @@ config CMDLINE
root device (e.g. root=/dev/nfs).
choice
- prompt "Kernel command line type" if CMDLINE != ""
+ prompt "Kernel command line type"
+ depends on CMDLINE != ""
default CMDLINE_FROM_BOOTLOADER
help
Choose how the kernel will handle the provided default kernel
@@ -2303,6 +2337,17 @@ config EFI
allow the kernel to be booted as an EFI application. This
is only useful on systems that have UEFI firmware.
+config COMPRESSED_INSTALL
+ bool "Install compressed image by default"
+ help
+ This makes the regular "make install" install the compressed
+ image we built, not the legacy uncompressed one.
+
+ You can check that a compressed image works for you by doing
+ "make zinstall" first, and verifying that everything is fine
+ in your environment before making "make install" do this for
+ you.
+
config DMI
bool "Enable support for SMBIOS (DMI) tables"
depends on EFI
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 24335565bad5..6c6d11536b42 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -8,6 +8,13 @@ config ARCH_ACTIONS
help
This enables support for the Actions Semiconductor S900 SoC family.
+config ARCH_AIROHA
+ bool "Airoha SoC Support"
+ select ARM_PSCI
+ select HAVE_ARM_ARCH_TIMER
+ help
+ This enables support for the ARM64 based Airoha SoCs.
+
config ARCH_SUNXI
bool "Allwinner sunxi 64-bit SoC Family"
select ARCH_HAS_RESET_CONTROLLER
@@ -200,7 +207,6 @@ if ARCH_NXP
config ARCH_LAYERSCAPE
bool "Freescale Layerscape SoC family"
- select EDAC_SUPPORT
help
This enables support for the Freescale Layerscape SoC family.
@@ -260,6 +266,7 @@ config ARCH_QCOM
bool "Qualcomm Platforms"
select GPIOLIB
select PINCTRL
+ select HAVE_PWRCTL if PCI
help
This enables support for the ARMv8 based Qualcomm chipsets.
@@ -304,7 +311,10 @@ config ARCH_STM32
select PINCTRL_STM32MP257
select ARM_SMC_MBOX
select ARM_SCMI_PROTOCOL
+ select REGULATOR
+ select REGULATOR_ARM_SCMI
select COMMON_CLK_SCMI
+ select STM32_FIREWALL
help
This enables support for ARMv8 based STMicroelectronics
STM32 family, including:
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 0e075d3c546b..f6bc3da1ef11 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -36,7 +36,14 @@ ifeq ($(CONFIG_BROKEN_GAS_INST),y)
$(warning Detected assembler with broken .inst; disassembly will be unreliable)
endif
-KBUILD_CFLAGS += -mgeneral-regs-only \
+# The GCC option -ffreestanding is required in order to compile code containing
+# ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel)
+CC_FLAGS_FPU := -ffreestanding
+# Enable <arm_neon.h>
+CC_FLAGS_FPU += -isystem $(shell $(CC) -print-file-name=include)
+CC_FLAGS_NO_FPU := -mgeneral-regs-only
+
+KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \
$(compat_vdso) $(cc_has_k_constraint)
KBUILD_CFLAGS += $(call cc-disable-warning, psabi)
KBUILD_AFLAGS += $(compat_vdso)
@@ -154,6 +161,10 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
# Default target when executing plain make
boot := arch/arm64/boot
+BOOT_TARGETS := Image vmlinuz.efi image.fit
+
+PHONY += $(BOOT_TARGETS)
+
ifeq ($(CONFIG_EFI_ZBOOT),)
KBUILD_IMAGE := $(boot)/Image.gz
else
@@ -162,14 +173,22 @@ endif
all: $(notdir $(KBUILD_IMAGE))
-vmlinuz.efi: Image
-Image vmlinuz.efi: vmlinux
+image.fit: dtbs
+
+vmlinuz.efi image.fit: Image
+$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
Image.%: Image
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
-install: KBUILD_IMAGE := $(boot)/Image
+ifeq ($(CONFIG_COMPRESSED_INSTALL),y)
+ DEFAULT_KBUILD_IMAGE = $(KBUILD_IMAGE)
+else
+ DEFAULT_KBUILD_IMAGE = $(boot)/Image
+endif
+
+install: KBUILD_IMAGE := $(DEFAULT_KBUILD_IMAGE)
install zinstall:
$(call cmd,install)
@@ -215,7 +234,8 @@ virtconfig:
define archhelp
echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
- echo ' install - Install uncompressed kernel'
+ echo ' image.fit - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
+ echo ' install - Install kernel (compressed if COMPRESSED_INSTALL set)'
echo ' zinstall - Install compressed kernel'
echo ' Install using (your) ~/bin/installkernel or'
echo ' (distribution) /sbin/installkernel or'
diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore
index af5dc61f8b43..abaae9de1bdd 100644
--- a/arch/arm64/boot/.gitignore
+++ b/arch/arm64/boot/.gitignore
@@ -2,3 +2,4 @@
Image
Image.gz
vmlinuz*
+image.fit
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index a5a787371117..607a67a649c4 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -16,7 +16,8 @@
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
-targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo Image.zst
+targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo \
+ Image.zst image.fit
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
@@ -39,6 +40,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE
$(obj)/Image.zst: $(obj)/Image FORCE
$(call if_changed,zstd)
+$(obj)/image.fit: $(obj)/Image $(obj)/dts/dtbs-list FORCE
+ $(call if_changed,fit)
+
EFI_ZBOOT_PAYLOAD := Image
EFI_ZBOOT_BFD_TARGET := elf64-littleaarch64
EFI_ZBOOT_MACH_TYPE := ARM64
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 30dd6347a929..21cd3a87f385 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
subdir-y += actions
+subdir-y += airoha
subdir-y += allwinner
subdir-y += altera
subdir-y += amazon
diff --git a/arch/arm64/boot/dts/actions/s700-cubieboard7.dts b/arch/arm64/boot/dts/actions/s700-cubieboard7.dts
index 63e375cd9eb4..bd54b5165129 100644
--- a/arch/arm64/boot/dts/actions/s700-cubieboard7.dts
+++ b/arch/arm64/boot/dts/actions/s700-cubieboard7.dts
@@ -24,7 +24,7 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
- memory@1,e0000000 {
+ memory@1e0000000 {
device_type = "memory";
reg = <0x1 0xe0000000 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/airoha/Makefile b/arch/arm64/boot/dts/airoha/Makefile
new file mode 100644
index 000000000000..ebea112ce1d7
--- /dev/null
+++ b/arch/arm64/boot/dts/airoha/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+dtb-$(CONFIG_ARCH_AIROHA) += en7581-evb.dtb
diff --git a/arch/arm64/boot/dts/airoha/en7581-evb.dts b/arch/arm64/boot/dts/airoha/en7581-evb.dts
new file mode 100644
index 000000000000..cf58e43dd5b2
--- /dev/null
+++ b/arch/arm64/boot/dts/airoha/en7581-evb.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+/* Bootloader installs ATF here */
+/memreserve/ 0x80000000 0x200000;
+
+#include "en7581.dtsi"
+
+/ {
+ model = "Airoha EN7581 Evaluation Board";
+ compatible = "airoha,en7581-evb", "airoha,en7581";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x2 0x00000000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi
new file mode 100644
index 000000000000..55eb1762fb11
--- /dev/null
+++ b/arch/arm64/boot/dts/airoha/en7581.dtsi
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ npu-binary@84000000 {
+ no-map;
+ reg = <0x0 0x84000000 0x0 0xa00000>;
+ };
+
+ npu-flag@84b0000 {
+ no-map;
+ reg = <0x0 0x84b00000 0x0 0x100000>;
+ };
+
+ npu-pkt@85000000 {
+ no-map;
+ reg = <0x0 0x85000000 0x0 0x1a00000>;
+ };
+
+ npu-phyaddr@86b00000 {
+ no-map;
+ reg = <0x0 0x86b00000 0x0 0x100000>;
+ };
+
+ npu-rxdesc@86d00000 {
+ no-map;
+ reg = <0x0 0x86d00000 0x0 0x100000>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+
+ core2 {
+ cpu = <&cpu2>;
+ };
+
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ enable-method = "psci";
+ clock-frequency = <80000000>;
+ next-level-cache = <&l2>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ enable-method = "psci";
+ clock-frequency = <80000000>;
+ next-level-cache = <&l2>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x2>;
+ enable-method = "psci";
+ clock-frequency = <80000000>;
+ next-level-cache = <&l2>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x3>;
+ enable-method = "psci";
+ clock-frequency = <80000000>;
+ next-level-cache = <&l2>;
+ };
+
+ l2: l2-cache {
+ compatible = "cache";
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-level = <2>;
+ cache-unified;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@9000000 {
+ compatible = "arm,gic-v3";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x09000000 0x0 0x20000>,
+ <0x0 0x09080000 0x0 0x80000>,
+ <0x0 0x09400000 0x0 0x2000>,
+ <0x0 0x09500000 0x0 0x2000>,
+ <0x0 0x09600000 0x0 0x20000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ uart1: serial@1fbf0000 {
+ compatible = "ns16550";
+ reg = <0x0 0x1fbf0000 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <1843200>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 21149b346a60..0db7b60b49a1 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -39,6 +39,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h313-tanix-tx1.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
@@ -47,3 +48,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero2w.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-2024.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-plus.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-h.dtb
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 e6d5bc0f7a61..d1f415acd7b5 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -53,7 +53,7 @@
};
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
index 0af6dcdf7515..dec9960a7440 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
@@ -41,7 +41,7 @@
};
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rtc CLK_OSC32K_FANOUT>;
clock-names = "ext_clock";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
index bfb806cf6d7a..fd3794678c33 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
@@ -52,7 +52,7 @@
status = "okay";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
};
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 4f8529d5ac00..c8303a66438d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
@@ -68,7 +68,7 @@
status = "okay";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 */
clocks = <&rtc CLK_OSC32K_FANOUT>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
index 596a25907432..709fe650a360 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
@@ -5,7 +5,7 @@
#include "sun50i-a64-sopine-baseboard.dts"
/ {
- model = "Pine64 LTS";
+ model = "Pine64 PINE A64 LTS";
compatible = "pine64,pine64-lts", "allwinner,sun50i-r18",
"allwinner,sun50i-a64";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
index b54099b654c8..026d843cd7e0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
@@ -4,7 +4,7 @@
#include "sun50i-a64-pine64.dts"
/ {
- model = "Pine64+";
+ model = "Pine64 PINE A64+";
compatible = "pine64,pine64-plus", "allwinner,sun50i-a64";
/* TODO: Camera, touchscreen, etc. */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 2accb5ddf783..09e71fd60785 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -9,7 +9,7 @@
#include <dt-bindings/gpio/gpio.h>
/ {
- model = "Pine64";
+ model = "Pine64 PINE A64";
compatible = "pine64,pine64", "allwinner,sun50i-a64";
aliases {
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
index 50ed2e9f10ed..379c2c8466f5 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
@@ -13,7 +13,7 @@
#include <dt-bindings/pwm/pwm.h>
/ {
- model = "Pinebook";
+ model = "Pine64 Pinebook";
compatible = "pine64,pinebook", "allwinner,sun50i-a64";
chassis-type = "laptop";
@@ -79,7 +79,7 @@
enable-active-high;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 87847116ab6d..6eab61a12cd8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -39,25 +39,35 @@
leds {
compatible = "gpio-leds";
- led-0 {
+ led0: led-0 {
function = LED_FUNCTION_INDICATOR;
color = <LED_COLOR_ID_BLUE>;
gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
+ retain-state-suspended;
};
- led-1 {
+ led1: led-1 {
function = LED_FUNCTION_INDICATOR;
color = <LED_COLOR_ID_GREEN>;
gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
+ retain-state-suspended;
};
- led-2 {
+ led2: led-2 {
function = LED_FUNCTION_INDICATOR;
color = <LED_COLOR_ID_RED>;
gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
+ retain-state-suspended;
};
};
+ multi-led {
+ compatible = "leds-group-multicolor";
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_INDICATOR;
+ leds = <&led0>, <&led1>, <&led2>;
+ };
+
reg_ps: ps-regulator {
compatible = "regulator-fixed";
regulator-name = "ps";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab-early-adopter.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab-early-adopter.dts
index 6265360ce623..86cc85eb3d48 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab-early-adopter.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab-early-adopter.dts
@@ -9,7 +9,7 @@
#include "sun50i-a64-pinetab.dts"
/ {
- model = "PineTab, Early Adopter's version";
+ model = "Pine64 PineTab Early Adopter";
compatible = "pine64,pinetab-early-adopter", "allwinner,sun50i-a64";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
index 0a5607f73049..f5fb1ee32dad 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
@@ -14,7 +14,7 @@
#include <dt-bindings/pwm/pwm.h>
/ {
- model = "PineTab, Development Sample";
+ model = "Pine64 PineTab Developer Sample";
compatible = "pine64,pinetab", "allwinner,sun50i-a64";
chassis-type = "tablet";
@@ -98,7 +98,7 @@
enable-active-high;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
post-power-on-delay-ms = <200>;
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 5e66ce1a334f..be2347c8f267 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -8,7 +8,7 @@
#include "sun50i-a64-sopine.dtsi"
/ {
- model = "SoPine with baseboard";
+ model = "Pine64 SOPINE on Baseboard carrier board";
compatible = "pine64,sopine-baseboard", "pine64,sopine",
"allwinner,sun50i-a64";
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 1128030e4c25..b407e1dd08a7 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
@@ -74,7 +74,7 @@
status = "okay";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 57ac18738c99..e868ca5ae753 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -51,10 +51,16 @@
device_type = "cpu";
reg = <0>;
enable-method = "psci";
- next-level-cache = <&L2>;
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu1: cpu@1 {
@@ -62,10 +68,16 @@
device_type = "cpu";
reg = <1>;
enable-method = "psci";
- next-level-cache = <&L2>;
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu2: cpu@2 {
@@ -73,10 +85,16 @@
device_type = "cpu";
reg = <2>;
enable-method = "psci";
- next-level-cache = <&L2>;
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu3: cpu@3 {
@@ -84,16 +102,25 @@
device_type = "cpu";
reg = <3>;
enable-method = "psci";
- next-level-cache = <&L2>;
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
- L2: l2-cache {
+ l2_cache: l2-cache {
compatible = "cache";
cache-level = <2>;
cache-unified;
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
};
};
@@ -107,27 +134,19 @@
gpu_opp_table: opp-table-gpu {
compatible = "operating-points-v2";
- opp-120000000 {
- opp-hz = /bits/ 64 <120000000>;
- };
-
- opp-312000000 {
- opp-hz = /bits/ 64 <312000000>;
- };
-
opp-432000000 {
opp-hz = /bits/ 64 <432000000>;
};
};
- osc24M: osc24M_clk {
+ osc24M: osc24M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc24M";
};
- osc32k: osc32k_clk {
+ osc32k: osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
@@ -216,21 +235,21 @@
};
trips {
- cpu_alert0: cpu_alert0 {
+ cpu_alert0: cpu-alert0 {
/* milliCelsius */
temperature = <75000>;
hysteresis = <2000>;
type = "passive";
};
- cpu_alert1: cpu_alert1 {
+ cpu_alert1: cpu-alert1 {
/* milliCelsius */
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
};
- cpu_crit: cpu_crit {
+ cpu_crit: cpu-crit {
/* milliCelsius */
temperature = <110000>;
hysteresis = <2000>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts
new file mode 100644
index 000000000000..bb2cde59bd03
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2024 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Tanix TX1";
+ compatible = "oranth,tanix-tx1", "allwinner,sun50i-h616";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet0 = &sdio_wifi;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key {
+ label = "hidden";
+ linux,code = <BTN_0>;
+ gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+ default-state = "on";
+ };
+ };
+
+ wifi_pwrseq: pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rtc CLK_OSC32K_FANOUT>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&x32clk_fanout_pin>;
+ pinctrl-names = "default";
+ reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+ };
+
+ reg_vcc5v: vcc5v {
+ /* board wide 5V supply directly from the DC input */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ir {
+ status = "okay";
+};
+
+&mmc1 {
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_aldo1>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ sdio_wifi: wifi@1 {
+ reg = <1>;
+ };
+};
+
+&mmc2 {
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_aldo1>;
+ bus-width = <8>;
+ non-removable;
+ max-frequency = <100000000>;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ vcc-pc-supply = <&reg_aldo1>;
+ vcc-pf-supply = <&reg_dldo1>;
+ vcc-pg-supply = <&reg_aldo1>;
+ vcc-ph-supply = <&reg_dldo1>;
+ vcc-pi-supply = <&reg_dldo1>;
+};
+
+&r_i2c {
+ status = "okay";
+
+ axp313: pmic@36 {
+ compatible = "x-powers,axp313a";
+ reg = <0x36>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+
+ vin1-supply = <&reg_vcc5v>;
+ vin2-supply = <&reg_vcc5v>;
+ vin3-supply = <&reg_vcc5v>;
+
+ regulators {
+ /* Supplies VCC-PLL, so needs to be always on. */
+ reg_aldo1: aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc1v8";
+ };
+
+ /* Supplies VCC-IO, so needs to be always on. */
+ reg_dldo1: dldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc3v3";
+ };
+
+ reg_dcdc1: dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <990000>;
+ regulator-name = "vdd-gpu-sys";
+ };
+
+ reg_dcdc2: dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "vdd-dram";
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "host"; /* USB A type receptable */
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
index 4c3921ac236c..b69032c44557 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
@@ -68,7 +68,7 @@
states = <1100000 0>, <1300000 1>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
post-power-on-delay-ms = <200>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
index a3e040da38a0..3a7ee44708a2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
@@ -103,7 +103,7 @@
states = <1100000 0x0>, <1300000 0x1>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
post-power-on-delay-ms = <200>;
@@ -170,7 +170,7 @@
non-removable;
status = "okay";
- rtl8189etv: sdio_wifi@1 {
+ rtl8189etv: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
index d7f8bad6bb98..b699bb900e13 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
@@ -85,7 +85,7 @@
status = "okay";
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 2 14 GPIO_ACTIVE_LOW>; /* PC14 */
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts
index 7ec5ac850a0d..ae85131aac9c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts
@@ -97,7 +97,7 @@
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
- rtl8189ftv: sdio_wifi@1 {
+ rtl8189ftv: wifi@1 {
reg = <1>;
};
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
index 22530ace12d5..734481e998b8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
@@ -52,7 +52,7 @@
regulator-max-microvolt = <3300000>;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
post-power-on-delay-ms = <200>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 381d58cea092..3be1e8c2fdb9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -34,7 +34,7 @@
};
};
- ext_osc32k: ext_osc32k_clk {
+ ext_osc32k: ext-osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
index 6fc65e8db220..6c3bfe3d09d9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
@@ -33,7 +33,7 @@
};
};
- ext_osc32k: ext_osc32k_clk {
+ ext_osc32k: ext-osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
index fb31dcb1cb6d..a3f65a45bd26 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
@@ -11,7 +11,7 @@
serial1 = &uart1; /* BT-UART */
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rtc CLK_OSC32K_FANOUT>;
clock-names = "ext_clock";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
index 92745128fcfe..13b07141c334 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
@@ -32,7 +32,7 @@
};
};
- ext_osc32k: ext_osc32k_clk {
+ ext_osc32k: ext-osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
index b710f1a0f53a..066fbeff8bfa 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
@@ -5,13 +5,13 @@
#include "sun50i-h6-pine-h64.dts"
+/delete-node/ &reg_gmac_3v3;
+
/ {
- model = "Pine H64 model B";
+ model = "Pine64 PINE H64 Model B";
compatible = "pine64,pine-h64-model-b", "allwinner,sun50i-h6";
- /delete-node/ reg_gmac_3v3;
-
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */
post-power-on-delay-ms = <200>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
index 1ffd68f43f87..c8b275552872 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -9,7 +9,7 @@
#include <dt-bindings/gpio/gpio.h>
/ {
- model = "Pine H64 model A";
+ model = "Pine64 PINE H64 Model A";
compatible = "pine64,pine-h64", "allwinner,sun50i-h6";
aliases {
@@ -22,7 +22,7 @@
stdout-path = "serial0:115200n8";
};
- ext_osc32k: ext_osc32k_clk {
+ ext_osc32k: ext-osc32k-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index d11e5041bae9..2301c59b41b1 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -29,6 +29,13 @@
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu1: cpu@1 {
@@ -39,6 +46,13 @@
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu2: cpu@2 {
@@ -49,6 +63,13 @@
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu3: cpu@3 {
@@ -59,6 +80,22 @@
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
+ };
+
+ l2_cache: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
};
};
@@ -68,7 +105,7 @@
status = "disabled";
};
- osc24M: osc24M_clk {
+ osc24M: osc24M-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
index af421ba24ce0..d12b01c5f41b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
@@ -6,6 +6,7 @@
/dts-v1/;
#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -62,6 +63,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&mmc0 {
vmmc-supply = <&reg_dldo1>;
/* Card detection pin is not connected */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
new file mode 100644
index 000000000000..dd10aaf472b6
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2023 Martin Botka <martin@somainline.org>
+
+/ {
+ cpu_opp_table: opp-table-cpu {
+ compatible = "allwinner,sun50i-h616-operating-points";
+ nvmem-cells = <&cpu_speed_grade>;
+ opp-shared;
+
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x3f>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x12>;
+ };
+
+ opp-720000000 {
+ opp-hz = /bits/ 64 <720000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x2d>;
+ };
+
+ opp-792000000 {
+ opp-hz = /bits/ 64 <792000000>;
+ opp-microvolt-speed1 = <900000>;
+ opp-microvolt-speed4 = <940000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x12>;
+ };
+
+ opp-936000000 {
+ opp-hz = /bits/ 64 <936000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x0d>;
+ };
+
+ opp-1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt-speed0 = <950000>;
+ opp-microvolt-speed1 = <940000>;
+ opp-microvolt-speed2 = <950000>;
+ opp-microvolt-speed3 = <950000>;
+ opp-microvolt-speed4 = <1020000>;
+ opp-microvolt-speed5 = <900000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x3f>;
+ };
+
+ opp-1032000000 {
+ opp-hz = /bits/ 64 <1032000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x20>;
+ };
+
+ opp-1104000000 {
+ opp-hz = /bits/ 64 <1104000000>;
+ opp-microvolt-speed0 = <1000000>;
+ opp-microvolt-speed2 = <1000000>;
+ opp-microvolt-speed3 = <1000000>;
+ opp-microvolt-speed5 = <950000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x2d>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt-speed0 = <1050000>;
+ opp-microvolt-speed1 = <1020000>;
+ opp-microvolt-speed2 = <1050000>;
+ opp-microvolt-speed3 = <1050000>;
+ opp-microvolt-speed4 = <1100000>;
+ opp-microvolt-speed5 = <1020000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x3f>;
+ };
+
+ opp-1320000000 {
+ opp-hz = /bits/ 64 <1320000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x1d>;
+ };
+
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x2d>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt-speed1 = <1100000>;
+ opp-microvolt-speed3 = <1100000>;
+ opp-microvolt-speed5 = <1160000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ opp-supported-hw = <0x2a>;
+ };
+ };
+};
+
+&cpu0 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu1 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu2 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu3 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
index b5d713926a34..a360d8567f95 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
@@ -6,12 +6,17 @@
/dts-v1/;
#include "sun50i-h616-orangepi-zero.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
/ {
model = "OrangePi Zero2";
compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
};
+&cpu0 {
+ cpu-supply = <&reg_dcdca>;
+};
+
&emac0 {
allwinner,rx-delay-ps = <3100>;
allwinner,tx-delay-ps = <700>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
index 959b6fd18483..26d25b5b59e0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -32,6 +33,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdca>;
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index b2e85e52d1a1..b29ce7321317 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -26,6 +26,14 @@
reg = <0>;
enable-method = "psci";
clocks = <&ccu CLK_CPUX>;
+ #cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu1: cpu@1 {
@@ -34,6 +42,14 @@
reg = <1>;
enable-method = "psci";
clocks = <&ccu CLK_CPUX>;
+ #cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu2: cpu@2 {
@@ -42,6 +58,14 @@
reg = <2>;
enable-method = "psci";
clocks = <&ccu CLK_CPUX>;
+ #cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu3: cpu@3 {
@@ -50,6 +74,23 @@
reg = <3>;
enable-method = "psci";
clocks = <&ccu CLK_CPUX>;
+ #cooling-cells = <2>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
+ };
+
+ l2_cache: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ cache-size = <0x40000>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
};
};
@@ -109,6 +150,16 @@
#size-cells = <1>;
ranges = <0x0 0x0 0x0 0x40000000>;
+ crypto: crypto@1904000 {
+ compatible = "allwinner,sun50i-h616-crypto";
+ reg = <0x01904000 0x800>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>,
+ <&ccu CLK_MBUS_CE>, <&rtc CLK_IOSC>;
+ clock-names = "bus", "mod", "ram", "trng";
+ resets = <&ccu RST_BUS_CE>;
+ };
+
syscon: syscon@3000000 {
compatible = "allwinner,sun50i-h616-system-control";
reg = <0x03000000 0x1000>;
@@ -156,6 +207,10 @@
ths_calibration: thermal-sensor-calibration@14 {
reg = <0x14 0x8>;
};
+
+ cpu_speed_grade: cpu-speed-grade@0 {
+ reg = <0x0 2>;
+ };
};
watchdog: watchdog@30090a0 {
@@ -194,7 +249,7 @@
};
i2c0_pins: i2c0-pins {
- pins = "PI6", "PI7";
+ pins = "PI5", "PI6";
function = "i2c0";
};
@@ -298,6 +353,15 @@
#interrupt-cells = <3>;
};
+ iommu: iommu@30f0000 {
+ compatible = "allwinner,sun50i-h616-iommu";
+ reg = <0x030f0000 0x10000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_IOMMU>;
+ resets = <&ccu RST_BUS_IOMMU>;
+ #iommu-cells = <1>;
+ };
+
mmc0: mmc@4020000 {
compatible = "allwinner,sun50i-h616-mmc",
"allwinner,sun50i-a100-mmc";
@@ -581,6 +645,17 @@
status = "disabled";
};
+ gpadc: adc@5070000 {
+ compatible = "allwinner,sun50i-h616-gpadc",
+ "allwinner,sun20i-d1-gpadc";
+ reg = <0x05070000 0x400>;
+ clocks = <&ccu CLK_BUS_GPADC>;
+ resets = <&ccu RST_BUS_GPADC>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #io-channel-cells = <1>;
+ };
+
ths: thermal-sensor@5070400 {
compatible = "allwinner,sun50i-h616-ths";
reg = <0x05070400 0x400>;
@@ -594,6 +669,16 @@
#thermal-sensor-cells = <1>;
};
+ lradc: lradc@5070800 {
+ compatible = "allwinner,sun50i-h616-lradc",
+ "allwinner,sun50i-r329-lradc";
+ reg = <0x05070800 0x400>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_KEYADC>;
+ resets = <&ccu RST_BUS_KEYADC>;
+ status = "disabled";
+ };
+
usbotg: usb@5100000 {
compatible = "allwinner,sun50i-h616-musb",
"allwinner,sun8i-h3-musb";
@@ -775,6 +860,15 @@
#reset-cells = <1>;
};
+ nmi_intc: interrupt-controller@7010320 {
+ compatible = "allwinner,sun50i-h616-nmi",
+ "allwinner,sun9i-a80-nmi";
+ reg = <0x07010320 0xc>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
r_pio: pinctrl@7022000 {
compatible = "allwinner,sun50i-h616-r-pinctrl";
reg = <0x07022000 0x400>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
index 8c1263a3939e..e92d150aaf1c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
@@ -4,6 +4,11 @@
*/
#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
&mmc2 {
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts
index 21ca1977055d..6a4f0da97233 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -53,6 +54,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci1 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
index b3b1b8692125..e1cd7572a14c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
@@ -6,12 +6,17 @@
/dts-v1/;
#include "sun50i-h616-orangepi-zero.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
/ {
model = "OrangePi Zero3";
compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618";
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&emac0 {
allwinner,tx-delay-ps = <700>;
phy-mode = "rgmii-rxid";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
index ac0a2b7ea6f3..d6631bfe629f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -41,7 +42,7 @@
regulator-always-on;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rtc CLK_OSC32K_FANOUT>;
clock-names = "ext_clock";
@@ -51,6 +52,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
index b6e3c169797f..ce90327e1b2e 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
@@ -42,7 +42,7 @@
regulator-always-on;
};
- wifi_pwrseq: wifi_pwrseq {
+ wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
post-power-on-delay-ms = <200>;
@@ -191,7 +191,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en;
vin1-supply = <&reg_vcc5v>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
new file mode 100644
index 000000000000..afb49e65859f
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2024 Ryan Walklin <ryan@testtoast.com>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Anbernic RG35XX 2024";
+ chassis-type = "handset";
+ compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio_keys_gamepad: gpio-keys-gamepad {
+ compatible = "gpio-keys";
+
+ button-a {
+ label = "Action-Pad A";
+ gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_EAST>;
+ };
+
+ button-b {
+ label = "Action-Pad B";
+ gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_SOUTH>;
+ };
+
+ button-down {
+ label = "D-Pad Down";
+ gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ button-l1 {
+ label = "Key L1";
+ gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_TL>;
+ };
+
+ button-l2 {
+ label = "Key L2";
+ gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_TL2>;
+ };
+
+ button-left {
+ label = "D-Pad left";
+ gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-menu {
+ label = "Key Menu";
+ gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_MODE>;
+ };
+
+ button-r1 {
+ label = "Key R1";
+ gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_TR>;
+ };
+
+ button-r2 {
+ label = "Key R2";
+ gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_TR2>;
+ };
+
+ button-right {
+ label = "D-Pad Right";
+ gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-select {
+ label = "Key Select";
+ gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_SELECT>;
+ };
+ button-start {
+ label = "Key Start";
+ gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_START>;
+ };
+
+ button-up {
+ label = "D-Pad Up";
+ gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ button-x {
+ label = "Action-Pad X";
+ gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_NORTH>;
+ };
+
+ button-y {
+ label = "Action Pad Y";
+ gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_WEST>;
+ };
+ };
+
+ gpio-keys-volume {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ button-vol-up {
+ label = "Key Volume Up";
+ gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ button-vol-down {
+ label = "Key Volume Down";
+ gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */
+ default-state = "on";
+ };
+ };
+
+ reg_vcc5v: regulator-vcc5v { /* USB-C power input */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc1>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&mmc0 {
+ vmmc-supply = <&reg_cldo3>;
+ disable-wp;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+ bus-width = <4>;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ vcc-pa-supply = <&reg_cldo3>;
+ vcc-pc-supply = <&reg_cldo3>;
+ vcc-pe-supply = <&reg_cldo3>;
+ vcc-pf-supply = <&reg_cldo3>;
+ vcc-pg-supply = <&reg_aldo4>;
+ vcc-ph-supply = <&reg_cldo3>;
+ vcc-pi-supply = <&reg_cldo3>;
+};
+
+&r_rsb {
+ status = "okay";
+
+ axp717: pmic@3a3 {
+ compatible = "x-powers,axp717";
+ reg = <0x3a3>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ vin1-supply = <&reg_vcc5v>;
+ vin2-supply = <&reg_vcc5v>;
+ vin3-supply = <&reg_vcc5v>;
+ vin4-supply = <&reg_vcc5v>;
+
+ regulators {
+ reg_dcdc1: dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1160000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdc2: dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <940000>;
+ regulator-max-microvolt = <940000>;
+ regulator-name = "vdd-gpu-sys";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-dram";
+ };
+
+ reg_aldo1: aldo1 {
+ /* 1.8v - unused */
+ };
+
+ reg_aldo2: aldo2 {
+ /* 1.8v - unused */
+ };
+
+ reg_aldo3: aldo3 {
+ /* 1.8v - unused */
+ };
+
+ reg_aldo4: aldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pg";
+ };
+
+ reg_bldo1: bldo1 {
+ /* 1.8v - unused */
+ };
+
+ reg_bldo2: bldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pll";
+ };
+
+ reg_bldo3: bldo3 {
+ /* 2.8v - unused */
+ };
+
+ reg_bldo4: bldo4 {
+ /* 1.2v - unused */
+ };
+
+ reg_cldo1: cldo1 {
+ /* 3.3v - audio codec - not yet implemented */
+ };
+
+ reg_cldo2: cldo2 {
+ /* 3.3v - unused */
+ };
+
+ reg_cldo3: cldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-io";
+ };
+
+ reg_cldo4: cldo4 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+ };
+
+ reg_boost: boost {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5200000>;
+ regulator-name = "boost";
+ };
+
+ reg_cpusldo: cpusldo {
+ /* unused */
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
+
+/* the AXP717 has USB type-C role switch functionality, not yet described by the binding */
+&usbotg {
+ dr_mode = "peripheral"; /* USB type-C receptable */
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts
new file mode 100644
index 000000000000..ff453336eab1
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2024 Ryan Walklin <ryan@testtoast.com>.
+ * Copyright (C) 2024 Chris Morgan <macroalpha82@gmail.com>.
+ */
+
+#include "sun50i-h700-anbernic-rg35xx-plus.dts"
+
+/ {
+ model = "Anbernic RG35XX H";
+ compatible = "anbernic,rg35xx-h", "allwinner,sun50i-h700";
+
+ adc-joystick {
+ compatible = "adc-joystick";
+ io-channels = <&adc_mux 0>,
+ <&adc_mux 1>,
+ <&adc_mux 2>,
+ <&adc_mux 3>;
+ pinctrl-0 = <&joy_mux_pin>;
+ pinctrl-names = "default";
+ poll-interval = <60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ axis@0 {
+ reg = <0>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <4096 0>;
+ linux,code = <ABS_X>;
+ };
+
+ axis@1 {
+ reg = <1>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <0 4096>;
+ linux,code = <ABS_Y>;
+ };
+
+ axis@2 {
+ reg = <2>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <0 4096>;
+ linux,code = <ABS_RX>;
+ };
+
+ axis@3 {
+ reg = <3>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <4096 0>;
+ linux,code = <ABS_RY>;
+ };
+ };
+
+ adc_mux: adc-mux {
+ compatible = "io-channel-mux";
+ channels = "left_x", "left_y", "right_x", "right_y";
+ #io-channel-cells = <1>;
+ io-channels = <&gpadc 0>;
+ io-channel-names = "parent";
+ mux-controls = <&gpio_mux>;
+ settle-time-us = <100>;
+ };
+
+ gpio_mux: mux-controller {
+ compatible = "gpio-mux";
+ mux-gpios = <&pio 8 1 GPIO_ACTIVE_LOW>,
+ <&pio 8 2 GPIO_ACTIVE_LOW>;
+ #mux-control-cells = <0>;
+ };
+};
+
+&gpadc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ channel@0 {
+ reg = <0>;
+ };
+};
+
+&gpio_keys_gamepad {
+ button-thumbl {
+ label = "GPIO Thumb Left";
+ gpios = <&pio 4 8 GPIO_ACTIVE_LOW>; /* PE8 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_THUMBL>;
+ };
+
+ button-thumbr {
+ label = "GPIO Thumb Right";
+ gpios = <&pio 4 9 GPIO_ACTIVE_LOW>; /* PE9 */
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_THUMBR>;
+ };
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ joy_mux_pin: joy-mux-pin {
+ pins = "PI0";
+ function = "gpio_out";
+ };
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts
new file mode 100644
index 000000000000..60a8e4922103
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2024 Ryan Walklin <ryan@testtoast.com>.
+ */
+
+#include "sun50i-h700-anbernic-rg35xx-2024.dts"
+
+/ {
+ model = "Anbernic RG35XX Plus";
+ compatible = "anbernic,rg35xx-plus", "allwinner,sun50i-h700";
+
+ wifi_pwrseq: pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rtc CLK_OSC32K_FANOUT>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&x32clk_fanout_pin>;
+ pinctrl-names = "default";
+ post-power-on-delay-ms = <200>;
+ reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+ };
+};
+
+/* SDIO WiFi RTL8821CS */
+&mmc1 {
+ vmmc-supply = <&reg_cldo4>;
+ vqmmc-supply = <&reg_aldo4>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ sdio_wifi: wifi@1 {
+ reg = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <6 15 IRQ_TYPE_LEVEL_LOW>; /* PG15 */
+ interrupt-names = "host-wake";
+ };
+};
+
+/* Bluetooth RTL8821CS */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "realtek,rtl8821cs-bt", "realtek,rtl8723bs-bt";
+ device-wake-gpios = <&pio 6 17 GPIO_ACTIVE_HIGH>; /* PG17 */
+ enable-gpios = <&pio 6 19 GPIO_ACTIVE_HIGH>; /* PG19 */
+ host-wake-gpios = <&pio 6 16 GPIO_ACTIVE_HIGH>; /* PG16 */
+ };
+};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
index 072fe20cfca0..0def0b0daaf7 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -34,6 +34,7 @@
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
+ next-level-cache = <&l2_shared>;
reg = <0x0>;
};
@@ -41,6 +42,7 @@
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
+ next-level-cache = <&l2_shared>;
reg = <0x1>;
};
@@ -48,6 +50,7 @@
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
+ next-level-cache = <&l2_shared>;
reg = <0x2>;
};
@@ -55,8 +58,15 @@
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
+ next-level-cache = <&l2_shared>;
reg = <0x3>;
};
+
+ l2_shared: cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ };
};
firmware {
@@ -79,7 +89,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <0 170 4>,
<0 171 4>,
<0 172 4>,
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
index 26173f0b0051..4eee777ef1a1 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -180,8 +180,6 @@
&qspi {
status = "okay";
flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "micron,mt25qu02g", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <100000000>;
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
index 81d0e914a77c..7c53cb9621e5 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
@@ -169,8 +169,6 @@
&qspi {
status = "okay";
flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "micron,mt25qu02g", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <100000000>;
diff --git a/arch/arm64/boot/dts/amazon/alpine-v2.dtsi b/arch/arm64/boot/dts/amazon/alpine-v2.dtsi
index dbf2dce8d1d6..da9de4986660 100644
--- a/arch/arm64/boot/dts/amazon/alpine-v2.dtsi
+++ b/arch/arm64/boot/dts/amazon/alpine-v2.dtsi
@@ -39,6 +39,7 @@
/ {
model = "Annapurna Labs Alpine v2";
compatible = "al,alpine-v2";
+ interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
@@ -89,6 +90,22 @@
clock-frequency = <1000000>;
};
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a57-pmu";
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
@@ -97,22 +114,6 @@
interrupt-parent = <&gic>;
ranges;
- timer {
- compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
- };
-
- pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
- };
-
gic: interrupt-controller@f0200000 {
compatible = "arm,gic-v3";
reg = <0x0 0xf0200000 0x0 0x10000>, /* GIC Dist */
@@ -150,7 +151,7 @@
al,msi-num-spis = <160>;
};
- io-fabric {
+ io-fabric@fc000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/amazon/alpine-v3.dtsi b/arch/arm64/boot/dts/amazon/alpine-v3.dtsi
index 3ea178acdddf..8b6156b5af65 100644
--- a/arch/arm64/boot/dts/amazon/alpine-v3.dtsi
+++ b/arch/arm64/boot/dts/amazon/alpine-v3.dtsi
@@ -244,7 +244,7 @@
next-level-cache = <&cluster3_l2>;
};
- cluster0_l2: cache@0 {
+ cluster0_l2: cache-0 {
compatible = "cache";
cache-size = <0x200000>;
cache-line-size = <64>;
@@ -253,7 +253,7 @@
cache-unified;
};
- cluster1_l2: cache@100 {
+ cluster1_l2: cache-100 {
compatible = "cache";
cache-size = <0x200000>;
cache-line-size = <64>;
@@ -262,7 +262,7 @@
cache-unified;
};
- cluster2_l2: cache@200 {
+ cluster2_l2: cache-200 {
compatible = "cache";
cache-size = <0x200000>;
cache-line-size = <64>;
@@ -271,7 +271,7 @@
cache-unified;
};
- cluster3_l2: cache@300 {
+ cluster3_l2: cache-300 {
compatible = "cache";
cache-size = <0x200000>;
cache-line-size = <64>;
@@ -318,7 +318,7 @@
#size-cells = <2>;
ranges;
- gic: interrupt-controller@f0000000 {
+ gic: interrupt-controller@f0800000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
interrupt-controller;
@@ -361,7 +361,7 @@
interrupt-parent = <&gic>;
};
- io-fabric {
+ io-fabric@fc000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/amd/elba-16core.dtsi b/arch/arm64/boot/dts/amd/elba-16core.dtsi
index 568bcc39ce9f..6c1b7b8fe354 100644
--- a/arch/arm64/boot/dts/amd/elba-16core.dtsi
+++ b/arch/arm64/boot/dts/amd/elba-16core.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
* Copyright 2020-2023 Advanced Micro Devices, Inc.
*/
diff --git a/arch/arm64/boot/dts/amd/elba-asic-common.dtsi b/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
index 46b6c6783f58..d12e9a7b5587 100644
--- a/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
+++ b/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
* Copyright 2020-2022 Advanced Micro Devices, Inc.
*/
diff --git a/arch/arm64/boot/dts/amd/elba-asic.dts b/arch/arm64/boot/dts/amd/elba-asic.dts
index c3f4da2f7449..20b0fa0807a1 100644
--- a/arch/arm64/boot/dts/amd/elba-asic.dts
+++ b/arch/arm64/boot/dts/amd/elba-asic.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
* Device Tree file for AMD Pensando Elba Board.
*
diff --git a/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi b/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
index cf761a05a81f..6ea2d777c8c9 100644
--- a/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
+++ b/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
* Copyright 2020-2023 Advanced Micro Devices, Inc.
*/
diff --git a/arch/arm64/boot/dts/amd/elba.dtsi b/arch/arm64/boot/dts/amd/elba.dtsi
index 674890cf2a34..758bce0a0b2a 100644
--- a/arch/arm64/boot/dts/amd/elba.dtsi
+++ b/arch/arm64/boot/dts/amd/elba.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
* Copyright 2020-2022 Advanced Micro Devices, Inc.
*/
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 1ab160bf928a..29417f04f886 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_MESON) += amlogic-a4-a113l2-ba400.dtb
+dtb-$(CONFIG_ARCH_MESON) += amlogic-a5-a113x2-av400.dtb
dtb-$(CONFIG_ARCH_MESON) += amlogic-c3-c302x-aw409.dtb
dtb-$(CONFIG_ARCH_MESON) += amlogic-t7-a311d2-an400.dtb
dtb-$(CONFIG_ARCH_MESON) += amlogic-t7-a311d2-khadas-vim4.dtb
@@ -16,7 +18,11 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-bananapi-m2s.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3-ts050.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-cm4io.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-mnt-reform2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-dreambox-one.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-dreambox-two.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gsking-x.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking.dtb
@@ -58,6 +64,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.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-s905x-vero4k.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxlx-s905l-p271.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-gt1-ultimate.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-mecool-kiii-pro.dtb
@@ -76,6 +84,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m2-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l-ts050.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-s905d3-libretech-cc.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
@@ -86,3 +95,5 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
# Overlays
meson-g12a-fbx8am-brcm-dtbs := meson-g12a-fbx8am.dtb meson-g12a-fbx8am-brcm.dtbo
meson-g12a-fbx8am-realtek-dtbs := meson-g12a-fbx8am.dtb meson-g12a-fbx8am-realtek.dtbo
+meson-g12b-a311d-khadas-vim3-ts050-dtbs := meson-g12b-a311d-khadas-vim3.dtb meson-khadas-vim3-ts050.dtbo
+meson-sm1-khadas-vim3l-ts050-dtbs := meson-sm1-khadas-vim3l.dtb meson-khadas-vim3-ts050.dtbo
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a4-a113l2-ba400.dts b/arch/arm64/boot/dts/amlogic/amlogic-a4-a113l2-ba400.dts
new file mode 100644
index 000000000000..ad3127e695d9
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a4-a113l2-ba400.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "amlogic-a4.dtsi"
+
+/ {
+ model = "Amlogic A113L2 ba400 Development Board";
+ compatible = "amlogic,ba400", "amlogic,a4";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart_b;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* 10 MiB reserved for ARM Trusted Firmware */
+ secmon_reserved: secmon@5000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0x05000000 0x0 0xa00000>;
+ no-map;
+ };
+ };
+};
+
+&uart_b {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a4-common.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a4-common.dtsi
new file mode 100644
index 000000000000..b6106ad4a072
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a4-common.dtsi
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/gpio.h>
+/ {
+ 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)>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@fff01000 {
+ compatible = "arm,gic-400";
+ reg = <0x0 0xfff01000 0 0x1000>,
+ <0x0 0xfff02000 0 0x2000>,
+ <0x0 0xfff04000 0 0x2000>,
+ <0x0 0xfff06000 0 0x2000>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ apb: bus@fe000000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xfe000000 0x0 0x480000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+
+ uart_b: serial@7a000 {
+ compatible = "amlogic,a4-uart",
+ "amlogic,meson-s4-uart";
+ reg = <0x0 0x7a000 0x0 0x18>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&xtal>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi
new file mode 100644
index 000000000000..de10e7aebf21
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ */
+
+#include "amlogic-a4-common.dtsi"
+#include <dt-bindings/power/amlogic,a4-pwrc.h>
+/ {
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ };
+ };
+
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gxbb-sm";
+
+ pwrc: power-controller {
+ compatible = "amlogic,a4-pwrc";
+ #power-domain-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5-a113x2-av400.dts b/arch/arm64/boot/dts/amlogic/amlogic-a5-a113x2-av400.dts
new file mode 100644
index 000000000000..11d8b88c1ce5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a5-a113x2-av400.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "amlogic-a5.dtsi"
+
+/ {
+ model = "Amlogic A113X2 av400 Development Board";
+ compatible = "amlogic,av400", "amlogic,a5";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart_b;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* 10 MiB reserved for ARM Trusted Firmware */
+ secmon_reserved: secmon@5000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0x05000000 0x0 0xa00000>;
+ no-map;
+ };
+ };
+};
+
+&uart_b {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
new file mode 100644
index 000000000000..43f68a7da2f7
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ */
+
+#include "amlogic-a4-common.dtsi"
+/ {
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi
index 32a754fe7990..f8fb060c49ae 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi
@@ -111,8 +111,7 @@
};
gpio_intc: interrupt-controller@4080 {
- compatible = "amlogic,meson-gpio-intc",
- "amlogic,c3-gpio-intc";
+ compatible = "amlogic,c3-gpio-intc", "amlogic,meson-gpio-intc";
reg = <0x0 0x4080 0x0 0x0020>;
interrupt-controller;
#interrupt-cells = <2>;
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-reset.h b/arch/arm64/boot/dts/amlogic/amlogic-t7-reset.h
new file mode 100644
index 000000000000..ec90a11df508
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-reset.h
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __DTS_AMLOGIC_T7_RESET_H
+#define __DTS_AMLOGIC_T7_RESET_H
+
+/* RESET0 */
+/* 0-3 */
+#define RESET_USB 4
+#define RESET_U2DRD 5
+#define RESET_U3DRD 6
+#define RESET_U3DRD_PIPE0 7
+#define RESET_U2PHY20 8
+#define RESET_U2PHY21 9
+#define RESET_GDC 10
+#define RESET_HDMI20_AES 11
+#define RESET_HDMIRX 12
+#define RESET_HDMIRX_APB 13
+#define RESET_DEWARP 14
+/* 15 */
+#define RESET_HDMITX_CAPB3 16
+#define RESET_BRG_VCBUG_DEC 17
+#define RESET_VCBUS 18
+#define RESET_VID_PLL_DIV 19
+#define RESET_VDI6 20
+#define RESET_GE2D 21
+#define RESET_HDMITXPHY 22
+#define RESET_VID_LOCK 23
+#define RESET_VENC0 24
+#define RESET_VDAC 25
+#define RESET_VENC2 26
+#define RESET_VENC1 27
+#define RESET_RDMA 28
+#define RESET_HDMITX 29
+#define RESET_VIU 30
+#define RESET_VENC 31
+
+/* RESET1 */
+#define RESET_AUDIO 32
+#define RESET_MALI_CAPB3 33
+#define RESET_MALI 34
+#define RESET_DDR_APB 35
+#define RESET_DDR 36
+#define RESET_DOS_CAPB3 37
+#define RESET_DOS 38
+#define RESET_COMBO_DPHY_CHAN2 39
+#define RESET_DEBUG_B 40
+#define RESET_DEBUG_A 41
+#define RESET_DSP_B 42
+#define RESET_DSP_A 43
+#define RESET_PCIE_A 44
+#define RESET_PCIE_PHY 45
+#define RESET_PCIE_APB 46
+#define RESET_ANAKIN 47
+#define RESET_ETH 48
+#define RESET_EDP0_CTRL 49
+#define RESET_EDP1_CTRL 50
+#define RESET_COMBO_DPHY_CHAN0 51
+#define RESET_COMBO_DPHY_CHAN1 52
+#define RESET_DSI_LVDS_EDP_TOP 53
+#define RESET_PCIE1_PHY 54
+#define RESET_PCIE1_APB 55
+#define RESET_DDR_1 56
+/* 57 */
+#define RESET_EDP1_PIPELINE 58
+#define RESET_EDP0_PIPELINE 59
+#define RESET_MIPI_DSI1_PHY 60
+#define RESET_MIPI_DSI0_PHY 61
+#define RESET_MIPI_DSI_A_HOST 62
+#define RESET_MIPI_DSI_B_HOST 63
+
+/* RESET2 */
+#define RESET_DEVICE_MMC_ARB 64
+#define RESET_IR_CTRL 65
+#define RESET_TS_A73 66
+#define RESET_TS_A53 67
+#define RESET_SPICC_2 68
+#define RESET_SPICC_3 69
+#define RESET_SPICC_4 70
+#define RESET_SPICC_5 71
+#define RESET_SMART_CARD 72
+#define RESET_SPICC_0 73
+#define RESET_SPICC_1 74
+#define RESET_RSA 75
+/* 76-79 */
+#define RESET_MSR_CLK 80
+#define RESET_SPIFC 81
+#define RESET_SAR_ADC 82
+#define RESET_BT 83
+/* 84-87 */
+#define RESET_ACODEC 88
+#define RESET_CEC 89
+#define RESET_AFIFO 90
+#define RESET_WATCHDOG 91
+/* 92-95 */
+
+/* RESET3 */
+#define RESET_BRG_NIC1_GPV 96
+#define RESET_BRG_NIC2_GPV 97
+#define RESET_BRG_NIC3_GPV 98
+#define RESET_BRG_NIC4_GPV 99
+#define RESET_BRG_NIC5_GPV 100
+/* 101-121 */
+#define RESET_MIPI_ISP 122
+#define RESET_BRG_ADB_MALI_1 123
+#define RESET_BRG_ADB_MALI_0 124
+#define RESET_BRG_ADB_A73 125
+#define RESET_BRG_ADB_A53 126
+#define RESET_BRG_CCI 127
+
+/* RESET4 */
+#define RESET_PWM_AO_AB 128
+#define RESET_PWM_AO_CD 129
+#define RESET_PWM_AO_EF 130
+#define RESET_PWM_AO_GH 131
+#define RESET_PWM_AB 132
+#define RESET_PWM_CD 133
+#define RESET_PWM_EF 134
+/* 135-137 */
+#define RESET_UART_A 138
+#define RESET_UART_B 139
+#define RESET_UART_C 140
+#define RESET_UART_D 141
+#define RESET_UART_E 142
+#define RESET_UART_F 143
+#define RESET_I2C_S_A 144
+#define RESET_I2C_M_A 145
+#define RESET_I2C_M_B 146
+#define RESET_I2C_M_C 147
+#define RESET_I2C_M_D 148
+#define RESET_I2C_M_E 149
+#define RESET_I2C_M_F 150
+#define RESET_I2C_M_AO_A 151
+#define RESET_SD_EMMC_A 152
+#define RESET_SD_EMMC_B 153
+#define RESET_SD_EMMC_C 154
+#define RESET_I2C_M_AO_B 155
+#define RESET_TS_GPU 156
+#define RESET_TS_NNA 157
+#define RESET_TS_VPN 158
+#define RESET_TS_HEVC 159
+
+/* RESET5 */
+#define RESET_BRG_NOC_DDR_1 160
+#define RESET_BRG_NOC_DDR_0 161
+#define RESET_BRG_NOC_MAIN 162
+#define RESET_BRG_NOC_ALL 163
+/* 164-167 */
+#define RESET_BRG_NIC2_SYS 168
+#define RESET_BRG_NIC2_MAIN 169
+#define RESET_BRG_NIC2_HDMI 170
+#define RESET_BRG_NIC2_ALL 171
+#define RESET_BRG_NIC3_WAVE 172
+#define RESET_BRG_NIC3_VDEC 173
+#define RESET_BRG_NIC3_HEVCF 174
+#define RESET_BRG_NIC3_HEVCB 175
+#define RESET_BRG_NIC3_HCODEC 176
+#define RESET_BRG_NIC3_GE2D 177
+#define RESET_BRG_NIC3_GDC 178
+#define RESET_BRG_NIC3_AMLOGIC 179
+#define RESET_BRG_NIC3_MAIN 180
+#define RESET_BRG_NIC3_ALL 181
+#define RESET_BRG_NIC5_VPU 182
+/* 183-185 */
+#define RESET_BRG_NIC4_DSPB 186
+#define RESET_BRG_NIC4_DSPA 187
+#define RESET_BRG_NIC4_VAPB 188
+#define RESET_BRG_NIC4_CLK81 189
+#define RESET_BRG_NIC4_MAIN 190
+#define RESET_BRG_NIC4_ALL 191
+
+/* RESET6 */
+#define RESET_BRG_VDEC_PIPEL 192
+#define RESET_BRG_HEVCF_DMC_PIPEL 193
+#define RESET_BRG_NIC2TONIC4_PIPEL 194
+#define RESET_BRG_HDMIRXTONIC2_PIPEL 195
+#define RESET_BRG_SECTONIC4_PIPEL 196
+#define RESET_BRG_VPUTONOC_PIPEL 197
+#define RESET_BRG_NIC4TONOC_PIPEL 198
+#define RESET_BRG_NIC3TONOC_PIPEL 199
+#define RESET_BRG_NIC2TONOC_PIPEL 200
+#define RESET_BRG_NNATONOC_PIPEL 201
+#define RESET_BRG_FRISP3_PIPEL 202
+#define RESET_BRG_FRISP2_PIPEL 203
+#define RESET_BRG_FRISP1_PIPEL 204
+#define RESET_BRG_FRISP0_PIPEL 205
+/* 206-217 */
+#define RESET_BRG_AMPIPE_NAND 218
+#define RESET_BRG_AMPIPE_ETH 219
+/* 220 */
+#define RESET_BRG_AM2AXI0 221
+#define RESET_BRG_AM2AXI1 222
+#define RESET_BRG_AM2AXI2 223
+
+#endif /* ___DTS_AMLOGIC_T7_RESET_H */
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 5248bdf824ea..c23efc6c7ac0 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/amlogic,t7-pwrc.h>
+#include "amlogic-t7-reset.h"
/ {
interrupt-parent = <&gic>;
@@ -149,6 +150,12 @@
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+ reset: reset-controller@2000 {
+ compatible = "amlogic,t7-reset";
+ reg = <0x0 0x2000 0x0 0x98>;
+ #reset-cells = <1>;
+ };
+
watchdog@2100 {
compatible = "amlogic,t7-wdt";
reg = <0x0 0x2100 0x0 0x10>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
index 4bc30af05848..0d92f5253b64 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include "meson-a1.dtsi"
+#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "amlogic,ad402", "amlogic,a1";
@@ -83,6 +84,50 @@
vin-supply = <&vddao_3v3>;
regulator-always-on;
};
+
+ thermal-zones {
+ soc_thermal: soc-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ sustainable-power = <130>;
+
+ thermal-sensors = <&cpu_temp>;
+
+ trips {
+ soc_passive: soc-passive {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ soc_hot: soc-hot {
+ temperature = <85000>;
+ hysteresis = <5000>;
+ type = "hot";
+ };
+
+ soc_critical: soc-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+
+ soc_cooling_maps: cooling-maps {
+ map0 {
+ trip = <&soc_passive>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&soc_hot>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
};
/* Bluetooth HCI H4 */
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index c03e207ea6c5..e5366d4239b1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -28,6 +28,7 @@
reg = <0x0 0x0>;
enable-method = "psci";
next-level-cache = <&l2>;
+ #cooling-cells = <2>;
};
cpu1: cpu@1 {
@@ -36,6 +37,7 @@
reg = <0x0 0x1>;
enable-method = "psci";
next-level-cache = <&l2>;
+ #cooling-cells = <2>;
};
l2: l2-cache0 {
@@ -398,6 +400,17 @@
power-domains = <&pwrc PWRC_USB_ID>;
};
+ cpu_temp: temperature-sensor@4c00 {
+ compatible = "amlogic,a1-cpu-thermal";
+ reg = <0x0 0x4c00 0x0 0x50>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc_periphs CLKID_TS>;
+ assigned-clocks = <&clkc_periphs CLKID_TS>;
+ assigned-clock-rates = <500000>;
+ #thermal-sensor-cells = <0>;
+ amlogic,ao-secure = <&sec_AO>;
+ };
+
hwrng: rng@5118 {
compatible = "amlogic,meson-rng";
reg = <0x0 0x5118 0x0 0x4>;
@@ -419,7 +432,7 @@
clock-names = "fixpll_in", "hifipll_in";
};
- sd_emmc: sd@10000 {
+ sd_emmc: mmc@10000 {
compatible = "amlogic,meson-axg-mmc";
reg = <0x0 0x10000 0x0 0x800>;
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
@@ -453,7 +466,6 @@
assigned-clocks = <&clkc_periphs CLKID_USB_BUS>;
assigned-clock-rates = <64000000>;
resets = <&reset RESET_USBCTRL>;
- reset-name = "usb_ctrl";
dr_mode = "otg";
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 6d12b760b90f..e9b22868983d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -25,10 +25,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_A";
- clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
- <&clkc_audio AUD_CLKID_MST_A_SCLK>,
- <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -36,10 +36,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_B";
- clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
- <&clkc_audio AUD_CLKID_MST_B_SCLK>,
- <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -47,10 +47,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_C";
- clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
- <&clkc_audio AUD_CLKID_MST_C_SCLK>,
- <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 9d5eab6595d0..d08c97797010 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -215,6 +215,11 @@
#sound-dai-cells = <0>;
status = "disabled";
+ assigned-clocks = <&clkc CLKID_HDMI_SEL>,
+ <&clkc CLKID_HDMI>;
+ assigned-clock-parents = <&xtal>, <0>;
+ assigned-clock-rates = <0>, <24000000>;
+
/* VPU VENC Input */
hdmi_tx_venc_port: port@0 {
reg = <0>;
@@ -987,7 +992,7 @@
mux {
groups = "spdif_out_h";
function = "spdif_out";
- drive-strength-microamp = <500>;
+ drive-strength-microamp = <3000>;
bias-disable;
};
};
@@ -996,7 +1001,7 @@
mux {
groups = "spdif_out_a11";
function = "spdif_out";
- drive-strength-microamp = <500>;
+ drive-strength-microamp = <3000>;
bias-disable;
};
};
@@ -1005,7 +1010,7 @@
mux {
groups = "spdif_out_a13";
function = "spdif_out";
- drive-strength-microamp = <500>;
+ drive-strength-microamp = <3000>;
bias-disable;
};
};
@@ -1663,9 +1668,28 @@
<250000000>,
<0>; /* Do Nothing */
};
+
+ mipi_analog_dphy: phy {
+ compatible = "amlogic,g12a-mipi-dphy-analog";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
};
};
+ mipi_dphy: phy@44000 {
+ compatible = "amlogic,axg-mipi-dphy";
+ reg = <0x0 0x44000 0x0 0x2000>;
+ clocks = <&clkc CLKID_MIPI_DSI_PHY>;
+ clock-names = "pclk";
+ resets = <&reset RESET_MIPI_DSI_PHY>;
+ reset-names = "phy";
+ phys = <&mipi_analog_dphy>;
+ phy-names = "analog";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
usb3_pcie_phy: phy@46000 {
compatible = "amlogic,g12a-usb3-pcie-phy";
reg = <0x0 0x46000 0x0 0x2000>;
@@ -1722,9 +1746,6 @@
compatible = "amlogic,meson-gx-ao-sysctrl",
"simple-mfd", "syscon";
reg = <0x0 0x0 0x0 0x100>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0x0 0x0 0x100>;
clkc_AO: clock-controller {
compatible = "amlogic,meson-g12a-aoclkc";
@@ -1733,278 +1754,278 @@
clocks = <&xtal>, <&clkc CLKID_CLK81>;
clock-names = "xtal", "mpeg-clk";
};
+ };
- ao_pinctrl: pinctrl {
- compatible = "amlogic,meson-g12a-aobus-pinctrl";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ ao_pinctrl: pinctrl@14 {
+ compatible = "amlogic,meson-g12a-aobus-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio_ao: bank@14 {
+ reg = <0x0 0x14 0x0 0x8>,
+ <0x0 0x1c 0x0 0x8>,
+ <0x0 0x24 0x0 0x14>;
+ reg-names = "mux",
+ "ds",
+ "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&ao_pinctrl 0 0 15>;
+ };
- gpio_ao: bank@14 {
- reg = <0x0 0x14 0x0 0x8>,
- <0x0 0x1c 0x0 0x8>,
- <0x0 0x24 0x0 0x14>;
- reg-names = "mux",
- "ds",
- "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&ao_pinctrl 0 0 15>;
+ i2c_ao_sck_pins: i2c_ao_sck_pins {
+ mux {
+ groups = "i2c_ao_sck";
+ function = "i2c_ao";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- i2c_ao_sck_pins: i2c_ao_sck_pins {
- mux {
- groups = "i2c_ao_sck";
- function = "i2c_ao";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ i2c_ao_sda_pins: i2c_ao_sda {
+ mux {
+ groups = "i2c_ao_sda";
+ function = "i2c_ao";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- i2c_ao_sda_pins: i2c_ao_sda {
- mux {
- groups = "i2c_ao_sda";
- function = "i2c_ao";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ i2c_ao_sck_e_pins: i2c_ao_sck_e {
+ mux {
+ groups = "i2c_ao_sck_e";
+ function = "i2c_ao";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- i2c_ao_sck_e_pins: i2c_ao_sck_e {
- mux {
- groups = "i2c_ao_sck_e";
- function = "i2c_ao";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
- };
-
- i2c_ao_sda_e_pins: i2c_ao_sda_e {
- mux {
- groups = "i2c_ao_sda_e";
- function = "i2c_ao";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ i2c_ao_sda_e_pins: i2c_ao_sda_e {
+ mux {
+ groups = "i2c_ao_sda_e";
+ function = "i2c_ao";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- mclk0_ao_pins: mclk0-ao {
- mux {
- groups = "mclk0_ao";
- function = "mclk0_ao";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ mclk0_ao_pins: mclk0-ao {
+ mux {
+ groups = "mclk0_ao";
+ function = "mclk0_ao";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- tdm_ao_b_din0_pins: tdm-ao-b-din0 {
- mux {
- groups = "tdm_ao_b_din0";
- function = "tdm_ao_b";
- bias-disable;
- };
+ tdm_ao_b_din0_pins: tdm-ao-b-din0 {
+ mux {
+ groups = "tdm_ao_b_din0";
+ function = "tdm_ao_b";
+ bias-disable;
};
+ };
- spdif_ao_out_pins: spdif-ao-out {
- mux {
- groups = "spdif_ao_out";
- function = "spdif_ao_out";
- drive-strength-microamp = <500>;
- bias-disable;
- };
+ spdif_ao_out_pins: spdif-ao-out {
+ mux {
+ groups = "spdif_ao_out";
+ function = "spdif_ao_out";
+ drive-strength-microamp = <3000>;
+ bias-disable;
};
+ };
- tdm_ao_b_din1_pins: tdm-ao-b-din1 {
- mux {
- groups = "tdm_ao_b_din1";
- function = "tdm_ao_b";
- bias-disable;
- };
+ tdm_ao_b_din1_pins: tdm-ao-b-din1 {
+ mux {
+ groups = "tdm_ao_b_din1";
+ function = "tdm_ao_b";
+ bias-disable;
};
+ };
- tdm_ao_b_din2_pins: tdm-ao-b-din2 {
- mux {
- groups = "tdm_ao_b_din2";
- function = "tdm_ao_b";
- bias-disable;
- };
+ tdm_ao_b_din2_pins: tdm-ao-b-din2 {
+ mux {
+ groups = "tdm_ao_b_din2";
+ function = "tdm_ao_b";
+ bias-disable;
};
+ };
- tdm_ao_b_dout0_pins: tdm-ao-b-dout0 {
- mux {
- groups = "tdm_ao_b_dout0";
- function = "tdm_ao_b";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ tdm_ao_b_dout0_pins: tdm-ao-b-dout0 {
+ mux {
+ groups = "tdm_ao_b_dout0";
+ function = "tdm_ao_b";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- tdm_ao_b_dout1_pins: tdm-ao-b-dout1 {
- mux {
- groups = "tdm_ao_b_dout1";
- function = "tdm_ao_b";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ tdm_ao_b_dout1_pins: tdm-ao-b-dout1 {
+ mux {
+ groups = "tdm_ao_b_dout1";
+ function = "tdm_ao_b";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- tdm_ao_b_dout2_pins: tdm-ao-b-dout2 {
- mux {
- groups = "tdm_ao_b_dout2";
- function = "tdm_ao_b";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ tdm_ao_b_dout2_pins: tdm-ao-b-dout2 {
+ mux {
+ groups = "tdm_ao_b_dout2";
+ function = "tdm_ao_b";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- tdm_ao_b_fs_pins: tdm-ao-b-fs {
- mux {
- groups = "tdm_ao_b_fs";
- function = "tdm_ao_b";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ tdm_ao_b_fs_pins: tdm-ao-b-fs {
+ mux {
+ groups = "tdm_ao_b_fs";
+ function = "tdm_ao_b";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- tdm_ao_b_sclk_pins: tdm-ao-b-sclk {
- mux {
- groups = "tdm_ao_b_sclk";
- function = "tdm_ao_b";
- bias-disable;
- drive-strength-microamp = <3000>;
- };
+ tdm_ao_b_sclk_pins: tdm-ao-b-sclk {
+ mux {
+ groups = "tdm_ao_b_sclk";
+ function = "tdm_ao_b";
+ bias-disable;
+ drive-strength-microamp = <3000>;
};
+ };
- tdm_ao_b_slv_fs_pins: tdm-ao-b-slv-fs {
- mux {
- groups = "tdm_ao_b_slv_fs";
- function = "tdm_ao_b";
- bias-disable;
- };
+ tdm_ao_b_slv_fs_pins: tdm-ao-b-slv-fs {
+ mux {
+ groups = "tdm_ao_b_slv_fs";
+ function = "tdm_ao_b";
+ bias-disable;
};
+ };
- tdm_ao_b_slv_sclk_pins: tdm-ao-b-slv-sclk {
- mux {
- groups = "tdm_ao_b_slv_sclk";
- function = "tdm_ao_b";
- bias-disable;
- };
+ tdm_ao_b_slv_sclk_pins: tdm-ao-b-slv-sclk {
+ mux {
+ groups = "tdm_ao_b_slv_sclk";
+ function = "tdm_ao_b";
+ bias-disable;
};
+ };
- uart_ao_a_pins: uart-a-ao {
- mux {
- groups = "uart_ao_a_tx",
- "uart_ao_a_rx";
- function = "uart_ao_a";
- bias-disable;
- };
+ uart_ao_a_pins: uart-a-ao {
+ mux {
+ groups = "uart_ao_a_tx",
+ "uart_ao_a_rx";
+ function = "uart_ao_a";
+ bias-disable;
};
+ };
- uart_ao_a_cts_rts_pins: uart-ao-a-cts-rts {
- mux {
- groups = "uart_ao_a_cts",
- "uart_ao_a_rts";
- function = "uart_ao_a";
- bias-disable;
- };
+ uart_ao_a_cts_rts_pins: uart-ao-a-cts-rts {
+ mux {
+ groups = "uart_ao_a_cts",
+ "uart_ao_a_rts";
+ function = "uart_ao_a";
+ bias-disable;
};
+ };
- uart_ao_b_2_3_pins: uart-ao-b-2-3 {
- mux {
- groups = "uart_ao_b_tx_2",
- "uart_ao_b_rx_3";
- function = "uart_ao_b";
- bias-disable;
- };
+ uart_ao_b_2_3_pins: uart-ao-b-2-3 {
+ mux {
+ groups = "uart_ao_b_tx_2",
+ "uart_ao_b_rx_3";
+ function = "uart_ao_b";
+ bias-disable;
};
+ };
- uart_ao_b_8_9_pins: uart-ao-b-8-9 {
- mux {
- groups = "uart_ao_b_tx_8",
- "uart_ao_b_rx_9";
- function = "uart_ao_b";
- bias-disable;
- };
+ uart_ao_b_8_9_pins: uart-ao-b-8-9 {
+ mux {
+ groups = "uart_ao_b_tx_8",
+ "uart_ao_b_rx_9";
+ function = "uart_ao_b";
+ bias-disable;
};
+ };
- uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
- mux {
- groups = "uart_ao_b_cts",
- "uart_ao_b_rts";
- function = "uart_ao_b";
- bias-disable;
- };
+ uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
+ mux {
+ groups = "uart_ao_b_cts",
+ "uart_ao_b_rts";
+ function = "uart_ao_b";
+ bias-disable;
};
+ };
- pwm_a_e_pins: pwm-a-e {
- mux {
- groups = "pwm_a_e";
- function = "pwm_a_e";
- bias-disable;
- };
+ pwm_a_e_pins: pwm-a-e {
+ mux {
+ groups = "pwm_a_e";
+ function = "pwm_a_e";
+ bias-disable;
};
+ };
- pwm_ao_a_pins: pwm-ao-a {
- mux {
- groups = "pwm_ao_a";
- function = "pwm_ao_a";
- bias-disable;
- };
+ pwm_ao_a_pins: pwm-ao-a {
+ mux {
+ groups = "pwm_ao_a";
+ function = "pwm_ao_a";
+ bias-disable;
};
+ };
- pwm_ao_b_pins: pwm-ao-b {
- mux {
- groups = "pwm_ao_b";
- function = "pwm_ao_b";
- bias-disable;
- };
+ pwm_ao_b_pins: pwm-ao-b {
+ mux {
+ groups = "pwm_ao_b";
+ function = "pwm_ao_b";
+ bias-disable;
};
+ };
- pwm_ao_c_4_pins: pwm-ao-c-4 {
- mux {
- groups = "pwm_ao_c_4";
- function = "pwm_ao_c";
- bias-disable;
- };
+ pwm_ao_c_4_pins: pwm-ao-c-4 {
+ mux {
+ groups = "pwm_ao_c_4";
+ function = "pwm_ao_c";
+ bias-disable;
};
+ };
- pwm_ao_c_6_pins: pwm-ao-c-6 {
- mux {
- groups = "pwm_ao_c_6";
- function = "pwm_ao_c";
- bias-disable;
- };
+ pwm_ao_c_6_pins: pwm-ao-c-6 {
+ mux {
+ groups = "pwm_ao_c_6";
+ function = "pwm_ao_c";
+ bias-disable;
};
+ };
- pwm_ao_d_5_pins: pwm-ao-d-5 {
- mux {
- groups = "pwm_ao_d_5";
- function = "pwm_ao_d";
- bias-disable;
- };
+ pwm_ao_d_5_pins: pwm-ao-d-5 {
+ mux {
+ groups = "pwm_ao_d_5";
+ function = "pwm_ao_d";
+ bias-disable;
};
+ };
- pwm_ao_d_10_pins: pwm-ao-d-10 {
- mux {
- groups = "pwm_ao_d_10";
- function = "pwm_ao_d";
- bias-disable;
- };
+ pwm_ao_d_10_pins: pwm-ao-d-10 {
+ mux {
+ groups = "pwm_ao_d_10";
+ function = "pwm_ao_d";
+ bias-disable;
};
+ };
- pwm_ao_d_e_pins: pwm-ao-d-e {
- mux {
- groups = "pwm_ao_d_e";
- function = "pwm_ao_d";
- };
+ pwm_ao_d_e_pins: pwm-ao-d-e {
+ mux {
+ groups = "pwm_ao_d_e";
+ function = "pwm_ao_d";
};
+ };
- remote_input_ao_pins: remote-input-ao {
- mux {
- groups = "remote_ao_input";
- function = "remote_ao_input";
- bias-disable;
- };
+ remote_input_ao_pins: remote-input-ao {
+ mux {
+ groups = "remote_ao_input";
+ function = "remote_ao_input";
+ bias-disable;
};
};
};
@@ -2152,6 +2173,15 @@
remote-endpoint = <&hdmi_tx_in>;
};
};
+
+ /* DPI output port */
+ dpi_port: port@2 {
+ reg = <2>;
+
+ dpi_out: endpoint {
+ remote-endpoint = <&mipi_dsi_in>;
+ };
+ };
};
gic: interrupt-controller@ffc01000 {
@@ -2189,6 +2219,48 @@
amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
};
+ mipi_dsi: dsi@7000 {
+ compatible = "amlogic,meson-g12a-dw-mipi-dsi";
+ reg = <0x0 0x7000 0x0 0x1000>;
+ resets = <&reset RESET_MIPI_DSI_HOST>;
+ reset-names = "top";
+ clocks = <&clkc CLKID_MIPI_DSI_HOST>,
+ <&clkc CLKID_MIPI_DSI_PXCLK>,
+ <&clkc CLKID_CTS_ENCL>;
+ clock-names = "pclk", "bit", "px";
+ phys = <&mipi_dphy>;
+ phy-names = "dphy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ assigned-clocks = <&clkc CLKID_MIPI_DSI_PXCLK_SEL>,
+ <&clkc CLKID_CTS_ENCL_SEL>,
+ <&clkc CLKID_VCLK2_SEL>;
+ assigned-clock-parents = <&clkc CLKID_GP0_PLL>,
+ <&clkc CLKID_VCLK2_DIV1>,
+ <&clkc CLKID_GP0_PLL>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* VPU VENC Input */
+ mipi_dsi_venc_port: port@0 {
+ reg = <0>;
+
+ mipi_dsi_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ /* DSI Output */
+ mipi_dsi_panel_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
watchdog: watchdog@f0d0 {
compatible = "amlogic,meson-gxbb-wdt";
reg = <0x0 0xf0d0 0x0 0x10>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
index e732df3f3114..664912d1beaa 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
@@ -363,6 +363,10 @@
power-domains = <&pwrc PWRC_G12A_ETH_ID>;
};
+&hdmi_tx {
+ power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
&vpu {
power-domains = <&pwrc PWRC_G12A_VPU_ID>;
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
index 3da7922d83f1..0e239939ade6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
@@ -24,7 +24,6 @@
compatible = "simple-audio-amplifier";
enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
VCC-supply = <&vcc_5v>;
- #sound-dai-cells = <0>;
sound-name-prefix = "10U2";
};
@@ -374,6 +373,7 @@
};
&acodec {
+ AVDD-supply = <&vddao_1v8>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts
new file mode 100644
index 000000000000..003efed529ba
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Neil Armstrong <neil.armstrong@linaro.org>
+ * Copyright 2023 MNT Research GmbH
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-bananapi-cm4.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ model = "MNT Reform 2 with BPI-CM4 Module";
+ compatible = "mntre,reform2-cm4", "bananapi,bpi-cm4", "amlogic,a311d", "amlogic,g12b";
+ chassis-type = "laptop";
+
+ aliases {
+ ethernet0 = &ethmac;
+ i2c0 = &i2c1;
+ i2c1 = &i2c3;
+ };
+
+ hdmi_connector: 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_ao GPIOAO_7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-green {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "MNT-REFORM2-BPI-CM4";
+ audio-widgets = "Headphone", "Headphone Jack",
+ "Speaker", "External Speaker",
+ "Microphone", "Mic Jack";
+ audio-aux-devs = <&tdmout_a>, <&tdmout_b>, <&tdmin_b>;
+ 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",
+ "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",
+ "TDMIN_B IN 1", "TDM_B Capture",
+ "TDMIN_B IN 4", "TDM_B Loopback",
+ "TODDR_A IN 1", "TDMIN_B OUT",
+ "TODDR_B IN 1", "TDMIN_B OUT",
+ "TODDR_C IN 1", "TDMIN_B OUT",
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "External Speaker", "SPK_LP",
+ "External Speaker", "SPK_LN",
+ "External Speaker", "SPK_RP",
+ "External Speaker", "SPK_RN",
+ "LINPUT1", "Mic Jack",
+ "Mic Jack", "MICB";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ 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_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>;
+ };
+ };
+
+ /* Analog Audio */
+ dai-link-7 {
+ sound-dai = <&tdmif_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ mclk-fs = <256>;
+
+ codec {
+ sound-dai = <&wm8960>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-8 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+
+ reg_main_1v8: regulator-main-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&reg_main_3v3>;
+ };
+
+ reg_main_1v2: regulator-main-1v2 {
+ compatible = "regulator-fixed";
+ regulator-name = "1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ vin-supply = <&reg_main_5v>;
+ };
+
+ reg_main_3v3: regulator-main-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_main_5v: regulator-main-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_main_usb: regulator-main-usb {
+ compatible = "regulator-fixed";
+ regulator-name = "USB_PWR";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&reg_main_5v>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm_AO_ab 0 10000 0>;
+ power-supply = <&reg_main_usb>;
+ enable-gpios = <&gpio 58 GPIO_ACTIVE_HIGH>;
+ brightness-levels = <0 32 64 128 160 200 255>;
+ default-brightness-level = <6>;
+ };
+
+ panel {
+ compatible = "innolux,n125hce-gn1";
+ power-supply = <&reg_main_3v3>;
+ backlight = <&backlight>;
+ no-hpd;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&edp_bridge_out>;
+ };
+ };
+ };
+
+ clock_12288: clock_12288 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12288000>;
+ };
+};
+
+&mipi_analog_dphy {
+ status = "okay";
+};
+
+&mipi_dphy {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ assigned-clocks = <&clkc CLKID_GP0_PLL>,
+ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>,
+ <&clkc CLKID_MIPI_DSI_PXCLK>,
+ <&clkc CLKID_CTS_ENCL_SEL>,
+ <&clkc CLKID_VCLK2_SEL>;
+ assigned-clock-parents = <0>,
+ <&clkc CLKID_GP0_PLL>,
+ <0>,
+ <&clkc CLKID_VCLK2_DIV1>,
+ <&clkc CLKID_GP0_PLL>;
+ assigned-clock-rates = <936000000>,
+ <0>,
+ <936000000>,
+ <0>,
+ <0>;
+};
+
+&mipi_dsi_panel_port {
+ mipi_dsi_out: endpoint {
+ remote-endpoint = <&edp_bridge_in>;
+ };
+};
+
+&cecb_AO {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&pwm_AO_ab {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_ao_a_pins>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+
+ edp_bridge: bridge@2c {
+ compatible = "ti,sn65dsi86";
+ reg = <0x2c>;
+ enable-gpios = <&gpio GPIOX_10 GPIO_ACTIVE_HIGH>; // PIN_24 / GPIO8
+ vccio-supply = <&reg_main_1v8>;
+ vpll-supply = <&reg_main_1v8>;
+ vcca-supply = <&reg_main_1v2>;
+ vcc-supply = <&reg_main_1v2>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ edp_bridge_in: endpoint {
+ remote-endpoint = <&mipi_dsi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ edp_bridge_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ wm8960: codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clock_12288>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+ wlf,shared-lrclk;
+ };
+
+ rtc@68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&sd_emmc_b {
+ status = "okay";
+};
+
+&tdmif_a {
+ status = "okay";
+};
+
+&tdmout_a {
+ status = "okay";
+};
+
+&tdmif_b {
+ pinctrl-0 = <&tdm_b_dout0_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, <&tdm_b_din1_pins>;
+ pinctrl-names = "default";
+
+ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>,
+ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>;
+ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+ assigned-clock-rates = <0>, <0>;
+};
+
+&tdmin_b {
+ status = "okay";
+};
+
+&toddr_a {
+ status = "okay";
+};
+
+&toddr_b {
+ status = "okay";
+};
+
+&toddr_c {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
+
+&usb {
+ dr_mode = "host";
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi.dtsi
index 4b8db872bbf3..6a346cb86a53 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi.dtsi
@@ -44,13 +44,6 @@
reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
};
- fan0: pwm-fan {
- compatible = "pwm-fan";
- #cooling-cells = <2>;
- cooling-levels = <0 120 170 220>;
- pwms = <&pwm_cd 1 40000 0>;
- };
-
hdmi-connector {
compatible = "hdmi-connector";
type = "a";
@@ -374,13 +367,6 @@
clock-names = "clkin0";
};
-&pwm_cd {
- status = "okay";
- pinctrl-0 = <&pwm_d_x6_pins>;
- pinctrl-names = "default";
- pwm-gpios = <&gpio GPIOAO_10 GPIO_ACTIVE_HIGH>;
-};
-
&pwm_ef {
status = "okay";
pinctrl-0 = <&pwm_e_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-one.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-one.dts
new file mode 100644
index 000000000000..ecfa1c683dde
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-one.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-dreambox.dtsi"
+
+/ {
+ compatible = "dream,dreambox-one", "amlogic,s922x", "amlogic,g12b";
+ model = "Dreambox One";
+};
+
+&sd_emmc_a {
+ sd-uhs-sdr12;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-two.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-two.dts
new file mode 100644
index 000000000000..df0d71983c3d
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox-two.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-dreambox.dtsi"
+
+/ {
+ compatible = "dream,dreambox-two", "amlogic,s922x", "amlogic,g12b";
+ model = "Dreambox Two";
+};
+
+&sd_emmc_a {
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi
new file mode 100644
index 000000000000..3a24c2411552
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+#include "meson-g12b-w400.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ cvbs-connector {
+ status = "disabled";
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOA_11 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+
+ spdif_dit: audio-codec-1 {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ status = "okay";
+ sound-name-prefix = "DIT";
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "DREAMBOX";
+ audio-aux-devs = <&tdmout_b>;
+ 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",
+ "SPDIFOUT_A IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT_A IN 1", "FRDDR_B OUT 3",
+ "SPDIFOUT_A IN 2", "FRDDR_C OUT 3";
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ 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_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 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
+ };
+
+ /* spdif hdmi or toslink interface */
+ dai-link-4 {
+ sound-dai = <&spdifout_a>;
+
+ codec-0 {
+ sound-dai = <&spdif_dit>;
+ };
+
+ codec-1 {
+ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>;
+ };
+ };
+
+ /* spdif hdmi interface */
+ dai-link-5 {
+ sound-dai = <&spdifout_b>;
+
+ codec {
+ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-6 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&ir {
+ linux,rc-map-name = "rc-dreambox";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddao_1v8>;
+};
+
+&spdifout_a {
+ pinctrl-0 = <&spdif_out_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spdifout_b {
+ status = "okay";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
index d80dd9a3da31..86eb81112232 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
@@ -31,6 +31,30 @@
enable-active-high;
};
+ /* USB hub supports both USB 2.0 and USB 3.0 root hub */
+ usb-hub {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* 2.0 hub on port 1 */
+ hub_2_0: hub@1 {
+ compatible = "usb5e3,610";
+ reg = <1>;
+ peer-hub = <&hub_3_0>;
+ vdd-supply = <&usb_pwr_en>;
+ };
+
+ /* 3.0 hub on port 4 */
+ hub_3_0: hub@2 {
+ compatible = "usb5e3,620";
+ reg = <2>;
+ peer-hub = <&hub_2_0>;
+ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&vcc_5v>;
+ };
+ };
+
sound {
compatible = "amlogic,axg-sound-card";
model = "ODROID-N2";
@@ -234,18 +258,6 @@
"PIN_3", /* GPIOX_17 */
"PIN_5", /* GPIOX_18 */
"PIN_36"; /* GPIOX_19 */
- /*
- * 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-hog {
- gpio-hog;
- gpios = <GPIOH_4 GPIO_ACTIVE_HIGH>;
- output-high;
- line-name = "usb-hub-reset";
- };
};
&i2c3 {
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
index 890f5bfebb03..8445701100d0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
@@ -33,6 +33,13 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
+ fan0: pwm-fan {
+ compatible = "pwm-fan";
+ #cooling-cells = <2>;
+ cooling-levels = <0 64 128 192 255>;
+ pwms = <&pwm_AO_ab 0 40000 0>;
+ };
+
gpio-keys-polled {
compatible = "gpio-keys-polled";
poll-interval = <100>;
@@ -286,6 +293,23 @@
clock-latency = <50000>;
};
+&cpu_thermal {
+ trips {
+ cpu_active: cpu-active {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map2 {
+ trip = <&cpu_active>;
+ cooling-device = <&fan0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
&frddr_a {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index c431986e6a33..c37cc6b036cd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -408,6 +408,6 @@
compatible = "usb5e3,610";
reg = <1>;
vdd-supply = <&p5v0>;
- reset-gpio = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
};
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 12ef6e81c8bd..ed00e67e6923 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -311,10 +311,16 @@
<&reset RESET_HDMI_SYSTEM_RESET>,
<&reset RESET_HDMI_TX>;
reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
- clocks = <&clkc CLKID_HDMI_PCLK>,
- <&clkc CLKID_CLK81>,
+ clocks = <&clkc CLKID_HDMI>,
+ <&clkc CLKID_HDMI_PCLK>,
<&clkc CLKID_GCLK_VENCI_INT0>;
clock-names = "isfr", "iahb", "venci";
+ power-domains = <&pwrc PWRC_GXBB_VPU_ID>;
+
+ assigned-clocks = <&clkc CLKID_HDMI_SEL>,
+ <&clkc CLKID_HDMI>;
+ assigned-clock-parents = <&xtal>, <0>;
+ assigned-clock-rates = <0>, <24000000>;
};
&sysctrl {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts
new file mode 100644
index 000000000000..de996e930b82
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxl-s905x-p212.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/sound/meson-aiu.h>
+
+/ {
+ compatible = "osmc,vero4k", "amlogic,s905x", "amlogic,meson-gxl";
+ model = "OSMC Vero 4K";
+
+ reserved-memory {
+ /* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+ secmon_reserved_bl32: secmon@5300000 {
+ reg = <0x0 0x05300000 0x0 0x2000000>;
+ no-map;
+ };
+ };
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ poll-interval = <20>;
+
+ button {
+ label = "power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-standby {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio GPIODV_24 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ panic-indicator;
+ };
+ };
+
+ dio2133: analog-amplifier {
+ compatible = "simple-audio-amplifier";
+ sound-name-prefix = "AU2";
+ VCC-supply = <&hdmi_5v>;
+ enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>;
+ };
+
+ spdif_dit: audio-codec-0 {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ sound-name-prefix = "DIT";
+ };
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "amlogic,gx-sound-card";
+ model = "VERO4K";
+ audio-aux-devs = <&dio2133>;
+ audio-widgets = "Line", "Lineout";
+ audio-routing = "AU2 INL", "ACODEC LOLP",
+ "AU2 INR", "ACODEC LORP",
+ "AU2 INL", "ACODEC LOLN",
+ "AU2 INR", "ACODEC LORN",
+ "Lineout", "AU2 OUTL",
+ "Lineout", "AU2 OUTR";
+ assigned-clocks = <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>,
+ <&clkc CLKID_MPLL2>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ dai-link-0 {
+ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+ dai-format = "i2s";
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+ };
+
+ codec-1 {
+ sound-dai = <&aiu AIU_ACODEC CTRL_I2S>;
+ };
+ };
+
+ dai-link-3 {
+ sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
+
+ codec-0 {
+ sound-dai = <&spdif_dit>;
+ };
+ };
+
+ dai-link-4 {
+ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+ codec-0 {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+
+ dai-link-5 {
+ sound-dai = <&aiu AIU_ACODEC CTRL_OUT>;
+
+ codec-0 {
+ sound-dai = <&acodec>;
+ };
+ };
+ };
+};
+
+&acodec {
+ AVDD-supply = <&vddio_ao18>;
+ status = "okay";
+};
+
+&aiu {
+ status = "okay";
+ pinctrl-0 = <&spdif_out_h_pins>;
+ pinctrl-names = "default";
+};
+
+&cec_AO {
+ status = "okay";
+ pinctrl-0 = <&ao_cec_pins>;
+ pinctrl-names = "default";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
+
+&ethmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+ pinctrl-names = "default";
+ hdmi-supply = <&hdmi_5v>;
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&internal_phy {
+ pinctrl-0 = <&eth_link_led_pins>, <&eth_act_led_pins>;
+ pinctrl-names = "default";
+};
+
+/* This UART is brought out to the DB9 connector */
+&uart_AO {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 17bcfa4702e1..f58d1790de1c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -323,10 +323,16 @@
<&reset RESET_HDMI_SYSTEM_RESET>,
<&reset RESET_HDMI_TX>;
reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
- clocks = <&clkc CLKID_HDMI_PCLK>,
- <&clkc CLKID_CLK81>,
+ clocks = <&clkc CLKID_HDMI>,
+ <&clkc CLKID_HDMI_PCLK>,
<&clkc CLKID_GCLK_VENCI_INT0>;
clock-names = "isfr", "iahb", "venci";
+ power-domains = <&pwrc PWRC_GXBB_VPU_ID>;
+
+ assigned-clocks = <&clkc CLKID_HDMI_SEL>,
+ <&clkc CLKID_HDMI>;
+ assigned-clock-parents = <&xtal>, <0>;
+ assigned-clock-rates = <0>, <24000000>;
};
&sysctrl {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxlx-s905l-p271.dts b/arch/arm64/boot/dts/amlogic/meson-gxlx-s905l-p271.dts
new file mode 100644
index 000000000000..1221f4545130
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxlx-s905l-p271.dts
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxl-s905x.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+ compatible = "amlogic,p271", "amlogic,s905l", "amlogic,meson-gxlx";
+ model = "Amlogic Meson GXLX (S905L) P271 Development Board";
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ sound {
+ model = "P271";
+ };
+};
+
+&apb {
+ mali: gpu@c0000 {
+ /* Mali 450-MP2 */
+ interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gp", "gpmmu", "pp", "pmu",
+ "pp0", "ppmmu0", "pp1", "ppmmu1";
+ };
+};
+
+&saradc {
+ compatible = "amlogic,meson-gxlx-saradc", "amlogic,meson-saradc";
+};
+
+&usb {
+ dr_mode = "host";
+};
+
+&vdec {
+ compatible = "amlogic,gxlx-vdec", "amlogic,gx-vdec";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso
new file mode 100644
index 000000000000..a41b4e619580
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/g12a-clkc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/amlogic,meson-g12a-gpio-intc.h>
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Enable Khadas TS050 DSI Panel + Touch Controller
+ * on Khadas VIM3 (A311D) and VIM3L (S905D3)
+ */
+
+&{/} {
+ panel_backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm_AO_cd 0 25000 0>;
+ brightness-levels = <0 255>;
+ num-interpolated-steps = <255>;
+ default-brightness-level = <200>;
+ };
+};
+
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ touch-controller@38 {
+ compatible = "edt,edt-ft5206";
+ reg = <0x38>;
+ interrupt-parent = <&gpio_intc>;
+ interrupts = <IRQID_GPIOA_5 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio_expander 6 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <1080>;
+ touchscreen-size-y = <1920>;
+ status = "okay";
+ };
+};
+
+&mipi_dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ assigned-clocks = <&clkc CLKID_GP0_PLL>,
+ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>,
+ <&clkc CLKID_MIPI_DSI_PXCLK>,
+ <&clkc CLKID_CTS_ENCL_SEL>,
+ <&clkc CLKID_VCLK2_SEL>;
+ assigned-clock-parents = <0>,
+ <&clkc CLKID_GP0_PLL>,
+ <0>,
+ <&clkc CLKID_VCLK2_DIV1>,
+ <&clkc CLKID_GP0_PLL>;
+ assigned-clock-rates = <960000000>,
+ <0>,
+ <960000000>,
+ <0>,
+ <0>;
+
+ panel@0 {
+ compatible = "khadas,ts050";
+ reset-gpios = <&gpio_expander 0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&gpio_expander 1 GPIO_ACTIVE_HIGH>;
+ power-supply = <&vcc_3v3>;
+ backlight = <&panel_backlight>;
+ reg = <0>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ mipi_out_panel: endpoint {
+ remote-endpoint = <&mipi_in_panel>;
+ };
+ };
+ };
+};
+
+&mipi_analog_dphy {
+ status = "okay";
+};
+
+&mipi_dphy {
+ status = "okay";
+};
+
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_c_6_pins>, <&pwm_ao_d_e_pins>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
index ce90b35686a2..b686eacb9662 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -65,10 +65,15 @@
#clock-cells = <0>;
};
- pwrc: power-controller {
- compatible = "amlogic,meson-s4-pwrc";
- #power-domain-cells = <1>;
- status = "okay";
+ firmware {
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gxbb-sm";
+
+ pwrc: power-controller {
+ compatible = "amlogic,meson-s4-pwrc";
+ #power-domain-cells = <1>;
+ };
+ };
};
soc {
@@ -307,6 +312,160 @@
};
};
+ pwm_a_pins1: pwm-a-pins1 {
+ mux {
+ groups = "pwm_a_d";
+ function = "pwm_a";
+ };
+ };
+
+ pwm_a_pins2: pwm-a-pins2 {
+ mux {
+ groups = "pwm_a_x";
+ function = "pwm_a";
+ };
+ };
+
+ pwm_b_pins1: pwm-b-pins1 {
+ mux {
+ groups = "pwm_b_d";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_b_pins2: pwm-b-pins2 {
+ mux {
+ groups = "pwm_b_x";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_c_pins1: pwm-c-pins1 {
+ mux {
+ groups = "pwm_c_d";
+ function = "pwm_c";
+ };
+ };
+
+ pwm_c_pins2: pwm-c-pins2 {
+ mux {
+ groups = "pwm_c_x";
+ function = "pwm_c";
+ };
+ };
+
+ pwm_d_pins1: pwm-d-pins1 {
+ mux {
+ groups = "pwm_d_d";
+ function = "pwm_d";
+ };
+ };
+
+ pwm_d_pins2: pwm-d-pins2 {
+ mux {
+ groups = "pwm_d_h";
+ function = "pwm_d";
+ };
+ };
+
+ pwm_e_pins1: pwm-e-pins1 {
+ mux {
+ groups = "pwm_e_x";
+ function = "pwm_e";
+ };
+ };
+
+ pwm_e_pins2: pwm-e-pins2 {
+ mux {
+ groups = "pwm_e_z";
+ function = "pwm_e";
+ };
+ };
+
+ pwm_f_pins1: pwm-f-pins1 {
+ mux {
+ groups = "pwm_f_x";
+ function = "pwm_f";
+ };
+ };
+
+ pwm_f_pins2: pwm-f-pins2 {
+ mux {
+ groups = "pwm_f_z";
+ function = "pwm_f";
+ };
+ };
+
+ pwm_g_pins1: pwm-g-pins1 {
+ mux {
+ groups = "pwm_g_d";
+ function = "pwm_g";
+ };
+ };
+
+ pwm_g_pins2: pwm-g-pins2 {
+ mux {
+ groups = "pwm_g_z";
+ function = "pwm_g";
+ };
+ };
+
+ pwm_h_pins: pwm-h-pins {
+ mux {
+ groups = "pwm_h";
+ function = "pwm_h";
+ };
+ };
+
+ pwm_i_pins1: pwm-i-pins1 {
+ mux {
+ groups = "pwm_i_d";
+ function = "pwm_i";
+ };
+ };
+
+ pwm_i_pins2: pwm-i-pins2 {
+ mux {
+ groups = "pwm_i_h";
+ function = "pwm_i";
+ };
+ };
+
+ pwm_j_pins: pwm-j-pins {
+ mux {
+ groups = "pwm_j";
+ function = "pwm_j";
+ };
+ };
+
+ pwm_a_hiz_pins: pwm-a-hiz-pins {
+ mux {
+ groups = "pwm_a_hiz";
+ function = "pwm_a_hiz";
+ };
+ };
+
+ pwm_b_hiz_pins: pwm-b-hiz-pins {
+ mux {
+ groups = "pwm_b_hiz";
+ function = "pwm_b_hiz";
+ };
+ };
+
+ pwm_c_hiz_pins: pwm-c-hiz-pins {
+ mux {
+ groups = "pwm_c_hiz";
+ function = "pwm_c_hiz";
+ };
+ };
+
+ pwm_g_hiz_pins: pwm-g-hiz-pins {
+ mux {
+ groups = "pwm_g_hiz";
+ function = "pwm_g_hiz";
+ };
+ };
+
spicc0_pins_x: spicc0-pins_x {
mux {
groups = "spi_a_mosi_x",
@@ -394,6 +553,51 @@
status = "disabled";
};
+ pwm_ab: pwm@58000 {
+ compatible = "amlogic,meson-s4-pwm";
+ reg = <0x0 0x58000 0x0 0x24>;
+ clocks = <&clkc_periphs CLKID_PWM_A>,
+ <&clkc_periphs CLKID_PWM_B>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_cd: pwm@5a000 {
+ compatible = "amlogic,meson-s4-pwm";
+ reg = <0x0 0x5a000 0x0 0x24>;
+ clocks = <&clkc_periphs CLKID_PWM_C>,
+ <&clkc_periphs CLKID_PWM_D>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_ef: pwm@5c000 {
+ compatible = "amlogic,meson-s4-pwm";
+ reg = <0x0 0x5c000 0x0 0x24>;
+ clocks = <&clkc_periphs CLKID_PWM_E>,
+ <&clkc_periphs CLKID_PWM_F>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_gh: pwm@5e000 {
+ compatible = "amlogic,meson-s4-pwm";
+ reg = <0x0 0x5e000 0x0 0x24>;
+ clocks = <&clkc_periphs CLKID_PWM_G>,
+ <&clkc_periphs CLKID_PWM_H>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_ij: pwm@60000 {
+ compatible = "amlogic,meson-s4-pwm";
+ reg = <0x0 0x60000 0x0 0x24>;
+ clocks = <&clkc_periphs CLKID_PWM_I>,
+ <&clkc_periphs CLKID_PWM_J>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
i2c0: i2c@66000 {
compatible = "amlogic,meson-axg-i2c";
reg = <0x0 0x66000 0x0 0x20>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
index 643f94d9d08e..97e4b52066dc 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
@@ -17,10 +17,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_A";
- clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
- <&clkc_audio AUD_CLKID_MST_A_SCLK>,
- <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -28,10 +28,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_B";
- clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
- <&clkc_audio AUD_CLKID_MST_B_SCLK>,
- <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -39,10 +39,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_C";
- clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
- <&clkc_audio AUD_CLKID_MST_C_SCLK>,
- <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -275,8 +275,7 @@
};
tdmin_a: audio-controller@300 {
- compatible = "amlogic,sm1-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,sm1-tdmin";
reg = <0x0 0x300 0x0 0x40>;
sound-name-prefix = "TDMIN_A";
resets = <&clkc_audio AUD_RESET_TDMIN_A>;
@@ -291,8 +290,7 @@
};
tdmin_b: audio-controller@340 {
- compatible = "amlogic,sm1-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,sm1-tdmin";
reg = <0x0 0x340 0x0 0x40>;
sound-name-prefix = "TDMIN_B";
resets = <&clkc_audio AUD_RESET_TDMIN_B>;
@@ -307,8 +305,7 @@
};
tdmin_c: audio-controller@380 {
- compatible = "amlogic,sm1-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,sm1-tdmin";
reg = <0x0 0x380 0x0 0x40>;
sound-name-prefix = "TDMIN_C";
resets = <&clkc_audio AUD_RESET_TDMIN_C>;
@@ -323,8 +320,7 @@
};
tdmin_lb: audio-controller@3c0 {
- compatible = "amlogic,sm1-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,sm1-tdmin";
reg = <0x0 0x3c0 0x0 0x40>;
sound-name-prefix = "TDMIN_LB";
resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
@@ -339,7 +335,7 @@
};
spdifin: audio-controller@400 {
- compatible = "amlogic,g12a-spdifin",
+ compatible = "amlogic,sm1-spdifin",
"amlogic,axg-spdifin";
reg = <0x0 0x400 0x0 0x30>;
#sound-dai-cells = <0>;
@@ -353,7 +349,7 @@
};
spdifout_a: audio-controller@480 {
- compatible = "amlogic,g12a-spdifout",
+ compatible = "amlogic,sm1-spdifout",
"amlogic,axg-spdifout";
reg = <0x0 0x480 0x0 0x50>;
#sound-dai-cells = <0>;
@@ -518,6 +514,10 @@
"amlogic,meson-gpio-intc";
};
+&hdmi_tx {
+ power-domains = <&pwrc PWRC_SM1_VPU_ID>;
+};
+
&pcie {
power-domains = <&pwrc PWRC_SM1_PCIE_ID>;
};
diff --git a/arch/arm64/boot/dts/apm/apm-merlin.dts b/arch/arm64/boot/dts/apm/apm-merlin.dts
index 2e8069002ec1..b1160780a2a6 100644
--- a/arch/arm64/boot/dts/apm/apm-merlin.dts
+++ b/arch/arm64/boot/dts/apm/apm-merlin.dts
@@ -15,7 +15,7 @@
chosen { };
- memory {
+ memory@100000000 {
device_type = "memory";
reg = < 0x1 0x00000000 0x0 0x80000000 >;
};
@@ -32,7 +32,7 @@
};
poweroff_mbox: poweroff_mbox@10548000 {
- compatible = "syscon";
+ compatible = "apm,merlin-poweroff-mailbox", "syscon";
reg = <0x0 0x10548000 0x0 0x30>;
};
diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts
index 033e10e12b18..2ef658796746 100644
--- a/arch/arm64/boot/dts/apm/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm/apm-mustang.dts
@@ -15,7 +15,7 @@
chosen { };
- memory {
+ memory@100000000 {
device_type = "memory";
reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
};
@@ -32,7 +32,7 @@
};
poweroff_mbox: poweroff_mbox@10548000 {
- compatible = "syscon";
+ compatible = "apm,mustang-poweroff-mailbox", "syscon";
reg = <0x0 0x10548000 0x0 0x30>;
};
diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
index 65ebac3082e2..ea5721ea02f0 100644
--- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -211,6 +211,13 @@
};
};
+ refclk: refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <1>;
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk";
+ };
+
pmu {
compatible = "arm,armv8-pmuv3";
interrupts = <1 12 0xff04>;
@@ -236,13 +243,6 @@
#size-cells = <2>;
ranges;
- refclk: refclk {
- compatible = "fixed-clock";
- #clock-cells = <1>;
- clock-frequency = <100000000>;
- clock-output-names = "refclk";
- };
-
pmdpll: pmdpll@170000f0 {
compatible = "apm,xgene-pcppll-v2-clock";
#clock-cells = <1>;
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index 988928c60f15..532401bc9c66 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -112,6 +112,13 @@
interrupts = <1 9 0xf04>; /* GIC Maintenence IRQ */
};
+ refclk: refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <1>;
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk";
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 0 0xff08>, /* Secure Phys IRQ */
@@ -122,7 +129,7 @@
};
pmu {
- compatible = "apm,potenza-pmu", "arm,armv8-pmuv3";
+ compatible = "apm,potenza-pmu";
interrupts = <1 12 0xff04>;
};
@@ -137,12 +144,6 @@
#address-cells = <2>;
#size-cells = <2>;
ranges;
- refclk: refclk {
- compatible = "fixed-clock";
- #clock-cells = <1>;
- clock-frequency = <100000000>;
- clock-output-names = "refclk";
- };
pcppll: pcppll@17000100 {
compatible = "apm,xgene-pcppll-clock";
diff --git a/arch/arm64/boot/dts/arm/corstone1000-fvp.dts b/arch/arm64/boot/dts/arm/corstone1000-fvp.dts
index 901a7fc83307..abd013562995 100644
--- a/arch/arm64/boot/dts/arm/corstone1000-fvp.dts
+++ b/arch/arm64/boot/dts/arm/corstone1000-fvp.dts
@@ -21,7 +21,7 @@
reg-io-width = <2>;
};
- vmmc_v3_3d: fixed_v3_3d {
+ vmmc_v3_3d: regulator-vmmc {
compatible = "regulator-fixed";
regulator-name = "vmmc_supply";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/arm/corstone1000.dtsi b/arch/arm64/boot/dts/arm/corstone1000.dtsi
index 6ad7829f9e28..bb9b96fb5314 100644
--- a/arch/arm64/boot/dts/arm/corstone1000.dtsi
+++ b/arch/arm64/boot/dts/arm/corstone1000.dtsi
@@ -60,14 +60,14 @@
cache-sets = <1024>;
};
- refclk100mhz: refclk100mhz {
+ refclk100mhz: clock-100000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "apb_pclk";
};
- smbclk: refclk24mhzx2 {
+ smbclk: clock-48000000 {
/* Reference 24MHz clock x 2 */
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -83,7 +83,7 @@
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
};
- uartclk: uartclk {
+ uartclk: clock-50000000 {
/* UART clock - 50MHz */
compatible = "fixed-clock";
#clock-cells = <0>;
diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi
index 7b41537731a6..93f1e7c026b8 100644
--- a/arch/arm64/boot/dts/arm/foundation-v8.dtsi
+++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi
@@ -99,21 +99,21 @@
timeout-sec = <30>;
};
- v2m_clk24mhz: clk24mhz {
+ v2m_clk24mhz: clock-24000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "v2m:clk24mhz";
};
- v2m_refclk1mhz: refclk1mhz {
+ v2m_refclk1mhz: clock-1000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000>;
clock-output-names = "v2m:refclk1mhz";
};
- v2m_refclk32khz: refclk32khz {
+ v2m_refclk32khz: clock-32768 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/arm/fvp-base-revc.dts b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
index 60472d65a355..85f1c15cc65d 100644
--- a/arch/arm64/boot/dts/arm/fvp-base-revc.dts
+++ b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
@@ -243,6 +243,7 @@
iommu-map = <0x0 &smmu 0x0 0x10000>;
dma-coherent;
+ ats-supported;
};
smmu: iommu@2b400000 {
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index b897f5542c0a..055764d0b9e5 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -663,7 +663,6 @@
dma-coherent;
/* The SMMU is only really of interest to bare-metal hypervisors */
/* iommus = <&smmu_gpu 0>; */
- status = "disabled";
};
sram: sram@2e000000 {
@@ -773,14 +772,14 @@
};
};
- big_cluster_thermal_zone: big-cluster-thermal {
+ big_cluster_thermal_zone: big-cl-thermal {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 21>;
status = "disabled";
};
- little_cluster_thermal_zone: little-cluster-thermal {
+ little_cluster_thermal_zone: little-cl-thermal {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 22>;
diff --git a/arch/arm64/boot/dts/arm/juno-clocks.dtsi b/arch/arm64/boot/dts/arm/juno-clocks.dtsi
index 2870b5eeb198..6d7d88e9591a 100644
--- a/arch/arm64/boot/dts/arm/juno-clocks.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-clocks.dtsi
@@ -8,35 +8,35 @@
*/
/ {
/* SoC fixed clocks */
- soc_uartclk: refclk7372800hz {
+ soc_uartclk: clock-7372800 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <7372800>;
clock-output-names = "juno:uartclk";
};
- soc_usb48mhz: clk48mhz {
+ soc_usb48mhz: clock-48000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <48000000>;
clock-output-names = "clk48mhz";
};
- soc_smc50mhz: clk50mhz {
+ soc_smc50mhz: clock-50000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
clock-output-names = "smc_clk";
};
- soc_refclk100mhz: refclk100mhz {
+ soc_refclk100mhz: clock-100000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "apb_pclk";
};
- soc_faxiclk: refclk400mhz {
+ soc_faxiclk: clock-400000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <400000000>;
diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index be42932f7e21..ffa4ba4f1fbc 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -8,35 +8,35 @@
*/
/ {
- mb_clk24mhz: clk24mhz {
+ mb_clk24mhz: clock-24000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "juno_mb:clk24mhz";
};
- mb_clk25mhz: clk25mhz {
+ mb_clk25mhz: clock-25000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
clock-output-names = "juno_mb:clk25mhz";
};
- v2m_refclk1mhz: refclk1mhz {
+ v2m_refclk1mhz: clock-1000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000>;
clock-output-names = "juno_mb:refclk1mhz";
};
- v2m_refclk32khz: refclk32khz {
+ v2m_refclk32khz: clock-32768 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
clock-output-names = "juno_mb:refclk32khz";
};
- mb_fixed_3v3: mcc-sb-3v3 {
+ mb_fixed_3v3: regulator-3v3 {
compatible = "regulator-fixed";
regulator-name = "MCC_SB_3V3";
regulator-min-microvolt = <3300000>;
@@ -158,7 +158,8 @@
};
apbregs@10000 {
- compatible = "syscon", "simple-mfd";
+ compatible = "arm,juno-fpga-apb-regs",
+ "syscon", "simple-mfd";
reg = <0x010000 0x1000>;
ranges = <0x0 0x10000 0x1000>;
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/arm/juno-scmi.dtsi b/arch/arm64/boot/dts/arm/juno-scmi.dtsi
index 31929e2377d8..f38c5b6ef657 100644
--- a/arch/arm64/boot/dts/arm/juno-scmi.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-scmi.dtsi
@@ -84,11 +84,11 @@
thermal-sensors = <&scmi_sensors0 3>;
};
- big-cluster-thermal {
+ big-cl-thermal {
thermal-sensors = <&scmi_sensors0 21>;
};
- little-cluster-thermal {
+ little-cl-thermal {
thermal-sensors = <&scmi_sensors0 22>;
};
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
index ba8beef3fe99..66b1b74d27dc 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
@@ -8,28 +8,28 @@
* VEMotherBoard.lisa
*/
/ {
- v2m_clk24mhz: clk24mhz {
+ v2m_clk24mhz: clock-24000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "v2m:clk24mhz";
};
- v2m_refclk1mhz: refclk1mhz {
+ v2m_refclk1mhz: clock-1000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000>;
clock-output-names = "v2m:refclk1mhz";
};
- v2m_refclk32khz: refclk32khz {
+ v2m_refclk32khz: clock-32768 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
clock-output-names = "v2m:refclk32khz";
};
- v2m_fixed_3v3: v2m-3v3 {
+ v2m_fixed_3v3: regulator-3v3 {
compatible = "regulator-fixed";
regulator-name = "3V3";
regulator-min-microvolt = <3300000>;
@@ -41,7 +41,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- v2m_oscclk1: oscclk1 {
+ v2m_oscclk1: clock-controller {
/* CLCD clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
index 8db4243a4947..a0e1fa83eafa 100644
--- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
+++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
@@ -102,7 +102,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -111,7 +111,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
- smbclk: smclk {
+ smbclk: clock-controller {
/* SMC clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 4>;
@@ -120,7 +120,7 @@
clock-output-names = "smclk";
};
- volt-vio {
+ regulator-vio {
/* VIO to expansion board above */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 0>;
@@ -130,7 +130,7 @@
regulator-always-on;
};
- volt-12v {
+ regulator-12v {
/* 12V from power connector J6 */
compatible = "arm,vexpress-volt";
arm,vexpress-sysreg,func = <2 1>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
index e01cf4f54077..8b924812322c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
@@ -594,6 +594,7 @@
reg-names = "nand", "nand-int-base";
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "nand_ctlrdy";
+ brcm,wp-not-connected;
status = "disabled";
nandcs: nand@0 {
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
index 030ffa5364fb..e5b37643296b 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
@@ -34,7 +34,6 @@
};
&nand_controller {
- brcm,wp-not-connected;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
index dec5a110f1e8..f43cfe66b6af 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
@@ -50,7 +50,7 @@
bootargs = "earlycon=uart8250,mmio32,0x66130000";
};
- memory {
+ memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
};
diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts
index 1d314f17bbdd..c50df1d02797 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts
@@ -47,7 +47,7 @@
bootargs = "earlycon=uart8250,mmio32,0x66130000";
};
- memory {
+ memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0x00000001 0x00000000>;
};
diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
index 896d1f33b5b6..cfd9fd23a1c2 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
@@ -102,7 +102,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a57-pmu";
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
index d8516ec0dae7..857fa427e195 100644
--- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
@@ -142,7 +142,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a72-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
index 8ad31dee11a3..cc860a80af51 100644
--- a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
+++ b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
@@ -361,24 +361,24 @@
};
pmu {
- compatible = "cavium,thunder-pmu", "arm,armv8-pmuv3";
+ compatible = "cavium,thunder-pmu";
interrupts = <1 7 4>;
};
+ refclk50mhz: refclk50mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ clock-output-names = "refclk50mhz";
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
- refclk50mhz: refclk50mhz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <50000000>;
- clock-output-names = "refclk50mhz";
- };
-
- gic0: interrupt-controller@8010,00000000 {
+ gic0: interrupt-controller@801000000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
#address-cells = <2>;
@@ -397,7 +397,7 @@
};
};
- uaa0: serial@87e0,24000000 {
+ uaa0: serial@87e024000000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x87e0 0x24000000 0x0 0x1000>;
interrupts = <1 21 4>;
@@ -405,7 +405,7 @@
clock-names = "apb_pclk";
};
- uaa1: serial@87e0,25000000 {
+ uaa1: serial@87e025000000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x87e0 0x25000000 0x0 0x1000>;
interrupts = <1 22 4>;
diff --git a/arch/arm64/boot/dts/cavium/thunder2-99xx.dts b/arch/arm64/boot/dts/cavium/thunder2-99xx.dts
index d005e1e79c3d..89fc4107a0c4 100644
--- a/arch/arm64/boot/dts/cavium/thunder2-99xx.dts
+++ b/arch/arm64/boot/dts/cavium/thunder2-99xx.dts
@@ -14,7 +14,7 @@
model = "Cavium ThunderX2 CN99XX";
compatible = "cavium,thunderx2-cn9900", "brcm,vulcan-soc";
- memory {
+ memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0x0 0x80000000>, /* 2G @ 2G */
<0x00000008 0x80000000 0x0 0x80000000>; /* 2G @ 34G */
diff --git a/arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi b/arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi
index 3419bd252696..6dfe78a7d4ab 100644
--- a/arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi
+++ b/arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi
@@ -83,7 +83,7 @@
};
pmu {
- compatible = "brcm,vulcan-pmu", "arm,armv8-pmuv3";
+ compatible = "brcm,vulcan-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; /* PMU overflow */
};
@@ -103,7 +103,6 @@
/* ECAM at 0x3000_0000 - 0x4000_0000 */
reg = <0x0 0x30000000 0x0 0x10000000>;
- reg-names = "PCI ECAM";
/*
* PCI ranges:
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 7fbbec04bff0..0b9053b9b2b5 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1468,6 +1468,7 @@
pinctrl-names = "default";
pinctrl-0 = <&spi0_bus>;
num-cs = <1>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -1487,6 +1488,7 @@
pinctrl-names = "default";
pinctrl-0 = <&spi1_bus>;
num-cs = <1>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1506,6 +1508,7 @@
pinctrl-names = "default";
pinctrl-0 = <&spi2_bus>;
num-cs = <1>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1525,6 +1528,7 @@
pinctrl-names = "default";
pinctrl-0 = <&spi3_bus>;
num-cs = <1>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1544,6 +1548,7 @@
pinctrl-names = "default";
pinctrl-0 = <&spi4_bus>;
num-cs = <1>;
+ fifo-depth = <64>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index 2ba67c3d0681..f1c8b4613cbc 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -93,6 +93,8 @@
compatible = "arm,cortex-a55";
reg = <0x0>;
enable-method = "psci";
+ clocks = <&cmu_cpucl0 CLK_CLUSTER0_SCLK>;
+ clock-names = "cluster0_clk";
};
cpu1: cpu@1 {
device_type = "cpu";
@@ -117,6 +119,8 @@
compatible = "arm,cortex-a55";
reg = <0x100>;
enable-method = "psci";
+ clocks = <&cmu_cpucl1 CLK_CLUSTER1_SCLK>;
+ clock-names = "cluster1_clk";
};
cpu5: cpu@101 {
device_type = "cpu";
@@ -254,6 +258,28 @@
"dout_peri_uart", "dout_peri_ip";
};
+ cmu_cpucl1: clock-controller@10800000 {
+ compatible = "samsung,exynos850-cmu-cpucl1";
+ reg = <0x10800000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL1_SWITCH>,
+ <&cmu_top CLK_DOUT_CPUCL1_DBG>;
+ clock-names = "oscclk", "dout_cpucl1_switch",
+ "dout_cpucl1_dbg";
+ };
+
+ cmu_cpucl0: clock-controller@10900000 {
+ compatible = "samsung,exynos850-cmu-cpucl0";
+ reg = <0x10900000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL0_SWITCH>,
+ <&cmu_top CLK_DOUT_CPUCL0_DBG>;
+ clock-names = "oscclk", "dout_cpucl0_switch",
+ "dout_cpucl0_dbg";
+ };
+
cmu_g3d: clock-controller@11400000 {
compatible = "samsung,exynos850-cmu-g3d";
reg = <0x11400000 0x8000>;
@@ -390,6 +416,14 @@
interrupts = <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>;
};
+ trng: rng@12081400 {
+ compatible = "samsung,exynos850-trng";
+ reg = <0x12081400 0x100>;
+ clocks = <&cmu_core CLK_GOUT_SSS_ACLK>,
+ <&cmu_core CLK_GOUT_SSS_PCLK>;
+ clock-names = "secss", "pclk";
+ };
+
pinctrl_hsi: pinctrl@13430000 {
compatible = "samsung,exynos850-pinctrl";
reg = <0x13430000 0x1000>;
diff --git a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
index c871a2f49fda..0248329da49a 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
@@ -435,6 +435,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -526,6 +527,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -617,6 +619,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -708,6 +711,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -799,6 +803,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -890,6 +895,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -981,6 +987,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <256>;
status = "disabled";
};
@@ -1072,6 +1079,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1163,6 +1171,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1254,6 +1263,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1345,6 +1355,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
@@ -1434,6 +1445,7 @@
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ fifo-depth = <64>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index 6ccade2c8cb4..387fb779bd29 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -29,8 +29,8 @@
gpio-keys {
compatible = "gpio-keys";
- pinctrl-names = "default";
pinctrl-0 = <&key_voldown>, <&key_volup>, <&key_power>;
+ pinctrl-names = "default";
button-vol-down {
label = "KEY_VOLUMEDOWN";
@@ -53,6 +53,21 @@
wakeup-source;
};
};
+
+ /* TODO: Remove this once PMIC is implemented */
+ reg_placeholder: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "placeholder_reg";
+ };
+
+ /* TODO: Remove this once S2MPG11 slave PMIC is implemented */
+ ufs_0_fixed_vcc_reg: regulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "ufs-vcc";
+ gpio = <&gpp0 1 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ enable-active-high;
+ };
};
&ext_24_5m {
@@ -103,8 +118,40 @@
};
&serial_0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_bus>;
+ status = "okay";
+};
+
+&ufs_0 {
+ status = "okay";
+ vcc-supply = <&ufs_0_fixed_vcc_reg>;
+};
+
+&ufs_0_phy {
+ status = "okay";
+};
+
+&usbdrd31 {
+ vdd10-supply = <&reg_placeholder>;
+ vdd33-supply = <&reg_placeholder>;
+ status = "okay";
+};
+
+&usbdrd31_dwc3 {
+ dr_mode = "otg";
+ usb-role-switch;
+ role-switch-default-mode = "peripheral";
+ maximum-speed = "super-speed-plus";
+ status = "okay";
+};
+
+&usbdrd31_phy {
+ /* TODO: Update these once PMIC is implemented */
+ pll-supply = <&reg_placeholder>;
+ dvdd-usb20-supply = <&reg_placeholder>;
+ vddh-usb20-supply = <&reg_placeholder>;
+ vdd33-usb20-supply = <&reg_placeholder>;
+ vdda-usbdp-supply = <&reg_placeholder>;
+ vddh-usbdp-supply = <&reg_placeholder>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 55e6bcb3689e..eadb8822e6d4 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -213,9 +213,9 @@
pmu-3 {
compatible = "arm,dsu-pmu";
- interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>;
cpus = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
<&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+ interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>;
};
psci {
@@ -288,6 +288,8 @@
compatible = "google,gs101-mct",
"samsung,exynos4210-mct";
reg = <0x10050000 0x800>;
+ clocks = <&ext_24_5m>, <&cmu_misc CLK_GOUT_MISC_MCT_PCLK>;
+ clock-names = "fin_pll", "mct";
interrupts = <GIC_SPI 753 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 754 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 755 IRQ_TYPE_LEVEL_HIGH 0>,
@@ -300,17 +302,15 @@
<GIC_SPI 762 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 763 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 764 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&ext_24_5m>, <&cmu_misc CLK_GOUT_MISC_MCT_PCLK>;
- clock-names = "fin_pll", "mct";
};
watchdog_cl0: watchdog@10060000 {
compatible = "google,gs101-wdt";
reg = <0x10060000 0x100>;
- interrupts = <GIC_SPI 765 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cmu_misc CLK_GOUT_MISC_WDT_CLUSTER0_PCLK>,
<&ext_24_5m>;
clock-names = "watchdog", "watchdog_src";
+ interrupts = <GIC_SPI 765 IRQ_TYPE_LEVEL_HIGH 0>;
samsung,syscon-phandle = <&pmu_system_controller>;
samsung,cluster-index = <0>;
status = "disabled";
@@ -319,10 +319,10 @@
watchdog_cl1: watchdog@10070000 {
compatible = "google,gs101-wdt";
reg = <0x10070000 0x100>;
- interrupts = <GIC_SPI 766 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cmu_misc CLK_GOUT_MISC_WDT_CLUSTER1_PCLK>,
<&ext_24_5m>;
clock-names = "watchdog", "watchdog_src";
+ interrupts = <GIC_SPI 766 IRQ_TYPE_LEVEL_HIGH 0>;
samsung,syscon-phandle = <&pmu_system_controller>;
samsung,cluster-index = <1>;
status = "disabled";
@@ -370,12 +370,398 @@
pinctrl_peric0: pinctrl@10840000 {
compatible = "google,gs101-pinctrl";
reg = <0x10840000 0x00001000>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_GPIO_PERIC0_PCLK>;
+ clock-names = "pclk";
interrupts = <GIC_SPI 625 IRQ_TYPE_LEVEL_HIGH 0>;
};
+ usi1: usi@109000c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109000c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1000>;
+ status = "disabled";
+
+ hsi2c_1: i2c@10900000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10900000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c1_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_1: serial@10900000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10900000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart1_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_1: spi@10900000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10900000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi1_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi2: usi@109100c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109100c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1004>;
+ status = "disabled";
+
+ hsi2c_2: i2c@10910000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10910000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c2_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_2: serial@10910000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10910000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart2_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_2: spi@10910000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10910000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi2_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi3: usi@109200c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109200c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1008>;
+ status = "disabled";
+
+ hsi2c_3: i2c@10920000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10920000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c3_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_3: serial@10920000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10920000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart3_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_3: spi@10920000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10920000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi3_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi4: usi@109300c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109300c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x100c>;
+ status = "disabled";
+
+ hsi2c_4: i2c@10930000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10930000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c4_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_4: serial@10930000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10930000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart4_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_4: spi@10930000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10930000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi4_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi5: usi@109400c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109400c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1010>;
+ status = "disabled";
+
+ hsi2c_5: i2c@10940000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10940000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c5_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_5: serial@10940000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10940000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart5_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_5: spi@10940000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10940000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi5_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi6: usi@109500c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109500c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1014>;
+ status = "disabled";
+
+ hsi2c_6: i2c@10950000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10950000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c6_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_6: serial@10950000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10950000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart6_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_6: spi@10950000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10950000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi6_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi7: usi@109600c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x109600c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1018>;
+ status = "disabled";
+
+ hsi2c_7: i2c@10960000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10960000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c7_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_7: serial@10960000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10960000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart7_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_7: spi@10960000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10960000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi7_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
usi8: usi@109700c0 {
- compatible = "google,gs101-usi",
- "samsung,exynos850-usi";
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
reg = <0x109700c0 0x20>;
ranges;
#address-cells = <1>;
@@ -390,21 +776,47 @@
compatible = "google,gs101-hsi2c",
"samsung,exynosautov9-hsi2c";
reg = <0x10970000 0xc0>;
- interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
#address-cells = <1>;
#size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&hsi2c8_bus>;
clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>,
<&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>;
clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c8_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_8: serial@10970000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10970000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart8_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_8: spi@10970000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10970000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi8_bus>;
+ pinctrl-names = "default";
status = "disabled";
};
};
usi_uart: usi@10a000c0 {
- compatible = "google,gs101-usi",
- "samsung,exynos850-usi";
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
reg = <0x10a000c0 0x20>;
ranges;
#address-cells = <1>;
@@ -419,16 +831,72 @@
serial_0: serial@10a00000 {
compatible = "google,gs101-uart";
reg = <0x10a00000 0xc0>;
- interrupts = <GIC_SPI 634
- IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_0>,
<&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_0>;
clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 634 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart0_bus>;
+ pinctrl-names = "default";
samsung,uart-fifosize = <256>;
status = "disabled";
};
};
+ usi14: usi@10a200c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x10a200c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x1028>;
+ status = "disabled";
+
+ hsi2c_14: i2c@10a20000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10a20000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c14_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_14: serial@10a20000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10a20000 0xc0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart14_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_14: spi@10a20000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10a20000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi14_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
cmu_peric1: clock-controller@10c00000 {
compatible = "google,gs101-cmu-peric1";
reg = <0x10c00000 0x4000>;
@@ -448,12 +916,233 @@
pinctrl_peric1: pinctrl@10c40000 {
compatible = "google,gs101-pinctrl";
reg = <0x10c40000 0x00001000>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_GPIO_PERIC1_PCLK>;
+ clock-names = "pclk";
interrupts = <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH 0>;
};
+ usi0: usi@10d100c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x10d100c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric1 0x1000>;
+ status = "disabled";
+
+ hsi2c_0: i2c@10d10000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10d10000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c0_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_usi0: serial@10d10000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10d10000 0xc0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart0_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_0: spi@10d10000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10d10000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi0_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi9: usi@10d200c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x10d200c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric1 0x1004>;
+ status = "disabled";
+
+ hsi2c_9: i2c@10d20000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10d20000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c9_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_9: serial@10d20000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10d20000 0xc0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart9_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_9: spi@10d20000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10d20000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi9_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi10: usi@10d300c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x10d300c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric1 0x1008>;
+ status = "disabled";
+
+ hsi2c_10: i2c@10d30000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10d30000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c10_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_10: serial@10d30000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10d30000 0xc0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart10_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_10: spi@10d30000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10d30000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi10_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi11: usi@10d400c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x10d400c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric1 0x100c>;
+ status = "disabled";
+
+ hsi2c_11: i2c@10d40000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10d40000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 654 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c11_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_11: serial@10d40000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10d40000 0xc0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 654 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart11_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_11: spi@10d40000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10d40000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 654 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi11_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
usi12: usi@10d500c0 {
- compatible = "google,gs101-usi",
- "samsung,exynos850-usi";
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
reg = <0x10d500c0 0x20>;
ranges;
#address-cells = <1>;
@@ -468,14 +1157,151 @@
compatible = "google,gs101-hsi2c",
"samsung,exynosautov9-hsi2c";
reg = <0x10d50000 0xc0>;
- interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
#address-cells = <1>;
#size-cells = <0>;
- pinctrl-0 = <&hsi2c12_bus>;
- pinctrl-names = "default";
clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>,
<&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>;
clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c12_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_12: serial@10d50000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10d50000 0xc0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart12_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_12: spi@10d50000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10d50000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi12_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ usi13: usi@10d600c0 {
+ compatible = "google,gs101-usi", "samsung,exynos850-usi";
+ reg = <0x10d600c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric1 0x1014>;
+ status = "disabled";
+
+ hsi2c_13: i2c@10d60000 {
+ compatible = "google,gs101-hsi2c",
+ "samsung,exynosautov9-hsi2c";
+ reg = <0x10d60000 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&hsi2c13_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ serial_13: serial@10d60000 {
+ compatible = "google,gs101-uart";
+ reg = <0x10d60000 0xc0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>;
+ clock-names = "uart", "clk_uart_baud0";
+ interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&uart13_bus_single>;
+ pinctrl-names = "default";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ spi_13: spi@10d60000 {
+ compatible = "google,gs101-spi";
+ reg = <0x10d60000 0x30>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>;
+ clock-names = "spi", "spi_busclk0";
+ interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&spi13_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ cmu_hsi0: clock-controller@11000000 {
+ compatible = "google,gs101-cmu-hsi0";
+ reg = <0x11000000 0x4000>;
+ #clock-cells = <1>;
+
+ clocks = <&ext_24_5m>,
+ <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+ <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>,
+ <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+ <&cmu_top CLK_DOUT_CMU_HSI0_USBDPDBG>;
+ clock-names = "oscclk", "bus", "dpgtc", "usb31drd",
+ "usbdpdbg";
+ };
+
+ usbdrd31_phy: phy@11100000 {
+ compatible = "google,gs101-usb31drd-phy";
+ reg = <0x11100000 0x0100>,
+ <0x110f0000 0x0800>,
+ <0x110e0000 0x2800>;
+ reg-names = "phy", "pcs", "pma";
+ clocks = <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USB20_PHY_REFCLK_26>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_CTRL_ACLK>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_CTRL_PCLK>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USBDPPHY_SCL_APB_PCLK>;
+ clock-names = "phy", "ref", "ctrl_aclk", "ctrl_pclk", "scl_pclk";
+ #phy-cells = <1>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ usbdrd31: usb@11110000 {
+ compatible = "google,gs101-dwusb3";
+ ranges = <0x0 0x11110000 0x10000>;
+ clocks = <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USB31DRD_SUSPEND_CLK_26>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_LINK_ACLK>,
+ <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_LINK_PCLK>;
+ clock-names = "bus_early", "susp_clk", "link_aclk", "link_pclk";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+
+ usbdrd31_dwc3: usb@0 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x10000>;
+ clocks = <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USB31DRD_REF_CLK_40>;
+ clock-names = "ref";
+ interrupts = <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH 0>;
+ phys = <&usbdrd31_phy 0>, <&usbdrd31_phy 1>;
+ phy-names = "usb2-phy", "usb3-phy";
status = "disabled";
};
};
@@ -483,15 +1309,74 @@
pinctrl_hsi1: pinctrl@11840000 {
compatible = "google,gs101-pinctrl";
reg = <0x11840000 0x00001000>;
+ /* TODO: update once support for this CMU exists */
+ clocks = <0>;
+ clock-names = "pclk";
interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH 0>;
};
+ cmu_hsi2: clock-controller@14400000 {
+ compatible = "google,gs101-cmu-hsi2";
+ reg = <0x14400000 0x4000>;
+ #clock-cells = <1>;
+ clocks = <&ext_24_5m>,
+ <&cmu_top CLK_DOUT_CMU_HSI2_BUS>,
+ <&cmu_top CLK_DOUT_CMU_HSI2_PCIE>,
+ <&cmu_top CLK_DOUT_CMU_HSI2_UFS_EMBD>,
+ <&cmu_top CLK_DOUT_CMU_HSI2_MMC_CARD>;
+ clock-names = "oscclk", "bus", "pcie", "ufs", "mmc";
+ };
+
+ sysreg_hsi2: syscon@14420000 {
+ compatible = "google,gs101-hsi2-sysreg", "syscon";
+ reg = <0x14420000 0x10000>;
+ clocks = <&cmu_hsi2 CLK_GOUT_HSI2_SYSREG_HSI2_PCLK>;
+ };
+
pinctrl_hsi2: pinctrl@14440000 {
compatible = "google,gs101-pinctrl";
reg = <0x14440000 0x00001000>;
+ clocks = <&cmu_hsi2 CLK_GOUT_HSI2_GPIO_HSI2_PCLK>;
+ clock-names = "pclk";
interrupts = <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH 0>;
};
+ ufs_0: ufs@14700000 {
+ compatible = "google,gs101-ufs";
+ reg = <0x14700000 0x200>,
+ <0x14701100 0x200>,
+ <0x14780000 0xa000>,
+ <0x14600000 0x100>;
+ reg-names = "hci", "vs_hci", "unipro", "ufsp";
+ interrupts = <GIC_SPI 532 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cmu_hsi2 CLK_GOUT_HSI2_UFS_EMBD_I_ACLK>,
+ <&cmu_hsi2 CLK_GOUT_HSI2_UFS_EMBD_I_CLK_UNIPRO>,
+ <&cmu_hsi2 CLK_GOUT_HSI2_UFS_EMBD_I_FMP_CLK>,
+ <&cmu_hsi2 CLK_GOUT_HSI2_QE_UFS_EMBD_HSI2_ACLK>,
+ <&cmu_hsi2 CLK_GOUT_HSI2_QE_UFS_EMBD_HSI2_PCLK>,
+ <&cmu_hsi2 CLK_GOUT_HSI2_SYSREG_HSI2_PCLK>;
+ clock-names = "core_clk", "sclk_unipro_main", "fmp",
+ "aclk", "pclk", "sysreg";
+ freq-table-hz = <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>;
+ pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
+ pinctrl-names = "default";
+ phys = <&ufs_0_phy>;
+ phy-names = "ufs-phy";
+ samsung,sysreg = <&sysreg_hsi2 0x710>;
+ status = "disabled";
+ };
+
+ ufs_0_phy: phy@14704000 {
+ compatible = "google,gs101-ufs-phy";
+ reg = <0x14704000 0x3000>;
+ reg-names = "phy-pma";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <0>;
+ clocks = <&ext_24_5m>;
+ clock-names = "ref_clk";
+ status = "disabled";
+ };
+
cmu_apm: clock-controller@17400000 {
compatible = "google,gs101-cmu-apm";
reg = <0x17400000 0x8000>;
@@ -514,6 +1399,8 @@
pinctrl_gpio_alive: pinctrl@174d0000 {
compatible = "google,gs101-pinctrl";
reg = <0x174d0000 0x00001000>;
+ clocks = <&cmu_apm CLK_GOUT_APM_APBIF_GPIO_ALIVE_PCLK>;
+ clock-names = "pclk";
wakeup-interrupt-controller {
compatible = "google,gs101-wakeup-eint",
@@ -525,6 +1412,8 @@
pinctrl_far_alive: pinctrl@174e0000 {
compatible = "google,gs101-pinctrl";
reg = <0x174e0000 0x00001000>;
+ clocks = <&cmu_apm CLK_GOUT_APM_APBIF_GPIO_FAR_ALIVE_PCLK>;
+ clock-names = "pclk";
wakeup-interrupt-controller {
compatible = "google,gs101-wakeup-eint",
@@ -536,11 +1425,17 @@
pinctrl_gsactrl: pinctrl@17940000 {
compatible = "google,gs101-pinctrl";
reg = <0x17940000 0x00001000>;
+ /* TODO: update once support for this CMU exists */
+ clocks = <0>;
+ clock-names = "pclk";
};
pinctrl_gsacore: pinctrl@17a80000 {
compatible = "google,gs101-pinctrl";
reg = <0x17a80000 0x00001000>;
+ /* TODO: update once support for this CMU exists */
+ clocks = <0>;
+ clock-names = "pclk";
};
cmu_top: clock-controller@1e080000 {
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 045250d0a040..f04c22b7de72 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -9,6 +9,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-kbox-a-230-ls.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var1.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var2.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
@@ -98,6 +99,10 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-tqmlx2160a-mblx2160a-14-11-x.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-tqmlx2160a-mblx2160a-14-8-x.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-tqmlx2160a-mblx2160a-14-7-x.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-aster.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-eval-v3.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-iris-v2.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-iris.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdp-mba8xx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb
@@ -109,6 +114,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-evkb.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-icore-mx8mm-ctouch2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-icore-mx8mm-edimm2.2.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-iot-gateway.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-innocomm-wb15-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-kontron-bl.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-kontron-bl-osm-s.dtb
@@ -166,11 +172,13 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-dhcom-pdk3.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-icore-mx8mp-edimm2.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-msc-sm2s-ep1.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-navqp.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-hdmi.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-lt6.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-mi1010ait-1cp1.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-tqma8mpql-mba8mpxl.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-tqma8mpql-mba8mp-ras314.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw71xx-2x.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw72xx-2x.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw73xx-2x.dtb
@@ -185,6 +193,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-verdin-wifi-mallow.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-verdin-wifi-yavia.dtb
+imx8mp-evk-mx8-dlvds-lcd1-dtbs += imx8mp-evk.dtb imx8mp-evk-mx8-dlvds-lcd1.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk-mx8-dlvds-lcd1.dtb
+
imx8mp-tqma8mpql-mba8mpxl-lvds-dtbs += imx8mp-tqma8mpql-mba8mpxl.dtb imx8mp-tqma8mpql-mba8mpxl-lvds.dtbo
imx8mp-tqma8mpql-mba8mpxl-lvds-g133han01-dtbs += imx8mp-tqma8mpql-mba8mpxl.dtb imx8mp-tqma8mpql-mba8mpxl-lvds-g133han01.dtbo
dtb-$(CONFIG_ARCH_MXC) += imx8mp-tqma8mpql-mba8mpxl-lvds.dtb
@@ -225,11 +236,13 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-iris-v2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-tqma8xqp-mba8xx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8ulp-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxca.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxla.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-var-som-symphony.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk.dtb
imx8mm-venice-gw72xx-0x-imx219-dtbs := imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-imx219.dtbo
imx8mm-venice-gw72xx-0x-rpidsi-dtbs := imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rpidsi.dtbo
@@ -257,6 +270,15 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw74xx-imx219.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw74xx-rpidsi.dtb
+imx8mm-phygate-tauri-l-rs232-rs232-dtbs := imx8mm-phygate-tauri-l.dtb imx8mm-phygate-tauri-l-rs232-rs232.dtbo
+imx8mm-phygate-tauri-l-rs232-cts-rts-dtbs := imx8mm-phygate-tauri-l.dtb imx8mm-phygate-tauri-l-rs232-rts-cts.dtbo
+imx8mm-phygate-tauri-l-rs232-rs485-dtbs := imx8mm-phygate-tauri-l.dtb imx8mm-phygate-tauri-l-rs232-rs485.dtbo
+
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l-rs232-rs232.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l-rs232-cts-rts.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l-rs232-rs485.dtb
+
dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb
+dtb-$(CONFIG_ARCH_S32) += s32g399a-rdb3.dtb
dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
index fe9093b3c02e..e61ea7e0737e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
@@ -74,15 +74,15 @@
timer {
compatible = "arm,armv8-timer";
- interrupts = <1 13 IRQ_TYPE_LEVEL_LOW>,/* Physical Secure PPI */
- <1 14 IRQ_TYPE_LEVEL_LOW>,/* Physical Non-Secure PPI */
- <1 11 IRQ_TYPE_LEVEL_LOW>,/* Virtual PPI */
- <1 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,/* Physical Secure PPI */
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,/* Physical Non-Secure PPI */
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,/* Virtual PPI */
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */
};
pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
};
gic: interrupt-controller@1400000 {
@@ -93,7 +93,7 @@
<0x0 0x1402000 0 0x2000>, /* GICC */
<0x0 0x1404000 0 0x2000>, /* GICH */
<0x0 0x1406000 0 0x2000>; /* GICV */
- interrupts = <1 9 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
};
reboot {
@@ -156,10 +156,10 @@
status = "disabled";
};
- esdhc0: esdhc@1560000 {
+ esdhc0: mmc@1560000 {
compatible = "fsl,ls1012a-esdhc", "fsl,esdhc";
reg = <0x0 0x1560000 0x0 0x10000>;
- interrupts = <0 62 0x4>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
voltage-ranges = <1800 1800 3300 3300>;
@@ -175,10 +175,10 @@
big-endian;
};
- esdhc1: esdhc@1580000 {
+ esdhc1: mmc@1580000 {
compatible = "fsl,ls1012a-esdhc", "fsl,esdhc";
reg = <0x0 0x1580000 0x0 0x10000>;
- interrupts = <0 65 0x4>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
voltage-ranges = <1800 1800 3300 3300>;
@@ -305,7 +305,7 @@
tmu: tmu@1f00000 {
compatible = "fsl,qoriq-tmu";
reg = <0x0 0x1f00000 0x0 0x10000>;
- interrupts = <0 33 0x4>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x60062>;
fsl,tmu-calibration =
<0x00000000 0x00000025>,
@@ -355,7 +355,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2180000 0x0 0x10000>;
- interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
scl-gpios = <&gpio0 2 0>;
@@ -367,7 +367,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2190000 0x0 0x10000>;
- interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
scl-gpios = <&gpio0 13 0>;
@@ -379,7 +379,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2100000 0x0 0x10000>;
- interrupts = <0 64 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "dspi";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
@@ -391,7 +391,7 @@
duart0: serial@21c0500 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x00 0x21c0500 0x0 0x100>;
- interrupts = <0 54 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
status = "disabled";
@@ -400,16 +400,16 @@
duart1: serial@21c0600 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x00 0x21c0600 0x0 0x100>;
- interrupts = <0 54 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
status = "disabled";
};
gpio0: gpio@2300000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
- interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -417,9 +417,9 @@
};
gpio1: gpio@2310000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2310000 0x0 0x10000>;
- interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -430,7 +430,7 @@
compatible = "fsl,ls1012a-wdt",
"fsl,imx21-wdt";
reg = <0x0 0x2ad0000 0x0 0x10000>;
- interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(1)>;
big-endian;
};
@@ -439,7 +439,7 @@
#sound-dai-cells = <0>;
compatible = "fsl,vf610-sai";
reg = <0x0 0x2b50000 0x0 0x10000>;
- interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>,
<&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -449,9 +449,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 47>,
- <&edma0 1 46>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 46>,
+ <&edma0 1 47>;
status = "disabled";
};
@@ -459,7 +459,7 @@
#sound-dai-cells = <0>;
compatible = "fsl,vf610-sai";
reg = <0x0 0x2b60000 0x0 0x10000>;
- interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>,
<&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -469,9 +469,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 45>,
- <&edma0 1 44>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 44>,
+ <&edma0 1 45>;
status = "disabled";
};
@@ -481,8 +481,8 @@
reg = <0x0 0x2c00000 0x0 0x10000>,
<0x0 0x2c10000 0x0 0x10000>,
<0x0 0x2c20000 0x0 0x10000>;
- interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>,
- <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "edma-tx", "edma-err";
dma-channels = <32>;
big-endian;
@@ -496,12 +496,11 @@
usb0: usb@2f00000 {
compatible = "snps,dwc3";
reg = <0x0 0x2f00000 0x0 0x10000>;
- interrupts = <0 60 0x4>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
- snps,host-vbus-glitches;
};
sata: sata@3200000 {
@@ -509,7 +508,7 @@
reg = <0x0 0x3200000 0x0 0x10000>,
<0x0 0x20140520 0x0 0x4>;
reg-names = "ahci", "sata-ecc";
- interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
dma-coherent;
@@ -519,7 +518,7 @@
usb1: usb@8600000 {
compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
reg = <0x0 0x8600000 0x0 0x1000>;
- interrupts = <0 139 0x4>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
phy_type = "ulpi";
};
@@ -528,7 +527,7 @@
compatible = "fsl,ls1012a-msi";
reg = <0x0 0x1572000 0x0 0x8>;
msi-controller;
- interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
};
pcie1: pcie@3400000 {
@@ -536,9 +535,9 @@
reg = <0x00 0x03400000 0x0 0x00100000>, /* controller registers */
<0x40 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 118 0x4>, /* controller interrupt */
- <0 117 0x4>; /* PME interrupt */
- interrupt-names = "aer", "pme";
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+ interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -563,7 +562,7 @@
#fsl,rcpm-wakeup-cells = <1>;
};
- ftm_alarm0: timer@29d0000 {
+ ftm_alarm0: rtc@29d0000 {
compatible = "fsl,ls1012a-ftm-alarm";
reg = <0x0 0x29d0000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x20000>;
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 ed4e69e87e30..195bdbafdf7c 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
@@ -10,7 +10,7 @@
/dts-v1/;
#include <dt-bindings/clock/fsl,qoriq-clockgen.h>
-#include "fsl-ls1028a-kontron-sl28.dts"
+#include "fsl-ls1028a-kontron-sl28-var3.dts"
/ {
model = "Kontron SMARC-sAL28 (Single PHY) on SMARC Eval 2.0 carrier";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts
new file mode 100644
index 000000000000..08851ca407a8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Device Tree file for the Kontron SMARC-sAL28 board.
+ *
+ * This is for the network variant 3 which has one ethernet ports.
+ *
+ * Copyright (C) 2024 Michael Walle <michael@walle.cc>
+ *
+ */
+
+/dts-v1/;
+
+#include "fsl-ls1028a-kontron-sl28.dts"
+
+/ {
+ model = "Kontron SMARC-sAL28 (Single PHY)";
+ compatible = "kontron,sl28-var3", "kontron,sl28", "fsl,ls1028a";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
index ecd2c1ea177f..757a34ba7da3 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
@@ -201,6 +201,37 @@
#address-cells = <1>;
#size-cells = <0>;
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+
+ /* Atmel AT24C512C-XHD­B: 64 KB EEPROM */
+ eeprom@50 {
+ compatible = "atmel,24c512";
+ reg = <0x50>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ /* AT24C04C 512-byte DDR4 SPD EEPROM */
+ /* Documentation says 0x51, but must be even and i2cdetect says 0x52 */
+ eeprom@52 {
+ compatible = "atmel,24c04";
+ reg = <0x52>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ /* Atmel AT24C02C-XHM­B: 256-byte EEPROM */
+ eeprom@57 {
+ compatible = "atmel,24c02";
+ reg = <0x57>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index ae534c23b970..6b6e3ee950e5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -155,7 +155,7 @@
};
thermal-zones {
- ddr-controller {
+ ddr-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 0>;
@@ -175,7 +175,7 @@
};
};
- core-cluster {
+ core-cluster-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 1>;
@@ -674,7 +674,7 @@
};
pcie_ep1: pcie-ep@3400000 {
- compatible = "fsl,ls1028a-pcie-ep","fsl,ls-pcie-ep";
+ compatible = "fsl,ls1028a-pcie-ep";
reg = <0x00 0x03400000 0x0 0x00100000
0x80 0x00000000 0x8 0x00000000>;
reg-names = "regs", "addr_space";
@@ -713,7 +713,7 @@
};
pcie_ep2: pcie-ep@3500000 {
- compatible = "fsl,ls1028a-pcie-ep","fsl,ls-pcie-ep";
+ compatible = "fsl,ls1028a-pcie-ep";
reg = <0x00 0x03500000 0x0 0x00100000
0x88 0x00000000 0x8 0x00000000>;
reg-names = "regs", "addr_space";
@@ -828,6 +828,7 @@
<GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "qdma-error", "qdma-queue0",
"qdma-queue1", "qdma-queue2", "qdma-queue3";
+ #dma-cells = <1>;
dma-channels = <8>;
block-number = <1>;
block-offset = <0x10000>;
@@ -859,8 +860,8 @@
malidp0: display@f080000 {
compatible = "arm,mali-dp500";
reg = <0x0 0xf080000 0x0 0x10000>;
- interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
- <0 223 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "DE", "SE";
clocks = <&dpclk>,
<&clockgen QORIQ_CLK_HWACCEL 2>,
@@ -902,9 +903,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 4>,
- <&edma0 1 3>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 3>,
+ <&edma0 1 4>;
fsl,sai-asynchronous;
status = "disabled";
};
@@ -923,9 +924,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 6>,
- <&edma0 1 5>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 5>,
+ <&edma0 1 6>;
fsl,sai-asynchronous;
status = "disabled";
};
@@ -944,9 +945,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 8>,
- <&edma0 1 7>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 7>,
+ <&edma0 1 8>;
fsl,sai-asynchronous;
status = "disabled";
};
@@ -965,9 +966,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 10>,
- <&edma0 1 9>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 9>,
+ <&edma0 1 10>;
fsl,sai-asynchronous;
status = "disabled";
};
@@ -986,9 +987,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 12>,
- <&edma0 1 11>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 11>,
+ <&edma0 1 12>;
fsl,sai-asynchronous;
status = "disabled";
};
@@ -1007,9 +1008,9 @@
<&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 1 14>,
- <&edma0 1 13>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 1 13>,
+ <&edma0 1 14>;
fsl,sai-asynchronous;
status = "disabled";
};
@@ -1024,7 +1025,7 @@
tmu: tmu@1f80000 {
compatible = "fsl,qoriq-tmu";
reg = <0x0 0x1f80000 0x0 0x10000>;
- interrupts = <0 23 0x4>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
fsl,tmu-calibration =
<0x00000000 0x00000024>,
@@ -1099,21 +1100,25 @@
0xc2000000 0x1 0xf8230000 0x1 0xf8230000 0x0 0x020000
/* BAR4 (PF5) - non-prefetchable memory */
0x82000000 0x1 0xfc000000 0x1 0xfc000000 0x0 0x400000>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+ <0000 0 0 2 &gic 0 0 GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
enetc_port0: ethernet@0,0 {
- compatible = "fsl,enetc";
+ compatible = "pci1957,e100", "fsl,enetc";
reg = <0x000000 0 0 0 0>;
status = "disabled";
};
enetc_port1: ethernet@0,1 {
- compatible = "fsl,enetc";
+ compatible = "pci1957,e100", "fsl,enetc";
reg = <0x000100 0 0 0 0>;
status = "disabled";
};
enetc_port2: ethernet@0,2 {
- compatible = "fsl,enetc";
+ compatible = "pci1957,e100", "fsl,enetc";
reg = <0x000200 0 0 0 0>;
phy-mode = "internal";
status = "disabled";
@@ -1126,14 +1131,14 @@
};
enetc_mdio_pf3: mdio@0,3 {
- compatible = "fsl,enetc-mdio";
+ compatible = "pci1957,ee01", "fsl,enetc-mdio";
reg = <0x000300 0 0 0 0>;
#address-cells = <1>;
#size-cells = <0>;
};
ethernet@0,4 {
- compatible = "fsl,enetc-ptp";
+ compatible = "pci1957,ee02", "fsl,enetc-ptp";
reg = <0x000400 0 0 0 0>;
clocks = <&clockgen QORIQ_CLK_HWACCEL 3>;
little-endian;
@@ -1143,7 +1148,7 @@
mscc_felix: ethernet-switch@0,5 {
reg = <0x000500 0 0 0 0>;
/* IEP INT_B */
- interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <2>;
status = "disabled";
mscc_felix_ports: ports {
@@ -1201,7 +1206,7 @@
};
enetc_port3: ethernet@0,6 {
- compatible = "fsl,enetc";
+ compatible = "pci1957,e100", "fsl,enetc";
reg = <0x000600 0 0 0 0>;
phy-mode = "internal";
status = "disabled";
@@ -1216,7 +1221,7 @@
rcec@1f,0 {
reg = <0x00f800 0 0 0 0>;
/* IEP INT_A */
- interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <1>;
};
};
@@ -1321,7 +1326,7 @@
little-endian;
};
- ftm_alarm0: timer@2800000 {
+ ftm_alarm0: rtc@2800000 {
compatible = "fsl,ls1028a-ftm-alarm";
reg = <0x0 0x2800000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0 0x0>;
@@ -1329,7 +1334,7 @@
status = "disabled";
};
- ftm_alarm1: timer@2810000 {
+ ftm_alarm1: rtc@2810000 {
compatible = "fsl,ls1028a-ftm-alarm";
reg = <0x0 0x2810000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0 0x0>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
index dda27ed7aaf2..11b1356e95d5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
@@ -64,7 +64,7 @@
0x2 0x0 0x0 0x7fb00000 0x00000100>;
status = "okay";
- nor@0,0 {
+ flash@0,0 {
compatible = "cfi-flash";
reg = <0x0 0x0 0x8000000>;
big-endian;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
index 26f8540cb101..c4532c809f0a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
@@ -71,7 +71,7 @@
0x1 0x0 0x0 0x7e800000 0x00010000
0x2 0x0 0x0 0x7fb00000 0x00000100>;
- nor@0,0 {
+ flash@0,0 {
compatible = "cfi-flash";
#address-cells = <1>;
#size-cells = <1>;
@@ -104,6 +104,12 @@
compatible = "n25q128a13", "jedec,spi-nor"; /* 16MB */
reg = <0>;
spi-max-frequency = <1000000>; /* input clock */
+ /*
+ * Standard CS timing properties replace the deprecated vendor
+ * variants below.
+ */
+ spi-cs-setup-delay-ns = <100>;
+ spi-cs-hold-delay-ns = <100>;
fsl,spi-cs-sck-delay = <100>;
fsl,spi-sck-cs-delay = <100>;
};
@@ -112,6 +118,12 @@
compatible = "maxim,ds26522";
reg = <2>;
spi-max-frequency = <2000000>;
+ /*
+ * Standard CS timing properties replace the deprecated vendor
+ * variants below.
+ */
+ spi-cs-setup-delay-ns = <100>;
+ spi-cs-hold-delay-ns = <50>;
fsl,spi-cs-sck-delay = <100>;
fsl,spi-sck-cs-delay = <50>;
};
@@ -120,6 +132,12 @@
compatible = "maxim,ds26522";
reg = <3>;
spi-max-frequency = <2000000>;
+ /*
+ * Standard CS timing properties replace the deprecated vendor
+ * variants below.
+ */
+ spi-cs-setup-delay-ns = <100>;
+ spi-cs-hold-delay-ns = <50>;
fsl,spi-cs-sck-delay = <100>;
fsl,spi-sck-cs-delay = <50>;
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index d333b773bc45..17f4e3171120 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -154,7 +154,7 @@
};
thermal-zones {
- ddr-controller {
+ ddr-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 0>;
@@ -174,7 +174,7 @@
};
};
- serdes {
+ serdes-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 1>;
@@ -194,7 +194,7 @@
};
};
- fman {
+ fman-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 2>;
@@ -214,7 +214,7 @@
};
};
- core-cluster {
+ core-cluster-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 3>;
@@ -245,7 +245,7 @@
};
};
- sec {
+ sec-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 4>;
@@ -268,19 +268,19 @@
timer {
compatible = "arm,armv8-timer";
- interrupts = <1 13 0xf08>, /* Physical Secure PPI */
- <1 14 0xf08>, /* Physical Non-Secure PPI */
- <1 11 0xf08>, /* Virtual PPI */
- <1 10 0xf08>; /* Hypervisor PPI */
+ 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)>;
fsl,erratum-a008585;
};
pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <0 106 0x4>,
- <0 107 0x4>,
- <0 95 0x4>,
- <0 97 0x4>;
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&cpu0>,
<&cpu1>,
<&cpu2>,
@@ -295,7 +295,7 @@
<0x0 0x1402000 0 0x2000>, /* GICC */
<0x0 0x1404000 0 0x2000>, /* GICH */
<0x0 0x1406000 0 0x2000>; /* GICV */
- interrupts = <1 9 0xf08>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
soc: soc {
@@ -352,7 +352,7 @@
#size-cells = <1>;
ranges = <0x0 0x00 0x1700000 0x100000>;
reg = <0x00 0x1700000 0x0 0x100000>;
- interrupts = <0 75 0x4>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
dma-coherent;
sec_jr0: jr@10000 {
@@ -360,7 +360,7 @@
"fsl,sec-v5.0-job-ring",
"fsl,sec-v4.0-job-ring";
reg = <0x10000 0x10000>;
- interrupts = <0 71 0x4>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
};
sec_jr1: jr@20000 {
@@ -368,7 +368,7 @@
"fsl,sec-v5.0-job-ring",
"fsl,sec-v4.0-job-ring";
reg = <0x20000 0x10000>;
- interrupts = <0 72 0x4>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
};
sec_jr2: jr@30000 {
@@ -376,7 +376,7 @@
"fsl,sec-v5.0-job-ring",
"fsl,sec-v4.0-job-ring";
reg = <0x30000 0x10000>;
- interrupts = <0 73 0x4>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
};
sec_jr3: jr@40000 {
@@ -384,7 +384,7 @@
"fsl,sec-v5.0-job-ring",
"fsl,sec-v4.0-job-ring";
reg = <0x40000 0x10000>;
- interrupts = <0 74 0x4>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -405,7 +405,7 @@
ifc: memory-controller@1530000 {
compatible = "fsl,ifc";
reg = <0x0 0x1530000 0x0 0x10000>;
- interrupts = <0 43 0x4>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
};
qspi: spi@1550000 {
@@ -415,7 +415,7 @@
reg = <0x0 0x1550000 0x0 0x10000>,
<0x0 0x40000000 0x0 0x4000000>;
reg-names = "QuadSPI", "QuadSPI-memory";
- interrupts = <0 99 0x4>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "qspi_en", "qspi";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>,
@@ -424,10 +424,10 @@
status = "disabled";
};
- esdhc: esdhc@1560000 {
+ esdhc: mmc@1560000 {
compatible = "fsl,ls1043a-esdhc", "fsl,esdhc";
reg = <0x0 0x1560000 0x0 0x10000>;
- interrupts = <0 62 0x4>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <0>;
voltage-ranges = <1800 1800 3300 3300>;
sdhci,auto-cmd12;
@@ -438,14 +438,14 @@
ddr: memory-controller@1080000 {
compatible = "fsl,qoriq-memory-controller";
reg = <0x0 0x1080000 0x0 0x1000>;
- interrupts = <0 144 0x4>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
big-endian;
};
tmu: tmu@1f00000 {
compatible = "fsl,qoriq-tmu";
reg = <0x0 0x1f00000 0x0 0x10000>;
- interrupts = <0 33 0x4>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x70062>;
fsl,tmu-calibration =
<0x00000000 0x00000023>,
@@ -505,11 +505,11 @@
memory-region = <&bman_fbpr>;
};
- bportals: bman-portals@508000000 {
+ bportals: bman-portals-bus@508000000 {
ranges = <0x0 0x5 0x08000000 0x8000000>;
};
- qportals: qman-portals@500000000 {
+ qportals: qman-portals-bus@500000000 {
ranges = <0x0 0x5 0x00000000 0x8000000>;
};
@@ -518,7 +518,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2100000 0x0 0x10000>;
- interrupts = <0 64 0x4>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "dspi";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
@@ -532,8 +532,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2180000 0x0 0x10000>;
- interrupts = <0 56 0x4>;
- clock-names = "i2c";
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
dmas = <&edma0 1 38>,
@@ -547,8 +547,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2190000 0x0 0x10000>;
- interrupts = <0 57 0x4>;
- clock-names = "i2c";
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
scl-gpios = <&gpio4 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
@@ -560,8 +560,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x21a0000 0x0 0x10000>;
- interrupts = <0 58 0x4>;
- clock-names = "i2c";
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
scl-gpios = <&gpio4 10 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
@@ -573,8 +573,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x21b0000 0x0 0x10000>;
- interrupts = <0 59 0x4>;
- clock-names = "i2c";
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
@@ -584,7 +584,7 @@
duart0: serial@21c0500 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x00 0x21c0500 0x0 0x100>;
- interrupts = <0 54 0x4>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
};
@@ -592,7 +592,7 @@
duart1: serial@21c0600 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x00 0x21c0600 0x0 0x100>;
- interrupts = <0 54 0x4>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
};
@@ -600,7 +600,7 @@
duart2: serial@21d0500 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x0 0x21d0500 0x0 0x100>;
- interrupts = <0 55 0x4>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
};
@@ -608,7 +608,7 @@
duart3: serial@21d0600 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x0 0x21d0600 0x0 0x100>;
- interrupts = <0 55 0x4>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
};
@@ -616,7 +616,7 @@
gpio1: gpio@2300000 {
compatible = "fsl,ls1043a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
- interrupts = <0 66 0x4>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -626,7 +626,7 @@
gpio2: gpio@2310000 {
compatible = "fsl,ls1043a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2310000 0x0 0x10000>;
- interrupts = <0 67 0x4>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -636,7 +636,7 @@
gpio3: gpio@2320000 {
compatible = "fsl,ls1043a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2320000 0x0 0x10000>;
- interrupts = <0 68 0x4>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -646,7 +646,7 @@
gpio4: gpio@2330000 {
compatible = "fsl,ls1043a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2330000 0x0 0x10000>;
- interrupts = <0 134 0x4>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -721,7 +721,7 @@
lpuart0: serial@2950000 {
compatible = "fsl,ls1021a-lpuart";
reg = <0x0 0x2950000 0x0 0x1000>;
- interrupts = <0 48 0x4>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_SYSCLK 0>;
clock-names = "ipg";
status = "disabled";
@@ -730,7 +730,7 @@
lpuart1: serial@2960000 {
compatible = "fsl,ls1021a-lpuart";
reg = <0x0 0x2960000 0x0 0x1000>;
- interrupts = <0 49 0x4>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
clock-names = "ipg";
@@ -740,7 +740,7 @@
lpuart2: serial@2970000 {
compatible = "fsl,ls1021a-lpuart";
reg = <0x0 0x2970000 0x0 0x1000>;
- interrupts = <0 50 0x4>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
clock-names = "ipg";
@@ -750,7 +750,7 @@
lpuart3: serial@2980000 {
compatible = "fsl,ls1021a-lpuart";
reg = <0x0 0x2980000 0x0 0x1000>;
- interrupts = <0 51 0x4>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
clock-names = "ipg";
@@ -760,7 +760,7 @@
lpuart4: serial@2990000 {
compatible = "fsl,ls1021a-lpuart";
reg = <0x0 0x2990000 0x0 0x1000>;
- interrupts = <0 52 0x4>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
clock-names = "ipg";
@@ -770,7 +770,7 @@
lpuart5: serial@29a0000 {
compatible = "fsl,ls1021a-lpuart";
reg = <0x0 0x29a0000 0x0 0x1000>;
- interrupts = <0 53 0x4>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
clock-names = "ipg";
@@ -780,10 +780,9 @@
wdog0: watchdog@2ad0000 {
compatible = "fsl,ls1043a-wdt", "fsl,imx21-wdt";
reg = <0x0 0x2ad0000 0x0 0x10000>;
- interrupts = <0 83 0x4>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
- clock-names = "wdog";
big-endian;
};
@@ -793,8 +792,8 @@
reg = <0x0 0x2c00000 0x0 0x10000>,
<0x0 0x2c10000 0x0 0x10000>,
<0x0 0x2c20000 0x0 0x10000>;
- interrupts = <0 103 0x4>,
- <0 103 0x4>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "edma-tx", "edma-err";
dma-channels = <32>;
big-endian;
@@ -805,7 +804,7 @@
QORIQ_CLK_PLL_DIV(1)>;
};
- aux_bus: aux_bus {
+ aux_bus: aux-bus {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
@@ -815,7 +814,7 @@
usb0: usb@2f00000 {
compatible = "snps,dwc3";
reg = <0x0 0x2f00000 0x0 0x10000>;
- interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -827,7 +826,7 @@
usb1: usb@3000000 {
compatible = "snps,dwc3";
reg = <0x0 0x3000000 0x0 0x10000>;
- interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -839,7 +838,7 @@
usb2: usb@3100000 {
compatible = "snps,dwc3";
reg = <0x0 0x3100000 0x0 0x10000>;
- interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -853,7 +852,7 @@
reg = <0x0 0x3200000 0x0 0x10000>,
<0x0 0x20140520 0x0 0x4>;
reg-names = "ahci", "sata-ecc";
- interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(1)>;
dma-coherent;
@@ -864,21 +863,21 @@
compatible = "fsl,ls1043a-msi";
reg = <0x0 0x1571000 0x0 0x8>;
msi-controller;
- interrupts = <0 116 0x4>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
};
msi2: msi-controller2@1572000 {
compatible = "fsl,ls1043a-msi";
reg = <0x0 0x1572000 0x0 0x8>;
msi-controller;
- interrupts = <0 126 0x4>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
};
msi3: msi-controller3@1573000 {
compatible = "fsl,ls1043a-msi";
reg = <0x0 0x1573000 0x0 0x8>;
msi-controller;
- interrupts = <0 160 0x4>;
+ interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>;
};
pcie1: pcie@3400000 {
@@ -886,8 +885,8 @@
reg = <0x00 0x03400000 0x0 0x00100000>, /* controller registers */
<0x40 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH>,
- <0 118 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
@@ -913,8 +912,8 @@
reg = <0x00 0x03500000 0x0 0x00100000>, /* controller registers */
<0x48 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 127 IRQ_TYPE_LEVEL_HIGH>,
- <0 128 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
@@ -940,8 +939,8 @@
reg = <0x00 0x03600000 0x0 0x00100000>, /* controller registers */
<0x50 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 161 IRQ_TYPE_LEVEL_HIGH>,
- <0 162 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
@@ -974,6 +973,7 @@
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "qdma-error", "qdma-queue0",
"qdma-queue1", "qdma-queue2", "qdma-queue3";
+ #dma-cells = <1>;
dma-channels = <8>;
block-number = <1>;
block-offset = <0x10000>;
@@ -989,7 +989,7 @@
#fsl,rcpm-wakeup-cells = <1>;
};
- ftm_alarm0: timer@29d0000 {
+ ftm_alarm0: rtc@29d0000 {
compatible = "fsl,ls1043a-ftm-alarm";
reg = <0x0 0x29d0000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x20000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
index 3b0ed9305f2b..e5296e51f656 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
@@ -151,7 +151,7 @@
0x2 0x0 0x0 0x7fb00000 0x00000100>;
status = "okay";
- nor@0,0 {
+ flash@0,0 {
compatible = "cfi-flash";
reg = <0x0 0x0 0x8000000>;
big-endian;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 754a64be739c..200e52622f99 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -122,7 +122,7 @@
};
thermal-zones {
- ddr-controller {
+ ddr-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 0>;
@@ -142,7 +142,7 @@
};
};
- serdes {
+ serdes-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 1>;
@@ -162,7 +162,7 @@
};
};
- fman {
+ fman-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 2>;
@@ -182,7 +182,7 @@
};
};
- core-cluster {
+ core-cluster-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 3>;
@@ -213,7 +213,7 @@
};
};
- sec {
+ sec-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 4>;
@@ -308,7 +308,7 @@
status = "disabled";
};
- esdhc: esdhc@1560000 {
+ esdhc: mmc@1560000 {
compatible = "fsl,ls1046a-esdhc", "fsl,esdhc";
reg = <0x0 0x1560000 0x0 0x10000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
@@ -409,11 +409,11 @@
};
- qportals: qman-portals@500000000 {
+ qportals: qman-portals-bus@500000000 {
ranges = <0x0 0x5 0x00000000 0x8000000>;
};
- bportals: bman-portals@508000000 {
+ bportals: bman-portals-bus@508000000 {
ranges = <0x0 0x5 0x08000000 0x8000000>;
};
@@ -441,7 +441,7 @@
tmu: tmu@1f00000 {
compatible = "fsl,qoriq-tmu";
reg = <0x0 0x1f00000 0x0 0x10000>;
- interrupts = <0 33 0x4>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x70062>;
fsl,tmu-calibration =
/* Calibration data group 1 */
@@ -589,7 +589,7 @@
};
gpio0: gpio@2300000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls1046a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -599,7 +599,7 @@
};
gpio1: gpio@2310000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls1046a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2310000 0x0 0x10000>;
interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -609,7 +609,7 @@
};
gpio2: gpio@2320000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls1046a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2320000 0x0 0x10000>;
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -619,7 +619,7 @@
};
gpio3: gpio@2330000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls1046a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2330000 0x0 0x10000>;
interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -715,7 +715,7 @@
QORIQ_CLK_PLL_DIV(2)>;
};
- aux_bus: aux_bus {
+ aux_bus: aux-bus {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
@@ -801,9 +801,9 @@
reg = <0x00 0x03400000 0x0 0x00100000>, /* controller registers */
<0x40 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
- <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
- interrupt-names = "aer", "pme";
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+ interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -840,9 +840,9 @@
reg = <0x00 0x03500000 0x0 0x00100000>, /* controller registers */
<0x48 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
- <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
- interrupt-names = "aer", "pme";
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+ interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -879,9 +879,9 @@
reg = <0x00 0x03600000 0x0 0x00100000>, /* controller registers */
<0x50 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
- <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
- interrupt-names = "aer", "pme";
+ interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+ interrupt-names = "pme", "aer";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -925,6 +925,7 @@
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "qdma-error", "qdma-queue0",
"qdma-queue1", "qdma-queue2", "qdma-queue3";
+ #dma-cells = <1>;
dma-channels = <8>;
block-number = <1>;
block-offset = <0x10000>;
@@ -940,7 +941,7 @@
#fsl,rcpm-wakeup-cells = <1>;
};
- ftm_alarm0: timer@29d0000 {
+ ftm_alarm0: rtc@29d0000 {
compatible = "fsl,ls1046a-ftm-alarm";
reg = <0x0 0x29d0000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x20000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
index aa52ff73ff9e..d238a8440a81 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
@@ -113,7 +113,7 @@
3 0 0x5 0x20000000 0x00010000>;
status = "okay";
- nor@0,0 {
+ flash@0,0 {
compatible = "cfi-flash";
reg = <0x0 0x0 0x8000000>;
bank-width = <2>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 604bf88d70b3..8ce4b6aae79d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -118,7 +118,7 @@
<0x0 0x0c0c0000 0 0x2000>, /* GICC */
<0x0 0x0c0d0000 0 0x1000>, /* GICH */
<0x0 0x0c0e0000 0 0x20000>; /* GICV */
- interrupts = <1 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
@@ -131,7 +131,7 @@
};
thermal-zones {
- core-cluster {
+ core-cluster-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 0>;
@@ -166,7 +166,7 @@
};
};
- soc {
+ soc-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 1>;
@@ -183,10 +183,10 @@
timer {
compatible = "arm,armv8-timer";
- interrupts = <1 13 IRQ_TYPE_LEVEL_LOW>,/* Physical Secure PPI */
- <1 14 IRQ_TYPE_LEVEL_LOW>,/* Physical Non-Secure PPI */
- <1 11 IRQ_TYPE_LEVEL_LOW>,/* Virtual PPI */
- <1 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,/* Physical Secure PPI */
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,/* Physical Non-Secure PPI */
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,/* Virtual PPI */
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */
};
pmu {
@@ -280,7 +280,7 @@
tmu: tmu@1f80000 {
compatible = "fsl,qoriq-tmu";
reg = <0x0 0x1f80000 0x0 0x10000>;
- interrupts = <0 23 0x4>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x70062>;
fsl,tmu-calibration =
/* Calibration data group 1 */
@@ -347,7 +347,7 @@
reg = <0x0 0x21c0500 0x0 0x100>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
- interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -356,14 +356,14 @@
reg = <0x0 0x21c0600 0x0 0x100>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
- interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
gpio0: gpio@2300000 {
compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
- interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
gpio-controller;
#gpio-cells = <2>;
@@ -374,7 +374,7 @@
gpio1: gpio@2310000 {
compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2310000 0x0 0x10000>;
- interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
gpio-controller;
#gpio-cells = <2>;
@@ -385,7 +385,7 @@
gpio2: gpio@2320000 {
compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2320000 0x0 0x10000>;
- interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
gpio-controller;
#gpio-cells = <2>;
@@ -396,7 +396,7 @@
gpio3: gpio@2330000 {
compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2330000 0x0 0x10000>;
- interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
gpio-controller;
#gpio-cells = <2>;
@@ -407,7 +407,7 @@
ifc: memory-controller@2240000 {
compatible = "fsl,ifc";
reg = <0x0 0x2240000 0x0 0x20000>;
- interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
#address-cells = <2>;
#size-cells = <1>;
@@ -419,7 +419,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2000000 0x0 0x10000>;
- interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(8)>;
status = "disabled";
@@ -430,7 +430,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2010000 0x0 0x10000>;
- interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(8)>;
status = "disabled";
@@ -441,7 +441,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2020000 0x0 0x10000>;
- interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(8)>;
status = "disabled";
@@ -452,7 +452,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2030000 0x0 0x10000>;
- interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(8)>;
status = "disabled";
@@ -474,10 +474,10 @@
status = "disabled";
};
- esdhc: esdhc@2140000 {
+ esdhc: mmc@2140000 {
compatible = "fsl,ls1088a-esdhc", "fsl,esdhc";
reg = <0x0 0x2140000 0x0 0x10000>;
- interrupts = <0 28 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <0>;
clocks = <&clockgen QORIQ_CLK_HWACCEL 1>;
voltage-ranges = <1800 1800 3300 3300>;
@@ -490,7 +490,7 @@
usb0: usb@3100000 {
compatible = "snps,dwc3";
reg = <0x0 0x3100000 0x0 0x10000>;
- interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -501,7 +501,7 @@
usb1: usb@3110000 {
compatible = "snps,dwc3";
reg = <0x0 0x3110000 0x0 0x10000>;
- interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -514,7 +514,7 @@
reg = <0x0 0x3200000 0x0 0x10000>,
<0x7 0x100520 0x0 0x4>;
reg-names = "ahci", "sata-ecc";
- interrupts = <0 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
dma-coherent;
@@ -565,7 +565,7 @@
reg = <0x00 0x03400000 0x0 0x00100000>, /* controller registers */
<0x20 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
interrupt-names = "aer";
#address-cells = <3>;
#size-cells = <2>;
@@ -604,7 +604,7 @@
reg = <0x00 0x03500000 0x0 0x00100000>, /* controller registers */
<0x28 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
interrupt-names = "aer";
#address-cells = <3>;
#size-cells = <2>;
@@ -642,7 +642,7 @@
reg = <0x00 0x03600000 0x0 0x00100000>, /* controller registers */
<0x30 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
interrupt-names = "aer";
#address-cells = <3>;
#size-cells = <2>;
@@ -880,7 +880,7 @@
};
};
- cluster1_core0_watchdog: wdt@c000000 {
+ cluster1_core0_watchdog: watchdog@c000000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc000000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -890,7 +890,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster1_core1_watchdog: wdt@c010000 {
+ cluster1_core1_watchdog: watchdog@c010000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc010000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -900,7 +900,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster1_core2_watchdog: wdt@c020000 {
+ cluster1_core2_watchdog: watchdog@c020000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc020000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -910,7 +910,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster1_core3_watchdog: wdt@c030000 {
+ cluster1_core3_watchdog: watchdog@c030000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc030000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -920,7 +920,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster2_core0_watchdog: wdt@c100000 {
+ cluster2_core0_watchdog: watchdog@c100000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc100000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -930,7 +930,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster2_core1_watchdog: wdt@c110000 {
+ cluster2_core1_watchdog: watchdog@c110000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc110000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -940,7 +940,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster2_core2_watchdog: wdt@c120000 {
+ cluster2_core2_watchdog: watchdog@c120000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc120000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -950,7 +950,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster2_core3_watchdog: wdt@c130000 {
+ cluster2_core3_watchdog: watchdog@c130000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc130000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -1040,7 +1040,7 @@
little-endian;
};
- ftm_alarm0: timer@2800000 {
+ ftm_alarm0: rtc@2800000 {
compatible = "fsl,ls1088a-ftm-alarm";
reg = <0x0 0x2800000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index 1aa38ed09aa4..e9bc1f4fa13c 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -12,6 +12,13 @@
#include <dt-bindings/clock/fsl,qoriq-clockgen.h>
#include "fsl-ls208xa.dtsi"
+/ {
+ pmu {
+ compatible = "arm,cortex-a57-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
&cpu {
cpu0: cpu@0 {
device_type = "cpu";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
index 8581ea55d254..60c422560e33 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
@@ -12,6 +12,13 @@
#include <dt-bindings/clock/fsl,qoriq-clockgen.h>
#include "fsl-ls208xa.dtsi"
+/ {
+ pmu {
+ compatible = "arm,cortex-a72-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
&cpu {
cpu0: cpu@0 {
device_type = "cpu";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
index e2c94da6d6e8..9178cd61c786 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
@@ -43,7 +43,7 @@
0x2 0x0 0x5 0x30000000 0x00010000
0x3 0x0 0x5 0x20000000 0x00010000>;
- nor@0,0 {
+ flash@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi
index 537cecb13dd0..69cd05a30b85 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi
@@ -21,7 +21,7 @@
0x2 0x0 0x5 0x30000000 0x00010000
0x3 0x0 0x5 0x20000000 0x00010000>;
- nor@0,0 {
+ flash@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index 0b7292835906..bde89de2576e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -58,7 +58,7 @@
#size-cells = <2>;
ranges;
interrupt-controller;
- interrupts = <1 9 0x4>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
its: msi-controller@6020000 {
compatible = "arm,gic-v3-its";
@@ -80,7 +80,7 @@
};
thermal-zones {
- ddr-controller1 {
+ ddr-ctrl1-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 1>;
@@ -94,7 +94,7 @@
};
};
- ddr-controller2 {
+ ddr-ctrl2-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 2>;
@@ -108,7 +108,7 @@
};
};
- ddr-controller3 {
+ ddr-ctrl3-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 3>;
@@ -122,7 +122,7 @@
};
};
- core-cluster1 {
+ core-cluster1-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 4>;
@@ -151,7 +151,7 @@
};
};
- core-cluster2 {
+ core-cluster2-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 5>;
@@ -180,7 +180,7 @@
};
};
- core-cluster3 {
+ core-cluster3-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 6>;
@@ -209,7 +209,7 @@
};
};
- core-cluster4 {
+ core-cluster4-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 7>;
@@ -241,15 +241,10 @@
timer: timer {
compatible = "arm,armv8-timer";
- interrupts = <1 13 4>, /* Physical Secure PPI, active-low */
- <1 14 4>, /* Physical Non-Secure PPI, active-low */
- <1 11 4>, /* Virtual PPI, active-low */
- <1 10 4>; /* Hypervisor PPI, active-low */
- };
-
- pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <1 7 0x8>; /* PMU PPI, Level low type */
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>, /* Physical Secure PPI */
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>, /* Physical Non-Secure PPI */
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>, /* Virtual PPI */
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>; /* Hypervisor PPI */
};
psci {
@@ -319,7 +314,7 @@
tmu: tmu@1f80000 {
compatible = "fsl,qoriq-tmu";
reg = <0x0 0x1f80000 0x0 0x10000>;
- interrupts = <0 23 0x4>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>;
fsl,tmu-calibration =
<0x00000000 0x00000026>,
@@ -367,7 +362,7 @@
reg = <0x0 0x21c0500 0x0 0x100>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
- interrupts = <0 32 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
serial1: serial@21c0600 {
@@ -375,7 +370,7 @@
reg = <0x0 0x21c0600 0x0 0x100>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
- interrupts = <0 32 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
serial2: serial@21d0500 {
@@ -383,7 +378,7 @@
reg = <0x0 0x21d0500 0x0 0x100>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
- interrupts = <0 33 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
};
serial3: serial@21d0600 {
@@ -391,10 +386,10 @@
reg = <0x0 0x21d0600 0x0 0x100>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
- interrupts = <0 33 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
};
- cluster1_core0_watchdog: wdt@c000000 {
+ cluster1_core0_watchdog: watchdog@c000000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc000000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -404,7 +399,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster1_core1_watchdog: wdt@c010000 {
+ cluster1_core1_watchdog: watchdog@c010000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc010000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -414,7 +409,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster2_core0_watchdog: wdt@c100000 {
+ cluster2_core0_watchdog: watchdog@c100000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc100000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -424,7 +419,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster2_core1_watchdog: wdt@c110000 {
+ cluster2_core1_watchdog: watchdog@c110000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc110000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -434,7 +429,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster3_core0_watchdog: wdt@c200000 {
+ cluster3_core0_watchdog: watchdog@c200000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc200000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -444,7 +439,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster3_core1_watchdog: wdt@c210000 {
+ cluster3_core1_watchdog: watchdog@c210000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc210000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -454,7 +449,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster4_core0_watchdog: wdt@c300000 {
+ cluster4_core0_watchdog: watchdog@c300000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc300000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -464,7 +459,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- cluster4_core1_watchdog: wdt@c310000 {
+ cluster4_core1_watchdog: watchdog@c310000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0 0xc310000 0x0 0x1000>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
@@ -888,48 +883,48 @@
#iommu-cells = <1>;
stream-match-mask = <0x7C00>;
dma-coherent;
- interrupts = <0 13 4>, /* global secure fault */
- <0 14 4>, /* combined secure interrupt */
- <0 15 4>, /* global non-secure fault */
- <0 16 4>, /* combined non-secure interrupt */
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, /* global secure fault */
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, /* combined secure interrupt */
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, /* global non-secure fault */
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, /* combined non-secure interrupt */
/* performance counter interrupts 0-7 */
- <0 211 4>, <0 212 4>,
- <0 213 4>, <0 214 4>,
- <0 215 4>, <0 216 4>,
- <0 217 4>, <0 218 4>,
+ <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
/* per context interrupt, 64 interrupts */
- <0 146 4>, <0 147 4>,
- <0 148 4>, <0 149 4>,
- <0 150 4>, <0 151 4>,
- <0 152 4>, <0 153 4>,
- <0 154 4>, <0 155 4>,
- <0 156 4>, <0 157 4>,
- <0 158 4>, <0 159 4>,
- <0 160 4>, <0 161 4>,
- <0 162 4>, <0 163 4>,
- <0 164 4>, <0 165 4>,
- <0 166 4>, <0 167 4>,
- <0 168 4>, <0 169 4>,
- <0 170 4>, <0 171 4>,
- <0 172 4>, <0 173 4>,
- <0 174 4>, <0 175 4>,
- <0 176 4>, <0 177 4>,
- <0 178 4>, <0 179 4>,
- <0 180 4>, <0 181 4>,
- <0 182 4>, <0 183 4>,
- <0 184 4>, <0 185 4>,
- <0 186 4>, <0 187 4>,
- <0 188 4>, <0 189 4>,
- <0 190 4>, <0 191 4>,
- <0 192 4>, <0 193 4>,
- <0 194 4>, <0 195 4>,
- <0 196 4>, <0 197 4>,
- <0 198 4>, <0 199 4>,
- <0 200 4>, <0 201 4>,
- <0 202 4>, <0 203 4>,
- <0 204 4>, <0 205 4>,
- <0 206 4>, <0 207 4>,
- <0 208 4>, <0 209 4>;
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, <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>, <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
};
dspi: spi@2100000 {
@@ -938,18 +933,18 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2100000 0x0 0x10000>;
- interrupts = <0 26 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
clock-names = "dspi";
spi-num-chipselects = <5>;
};
- esdhc: esdhc@2140000 {
+ esdhc: mmc@2140000 {
status = "disabled";
compatible = "fsl,ls2080a-esdhc", "fsl,esdhc";
reg = <0x0 0x2140000 0x0 0x10000>;
- interrupts = <0 28 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
voltage-ranges = <1800 1800 3300 3300>;
@@ -961,7 +956,7 @@
gpio0: gpio@2300000 {
compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
- interrupts = <0 36 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
little-endian;
#gpio-cells = <2>;
@@ -972,7 +967,7 @@
gpio1: gpio@2310000 {
compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2310000 0x0 0x10000>;
- interrupts = <0 36 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
little-endian;
#gpio-cells = <2>;
@@ -983,7 +978,7 @@
gpio2: gpio@2320000 {
compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2320000 0x0 0x10000>;
- interrupts = <0 37 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
little-endian;
#gpio-cells = <2>;
@@ -994,7 +989,7 @@
gpio3: gpio@2330000 {
compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2330000 0x0 0x10000>;
- interrupts = <0 37 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
little-endian;
#gpio-cells = <2>;
@@ -1008,8 +1003,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2000000 0x0 0x10000>;
- interrupts = <0 34 0x4>; /* Level high type */
- clock-names = "i2c";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
};
@@ -1020,8 +1015,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2010000 0x0 0x10000>;
- interrupts = <0 34 0x4>; /* Level high type */
- clock-names = "i2c";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
};
@@ -1032,8 +1027,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2020000 0x0 0x10000>;
- interrupts = <0 35 0x4>; /* Level high type */
- clock-names = "i2c";
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
};
@@ -1044,8 +1039,8 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2030000 0x0 0x10000>;
- interrupts = <0 35 0x4>; /* Level high type */
- clock-names = "i2c";
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
};
@@ -1053,7 +1048,7 @@
ifc: memory-controller@2240000 {
compatible = "fsl,ifc";
reg = <0x0 0x2240000 0x0 0x20000>;
- interrupts = <0 21 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
#address-cells = <2>;
#size-cells = <1>;
@@ -1082,7 +1077,7 @@
pcie1: pcie@3400000 {
compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie";
reg-names = "regs", "config";
- interrupts = <0 108 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
#address-cells = <3>;
#size-cells = <2>;
@@ -1104,7 +1099,7 @@
pcie2: pcie@3500000 {
compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie";
reg-names = "regs", "config";
- interrupts = <0 113 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
#address-cells = <3>;
#size-cells = <2>;
@@ -1126,7 +1121,7 @@
pcie3: pcie@3600000 {
compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie";
reg-names = "regs", "config";
- interrupts = <0 118 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
#address-cells = <3>;
#size-cells = <2>;
@@ -1148,7 +1143,7 @@
pcie4: pcie@3700000 {
compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie";
reg-names = "regs", "config";
- interrupts = <0 123 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
#address-cells = <3>;
#size-cells = <2>;
@@ -1171,7 +1166,7 @@
status = "disabled";
compatible = "fsl,ls2080a-ahci";
reg = <0x0 0x3200000 0x0 0x10000>;
- interrupts = <0 133 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
dma-coherent;
@@ -1181,7 +1176,7 @@
status = "disabled";
compatible = "fsl,ls2080a-ahci";
reg = <0x0 0x3210000 0x0 0x10000>;
- interrupts = <0 136 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
dma-coherent;
@@ -1197,7 +1192,7 @@
usb0: usb@3100000 {
compatible = "snps,dwc3";
reg = <0x0 0x3100000 0x0 0x10000>;
- interrupts = <0 80 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -1208,7 +1203,7 @@
usb1: usb@3110000 {
compatible = "snps,dwc3";
reg = <0x0 0x3110000 0x0 0x10000>;
- interrupts = <0 81 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
@@ -1220,7 +1215,7 @@
ccn@4000000 {
compatible = "arm,ccn-504";
reg = <0x0 0x04000000 0x0 0x01000000>;
- interrupts = <0 12 4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
};
rcpm: power-controller@1e34040 {
@@ -1230,7 +1225,7 @@
little-endian;
};
- ftm_alarm0: timer@2800000 {
+ ftm_alarm0: rtc@2800000 {
compatible = "fsl,ls208xa-ftm-alarm";
reg = <0x0 0x2800000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0>;
@@ -1241,14 +1236,14 @@
ddr1: memory-controller@1080000 {
compatible = "fsl,qoriq-memory-controller";
reg = <0x0 0x1080000 0x0 0x1000>;
- interrupts = <0 17 0x4>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
};
ddr2: memory-controller@1090000 {
compatible = "fsl,qoriq-memory-controller";
reg = <0x0 0x1090000 0x0 0x1000>;
- interrupts = <0 18 0x4>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index e665c629e1a1..26c7ca31e22e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -449,7 +449,7 @@
};
thermal-zones {
- cluster6-7 {
+ cluster6-7-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 0>;
@@ -492,7 +492,7 @@
};
};
- ddr-cluster5 {
+ ddr-cluster5-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 1>;
@@ -512,7 +512,7 @@
};
};
- wriop {
+ wriop-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 2>;
@@ -532,7 +532,7 @@
};
};
- dce-qbman-hsio2 {
+ dce-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 3>;
@@ -552,7 +552,7 @@
};
};
- ccn-dpaa-tbu {
+ ccn-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 4>;
@@ -572,7 +572,7 @@
};
};
- cluster4-hsio3 {
+ cluster4-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 5>;
@@ -592,7 +592,7 @@
};
};
- cluster2-3 {
+ cluster2-3-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu 6>;
@@ -745,10 +745,13 @@
#size-cells = <0>;
reg = <0x0 0x2000000 0x0 0x10000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
- scl-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c0_scl>;
+ pinctrl-1 = <&i2c0_scl_gpio>;
+ scl-gpios = <&gpio0 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -758,9 +761,13 @@
#size-cells = <0>;
reg = <0x0 0x2010000 0x0 0x10000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c1_scl>;
+ pinctrl-1 = <&i2c1_scl_gpio>;
+ scl-gpios = <&gpio0 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -770,9 +777,13 @@
#size-cells = <0>;
reg = <0x0 0x2020000 0x0 0x10000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c2_scl>;
+ pinctrl-1 = <&i2c2_scl_gpio>;
+ scl-gpios = <&gpio0 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -782,9 +793,13 @@
#size-cells = <0>;
reg = <0x0 0x2030000 0x0 0x10000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c3_scl>;
+ pinctrl-1 = <&i2c3_scl_gpio>;
+ scl-gpios = <&gpio0 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -794,10 +809,13 @@
#size-cells = <0>;
reg = <0x0 0x2040000 0x0 0x10000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
- scl-gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c4_scl>;
+ pinctrl-1 = <&i2c4_scl_gpio>;
+ scl-gpios = <&gpio0 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -807,9 +825,13 @@
#size-cells = <0>;
reg = <0x0 0x2050000 0x0 0x10000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c5_scl>;
+ pinctrl-1 = <&i2c5_scl_gpio>;
+ scl-gpios = <&gpio0 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -819,9 +841,13 @@
#size-cells = <0>;
reg = <0x0 0x2060000 0x0 0x10000>;
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c6_scl>;
+ pinctrl-1 = <&i2c6_scl_gpio>;
+ scl-gpios = <&gpio1 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -831,9 +857,13 @@
#size-cells = <0>;
reg = <0x0 0x2070000 0x0 0x10000>;
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "i2c";
+ clock-names = "ipg";
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(16)>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c7_scl>;
+ pinctrl-1 = <&i2c7_scl_gpio>;
+ scl-gpios = <&gpio1 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
};
@@ -895,10 +925,10 @@
status = "disabled";
};
- esdhc0: esdhc@2140000 {
- compatible = "fsl,esdhc";
+ esdhc0: mmc@2140000 {
+ compatible = "fsl,ls2080a-esdhc", "fsl,esdhc";
reg = <0x0 0x2140000 0x0 0x10000>;
- interrupts = <0 28 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
dma-coherent;
@@ -909,10 +939,10 @@
status = "disabled";
};
- esdhc1: esdhc@2150000 {
- compatible = "fsl,esdhc";
+ esdhc1: mmc@2150000 {
+ compatible = "fsl,ls2080a-esdhc", "fsl,esdhc";
reg = <0x0 0x2150000 0x0 0x10000>;
- interrupts = <0 63 0x4>; /* Level high type */
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(2)>;
dma-coherent;
@@ -997,7 +1027,7 @@
};
gpio0: gpio@2300000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -1008,7 +1038,7 @@
};
gpio1: gpio@2310000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2310000 0x0 0x10000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -1019,7 +1049,7 @@
};
gpio2: gpio@2320000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2320000 0x0 0x10000>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -1030,7 +1060,7 @@
};
gpio3: gpio@2330000 {
- compatible = "fsl,qoriq-gpio";
+ compatible = "fsl,ls2080a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2330000 0x0 0x10000>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
@@ -1055,7 +1085,7 @@
little-endian;
};
- ftm_alarm0: timer@2800000 {
+ ftm_alarm0: rtc@2800000 {
compatible = "fsl,lx2160a-ftm-alarm";
reg = <0x0 0x2800000 0x0 0x10000>;
fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0 0x0>;
@@ -1669,6 +1699,80 @@
};
};
+ pinmux_i2crv: pinmux@70010012c {
+ compatible = "pinctrl-single";
+ reg = <0x00000007 0x0010012c 0x0 0xc>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,bit-per-mux;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0x7>;
+
+ i2c1_scl: i2c1-scl-pins {
+ pinctrl-single,bits = <0x0 0 0x7>;
+ };
+
+ i2c1_scl_gpio: i2c1-scl-gpio-pins {
+ pinctrl-single,bits = <0x0 0x1 0x7>;
+ };
+
+ i2c2_scl: i2c2-scl-pins {
+ pinctrl-single,bits = <0x0 0 (0x7 << 3)>;
+ };
+
+ i2c2_scl_gpio: i2c2-scl-gpio-pins {
+ pinctrl-single,bits = <0x0 (0x1 << 3) (0x7 << 3)>;
+ };
+
+ i2c3_scl: i2c3-scl-pins {
+ pinctrl-single,bits = <0x0 0 (0x7 << 6)>;
+ };
+
+ i2c3_scl_gpio: i2c3-scl-gpio-pins {
+ pinctrl-single,bits = <0x0 (0x1 << 6) (0x7 << 6)>;
+ };
+
+ i2c4_scl: i2c4-scl-pins {
+ pinctrl-single,bits = <0x0 0 (0x7 << 9)>;
+ };
+
+ i2c4_scl_gpio: i2c4-scl-gpio-pins {
+ pinctrl-single,bits = <0x0 (0x1 << 9) (0x7 << 9)>;
+ };
+
+ i2c5_scl: i2c5-scl-pins {
+ pinctrl-single,bits = <0x0 0 (0x7 << 12)>;
+ };
+
+ i2c5_scl_gpio: i2c5-scl-gpio-pins {
+ pinctrl-single,bits = <0x0 (0x1 << 12) (0x7 << 12)>;
+ };
+
+ i2c6_scl: i2c6-scl-pins {
+ pinctrl-single,bits = <0x4 0x2 0x7>;
+ };
+
+ i2c6_scl_gpio: i2c6-scl-gpio-pins {
+ pinctrl-single,bits = <0x4 0x1 0x7>;
+ };
+
+ i2c7_scl: i2c7-scl-pins {
+ pinctrl-single,bits = <0x4 0x2 0x7>;
+ };
+
+ i2c7_scl_gpio: i2c7-scl-gpio-pins {
+ pinctrl-single,bits = <0x4 0x1 0x7>;
+ };
+
+ i2c0_scl: i2c0-scl-pins {
+ pinctrl-single,bits = <0x8 0 (0x7 << 10)>;
+ };
+
+ i2c0_scl_gpio: i2c0-scl-gpio-pins {
+ pinctrl-single,bits = <0x8 (0x1 << 10) (0x7 << 10)>;
+ };
+ };
+
fsl_mc: fsl-mc@80c000000 {
compatible = "fsl,qoriq-mc";
reg = <0x00000008 0x0c000000 0 0x40>,
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
index 9f88583aa25e..eafef8718a0f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
@@ -25,6 +25,7 @@
i2c7 = &mpcie1_i2c;
i2c8 = &mpcie0_i2c;
i2c9 = &pcieclk_i2c;
+ i2c10 = &i2c5;
mmc0 = &esdhc0;
mmc1 = &esdhc1;
serial0 = &uart0;
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
index 0580ea30cfbc..e914291e63a1 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
@@ -71,3 +71,12 @@
reg = <0x54>;
};
};
+
+&i2c5 {
+ status = "okay";
+
+ rtc@6f {
+ compatible = "microchip,mcp7940x";
+ reg = <0x6f>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
index 07afeb78ed56..ff5df0fed9e9 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/clock/imx8-clock.h>
#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/dma/fsl-edma.h>
#include <dt-bindings/firmware/imx/rsrc.h>
audio_ipg_clk: clock-audio-ipg {
@@ -119,13 +120,96 @@ audio_subsys: bus@59000000 {
#size-cells = <1>;
ranges = <0x59000000 0x0 0x59000000 0x1000000>;
+ asrc0: asrc@59000000 {
+ compatible = "fsl,imx8qm-asrc";
+ reg = <0x59000000 0x10000>;
+ interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&asrc0_lpcg IMX_LPCG_CLK_0>,
+ <&asrc0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div0_lpcg IMX_LPCG_CLK_4>,
+ <&aud_pll_div1_lpcg IMX_LPCG_CLK_4>,
+ <&acm IMX_ADMA_ACM_AUD_CLK0_SEL>,
+ <&acm IMX_ADMA_ACM_AUD_CLK1_SEL>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "mem", "ipg",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+ "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+ "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+ "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+ "spba";
+ dmas = <&edma0 0 0 0>,
+ <&edma0 1 0 0>,
+ <&edma0 2 0 0>,
+ <&edma0 3 0 FSL_EDMA_RX>,
+ <&edma0 4 0 FSL_EDMA_RX>,
+ <&edma0 5 0 FSL_EDMA_RX>;
+ /* tx* is output channel of asrc, it is rx channel for eDMA */
+ dma-names = "rxa", "rxb", "rxc", "txa", "txb", "txc";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-width = <16>;
+ fsl,asrc-clk-map = <0>;
+ power-domains = <&pd IMX_SC_R_ASRC_0>;
+ status = "disabled";
+ };
+
+ esai0: esai@59010000 {
+ compatible = "fsl,imx8qm-esai";
+ reg = <0x59010000 0x10000>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&esai0_lpcg IMX_LPCG_CLK_4>,
+ <&esai0_lpcg IMX_LPCG_CLK_0>,
+ <&esai0_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>;
+ clock-names = "core", "extal", "fsys", "spba";
+ dmas = <&edma0 6 0 FSL_EDMA_RX>, <&edma0 7 0 0>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd IMX_SC_R_ESAI_0>;
+ status = "disabled";
+ };
+
+ spdif0: spdif@59020000 {
+ compatible = "fsl,imx8qm-spdif";
+ reg = <0x59020000 0x10000>;
+ interrupts = <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, /* rx */
+ <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>; /* tx */
+ clocks = <&spdif0_lpcg IMX_LPCG_CLK_4>, /* core */
+ <&clk_dummy>, /* rxtx0 */
+ <&spdif0_lpcg IMX_LPCG_CLK_0>, /* rxtx1 */
+ <&clk_dummy>, /* rxtx2 */
+ <&clk_dummy>, /* rxtx3 */
+ <&clk_dummy>, /* rxtx4 */
+ <&audio_ipg_clk>, /* rxtx5 */
+ <&clk_dummy>, /* rxtx6 */
+ <&clk_dummy>, /* rxtx7 */
+ <&clk_dummy>; /* spba */
+ clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6", "rxtx7", "spba";
+ dmas = <&edma0 8 0 (FSL_EDMA_MULTI_FIFO | FSL_EDMA_RX)>,
+ <&edma0 9 0 FSL_EDMA_MULTI_FIFO>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd IMX_SC_R_SPDIF_0>;
+ status = "disabled";
+ };
+
sai0: sai@59040000 {
compatible = "fsl,imx8qm-sai";
reg = <0x59040000 0x10000>;
interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sai0_lpcg 1>,
+ clocks = <&sai0_lpcg IMX_LPCG_CLK_4>,
<&clk_dummy>,
- <&sai0_lpcg 0>,
+ <&sai0_lpcg IMX_LPCG_CLK_0>,
<&clk_dummy>,
<&clk_dummy>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -139,9 +223,9 @@ audio_subsys: bus@59000000 {
compatible = "fsl,imx8qm-sai";
reg = <0x59050000 0x10000>;
interrupts = <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sai1_lpcg 1>,
+ clocks = <&sai1_lpcg IMX_LPCG_CLK_4>,
<&clk_dummy>,
- <&sai1_lpcg 0>,
+ <&sai1_lpcg IMX_LPCG_CLK_0>,
<&clk_dummy>,
<&clk_dummy>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -155,9 +239,9 @@ audio_subsys: bus@59000000 {
compatible = "fsl,imx8qm-sai";
reg = <0x59060000 0x10000>;
interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sai2_lpcg 1>,
+ clocks = <&sai2_lpcg IMX_LPCG_CLK_4>,
<&clk_dummy>,
- <&sai2_lpcg 0>,
+ <&sai2_lpcg IMX_LPCG_CLK_0>,
<&clk_dummy>,
<&clk_dummy>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -171,9 +255,9 @@ audio_subsys: bus@59000000 {
compatible = "fsl,imx8qm-sai";
reg = <0x59070000 0x10000>;
interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sai3_lpcg 1>,
+ clocks = <&sai3_lpcg IMX_LPCG_CLK_4>,
<&clk_dummy>,
- <&sai3_lpcg 0>,
+ <&sai3_lpcg IMX_LPCG_CLK_0>,
<&clk_dummy>,
<&clk_dummy>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -239,6 +323,40 @@ audio_subsys: bus@59000000 {
<&pd IMX_SC_R_DMA_0_CH23>;
};
+ asrc0_lpcg: clock-controller@59400000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59400000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>;
+ clock-output-names = "asrc0_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_ASRC_0>;
+ };
+
+ esai0_lpcg: clock-controller@59410000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59410000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_ESAI0_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "esai0_lpcg_extal_clk",
+ "esai0_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_ESAI_0>;
+ };
+
+ spdif0_lpcg: clock-controller@59420000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59420000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SPDIF0_TX_CLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "spdif0_lpcg_tx_clk",
+ "spdif0_lpcg_gclkw";
+ power-domains = <&pd IMX_SC_R_SPDIF_0>;
+ };
+
sai0_lpcg: clock-controller@59440000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x59440000 0x10000>;
@@ -329,7 +447,101 @@ audio_subsys: bus@59000000 {
<&lsio_mu13 2 1>,
<&lsio_mu13 3 0>,
<&lsio_mu13 3 1>;
- memory-region = <&dsp_reserved>;
+ status = "disabled";
+ };
+
+ asrc1: asrc@59800000 {
+ compatible = "fsl,imx8qm-asrc";
+ reg = <0x59800000 0x10000>;
+ interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&asrc1_lpcg IMX_LPCG_CLK_4>,
+ <&asrc1_lpcg IMX_LPCG_CLK_4>,
+ <&aud_pll_div0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>,
+ <&acm IMX_ADMA_ACM_AUD_CLK0_SEL>,
+ <&acm IMX_ADMA_ACM_AUD_CLK1_SEL>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "mem", "ipg",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+ "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+ "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+ "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+ "spba";
+ dmas = <&edma1 0 0 0>,
+ <&edma1 1 0 0>,
+ <&edma1 2 0 0>,
+ <&edma1 3 0 FSL_EDMA_RX>,
+ <&edma1 4 0 FSL_EDMA_RX>,
+ <&edma1 5 0 FSL_EDMA_RX>;
+ /* tx* is output channel of asrc, it is rx channel for eDMA */
+ dma-names = "rxa", "rxb", "rxc", "txa", "txb", "txc";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-width = <16>;
+ fsl,asrc-clk-map = <1>;
+ power-domains = <&pd IMX_SC_R_ASRC_1>;
+ status = "disabled";
+ };
+
+ sai4: sai@59820000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59820000 0x10000>;
+ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai4_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&sai4_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&edma1 8 0 FSL_EDMA_RX>, <&edma1 9 0 0>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd IMX_SC_R_SAI_4>;
+ status = "disabled";
+ };
+
+ sai5: sai@59830000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59830000 0x10000>;
+ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai5_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&sai5_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&edma1 10 0 0>;
+ dma-names = "tx";
+ power-domains = <&pd IMX_SC_R_SAI_5>;
+ status = "disabled";
+ };
+
+ amix: amix@59840000 {
+ compatible = "fsl,imx8qm-audmix";
+ reg = <0x59840000 0x10000>;
+ clocks = <&amix_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "ipg";
+ power-domains = <&pd IMX_SC_R_AMIX>;
+ dais = <&sai4>, <&sai5>;
+ status = "disabled";
+ };
+
+ mqs: mqs@59850000 {
+ compatible = "fsl,imx8qm-mqs";
+ reg = <0x59850000 0x10000>;
+ clocks = <&mqs0_lpcg IMX_LPCG_CLK_4>, <&mqs0_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk", "core";
+ power-domains = <&pd IMX_SC_R_MQS_0>;
status = "disabled";
};
@@ -481,4 +693,60 @@ audio_subsys: bus@59000000 {
"sai3_rx_bclk",
"sai4_rx_bclk";
};
+
+ asrc1_lpcg: clock-controller@59c00000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c00000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>;
+ clock-output-names = "asrc1_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_ASRC_1>;
+ };
+
+ sai4_lpcg: clock-controller@59c20000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c20000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI4_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "sai4_lpcg_mclk",
+ "sai4_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_4>;
+ };
+
+ sai5_lpcg: clock-controller@59c30000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c30000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI5_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "sai5_lpcg_mclk",
+ "sai5_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_5>;
+ };
+
+ amix_lpcg: clock-controller@59c40000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c40000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "amix_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_AMIX>;
+ };
+
+ mqs0_lpcg: clock-controller@59c50000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c50000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_MQS_TX_CLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "mqs0_lpcg_mclk",
+ "mqs0_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_MQS_0>;
+ };
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
new file mode 100644
index 000000000000..92752c0c5eb5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ * Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+cm40_ipg_clk: clock-cm40-ipg {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <132000000>;
+ clock-output-names = "cm40_ipg_clk";
+};
+
+cm40_subsys: bus@34000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x34000000 0x0 0x34000000 0x4000000>;
+ interrupt-parent = <&cm40_intmux>;
+
+ cm40_lpuart: serial@37220000 {
+ compatible = "fsl,imx8qxp-lpuart";
+ reg = <0x37220000 0x1000>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cm40_uart_lpcg IMX_LPCG_CLK_1>, <&cm40_uart_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "ipg", "baud";
+ assigned-clocks = <&clk IMX_SC_R_M4_0_UART IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd IMX_SC_R_M4_0_UART>;
+ status = "disabled";
+ };
+
+ cm40_i2c: i2c@37230000 {
+ compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x37230000 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cm40_i2c_lpcg IMX_LPCG_CLK_0>,
+ <&cm40_i2c_lpcg IMX_LPCG_CLK_4>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX_SC_R_M4_0_I2C IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd IMX_SC_R_M4_0_I2C>;
+ status = "disabled";
+ };
+
+ cm40_intmux: intmux@37400000 {
+ compatible = "fsl,imx-intmux";
+ reg = <0x37400000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&cm40_ipg_clk>;
+ clock-names = "ipg";
+ power-domains = <&pd IMX_SC_R_M4_0_INTMUX>;
+ status = "disabled";
+ };
+
+ cm40_uart_lpcg: clock-controller@37620000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x37620000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_M4_0_UART IMX_SC_PM_CLK_PER>,
+ <&cm40_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>;
+ clock-output-names = "cm40_lpcg_uart_clk",
+ "cm40_lpcg_uart_ipg_clk";
+ power-domains = <&pd IMX_SC_R_M4_0_UART>;
+ };
+
+ cm40_i2c_lpcg: clock-controller@37630000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x37630000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_M4_0_I2C IMX_SC_PM_CLK_PER>,
+ <&cm40_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "cm40_lpcg_i2c_clk",
+ "cm40_lpcg_i2c_ipg_clk";
+ power-domains = <&pd IMX_SC_R_M4_0_I2C>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-cm41.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-cm41.dtsi
new file mode 100644
index 000000000000..d715f2a6b037
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-cm41.dtsi
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ * Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <dt-bindings/clock/imx8-lpcg.h>
+
+cm41_ipg_clk: clock-cm41-ipg {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <132000000>;
+ clock-output-names = "cm41_ipg_clk";
+};
+
+cm41_subsys: bus@38000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x38000000 0x0 0x38000000 0x4000000>;
+ interrupt-parent = <&cm41_intmux>;
+
+ cm41_i2c: i2c@3b230000 {
+ compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x3b230000 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cm41_i2c_lpcg IMX_LPCG_CLK_0>,
+ <&cm41_i2c_lpcg IMX_LPCG_CLK_4>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX_SC_R_M4_1_I2C IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd IMX_SC_R_M4_1_I2C>;
+ status = "disabled";
+ };
+
+ cm41_intmux: intmux@3b400000 {
+ compatible = "fsl,imx-intmux";
+ reg = <0x3b400000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&cm41_ipg_clk>;
+ clock-names = "ipg";
+ power-domains = <&pd IMX_SC_R_M4_1_INTMUX>;
+ status = "disabled";
+ };
+
+ cm41_i2c_lpcg: clock-controller@3b630000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x3b630000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_M4_1_I2C IMX_SC_PM_CLK_PER>,
+ <&cm41_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "cm41_lpcg_i2c_clk",
+ "cm41_lpcg_i2c_ipg_clk";
+ power-domains = <&pd IMX_SC_R_M4_1_I2C>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
index 4aaf5a0c1ed8..a4a10ce03bfe 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
@@ -28,6 +28,13 @@ conn_ipg_clk: clock-conn-ipg {
clock-output-names = "conn_ipg_clk";
};
+conn_bch_clk: clock-conn-bch {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <400000000>;
+ clock-output-names = "conn_bch_clk";
+};
+
conn_subsys: bus@5b000000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -302,4 +309,66 @@ conn_subsys: bus@5b000000 {
"usb3_aclk";
power-domains = <&pd IMX_SC_R_USB_2_PHY>;
};
+
+ rawnand_0_lpcg: clock-controller@5b290000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x5b290000 0x4>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_NAND IMX_SC_PM_CLK_PER>,
+ <&clk IMX_SC_R_NAND IMX_SC_PM_CLK_MST_BUS>,
+ <&conn_axi_clk>,
+ <&conn_axi_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>,
+ <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>;
+ clock-output-names = "gpmi_bch",
+ "gpmi_io",
+ "gpmi_apb",
+ "gpmi_bch_apb";
+ power-domains = <&pd IMX_SC_R_NAND>;
+ };
+
+ rawnand_4_lpcg: clock-controller@5b290004 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x5b290004 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&conn_axi_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>;
+ clock-output-names = "apbhdma_hclk";
+ power-domains = <&pd IMX_SC_R_NAND>;
+ };
+
+ dma_apbh: dma-controller@5b810000 {
+ compatible = "fsl,imx8qxp-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0x5b810000 0x2000>;
+ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&rawnand_4_lpcg IMX_LPCG_CLK_0>;
+ power-domains = <&pd IMX_SC_R_NAND>;
+ };
+
+ gpmi: nand-controller@5b812000{
+ compatible = "fsl,imx8qxp-gpmi-nand";
+ reg = <0x5b812000 0x2000>, <0x5b814000 0x2000>;
+ reg-names = "gpmi-nand", "bch";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&rawnand_0_lpcg IMX_LPCG_CLK_1>,
+ <&rawnand_0_lpcg IMX_LPCG_CLK_4>,
+ <&rawnand_0_lpcg IMX_LPCG_CLK_0>,
+ <&rawnand_0_lpcg IMX_LPCG_CLK_5>;
+ clock-names = "gpmi_io", "gpmi_apb",
+ "gpmi_bch", "gpmi_bch_apb";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ power-domains = <&pd IMX_SC_R_NAND>;
+ assigned-clocks = <&clk IMX_SC_R_NAND IMX_SC_PM_CLK_MST_BUS>;
+ assigned-clock-rates = <50000000>;
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
index e7783cc2d830..77d2928997b4 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
@@ -21,7 +21,6 @@ img_subsys: bus@58000000 {
interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
- clock-names = "per", "ipg";
assigned-clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
assigned-clock-rates = <200000000>, <200000000>;
@@ -35,7 +34,6 @@ img_subsys: bus@58000000 {
interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
- clock-names = "per", "ipg";
assigned-clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
assigned-clock-rates = <200000000>, <200000000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts
new file mode 100644
index 000000000000..c974f5dc0283
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Aster Board";
+ compatible = "toradex,colibri-imx8x-aster",
+ "toradex,colibri-imx8x",
+ "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts
new file mode 100644
index 000000000000..f2bf15463ae8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-eval-v3.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Colibri Evaluation Board V3";
+ compatible = "toradex,colibri-imx8x-eval-v3",
+ "toradex,colibri-imx8x",
+ "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts
new file mode 100644
index 000000000000..fd425c70cf2b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Colibri Iris V2 Board";
+ compatible = "toradex,colibri-imx8x-iris-v2",
+ "toradex,colibri-imx8x",
+ "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts
new file mode 100644
index 000000000000..e5e2346ce4f1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Colibri Iris Board";
+ compatible = "toradex,colibri-imx8x-iris",
+ "toradex,colibri-imx8x",
+ "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi
new file mode 100644
index 000000000000..66b0fcc6687d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include "imx8dx.dtsi"
+#include "imx8x-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX Module";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx.dtsi b/arch/arm64/boot/dts/freescale/imx8dx.dtsi
new file mode 100644
index 000000000000..ce76efc1a041
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2020 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8dxp.dtsi"
+
+&gpu_3d0 {
+ assigned-clock-rates = <372000000>, <372000000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index 2123d431e061..1a74ac3ee4ee 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -16,12 +16,27 @@
mmc0 = &usdhc1;
mmc1 = &usdhc2;
serial0 = &lpuart0;
+ serial1 = &lpuart1;
+ serial6 = &cm40_lpuart;
};
chosen {
stdout-path = &lpuart0;
};
+ imx8dxl-cm4 {
+ compatible = "fsl,imx8qxp-cm4";
+ clocks = <&clk_dummy>;
+ mbox-names = "tx", "rx", "rxdb";
+ mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>;
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+ <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
+ power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>;
+ fsl,resource-id = <IMX_SC_R_M4_0_PID0>;
+ fsl,entry-address = <0x34fe0000>;
+ };
+
+
memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0 0x40000000>;
@@ -49,6 +64,47 @@
alloc-ranges = <0 0x98000000 0 0x14000000>;
linux,cma-default;
};
+
+ vdev0vring0: memory0@90000000 {
+ reg = <0 0x90000000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: memory@90008000 {
+ reg = <0 0x90008000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: memory@90010000 {
+ reg = <0 0x90010000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: memory@90018000 {
+ reg = <0 0x90018000 0 0x8000>;
+ no-map;
+ };
+
+ rsc_table: memory-rsc-table@900ff000 {
+ reg = <0 0x900ff000 0 0x1000>;
+ no-map;
+ };
+
+ vdevbuffer: memory-vdevbuffer@90400000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90400000 0 0x100000>;
+ no-map;
+ };
+ };
+
+ m2_uart1_sel: regulator-m2uart1sel {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "m2_uart1_sel";
+ gpio = <&pca6416_1 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
};
mux3_en: regulator-0 {
@@ -125,6 +181,76 @@
enable-active-high;
regulator-always-on;
};
+
+ bt_sco_codec: audio-codec-bt {
+ compatible = "linux,bt-sco";
+ #sound-dai-cells = <1>;
+ };
+
+ sound-bt-sco {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "bt-sco-audio";
+ simple-audio-card,format = "dsp_a";
+ simple-audio-card,bitclock-inversion;
+ simple-audio-card,frame-master = <&btcpu>;
+ simple-audio-card,bitclock-master = <&btcpu>;
+
+ btcpu: simple-audio-card,cpu {
+ sound-dai = <&sai0>;
+ dai-tdm-slot-num = <2>;
+ dai-tdm-slot-width = <16>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&bt_sco_codec 1>;
+ };
+ };
+
+ sound-wm8960-1 {
+ compatible = "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&wm8960_1>;
+ audio-asrc = <&asrc0>;
+ 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", "Mic Jack",
+ "Mic Jack", "MICB";
+ };
+
+ sound-wm8960-2 {
+ compatible = "fsl,imx-audio-wm8960";
+ model = "wm8960-audio-2";
+ audio-cpu = <&sai2>;
+ audio-codec = <&wm8960_2>;
+ 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", "Mic Jack",
+ "Mic Jack", "MICB";
+ };
+
+ sound-wm8960-3 {
+ compatible = "fsl,imx-audio-wm8960";
+ model = "wm8960-audio-3";
+ audio-cpu = <&sai3>;
+ audio-codec = <&wm8960_3>;
+ 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", "Mic Jack",
+ "Mic Jack", "MICB";
+ };
};
&adc0 {
@@ -132,6 +258,11 @@
status = "okay";
};
+&asrc0 {
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
&eqos {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eqos>;
@@ -259,6 +390,78 @@
};
};
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+
+ wm8960_1: audio-codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&mclkout1_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk";
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>,
+ <49152000>,
+ <12288000>,
+ <12288000>;
+ wlf,shared-lrclk;
+ wlf,hp-cfg = <2 2 3>;
+ wlf,gpio-cfg = <1 3>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+
+ wm8960_2: audio-codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&mclkout1_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk";
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>,
+ <49152000>,
+ <12288000>,
+ <12288000>;
+ wlf,shared-lrclk;
+ wlf,hp-cfg = <2 2 3>;
+ wlf,gpio-cfg = <1 3>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ wm8960_3: audio-codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&mclkout1_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk";
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>,
+ <49152000>,
+ <12288000>,
+ <12288000>;
+ wlf,shared-lrclk;
+ wlf,hp-cfg = <2 2 3>;
+ wlf,gpio-cfg = <1 3>;
+ };
+ };
+
i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
@@ -340,6 +543,16 @@
status = "okay";
};
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+&lsio_mu5 {
+ status = "okay";
+};
+
&flexcan2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan2>;
@@ -354,6 +567,16 @@
status = "okay";
};
+&cm40_intmux {
+ status = "disabled";
+};
+
+&cm40_lpuart {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cm40_lpuart>;
+ status = "disabled";
+};
+
&lsio_gpio4 {
status = "okay";
};
@@ -362,6 +585,53 @@
status = "okay";
};
+&sai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai0_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&sai2 {
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai2_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai3 {
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai3_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
&thermal_zones {
pmic-thermal {
polling-delay-passive = <250>;
@@ -595,6 +865,50 @@
>;
};
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ IMX8DXL_UART1_TX_ADMA_UART1_TX 0x06000020
+ IMX8DXL_UART1_RX_ADMA_UART1_RX 0x06000020
+ IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B 0x06000020
+ IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B 0x06000020
+ >;
+ };
+
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ IMX8DXL_SPI0_CS0_ADMA_SAI0_RXD 0x06000060
+ IMX8DXL_SPI0_CS1_ADMA_SAI0_RXC 0x06000040
+ IMX8DXL_SPI0_SCK_ADMA_SAI0_TXC 0x06000060
+ IMX8DXL_SPI0_SDI_ADMA_SAI0_TXD 0x06000060
+ IMX8DXL_SPI0_SDO_ADMA_SAI0_TXFS 0x06000040
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ IMX8DXL_FLEXCAN0_RX_ADMA_SAI1_TXC 0x06000040
+ IMX8DXL_FLEXCAN0_TX_ADMA_SAI1_TXFS 0x06000040
+ IMX8DXL_FLEXCAN1_RX_ADMA_SAI1_TXD 0x06000060
+ IMX8DXL_FLEXCAN1_TX_ADMA_SAI1_RXD 0x06000060
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ IMX8DXL_SNVS_TAMPER_OUT3_ADMA_SAI2_RXC 0x06000040
+ IMX8DXL_SNVS_TAMPER_IN0_ADMA_SAI2_RXFS 0x06000040
+ IMX8DXL_SNVS_TAMPER_OUT4_ADMA_SAI2_RXD 0x06000060
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ IMX8DXL_SNVS_TAMPER_IN1_ADMA_SAI3_RXC 0x06000040
+ IMX8DXL_SNVS_TAMPER_IN3_ADMA_SAI3_RXFS 0x06000040
+ IMX8DXL_SNVS_TAMPER_IN2_ADMA_SAI3_RXD 0x06000060
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
index 5d012c95222f..72434529f78e 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
@@ -3,6 +3,63 @@
* Copyright 2019~2020, 2022 NXP
*/
+/delete-node/ &asrc1;
+/delete-node/ &asrc1_lpcg;
+/delete-node/ &adc1;
+/delete-node/ &adc1_lpcg;
+/delete-node/ &amix;
+/delete-node/ &amix_lpcg;
+/delete-node/ &edma1;
+/delete-node/ &esai0;
+/delete-node/ &esai0_lpcg;
+/delete-node/ &sai4;
+/delete-node/ &sai4_lpcg;
+/delete-node/ &sai5;
+/delete-node/ &sai5_lpcg;
+
+&acm {
+ compatible = "fsl,imx8dxl-acm";
+ power-domains = <&pd IMX_SC_R_AUDIO_CLK_0>,
+ <&pd IMX_SC_R_AUDIO_CLK_1>,
+ <&pd IMX_SC_R_MCLK_OUT_0>,
+ <&pd IMX_SC_R_MCLK_OUT_1>,
+ <&pd IMX_SC_R_AUDIO_PLL_0>,
+ <&pd IMX_SC_R_AUDIO_PLL_1>,
+ <&pd IMX_SC_R_ASRC_0>,
+ <&pd IMX_SC_R_SAI_0>,
+ <&pd IMX_SC_R_SAI_1>,
+ <&pd IMX_SC_R_SAI_2>,
+ <&pd IMX_SC_R_SAI_3>,
+ <&pd IMX_SC_R_SPDIF_0>,
+ <&pd IMX_SC_R_MQS_0>;
+ clocks = <&aud_rec0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_rec1_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>,
+ <&clk_ext_aud_mclk0>,
+ <&clk_ext_aud_mclk1>,
+ <&clk_spdif0_rx>,
+ <&clk_sai0_rx_bclk>,
+ <&clk_sai0_tx_bclk>,
+ <&clk_sai1_rx_bclk>,
+ <&clk_sai1_tx_bclk>,
+ <&clk_sai2_rx_bclk>,
+ <&clk_sai3_rx_bclk>;
+ clock-names = "aud_rec_clk0_lpcg_clk",
+ "aud_rec_clk1_lpcg_clk",
+ "aud_pll_div_clk0_lpcg_clk",
+ "aud_pll_div_clk1_lpcg_clk",
+ "ext_aud_mclk0",
+ "ext_aud_mclk1",
+ "spdif0_rx",
+ "sai0_rx_bclk",
+ "sai0_tx_bclk",
+ "sai1_rx_bclk",
+ "sai1_tx_bclk",
+ "sai2_rx_bclk",
+ "sai3_rx_bclk";
+};
+
&audio_ipg_clk {
clock-frequency = <160000000>;
};
@@ -177,3 +234,24 @@
&lpspi3 {
interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
};
+
+&sai0 {
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&sai1 {
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&sai2 {
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&sai3 {
+ interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&spdif0 {
+ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* rx */
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>; /* tx */
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
index 6d13e4fafb76..1e02b04494e9 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
@@ -108,6 +108,13 @@
};
+&dma_apbh {
+ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+};
+
&enet0_lpcg {
clocks = <&conn_enet0_root_clk>,
<&conn_enet0_root_clk>,
@@ -127,6 +134,10 @@
assigned-clock-rates = <125000000>;
};
+&gpmi {
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+};
+
&usdhc1 {
compatible = "fsl,imx8dxl-usdhc", "fsl,imx8qxp-usdhc";
interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
index a0674c5c5576..7e54cf202858 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/clock/imx8-clock.h>
#include <dt-bindings/dma/fsl-edma.h>
+#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -104,7 +105,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a35-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -231,6 +232,7 @@
};
/* sorted in register address */
+ #include "imx8-ss-cm40.dtsi"
#include "imx8-ss-adma.dtsi"
#include "imx8-ss-conn.dtsi"
#include "imx8-ss-ddr.dtsi"
@@ -241,3 +243,14 @@
#include "imx8dxl-ss-conn.dtsi"
#include "imx8dxl-ss-lsio.dtsi"
#include "imx8dxl-ss-ddr.dtsi"
+
+&cm40_intmux {
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index bd5b365867fd..930e14fec423 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -72,6 +72,20 @@
enable-active-high;
};
+ reg_1v5: regulator-1v5 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_1V5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ };
+
+ reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
reg_vddext_3v3: regulator-vddext-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDEXT_3V3";
@@ -381,12 +395,12 @@
};
ptn5110: tcpc@50 {
- compatible = "nxp,ptn5110";
+ compatible = "nxp,ptn5110", "tcpci";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec1>;
reg = <0x50>;
interrupt-parent = <&gpio2>;
- interrupts = <11 8>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
status = "okay";
typec1_con: connector {
@@ -441,6 +455,9 @@
assigned-clock-rates = <24000000>;
powerdown-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ DOVDD-supply = <&buck5_reg>;
+ AVDD-supply = <&reg_1v8>;
+ DVDD-supply = <&reg_1v5>;
port {
ov5640_to_mipi_csi2: endpoint {
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-iot-gateway.dts b/arch/arm64/boot/dts/freescale/imx8mm-iot-gateway.dts
new file mode 100644
index 000000000000..370558a8ba46
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-iot-gateway.dts
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+//
+// Copyright 2020 CompuLab
+
+#include "imx8mm-ucm-som.dtsi"
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+/ {
+ model = "CompuLab i.MX8MM IoT Gateway";
+ compatible = "compulab,imx8mm-iot-gateway", "compulab,imx8mm-ucm-som", "fsl,imx8mm";
+
+ regulator-usbhub-ena {
+ compatible = "regulator-fixed";
+ regulator-name = "usbhub_ena";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-usbhub-rst {
+ compatible = "regulator-fixed";
+ regulator-name = "usbhub_rst";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-uart1-mode {
+ compatible = "regulator-fixed";
+ regulator-name = "uart1_mode";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-uart1-duplex {
+ compatible = "regulator-fixed";
+ regulator-name = "uart1_duplex";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-uart1-shdn {
+ compatible = "regulator-fixed";
+ regulator-name = "uart1_shdn";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-uart1-trmen {
+ compatible = "regulator-fixed";
+ regulator-name = "uart1_trmen";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 25 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+
+ regulator-usdhc2-v {
+ compatible = "regulator-fixed";
+ regulator-name = "usdhc2_v";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-mpcie2-rst {
+ compatible = "regulator-fixed";
+ regulator-name = "mpcie2_rst";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-mpcie2lora-dis {
+ compatible = "regulator-fixed";
+ regulator-name = "mpcie2lora_dis";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 21 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ pcie0_refclk: clock-pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom@54 {
+ compatible = "atmel,24c08";
+ reg = <0x54>;
+ pagesize = <16>;
+ };
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,tx-deemph-gen1 = <0x2d>;
+ fsl,tx-deemph-gen2 = <0xf>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ clock-names = "ref";
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio3 20 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dr_mode = "host";
+ usb-role-switch;
+ status = "okay";
+
+ usbhub@1 {
+ compatible = "usb424,9514";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb9514>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet: ethernet@1 {
+ compatible = "usb424,ec00";
+ reg = <1>;
+ };
+ };
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ mmc-ddr-1_8v;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* mPCIe2 */
+ MX8MM_IOMUXC_SAI5_RXD0_GPIO3_IO21 0x140
+ MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x140
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82
+ MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82
+ MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82
+ >;
+ };
+
+ pinctrl_ecspi1_cs: ecspi1csgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x40000
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x140
+ >;
+ };
+
+ pinctrl_usb9514: usb9514grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x140 /* USB_PS_EN */
+ MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x140 /* HUB_RSTn */
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs232.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs232.dtso
new file mode 100644
index 000000000000..bf3e04651ba0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs232.dtso
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 PHYTEC Messtechnik GmbH
+ * Author: Jens Lang <j.lang@phytec.de>
+ *
+ * Tauri-L 2 x RS232:
+ * - GPIO3_20 uart4_rs485_en needs to be driven low (inactive)
+ */
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "phytec,imx8mm-phygate-tauri-l";
+
+};
+
+&gpio3 {
+ pinctrl-names = "default";
+ pinctrcl-0 = <&pinctrl_gpio3_hog>;
+
+ uart4_rs485_en {
+ gpio-hog;
+ gpios = <20 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "uart4_rs485_en";
+ };
+};
+
+/* UART2 - RS232 */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+/* UART4 - RS232 */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART4>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_gpio3_hog: gpio3hoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x49
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x00
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x00
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x49
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x49
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs485.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs485.dtso
new file mode 100644
index 000000000000..f4448cde0407
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rs485.dtso
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 PHYTEC Messtechnik GmbH
+ * Author: Jens Lang <j.lang@phytec.de>
+ *
+ * Tauri-L RS232 + RS485:
+ * - GPIO3_20 uart4_rs485_en needs to be driven high (active)
+ * - GPIO3_25 RS485_DE Driver enable
+ */
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "phytec,imx8mm-phygate-tauri-l";
+
+};
+
+&gpio3 {
+ pinctrl-names = "default";
+ pinctrcl-0 = <&pinctrl_gpio3_hog>;
+
+ uart4_rs485_en {
+ gpio-hog;
+ gpios = <20 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "uart4_rs485_en";
+ };
+};
+
+/* UART2 - RS232 */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+/* UART4 - RS485 */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART4>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ rts-gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_gpio3_hog: gpio3hoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x49
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x00
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x00
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x49
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x49
+ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x49
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rts-cts.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rts-cts.dtso
new file mode 100644
index 000000000000..107f743fbb1c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l-rs232-rts-cts.dtso
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 PHYTEC Messtechnik GmbH
+ * Author: Jens Lang <j.lang@phytec.de>
+ *
+ * Tauri-L RS232 with RTS/CTS hardware flow control:
+ * - UART4_TX becomes RTS
+ * - UART4_RX becomes CTS
+ */
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+
+&{/} {
+ compatible = "phytec,imx8mm-phygate-tauri-l";
+
+};
+
+&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";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x00
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x00
+ MX8MM_IOMUXC_UART4_RXD_UART2_DCE_CTS_B 0x00
+ MX8MM_IOMUXC_UART4_TXD_UART2_DCE_RTS_B 0x00
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
index 27a902569e2a..ba6ce3c7f477 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
@@ -7,6 +7,7 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include "imx8mm-phycore-som.dtsi"
/ {
@@ -185,6 +186,15 @@
status = "okay";
};
+&pcie_phy {
+ clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+ fsl,clkreq-unsupported;
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
+ fsl,tx-deemph-gen1 = <0x2d>;
+ fsl,tx-deemph-gen2 = <0xf>;
+ status = "okay";
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
index 8c0c6e715924..ca0205b9019e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
@@ -62,11 +62,15 @@
flash0: flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
spi-max-frequency = <84000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-ucm-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-ucm-som.dtsi
new file mode 100644
index 000000000000..d3b21203c5f4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-ucm-som.dtsi
@@ -0,0 +1,679 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+//
+// Copyright 2018 CompuLab
+
+/dts-v1/;
+
+#include "imx8mm.dtsi"
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ mmc0 = &usdhc3;
+ };
+
+ chosen {
+ stdout-path = &uart3;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 3000000 0>;
+ brightness-levels = <0 255>;
+ num-interpolated-steps = <255>;
+ default-brightness-level = <222>;
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_led>;
+
+ heartbeat-led {
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ pmic_osc: clock-pmic {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "pmic_osc";
+ };
+
+ wlreg_on: regulator-wlreg-on {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "wlreg_on";
+ gpio = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ startup-delay-us = <100>;
+ off-on-delay-us = <12000>;
+ };
+
+ regulator-usdhc3rst {
+ compatible = "regulator-fixed";
+ regulator-name = "usdhc3_rst";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ regulator-fec1rst {
+ compatible = "regulator-fixed";
+ regulator-name = "fec1_rst";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ startup-delay-us = <500>;
+ regulator-boot-on;
+ };
+};
+
+&A53_0 {
+ arm-supply = <&buck2>;
+};
+
+&cpu_alert0 {
+ temperature = <105000>;
+};
+
+&cpu_crit0 {
+ temperature = <115000>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic@4b {
+ reg = <0x4b>;
+ compatible = "rohm,bd71837";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ #clock-cells = <0>;
+ clocks = <&pmic_osc>;
+ clock-names = "osc";
+ clock-output-names = "pmic_clk";
+ interrupt-parent = <&gpio1>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ rohm,reset-snvs-powered;
+
+ regulators {
+ buck1: BUCK1 {
+ regulator-name = "buck1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck2: 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: BUCK3 {
+ regulator-name = "buck3";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck4: BUCK4 {
+ regulator-name = "buck4";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5: BUCK5 {
+ regulator-name = "buck5";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6: BUCK6 {
+ regulator-name = "buck6";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck7: BUCK7 {
+ regulator-name = "buck7";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck8: BUCK8 {
+ regulator-name = "buck8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: LDO1 {
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2: LDO2 {
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3: LDO3 {
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5: LDO5 {
+ regulator-name = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo6: LDO6 {
+ regulator-name = "ldo6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo7: LDO7 {
+ regulator-name = "ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ rtc_i2c: rtc@69 {
+ compatible = "abracon,ab1805";
+ reg = <0x69>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "disabled";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_backlight>;
+ status = "okay";
+};
+
+&sai2 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ clocks = <&clk IMX8MM_CLK_SAI2_IPG>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI2_ROOT>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>,
+ <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&snvs {
+ status = "okay";
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "disabled";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "disabled";
+};
+
+&uart3 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&uart4 { /* bluetooth */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART4>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ uart-has-rtscts;
+ status = "disabled";
+
+ bluetooth {
+ compatible = "brcm,bcm4330-bt";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_bt>;
+ max-speed = <3000000>;
+ device-wakeup-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
+ host-wakeup-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ disable-over-current;
+ status = "disabled";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ hnp-disable;
+ srp-disable;
+ disable-over-current;
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>;
+ bus-width = <4>;
+ non-removable;
+};
+
+&usdhc2 {
+ 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 = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ bus-width = <4>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&usdhc3 {
+ 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;
+ no-1-8-v;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x19
+ MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x190
+ >;
+ };
+
+ pinctrl_bt: bt0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19 /* BT_REG_ON */
+ MX8MM_IOMUXC_SD1_DATA5_GPIO2_IO7 0x19 /* BT_DEV_WU */
+ MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x19 /* BT_HST_WU */
+ >;
+ };
+
+ 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
+ >;
+ };
+
+ pinctrl_gpio_led: gpioledgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x19
+ >;
+ };
+
+ 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_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
+ >;
+ };
+
+ pinctrl_pwm_backlight: pwmbacklightgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO13_PWM2_OUT 0x03
+ >;
+ };
+
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6
+ MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
+ MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x49
+ MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x49
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX 0x140
+ MX8MM_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B 0x140
+ MX8MM_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX 0x140
+ >;
+ };
+
+ pinctrl_usdhc1_gpio: usdhc1grpgpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
+ MX8MM_IOMUXC_GPIO1_IO03_USDHC1_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO03_USDHC1_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO03_USDHC1_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41
+ MX8MM_IOMUXC_SD2_WP_GPIO2_IO20 0x00
+ >;
+ };
+
+ 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: usdhc2grp100mhzgrp {
+ 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: usdhc2grp200mhzgrp {
+ 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 0x40000190
+ 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: usdhc3grp100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x40000194
+ 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: usdhc3grp200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x40000196
+ 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-var-som-symphony.dts b/arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts
index d643381417f1..affbc67c2ef6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts
@@ -117,7 +117,6 @@
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ptn5150>;
- status = "okay";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi
index de7f67a4ff2a..36803b038cd5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/net/ti-dp83867.h>
/ {
@@ -113,6 +114,25 @@
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
index 41c966147b94..429be2bab8a2 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
@@ -57,7 +57,7 @@
status = "okay";
tpm@1 {
- compatible = "tcg,tpm_tis-spi";
+ compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
reg = <0x1>;
spi-max-frequency = <36000000>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
index 5e2cbaf27e0f..136cb30df03a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
@@ -297,7 +297,7 @@
};
tpm@1 {
- compatible = "tcg,tpm_tis-spi";
+ compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
reg = <0x1>;
spi-max-frequency = <36000000>;
};
@@ -364,8 +364,6 @@
interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
index c11260c26d0b..1d56f2a6c06a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
@@ -314,8 +314,6 @@
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
index db1737bf637d..45470160f98f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
@@ -280,8 +280,6 @@
interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
index 05489a31e7fd..ef951bc9f0dd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
@@ -330,8 +330,6 @@
interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
index 1cff0b829357..ce20de259805 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
@@ -10,7 +10,7 @@
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&dailink_master>;
simple-audio-card,mclk-fs = <256>;
- simple-audio-card,name = "imx8mm-wm8904";
+ simple-audio-card,name = "verdin-wm8904";
simple-audio-card,routing =
"Headphone Jack", "HPOUTL",
"Headphone Jack", "HPOUTR",
@@ -32,6 +32,25 @@
sound-dai = <&sai2>;
};
};
+
+ reg_usb_hub: regulator-usb-hub {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ regulator-name = "HUB_PWR_EN";
+ };
+
+ reg_pcie: regulator-pcie {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ regulator-name = "PCIE_1_PWR_EN";
+ startup-delay-us = <100000>;
+ };
};
/* Verdin SPI_1 */
@@ -58,6 +77,11 @@
status = "okay";
};
+&gpio5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
/* Current measurement into module VCC */
&hwmon {
status = "okay";
@@ -93,6 +117,7 @@
/* Verdin PCIE_1 */
&pcie0 {
+ vpcie-supply = <&reg_pcie>;
status = "okay";
};
@@ -115,6 +140,11 @@
status = "okay";
};
+/* We support turning off sleep moci on Dahlia */
+&reg_force_sleep_moci {
+ status = "disabled";
+};
+
/* Verdin I2S_1 */
&sai2 {
status = "okay";
@@ -143,8 +173,16 @@
/* Verdin USB_2 */
&usbotg2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
disable-over-current;
status = "okay";
+
+ usb-hub@1 {
+ compatible = "usb424,2744";
+ reg = <1>;
+ vdd-supply = <&reg_usb_hub>;
+ };
};
/* Verdin SD_1 */
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
index 3c4b8ca125e3..1d8d146d9eeb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
@@ -10,7 +10,7 @@
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&dailink_master>;
simple-audio-card,mclk-fs = <256>;
- simple-audio-card,name = "imx8mm-nau8822";
+ simple-audio-card,name = "verdin-nau8822";
simple-audio-card,routing =
"Headphones", "LHP",
"Headphones", "RHP",
@@ -78,6 +78,11 @@
status = "okay";
};
+&gpio5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
&gpio_expander_21 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-yavia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-yavia.dtsi
index 1e28c78e381f..763f069e8405 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-yavia.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-yavia.dtsi
@@ -81,6 +81,11 @@
pinctrl-0 = <&pinctrl_gpios_ext_yavia>;
};
+&gpio5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
&hwmon_temp {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
index 6f0811587142..5fa395914191 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/phy/phy-imx8-pcie.h>
#include <dt-bindings/pwm/pwm.h>
#include "imx8mm.dtsi"
+#include "imx8mm-overdrive.dtsi"
/ {
chosen {
@@ -110,6 +111,22 @@
startup-delay-us = <200000>;
};
+ /*
+ * By default we enable CTRL_SLEEP_MOCI#, this is required to have
+ * peripherals on the carrier board powered.
+ * If more granularity or power saving is required this can be disabled
+ * in the carrier board device tree files.
+ */
+ reg_force_sleep_moci: regulator-force-sleep-moci {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "CTRL_SLEEP_MOCI#";
+ };
+
reg_usb_otg1_vbus: regulator-usb-otg1 {
compatible = "regulator-fixed";
enable-active-high;
@@ -211,15 +228,16 @@
pinctrl-0 = <&pinctrl_ecspi2>;
};
-/* Verdin CAN_1 (On-module) */
+/* On-module SPI */
&ecspi3 {
#address-cells = <1>;
#size-cells = <0>;
- cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>, <&gpio4 19 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi3>;
+ pinctrl-0 = <&pinctrl_ecspi3>, <&pinctrl_tpm_spi_cs>;
status = "okay";
+ /* Verdin CAN_1 */
can1: can@0 {
compatible = "microchip,mcp251xfd";
clocks = <&clk40m>;
@@ -229,6 +247,12 @@
reg = <0>;
spi-max-frequency = <8500000>;
};
+
+ verdin_som_tpm: tpm@1 {
+ compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
+ reg = <0x1>;
+ spi-max-frequency = <36000000>;
+ };
};
/* Verdin ETH_1 (On-module PHY) */
@@ -333,16 +357,6 @@
"SODIMM_212",
"SODIMM_151",
"SODIMM_153";
-
- ctrl-sleep-moci-hog {
- gpio-hog;
- /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
- gpios = <1 GPIO_ACTIVE_HIGH>;
- line-name = "CTRL_SLEEP_MOCI#";
- output-high;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
- };
};
/* On-module I2C */
@@ -541,7 +555,7 @@
/* Verdin I2C_2_DSI */
&i2c2 {
- clock-frequency = <10000>;
+ clock-frequency = <400000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
pinctrl-1 = <&pinctrl_i2c2_gpio>;
@@ -801,8 +815,7 @@
pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
<&pinctrl_gpio3>, <&pinctrl_gpio4>,
<&pinctrl_gpio7>, <&pinctrl_gpio8>,
- <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
- <&pinctrl_pmic_tpm_ena>;
+ <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>;
pinctrl_can1_int: can1intgrp {
fsl,pins =
@@ -929,7 +942,7 @@
/* Verdin GPIO_9_DSI (pulled-up as active-low) */
pinctrl_gpio_9_dsi: gpio9dsigrp {
fsl,pins =
- <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x146>; /* SODIMM 17 */
+ <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x1c6>; /* SODIMM 17 */
};
/* Verdin GPIO_10_DSI (pulled-up as active-low) */
@@ -1104,7 +1117,7 @@
};
/* control signal for optional ATTPM20P or SE050 */
- pinctrl_pmic_tpm_ena: pmictpmenagrp {
+ pinctrl_tpm_spi_cs: tpmspicsgrp {
fsl,pins =
<MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x106>; /* PMIC_TPM_ENA */
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 8a1b42b94dce..9535dedcef59 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -1168,6 +1168,13 @@
remote-endpoint = <&lcdif_to_dsim>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mipi_dsi_out: endpoint {
+ };
+ };
};
};
@@ -1253,7 +1260,6 @@
reg = <0x32e40000 0x200>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
- clock-names = "usb1_ctrl_root_clk";
assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>;
assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
phys = <&usbphynop1>;
@@ -1274,7 +1280,6 @@
reg = <0x32e50000 0x200>;
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
- clock-names = "usb1_ctrl_root_clk";
assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>;
assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
phys = <&usbphynop2>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-ddr3l-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-ddr3l-evk.dts
index 000e2c0596df..d25032e3ceab 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-ddr3l-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-ddr3l-evk.dts
@@ -112,3 +112,19 @@
};
};
};
+
+&i2c2 {
+ hdmi@3d {
+ avdd-supply = <&buck5>;
+ dvdd-supply = <&buck5>;
+ pvdd-supply = <&buck5>;
+ a2vdd-supply = <&buck5>;
+ v1p2-supply = <&buck5>;
+ };
+};
+
+&i2c3 {
+ camera@3c {
+ DOVDD-supply = <&buck5>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
index cc2ff59ac53b..6d85a0b052c9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
@@ -158,3 +158,19 @@
};
};
};
+
+&i2c2 {
+ hdmi@3d {
+ avdd-supply = <&buck5_reg>;
+ dvdd-supply = <&buck5_reg>;
+ pvdd-supply = <&buck5_reg>;
+ a2vdd-supply = <&buck5_reg>;
+ v1p2-supply = <&buck5_reg>;
+ };
+};
+
+&i2c3 {
+ camera@3c {
+ DOVDD-supply = <&buck5_reg>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
index 0b71f50d936e..41330210a05f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
@@ -125,3 +125,19 @@
};
};
};
+
+&i2c2 {
+ hdmi@3d {
+ avdd-supply = <&buck5>;
+ dvdd-supply = <&buck5>;
+ pvdd-supply = <&buck5>;
+ a2vdd-supply = <&buck5>;
+ v1p2-supply = <&buck5>;
+ };
+};
+
+&i2c3 {
+ camera@3c {
+ DOVDD-supply = <&buck5>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index 269e70f66a13..9e0259ddf4bc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -30,7 +30,7 @@
port {
hdmi_connector_in: endpoint {
- remote-endpoint = <&adv7533_out>;
+ remote-endpoint = <&adv7535_out>;
};
};
};
@@ -52,6 +52,27 @@
enable-active-high;
};
+ reg_1v5: regulator-1v5 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_1V5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ };
+
+ reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_vddext_3v3: regulator-vddext-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDEXT_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
ir-receiver {
compatible = "gpio-ir-receiver";
gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
@@ -193,15 +214,11 @@
hdmi@3d {
compatible = "adi,adv7535";
- reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>;
- reg-names = "main", "cec", "edid", "packet";
+ reg = <0x3d>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
adi,dsi-lanes = <4>;
-
- adi,input-depth = <8>;
- adi,input-colorspace = "rgb";
- adi,input-clock = "1x";
- adi,input-style = <1>;
- adi,input-justification = "evenly";
+ v3p3-supply = <&reg_vddext_3v3>;
ports {
#address-cells = <1>;
@@ -210,7 +227,7 @@
port@0 {
reg = <0>;
- adv7533_in: endpoint {
+ adv7535_in: endpoint {
remote-endpoint = <&dsi_out>;
};
};
@@ -218,7 +235,7 @@
port@1 {
reg = <1>;
- adv7533_out: endpoint {
+ adv7535_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
@@ -227,7 +244,7 @@
};
ptn5110: tcpc@50 {
- compatible = "nxp,ptn5110";
+ compatible = "nxp,ptn5110", "tcpci";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec1>;
reg = <0x50>;
@@ -284,6 +301,8 @@
assigned-clock-rates = <24000000>;
powerdown-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ AVDD-supply = <&reg_1v8>;
+ DVDD-supply = <&reg_1v5>;
port {
ov5640_to_mipi_csi2: endpoint {
@@ -335,7 +354,7 @@
reg = <1>;
dsi_out: endpoint {
- remote-endpoint = <&adv7533_in>;
+ remote-endpoint = <&adv7535_in>;
data-lanes = <1 2 3 4>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
index fb24b9aa1b93..e68a3fd73e17 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
@@ -60,11 +60,15 @@
flash0: flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
spi-max-frequency = <84000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts b/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts
index a6b94d1957c9..3434b189fa58 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts
@@ -126,7 +126,6 @@
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ptn5150>;
- status = "okay";
port {
typec1_dr_sw: endpoint {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
index 0b1fa04f1d67..72004ab6bda5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
@@ -312,8 +312,6 @@
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 932c8b05c75f..a5f9cfb46e5d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -1104,6 +1104,13 @@
remote-endpoint = <&lcdif_to_dsim>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mipi_dsi_out: endpoint {
+ };
+ };
};
};
@@ -1213,7 +1220,6 @@
reg = <0x32e40000 0x200>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>;
- clock-names = "usb1_ctrl_root_clk";
assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>;
assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>;
phys = <&usbphynop1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
index a08057410bde..17e2c19d8455 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
@@ -302,10 +302,18 @@
adv_bridge: hdmi@3d {
compatible = "adi,adv7535";
- reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>;
- reg-names = "main", "cec", "edid", "packet";
+ reg = <0x3d>;
+ reg-names = "main";
+ interrupt-parent = <&gpio4>;
+ interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
adi,dsi-lanes = <4>;
#sound-dai-cells = <0>;
+ avdd-supply = <&buck5>;
+ dvdd-supply = <&buck5>;
+ pvdd-supply = <&buck5>;
+ a2vdd-supply = <&buck5>;
+ v1p2-supply = <&buck5>;
+ v3p3-supply = <&buck4>;
ports {
#address-cells = <1>;
@@ -340,7 +348,7 @@
&i2c3 {
/* Connected to USB Hub */
usb-typec@52 {
- compatible = "nxp,ptn5110";
+ compatible = "nxp,ptn5110", "tcpci";
reg = <0x52>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
index 8be251b69378..15f7ab58db36 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
@@ -71,7 +71,6 @@
mtl_rx_setup: rx-queues-config {
snps,rx-queues-to-use = <5>;
- snps,rx-sched-sp;
queue0 {
snps,dcb-algorithm;
@@ -106,7 +105,6 @@
mtl_tx_setup: tx-queues-config {
snps,tx-queues-to-use = <5>;
- snps,tx-sched-sp;
queue0 {
snps,dcb-algorithm;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
index 2c19766ebf09..af02af9e5334 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
@@ -20,6 +20,18 @@
stdout-path = &uart2;
};
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -94,6 +106,28 @@
};
};
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
&i2c1 {
clock-frequency = <400000>;
pinctrl-names = "default";
@@ -197,10 +231,8 @@
};
&i2c2 {
- clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
- status = "okay";
};
&i2c3 {
@@ -241,6 +273,10 @@
status = "okay";
};
+&lcdif3 {
+ status = "okay";
+};
+
&snvs_pwrkey {
status = "okay";
};
@@ -358,6 +394,15 @@
>;
};
+ pinctrl_hdmi: hdmigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c3
+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c3
+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x19
+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x19
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
index b11d694b98e1..d241db3743a9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
@@ -144,7 +144,6 @@
pinctrl-0 = <&pinctrl_eqos>;
nvmem-cells = <&ethmac1>;
nvmem-cell-names = "mac-address";
- phy-supply = <&reg_baseboard_vdd3v3>;
phy-handle = <&ethphy0>;
phy-mode = "rgmii-id";
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts
index 3b1c940860e0..ebdf13e97b4e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts
@@ -69,6 +69,18 @@
};
};
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X38";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
led {
compatible = "gpio-leds";
@@ -184,6 +196,33 @@
status = "okay";
};
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ ddc-i2c-bus = <&i2c5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
&pcie_phy {
clock-names = "ref";
clocks = <&hsio_blk_ctrl>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
index b749e28e5ede..ef012e8365b1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
@@ -75,6 +75,18 @@
};
};
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X28";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
led {
compatible = "gpio-leds";
@@ -167,6 +179,16 @@
VDDIO-supply = <&reg_vdd_3p3v_awo>;
};
+ csi2exp: gpio@24 {
+ compatible = "nxp,pca9570";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names =
+ "CSI2_#RESET", "CSI2_#PWDN",
+ "CSI_#PWDN", "CSI_#RESET";
+ };
+
typec@3d {
compatible = "nxp,ptn5150";
reg = <0x3d>;
@@ -238,6 +260,33 @@
status = "okay";
};
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ ddc-i2c-bus = <&i2cmuxed1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
&pcie_phy {
clocks = <&pcieclk 1>;
clock-names = "ref";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
index 43f1d45ccc96..a90e28c07e3f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
@@ -78,6 +78,11 @@
cpu-supply = <&buck2>;
};
+&audio_blk_ctrl {
+ assigned-clocks = <&clk IMX8MP_AUDIO_PLL1>;
+ assigned-clock-rates = <393216000>;
+};
+
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
@@ -105,14 +110,14 @@
#size-cells = <0>;
/* Up to one of these two PHYs may be populated. */
- ethphy0f: ethernet-phy@0 { /* SMSC LAN8740Ai */
+ ethphy0f: ethernet-phy@1 { /* SMSC LAN8740Ai */
compatible = "ethernet-phy-id0007.c110",
"ethernet-phy-ieee802.3-c22";
interrupt-parent = <&gpio3>;
interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
pinctrl-0 = <&pinctrl_ethphy0>;
pinctrl-names = "default";
- reg = <0>;
+ reg = <1>;
reset-assert-us = <1000>;
reset-deassert-us = <1000>;
reset-gpios = <&ioexp 4 GPIO_ACTIVE_LOW>;
@@ -151,14 +156,14 @@
#size-cells = <0>;
/* Up to one PHY may be populated. */
- ethphy1f: ethernet-phy@1 { /* SMSC LAN8740Ai */
+ ethphy1f: ethernet-phy@2 { /* SMSC LAN8740Ai */
compatible = "ethernet-phy-id0007.c110",
"ethernet-phy-ieee802.3-c22";
interrupt-parent = <&gpio4>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
pinctrl-0 = <&pinctrl_ethphy1>;
pinctrl-names = "default";
- reg = <1>;
+ reg = <2>;
reset-assert-us = <1000>;
reset-deassert-us = <1000>;
reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
@@ -254,7 +259,7 @@
<&clk IMX8MP_CLK_CLKOUT2>,
<&clk IMX8MP_AUDIO_PLL2_OUT>;
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>;
- assigned-clock-rates = <13000000>, <13000000>, <156000000>;
+ assigned-clock-rates = <13000000>, <13000000>, <208000000>;
reset-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk-mx8-dlvds-lcd1.dtso b/arch/arm64/boot/dts/freescale/imx8mp-evk-mx8-dlvds-lcd1.dtso
new file mode 100644
index 000000000000..1b71890d43d5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk-mx8-dlvds-lcd1.dtso
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ panel-lvds {
+ compatible = "koe,tx26d202vm0bwa";
+ backlight = <&backlight_lvds>;
+ power-supply = <&reg_vext_3v3>;
+
+ panel-timing {
+ clock-frequency = <148500000>;
+ hactive = <1920>;
+ vactive = <1200>;
+ hfront-porch = <130>;
+ hback-porch = <70>;
+ hsync-len = <30>;
+ vfront-porch = <5>;
+ vback-porch = <5>;
+ vsync-len = <5>;
+ de-active = <1>;
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dual-lvds-odd-pixels;
+
+ panel_in_odd: endpoint {
+ remote-endpoint = <&ldb_lvds_ch0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dual-lvds-even-pixels;
+
+ panel_in_even: endpoint {
+ remote-endpoint = <&ldb_lvds_ch1>;
+ };
+ };
+ };
+ };
+};
+
+&backlight_lvds {
+ status = "okay";
+};
+
+&lcdif2 {
+ status = "okay";
+};
+
+&lvds_bridge {
+ status = "okay";
+
+ ports {
+ port@1 {
+ ldb_lvds_ch0: endpoint {
+ remote-endpoint = <&panel_in_odd>;
+ };
+ };
+
+ port@2 {
+ ldb_lvds_ch1: endpoint {
+ remote-endpoint = <&panel_in_even>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 9beba8d6a0df..938347704136 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -16,6 +16,16 @@
stdout-path = &uart2;
};
+ backlight_lvds: backlight-lvds {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 100000 0>;
+ brightness-levels = <0 100>;
+ num-interpolated-steps = <100>;
+ default-brightness-level = <100>;
+ power-supply = <&reg_per_12v>;
+ status = "disabled";
+ };
+
hdmi-connector {
compatible = "hdmi-connector";
label = "hdmi";
@@ -96,6 +106,15 @@
enable-active-high;
};
+ reg_per_12v: regulator-per-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "PER_12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&pca6416 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
reg_usdhc2_vmmc: regulator-usdhc2 {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -114,6 +133,11 @@
regulator-max-microvolt = <3300000>;
};
+ audio_codec_bt_sco: audio-codec-bt-sco {
+ compatible = "linux,bt-sco";
+ #sound-dai-cells = <1>;
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "wm8960-audio";
@@ -145,6 +169,59 @@
};
+ sound-bt-sco {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "bt-sco-audio";
+ simple-audio-card,format = "dsp_a";
+ simple-audio-card,bitclock-inversion;
+ simple-audio-card,frame-master = <&btcpu>;
+ simple-audio-card,bitclock-master = <&btcpu>;
+
+ btcpu: simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ dai-tdm-slot-num = <2>;
+ dai-tdm-slot-width = <16>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&audio_codec_bt_sco 1>;
+ };
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx-audio-hdmi";
+ model = "audio-hdmi";
+ audio-cpu = <&aud2htx>;
+ hdmi-out;
+ };
+
+ sound-micfil {
+ compatible = "fsl,imx-audio-card";
+ model = "micfil-audio";
+
+ pri-dai-link {
+ link-name = "micfil hifi";
+ format = "i2s";
+
+ cpu {
+ sound-dai = <&micfil>;
+ };
+ };
+ };
+
+ sound-xcvr {
+ compatible = "fsl,imx-audio-card";
+ model = "imx-audio-xcvr";
+
+ pri-dai-link {
+ link-name = "XCVR PCM";
+
+ cpu {
+ sound-dai = <&xcvr>;
+ };
+ };
+ };
+
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
@@ -198,6 +275,10 @@
cpu-supply = <&reg_arm>;
};
+&aud2htx {
+ status = "okay";
+};
+
&eqos {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eqos>;
@@ -226,7 +307,6 @@
mtl_tx_setup: tx-queues-config {
snps,tx-queues-to-use = <5>;
- snps,tx-sched-sp;
queue0 {
snps,dcb-algorithm;
@@ -524,6 +604,16 @@
status = "okay";
};
+&micfil {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MP_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <196608000>;
+ status = "okay";
+};
+
&mipi_dsi {
samsung,esc-clock-frequency = <10000000>;
status = "okay";
@@ -573,6 +663,17 @@
status = "okay";
};
+&sai2 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clk IMX8MP_CLK_SAI2>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <12288000>;
+ fsl,sai-mclk-direction-output;
+ status = "okay";
+};
+
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
@@ -659,7 +760,15 @@
status = "okay";
};
+&xcvr {
+ #sound-dai-cells = <0>;
+ status = "okay";
+};
+
&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
pinctrl_audio_pwr_reg: audiopwrreggrp {
fsl,pins = <
MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0xd6
@@ -749,6 +858,12 @@
>;
};
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000010
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2
@@ -790,6 +905,16 @@
>;
};
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_PDM_CLK 0xd6
+ MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_PDM_BIT_STREAM00 0xd6
+ MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_PDM_BIT_STREAM01 0xd6
+ MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_PDM_BIT_STREAM02 0xd6
+ MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_PDM_BIT_STREAM03 0xd6
+ >;
+ };
+
pinctrl_pmic: pmicgrp {
fsl,pins = <
MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x000001c0
@@ -835,6 +960,15 @@
>;
};
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0xd6
+ MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0xd6
+ MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0xd6
+ MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0xd6
+ >;
+ };
+
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0xd6
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dts b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dts
index da4b1807c275..83194ea7cb81 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dts
@@ -46,6 +46,24 @@
};
};
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
&i2c1 {
sgtl5000: audio-codec@a {
compatible = "fsl,sgtl5000";
@@ -92,6 +110,15 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_smarc_gpio>;
+ pinctrl_hdmi: hdmigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c2
+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c2
+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x10
+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x10
+ >;
+ };
+
pinctrl_sai2: sai2grp {
fsl,pins = <
MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0xd6
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
index 61c2a63efc6d..0fd5c3abcdb7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
@@ -200,8 +200,11 @@
};
&i2c1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <400000>;
status = "okay";
@@ -241,8 +244,11 @@
};
&i2c6 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c6>;
+ pinctrl-1 = <&pinctrl_i2c6_gpio>;
+ scl-gpios = <&gpio3 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio3 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <400000>;
status = "okay";
@@ -602,38 +608,50 @@
pinctrl_i2c1: i2c1grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001e0>,
+ <MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001e0>;
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins =
+ <MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x1e0>,
+ <MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x1e0>;
};
pinctrl_i2c2: i2c2grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001e0>,
+ <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001e0>;
};
pinctrl_i2c3: i2c3grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001e0>,
+ <MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001e0>;
};
pinctrl_i2c4: i2c4grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001e0>,
+ <MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001e0>;
};
pinctrl_i2c5: i2c5grp {
fsl,pins =
- <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001c3>,
- <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001e0>,
+ <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001e0>;
};
pinctrl_i2c6: i2c6grp {
fsl,pins =
- <MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL 0x400001c3>,
- <MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL 0x400001e0>,
+ <MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x400001e0>;
+ };
+
+ pinctrl_i2c6_gpio: i2c6gpiogrp {
+ fsl,pins =
+ <MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19 0x1e0>,
+ <MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x1e0>;
};
pinctrl_lcd0_backlight: lcd0-backlightgrp {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts b/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts
new file mode 100644
index 000000000000..5fd1614982cd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Emcraft Systems
+ * Copyright 2024 Gilles Talis <gilles.talis@gmail.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "imx8mp.dtsi"
+
+/ {
+ model = "Emcraft Systems i.MX8MPlus NavQ+ Kit";
+ compatible = "emcraft,imx8mp-navqp", "fsl,imx8mp";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_led>;
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_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;
+ startup-delay-us = <100>;
+ off-on-delay-us = <12000>;
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_1 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_2 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_3 {
+ cpu-supply = <&buck2>;
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-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 = <1000>;
+ reset-deassert-us = <10000>;
+ qca,disable-smarteee;
+ qca,disable-hibernation-mode;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic@25 {
+ compatible = "nxp,pca9450c";
+ reg = <0x25>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+ regulators {
+ BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
+ };
+
+ BUCK4 {
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ BUCK5 {
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO5 {
+ regulator-name = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ rtc@53 {
+ compatible = "nxp,pcf2131";
+ reg = <0x53>;
+ };
+};
+
+&uart2 {
+ /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+/* SD Card */
+&usdhc2 {
+ 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 = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+/* eMMC */
+&usdhc3 {
+ assigned-clocks = <&clk IMX8MP_CLK_USDHC3>;
+ 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_eqos: eqosgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3
+ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3
+ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91
+ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91
+ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91
+ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91
+ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91
+ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91
+ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f
+ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f
+ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f
+ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f
+ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f
+ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f
+ MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x110
+ >;
+ };
+
+ pinctrl_gpio_led: gpioledgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x19
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3
+ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3
+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3
+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c3
+ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x41
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x49
+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x49
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts
new file mode 100644
index 000000000000..d7fd9d36f824
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts
@@ -0,0 +1,906 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2023-2024 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Martin Schmiedel
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "imx8mp-tqma8mpql.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8MPlus TQMa8MPxL on MBa8MP-RAS314";
+ compatible = "tq,imx8mp-tqma8mpql-mba8mp-ras314", "tq,imx8mp-tqma8mpql", "fsl,imx8mp";
+ chassis-type = "embedded";
+
+ chosen {
+ stdout-path = &uart4;
+ };
+
+ aliases {
+ mmc0 = &usdhc3;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc1;
+ rtc0 = &pcf85063;
+ rtc1 = &snvs_rtc;
+ };
+
+ /* X8 */
+ backlight_lvds: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ pwms = <&pwm2 0 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_vcc_12v0>;
+ enable-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ /* X7 + X8 */
+ display: display {
+ /*
+ * Display is not fixed, so compatible has to be added from
+ * DT overlay
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvdsdisplay>;
+ power-supply = <&reg_vcc_3v3>;
+ enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ backlight = <&backlight_lvds>;
+ status = "disabled";
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioled>;
+
+ led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ function-enumerator = <0>;
+ gpios = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-2 {
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_STATUS;
+ function-enumerator = <1>;
+ gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X9";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
+ 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;
+ startup-delay-us = <100>;
+ off-on-delay-us = <12000>;
+ };
+
+ reg_vcc_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_vcc_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_5V0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_vcc_12v0: regulator-12v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x38000000>;
+ alloc-ranges = <0 0x40000000 0 0xB0000000>;
+ linux,cma-default;
+ };
+ };
+
+ rfkill {
+ compatible = "rfkill-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rfkill>;
+ label = "rfkill-pcie-wlan";
+ radio-type = "wlan";
+ shutdown-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-tlv320aic32x4";
+ model = "tq-mba8mp-ras314";
+ audio-cpu = <&sai5>;
+ audio-codec = <&tlv320aic3x04>;
+ audio-routing =
+ "IN3_L", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR";
+ };
+};
+
+&ecspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>, <&gpio1 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy3>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy3: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos_phy>;
+ reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ enet-phy-lane-no-swap;
+ interrupt-parent = <&gpio4>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec_phy>;
+ reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ enet-phy-lane-no-swap;
+ interrupt-parent = <&gpio4>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ };
+ };
+};
+
+&gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>;
+
+ gpio-line-names = "WIFI_PMIC_EN", "LVDS_RESET#", "", "",
+ "", "", "GPIO8", "",
+ "", "", "", "",
+ "", "", "GPIO12", "GPIO13",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "";
+
+ wifi-pmic-en-hog {
+ gpio-hog;
+ gpios = <0 0>;
+ output-high;
+ line-name = "WIFI_PMIC_EN";
+ };
+};
+
+&gpio2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio2>;
+
+ gpio-line-names = "GPIO22", "GPIO23", "GPIO24", "GPIO25",
+ "GPIO26", "GPIO27", "CAM_GPIO1", "CAM_GPIO2",
+ "", "", "GPIO1", "GPIO0",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio3>;
+
+ gpio-line-names = "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "TEMP_EVENT#", "", "", "",
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio4>;
+
+ gpio-line-names = "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "HDMI_OC#", "GPIO14", "GPIO15", "GPIO16",
+ "GPIO17", "PCIE_WAKE#", "GPIO19", "GPIO20",
+ "PCIE_PERST#", "", "", "";
+
+ pewake-hog {
+ gpio-hog;
+ gpios = <25 0>;
+ input;
+ line-name = "PCIE_WAKE#";
+ };
+};
+
+&gpio5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio5>, <&pinctrl_gpt1_gpio>,
+ <&pinctrl_gpt2_gpio>, <&pinctrl_gpt3_gpio>;
+
+ gpio-line-names = "", "GPIO18", "", "GPIO3",
+ "GPIO2", "GPIO21", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "GPIO5", "GPIO6",
+ "", "", "GPIO11", "GPIO10",
+ "GPIO9", "GPIO7", "", "GPIO4",
+ "", "", "", "";
+};
+
+&gpt1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpt1>;
+ status = "disabled";
+};
+
+&gpt2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpt2>;
+ status = "disabled";
+};
+
+&gpt3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpt3>;
+ status = "disabled";
+};
+
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
+/* X5 + X6 Camera & Display interface */
+&i2c2 {
+ clock-frequency = <384000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+/* X1 ID_I2C */
+&i2c3 {
+ clock-frequency = <384000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio2 10 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio2 11 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <384000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_gpio>;
+ scl-gpios = <&gpio5 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ tlv320aic3x04: audio-codec@18 {
+ compatible = "ti,tlv320aic32x4";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tlv320aic3x04>;
+ reg = <0x18>;
+ clock-names = "mclk";
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1>;
+ reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+ iov-supply = <&reg_vcc_3v3>;
+ ldoin-supply = <&reg_vcc_3v3>;
+ };
+};
+
+/* X1 I2C */
+&i2c5 {
+ clock-frequency = <384000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c5>;
+ pinctrl-1 = <&pinctrl_i2c5_gpio>;
+ scl-gpios = <&gpio5 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+/* X1 I2C on GPIO24/GPIO25 */
+&i2c6 {
+ clock-frequency = <384000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c6>;
+ pinctrl-1 = <&pinctrl_i2c6_gpio>;
+ scl-gpios = <&gpio2 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio2 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "disabled";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
+&pcf85063 {
+ /* RTC_EVENT# is connected on MBa8MP-RAS314 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcf85063>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+};
+
+&pcie_phy {
+ clocks = <&hsio_blk_ctrl>;
+ clock-names = "ref";
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&sai5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai5>;
+ assigned-clocks = <&clk IMX8MP_CLK_SAI5>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <12288000>;
+ fsl,sai-mclk-direction-output;
+ status = "okay";
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+/* X1 UART1 */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ uart-has-rtscts;
+ assigned-clocks = <&clk IMX8MP_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ uart-has-rtscts;
+ assigned-clocks = <&clk IMX8MP_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
+ status = "okay";
+
+ bluetooth {
+ compatible = "nxp,88w8987-bt";
+ };
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clk IMX8MP_CLK_UART3>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&uart4 {
+ /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&usb3_0 {
+ fsl,disable-port-power-control;
+ status = "okay";
+};
+
+&usb3_1 {
+ fsl,disable-port-power-control;
+ fsl,permanently-attached;
+ status = "okay";
+};
+
+&usb3_phy0 {
+ vbus-supply = <&reg_vcc_5v0>;
+ status = "okay";
+};
+
+&usb3_phy1 {
+ vbus-supply = <&reg_vcc_5v0>;
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb_dwc3_1 {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbhub>;
+ status = "okay";
+
+ hub_2_0: hub@1 {
+ compatible = "usb451,8142";
+ reg = <1>;
+ peer-hub = <&hub_3_0>;
+ reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&reg_vcc_3v3>;
+ };
+
+ hub_3_0: hub@2 {
+ compatible = "usb451,8140";
+ reg = <2>;
+ peer-hub = <&hub_2_0>;
+ reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&reg_vcc_3v3>;
+ };
+};
+
+/* X1 SD card on GPIO22-GPIO27 */
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ disable-wp;
+ bus-width = <4>;
+ status = "disabled";
+};
+
+&usdhc2 {
+ 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 = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_backlight: backlightgrp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x14>;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <MX8MP_IOMUXC_UART1_RXD__ECSPI3_SCLK 0x140>,
+ <MX8MP_IOMUXC_UART1_TXD__ECSPI3_MOSI 0x140>,
+ <MX8MP_IOMUXC_UART2_RXD__ECSPI3_MISO 0x1c0>,
+ <MX8MP_IOMUXC_UART2_TXD__GPIO5_IO25 0x140>,
+ <MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x140>;
+ };
+
+ pinctrl_ecspi3_gpio: ecspi3gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_UART1_RXD__GPIO5_IO22 0x80>,
+ <MX8MP_IOMUXC_UART1_TXD__GPIO5_IO23 0x80>,
+ <MX8MP_IOMUXC_UART2_RXD__GPIO5_IO24 0x80>,
+ <MX8MP_IOMUXC_UART2_TXD__GPIO5_IO25 0x80>,
+ <MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x80>;
+ };
+
+ pinctrl_eqos: eqosgrp {
+ fsl,pins = <MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x40000044>,
+ <MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x40000044>,
+ <MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90>,
+ <MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90>,
+ <MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90>,
+ <MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90>,
+ <MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90>,
+ <MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90>,
+ <MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x12>,
+ <MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x12>,
+ <MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x12>,
+ <MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x12>,
+ <MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x12>,
+ <MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x14>;
+ };
+
+ pinctrl_eqos_phy: eqosphygrp {
+ fsl,pins = <MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x100>,
+ <MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03 0x1c0>;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x40000044>,
+ <MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x40000044>,
+ <MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x90>,
+ <MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x90>,
+ <MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x90>,
+ <MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x90>,
+ <MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x90>,
+ <MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x90>,
+ <MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x12>,
+ <MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x12>,
+ <MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x12>,
+ <MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x12>,
+ <MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x12>,
+ <MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x14>;
+ };
+
+ pinctrl_fec_phy: fecphygrp {
+ fsl,pins = <MX8MP_IOMUXC_SAI1_RXFS__GPIO4_IO00 0x100>,
+ <MX8MP_IOMUXC_SAI1_RXC__GPIO4_IO01 0x1c0>;
+ };
+
+ pinctrl_gpioled: gpioledgrp {
+ fsl,pins = <MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x14>,
+ <MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x14>;
+ };
+
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00 0x14>,
+ <MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01 0x14>;
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_CLK__GPIO2_IO00 0x94>,
+ <MX8MP_IOMUXC_SD1_CMD__GPIO2_IO01 0x94>,
+ <MX8MP_IOMUXC_SD1_DATA0__GPIO2_IO02 0x94>,
+ <MX8MP_IOMUXC_SD1_DATA1__GPIO2_IO03 0x94>,
+ <MX8MP_IOMUXC_SD1_DATA2__GPIO2_IO04 0x94>,
+ <MX8MP_IOMUXC_SD1_DATA3__GPIO2_IO05 0x94>,
+ <MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x94>,
+ <MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x94>;
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x180>;
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x80>,
+ /* PCIE_WAKE# */
+ <MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x180>,
+ <MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x94>,
+ <MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x94>;
+ };
+
+ pinctrl_gpio5: gpio5grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x80>,
+ <MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x80>;
+ };
+
+ pinctrl_hdmi: hdmigrp {
+ fsl,pins = <MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x400001c2>,
+ <MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000010>,
+ <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000154>;
+ };
+
+ pinctrl_gpt1: gpt1grp {
+ fsl,pins = <MX8MP_IOMUXC_UART3_TXD__GPT1_CLK 0x14>;
+ };
+
+ pinctrl_gpt1_gpio: gpt1gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_UART3_TXD__GPIO5_IO27 0x80>;
+ };
+
+ pinctrl_gpt2: gpt2grp {
+ fsl,pins = <MX8MP_IOMUXC_I2C3_SCL__GPT2_CLK 0x14>;
+ };
+
+ pinctrl_gpt2_gpio: gpt2gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x80>;
+ };
+
+ pinctrl_gpt3: gpt3grp {
+ fsl,pins = <MX8MP_IOMUXC_I2C3_SDA__GPT3_CLK 0x14>;
+ };
+
+ pinctrl_gpt3_gpio: gpt3gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x80>;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001e2>,
+ <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001e2>;
+ };
+
+ pinctrl_i2c2_gpio: i2c2-gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x400001e2>,
+ <MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x400001e2>;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_RESET_B__I2C3_SCL 0x400001e2>,
+ <MX8MP_IOMUXC_SD1_STROBE__I2C3_SDA 0x400001e2>;
+ };
+
+ pinctrl_i2c3_gpio: i2c3-gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x400001e2>,
+ <MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x400001e2>;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <MX8MP_IOMUXC_ECSPI2_MISO__I2C4_SCL 0x400001e2>,
+ <MX8MP_IOMUXC_ECSPI2_SS0__I2C4_SDA 0x400001e2>;
+ };
+
+ pinctrl_i2c4_gpio: i2c4-gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_ECSPI2_MISO__GPIO5_IO12 0x400001e2>,
+ <MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x400001e2>;
+ };
+
+ pinctrl_i2c5: i2c5grp {
+ fsl,pins = <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001e2>,
+ <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001e2>;
+ };
+
+ pinctrl_i2c5_gpio: i2c5-gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_SPDIF_TX__GPIO5_IO03 0x400001e2>,
+ <MX8MP_IOMUXC_SPDIF_RX__GPIO5_IO04 0x400001e2>;
+ };
+
+ pinctrl_i2c6: i2c6grp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_DATA0__I2C6_SCL 0x400001e2>,
+ <MX8MP_IOMUXC_SD1_DATA1__I2C6_SDA 0x400001e2>;
+ };
+
+ pinctrl_i2c6_gpio: i2c6-gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_DATA0__GPIO2_IO02 0x400001e2>,
+ <MX8MP_IOMUXC_SD1_DATA1__GPIO2_IO03 0x400001e2>;
+ };
+
+ pinctrl_pcf85063: pcf85063grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19 0x80>;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x60>,
+ <MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x94>;
+ };
+
+ pinctrl_lvdsdisplay: lvdsdisplaygrp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x10>;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO09__PWM2_OUT 0x14>;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO14__PWM3_OUT 0x14>;
+ };
+
+ pinctrl_pwm3_gpio: pwm3grpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x80>;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO15__PWM4_OUT 0x14>;
+ };
+
+ pinctrl_pwm4_gpio: pwm4grpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x80>;
+ };
+
+ pinctrl_rfkill: rfkillgrp {
+ fsl,pins = <MX8MP_IOMUXC_SAI3_MCLK__GPIO5_IO02 0x14>;
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI5_MCLK 0x94>,
+ <MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_SAI5_RX_DATA00 0x94>,
+ <MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_TX_DATA00 0x94>,
+ <MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_TX_SYNC 0x94>,
+ <MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_TX_BCLK 0x94>;
+ };
+
+ pinctrl_tlv320aic3x04: tlv320aic3x04grp {
+ fsl,pins = <MX8MP_IOMUXC_ECSPI2_MOSI__GPIO5_IO11 0x180>;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI2_RXFS__UART1_DCE_TX 0x14>,
+ <MX8MP_IOMUXC_SAI2_RXC__UART1_DCE_RX 0x14>,
+ <MX8MP_IOMUXC_SAI2_RXD0__UART1_DTE_CTS 0x14>,
+ <MX8MP_IOMUXC_SAI2_TXFS__UART1_DTE_RTS 0x14>;
+ };
+
+ pinctrl_uart1_gpio: uart1gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x80>,
+ <MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x80>,
+ <MX8MP_IOMUXC_SAI2_RXD0__GPIO4_IO23 0x80>,
+ <MX8MP_IOMUXC_SAI2_TXFS__GPIO4_IO24 0x80>;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <MX8MP_IOMUXC_SAI3_TXC__UART2_DCE_TX 0x14>,
+ <MX8MP_IOMUXC_SAI3_TXFS__UART2_DCE_RX 0x14>,
+ <MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS 0x14>,
+ <MX8MP_IOMUXC_SAI3_RXC__UART2_DCE_CTS 0x14>;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_DATA6__UART3_DCE_TX 0x140>,
+ <MX8MP_IOMUXC_SD1_DATA7__UART3_DCE_RX 0x140>;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140>,
+ <MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x140>;
+ };
+
+ pinctrl_usbhub: usbhubgrp {
+ fsl,pins = <MX8MP_IOMUXC_UART3_RXD__GPIO5_IO26 0x10>;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x192>,
+ <MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d2>,
+ <MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d2>,
+ <MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d2>,
+ <MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d2>,
+ <MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d2>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x192>,
+ <MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d2>,
+ <MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d2>,
+ <MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d2>,
+ <MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d2>,
+ <MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d2>,
+ <MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0>;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194>,
+ <MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4>,
+ <MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0>;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194>,
+ <MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4>,
+ <MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4>,
+ <MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0>;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2-gpiogrp {
+ fsl,pins = <MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts
index 86d3da36e4f3..ae64731266f3 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts
@@ -135,6 +135,18 @@
};
};
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X44";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
display: display {
/*
* Display is not fixed, so compatible has to be added from
@@ -210,11 +222,6 @@
#size-cells = <2>;
ranges;
- ocram: ocram@900000 {
- no-map;
- reg = <0 0x900000 0 0x70000>;
- };
-
/* global autoconfigured region for contiguous allocations */
linux,cma {
compatible = "shared-dma-pool";
@@ -470,6 +477,28 @@
"", "", "", "";
};
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
&i2c2 {
clock-frequency = <384000>;
pinctrl-names = "default", "gpio";
@@ -531,6 +560,10 @@
status = "okay";
};
+&lcdif3 {
+ status = "okay";
+};
+
&pcf85063 {
/* RTC_EVENT# is connected on MBa8MPxL */
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi
index ebc29a950ba9..336785a9fba8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi
@@ -45,12 +45,16 @@
flash0: flash@0 {
reg = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "jedec,spi-nor";
spi-max-frequency = <80000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi
index 560c68e4da6d..6c75a5ecf56b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/net/ti-dp83867.h>
/ {
@@ -102,6 +103,25 @@
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
index e7bf032265e0..2f740d74707b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
@@ -68,7 +68,7 @@
status = "okay";
tpm@1 {
- compatible = "tcg,tpm_tis-spi";
+ compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
reg = <0x1>;
spi-max-frequency = <36000000>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
index f24b14744799..5ab3ffe9931d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
@@ -8,6 +8,10 @@
#include <dt-bindings/phy/phy-imx8-pcie.h>
/ {
+ aliases {
+ ethernet1 = &eth1;
+ };
+
connector {
compatible = "gpio-usb-b-connector", "usb-b-connector";
pinctrl-names = "default";
@@ -152,6 +156,38 @@
pinctrl-0 = <&pinctrl_pcie0>;
reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ pcie@3,0 {
+ reg = <0x1800 0 0 0 0>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ eth1: ethernet@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+ };
};
/* GPS */
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
index f5491a608b2f..e2b5e7ac3e46 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
@@ -8,6 +8,10 @@
#include <dt-bindings/phy/phy-imx8-pcie.h>
/ {
+ aliases {
+ ethernet1 = &eth1;
+ };
+
connector {
compatible = "gpio-usb-b-connector", "usb-b-connector";
pinctrl-names = "default";
@@ -164,6 +168,38 @@
pinctrl-0 = <&pinctrl_pcie0>;
reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ pcie@4,0 {
+ reg = <0x2000 0 0 0 0>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ eth1: ethernet@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+ };
};
/* GPS */
@@ -183,7 +219,7 @@
bluetooth {
compatible = "brcm,bcm4330-bt";
- shutdown-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso
index 270a9114da97..edf22ff549a4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso
@@ -62,12 +62,25 @@
status = "okay";
ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
port@0 {
+ reg = <0>;
+
mipi_csi_0_in: endpoint {
remote-endpoint = <&imx219_to_mipi_csi2>;
data-lanes = <1 2>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mipi_csi_0_out: endpoint {
+ remote-endpoint = <&isi_in_0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
index cae586cd45bd..d765b7972841 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include <dt-bindings/net/ti-dp83867.h>
#include "imx8mp.dtsi"
@@ -225,6 +226,29 @@
ethphy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
};
};
@@ -404,6 +428,12 @@
label = "vdd_dram";
};
+ channel@9e {
+ gw,mode = <2>;
+ reg = <0x9e>;
+ label = "vdd_1p0";
+ };
+
channel@a2 {
gw,mode = <2>;
reg = <0xa2>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi
index 7e9e4b13b5c5..fbcd93e33aea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi
@@ -4,13 +4,25 @@
*/
/ {
+ native-hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X21";
+ type = "a";
+
+ port {
+ native_hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,bitclock-master = <&codec_dai>;
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&codec_dai>;
simple-audio-card,mclk-fs = <256>;
- simple-audio-card,name = "imx8mp-wm8904";
+ simple-audio-card,name = "verdin-wm8904";
simple-audio-card,routing =
"Headphone Jack", "HPOUTL",
"Headphone Jack", "HPOUTR",
@@ -32,6 +44,25 @@
sound-dai = <&sai1>;
};
};
+
+ reg_usb_hub: regulator-usb-hub {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ regulator-name = "HUB_PWR_EN";
+ };
+
+ reg_pcie: regulator-pcie {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ regulator-name = "PCIE_1_PWR_EN";
+ startup-delay-us = <100000>;
+ };
};
&backlight {
@@ -70,6 +101,32 @@
status = "okay";
};
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
+/* Verdin HDMI_1 */
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&native_hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
/* Current measurement into module VCC */
&hwmon {
status = "okay";
@@ -110,8 +167,18 @@
};
};
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
/* Verdin PCIE_1 */
&pcie {
+ vpcie-supply = <&reg_pcie>;
status = "okay";
};
@@ -138,6 +205,11 @@
vin-supply = <&reg_3p3v>;
};
+/* We support turning off sleep moci on Dahlia */
+&reg_force_sleep_moci {
+ status = "disabled";
+};
+
/* Verdin I2S_1 */
&sai1 {
assigned-clocks = <&clk IMX8MP_CLK_SAI1>;
@@ -181,6 +253,25 @@
status = "okay";
};
+&usb_dwc3_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb_hub_3_0: usb-hub@1 {
+ compatible = "usb424,5744";
+ reg = <1>;
+ peer-hub = <&usb_hub_2_0>;
+ vdd-supply = <&reg_usb_hub>;
+ };
+
+ usb_hub_2_0: usb-hub@2 {
+ compatible = "usb424,2744";
+ reg = <2>;
+ peer-hub = <&usb_hub_3_0>;
+ vdd-supply = <&reg_usb_hub>;
+ };
+};
+
/* Verdin SD_1 */
&usdhc2 {
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
index a509b2b7fa85..09733fea036d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
@@ -4,6 +4,18 @@
*/
/ {
+ native-hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X37";
+ type = "a";
+
+ port {
+ native_hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
reg_eth2phy: regulator-eth2phy {
compatible = "regulator-fixed";
enable-active-high;
@@ -22,7 +34,7 @@
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&codec_dai>;
simple-audio-card,mclk-fs = <256>;
- simple-audio-card,name = "imx8mp-nau8822";
+ simple-audio-card,name = "verdin-nau8822";
simple-audio-card,routing =
"Headphones", "LHP",
"Headphones", "RHP",
@@ -93,11 +105,37 @@
status = "okay";
};
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
&gpio_expander_21 {
status = "okay";
vcc-supply = <&reg_1p8v>;
};
+/* Verdin HDMI_1 */
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&native_hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
/* Current measurement into module VCC */
&hwmon {
status = "okay";
@@ -131,6 +169,15 @@
};
};
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
/* Verdin PCIE_1 */
&pcie {
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-mallow.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-mallow.dtsi
index 8482393f3cac..3a40338cf2d8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-mallow.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-mallow.dtsi
@@ -11,6 +11,18 @@
#include <dt-bindings/leds/common.h>
/ {
+ native-hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "X14";
+ type = "a";
+
+ port {
+ native_hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -91,6 +103,27 @@
status = "okay";
};
+/* Verdin HDMI_1 */
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&native_hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
/* Temperature sensor on Mallow */
&hwmon_temp {
compatible = "ti,tmp1075";
@@ -112,6 +145,15 @@
status = "okay";
};
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
/* Verdin PCIE_1 */
&pcie {
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi
index 91d597391b7c..2ee91f31e7f0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi
@@ -41,8 +41,7 @@
pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
<&pinctrl_gpio3>, <&pinctrl_gpio4>,
<&pinctrl_gpio7>, <&pinctrl_gpio8>,
- <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
- <&pinctrl_hdmi_hog>;
+ <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>;
};
/*
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi
index ef94f9a57e20..efcab00c0142 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi
@@ -55,8 +55,7 @@
pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
<&pinctrl_gpio3>, <&pinctrl_gpio4>,
<&pinctrl_gpio7>, <&pinctrl_gpio8>,
- <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>, <&pinctrl_gpio_hog4>,
- <&pinctrl_hdmi_hog>;
+ <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>, <&pinctrl_gpio_hog4>;
};
/* On-module Bluetooth */
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi
index db1722f0d80e..533b7fe218ce 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi
@@ -6,6 +6,18 @@
#include <dt-bindings/leds/common.h>
/ {
+ native-hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "J15";
+ type = "a";
+
+ port {
+ native_hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
/* Carrier Board Supply +V1.8 */
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
@@ -100,6 +112,32 @@
status = "okay";
};
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
+/* Verdin HDMI_1 */
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&native_hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
&hwmon_temp {
status = "okay";
};
@@ -117,6 +155,15 @@
status = "okay";
};
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+ status = "okay";
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
/* Verdin PCIE_1 */
&pcie {
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
index faa17cbbe2fd..d23a3942174d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
@@ -116,6 +116,22 @@
vin-supply = <&reg_vdd_3v3>;
};
+ /*
+ * By default we enable CTRL_SLEEP_MOCI#, this is required to have
+ * peripherals on the carrier board powered.
+ * If more granularity or power saving is required this can be disabled
+ * in the carrier board device tree files.
+ */
+ reg_force_sleep_moci: regulator-force-sleep-moci {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "CTRL_SLEEP_MOCI#";
+ };
+
reg_usb1_vbus: regulator-usb1-vbus {
compatible = "regulator-fixed";
enable-active-high;
@@ -225,7 +241,6 @@
mtl_rx_setup: rx-queues-config {
snps,rx-queues-to-use = <5>;
- snps,rx-sched-sp;
queue0 {
snps,dcb-algorithm;
@@ -260,7 +275,6 @@
mtl_tx_setup: tx-queues-config {
snps,tx-queues-to-use = <5>;
- snps,tx-sched-sp;
queue0 {
snps,dcb-algorithm;
@@ -439,16 +453,13 @@
"SODIMM_256",
"SODIMM_48",
"SODIMM_44";
+};
- ctrl-sleep-moci-hog {
- gpio-hog;
- /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
- gpios = <29 GPIO_ACTIVE_HIGH>;
- line-name = "CTRL_SLEEP_MOCI#";
- output-high;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
- };
+/* Verdin HDMI_1 */
+&hdmi_tx {
+ ddc-i2c-bus = <&i2c5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
};
/* On-module I2C */
@@ -644,8 +655,7 @@
/* Verdin I2C_2_DSI */
&i2c2 {
- /* Lower frequency to avoid DDC/EDID issues with certain displays/screens. */
- clock-frequency = <10000>;
+ clock-frequency = <400000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
pinctrl-1 = <&pinctrl_i2c2_gpio>;
@@ -664,8 +674,6 @@
};
};
-/* TODO: Verdin I2C_3_HDMI */
-
/* Verdin I2C_4_CSI */
&i2c3 {
clock-frequency = <400000>;
@@ -764,6 +772,16 @@
};
};
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c5>;
+ pinctrl-1 = <&pinctrl_i2c5_gpio>;
+ scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
/* Verdin PCIE_1 */
&pcie {
pinctrl-names = "default";
@@ -1103,12 +1121,10 @@
<MX8MP_IOMUXC_SAI1_RXFS__GPIO4_IO00 0x1c4>; /* SODIMM 252 */
};
- pinctrl_hdmi_hog: hdmihoggrp {
+ pinctrl_hdmi: hdmigrp {
fsl,pins =
- <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000019>, /* SODIMM 63 */
- <MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x400001c3>, /* SODIMM 59 */
- <MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x400001c3>, /* SODIMM 57 */
- <MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000019>; /* SODIMM 61 */
+ <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x140>, /* SODIMM 63 */
+ <MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x180>; /* SODIMM 61 */
};
/* On-module I2C */
@@ -1163,6 +1179,19 @@
<MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x400001c6>; /* SODIMM 12 */
};
+ /* Verdin I2C_3_HDMI */
+ pinctrl_i2c5: i2c5grp {
+ fsl,pins =
+ <MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL 0x400001c6>, /* SODIMM 59 */
+ <MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA 0x400001c6>; /* SODIMM 57 */
+ };
+
+ pinctrl_i2c5_gpio: i2c5gpiogrp {
+ fsl,pins =
+ <MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26 0x400001c6>, /* SODIMM 59 */
+ <MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27 0x400001c6>; /* SODIMM 57 */
+ };
+
/* Verdin I2S_2_BCLK (TOUCH_RESET#) */
pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
fsl,pins =
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 8141926e4ef1..603dfe80216f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -789,6 +789,23 @@
reg = <IMX8MP_POWER_DOMAIN_USB2_PHY>;
};
+ pgc_mlmix: power-domain@4 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MP_POWER_DOMAIN_MLMIX>;
+ clocks = <&clk IMX8MP_CLK_ML_AXI>,
+ <&clk IMX8MP_CLK_ML_AHB>,
+ <&clk IMX8MP_CLK_NPU_ROOT>;
+ assigned-clocks = <&clk IMX8MP_CLK_ML_CORE>,
+ <&clk IMX8MP_CLK_ML_AXI>,
+ <&clk IMX8MP_CLK_ML_AHB>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+ <&clk IMX8MP_SYS_PLL1_800M>,
+ <&clk IMX8MP_SYS_PLL1_800M>;
+ assigned-clock-rates = <800000000>,
+ <800000000>,
+ <300000000>;
+ };
+
pgc_audio: power-domain@5 {
#power-domain-cells = <0>;
reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>;
@@ -821,6 +838,12 @@
assigned-clock-rates = <800000000>, <400000000>;
};
+ pgc_vpumix: power-domain@8 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MP_POWER_DOMAIN_VPUMIX>;
+ clocks = <&clk IMX8MP_CLK_VPU_ROOT>;
+ };
+
pgc_gpu3d: power-domain@9 {
#power-domain-cells = <0>;
reg = <IMX8MP_POWER_DOMAIN_GPU3D>;
@@ -836,69 +859,64 @@
<&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
};
- pgc_mipi_phy2: power-domain@16 {
+ pgc_vpu_g1: power-domain@11 {
#power-domain-cells = <0>;
- reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
+ power-domains = <&pgc_vpumix>;
+ reg = <IMX8MP_POWER_DOMAIN_VPU_G1>;
+ clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>;
};
- pgc_hsiomix: power-domain@17 {
+ pgc_vpu_g2: power-domain@12 {
#power-domain-cells = <0>;
- reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
- clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
- <&clk IMX8MP_CLK_HSIO_ROOT>;
- assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
- assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
- assigned-clock-rates = <500000000>;
+ power-domains = <&pgc_vpumix>;
+ reg = <IMX8MP_POWER_DOMAIN_VPU_G2>;
+ clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>;
+
};
- pgc_ispdwp: power-domain@18 {
+ pgc_vpu_vc8000e: power-domain@13 {
#power-domain-cells = <0>;
- reg = <IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP>;
- clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>;
+ power-domains = <&pgc_vpumix>;
+ reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>;
+ clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>;
};
- pgc_vpumix: power-domain@19 {
+ pgc_hdmimix: power-domain@14 {
#power-domain-cells = <0>;
- reg = <IMX8MP_POWER_DOMAIN_VPUMIX>;
- clocks = <&clk IMX8MP_CLK_VPU_ROOT>;
+ reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>;
+ clocks = <&clk IMX8MP_CLK_HDMI_ROOT>,
+ <&clk IMX8MP_CLK_HDMI_APB>;
+ assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+ <&clk IMX8MP_CLK_HDMI_APB>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+ <&clk IMX8MP_SYS_PLL1_133M>;
+ assigned-clock-rates = <500000000>, <133000000>;
};
- pgc_vpu_g1: power-domain@20 {
+ pgc_hdmi_phy: power-domain@15 {
#power-domain-cells = <0>;
- power-domains = <&pgc_vpumix>;
- reg = <IMX8MP_POWER_DOMAIN_VPU_G1>;
- clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>;
+ reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
};
- pgc_vpu_g2: power-domain@21 {
+ pgc_mipi_phy2: power-domain@16 {
#power-domain-cells = <0>;
- power-domains = <&pgc_vpumix>;
- reg = <IMX8MP_POWER_DOMAIN_VPU_G2>;
- clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>;
+ reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
};
- pgc_vpu_vc8000e: power-domain@22 {
+ pgc_hsiomix: power-domain@17 {
#power-domain-cells = <0>;
- power-domains = <&pgc_vpumix>;
- reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>;
- clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>;
+ reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
+ clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
+ <&clk IMX8MP_CLK_HSIO_ROOT>;
+ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+ assigned-clock-rates = <500000000>;
};
- pgc_mlmix: power-domain@24 {
+ pgc_ispdwp: power-domain@18 {
#power-domain-cells = <0>;
- reg = <IMX8MP_POWER_DOMAIN_MLMIX>;
- clocks = <&clk IMX8MP_CLK_ML_AXI>,
- <&clk IMX8MP_CLK_ML_AHB>,
- <&clk IMX8MP_CLK_NPU_ROOT>;
- assigned-clocks = <&clk IMX8MP_CLK_ML_CORE>,
- <&clk IMX8MP_CLK_ML_AXI>,
- <&clk IMX8MP_CLK_ML_AHB>;
- assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
- <&clk IMX8MP_SYS_PLL1_800M>,
- <&clk IMX8MP_SYS_PLL1_800M>;
- assigned-clock-rates = <800000000>,
- <800000000>,
- <300000000>;
+ reg = <IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP>;
+ clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>;
};
};
};
@@ -1513,6 +1531,41 @@
status = "disabled";
};
+ aud2htx: aud2htx@30cb0000 {
+ compatible = "fsl,imx8mp-aud2htx";
+ reg = <0x30cb0000 0x10000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG>;
+ clock-names = "bus";
+ dmas = <&sdma2 26 2 0>;
+ dma-names = "tx";
+ status = "disabled";
+ };
+
+ xcvr: xcvr@30cc0000 {
+ compatible = "fsl,imx8mp-xcvr";
+ reg = <0x30cc0000 0x800>,
+ <0x30cc0800 0x400>,
+ <0x30cc0c00 0x080>,
+ <0x30cc0e00 0x080>;
+ reg-names = "ram", "regs", "rxfifo",
+ "txfifo";
+ interrupts = /* XCVR IRQ 0 */
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ /* XCVR IRQ 1 */
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ /* XCVR PHY - SPDIF wakeup IRQ */
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_EARC_IPG>,
+ <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_EARC_PHY>,
+ <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT>,
+ <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT>;
+ clock-names = "ipg", "phy", "spba", "pll_ipg";
+ dmas = <&sdma2 30 2 0>, <&sdma2 31 2 0>;
+ dma-names = "rx", "tx";
+ resets = <&audio_blk_ctrl 0>;
+ status = "disabled";
+ };
};
sdma3: dma-controller@30e00000 {
@@ -1541,6 +1594,7 @@
compatible = "fsl,imx8mp-audio-blk-ctrl";
reg = <0x30e20000 0x10000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>,
<&clk IMX8MP_CLK_SAI1>,
<&clk IMX8MP_CLK_SAI2>,
@@ -1552,6 +1606,9 @@
"sai1", "sai2", "sai3",
"sai5", "sai6", "sai7";
power-domains = <&pgc_audio>;
+ assigned-clocks = <&clk IMX8MP_AUDIO_PLL1>,
+ <&clk IMX8MP_AUDIO_PLL2>;
+ assigned-clock-rates = <393216000>, <361267200>;
};
};
@@ -1630,7 +1687,7 @@
compatible = "fsl,imx8mp-mipi-csi2", "fsl,imx8mm-mipi-csi2";
reg = <0x32e40000 0x10000>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
- clock-frequency = <500000000>;
+ clock-frequency = <266000000>;
clocks = <&clk IMX8MP_CLK_MEDIA_APB_ROOT>,
<&clk IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT>,
<&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT>,
@@ -1640,7 +1697,7 @@
<&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF>;
assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>,
<&clk IMX8MP_CLK_24M>;
- assigned-clock-rates = <500000000>;
+ assigned-clock-rates = <266000000>;
power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_CSI2_1>;
status = "disabled";
@@ -1725,6 +1782,13 @@
remote-endpoint = <&lcdif1_to_dsim>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mipi_dsi_out: endpoint {
+ };
+ };
};
};
@@ -1889,6 +1953,136 @@
#power-domain-cells = <1>;
#clock-cells = <0>;
};
+
+ hdmi_blk_ctrl: blk-ctrl@32fc0000 {
+ compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon";
+ reg = <0x32fc0000 0x1000>;
+ clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+ <&clk IMX8MP_CLK_HDMI_ROOT>,
+ <&clk IMX8MP_CLK_HDMI_REF_266M>,
+ <&clk IMX8MP_CLK_HDMI_24M>,
+ <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+ clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
+ power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>,
+ <&pgc_hdmimix>, <&pgc_hdmimix>,
+ <&pgc_hdmimix>, <&pgc_hdmimix>,
+ <&pgc_hdmimix>, <&pgc_hdmi_phy>,
+ <&pgc_hdmimix>, <&pgc_hdmimix>;
+ power-domain-names = "bus", "irqsteer", "lcdif",
+ "pai", "pvi", "trng",
+ "hdmi-tx", "hdmi-tx-phy",
+ "hdcp", "hrv";
+ #power-domain-cells = <1>;
+ };
+
+ irqsteer_hdmi: interrupt-controller@32fc2000 {
+ compatible = "fsl,imx8mp-irqsteer", "fsl,imx-irqsteer";
+ reg = <0x32fc2000 0x1000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ fsl,channel = <1>;
+ fsl,num-irqs = <64>;
+ clocks = <&clk IMX8MP_CLK_HDMI_APB>;
+ clock-names = "ipg";
+ power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
+ };
+
+ hdmi_pvi: display-bridge@32fc4000 {
+ compatible = "fsl,imx8mp-hdmi-pvi";
+ reg = <0x32fc4000 0x1000>;
+ interrupt-parent = <&irqsteer_hdmi>;
+ interrupts = <12>;
+ power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ pvi_from_lcdif3: endpoint {
+ remote-endpoint = <&lcdif3_to_pvi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ pvi_to_hdmi_tx: endpoint {
+ remote-endpoint = <&hdmi_tx_from_pvi>;
+ };
+ };
+ };
+ };
+
+ lcdif3: display-controller@32fc6000 {
+ compatible = "fsl,imx8mp-lcdif";
+ reg = <0x32fc6000 0x1000>;
+ interrupt-parent = <&irqsteer_hdmi>;
+ interrupts = <8>;
+ clocks = <&hdmi_tx_phy>,
+ <&clk IMX8MP_CLK_HDMI_APB>,
+ <&clk IMX8MP_CLK_HDMI_ROOT>;
+ clock-names = "pix", "axi", "disp_axi";
+ power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>;
+ status = "disabled";
+
+ port {
+ lcdif3_to_pvi: endpoint {
+ remote-endpoint = <&pvi_from_lcdif3>;
+ };
+ };
+ };
+
+ hdmi_tx: hdmi@32fd8000 {
+ compatible = "fsl,imx8mp-hdmi-tx";
+ reg = <0x32fd8000 0x7eff>;
+ interrupt-parent = <&irqsteer_hdmi>;
+ interrupts = <0>;
+ clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+ <&clk IMX8MP_CLK_HDMI_REF_266M>,
+ <&clk IMX8MP_CLK_32K>,
+ <&hdmi_tx_phy>;
+ clock-names = "iahb", "isfr", "cec", "pix";
+ assigned-clocks = <&clk IMX8MP_CLK_HDMI_REF_266M>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>;
+ power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
+ reg-io-width = <1>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ hdmi_tx_from_pvi: endpoint {
+ remote-endpoint = <&pvi_to_hdmi_tx>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ /* Point endpoint to the HDMI connector */
+ };
+ };
+ };
+
+ hdmi_tx_phy: phy@32fdff00 {
+ compatible = "fsl,imx8mp-hdmi-phy";
+ reg = <0x32fdff00 0x100>;
+ clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+ <&clk IMX8MP_CLK_HDMI_24M>;
+ clock-names = "apb", "ref";
+ assigned-clocks = <&clk IMX8MP_CLK_HDMI_24M>;
+ assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+ power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
};
pcie: pcie@33800000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
index 366693f31992..e92b5d5a66b5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
@@ -42,7 +42,7 @@
status = "okay";
typec_ptn5100: usb-typec@50 {
- compatible = "nxp,ptn5110";
+ compatible = "nxp,ptn5110", "tcpci";
reg = <0x50>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
index 8055a2c23035..b268ba7a0e12 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
@@ -429,7 +429,7 @@
};
typec_ptn5100: usb-typec@52 {
- compatible = "nxp,ptn5110";
+ compatible = "nxp,ptn5110", "tcpci";
reg = <0x52>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
index ffb5fe61630d..1b39514d5c12 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
@@ -45,7 +45,6 @@
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
linux,code = <KEY_VOLUMEDOWN>;
debounce-interval = <50>;
- wakeup-source;
};
key-vol-up {
@@ -53,7 +52,6 @@
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
linux,code = <KEY_VOLUMEUP>;
debounce-interval = <50>;
- wakeup-source;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
index 5ca6b2252546..01e5092e4c40 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
@@ -251,11 +251,15 @@
flash0: flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
spi-max-frequency = <84000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index c6dc3ba0d43b..e03186bbc415 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1290,6 +1290,13 @@
remote-endpoint = <&lcdif_mipi_dsi>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mipi_dsi_out: endpoint {
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index 77ac0efdfaad..778741dbbb33 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -36,9 +36,182 @@
regulator-name = "SD1_SPWR";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
- gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>;
+ gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ reg_fec2_supply: regulator-fec2-nvcc {
+ compatible = "regulator-fixed";
+ regulator-name = "fec2_nvcc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can01_en: regulator-can01-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can01-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 3 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can2_en: regulator-can2-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can2-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can01_stby: regulator-can01-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can01-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can01_en>;
+ };
+
+ reg_can2_stby: regulator-can2-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can2-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can2_en>;
+ };
+
+ reg_vref_1v8: regulator-adc-vref {
+ compatible = "regulator-fixed";
+ regulator-name = "vref_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ bt_sco_codec: audio-codec-bt {
+ compatible = "linux,bt-sco";
+ #sound-dai-cells = <1>;
+ };
+
+ sound-bt-sco {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "bt-sco-audio";
+ simple-audio-card,format = "dsp_a";
+ simple-audio-card,bitclock-inversion;
+ simple-audio-card,frame-master = <&btcpu>;
+ simple-audio-card,bitclock-master = <&btcpu>;
+
+ btcpu: simple-audio-card,cpu {
+ sound-dai = <&sai0>;
+ dai-tdm-slot-num = <2>;
+ dai-tdm-slot-width = <16>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&bt_sco_codec 1>;
+ };
+ };
+
+ sound-wm8960 {
+ compatible = "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&wm8960>;
+ hp-det-gpio = <&lsio_gpio0 31 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", "Mic Jack",
+ "Mic Jack", "MICB";
+ };
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&cm41_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cm41_i2c>;
+ status = "okay";
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&cm41_intmux {
+ status = "okay";
+};
+
+&i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ status = "okay";
+
+ accelerometer@19 {
+ compatible = "st,lsm303agr-accel";
+ reg = <0x19>;
+ };
+
+ gyrometer@20 {
+ compatible = "nxp,fxas21002c";
+ reg = <0x20>;
+ };
+
+ light-sensor@44 {
+ compatible = "isil,isl29023";
+ reg = <0x44>;
+ interrupt-parent = <&lsio_gpio4>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ pressure-sensor@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ };
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gyrometer@69 {
+ compatible = "st,l3g4200d-gyro";
+ reg = <0x69>;
+ };
};
&i2c1 {
@@ -51,6 +224,42 @@
scl-gpios = <&lsio_gpio0 14 GPIO_ACTIVE_HIGH>;
sda-gpios = <&lsio_gpio0 15 GPIO_ACTIVE_HIGH>;
status = "okay";
+
+ wm8960: audio-codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk";
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ wlf,shared-lrclk;
+ wlf,hp-cfg = <2 2 3>;
+ wlf,gpio-cfg = <1 3>;
+ };
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can01_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can01_stby>;
+ status = "okay";
+};
+
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_can2_stby>;
+ status = "okay";
};
&lpuart0 {
@@ -71,6 +280,45 @@
status = "okay";
};
+&lpspi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi2 &pinctrl_lpspi2_cs>;
+ cs-gpios = <&lsio_gpio3 10 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <30000000>;
+ };
+};
+
+&lsio_mu5 {
+ status = "okay";
+};
+
+&lsio_mu6 {
+ status = "okay";
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: flash@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <133000000>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ };
+};
+
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
@@ -95,6 +343,19 @@
};
};
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec2_supply>;
+ nvmem-cells = <&fec_mac1>;
+ nvmem-cell-names = "mac-address";
+ rx-internal-delay-ps = <2000>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1>;
@@ -115,7 +376,71 @@
status = "okay";
};
+&sai0 {
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai0_lpcg IMX_LPCG_CLK_4>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai1_lpcg IMX_LPCG_CLK_4>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&sai6 {
+ assigned-clocks = <&acm IMX_ADMA_ACM_SAI6_MCLK_SEL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai6_lpcg IMX_LPCG_CLK_4>;
+ assigned-clock-parents = <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai7 {
+ assigned-clocks = <&acm IMX_ADMA_ACM_SAI7_MCLK_SEL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai7_lpcg IMX_LPCG_CLK_4>;
+ assigned-clock-parents = <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ IMX8QM_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0x0600004c
+ IMX8QM_SCU_GPIO0_03_LSIO_GPIO0_IO31 0x0600004c
+ >;
+ };
+
+ pinctrl_i2c0: i2c0grp {
+ fsl,pins = <
+ IMX8QM_HDMI_TX0_TS_SCL_DMA_I2C0_SCL 0x06000021
+ IMX8QM_HDMI_TX0_TS_SDA_DMA_I2C0_SDA 0x06000021
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
IMX8QM_GPT0_CLK_DMA_I2C1_SCL 0x0600004c
@@ -130,6 +455,19 @@
>;
};
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <
+ IMX8QM_ADC_IN0_DMA_ADC0_IN0 0xc0000060
+ >;
+ };
+
+ pinctrl_cm41_i2c: cm41i2cgrp {
+ fsl,pins = <
+ IMX8QM_M41_I2C0_SDA_M41_I2C0_SDA 0x0600004c
+ IMX8QM_M41_I2C0_SCL_M41_I2C0_SCL 0x0600004c
+ >;
+ };
+
pinctrl_fec1: fec1grp {
fsl,pins = <
IMX8QM_ENET0_MDC_CONN_ENET0_MDC 0x06000020
@@ -149,6 +487,80 @@
>;
};
+ pinctrl_lpspi2: lpspi2grp {
+ fsl,pins = <
+ IMX8QM_SPI2_SCK_DMA_SPI2_SCK 0x06000040
+ IMX8QM_SPI2_SDO_DMA_SPI2_SDO 0x06000040
+ IMX8QM_SPI2_SDI_DMA_SPI2_SDI 0x06000040
+ >;
+ };
+
+ pinctrl_lpspi2_cs: lpspi2csgrp {
+ fsl,pins = <
+ IMX8QM_SPI2_CS0_LSIO_GPIO3_IO10 0x21
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ IMX8QM_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ IMX8QM_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ IMX8QM_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ IMX8QM_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ IMX8QM_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021
+ IMX8QM_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ IMX8QM_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021
+ IMX8QM_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ IMX8QM_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021
+ IMX8QM_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021
+ IMX8QM_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021
+ IMX8QM_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021
+ IMX8QM_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021
+ IMX8QM_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021
+ IMX8QM_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021
+ IMX8QM_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021
+ >;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <
+ IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0
+ IMX8QM_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x00000060
+ IMX8QM_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC 0x00000060
+ IMX8QM_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x00000060
+ IMX8QM_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x00000060
+ IMX8QM_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 0x00000060
+ IMX8QM_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 0x00000060
+ IMX8QM_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC 0x00000060
+ IMX8QM_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x00000060
+ IMX8QM_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x00000060
+ IMX8QM_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x00000060
+ IMX8QM_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 0x00000060
+ IMX8QM_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN0_TX_DMA_FLEXCAN0_TX 0x21
+ IMX8QM_FLEXCAN0_RX_DMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN1_TX_DMA_FLEXCAN1_TX 0x21
+ IMX8QM_FLEXCAN1_RX_DMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan3: flexcan3grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN2_TX_DMA_FLEXCAN2_TX 0x21
+ IMX8QM_FLEXCAN2_RX_DMA_FLEXCAN2_RX 0x21
+ >;
+ };
+
pinctrl_lpuart0: lpuart0grp {
fsl,pins = <
IMX8QM_UART0_RX_DMA_UART0_RX 0x06000020
@@ -170,6 +582,24 @@
>;
};
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ IMX8QM_SPI0_CS1_AUD_SAI0_TXC 0x0600004c
+ IMX8QM_SPI2_CS1_AUD_SAI0_TXFS 0x0600004c
+ IMX8QM_SAI1_RXFS_AUD_SAI0_RXD 0x0600004c
+ IMX8QM_SAI1_RXC_AUD_SAI0_TXD 0x0600006c
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ IMX8QM_SAI1_RXD_AUD_SAI1_RXD 0x06000040
+ IMX8QM_SAI1_TXFS_AUD_SAI1_TXFS 0x06000040
+ IMX8QM_SAI1_TXD_AUD_SAI1_TXD 0x06000060
+ IMX8QM_SAI1_TXC_AUD_SAI1_TXC 0x06000040
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi
new file mode 100644
index 000000000000..3036af49fc85
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ * Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+/delete-node/ &acm;
+/delete-node/ &sai4;
+/delete-node/ &sai5;
+/delete-node/ &sai4_lpcg;
+/delete-node/ &sai5_lpcg;
+
+&amix {
+ dais = <&sai6>, <&sai7>;
+};
+
+&asrc0 {
+ clocks = <&asrc0_lpcg IMX_LPCG_CLK_0>,
+ <&asrc0_lpcg IMX_LPCG_CLK_2>,
+ <&aud_pll_div0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>,
+ <&acm IMX_ADMA_ACM_AUD_CLK0_SEL>,
+ <&acm IMX_ADMA_ACM_AUD_CLK1_SEL>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_ASRC_0>;
+};
+
+&asrc0_lpcg {
+ clocks = <&audio_ipg_clk>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_2>;
+ clock-output-names = "asrc0_lpcg_ipg_clk", "asrc0_lpcg_mem_clk";
+};
+
+&asrc1 {
+ clocks = <&asrc1_lpcg IMX_LPCG_CLK_0>,
+ <&asrc1_lpcg IMX_LPCG_CLK_2>,
+ <&aud_pll_div0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>,
+ <&acm IMX_ADMA_ACM_AUD_CLK0_SEL>,
+ <&acm IMX_ADMA_ACM_AUD_CLK1_SEL>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_ASRC_1>;
+};
+
+&asrc1_lpcg {
+ clocks = <&audio_ipg_clk>, <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_2>;
+ clock-output-names = "asrc1_lpcg_ipg_clk", "asrc1_lpcg_mem_clk";
+};
+
+&audio_subsys {
+
+ sai4: sai@59080000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59080000 0x10000>;
+ interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai4_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai4_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma0 18 0 1>;
+ fsl,dataline = <0 0xf 0x0>;
+ power-domains = <&pd IMX_SC_R_SAI_4>;
+ status = "disabled";
+ };
+
+ sai5: sai@59090000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59090000 0x10000>;
+ interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai5_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai5_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx";
+ dmas = <&edma0 19 0 0>;
+ fsl,dataline = <0 0x0 0xf>;
+ power-domains = <&pd IMX_SC_R_SAI_5>;
+ status = "disabled";
+ };
+
+ sai4_lpcg: clock-controller@59480000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59480000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI4_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai4_lpcg_mclk", "sai4_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_4>;
+ status = "disabled";
+ };
+
+ sai5_lpcg: clock-controller@59490000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59490000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI5_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai5_lpcg_mclk", "sai5_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_5>;
+ status = "disabled";
+ };
+
+ esai1: esai@59810000 {
+ compatible = "fsl,imx8qm-esai";
+ reg = <0x59810000 0x10000>;
+ interrupts = <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&esai1_lpcg IMX_LPCG_CLK_0>,
+ <&esai1_lpcg IMX_LPCG_CLK_4>,
+ <&esai1_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>;
+ clock-names = "core", "extal", "fsys", "spba";
+ dmas = <&edma1 6 0 1>, <&edma1 7 0 0>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd IMX_SC_R_ESAI_1>;
+ status = "disabled";
+ };
+
+ sai6: sai@59820000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59820000 0x10000>;
+ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai6_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai6_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma1 8 0 1>, <&edma1 9 0 0>;
+ power-domains = <&pd IMX_SC_R_SAI_6>;
+ status = "disabled";
+ };
+
+ sai7: sai@59830000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59830000 0x10000>;
+ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai7_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai7_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx";
+ dmas = <&edma1 10 0 0>;
+ power-domains = <&pd IMX_SC_R_SAI_7>;
+ status = "disabled";
+ };
+
+ esai1_lpcg: clock-controller@59c10000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c10000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_ESAI1_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "esai1_lpcg_extal_clk", "esai1_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_ESAI_1>;
+ };
+
+ sai6_lpcg: clock-controller@59c20000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c20000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI6_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai6_lpcg_mclk", "sai6_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_6>;
+ };
+
+ sai7_lpcg: clock-controller@59c30000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59c30000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI7_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai7_lpcg_mclk", "sai7_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_7>;
+ };
+
+ acm: acm@59e00000 {
+ compatible = "fsl,imx8qm-acm";
+ reg = <0x59e00000 0x1d0000>;
+ #clock-cells = <1>;
+ power-domains = <&pd IMX_SC_R_AUDIO_CLK_0>,
+ <&pd IMX_SC_R_AUDIO_CLK_1>,
+ <&pd IMX_SC_R_MCLK_OUT_0>,
+ <&pd IMX_SC_R_MCLK_OUT_1>,
+ <&pd IMX_SC_R_AUDIO_PLL_0>,
+ <&pd IMX_SC_R_AUDIO_PLL_1>,
+ <&pd IMX_SC_R_ASRC_0>,
+ <&pd IMX_SC_R_ASRC_1>,
+ <&pd IMX_SC_R_ESAI_0>,
+ <&pd IMX_SC_R_ESAI_1>,
+ <&pd IMX_SC_R_SAI_0>,
+ <&pd IMX_SC_R_SAI_1>,
+ <&pd IMX_SC_R_SAI_2>,
+ <&pd IMX_SC_R_SAI_3>,
+ <&pd IMX_SC_R_SAI_4>,
+ <&pd IMX_SC_R_SAI_5>,
+ <&pd IMX_SC_R_SAI_6>,
+ <&pd IMX_SC_R_SAI_7>,
+ <&pd IMX_SC_R_SPDIF_0>,
+ <&pd IMX_SC_R_SPDIF_1>,
+ <&pd IMX_SC_R_MQS_0>;
+ clocks = <&aud_rec0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_rec1_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div0_lpcg IMX_LPCG_CLK_0>,
+ <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>,
+ <&clk_mlb_clk>,
+ <&clk_hdmi_rx_mclk>,
+ <&clk_ext_aud_mclk0>,
+ <&clk_ext_aud_mclk1>,
+ <&clk_esai0_rx_clk>,
+ <&clk_esai0_rx_hf_clk>,
+ <&clk_esai0_tx_clk>,
+ <&clk_esai0_tx_hf_clk>,
+ <&clk_esai1_rx_clk>,
+ <&clk_esai1_rx_hf_clk>,
+ <&clk_esai1_tx_clk>,
+ <&clk_esai1_tx_hf_clk>,
+ <&clk_spdif0_rx>,
+ <&clk_spdif0_rx>,
+ <&clk_sai0_rx_bclk>,
+ <&clk_sai0_tx_bclk>,
+ <&clk_sai1_rx_bclk>,
+ <&clk_sai1_tx_bclk>,
+ <&clk_sai2_rx_bclk>,
+ <&clk_sai3_rx_bclk>,
+ <&clk_sai4_rx_bclk>,
+ <&clk_sai5_rx_bclk>,
+ <&clk_sai6_rx_bclk>;
+ clock-names = "aud_rec_clk0_lpcg_clk",
+ "aud_rec_clk1_lpcg_clk",
+ "aud_pll_div_clk0_lpcg_clk",
+ "aud_pll_div_clk1_lpcg_clk",
+ "mlb_clk",
+ "hdmi_rx_mclk",
+ "ext_aud_mclk0",
+ "ext_aud_mclk1",
+ "esai0_rx_clk",
+ "esai0_rx_hf_clk",
+ "esai0_tx_clk",
+ "esai0_tx_hf_clk",
+ "esai1_rx_clk",
+ "esai1_rx_hf_clk",
+ "esai1_tx_clk",
+ "esai1_tx_hf_clk",
+ "spdif0_rx",
+ "spdif1_rx",
+ "sai0_rx_bclk",
+ "sai0_tx_bclk",
+ "sai1_rx_bclk",
+ "sai1_tx_bclk",
+ "sai2_rx_bclk",
+ "sai3_rx_bclk",
+ "sai4_rx_bclk",
+ "sai5_tx_bclk",
+ "sai6_rx_bclk";
+ };
+};
+
+&dsp_lpcg {
+ status = "disabled";
+};
+
+&dsp_ram_lpcg {
+ status = "disabled";
+};
+
+/* edma2 called in imx8qm RM with the same address in edma0 of imx8qxp */
+&edma0{
+ reg = <0x591f0000 0x150000>;
+ dma-channels = <20>;
+ dma-channel-mask = <0>;
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>, /* asrc0 */
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* esai0 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>, /* spdif1 */
+ <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>, /* sai2 */
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* sai3 */
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* sai4 */
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>; /* sai5 */
+ power-domains = <&pd IMX_SC_R_DMA_2_CH0>,
+ <&pd IMX_SC_R_DMA_2_CH1>,
+ <&pd IMX_SC_R_DMA_2_CH2>,
+ <&pd IMX_SC_R_DMA_2_CH3>,
+ <&pd IMX_SC_R_DMA_2_CH4>,
+ <&pd IMX_SC_R_DMA_2_CH5>,
+ <&pd IMX_SC_R_DMA_2_CH6>,
+ <&pd IMX_SC_R_DMA_2_CH7>,
+ <&pd IMX_SC_R_DMA_2_CH8>,
+ <&pd IMX_SC_R_DMA_2_CH9>,
+ <&pd IMX_SC_R_DMA_2_CH10>,
+ <&pd IMX_SC_R_DMA_2_CH11>,
+ <&pd IMX_SC_R_DMA_2_CH12>,
+ <&pd IMX_SC_R_DMA_2_CH13>,
+ <&pd IMX_SC_R_DMA_2_CH14>,
+ <&pd IMX_SC_R_DMA_2_CH15>,
+ <&pd IMX_SC_R_DMA_2_CH16>,
+ <&pd IMX_SC_R_DMA_2_CH17>,
+ <&pd IMX_SC_R_DMA_2_CH18>,
+ <&pd IMX_SC_R_DMA_2_CH19>;
+};
+
+/* edma3 called in imx8qm RM with the same address in edma1 of imx8qxp */
+&edma1{
+ reg = <0x599f0000 0xc0000>;
+ dma-channels = <11>;
+ dma-channel-mask = <0xc0>;
+ interrupts = <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>, /* asrc1 */
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* no used */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* no used */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* sai6 */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>; /* sai7 */
+ power-domains = <&pd IMX_SC_R_DMA_3_CH0>,
+ <&pd IMX_SC_R_DMA_3_CH1>,
+ <&pd IMX_SC_R_DMA_3_CH2>,
+ <&pd IMX_SC_R_DMA_3_CH3>,
+ <&pd IMX_SC_R_DMA_3_CH4>,
+ <&pd IMX_SC_R_DMA_3_CH5>,
+ <&pd IMX_SC_R_DMA_3_CH6>,
+ <&pd IMX_SC_R_DMA_3_CH7>,
+ <&pd IMX_SC_R_DMA_3_CH8>,
+ <&pd IMX_SC_R_DMA_3_CH9>,
+ <&pd IMX_SC_R_DMA_3_CH10>;
+};
+
+&esai0 {
+ clocks = <&esai0_lpcg IMX_LPCG_CLK_0>,
+ <&esai0_lpcg IMX_LPCG_CLK_4>,
+ <&esai0_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_ESAI_0>;
+};
+
+&esai0_lpcg {
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "esai0_lpcg_extal_clk", "esai0_lpcg_ipg_clk";
+};
+
+&mqs0_lpcg {
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "mqs0_lpcg_mclk", "mqs0_lpcg_ipg_clk";
+};
+
+&sai0 {
+ clocks = <&sai0_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai0_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_SAI_0>;
+};
+
+&sai0_lpcg {
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai0_lpcg_mclk", "sai0_lpcg_ipg_clk";
+};
+
+&sai1 {
+ clocks = <&sai1_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai1_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_SAI_1>;
+};
+
+&sai1_lpcg {
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai1_lpcg_mclk", "sai1_lpcg_ipg_clk";
+};
+
+&sai2 {
+ clocks = <&sai2_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai2_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_SAI_2>;
+};
+
+&sai2_lpcg {
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai2_lpcg_mclk", "sai2_lpcg_ipg_clk";
+};
+
+&sai3 {
+ clocks = <&sai3_lpcg IMX_LPCG_CLK_0>,
+ <&clk_dummy>,
+ <&sai3_lpcg IMX_LPCG_CLK_4>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ power-domains = <&pd IMX_SC_R_SAI_3>;
+};
+
+&sai3_lpcg {
+ clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_0>;
+ clock-output-names = "sai3_lpcg_mclk", "sai3_lpcg_ipg_clk";
+};
+
+&spdif0 {
+ clocks = <&spdif0_lpcg IMX_LPCG_CLK_4>, /* core */
+ <&clk_dummy>, /* rxtx0 */
+ <&spdif0_lpcg IMX_LPCG_CLK_5>, /* rxtx1 */
+ <&clk_dummy>, /* rxtx2 */
+ <&clk_dummy>, /* rxtx3 */
+ <&clk_dummy>, /* rxtx4 */
+ <&audio_ipg_clk>, /* rxtx5 */
+ <&clk_dummy>, /* rxtx6 */
+ <&clk_dummy>, /* rxtx7 */
+ <&clk_dummy>; /* spba */
+ power-domains = <&pd IMX_SC_R_SPDIF_0>;
+};
+
+&spdif0_lpcg {
+ clock-indices = <IMX_LPCG_CLK_5>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "spdif0_lpcg_tx_clk", "spdif0_lpcg_gclkw";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
index b3d01677b70c..61986e0639e5 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
@@ -333,6 +333,21 @@
compatible = "fsl,imx8qxp-sc-rtc";
};
+ ocotp: ocotp {
+ compatible = "fsl,imx8qm-scu-ocotp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ read-only;
+
+ fec_mac0: mac@1c4 {
+ reg = <0x1c4 6>;
+ };
+
+ fec_mac1: mac@1c6 {
+ reg = <0x1c6 6>;
+ };
+ };
+
tsens: thermal-sensor {
compatible = "fsl,imx8qxp-sc-thermal", "fsl,imx-sc-thermal";
#thermal-sensor-cells = <1>;
@@ -461,8 +476,95 @@
};
};
+ clk_dummy: clock-dummy {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "clk_dummy";
+ };
+
+ clk_esai1_rx_clk: clock-esai1-rx {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai1_rx_clk";
+ };
+
+ clk_esai1_rx_hf_clk: clock-esai1-rx-hf {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai1_rx_hf_clk";
+ };
+
+ clk_esai1_tx_clk: clock-esai1-tx {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai1_tx_clk";
+ };
+
+ clk_esai1_tx_hf_clk: clock-esai1-tx-hf {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai1_tx_hf_clk";
+ };
+
+ clk_hdmi_rx_mclk: clock-hdmi-rx-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "hdmi-rx-mclk";
+ };
+
+ clk_mlb_clk: clock-mlb-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "mlb_clk";
+ };
+
+ clk_sai5_rx_bclk: clock-sai5-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai5_rx_bclk";
+ };
+
+ clk_sai5_tx_bclk: clock-sai5-tx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai5_tx_bclk";
+ };
+
+ clk_sai6_rx_bclk: clock-sai6-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai6_rx_bclk";
+ };
+
+ clk_sai6_tx_bclk: clock-sai6-tx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai6_tx_bclk";
+ };
+
+ clk_spdif1_rx: clock-spdif1-rx {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "spdif1_rx";
+ };
+
/* sorted in register address */
+ #include "imx8-ss-cm41.dtsi"
+ #include "imx8-ss-audio.dtsi"
#include "imx8-ss-vpu.dtsi"
+ #include "imx8-ss-gpu0.dtsi"
#include "imx8-ss-img.dtsi"
#include "imx8-ss-dma.dtsi"
#include "imx8-ss-conn.dtsi"
@@ -473,3 +575,4 @@
#include "imx8qm-ss-dma.dtsi"
#include "imx8qm-ss-conn.dtsi"
#include "imx8qm-ss-lsio.dtsi"
+#include "imx8qm-ss-audio.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 8360bb851ac0..936ba5ecdcac 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -44,9 +44,26 @@
};
};
};
+
+ sound-wm8960 {
+ compatible = "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&wm8960>;
+ hp-det-gpio = <&lsio_gpio1 0 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", "Mic Jack",
+ "Mic Jack", "MICB";
+ };
};
&dsp {
+ memory-region = <&dsp_reserved>;
status = "okay";
};
@@ -149,7 +166,7 @@
};
ptn5110: tcpc@50 {
- compatible = "nxp,ptn5110";
+ compatible = "nxp,ptn5110", "tcpci";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec>;
reg = <0x50>;
@@ -188,6 +205,47 @@
};
+&cm40_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_cm40_i2c>;
+ pinctrl-1 = <&pinctrl_cm40_i2c_gpio>;
+ scl-gpios = <&lsio_gpio1 10 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&lsio_gpio1 9 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ wm8960: audio-codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk";
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>,
+ <49152000>,
+ <12288000>,
+ <12288000>;
+ wlf,shared-lrclk;
+ wlf,hp-cfg = <2 2 3>;
+ wlf,gpio-cfg = <1 3>;
+ };
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&cm40_intmux {
+ status = "okay";
+};
+
&lpuart0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpuart0>;
@@ -218,6 +276,53 @@
status = "okay";
};
+&sai0 {
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai0_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&sai4 {
+ assigned-clocks = <&acm IMX_ADMA_ACM_SAI4_MCLK_SEL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai4_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-parents = <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai5 {
+ assigned-clocks = <&acm IMX_ADMA_ACM_SAI5_MCLK_SEL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai5_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-parents = <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
&thermal_zones {
pmic-thermal {
polling-delay-passive = <250>;
@@ -314,6 +419,21 @@
};
&iomuxc {
+
+ pinctrl_cm40_i2c: cm40i2cgrp {
+ fsl,pins = <
+ IMX8QXP_ADC_IN1_M40_I2C0_SDA 0x0600004c
+ IMX8QXP_ADC_IN0_M40_I2C0_SCL 0x0600004c
+ >;
+ };
+
+ pinctrl_cm40_i2c_gpio: cm40i2cgpio-grp {
+ fsl,pins = <
+ IMX8QXP_ADC_IN1_LSIO_GPIO1_IO09 0xc600004c
+ IMX8QXP_ADC_IN0_LSIO_GPIO1_IO10 0xc600004c
+ >;
+ };
+
pinctrl_fec1: fec1grp {
fsl,pins = <
IMX8QXP_ENET0_MDC_CONN_ENET0_MDC 0x06000020
@@ -385,6 +505,25 @@
>;
};
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ IMX8QXP_SAI0_TXD_ADMA_SAI0_TXD 0x06000060
+ IMX8QXP_SAI0_RXD_ADMA_SAI0_RXD 0x06000040
+ IMX8QXP_SAI0_TXC_ADMA_SAI0_TXC 0x06000040
+ IMX8QXP_SAI0_TXFS_ADMA_SAI0_TXFS 0x06000040
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ IMX8QXP_SAI1_RXD_ADMA_SAI1_RXD 0x06000040
+ IMX8QXP_SAI1_RXC_ADMA_SAI1_TXC 0x06000040
+ IMX8QXP_SAI1_RXFS_ADMA_SAI1_TXFS 0x06000040
+ IMX8QXP_SPI0_CS1_ADMA_SAI1_TXD 0x06000060
+ IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00 0x06000040
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 10e16d84c0c3..0313f295de2e 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -317,6 +317,7 @@
/* sorted in register address */
#include "imx8-ss-img.dtsi"
#include "imx8-ss-vpu.dtsi"
+ #include "imx8-ss-cm40.dtsi"
#include "imx8-ss-gpu0.dtsi"
#include "imx8-ss-adma.dtsi"
#include "imx8-ss-conn.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 24bb253b938d..e937e5f8fa8b 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -127,12 +127,70 @@
pinctrl-1 = <&pinctrl_lpi2c7>;
status = "okay";
+ ptn5150_1: typec@1d {
+ compatible = "nxp,ptn5150";
+ reg = <0x1d>;
+ int-gpios = <&gpiof 3 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec1>;
+ status = "disabled";
+ };
+
pcal6408: gpio@21 {
compatible = "nxp,pcal9554b";
reg = <0x21>;
gpio-controller;
#gpio-cells = <2>;
};
+
+ ptn5150_2: typec@3d {
+ compatible = "nxp,ptn5150";
+ reg = <0x3d>;
+ int-gpios = <&gpiof 5 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec2>;
+ status = "disabled";
+ };
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ over-current-active-low;
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <110>;
+ status = "okay";
+};
+
+&usbmisc1 {
+ status = "okay";
+};
+
+&usbotg2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ over-current-active-low;
+ status = "okay";
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <110>;
+ status = "okay";
+};
+
+&usbmisc2 {
+ status = "okay";
};
&usdhc0 {
@@ -224,6 +282,32 @@
>;
};
+ pinctrl_typec1: typec1grp {
+ fsl,pins = <
+ MX8ULP_PAD_PTF3__PTF3 0x3
+ >;
+ };
+
+ pinctrl_typec2: typec2grp {
+ fsl,pins = <
+ MX8ULP_PAD_PTF5__PTF5 0x3
+ >;
+ };
+
+ pinctrl_usb1: usb1grp {
+ fsl,pins = <
+ MX8ULP_PAD_PTF2__USB0_ID 0x10003
+ MX8ULP_PAD_PTF4__USB0_OC 0x10003
+ >;
+ };
+
+ pinctrl_usb2: usb2grp {
+ fsl,pins = <
+ MX8ULP_PAD_PTD23__USB1_ID 0x10003
+ MX8ULP_PAD_PTF6__USB1_OC 0x10003
+ >;
+ };
+
pinctrl_usdhc0: usdhc0grp {
fsl,pins = <
MX8ULP_PAD_PTD1__SDHC0_CMD 0x3
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index c4a0082f30d3..e32d5afcf4a9 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -252,6 +252,38 @@
#reset-cells = <1>;
};
+ crypto: crypto@292e0000 {
+ compatible = "fsl,sec-v4.0";
+ reg = <0x292e0000 0x10000>;
+ ranges = <0 0x292e0000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sec_jr0: jr@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr2: jr@3000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr3: jr@4000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
tpm5: tpm@29340000 {
compatible = "fsl,imx8ulp-tpm", "fsl,imx7ulp-tpm";
reg = <0x29340000 0x1000>;
@@ -472,6 +504,68 @@
status = "disabled";
};
+ usbotg1: usb@29900000 {
+ compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+ reg = <0x29900000 0x200>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pcc4 IMX8ULP_CLK_USB0>;
+ power-domains = <&scmi_devpd IMX8ULP_PD_USB0>;
+ phys = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x8>;
+ rx-burst-size-dword = <0x8>;
+ status = "disabled";
+ };
+
+ usbmisc1: usbmisc@29900200 {
+ compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+ "fsl,imx6q-usbmisc";
+ reg = <0x29900200 0x200>;
+ #index-cells = <1>;
+ status = "disabled";
+ };
+
+ usbphy1: usb-phy@29910000 {
+ compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+ reg = <0x29910000 0x10000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pcc4 IMX8ULP_CLK_USB0_PHY>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ usbotg2: usb@29920000 {
+ compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+ reg = <0x29920000 0x200>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pcc4 IMX8ULP_CLK_USB1>;
+ power-domains = <&scmi_devpd IMX8ULP_PD_USDHC2_USB1>;
+ phys = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc2 0>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x8>;
+ rx-burst-size-dword = <0x8>;
+ status = "disabled";
+ };
+
+ usbmisc2: usbmisc@29920200 {
+ compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+ "fsl,imx6q-usbmisc";
+ reg = <0x29920200 0x200>;
+ #index-cells = <1>;
+ status = "disabled";
+ };
+
+ usbphy2: usb-phy@29930000 {
+ compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+ reg = <0x29930000 0x10000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pcc4 IMX8ULP_CLK_USB1_PHY>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
fec: ethernet@29950000 {
compatible = "fsl,imx8ulp-fec", "fsl,imx6ul-fec", "fsl,imx6q-fec";
reg = <0x29950000 0x10000>;
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index 9921ea13ab48..a15987f49e8d 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -5,6 +5,7 @@
/dts-v1/;
+#include <dt-bindings/usb/pd.h>
#include "imx93.dtsi"
/ {
@@ -38,7 +39,7 @@
no-map;
};
- vdev1vring0: vdev1vring0@a4000000 {
+ vdev1vring0: vdev1vring0@a4010000 {
reg = <0 0xa4010000 0 0x8000>;
no-map;
};
@@ -48,8 +49,8 @@
no-map;
};
- rsc_table: rsc-table@2021f000 {
- reg = <0 0x2021f000 0 0x1000>;
+ rsc_table: rsc-table@2021e000 {
+ reg = <0 0x2021e000 0 0x1000>;
no-map;
};
@@ -96,17 +97,10 @@
status = "okay";
};
-&mu1 {
- status = "okay";
-};
-
-&mu2 {
- status = "okay";
-};
-
&eqos {
- pinctrl-names = "default";
+ pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_eqos>;
+ pinctrl-1 = <&pinctrl_eqos_sleep>;
phy-mode = "rgmii-id";
phy-handle = <&ethphy1>;
status = "okay";
@@ -120,13 +114,17 @@
ethphy1: ethernet-phy@1 {
reg = <1>;
eee-broken-1000t;
+ reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
};
};
};
&fec {
- pinctrl-names = "default";
+ pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_fec>;
+ pinctrl-1 = <&pinctrl_fec_sleep>;
phy-mode = "rgmii-id";
phy-handle = <&ethphy2>;
fsl,magic-packet;
@@ -140,8 +138,191 @@
ethphy2: ethernet-phy@2 {
reg = <2>;
eee-broken-1000t;
+ reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ };
+ };
+};
+
+&lpi2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ pinctrl-1 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ pcal6524: gpio@22 {
+ compatible = "nxp,pcal6524";
+ reg = <0x22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcal6524>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmic@25 {
+ compatible = "nxp,pca9451a";
+ reg = <0x25>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+
+ regulators {
+ buck1: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <610000>;
+ regulator-max-microvolt = <950000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <670000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck4: BUCK4{
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5: BUCK5{
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6: BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <1060000>;
+ regulator-max-microvolt = <1140000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <840000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5: LDO5 {
+ regulator-name = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&lpi2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ status = "okay";
+
+ ptn5110: tcpc@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+ 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;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ typec1_dr_sw: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+ };
+ };
+ };
+
+ ptn5110_2: tcpc@51 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x51>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+ typec2_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;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ typec2_dr_sw: endpoint {
+ remote-endpoint = <&usb2_drd_sw>;
+ };
+ };
+ };
};
};
+
+ pcf2131: rtc@53 {
+ compatible = "nxp,pcf2131";
+ reg = <0x53>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ };
};
&lpuart1 { /* console */
@@ -156,26 +337,70 @@
status = "okay";
};
+&mu1 {
+ status = "okay";
+};
+
+&mu2 {
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ 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>;
+ };
+ };
+};
+
+&usbotg2 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ usb2_drd_sw: endpoint {
+ remote-endpoint = <&typec2_dr_sw>;
+ };
+ };
+};
+
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
- pinctrl-1 = <&pinctrl_usdhc1>;
- pinctrl-2 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
bus-width = <8>;
non-removable;
status = "okay";
};
&usdhc2 {
- pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
- pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
- pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>;
cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
vmmc-supply = <&reg_usdhc2_vmmc>;
bus-width = <4>;
status = "okay";
- no-sdio;
no-mmc;
};
@@ -203,6 +428,25 @@
>;
};
+ pinctrl_eqos_sleep: eqossleepgrp {
+ fsl,pins = <
+ MX93_PAD_ENET1_MDC__GPIO4_IO00 0x31e
+ MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x31e
+ MX93_PAD_ENET1_RD0__GPIO4_IO10 0x31e
+ MX93_PAD_ENET1_RD1__GPIO4_IO11 0x31e
+ MX93_PAD_ENET1_RD2__GPIO4_IO12 0x31e
+ MX93_PAD_ENET1_RD3__GPIO4_IO13 0x31e
+ MX93_PAD_ENET1_RXC__GPIO4_IO09 0x31e
+ MX93_PAD_ENET1_RX_CTL__GPIO4_IO08 0x31e
+ MX93_PAD_ENET1_TD0__GPIO4_IO05 0x31e
+ MX93_PAD_ENET1_TD1__GPIO4_IO04 0x31e
+ MX93_PAD_ENET1_TD2__GPIO4_IO03 0x31e
+ MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e
+ MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e
+ MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e
+ >;
+ };
+
pinctrl_fec: fecgrp {
fsl,pins = <
MX93_PAD_ENET2_MDC__ENET1_MDC 0x57e
@@ -222,6 +466,32 @@
>;
};
+ pinctrl_lpi2c3: lpi2c3grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e
+ MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e
+ >;
+ };
+
+ pinctrl_fec_sleep: fecsleepgrp {
+ fsl,pins = <
+ MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e
+ MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e
+ MX93_PAD_ENET2_RD0__GPIO4_IO24 0x51e
+ MX93_PAD_ENET2_RD1__GPIO4_IO25 0x51e
+ MX93_PAD_ENET2_RD2__GPIO4_IO26 0x51e
+ MX93_PAD_ENET2_RD3__GPIO4_IO27 0x51e
+ MX93_PAD_ENET2_RXC__GPIO4_IO23 0x51e
+ MX93_PAD_ENET2_RX_CTL__GPIO4_IO22 0x51e
+ MX93_PAD_ENET2_TD0__GPIO4_IO19 0x51e
+ MX93_PAD_ENET2_TD1__GPIO4_IO18 0x51e
+ MX93_PAD_ENET2_TD2__GPIO4_IO17 0x51e
+ MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e
+ MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e
+ MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX93_PAD_UART1_RXD__LPUART1_RX 0x31e
@@ -238,9 +508,63 @@
>;
};
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e
+ MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_lpi2c3: lpi2c3grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e
+ MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e
+ >;
+ };
+
+ pinctrl_pcal6524: pcal6524grp {
+ fsl,pins = <
+ MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e
+ >;
+ };
+
/* need to config the SION for data and cmd pad, refer to ERR052021 */
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <
MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe
MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe
MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe
@@ -267,9 +591,41 @@
>;
};
+ pinctrl_usdhc2_gpio_sleep: usdhc2gpiosleepgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e
+ >;
+ };
+
/* need to config the SION for data and cmd pad, refer to ERR052021 */
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe
MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe
MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe
@@ -279,4 +635,17 @@
MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
>;
};
+
+ pinctrl_usdhc2_sleep: usdhc2sleepgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e
+ MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e
+ MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e
+ MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e
+ MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e
+ MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e
+ MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e
+ >;
+ };
+
};
diff --git a/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts
new file mode 100644
index 000000000000..950dece83c24
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts
@@ -0,0 +1,492 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/usb/pd.h>
+#include "imx93.dtsi"
+
+/ {
+ model = "NXP i.MX93 9x9 Quick Start Board";
+ compatible = "fsl,imx93-9x9-qsb", "fsl,imx93";
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x10000000>;
+ linux,cma-default;
+ };
+
+ vdev0vring0: vdev0vring0@a4000000 {
+ reg = <0 0xa4000000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@a4008000 {
+ reg = <0 0xa4008000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: vdev1vring0@a4010000 {
+ reg = <0 0xa4010000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: vdev1vring1@a4018000 {
+ reg = <0 0xa4018000 0 0x8000>;
+ no-map;
+ };
+
+ rsc_table: rsc-table@2021e000 {
+ reg = <0 0x2021e000 0 0x1000>;
+ no-map;
+ };
+
+ vdevbuffer: vdevbuffer@a4020000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0xa4020000 0 0x100000>;
+ no-map;
+ };
+
+ };
+
+ reg_vref_1v8: regulator-adc-vref {
+ compatible = "regulator-fixed";
+ regulator-name = "VREF_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_rpi_3v3: regulator-rpi {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_RPI_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pcal6524 21 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ 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 = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ off-on-delay-us = <12000>;
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&cm33 {
+ mbox-names = "tx", "rx", "rxdb";
+ mboxes = <&mu1 0 1>,
+ <&mu1 1 1>,
+ <&mu1 3 1>;
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+ <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
+ status = "okay";
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <5000000>;
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ eee-broken-1000t;
+ reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ realtek,clkout-disable;
+ };
+ };
+};
+
+&lpi2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ ptn5110: tcpc@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+
+ 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;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ typec1_dr_sw: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+ };
+ };
+ };
+
+ rtc@53 {
+ compatible = "nxp,pcf2131";
+ reg = <0x53>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&lpi2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ pcal6524: gpio@22 {
+ compatible = "nxp,pcal6524";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcal6524>;
+ };
+
+ pmic@25 {
+ compatible = "nxp,pca9451a";
+ reg = <0x25>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+
+ regulators {
+ buck1: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2237500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck4: BUCK4{
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5: BUCK5{
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6: BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5: LDO5 {
+ regulator-name = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&lpuart1 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&mu1 {
+ status = "okay";
+};
+
+&mu2 {
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ 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>;
+ };
+ };
+};
+
+&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>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ 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 = <&gpio3 0 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ bus-width = <4>;
+ no-mmc;
+ status = "okay";
+};
+
+&wdog3 {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_eqos: eqosgrp {
+ fsl,pins = <
+ MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e
+ MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e
+ MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e
+ MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e
+ MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e
+ MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e
+ MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x58e
+ MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e
+ MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e
+ MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e
+ MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e
+ MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e
+ MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x58e
+ MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e
+ MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e
+ MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_pcal6524: pcal6524grp {
+ fsl,pins = <
+ MX93_PAD_CCM_CLKO1__GPIO3_IO26 0x31e
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX93_PAD_UART1_RXD__LPUART1_RX 0x31e
+ MX93_PAD_UART1_TXD__LPUART1_TX 0x31e
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e
+ MX93_PAD_DAP_TDI__LPUART5_RX 0x31e
+ MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e
+ MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts
index af795ecf678b..852dd3d2eac7 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts
@@ -303,6 +303,32 @@
reg = <0x1c>;
};
+ ptn5110: usb-typec@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+
+ connector {
+ compatible = "usb-c-connector";
+ label = "X17";
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "sink";
+ typec-power-opmode = "default";
+ pd-disable;
+ self-powered;
+
+ port {
+ typec_con_hs: endpoint {
+ remote-endpoint = <&typec_hs>;
+ };
+ };
+ };
+ };
+
eeprom2: eeprom@54 {
compatible = "nxp,se97b", "atmel,24c02";
reg = <0x54>;
@@ -371,18 +397,6 @@
"WLAN_PERST#", "12V_EN";
/*
- * Controls the on board USB Hub reset which is low
- * active as reset signal. The output-low states, the
- * signal is inactive, e.g. no reset
- */
- usb-reset-hog {
- gpio-hog;
- gpios = <2 GPIO_ACTIVE_LOW>;
- output-low;
- line-name = "USB_RESET#";
- };
-
- /*
* Controls the WiFi card PD pin which is low active
* as power down signal. The output-high states, the signal
* is active, e.g. card is powered down
@@ -492,6 +506,41 @@
status = "okay";
};
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ typec_hs: endpoint {
+ remote-endpoint = <&typec_con_hs>;
+ };
+ };
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ hub_2_0: hub@1 {
+ compatible = "usb424,2517";
+ reg = <1>;
+ reset-gpios = <&expander1 2 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&reg_3v3>;
+ };
+};
+
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2_hs>, <&pinctrl_usdhc2_gpio>;
diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
index eb3f4cfb6986..da8f19a646a9 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
@@ -252,6 +252,32 @@
reg = <0x1c>;
};
+ ptn5110: usb-typec@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+
+ connector {
+ compatible = "usb-c-connector";
+ label = "X17";
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "sink";
+ typec-power-opmode = "default";
+ pd-disable;
+ self-powered;
+
+ port {
+ typec_con_hs: endpoint {
+ remote-endpoint = <&typec_hs>;
+ };
+ };
+ };
+ };
+
eeprom2: eeprom@54 {
compatible = "nxp,se97b", "atmel,24c02";
reg = <0x54>;
@@ -433,6 +459,41 @@
pinctrl-0 = <&pinctrl_tpm5>;
};
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ typec_hs: endpoint {
+ remote-endpoint = <&typec_con_hs>;
+ };
+ };
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ hub_2_0: hub@1 {
+ compatible = "usb424,2517";
+ reg = <1>;
+ reset-gpios = <&expander1 2 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&reg_3v3>;
+ };
+};
+
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2_hs>, <&pinctrl_usdhc2_gpio>;
diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
index 9d2328c185c9..edbd8cad35bc 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
@@ -75,6 +75,12 @@
spi-max-frequency = <62000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 601c94e1fac8..4a3f42355cb8 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/imx93-clock.h>
+#include <dt-bindings/dma/fsl-edma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -183,6 +184,20 @@
status = "disabled";
};
+ usbphynop1: usbphynop1 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+ clock-names = "main_clk";
+ };
+
+ usbphynop2: usbphynop2 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+ clock-names = "main_clk";
+ };
+
soc@0 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -316,6 +331,8 @@
clocks = <&clk IMX93_CLK_LPI2C1_GATE>,
<&clk IMX93_CLK_BUS_AON>;
clock-names = "per", "ipg";
+ dmas = <&edma1 7 0 0>, <&edma1 8 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -328,6 +345,8 @@
clocks = <&clk IMX93_CLK_LPI2C2_GATE>,
<&clk IMX93_CLK_BUS_AON>;
clock-names = "per", "ipg";
+ dmas = <&edma1 9 0 0>, <&edma1 10 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -340,6 +359,8 @@
clocks = <&clk IMX93_CLK_LPSPI1_GATE>,
<&clk IMX93_CLK_BUS_AON>;
clock-names = "per", "ipg";
+ dmas = <&edma1 11 0 0>, <&edma1 12 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -352,6 +373,8 @@
clocks = <&clk IMX93_CLK_LPSPI2_GATE>,
<&clk IMX93_CLK_BUS_AON>;
clock-names = "per", "ipg";
+ dmas = <&edma1 13 0 0>, <&edma1 14 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -361,7 +384,7 @@
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART1_GATE>;
clock-names = "ipg";
- dmas = <&edma1 17 0 1>, <&edma1 16 0 0>;
+ dmas = <&edma1 17 0 FSL_EDMA_RX>, <&edma1 16 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -372,7 +395,7 @@
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART2_GATE>;
clock-names = "ipg";
- dmas = <&edma1 19 0 1>, <&edma1 18 0 0>;
+ dmas = <&edma1 19 0 FSL_EDMA_RX>, <&edma1 18 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -400,7 +423,7 @@
<&clk IMX93_CLK_SAI1_GATE>, <&clk IMX93_CLK_DUMMY>,
<&clk IMX93_CLK_DUMMY>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
- dmas = <&edma1 22 0 1>, <&edma1 21 0 0>;
+ dmas = <&edma1 22 0 FSL_EDMA_RX>, <&edma1 21 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -509,8 +532,7 @@
reg = <0x44530000 0x10000>;
interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_ADC1_GATE>;
clock-names = "ipg";
#io-channel-cells = <1>;
@@ -693,6 +715,8 @@
clocks = <&clk IMX93_CLK_LPI2C3_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 8 0 0>, <&edma2 9 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -705,6 +729,8 @@
clocks = <&clk IMX93_CLK_LPI2C4_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 10 0 0>, <&edma2 11 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -717,6 +743,8 @@
clocks = <&clk IMX93_CLK_LPSPI3_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 12 0 0>, <&edma2 13 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -729,6 +757,8 @@
clocks = <&clk IMX93_CLK_LPSPI4_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 14 0 0>, <&edma2 15 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -738,7 +768,7 @@
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART3_GATE>;
clock-names = "ipg";
- dmas = <&edma2 18 0 1>, <&edma2 17 0 0>;
+ dmas = <&edma2 18 0 FSL_EDMA_RX>, <&edma2 17 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -749,7 +779,7 @@
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART4_GATE>;
clock-names = "ipg";
- dmas = <&edma2 20 0 1>, <&edma2 19 0 0>;
+ dmas = <&edma2 20 0 FSL_EDMA_RX>, <&edma2 19 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -760,7 +790,7 @@
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART5_GATE>;
clock-names = "ipg";
- dmas = <&edma2 22 0 1>, <&edma2 21 0 0>;
+ dmas = <&edma2 22 0 FSL_EDMA_RX>, <&edma2 21 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -771,7 +801,7 @@
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART6_GATE>;
clock-names = "ipg";
- dmas = <&edma2 24 0 1>, <&edma2 23 0 0>;
+ dmas = <&edma2 24 0 FSL_EDMA_RX>, <&edma2 23 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -814,7 +844,7 @@
<&clk IMX93_CLK_SAI2_GATE>, <&clk IMX93_CLK_DUMMY>,
<&clk IMX93_CLK_DUMMY>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
- dmas = <&edma2 59 0 1>, <&edma2 58 0 0>;
+ dmas = <&edma2 59 0 FSL_EDMA_RX>, <&edma2 58 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -827,7 +857,7 @@
<&clk IMX93_CLK_SAI3_GATE>, <&clk IMX93_CLK_DUMMY>,
<&clk IMX93_CLK_DUMMY>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
- dmas = <&edma2 61 0 1>, <&edma2 60 0 0>;
+ dmas = <&edma2 61 0 FSL_EDMA_RX>, <&edma2 60 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -846,7 +876,7 @@
<&clk IMX93_CLK_DUMMY>,
<&clk IMX93_CLK_AUD_XCVR_GATE>;
clock-names = "ipg", "phy", "spba", "pll_ipg";
- dmas = <&edma2 65 0 1>, <&edma2 66 0 0>;
+ dmas = <&edma2 65 0 FSL_EDMA_RX>, <&edma2 66 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -857,7 +887,7 @@
interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART7_GATE>;
clock-names = "ipg";
- dmas = <&edma2 88 0 1>, <&edma2 87 0 0>;
+ dmas = <&edma2 88 0 FSL_EDMA_RX>, <&edma2 87 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -868,7 +898,7 @@
interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART8_GATE>;
clock-names = "ipg";
- dmas = <&edma2 90 0 1>, <&edma2 89 0 0>;
+ dmas = <&edma2 90 0 FSL_EDMA_RX>, <&edma2 89 0 0>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -882,6 +912,8 @@
clocks = <&clk IMX93_CLK_LPI2C5_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 71 0 0>, <&edma2 72 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -894,6 +926,8 @@
clocks = <&clk IMX93_CLK_LPI2C6_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 73 0 0>, <&edma2 74 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -906,6 +940,8 @@
clocks = <&clk IMX93_CLK_LPI2C7_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 75 0 0>, <&edma2 76 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -918,6 +954,8 @@
clocks = <&clk IMX93_CLK_LPI2C8_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 77 0 0>, <&edma2 78 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -930,6 +968,8 @@
clocks = <&clk IMX93_CLK_LPSPI5_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 79 0 0>, <&edma2 80 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -942,6 +982,8 @@
clocks = <&clk IMX93_CLK_LPSPI6_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 81 0 0>, <&edma2 82 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -954,6 +996,8 @@
clocks = <&clk IMX93_CLK_LPSPI7_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 83 0 0>, <&edma2 84 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -966,6 +1010,8 @@
clocks = <&clk IMX93_CLK_LPSPI8_GATE>,
<&clk IMX93_CLK_BUS_WAKEUP>;
clock-names = "per", "ipg";
+ dmas = <&edma2 85 0 0>, <&edma2 86 0 FSL_EDMA_RX>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -986,6 +1032,9 @@
<&clk IMX93_CLK_WAKEUP_AXI>,
<&clk IMX93_CLK_USDHC1_GATE>;
clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clk IMX93_CLK_USDHC1>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>;
+ assigned-clock-rates = <400000000>;
bus-width = <8>;
fsl,tuning-start-tap = <1>;
fsl,tuning-step = <2>;
@@ -1000,6 +1049,9 @@
<&clk IMX93_CLK_WAKEUP_AXI>,
<&clk IMX93_CLK_USDHC2_GATE>;
clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clk IMX93_CLK_USDHC2>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>;
+ assigned-clock-rates = <400000000>;
bus-width = <4>;
fsl,tuning-start-tap = <1>;
fsl,tuning-step = <2>;
@@ -1030,6 +1082,8 @@
fsl,num-tx-queues = <3>;
fsl,num-rx-queues = <3>;
fsl,stop-mode = <&wakeupmix_gpr 0x0c 1>;
+ nvmem-cells = <&eth_mac1>;
+ nvmem-cell-names = "mac-address";
status = "disabled";
};
@@ -1052,6 +1106,8 @@
assigned-clock-rates = <100000000>, <250000000>;
intf_mode = <&wakeupmix_gpr 0x28>;
snps,clk-csr = <0>;
+ nvmem-cells = <&eth_mac2>;
+ nvmem-cell-names = "mac-address";
status = "disabled";
};
@@ -1063,6 +1119,9 @@
<&clk IMX93_CLK_WAKEUP_AXI>,
<&clk IMX93_CLK_USDHC3_GATE>;
clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clk IMX93_CLK_USDHC3>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>;
+ assigned-clock-rates = <400000000>;
bus-width = <4>;
fsl,tuning-start-tap = <1>;
fsl,tuning-step = <2>;
@@ -1136,6 +1195,15 @@
reg = <0x47510000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
+
+ eth_mac1: mac-address@4ec {
+ reg = <0x4ec 0x6>;
+ };
+
+ eth_mac2: mac-address@4f2 {
+ reg = <0x4f2 0x6>;
+ };
+
};
s4muap: mailbox@47520000 {
@@ -1167,6 +1235,50 @@
status = "disabled";
};
+ usbotg1: usb@4c100000 {
+ compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x4c100000 0x200>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+ <&clk IMX93_CLK_HSIO_32K_GATE>;
+ clock-names = "usb_ctrl_root", "usb_wakeup";
+ assigned-clocks = <&clk IMX93_CLK_HSIO>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+ assigned-clock-rates = <133000000>;
+ phys = <&usbphynop1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ status = "disabled";
+ };
+
+ usbmisc1: usbmisc@4c100200 {
+ compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+ "fsl,imx6q-usbmisc";
+ reg = <0x4c100200 0x200>;
+ #index-cells = <1>;
+ };
+
+ usbotg2: usb@4c200000 {
+ compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x4c200000 0x200>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+ <&clk IMX93_CLK_HSIO_32K_GATE>;
+ clock-names = "usb_ctrl_root", "usb_wakeup";
+ assigned-clocks = <&clk IMX93_CLK_HSIO>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+ assigned-clock-rates = <133000000>;
+ phys = <&usbphynop2>;
+ fsl,usbmisc = <&usbmisc2 0>;
+ status = "disabled";
+ };
+
+ usbmisc2: usbmisc@4c200200 {
+ compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+ "fsl,imx6q-usbmisc";
+ reg = <0x4c200200 0x200>;
+ #index-cells = <1>;
+ };
+
ddr-pmu@4e300dc0 {
compatible = "fsl,imx93-ddr-pmu";
reg = <0x4e300dc0 0x200>;
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
new file mode 100644
index 000000000000..d14a54ab4fd4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+
+#include "imx95.dtsi"
+
+/ {
+ model = "NXP i.MX95 19X19 board";
+ compatible = "fsl,imx95-19x19-evk", "fsl,imx95";
+
+ aliases {
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ serial0 = &lpuart1;
+ };
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0 0x80000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ linux_cma: linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x80000000 0 0x7f000000>;
+ size = <0 0x3c000000>;
+ linux,cma-default;
+ reusable;
+ };
+ };
+
+ reg_m2_pwr: regulator-m2-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "M.2-power";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&i2c7_pcal6524 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_pcie0: regulator-pcie {
+ compatible = "regulator-fixed";
+ regulator-name = "PCIE_WLAN_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&reg_m2_pwr>;
+ gpio = <&i2c7_pcal6524 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_slot_pwr: regulator-slot-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "PCIe slot-power";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&i2c7_pcal6524 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ regulator-name = "VDD_SD2_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ off-on-delay-us = <12000>;
+ };
+};
+
+&lpi2c7 {
+ clock-frequency = <1000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c7>;
+ status = "okay";
+
+ i2c7_pcal6524: i2c7-gpio@22 {
+ compatible = "nxp,pcal6524";
+ reg = <0x22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c7_pcal6524>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&lpuart1 {
+ /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&mu7 {
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-0 = <&pinctrl_pcie0>;
+ pinctrl-names = "default";
+ reset-gpio = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>;
+ vpcie-supply = <&reg_pcie0>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-0 = <&pinctrl_pcie1>;
+ pinctrl-names = "default";
+ reset-gpio = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>;
+ vpcie-supply = <&reg_slot_pwr>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ pinctrl-3 = <&pinctrl_usdhc1>;
+ bus-width = <8>;
+ non-removable;
+ no-sdio;
+ no-sd;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-3 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&wdog3 {
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&scmi_iomuxc {
+ pinctrl_i2c7_pcal6524: i2c7pcal6524grp {
+ fsl,pins = <
+ IMX95_PAD_GPIO_IO36__GPIO5_IO_BIT16 0x31e
+ >;
+ };
+
+ pinctrl_lpi2c7: lpi2c7grp {
+ fsl,pins = <
+ IMX95_PAD_GPIO_IO08__LPI2C7_SDA 0x40000b9e
+ IMX95_PAD_GPIO_IO09__LPI2C7_SCL 0x40000b9e
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ IMX95_PAD_GPIO_IO32__HSIOMIX_TOP_PCIE1_CLKREQ_B 0x4000031e
+ >;
+ };
+
+ pinctrl_pcie1: pcie1grp {
+ fsl,pins = <
+ IMX95_PAD_GPIO_IO35__HSIOMIX_TOP_PCIE2_CLKREQ_B 0x4000031e
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x31e
+ IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e
+ IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e
+ IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e
+ IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e
+ IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e
+ IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e
+ IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e
+ IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e
+ IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e
+ IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e
+ IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <
+ IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e
+ IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e
+ IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e
+ IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e
+ IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e
+ IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e
+ IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e
+ IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e
+ IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e
+ IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e
+ IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <
+ IMX95_PAD_SD1_CLK__USDHC1_CLK 0x15fe
+ IMX95_PAD_SD1_CMD__USDHC1_CMD 0x13fe
+ IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe
+ IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe
+ IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe
+ IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe
+ IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe
+ IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe
+ IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe
+ IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe
+ IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ IMX95_PAD_SD2_CLK__USDHC2_CLK 0x158e
+ IMX95_PAD_SD2_CMD__USDHC2_CMD 0x138e
+ IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x138e
+ IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x138e
+ IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e
+ IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e
+ IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ IMX95_PAD_SD2_CLK__USDHC2_CLK 0x158e
+ IMX95_PAD_SD2_CMD__USDHC2_CMD 0x138e
+ IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x138e
+ IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x138e
+ IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e
+ IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e
+ IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ IMX95_PAD_SD2_CLK__USDHC2_CLK 0x15fe
+ IMX95_PAD_SD2_CMD__USDHC2_CMD 0x13fe
+ IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe
+ IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe
+ IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x13fe
+ IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x13fe
+ IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx95-clock.h b/arch/arm64/boot/dts/freescale/imx95-clock.h
new file mode 100644
index 000000000000..e1f91203e794
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-clock.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __CLOCK_IMX95_H
+#define __CLOCK_IMX95_H
+
+/* The index should match i.MX95 SCMI Firmware */
+#define IMX95_CLK_32K 1
+#define IMX95_CLK_24M 2
+#define IMX95_CLK_FRO 3
+#define IMX95_CLK_SYSPLL1_VCO 4
+#define IMX95_CLK_SYSPLL1_PFD0_UNGATED 5
+#define IMX95_CLK_SYSPLL1_PFD0 6
+#define IMX95_CLK_SYSPLL1_PFD0_DIV2 7
+#define IMX95_CLK_SYSPLL1_PFD1_UNGATED 8
+#define IMX95_CLK_SYSPLL1_PFD1 9
+#define IMX95_CLK_SYSPLL1_PFD1_DIV2 10
+#define IMX95_CLK_SYSPLL1_PFD2_UNGATED 11
+#define IMX95_CLK_SYSPLL1_PFD2 12
+#define IMX95_CLK_SYSPLL1_PFD2_DIV2 13
+#define IMX95_CLK_AUDIOPLL1_VCO 14
+#define IMX95_CLK_AUDIOPLL1 15
+#define IMX95_CLK_AUDIOPLL2_VCO 16
+#define IMX95_CLK_AUDIOPLL2 17
+#define IMX95_CLK_VIDEOPLL1_VCO 18
+#define IMX95_CLK_VIDEOPLL1 19
+#define IMX95_CLK_RESERVED20 20
+#define IMX95_CLK_RESERVED21 21
+#define IMX95_CLK_RESERVED22 22
+#define IMX95_CLK_RESERVED23 23
+#define IMX95_CLK_ARMPLL_VCO 24
+#define IMX95_CLK_ARMPLL_PFD0_UNGATED 25
+#define IMX95_CLK_ARMPLL_PFD0 26
+#define IMX95_CLK_ARMPLL_PFD1_UNGATED 27
+#define IMX95_CLK_ARMPLL_PFD1 28
+#define IMX95_CLK_ARMPLL_PFD2_UNGATED 29
+#define IMX95_CLK_ARMPLL_PFD2 30
+#define IMX95_CLK_ARMPLL_PFD3_UNGATED 31
+#define IMX95_CLK_ARMPLL_PFD3 32
+#define IMX95_CLK_DRAMPLL_VCO 33
+#define IMX95_CLK_DRAMPLL 34
+#define IMX95_CLK_HSIOPLL_VCO 35
+#define IMX95_CLK_HSIOPLL 36
+#define IMX95_CLK_LDBPLL_VCO 37
+#define IMX95_CLK_LDBPLL 38
+#define IMX95_CLK_EXT1 39
+#define IMX95_CLK_EXT2 40
+
+#define IMX95_CCM_NUM_CLK_SRC 41
+
+#define IMX95_CLK_ADC (IMX95_CCM_NUM_CLK_SRC + 0)
+#define IMX95_CLK_TMU (IMX95_CCM_NUM_CLK_SRC + 1)
+#define IMX95_CLK_BUSAON (IMX95_CCM_NUM_CLK_SRC + 2)
+#define IMX95_CLK_CAN1 (IMX95_CCM_NUM_CLK_SRC + 3)
+#define IMX95_CLK_I3C1 (IMX95_CCM_NUM_CLK_SRC + 4)
+#define IMX95_CLK_I3C1SLOW (IMX95_CCM_NUM_CLK_SRC + 5)
+#define IMX95_CLK_LPI2C1 (IMX95_CCM_NUM_CLK_SRC + 6)
+#define IMX95_CLK_LPI2C2 (IMX95_CCM_NUM_CLK_SRC + 7)
+#define IMX95_CLK_LPSPI1 (IMX95_CCM_NUM_CLK_SRC + 8)
+#define IMX95_CLK_LPSPI2 (IMX95_CCM_NUM_CLK_SRC + 9)
+#define IMX95_CLK_LPTMR1 (IMX95_CCM_NUM_CLK_SRC + 10)
+#define IMX95_CLK_LPUART1 (IMX95_CCM_NUM_CLK_SRC + 11)
+#define IMX95_CLK_LPUART2 (IMX95_CCM_NUM_CLK_SRC + 12)
+#define IMX95_CLK_M33 (IMX95_CCM_NUM_CLK_SRC + 13)
+#define IMX95_CLK_M33SYSTICK (IMX95_CCM_NUM_CLK_SRC + 14)
+#define IMX95_CLK_MQS1 (IMX95_CCM_NUM_CLK_SRC + 15)
+#define IMX95_CLK_PDM (IMX95_CCM_NUM_CLK_SRC + 16)
+#define IMX95_CLK_SAI1 (IMX95_CCM_NUM_CLK_SRC + 17)
+#define IMX95_CLK_SENTINEL (IMX95_CCM_NUM_CLK_SRC + 18)
+#define IMX95_CLK_TPM2 (IMX95_CCM_NUM_CLK_SRC + 19)
+#define IMX95_CLK_TSTMR1 (IMX95_CCM_NUM_CLK_SRC + 20)
+#define IMX95_CLK_CAMAPB (IMX95_CCM_NUM_CLK_SRC + 21)
+#define IMX95_CLK_CAMAXI (IMX95_CCM_NUM_CLK_SRC + 22)
+#define IMX95_CLK_CAMCM0 (IMX95_CCM_NUM_CLK_SRC + 23)
+#define IMX95_CLK_CAMISI (IMX95_CCM_NUM_CLK_SRC + 24)
+#define IMX95_CLK_MIPIPHYCFG (IMX95_CCM_NUM_CLK_SRC + 25)
+#define IMX95_CLK_MIPIPHYPLLBYPASS (IMX95_CCM_NUM_CLK_SRC + 26)
+#define IMX95_CLK_MIPIPHYPLLREF (IMX95_CCM_NUM_CLK_SRC + 27)
+#define IMX95_CLK_MIPITESTBYTE (IMX95_CCM_NUM_CLK_SRC + 28)
+#define IMX95_CLK_A55 (IMX95_CCM_NUM_CLK_SRC + 29)
+#define IMX95_CLK_A55MTRBUS (IMX95_CCM_NUM_CLK_SRC + 30)
+#define IMX95_CLK_A55PERIPH (IMX95_CCM_NUM_CLK_SRC + 31)
+#define IMX95_CLK_DRAMALT (IMX95_CCM_NUM_CLK_SRC + 32)
+#define IMX95_CLK_DRAMAPB (IMX95_CCM_NUM_CLK_SRC + 33)
+#define IMX95_CLK_DISPAPB (IMX95_CCM_NUM_CLK_SRC + 34)
+#define IMX95_CLK_DISPAXI (IMX95_CCM_NUM_CLK_SRC + 35)
+#define IMX95_CLK_DISPDP (IMX95_CCM_NUM_CLK_SRC + 36)
+#define IMX95_CLK_DISPOCRAM (IMX95_CCM_NUM_CLK_SRC + 37)
+#define IMX95_CLK_DISPUSB31 (IMX95_CCM_NUM_CLK_SRC + 38)
+#define IMX95_CLK_DISP1PIX (IMX95_CCM_NUM_CLK_SRC + 39)
+#define IMX95_CLK_DISP2PIX (IMX95_CCM_NUM_CLK_SRC + 40)
+#define IMX95_CLK_DISP3PIX (IMX95_CCM_NUM_CLK_SRC + 41)
+#define IMX95_CLK_GPUAPB (IMX95_CCM_NUM_CLK_SRC + 42)
+#define IMX95_CLK_GPU (IMX95_CCM_NUM_CLK_SRC + 43)
+#define IMX95_CLK_HSIOACSCAN480M (IMX95_CCM_NUM_CLK_SRC + 44)
+#define IMX95_CLK_HSIOACSCAN80M (IMX95_CCM_NUM_CLK_SRC + 45)
+#define IMX95_CLK_HSIO (IMX95_CCM_NUM_CLK_SRC + 46)
+#define IMX95_CLK_HSIOPCIEAUX (IMX95_CCM_NUM_CLK_SRC + 47)
+#define IMX95_CLK_HSIOPCIETEST160M (IMX95_CCM_NUM_CLK_SRC + 48)
+#define IMX95_CLK_HSIOPCIETEST400M (IMX95_CCM_NUM_CLK_SRC + 49)
+#define IMX95_CLK_HSIOPCIETEST500M (IMX95_CCM_NUM_CLK_SRC + 50)
+#define IMX95_CLK_HSIOUSBTEST50M (IMX95_CCM_NUM_CLK_SRC + 51)
+#define IMX95_CLK_HSIOUSBTEST60M (IMX95_CCM_NUM_CLK_SRC + 52)
+#define IMX95_CLK_BUSM7 (IMX95_CCM_NUM_CLK_SRC + 53)
+#define IMX95_CLK_M7 (IMX95_CCM_NUM_CLK_SRC + 54)
+#define IMX95_CLK_M7SYSTICK (IMX95_CCM_NUM_CLK_SRC + 55)
+#define IMX95_CLK_BUSNETCMIX (IMX95_CCM_NUM_CLK_SRC + 56)
+#define IMX95_CLK_ENET (IMX95_CCM_NUM_CLK_SRC + 57)
+#define IMX95_CLK_ENETPHYTEST200M (IMX95_CCM_NUM_CLK_SRC + 58)
+#define IMX95_CLK_ENETPHYTEST500M (IMX95_CCM_NUM_CLK_SRC + 59)
+#define IMX95_CLK_ENETPHYTEST667M (IMX95_CCM_NUM_CLK_SRC + 60)
+#define IMX95_CLK_ENETREF (IMX95_CCM_NUM_CLK_SRC + 61)
+#define IMX95_CLK_ENETTIMER1 (IMX95_CCM_NUM_CLK_SRC + 62)
+#define IMX95_CLK_MQS2 (IMX95_CCM_NUM_CLK_SRC + 63)
+#define IMX95_CLK_SAI2 (IMX95_CCM_NUM_CLK_SRC + 64)
+#define IMX95_CLK_NOCAPB (IMX95_CCM_NUM_CLK_SRC + 65)
+#define IMX95_CLK_NOC (IMX95_CCM_NUM_CLK_SRC + 66)
+#define IMX95_CLK_NPUAPB (IMX95_CCM_NUM_CLK_SRC + 67)
+#define IMX95_CLK_NPU (IMX95_CCM_NUM_CLK_SRC + 68)
+#define IMX95_CLK_CCMCKO1 (IMX95_CCM_NUM_CLK_SRC + 69)
+#define IMX95_CLK_CCMCKO2 (IMX95_CCM_NUM_CLK_SRC + 70)
+#define IMX95_CLK_CCMCKO3 (IMX95_CCM_NUM_CLK_SRC + 71)
+#define IMX95_CLK_CCMCKO4 (IMX95_CCM_NUM_CLK_SRC + 72)
+#define IMX95_CLK_VPUAPB (IMX95_CCM_NUM_CLK_SRC + 73)
+#define IMX95_CLK_VPU (IMX95_CCM_NUM_CLK_SRC + 74)
+#define IMX95_CLK_VPUDSP (IMX95_CCM_NUM_CLK_SRC + 75)
+#define IMX95_CLK_VPUJPEG (IMX95_CCM_NUM_CLK_SRC + 76)
+#define IMX95_CLK_AUDIOXCVR (IMX95_CCM_NUM_CLK_SRC + 77)
+#define IMX95_CLK_BUSWAKEUP (IMX95_CCM_NUM_CLK_SRC + 78)
+#define IMX95_CLK_CAN2 (IMX95_CCM_NUM_CLK_SRC + 79)
+#define IMX95_CLK_CAN3 (IMX95_CCM_NUM_CLK_SRC + 80)
+#define IMX95_CLK_CAN4 (IMX95_CCM_NUM_CLK_SRC + 81)
+#define IMX95_CLK_CAN5 (IMX95_CCM_NUM_CLK_SRC + 82)
+#define IMX95_CLK_FLEXIO1 (IMX95_CCM_NUM_CLK_SRC + 83)
+#define IMX95_CLK_FLEXIO2 (IMX95_CCM_NUM_CLK_SRC + 84)
+#define IMX95_CLK_FLEXSPI1 (IMX95_CCM_NUM_CLK_SRC + 85)
+#define IMX95_CLK_I3C2 (IMX95_CCM_NUM_CLK_SRC + 86)
+#define IMX95_CLK_I3C2SLOW (IMX95_CCM_NUM_CLK_SRC + 87)
+#define IMX95_CLK_LPI2C3 (IMX95_CCM_NUM_CLK_SRC + 88)
+#define IMX95_CLK_LPI2C4 (IMX95_CCM_NUM_CLK_SRC + 89)
+#define IMX95_CLK_LPI2C5 (IMX95_CCM_NUM_CLK_SRC + 90)
+#define IMX95_CLK_LPI2C6 (IMX95_CCM_NUM_CLK_SRC + 91)
+#define IMX95_CLK_LPI2C7 (IMX95_CCM_NUM_CLK_SRC + 92)
+#define IMX95_CLK_LPI2C8 (IMX95_CCM_NUM_CLK_SRC + 93)
+#define IMX95_CLK_LPSPI3 (IMX95_CCM_NUM_CLK_SRC + 94)
+#define IMX95_CLK_LPSPI4 (IMX95_CCM_NUM_CLK_SRC + 95)
+#define IMX95_CLK_LPSPI5 (IMX95_CCM_NUM_CLK_SRC + 96)
+#define IMX95_CLK_LPSPI6 (IMX95_CCM_NUM_CLK_SRC + 97)
+#define IMX95_CLK_LPSPI7 (IMX95_CCM_NUM_CLK_SRC + 98)
+#define IMX95_CLK_LPSPI8 (IMX95_CCM_NUM_CLK_SRC + 99)
+#define IMX95_CLK_LPTMR2 (IMX95_CCM_NUM_CLK_SRC + 100)
+#define IMX95_CLK_LPUART3 (IMX95_CCM_NUM_CLK_SRC + 101)
+#define IMX95_CLK_LPUART4 (IMX95_CCM_NUM_CLK_SRC + 102)
+#define IMX95_CLK_LPUART5 (IMX95_CCM_NUM_CLK_SRC + 103)
+#define IMX95_CLK_LPUART6 (IMX95_CCM_NUM_CLK_SRC + 104)
+#define IMX95_CLK_LPUART7 (IMX95_CCM_NUM_CLK_SRC + 105)
+#define IMX95_CLK_LPUART8 (IMX95_CCM_NUM_CLK_SRC + 106)
+#define IMX95_CLK_SAI3 (IMX95_CCM_NUM_CLK_SRC + 107)
+#define IMX95_CLK_SAI4 (IMX95_CCM_NUM_CLK_SRC + 108)
+#define IMX95_CLK_SAI5 (IMX95_CCM_NUM_CLK_SRC + 109)
+#define IMX95_CLK_SPDIF (IMX95_CCM_NUM_CLK_SRC + 110)
+#define IMX95_CLK_SWOTRACE (IMX95_CCM_NUM_CLK_SRC + 111)
+#define IMX95_CLK_TPM4 (IMX95_CCM_NUM_CLK_SRC + 112)
+#define IMX95_CLK_TPM5 (IMX95_CCM_NUM_CLK_SRC + 113)
+#define IMX95_CLK_TPM6 (IMX95_CCM_NUM_CLK_SRC + 114)
+#define IMX95_CLK_TSTMR2 (IMX95_CCM_NUM_CLK_SRC + 115)
+#define IMX95_CLK_USBPHYBURUNIN (IMX95_CCM_NUM_CLK_SRC + 116)
+#define IMX95_CLK_USDHC1 (IMX95_CCM_NUM_CLK_SRC + 117)
+#define IMX95_CLK_USDHC2 (IMX95_CCM_NUM_CLK_SRC + 118)
+#define IMX95_CLK_USDHC3 (IMX95_CCM_NUM_CLK_SRC + 119)
+#define IMX95_CLK_V2XPK (IMX95_CCM_NUM_CLK_SRC + 120)
+#define IMX95_CLK_WAKEUPAXI (IMX95_CCM_NUM_CLK_SRC + 121)
+#define IMX95_CLK_XSPISLVROOT (IMX95_CCM_NUM_CLK_SRC + 122)
+#define IMX95_CLK_SEL_EXT (IMX95_CCM_NUM_CLK_SRC + 123 + 0)
+#define IMX95_CLK_SEL_A55C0 (IMX95_CCM_NUM_CLK_SRC + 123 + 1)
+#define IMX95_CLK_SEL_A55C1 (IMX95_CCM_NUM_CLK_SRC + 123 + 2)
+#define IMX95_CLK_SEL_A55C2 (IMX95_CCM_NUM_CLK_SRC + 123 + 3)
+#define IMX95_CLK_SEL_A55C3 (IMX95_CCM_NUM_CLK_SRC + 123 + 4)
+#define IMX95_CLK_SEL_A55C4 (IMX95_CCM_NUM_CLK_SRC + 123 + 5)
+#define IMX95_CLK_SEL_A55C5 (IMX95_CCM_NUM_CLK_SRC + 123 + 6)
+#define IMX95_CLK_SEL_A55P (IMX95_CCM_NUM_CLK_SRC + 123 + 7)
+#define IMX95_CLK_SEL_DRAM (IMX95_CCM_NUM_CLK_SRC + 123 + 8)
+#define IMX95_CLK_SEL_TEMPSENSE (IMX95_CCM_NUM_CLK_SRC + 123 + 9)
+
+#endif /* __CLOCK_IMX95_H */
diff --git a/arch/arm64/boot/dts/freescale/imx95-pinfunc.h b/arch/arm64/boot/dts/freescale/imx95-pinfunc.h
new file mode 100644
index 000000000000..9f614eea7c86
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-pinfunc.h
@@ -0,0 +1,865 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DTS_IMX95_PINFUNC_H
+#define __DTS_IMX95_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define IMX95_PAD_DAP_TDI__JTAG_MUX_TDI 0x0000 0x0204 0x0610 0x00 0x00
+#define IMX95_PAD_DAP_TDI__NETCMIX_TOP_MQS2_LEFT 0x0000 0x0204 0x0000 0x01 0x00
+#define IMX95_PAD_DAP_TDI__NETCMIX_TOP_NETC_TMR_1588_ALARM1 0x0000 0x0204 0x0000 0x02 0x00
+#define IMX95_PAD_DAP_TDI__CAN2_TX 0x0000 0x0204 0x0000 0x03 0x00
+#define IMX95_PAD_DAP_TDI__FLEXIO2_FLEXIO_BIT30 0x0000 0x0204 0x0000 0x04 0x00
+#define IMX95_PAD_DAP_TDI__GPIO3_IO_BIT28 0x0000 0x0204 0x0000 0x05 0x00
+#define IMX95_PAD_DAP_TDI__LPUART5_RX 0x0000 0x0204 0x0570 0x06 0x00
+
+#define IMX95_PAD_DAP_TMS_SWDIO__JTAG_MUX_TMS 0x0004 0x0208 0x0614 0x00 0x00
+#define IMX95_PAD_DAP_TMS_SWDIO__CAN4_TX 0x0004 0x0208 0x0000 0x02 0x00
+#define IMX95_PAD_DAP_TMS_SWDIO__FLEXIO2_FLEXIO_BIT31 0x0004 0x0208 0x0000 0x04 0x00
+#define IMX95_PAD_DAP_TMS_SWDIO__GPIO3_IO_BIT29 0x0004 0x0208 0x0000 0x05 0x00
+#define IMX95_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x0004 0x0208 0x0000 0x06 0x00
+
+#define IMX95_PAD_DAP_TCLK_SWCLK__JTAG_MUX_TCK 0x0008 0x020C 0x060C 0x00 0x00
+#define IMX95_PAD_DAP_TCLK_SWCLK__CAN4_RX 0x0008 0x020C 0x044C 0x02 0x00
+#define IMX95_PAD_DAP_TCLK_SWCLK__FLEXIO1_FLEXIO_BIT30 0x0008 0x020C 0x0460 0x04 0x00
+#define IMX95_PAD_DAP_TCLK_SWCLK__GPIO3_IO_BIT30 0x0008 0x020C 0x0000 0x05 0x00
+#define IMX95_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x0008 0x020C 0x056C 0x06 0x00
+
+#define IMX95_PAD_DAP_TDO_TRACESWO__JTAG_MUX_TDO 0x000C 0x0210 0x0000 0x00 0x00
+#define IMX95_PAD_DAP_TDO_TRACESWO__NETCMIX_TOP_MQS2_RIGHT 0x000C 0x0210 0x0000 0x01 0x00
+#define IMX95_PAD_DAP_TDO_TRACESWO__NETCMIX_TOP_NETC_TMR_1588_ALARM 0x000C 0x0210 0x0000 0x02 0x00
+#define IMX95_PAD_DAP_TDO_TRACESWO__CAN2_RX 0x000C 0x0210 0x0444 0x03 0x00
+#define IMX95_PAD_DAP_TDO_TRACESWO__FLEXIO1_FLEXIO_BIT31 0x000C 0x0210 0x0464 0x04 0x00
+#define IMX95_PAD_DAP_TDO_TRACESWO__GPIO3_IO_BIT31 0x000C 0x0210 0x0000 0x05 0x00
+#define IMX95_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x000C 0x0210 0x0574 0x06 0x00
+
+#define IMX95_PAD_GPIO_IO00__GPIO2_IO_BIT0 0x0010 0x0214 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO00__LPI2C3_SDA 0x0010 0x0214 0x0504 0x11 0x00
+#define IMX95_PAD_GPIO_IO00__LPSPI6_PCS0 0x0010 0x0214 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO00__LPUART5_TX 0x0010 0x0214 0x0574 0x05 0x01
+#define IMX95_PAD_GPIO_IO00__LPI2C5_SDA 0x0010 0x0214 0x0514 0x16 0x00
+#define IMX95_PAD_GPIO_IO00__FLEXIO1_FLEXIO_BIT0 0x0010 0x0214 0x0468 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO01__GPIO2_IO_BIT1 0x0014 0x0218 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO01__LPI2C3_SCL 0x0014 0x0218 0x0500 0x11 0x00
+#define IMX95_PAD_GPIO_IO01__LPSPI6_SIN 0x0014 0x0218 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO01__LPUART5_RX 0x0014 0x0218 0x0570 0x05 0x01
+#define IMX95_PAD_GPIO_IO01__LPI2C5_SCL 0x0014 0x0218 0x0510 0x16 0x00
+#define IMX95_PAD_GPIO_IO01__FLEXIO1_FLEXIO_BIT1 0x0014 0x0218 0x046C 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO02__GPIO2_IO_BIT2 0x0018 0x021C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO02__LPI2C4_SDA 0x0018 0x021C 0x050C 0x11 0x00
+#define IMX95_PAD_GPIO_IO02__LPSPI6_SOUT 0x0018 0x021C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO02__LPUART5_CTS_B 0x0018 0x021C 0x056C 0x05 0x01
+#define IMX95_PAD_GPIO_IO02__LPI2C6_SDA 0x0018 0x021C 0x051C 0x16 0x00
+#define IMX95_PAD_GPIO_IO02__FLEXIO1_FLEXIO_BIT2 0x0018 0x021C 0x0470 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO03__GPIO2_IO_BIT3 0x001C 0x0220 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO03__LPI2C4_SCL 0x001C 0x0220 0x0508 0x11 0x00
+#define IMX95_PAD_GPIO_IO03__LPSPI6_SCK 0x001C 0x0220 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO03__LPUART5_RTS_B 0x001C 0x0220 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO03__LPI2C6_SCL 0x001C 0x0220 0x0518 0x16 0x00
+#define IMX95_PAD_GPIO_IO03__FLEXIO1_FLEXIO_BIT3 0x001C 0x0220 0x0474 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO04__GPIO2_IO_BIT4 0x0020 0x0224 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO04__TPM3_CH0 0x0020 0x0224 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO04__AONMIX_TOP_PDM_CLK 0x0020 0x0224 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO04__CAN4_TX 0x0020 0x0224 0x0000 0x03 0x00
+#define IMX95_PAD_GPIO_IO04__LPSPI7_PCS0 0x0020 0x0224 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO04__LPUART6_TX 0x0020 0x0224 0x0580 0x05 0x01
+#define IMX95_PAD_GPIO_IO04__LPI2C6_SDA 0x0020 0x0224 0x051C 0x16 0x01
+#define IMX95_PAD_GPIO_IO04__FLEXIO1_FLEXIO_BIT4 0x0020 0x0224 0x0478 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO05__GPIO2_IO_BIT5 0x0024 0x0228 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO05__TPM4_CH0 0x0024 0x0228 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO05__AONMIX_TOP_PDM_BIT_STREAM_BIT0 0x0024 0x0228 0x040C 0x02 0x01
+#define IMX95_PAD_GPIO_IO05__CAN4_RX 0x0024 0x0228 0x044C 0x03 0x01
+#define IMX95_PAD_GPIO_IO05__LPSPI7_SIN 0x0024 0x0228 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO05__LPUART6_RX 0x0024 0x0228 0x057C 0x05 0x01
+#define IMX95_PAD_GPIO_IO05__LPI2C6_SCL 0x0024 0x0228 0x0518 0x16 0x01
+#define IMX95_PAD_GPIO_IO05__FLEXIO1_FLEXIO_BIT5 0x0024 0x0228 0x047C 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO06__GPIO2_IO_BIT6 0x0028 0x022C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO06__TPM5_CH0 0x0028 0x022C 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO06__AONMIX_TOP_PDM_BIT_STREAM_BIT1 0x0028 0x022C 0x0410 0x02 0x01
+#define IMX95_PAD_GPIO_IO06__LPSPI7_SOUT 0x0028 0x022C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO06__LPUART6_CTS_B 0x0028 0x022C 0x0578 0x05 0x01
+#define IMX95_PAD_GPIO_IO06__LPI2C7_SDA 0x0028 0x022C 0x0524 0x16 0x00
+#define IMX95_PAD_GPIO_IO06__FLEXIO1_FLEXIO_BIT6 0x0028 0x022C 0x0480 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO07__GPIO2_IO_BIT7 0x002C 0x0230 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO07__LPSPI3_PCS1 0x002C 0x0230 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO07__LPSPI7_SCK 0x002C 0x0230 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO07__LPUART6_RTS_B 0x002C 0x0230 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO07__LPI2C7_SCL 0x002C 0x0230 0x0520 0x16 0x00
+#define IMX95_PAD_GPIO_IO07__FLEXIO1_FLEXIO_BIT7 0x002C 0x0230 0x0484 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO08__GPIO2_IO_BIT8 0x0030 0x0234 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO08__LPSPI3_PCS0 0x0030 0x0234 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO08__TPM6_CH0 0x0030 0x0234 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO08__LPUART7_TX 0x0030 0x0234 0x0588 0x05 0x01
+#define IMX95_PAD_GPIO_IO08__LPI2C7_SDA 0x0030 0x0234 0x0524 0x16 0x01
+#define IMX95_PAD_GPIO_IO08__FLEXIO1_FLEXIO_BIT8 0x0030 0x0234 0x0488 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO09__GPIO2_IO_BIT9 0x0034 0x0238 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO09__LPSPI3_SIN 0x0034 0x0238 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO09__TPM3_EXTCLK 0x0034 0x0238 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO09__LPUART7_RX 0x0034 0x0238 0x0584 0x05 0x01
+#define IMX95_PAD_GPIO_IO09__LPI2C7_SCL 0x0034 0x0238 0x0520 0x16 0x01
+#define IMX95_PAD_GPIO_IO09__FLEXIO1_FLEXIO_BIT9 0x0034 0x0238 0x048C 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO10__GPIO2_IO_BIT10 0x0038 0x023C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO10__LPSPI3_SOUT 0x0038 0x023C 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO10__TPM4_EXTCLK 0x0038 0x023C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO10__LPUART7_CTS_B 0x0038 0x023C 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO10__LPI2C8_SDA 0x0038 0x023C 0x052C 0x16 0x00
+#define IMX95_PAD_GPIO_IO10__FLEXIO1_FLEXIO_BIT10 0x0038 0x023C 0x0490 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO11__GPIO2_IO_BIT11 0x003C 0x0240 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO11__LPSPI3_SCK 0x003C 0x0240 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO11__TPM5_EXTCLK 0x003C 0x0240 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO11__LPUART7_RTS_B 0x003C 0x0240 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO11__LPI2C8_SCL 0x003C 0x0240 0x0528 0x16 0x00
+#define IMX95_PAD_GPIO_IO11__FLEXIO1_FLEXIO_BIT11 0x003C 0x0240 0x0494 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO12__GPIO2_IO_BIT12 0x0040 0x0244 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO12__TPM3_CH2 0x0040 0x0244 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO12__AONMIX_TOP_PDM_BIT_STREAM_BIT2 0x0040 0x0244 0x0414 0x02 0x00
+#define IMX95_PAD_GPIO_IO12__FLEXIO1_FLEXIO_BIT12 0x0040 0x0244 0x0498 0x03 0x00
+#define IMX95_PAD_GPIO_IO12__LPSPI8_PCS0 0x0040 0x0244 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO12__LPUART8_TX 0x0040 0x0244 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO12__LPI2C8_SDA 0x0040 0x0244 0x052C 0x16 0x01
+#define IMX95_PAD_GPIO_IO12__SAI3_RX_SYNC 0x0040 0x0244 0x0590 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO13__GPIO2_IO_BIT13 0x0044 0x0248 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO13__TPM4_CH2 0x0044 0x0248 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO13__AONMIX_TOP_PDM_BIT_STREAM_BIT3 0x0044 0x0248 0x0418 0x02 0x00
+#define IMX95_PAD_GPIO_IO13__LPSPI8_SIN 0x0044 0x0248 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO13__LPUART8_RX 0x0044 0x0248 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO13__LPI2C8_SCL 0x0044 0x0248 0x0528 0x16 0x01
+#define IMX95_PAD_GPIO_IO13__FLEXIO1_FLEXIO_BIT13 0x0044 0x0248 0x049C 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO14__GPIO2_IO_BIT14 0x0048 0x024C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO14__LPUART3_TX 0x0048 0x024C 0x055C 0x01 0x01
+#define IMX95_PAD_GPIO_IO14__LPSPI8_SOUT 0x0048 0x024C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO14__LPUART8_CTS_B 0x0048 0x024C 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO14__LPUART4_TX 0x0048 0x024C 0x0568 0x06 0x01
+#define IMX95_PAD_GPIO_IO14__FLEXIO1_FLEXIO_BIT14 0x0048 0x024C 0x04A0 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO15__GPIO2_IO_BIT15 0x004C 0x0250 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO15__LPUART3_RX 0x004C 0x0250 0x0558 0x01 0x01
+#define IMX95_PAD_GPIO_IO15__LPSPI8_SCK 0x004C 0x0250 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO15__LPUART8_RTS_B 0x004C 0x0250 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO15__LPUART4_RX 0x004C 0x0250 0x0564 0x06 0x01
+#define IMX95_PAD_GPIO_IO15__FLEXIO1_FLEXIO_BIT15 0x004C 0x0250 0x04A4 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO16__GPIO2_IO_BIT16 0x0050 0x0254 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO16__SAI3_TX_BCLK 0x0050 0x0254 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO16__AONMIX_TOP_PDM_BIT_STREAM_BIT2 0x0050 0x0254 0x0414 0x02 0x01
+#define IMX95_PAD_GPIO_IO16__LPUART3_CTS_B 0x0050 0x0254 0x0554 0x04 0x01
+#define IMX95_PAD_GPIO_IO16__LPSPI4_PCS2 0x0050 0x0254 0x0538 0x05 0x01
+#define IMX95_PAD_GPIO_IO16__LPUART4_CTS_B 0x0050 0x0254 0x0560 0x06 0x01
+#define IMX95_PAD_GPIO_IO16__FLEXIO1_FLEXIO_BIT16 0x0050 0x0254 0x04A8 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO17__GPIO2_IO_BIT17 0x0054 0x0258 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO17__SAI3_MCLK 0x0054 0x0258 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO17__LPUART3_RTS_B 0x0054 0x0258 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO17__LPSPI4_PCS1 0x0054 0x0258 0x0534 0x05 0x01
+#define IMX95_PAD_GPIO_IO17__LPUART4_RTS_B 0x0054 0x0258 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO17__FLEXIO1_FLEXIO_BIT17 0x0054 0x0258 0x04AC 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO18__GPIO2_IO_BIT18 0x0058 0x025C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO18__SAI3_RX_BCLK 0x0058 0x025C 0x058C 0x01 0x00
+#define IMX95_PAD_GPIO_IO18__LPSPI5_PCS0 0x0058 0x025C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO18__LPSPI4_PCS0 0x0058 0x025C 0x0530 0x05 0x01
+#define IMX95_PAD_GPIO_IO18__TPM5_CH2 0x0058 0x025C 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO18__FLEXIO1_FLEXIO_BIT18 0x0058 0x025C 0x04B0 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO19__GPIO2_IO_BIT19 0x005C 0x0260 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO19__SAI3_RX_SYNC 0x005C 0x0260 0x0590 0x01 0x01
+#define IMX95_PAD_GPIO_IO19__AONMIX_TOP_PDM_BIT_STREAM_BIT3 0x005C 0x0260 0x0418 0x02 0x01
+#define IMX95_PAD_GPIO_IO19__FLEXIO1_FLEXIO_BIT19 0x005C 0x0260 0x04B4 0x03 0x00
+#define IMX95_PAD_GPIO_IO19__LPSPI5_SIN 0x005C 0x0260 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO19__LPSPI4_SIN 0x005C 0x0260 0x0540 0x05 0x01
+#define IMX95_PAD_GPIO_IO19__TPM6_CH2 0x005C 0x0260 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO19__SAI3_TX_DATA_BIT0 0x005C 0x0260 0x0000 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO20__GPIO2_IO_BIT20 0x0060 0x0264 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO20__SAI3_RX_DATA_BIT0 0x0060 0x0264 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO20__AONMIX_TOP_PDM_BIT_STREAM_BIT0 0x0060 0x0264 0x040C 0x02 0x02
+#define IMX95_PAD_GPIO_IO20__LPSPI5_SOUT 0x0060 0x0264 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO20__LPSPI4_SOUT 0x0060 0x0264 0x0544 0x05 0x01
+#define IMX95_PAD_GPIO_IO20__TPM3_CH1 0x0060 0x0264 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO20__FLEXIO1_FLEXIO_BIT20 0x0060 0x0264 0x04B8 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO21__GPIO2_IO_BIT21 0x0064 0x0268 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO21__SAI3_TX_DATA_BIT0 0x0064 0x0268 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO21__AONMIX_TOP_PDM_CLK 0x0064 0x0268 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO21__FLEXIO1_FLEXIO_BIT21 0x0064 0x0268 0x04BC 0x03 0x00
+#define IMX95_PAD_GPIO_IO21__LPSPI5_SCK 0x0064 0x0268 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO21__LPSPI4_SCK 0x0064 0x0268 0x053C 0x05 0x01
+#define IMX95_PAD_GPIO_IO21__TPM4_CH1 0x0064 0x0268 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO21__SAI3_RX_BCLK 0x0064 0x0268 0x058C 0x07 0x01
+
+#define IMX95_PAD_GPIO_IO22__GPIO2_IO_BIT22 0x0068 0x026C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO22__USDHC3_CLK 0x0068 0x026C 0x05C8 0x01 0x00
+#define IMX95_PAD_GPIO_IO22__SPDIF_IN 0x0068 0x026C 0x0454 0x02 0x02
+#define IMX95_PAD_GPIO_IO22__CAN5_TX 0x0068 0x026C 0x0000 0x03 0x00
+#define IMX95_PAD_GPIO_IO22__TPM5_CH1 0x0068 0x026C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO22__TPM6_EXTCLK 0x0068 0x026C 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO22__LPI2C5_SDA 0x0068 0x026C 0x0514 0x16 0x01
+#define IMX95_PAD_GPIO_IO22__FLEXIO1_FLEXIO_BIT22 0x0068 0x026C 0x04C0 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO23__GPIO2_IO_BIT23 0x006C 0x0270 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO23__USDHC3_CMD 0x006C 0x0270 0x05CC 0x01 0x00
+#define IMX95_PAD_GPIO_IO23__SPDIF_OUT 0x006C 0x0270 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO23__CAN5_RX 0x006C 0x0270 0x0450 0x03 0x00
+#define IMX95_PAD_GPIO_IO23__TPM6_CH1 0x006C 0x0270 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO23__LPI2C5_SCL 0x006C 0x0270 0x0510 0x16 0x01
+#define IMX95_PAD_GPIO_IO23__FLEXIO1_FLEXIO_BIT23 0x006C 0x0270 0x04C4 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO24__GPIO2_IO_BIT24 0x0070 0x0274 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO24__USDHC3_DATA0 0x0070 0x0274 0x05D0 0x01 0x00
+#define IMX95_PAD_GPIO_IO24__TPM3_CH3 0x0070 0x0274 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO24__JTAG_MUX_TDO 0x0070 0x0274 0x0000 0x05 0x00
+#define IMX95_PAD_GPIO_IO24__LPSPI6_PCS1 0x0070 0x0274 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO24__FLEXIO1_FLEXIO_BIT24 0x0070 0x0274 0x04C8 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO25__GPIO2_IO_BIT25 0x0074 0x0278 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO25__USDHC3_DATA1 0x0074 0x0278 0x05D4 0x01 0x00
+#define IMX95_PAD_GPIO_IO25__CAN2_TX 0x0074 0x0278 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO25__TPM4_CH3 0x0074 0x0278 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO25__JTAG_MUX_TCK 0x0074 0x0278 0x060C 0x05 0x01
+#define IMX95_PAD_GPIO_IO25__LPSPI7_PCS1 0x0074 0x0278 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO25__FLEXIO1_FLEXIO_BIT25 0x0074 0x0278 0x04CC 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO26__GPIO2_IO_BIT26 0x0078 0x027C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO26__USDHC3_DATA2 0x0078 0x027C 0x05D8 0x01 0x00
+#define IMX95_PAD_GPIO_IO26__AONMIX_TOP_PDM_BIT_STREAM_BIT1 0x0078 0x027C 0x0410 0x02 0x02
+#define IMX95_PAD_GPIO_IO26__FLEXIO1_FLEXIO_BIT26 0x0078 0x027C 0x0458 0x03 0x01
+#define IMX95_PAD_GPIO_IO26__TPM5_CH3 0x0078 0x027C 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO26__JTAG_MUX_TDI 0x0078 0x027C 0x0610 0x05 0x01
+#define IMX95_PAD_GPIO_IO26__LPSPI8_PCS1 0x0078 0x027C 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO26__SAI3_TX_SYNC 0x0078 0x027C 0x0000 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO27__GPIO2_IO_BIT27 0x007C 0x0280 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO27__USDHC3_DATA3 0x007C 0x0280 0x05DC 0x01 0x00
+#define IMX95_PAD_GPIO_IO27__CAN2_RX 0x007C 0x0280 0x0444 0x02 0x02
+#define IMX95_PAD_GPIO_IO27__TPM6_CH3 0x007C 0x0280 0x0000 0x04 0x00
+#define IMX95_PAD_GPIO_IO27__JTAG_MUX_TMS 0x007C 0x0280 0x0614 0x05 0x01
+#define IMX95_PAD_GPIO_IO27__LPSPI5_PCS1 0x007C 0x0280 0x0000 0x06 0x00
+#define IMX95_PAD_GPIO_IO27__FLEXIO1_FLEXIO_BIT27 0x007C 0x0280 0x045C 0x07 0x01
+
+#define IMX95_PAD_GPIO_IO28__GPIO2_IO_BIT28 0x0080 0x0284 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO28__LPI2C3_SDA 0x0080 0x0284 0x0504 0x11 0x01
+#define IMX95_PAD_GPIO_IO28__CAN3_TX 0x0080 0x0284 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO28__FLEXIO1_FLEXIO_BIT28 0x0080 0x0284 0x0000 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO29__GPIO2_IO_BIT29 0x0084 0x0288 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO29__LPI2C3_SCL 0x0084 0x0288 0x0500 0x11 0x01
+#define IMX95_PAD_GPIO_IO29__CAN3_RX 0x0084 0x0288 0x0448 0x02 0x01
+#define IMX95_PAD_GPIO_IO29__FLEXIO1_FLEXIO_BIT29 0x0084 0x0288 0x0000 0x07 0x00
+
+#define IMX95_PAD_GPIO_IO30__GPIO2_IO_BIT30 0x0088 0x028C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO30__LPI2C4_SDA 0x0088 0x028C 0x050C 0x11 0x01
+#define IMX95_PAD_GPIO_IO30__CAN5_TX 0x0088 0x028C 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO30__FLEXIO1_FLEXIO_BIT30 0x0088 0x028C 0x0460 0x07 0x01
+
+#define IMX95_PAD_GPIO_IO31__GPIO2_IO_BIT31 0x008C 0x0290 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO31__LPI2C4_SCL 0x008C 0x0290 0x0508 0x11 0x01
+#define IMX95_PAD_GPIO_IO31__CAN5_RX 0x008C 0x0290 0x0450 0x02 0x01
+#define IMX95_PAD_GPIO_IO31__FLEXIO1_FLEXIO_BIT31 0x008C 0x0290 0x0464 0x07 0x01
+
+#define IMX95_PAD_GPIO_IO32__GPIO5_IO_BIT12 0x0090 0x0294 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO32__HSIOMIX_TOP_PCIE1_CLKREQ_B 0x0090 0x0294 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO32__LPUART6_TX 0x0090 0x0294 0x0580 0x02 0x00
+#define IMX95_PAD_GPIO_IO32__LPSPI4_PCS2 0x0090 0x0294 0x0538 0x04 0x00
+
+#define IMX95_PAD_GPIO_IO33__GPIO5_IO_BIT13 0x0094 0x0298 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO33__LPUART6_RX 0x0094 0x0298 0x057C 0x02 0x00
+#define IMX95_PAD_GPIO_IO33__LPSPI4_PCS1 0x0094 0x0298 0x0534 0x04 0x00
+
+#define IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14 0x0098 0x029C 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO34__LPUART6_CTS_B 0x0098 0x029C 0x0578 0x02 0x00
+#define IMX95_PAD_GPIO_IO34__LPSPI4_PCS0 0x0098 0x029C 0x0530 0x04 0x00
+
+#define IMX95_PAD_GPIO_IO35__GPIO5_IO_BIT15 0x009C 0x02A0 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO35__HSIOMIX_TOP_PCIE2_CLKREQ_B 0x009C 0x02A0 0x0000 0x01 0x00
+#define IMX95_PAD_GPIO_IO35__LPUART6_RTS_B 0x009C 0x02A0 0x0000 0x02 0x00
+#define IMX95_PAD_GPIO_IO35__LPSPI4_SIN 0x009C 0x02A0 0x0540 0x04 0x00
+
+#define IMX95_PAD_GPIO_IO36__LPSPI4_SOUT 0x00A0 0x02A4 0x0544 0x04 0x00
+#define IMX95_PAD_GPIO_IO36__GPIO5_IO_BIT16 0x00A0 0x02A4 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO36__LPUART7_TX 0x00A0 0x02A4 0x0588 0x02 0x00
+
+#define IMX95_PAD_GPIO_IO37__GPIO5_IO_BIT17 0x00A4 0x02A8 0x0000 0x00 0x00
+#define IMX95_PAD_GPIO_IO37__LPUART7_RX 0x00A4 0x02A8 0x0584 0x02 0x00
+#define IMX95_PAD_GPIO_IO37__LPSPI4_SCK 0x00A4 0x02A8 0x053C 0x04 0x00
+
+#define IMX95_PAD_CCM_CLKO1__CCMSRCGPCMIX_TOP_CLKO_1 0x00A8 0x02AC 0x0000 0x00 0x00
+#define IMX95_PAD_CCM_CLKO1__NETCMIX_TOP_NETC_TMR_1588_TRIG1 0x00A8 0x02AC 0x0434 0x01 0x00
+#define IMX95_PAD_CCM_CLKO1__FLEXIO1_FLEXIO_BIT26 0x00A8 0x02AC 0x0458 0x04 0x00
+#define IMX95_PAD_CCM_CLKO1__GPIO3_IO_BIT26 0x00A8 0x02AC 0x0000 0x05 0x00
+
+#define IMX95_PAD_CCM_CLKO2__GPIO3_IO_BIT27 0x00AC 0x02B0 0x0000 0x05 0x00
+#define IMX95_PAD_CCM_CLKO2__CCMSRCGPCMIX_TOP_CLKO_2 0x00AC 0x02B0 0x0000 0x00 0x00
+#define IMX95_PAD_CCM_CLKO2__NETCMIX_TOP_NETC_TMR_1588_PP1 0x00AC 0x02B0 0x0000 0x01 0x00
+#define IMX95_PAD_CCM_CLKO2__FLEXIO1_FLEXIO_BIT27 0x00AC 0x02B0 0x045C 0x04 0x00
+
+#define IMX95_PAD_CCM_CLKO3__CCMSRCGPCMIX_TOP_CLKO_3 0x00B0 0x02B4 0x0000 0x00 0x00
+#define IMX95_PAD_CCM_CLKO3__NETCMIX_TOP_NETC_TMR_1588_TRIG2 0x00B0 0x02B4 0x0438 0x01 0x00
+#define IMX95_PAD_CCM_CLKO3__CAN3_TX 0x00B0 0x02B4 0x0000 0x02 0x00
+#define IMX95_PAD_CCM_CLKO3__FLEXIO2_FLEXIO_BIT28 0x00B0 0x02B4 0x0000 0x04 0x00
+#define IMX95_PAD_CCM_CLKO3__GPIO4_IO_BIT28 0x00B0 0x02B4 0x0000 0x05 0x00
+
+#define IMX95_PAD_CCM_CLKO4__CCMSRCGPCMIX_TOP_CLKO_4 0x00B4 0x02B8 0x0000 0x00 0x00
+#define IMX95_PAD_CCM_CLKO4__NETCMIX_TOP_NETC_TMR_1588_PP2 0x00B4 0x02B8 0x0000 0x01 0x00
+#define IMX95_PAD_CCM_CLKO4__CAN3_RX 0x00B4 0x02B8 0x0448 0x02 0x00
+#define IMX95_PAD_CCM_CLKO4__FLEXIO2_FLEXIO_BIT29 0x00B4 0x02B8 0x0000 0x04 0x00
+#define IMX95_PAD_CCM_CLKO4__GPIO4_IO_BIT29 0x00B4 0x02B8 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC 0x00B8 0x02BC 0x0424 0x00 0x00
+#define IMX95_PAD_ENET1_MDC__LPUART3_DCD_B 0x00B8 0x02BC 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_MDC__I3C2_SCL 0x00B8 0x02BC 0x04F8 0x02 0x00
+#define IMX95_PAD_ENET1_MDC__HSIOMIX_TOP_USB1_OTG_ID 0x00B8 0x02BC 0x0000 0x03 0x00
+#define IMX95_PAD_ENET1_MDC__FLEXIO2_FLEXIO_BIT0 0x00B8 0x02BC 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_MDC__GPIO4_IO_BIT0 0x00B8 0x02BC 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO 0x00BC 0x02C0 0x0428 0x00 0x00
+#define IMX95_PAD_ENET1_MDIO__LPUART3_RIN_B 0x00BC 0x02C0 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_MDIO__I3C2_SDA 0x00BC 0x02C0 0x04FC 0x02 0x00
+#define IMX95_PAD_ENET1_MDIO__HSIOMIX_TOP_USB1_OTG_PWR 0x00BC 0x02C0 0x0000 0x03 0x00
+#define IMX95_PAD_ENET1_MDIO__FLEXIO2_FLEXIO_BIT1 0x00BC 0x02C0 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_MDIO__GPIO4_IO_BIT1 0x00BC 0x02C0 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x00C0 0x02C4 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_TD3__CAN2_TX 0x00C0 0x02C4 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_TD3__HSIOMIX_TOP_USB2_OTG_ID 0x00C0 0x02C4 0x0000 0x03 0x00
+#define IMX95_PAD_ENET1_TD3__FLEXIO2_FLEXIO_BIT2 0x00C0 0x02C4 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_TD3__GPIO4_IO_BIT2 0x00C0 0x02C4 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x00C4 0x02C8 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RMII_REF50_CLK 0x00C4 0x02C8 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_TD2__CAN2_RX 0x00C4 0x02C8 0x0444 0x02 0x01
+#define IMX95_PAD_ENET1_TD2__HSIOMIX_TOP_USB2_OTG_OC 0x00C4 0x02C8 0x0000 0x03 0x00
+#define IMX95_PAD_ENET1_TD2__FLEXIO2_FLEXIO_BIT3 0x00C4 0x02C8 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_TD2__GPIO4_IO_BIT3 0x00C4 0x02C8 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x00C8 0x02CC 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_TD1__LPUART3_RTS_B 0x00C8 0x02CC 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_TD1__I3C2_PUR 0x00C8 0x02CC 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_TD1__HSIOMIX_TOP_USB1_OTG_OC 0x00C8 0x02CC 0x0000 0x03 0x00
+#define IMX95_PAD_ENET1_TD1__FLEXIO2_FLEXIO_BIT4 0x00C8 0x02CC 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_TD1__GPIO4_IO_BIT4 0x00C8 0x02CC 0x0000 0x05 0x00
+#define IMX95_PAD_ENET1_TD1__I3C2_PUR_B 0x00C8 0x02CC 0x0000 0x06 0x00
+#define IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RMII_TXD1 0x00C8 0x02CC 0x0000 0x07 0x00
+
+#define IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x00CC 0x02D0 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_TD0__LPUART3_TX 0x00CC 0x02D0 0x055C 0x01 0x00
+#define IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RMII_TXD0 0x00CC 0x02D0 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_TD0__FLEXIO2_FLEXIO_BIT5 0x00CC 0x02D0 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_TD0__GPIO4_IO_BIT5 0x00CC 0x02D0 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x00D0 0x02D4 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_TX_CTL__LPUART3_DTR_B 0x00D0 0x02D4 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RMII_TX_EN 0x00D0 0x02D4 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_TX_CTL__FLEXIO2_FLEXIO_BIT6 0x00D0 0x02D4 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_TX_CTL__GPIO4_IO_BIT6 0x00D0 0x02D4 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x00D4 0x02D8 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_TXC__CCMSRCGPCMIX_TOP_ENET_CLK_ROOT 0x00D4 0x02D8 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_TXC__FLEXIO2_FLEXIO_BIT7 0x00D4 0x02D8 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_TXC__GPIO4_IO_BIT7 0x00D4 0x02D8 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x00D8 0x02DC 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_RX_CTL__LPUART3_DSR_B 0x00D8 0x02DC 0x0000 0x01 0x00
+#define IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RMII_CRS_DV 0x00D8 0x02DC 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_RX_CTL__HSIOMIX_TOP_USB2_OTG_PWR 0x00D8 0x02DC 0x0000 0x03 0x00
+#define IMX95_PAD_ENET1_RX_CTL__FLEXIO2_FLEXIO_BIT8 0x00D8 0x02DC 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_RX_CTL__GPIO4_IO_BIT8 0x00D8 0x02DC 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK 0x00DC 0x02E0 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RMII_RX_ER 0x00DC 0x02E0 0x042C 0x01 0x00
+#define IMX95_PAD_ENET1_RXC__FLEXIO2_FLEXIO_BIT9 0x00DC 0x02E0 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_RXC__GPIO4_IO_BIT9 0x00DC 0x02E0 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0 0x00E0 0x02E4 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_RD0__LPUART3_RX 0x00E0 0x02E4 0x0558 0x01 0x00
+#define IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RMII_RXD0 0x00E0 0x02E4 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_RD0__FLEXIO2_FLEXIO_BIT10 0x00E0 0x02E4 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_RD0__GPIO4_IO_BIT10 0x00E0 0x02E4 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1 0x00E4 0x02E8 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_RD1__LPUART3_CTS_B 0x00E4 0x02E8 0x0554 0x01 0x00
+#define IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RMII_RXD1 0x00E4 0x02E8 0x0000 0x02 0x00
+#define IMX95_PAD_ENET1_RD1__LPTMR2_ALT1 0x00E4 0x02E8 0x0548 0x03 0x00
+#define IMX95_PAD_ENET1_RD1__FLEXIO2_FLEXIO_BIT11 0x00E4 0x02E8 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_RD1__GPIO4_IO_BIT11 0x00E4 0x02E8 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2 0x00E8 0x02EC 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RMII_RX_ER 0x00E8 0x02EC 0x042C 0x02 0x01
+#define IMX95_PAD_ENET1_RD2__LPTMR2_ALT2 0x00E8 0x02EC 0x054C 0x03 0x00
+#define IMX95_PAD_ENET1_RD2__FLEXIO2_FLEXIO_BIT12 0x00E8 0x02EC 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_RD2__GPIO4_IO_BIT12 0x00E8 0x02EC 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3 0x00EC 0x02F0 0x0000 0x00 0x00
+#define IMX95_PAD_ENET1_RD3__LPTMR2_ALT3 0x00EC 0x02F0 0x0550 0x03 0x00
+#define IMX95_PAD_ENET1_RD3__FLEXIO2_FLEXIO_BIT13 0x00EC 0x02F0 0x0000 0x04 0x00
+#define IMX95_PAD_ENET1_RD3__GPIO4_IO_BIT13 0x00EC 0x02F0 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC 0x00F0 0x02F4 0x0424 0x00 0x01
+#define IMX95_PAD_ENET2_MDC__LPUART4_DCD_B 0x00F0 0x02F4 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_MDC__NETCMIX_TOP_SAI2_RX_SYNC 0x00F0 0x02F4 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_MDC__FLEXIO2_FLEXIO_BIT14 0x00F0 0x02F4 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_MDC__GPIO4_IO_BIT14 0x00F0 0x02F4 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO 0x00F4 0x02F8 0x0428 0x00 0x01
+#define IMX95_PAD_ENET2_MDIO__LPUART4_RIN_B 0x00F4 0x02F8 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_SAI2_RX_BCLK 0x00F4 0x02F8 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_MDIO__FLEXIO2_FLEXIO_BIT15 0x00F4 0x02F8 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_MDIO__GPIO4_IO_BIT15 0x00F4 0x02F8 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_TD3__NETCMIX_TOP_SAI2_RX_DATA_BIT0 0x00F8 0x02FC 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_TD3__FLEXIO2_FLEXIO_BIT16 0x00F8 0x02FC 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_TD3__GPIO4_IO_BIT16 0x00F8 0x02FC 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3 0x00F8 0x02FC 0x0000 0x00 0x00
+
+#define IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2 0x00FC 0x0300 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RMII_REF50_CLK 0x00FC 0x0300 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_TD2__NETCMIX_TOP_SAI2_RX_DATA_BIT1 0x00FC 0x0300 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_TD2__SAI4_TX_SYNC 0x00FC 0x0300 0x05A4 0x03 0x00
+#define IMX95_PAD_ENET2_TD2__FLEXIO2_FLEXIO_BIT17 0x00FC 0x0300 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_TD2__GPIO4_IO_BIT17 0x00FC 0x0300 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1 0x0100 0x0304 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_TD1__LPUART4_RTS_B 0x0100 0x0304 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_TD1__NETCMIX_TOP_SAI2_RX_DATA_BIT2 0x0100 0x0304 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_TD1__SAI4_TX_BCLK 0x0100 0x0304 0x05A0 0x03 0x00
+#define IMX95_PAD_ENET2_TD1__FLEXIO2_FLEXIO_BIT18 0x0100 0x0304 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_TD1__GPIO4_IO_BIT18 0x0100 0x0304 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RMII_TXD1 0x0100 0x0304 0x0000 0x06 0x00
+
+#define IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0 0x0104 0x0308 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_TD0__LPUART4_TX 0x0104 0x0308 0x0568 0x01 0x00
+#define IMX95_PAD_ENET2_TD0__NETCMIX_TOP_SAI2_RX_DATA_BIT3 0x0104 0x0308 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_TD0__SAI4_TX_DATA_BIT0 0x0104 0x0308 0x0000 0x03 0x00
+#define IMX95_PAD_ENET2_TD0__FLEXIO2_FLEXIO_BIT19 0x0104 0x0308 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_TD0__GPIO4_IO_BIT19 0x0104 0x0308 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RMII_TXD0 0x0104 0x0308 0x0000 0x06 0x00
+
+#define IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RGMII_TX_CTL 0x0108 0x030C 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_TX_CTL__LPUART4_DTR_B 0x0108 0x030C 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_SAI2_TX_SYNC 0x0108 0x030C 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RMII_TX_EN 0x0108 0x030C 0x0000 0x03 0x00
+#define IMX95_PAD_ENET2_TX_CTL__FLEXIO2_FLEXIO_BIT20 0x0108 0x030C 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_TX_CTL__GPIO4_IO_BIT20 0x0108 0x030C 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_TXC__NETCMIX_TOP_ETH1_RGMII_TX_CLK 0x010C 0x0310 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_TXC__CCMSRCGPCMIX_TOP_ENET_CLK_ROOT 0x010C 0x0310 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_TXC__NETCMIX_TOP_SAI2_TX_BCLK 0x010C 0x0310 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_TXC__FLEXIO2_FLEXIO_BIT21 0x010C 0x0310 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_TXC__GPIO4_IO_BIT21 0x010C 0x0310 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RGMII_RX_CTL 0x0110 0x0314 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_RX_CTL__LPUART4_DSR_B 0x0110 0x0314 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_SAI2_TX_DATA_BIT0 0x0110 0x0314 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_RX_CTL__FLEXIO2_FLEXIO_BIT22 0x0110 0x0314 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_RX_CTL__GPIO4_IO_BIT22 0x0110 0x0314 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RMII_CRS_DV 0x0110 0x0314 0x0000 0x06 0x00
+
+#define IMX95_PAD_ENET2_RXC__NETCMIX_TOP_ETH1_RGMII_RX_CLK 0x0114 0x0318 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_RXC__NETCMIX_TOP_ETH1_RMII_RX_ER 0x0114 0x0318 0x0430 0x01 0x00
+#define IMX95_PAD_ENET2_RXC__NETCMIX_TOP_SAI2_TX_DATA_BIT1 0x0114 0x0318 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_RXC__SAI4_RX_SYNC 0x0114 0x0318 0x059C 0x03 0x00
+#define IMX95_PAD_ENET2_RXC__FLEXIO2_FLEXIO_BIT23 0x0114 0x0318 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_RXC__GPIO4_IO_BIT23 0x0114 0x0318 0x0000 0x05 0x00
+
+#define IMX95_PAD_ENET2_RD0__NETCMIX_TOP_ETH1_RGMII_RD0 0x0118 0x031C 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_RD0__LPUART4_RX 0x0118 0x031C 0x0564 0x01 0x00
+#define IMX95_PAD_ENET2_RD0__NETCMIX_TOP_SAI2_TX_DATA_BIT2 0x0118 0x031C 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_RD0__SAI4_RX_BCLK 0x0118 0x031C 0x0594 0x03 0x00
+#define IMX95_PAD_ENET2_RD0__FLEXIO2_FLEXIO_BIT24 0x0118 0x031C 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_RD0__GPIO4_IO_BIT24 0x0118 0x031C 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_RD0__NETCMIX_TOP_ETH1_RMII_RXD0 0x0118 0x031C 0x0000 0x06 0x00
+
+#define IMX95_PAD_ENET2_RD1__NETCMIX_TOP_ETH1_RGMII_RD1 0x011C 0x0320 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_RD1__SPDIF_IN 0x011C 0x0320 0x0454 0x01 0x00
+#define IMX95_PAD_ENET2_RD1__NETCMIX_TOP_SAI2_TX_DATA_BIT3 0x011C 0x0320 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_RD1__SAI4_RX_DATA_BIT0 0x011C 0x0320 0x0598 0x03 0x00
+#define IMX95_PAD_ENET2_RD1__FLEXIO2_FLEXIO_BIT25 0x011C 0x0320 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_RD1__GPIO4_IO_BIT25 0x011C 0x0320 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_RD1__NETCMIX_TOP_ETH1_RMII_RXD1 0x011C 0x0320 0x0000 0x06 0x00
+
+#define IMX95_PAD_ENET2_RD2__NETCMIX_TOP_ETH1_RGMII_RD2 0x0120 0x0324 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_RD2__LPUART4_CTS_B 0x0120 0x0324 0x0560 0x01 0x00
+#define IMX95_PAD_ENET2_RD2__NETCMIX_TOP_SAI2_MCLK 0x0120 0x0324 0x0000 0x02 0x00
+#define IMX95_PAD_ENET2_RD2__NETCMIX_TOP_MQS2_RIGHT 0x0120 0x0324 0x0000 0x03 0x00
+#define IMX95_PAD_ENET2_RD2__FLEXIO2_FLEXIO_BIT26 0x0120 0x0324 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_RD2__GPIO4_IO_BIT26 0x0120 0x0324 0x0000 0x05 0x00
+#define IMX95_PAD_ENET2_RD2__NETCMIX_TOP_ETH1_RMII_RX_ER 0x0120 0x0324 0x0430 0x06 0x01
+
+#define IMX95_PAD_ENET2_RD3__NETCMIX_TOP_ETH1_RGMII_RD3 0x0124 0x0328 0x0000 0x00 0x00
+#define IMX95_PAD_ENET2_RD3__SPDIF_OUT 0x0124 0x0328 0x0000 0x01 0x00
+#define IMX95_PAD_ENET2_RD3__SPDIF_IN 0x0124 0x0328 0x0454 0x02 0x01
+#define IMX95_PAD_ENET2_RD3__NETCMIX_TOP_MQS2_LEFT 0x0124 0x0328 0x0000 0x03 0x00
+#define IMX95_PAD_ENET2_RD3__FLEXIO2_FLEXIO_BIT27 0x0124 0x0328 0x0000 0x04 0x00
+#define IMX95_PAD_ENET2_RD3__GPIO4_IO_BIT27 0x0124 0x0328 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD1_CLK__FLEXIO1_FLEXIO_BIT8 0x0128 0x032C 0x0488 0x04 0x01
+#define IMX95_PAD_SD1_CLK__GPIO3_IO_BIT8 0x0128 0x032C 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_CLK__USDHC1_CLK 0x0128 0x032C 0x0000 0x00 0x00
+
+#define IMX95_PAD_SD1_CMD__USDHC1_CMD 0x012C 0x0330 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_CMD__FLEXIO1_FLEXIO_BIT9 0x012C 0x0330 0x048C 0x04 0x01
+#define IMX95_PAD_SD1_CMD__GPIO3_IO_BIT9 0x012C 0x0330 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x0130 0x0334 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA0__FLEXIO1_FLEXIO_BIT10 0x0130 0x0334 0x0490 0x04 0x01
+#define IMX95_PAD_SD1_DATA0__GPIO3_IO_BIT10 0x0130 0x0334 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x0134 0x0338 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA1__FLEXIO1_FLEXIO_BIT11 0x0134 0x0338 0x0494 0x04 0x01
+#define IMX95_PAD_SD1_DATA1__GPIO3_IO_BIT11 0x0134 0x0338 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x0138 0x033C 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA2__FLEXIO1_FLEXIO_BIT12 0x0138 0x033C 0x0498 0x04 0x01
+#define IMX95_PAD_SD1_DATA2__GPIO3_IO_BIT12 0x0138 0x033C 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_DATA2__CCMSRCGPCMIX_TOP_PMIC_READY 0x0138 0x033C 0x0000 0x06 0x00
+
+#define IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x013C 0x0340 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA3__FLEXSPI1_A_SS1_B 0x013C 0x0340 0x0000 0x01 0x00
+#define IMX95_PAD_SD1_DATA3__FLEXIO1_FLEXIO_BIT13 0x013C 0x0340 0x049C 0x04 0x01
+#define IMX95_PAD_SD1_DATA3__GPIO3_IO_BIT13 0x013C 0x0340 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x0140 0x0344 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA4__FLEXSPI1_A_DATA_BIT4 0x0140 0x0344 0x04E4 0x01 0x00
+#define IMX95_PAD_SD1_DATA4__FLEXIO1_FLEXIO_BIT14 0x0140 0x0344 0x04A0 0x04 0x01
+#define IMX95_PAD_SD1_DATA4__GPIO3_IO_BIT14 0x0140 0x0344 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_DATA4__XSPI_DATA_BIT4 0x0140 0x0344 0x05FC 0x06 0x00
+
+#define IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x0144 0x0348 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA5__FLEXSPI1_A_DATA_BIT5 0x0144 0x0348 0x04E8 0x01 0x00
+#define IMX95_PAD_SD1_DATA5__USDHC1_RESET_B 0x0144 0x0348 0x0000 0x02 0x00
+#define IMX95_PAD_SD1_DATA5__FLEXIO1_FLEXIO_BIT15 0x0144 0x0348 0x04A4 0x04 0x01
+#define IMX95_PAD_SD1_DATA5__GPIO3_IO_BIT15 0x0144 0x0348 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_DATA5__XSPI_DATA_BIT5 0x0144 0x0348 0x0600 0x06 0x00
+
+#define IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x0148 0x034C 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA6__FLEXSPI1_A_DATA_BIT6 0x0148 0x034C 0x04EC 0x01 0x00
+#define IMX95_PAD_SD1_DATA6__USDHC1_CD_B 0x0148 0x034C 0x0000 0x02 0x00
+#define IMX95_PAD_SD1_DATA6__FLEXIO1_FLEXIO_BIT16 0x0148 0x034C 0x04A8 0x04 0x01
+#define IMX95_PAD_SD1_DATA6__GPIO3_IO_BIT16 0x0148 0x034C 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_DATA6__XSPI_DATA_BIT6 0x0148 0x034C 0x0604 0x06 0x00
+
+#define IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x014C 0x0350 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_DATA7__FLEXSPI1_A_DATA_BIT7 0x014C 0x0350 0x04F0 0x01 0x00
+#define IMX95_PAD_SD1_DATA7__USDHC1_WP 0x014C 0x0350 0x0000 0x02 0x00
+#define IMX95_PAD_SD1_DATA7__FLEXIO1_FLEXIO_BIT17 0x014C 0x0350 0x04AC 0x04 0x01
+#define IMX95_PAD_SD1_DATA7__GPIO3_IO_BIT17 0x014C 0x0350 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_DATA7__XSPI_DATA_BIT7 0x014C 0x0350 0x0608 0x06 0x00
+
+#define IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x0150 0x0354 0x0000 0x00 0x00
+#define IMX95_PAD_SD1_STROBE__FLEXSPI1_A_DQS 0x0150 0x0354 0x04D0 0x01 0x00
+#define IMX95_PAD_SD1_STROBE__FLEXIO1_FLEXIO_BIT18 0x0150 0x0354 0x04B0 0x04 0x01
+#define IMX95_PAD_SD1_STROBE__GPIO3_IO_BIT18 0x0150 0x0354 0x0000 0x05 0x00
+#define IMX95_PAD_SD1_STROBE__XSPI_DQS 0x0150 0x0354 0x05E4 0x06 0x00
+
+#define IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x0154 0x0358 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_VSELECT__USDHC2_WP 0x0154 0x0358 0x0000 0x01 0x00
+#define IMX95_PAD_SD2_VSELECT__LPTMR2_ALT3 0x0154 0x0358 0x0550 0x02 0x01
+#define IMX95_PAD_SD2_VSELECT__FLEXIO1_FLEXIO_BIT19 0x0154 0x0358 0x04B4 0x04 0x01
+#define IMX95_PAD_SD2_VSELECT__GPIO3_IO_BIT19 0x0154 0x0358 0x0000 0x05 0x00
+#define IMX95_PAD_SD2_VSELECT__CCMSRCGPCMIX_TOP_EXT_CLK1 0x0154 0x0358 0x0420 0x06 0x01
+
+#define IMX95_PAD_SD3_CLK__USDHC3_CLK 0x0158 0x035C 0x05C8 0x00 0x01
+#define IMX95_PAD_SD3_CLK__FLEXSPI1_A_SCLK 0x0158 0x035C 0x04F4 0x01 0x00
+#define IMX95_PAD_SD3_CLK__SAI5_TX_DATA_BIT1 0x0158 0x035C 0x0000 0x02 0x00
+#define IMX95_PAD_SD3_CLK__SAI5_RX_DATA_BIT0 0x0158 0x035C 0x05AC 0x03 0x00
+#define IMX95_PAD_SD3_CLK__FLEXIO1_FLEXIO_BIT20 0x0158 0x035C 0x04B8 0x04 0x01
+#define IMX95_PAD_SD3_CLK__GPIO3_IO_BIT20 0x0158 0x035C 0x0000 0x05 0x00
+#define IMX95_PAD_SD3_CLK__XSPI_CLK 0x0158 0x035C 0x05E8 0x06 0x00
+
+#define IMX95_PAD_SD3_CMD__USDHC3_CMD 0x015C 0x0360 0x05CC 0x00 0x01
+#define IMX95_PAD_SD3_CMD__FLEXSPI1_A_SS0_B 0x015C 0x0360 0x0000 0x01 0x00
+#define IMX95_PAD_SD3_CMD__SAI5_TX_DATA_BIT2 0x015C 0x0360 0x0000 0x02 0x00
+#define IMX95_PAD_SD3_CMD__SAI5_RX_SYNC 0x015C 0x0360 0x05BC 0x03 0x00
+#define IMX95_PAD_SD3_CMD__FLEXIO1_FLEXIO_BIT21 0x015C 0x0360 0x04BC 0x04 0x01
+#define IMX95_PAD_SD3_CMD__GPIO3_IO_BIT21 0x015C 0x0360 0x0000 0x05 0x00
+#define IMX95_PAD_SD3_CMD__XSPI_CS 0x015C 0x0360 0x05E0 0x06 0x00
+
+#define IMX95_PAD_SD3_DATA0__USDHC3_DATA0 0x0160 0x0364 0x05D0 0x00 0x01
+#define IMX95_PAD_SD3_DATA0__FLEXSPI1_A_DATA_BIT0 0x0160 0x0364 0x04D4 0x01 0x00
+#define IMX95_PAD_SD3_DATA0__SAI5_TX_DATA_BIT3 0x0160 0x0364 0x0000 0x02 0x00
+#define IMX95_PAD_SD3_DATA0__SAI5_RX_BCLK 0x0160 0x0364 0x05A8 0x03 0x00
+#define IMX95_PAD_SD3_DATA0__FLEXIO1_FLEXIO_BIT22 0x0160 0x0364 0x04C0 0x04 0x01
+#define IMX95_PAD_SD3_DATA0__GPIO3_IO_BIT22 0x0160 0x0364 0x0000 0x05 0x00
+#define IMX95_PAD_SD3_DATA0__XSPI_DATA_BIT0 0x0160 0x0364 0x05EC 0x06 0x00
+
+#define IMX95_PAD_SD3_DATA1__USDHC3_DATA1 0x0164 0x0368 0x05D4 0x00 0x01
+#define IMX95_PAD_SD3_DATA1__FLEXSPI1_A_DATA_BIT1 0x0164 0x0368 0x04D8 0x01 0x00
+#define IMX95_PAD_SD3_DATA1__SAI5_RX_DATA_BIT1 0x0164 0x0368 0x05B0 0x02 0x00
+#define IMX95_PAD_SD3_DATA1__SAI5_TX_DATA_BIT0 0x0164 0x0368 0x0000 0x03 0x00
+#define IMX95_PAD_SD3_DATA1__FLEXIO1_FLEXIO_BIT23 0x0164 0x0368 0x04C4 0x04 0x01
+#define IMX95_PAD_SD3_DATA1__GPIO3_IO_BIT23 0x0164 0x0368 0x0000 0x05 0x00
+#define IMX95_PAD_SD3_DATA1__XSPI_DATA_BIT1 0x0164 0x0368 0x05F0 0x06 0x00
+
+#define IMX95_PAD_SD3_DATA2__USDHC3_DATA2 0x0168 0x036C 0x05D8 0x00 0x01
+#define IMX95_PAD_SD3_DATA2__FLEXSPI1_A_DATA_BIT2 0x0168 0x036C 0x04DC 0x01 0x00
+#define IMX95_PAD_SD3_DATA2__SAI5_RX_DATA_BIT2 0x0168 0x036C 0x05B4 0x02 0x00
+#define IMX95_PAD_SD3_DATA2__SAI5_TX_SYNC 0x0168 0x036C 0x05C4 0x03 0x00
+#define IMX95_PAD_SD3_DATA2__FLEXIO1_FLEXIO_BIT24 0x0168 0x036C 0x04C8 0x04 0x01
+#define IMX95_PAD_SD3_DATA2__GPIO3_IO_BIT24 0x0168 0x036C 0x0000 0x05 0x00
+#define IMX95_PAD_SD3_DATA2__XSPI_DATA_BIT2 0x0168 0x036C 0x05F4 0x06 0x00
+
+#define IMX95_PAD_SD3_DATA3__USDHC3_DATA3 0x016C 0x0370 0x05DC 0x00 0x01
+#define IMX95_PAD_SD3_DATA3__FLEXSPI1_A_DATA_BIT3 0x016C 0x0370 0x04E0 0x01 0x00
+#define IMX95_PAD_SD3_DATA3__SAI5_RX_DATA_BIT3 0x016C 0x0370 0x05B8 0x02 0x00
+#define IMX95_PAD_SD3_DATA3__SAI5_TX_BCLK 0x016C 0x0370 0x05C0 0x03 0x00
+#define IMX95_PAD_SD3_DATA3__FLEXIO1_FLEXIO_BIT25 0x016C 0x0370 0x04CC 0x04 0x01
+#define IMX95_PAD_SD3_DATA3__GPIO3_IO_BIT25 0x016C 0x0370 0x0000 0x05 0x00
+#define IMX95_PAD_SD3_DATA3__XSPI_DATA_BIT3 0x016C 0x0370 0x05F8 0x06 0x00
+
+#define IMX95_PAD_XSPI1_DATA0__FLEXSPI1_A_DATA_BIT0 0x0170 0x0374 0x04D4 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA0__NETCMIX_TOP_SAI2_TX_DATA_BIT4 0x0170 0x0374 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_DATA0__SAI4_TX_BCLK 0x0170 0x0374 0x05A0 0x02 0x01
+#define IMX95_PAD_XSPI1_DATA0__SAI4_RX_DATA_BIT1 0x0170 0x0374 0x0000 0x03 0x00
+#define IMX95_PAD_XSPI1_DATA0__XSPI_DATA_BIT0 0x0170 0x0374 0x05EC 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA0__GPIO5_IO_BIT0 0x0170 0x0374 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA1__FLEXSPI1_A_DATA_BIT1 0x0174 0x0378 0x04D8 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA1__NETCMIX_TOP_SAI2_TX_DATA_BIT5 0x0174 0x0378 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_DATA1__SAI4_TX_SYNC 0x0174 0x0378 0x05A4 0x02 0x01
+#define IMX95_PAD_XSPI1_DATA1__SAI4_TX_DATA_BIT1 0x0174 0x0378 0x0000 0x03 0x00
+#define IMX95_PAD_XSPI1_DATA1__XSPI_DATA_BIT1 0x0174 0x0378 0x05F0 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA1__GPIO5_IO_BIT1 0x0174 0x0378 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA2__FLEXSPI1_A_DATA_BIT2 0x0178 0x037C 0x04DC 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA2__NETCMIX_TOP_SAI2_TX_DATA_BIT6 0x0178 0x037C 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_DATA2__SAI4_TX_DATA_BIT0 0x0178 0x037C 0x0000 0x02 0x00
+#define IMX95_PAD_XSPI1_DATA2__XSPI_DATA_BIT2 0x0178 0x037C 0x05F4 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA2__GPIO5_IO_BIT2 0x0178 0x037C 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA3__FLEXSPI1_A_DATA_BIT3 0x017C 0x0380 0x04E0 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA3__NETCMIX_TOP_SAI2_TX_DATA_BIT7 0x017C 0x0380 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_DATA3__SAI4_RX_DATA_BIT0 0x017C 0x0380 0x0598 0x02 0x01
+#define IMX95_PAD_XSPI1_DATA3__XSPI_DATA_BIT3 0x017C 0x0380 0x05F8 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA3__GPIO5_IO_BIT3 0x017C 0x0380 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA4__FLEXSPI1_A_DATA_BIT4 0x0180 0x0384 0x04E4 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA4__SAI5_TX_DATA_BIT0 0x0180 0x0384 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_DATA4__SAI5_RX_DATA_BIT1 0x0180 0x0384 0x05B0 0x02 0x01
+#define IMX95_PAD_XSPI1_DATA4__XSPI_DATA_BIT4 0x0180 0x0384 0x05FC 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA4__GPIO5_IO_BIT4 0x0180 0x0384 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA5__FLEXSPI1_A_DATA_BIT5 0x0184 0x0388 0x04E8 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA5__SAI5_TX_SYNC 0x0184 0x0388 0x05C4 0x01 0x01
+#define IMX95_PAD_XSPI1_DATA5__SAI5_RX_DATA_BIT2 0x0184 0x0388 0x05B4 0x02 0x01
+#define IMX95_PAD_XSPI1_DATA5__NETCMIX_TOP_SAI2_RX_DATA_BIT6 0x0184 0x0388 0x043C 0x03 0x00
+#define IMX95_PAD_XSPI1_DATA5__XSPI_DATA_BIT5 0x0184 0x0388 0x0600 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA5__GPIO5_IO_BIT5 0x0184 0x0388 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA6__FLEXSPI1_A_DATA_BIT6 0x0188 0x038C 0x04EC 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA6__SAI5_TX_BCLK 0x0188 0x038C 0x05C0 0x01 0x01
+#define IMX95_PAD_XSPI1_DATA6__SAI5_RX_DATA_BIT3 0x0188 0x038C 0x05B8 0x02 0x01
+#define IMX95_PAD_XSPI1_DATA6__NETCMIX_TOP_SAI2_RX_DATA_BIT7 0x0188 0x038C 0x0440 0x03 0x00
+#define IMX95_PAD_XSPI1_DATA6__XSPI_DATA_BIT6 0x0188 0x038C 0x0604 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA6__GPIO5_IO_BIT6 0x0188 0x038C 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DATA7__FLEXSPI1_A_DATA_BIT7 0x018C 0x0390 0x04F0 0x00 0x01
+#define IMX95_PAD_XSPI1_DATA7__SAI5_RX_DATA_BIT0 0x018C 0x0390 0x05AC 0x01 0x01
+#define IMX95_PAD_XSPI1_DATA7__SAI5_TX_DATA_BIT1 0x018C 0x0390 0x0000 0x02 0x00
+#define IMX95_PAD_XSPI1_DATA7__XSPI_DATA_BIT7 0x018C 0x0390 0x0608 0x04 0x01
+#define IMX95_PAD_XSPI1_DATA7__GPIO5_IO_BIT7 0x018C 0x0390 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_DQS__FLEXSPI1_A_DQS 0x0190 0x0394 0x04D0 0x00 0x01
+#define IMX95_PAD_XSPI1_DQS__SAI5_RX_SYNC 0x0190 0x0394 0x05BC 0x01 0x01
+#define IMX95_PAD_XSPI1_DQS__SAI5_TX_DATA_BIT2 0x0190 0x0394 0x0000 0x02 0x00
+#define IMX95_PAD_XSPI1_DQS__NETCMIX_TOP_SAI2_RX_DATA_BIT6 0x0190 0x0394 0x043C 0x03 0x01
+#define IMX95_PAD_XSPI1_DQS__XSPI_DQS 0x0190 0x0394 0x05E4 0x04 0x01
+#define IMX95_PAD_XSPI1_DQS__GPIO5_IO_BIT8 0x0190 0x0394 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_SCLK__FLEXSPI1_A_SCLK 0x0194 0x0398 0x04F4 0x00 0x01
+#define IMX95_PAD_XSPI1_SCLK__NETCMIX_TOP_SAI2_RX_DATA_BIT4 0x0194 0x0398 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_SCLK__SAI4_RX_SYNC 0x0194 0x0398 0x059C 0x02 0x01
+#define IMX95_PAD_XSPI1_SCLK__EARC_DC_HPD_IN 0x0194 0x0398 0x0000 0x03 0x00
+#define IMX95_PAD_XSPI1_SCLK__XSPI_CLK 0x0194 0x0398 0x05E8 0x04 0x01
+#define IMX95_PAD_XSPI1_SCLK__GPIO5_IO_BIT9 0x0194 0x0398 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B 0x0198 0x039C 0x0000 0x00 0x00
+#define IMX95_PAD_XSPI1_SS0_B__NETCMIX_TOP_SAI2_RX_DATA_BIT5 0x0198 0x039C 0x0000 0x01 0x00
+#define IMX95_PAD_XSPI1_SS0_B__SAI4_RX_BCLK 0x0198 0x039C 0x0594 0x02 0x01
+#define IMX95_PAD_XSPI1_SS0_B__EARC_CEC_OUT 0x0198 0x039C 0x0000 0x03 0x00
+#define IMX95_PAD_XSPI1_SS0_B__XSPI_CS 0x0198 0x039C 0x05E0 0x04 0x01
+#define IMX95_PAD_XSPI1_SS0_B__GPIO5_IO_BIT10 0x0198 0x039C 0x0000 0x05 0x00
+
+#define IMX95_PAD_XSPI1_SS1_B__FLEXSPI1_A_SS1_B 0x019C 0x03A0 0x0000 0x00 0x00
+#define IMX95_PAD_XSPI1_SS1_B__SAI5_RX_BCLK 0x019C 0x03A0 0x05A8 0x01 0x01
+#define IMX95_PAD_XSPI1_SS1_B__SAI5_TX_DATA_BIT3 0x019C 0x03A0 0x0000 0x02 0x00
+#define IMX95_PAD_XSPI1_SS1_B__NETCMIX_TOP_SAI2_RX_DATA_BIT7 0x019C 0x03A0 0x0440 0x03 0x01
+#define IMX95_PAD_XSPI1_SS1_B__GPIO5_IO_BIT11 0x019C 0x03A0 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD2_CD_B__USDHC2_CD_B 0x01A0 0x03A4 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_CD_B__NETCMIX_TOP_NETC_TMR_1588_TRIG1 0x01A0 0x03A4 0x0434 0x01 0x01
+#define IMX95_PAD_SD2_CD_B__I3C2_SCL 0x01A0 0x03A4 0x04F8 0x02 0x01
+#define IMX95_PAD_SD2_CD_B__FLEXIO1_FLEXIO_BIT0 0x01A0 0x03A4 0x0468 0x04 0x01
+#define IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x01A0 0x03A4 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD2_CLK__USDHC2_CLK 0x01A4 0x03A8 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_CLK__NETCMIX_TOP_NETC_TMR_1588_PP1 0x01A4 0x03A8 0x0000 0x01 0x00
+#define IMX95_PAD_SD2_CLK__I3C2_SDA 0x01A4 0x03A8 0x04FC 0x02 0x01
+#define IMX95_PAD_SD2_CLK__FLEXIO1_FLEXIO_BIT1 0x01A4 0x03A8 0x046C 0x04 0x01
+#define IMX95_PAD_SD2_CLK__GPIO3_IO_BIT1 0x01A4 0x03A8 0x0000 0x05 0x00
+#define IMX95_PAD_SD2_CLK__CCMSRCGPCMIX_TOP_OBSERVE_0 0x01A4 0x03A8 0x0000 0x06 0x00
+
+#define IMX95_PAD_SD2_CMD__USDHC2_CMD 0x01A8 0x03AC 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_CMD__NETCMIX_TOP_NETC_TMR_1588_TRIG2 0x01A8 0x03AC 0x0438 0x01 0x01
+#define IMX95_PAD_SD2_CMD__I3C2_PUR 0x01A8 0x03AC 0x0000 0x02 0x00
+#define IMX95_PAD_SD2_CMD__I3C2_PUR_B 0x01A8 0x03AC 0x0000 0x03 0x00
+#define IMX95_PAD_SD2_CMD__FLEXIO1_FLEXIO_BIT2 0x01A8 0x03AC 0x0470 0x04 0x01
+#define IMX95_PAD_SD2_CMD__GPIO3_IO_BIT2 0x01A8 0x03AC 0x0000 0x05 0x00
+#define IMX95_PAD_SD2_CMD__CCMSRCGPCMIX_TOP_OBSERVE_1 0x01A8 0x03AC 0x0000 0x06 0x00
+
+#define IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x01AC 0x03B0 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_DATA0__NETCMIX_TOP_NETC_TMR_1588_PP2 0x01AC 0x03B0 0x0000 0x01 0x00
+#define IMX95_PAD_SD2_DATA0__CAN2_TX 0x01AC 0x03B0 0x0000 0x02 0x00
+#define IMX95_PAD_SD2_DATA0__FLEXIO1_FLEXIO_BIT3 0x01AC 0x03B0 0x0474 0x04 0x01
+#define IMX95_PAD_SD2_DATA0__GPIO3_IO_BIT3 0x01AC 0x03B0 0x0000 0x05 0x00
+#define IMX95_PAD_SD2_DATA0__CCMSRCGPCMIX_TOP_OBSERVE_2 0x01AC 0x03B0 0x0000 0x06 0x00
+
+#define IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x01B0 0x03B4 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_DATA1__NETCMIX_TOP_NETC_TMR_1588_CLK 0x01B0 0x03B4 0x0000 0x01 0x00
+#define IMX95_PAD_SD2_DATA1__CAN2_RX 0x01B0 0x03B4 0x0444 0x02 0x03
+#define IMX95_PAD_SD2_DATA1__FLEXIO1_FLEXIO_BIT4 0x01B0 0x03B4 0x0478 0x04 0x01
+#define IMX95_PAD_SD2_DATA1__GPIO3_IO_BIT4 0x01B0 0x03B4 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x01B4 0x03B8 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_DATA2__NETCMIX_TOP_NETC_TMR_1588_PP3 0x01B4 0x03B8 0x0000 0x01 0x00
+#define IMX95_PAD_SD2_DATA2__NETCMIX_TOP_MQS2_RIGHT 0x01B4 0x03B8 0x0000 0x02 0x00
+#define IMX95_PAD_SD2_DATA2__FLEXIO1_FLEXIO_BIT5 0x01B4 0x03B8 0x047C 0x04 0x01
+#define IMX95_PAD_SD2_DATA2__GPIO3_IO_BIT5 0x01B4 0x03B8 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x01B8 0x03BC 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_DATA3__LPTMR2_ALT1 0x01B8 0x03BC 0x0548 0x01 0x01
+#define IMX95_PAD_SD2_DATA3__NETCMIX_TOP_MQS2_LEFT 0x01B8 0x03BC 0x0000 0x02 0x00
+#define IMX95_PAD_SD2_DATA3__NETCMIX_TOP_NETC_TMR_1588_ALARM1 0x01B8 0x03BC 0x0000 0x03 0x00
+#define IMX95_PAD_SD2_DATA3__FLEXIO1_FLEXIO_BIT6 0x01B8 0x03BC 0x0480 0x04 0x01
+#define IMX95_PAD_SD2_DATA3__GPIO3_IO_BIT6 0x01B8 0x03BC 0x0000 0x05 0x00
+
+#define IMX95_PAD_SD2_RESET_B__USDHC2_RESET_B 0x01BC 0x03C0 0x0000 0x00 0x00
+#define IMX95_PAD_SD2_RESET_B__LPTMR2_ALT2 0x01BC 0x03C0 0x054C 0x01 0x01
+#define IMX95_PAD_SD2_RESET_B__NETCMIX_TOP_NETC_TMR_1588_GCLK 0x01BC 0x03C0 0x0000 0x03 0x00
+#define IMX95_PAD_SD2_RESET_B__FLEXIO1_FLEXIO_BIT7 0x01BC 0x03C0 0x0484 0x04 0x01
+#define IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x01BC 0x03C0 0x0000 0x05 0x00
+
+#define IMX95_PAD_I2C1_SCL__AONMIX_TOP_LPI2C1_SCL 0x01C0 0x03C4 0x0000 0x00 0x00
+#define IMX95_PAD_I2C1_SCL__AONMIX_TOP_I3C1_SCL 0x01C0 0x03C4 0x0000 0x01 0x00
+#define IMX95_PAD_I2C1_SCL__AONMIX_TOP_LPUART1_DCD_B 0x01C0 0x03C4 0x0000 0x02 0x00
+#define IMX95_PAD_I2C1_SCL__AONMIX_TOP_TPM2_CH0 0x01C0 0x03C4 0x0000 0x03 0x00
+#define IMX95_PAD_I2C1_SCL__VPUMIX_TOP_UART_RX 0x01C0 0x03C4 0x0000 0x04 0x00
+#define IMX95_PAD_I2C1_SCL__AONMIX_TOP_GPIO1_IO_BIT0 0x01C0 0x03C4 0x0000 0x05 0x00
+
+#define IMX95_PAD_I2C1_SDA__AONMIX_TOP_LPI2C1_SDA 0x01C4 0x03C8 0x0000 0x00 0x00
+#define IMX95_PAD_I2C1_SDA__AONMIX_TOP_I3C1_SDA 0x01C4 0x03C8 0x0000 0x01 0x00
+#define IMX95_PAD_I2C1_SDA__AONMIX_TOP_LPUART1_RIN_B 0x01C4 0x03C8 0x0000 0x02 0x00
+#define IMX95_PAD_I2C1_SDA__AONMIX_TOP_TPM2_CH1 0x01C4 0x03C8 0x0000 0x03 0x00
+#define IMX95_PAD_I2C1_SDA__VPUMIX_TOP_UART_TX 0x01C4 0x03C8 0x0000 0x04 0x00
+#define IMX95_PAD_I2C1_SDA__AONMIX_TOP_GPIO1_IO_BIT1 0x01C4 0x03C8 0x0000 0x05 0x00
+
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_LPI2C2_SCL 0x01C8 0x03CC 0x0000 0x00 0x00
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_I3C1_PUR 0x01C8 0x03CC 0x0000 0x01 0x00
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_LPUART2_DCD_B 0x01C8 0x03CC 0x0000 0x02 0x00
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_TPM2_CH2 0x01C8 0x03CC 0x0000 0x03 0x00
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_SAI1_RX_SYNC 0x01C8 0x03CC 0x0000 0x04 0x00
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_GPIO1_IO_BIT2 0x01C8 0x03CC 0x0000 0x05 0x00
+#define IMX95_PAD_I2C2_SCL__AONMIX_TOP_I3C1_PUR_B 0x01C8 0x03CC 0x0000 0x06 0x00
+
+#define IMX95_PAD_I2C2_SDA__AONMIX_TOP_LPI2C2_SDA 0x01CC 0x03D0 0x0000 0x00 0x00
+#define IMX95_PAD_I2C2_SDA__AONMIX_TOP_LPUART2_RIN_B 0x01CC 0x03D0 0x0000 0x02 0x00
+#define IMX95_PAD_I2C2_SDA__AONMIX_TOP_TPM2_CH3 0x01CC 0x03D0 0x0000 0x03 0x00
+#define IMX95_PAD_I2C2_SDA__AONMIX_TOP_SAI1_RX_BCLK 0x01CC 0x03D0 0x0000 0x04 0x00
+#define IMX95_PAD_I2C2_SDA__AONMIX_TOP_GPIO1_IO_BIT3 0x01CC 0x03D0 0x0000 0x05 0x00
+
+#define IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x01D0 0x03D4 0x0000 0x00 0x00
+#define IMX95_PAD_UART1_RXD__S400_UART_RX 0x01D0 0x03D4 0x0000 0x01 0x00
+#define IMX95_PAD_UART1_RXD__AONMIX_TOP_LPSPI2_SIN 0x01D0 0x03D4 0x0000 0x02 0x00
+#define IMX95_PAD_UART1_RXD__AONMIX_TOP_TPM1_CH0 0x01D0 0x03D4 0x0000 0x03 0x00
+#define IMX95_PAD_UART1_RXD__AONMIX_TOP_GPIO1_IO_BIT4 0x01D0 0x03D4 0x0000 0x05 0x00
+
+#define IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x01D4 0x03D8 0x0000 0x00 0x00
+#define IMX95_PAD_UART1_TXD__S400_UART_TX 0x01D4 0x03D8 0x0000 0x01 0x00
+#define IMX95_PAD_UART1_TXD__AONMIX_TOP_LPSPI2_PCS0 0x01D4 0x03D8 0x0000 0x02 0x00
+#define IMX95_PAD_UART1_TXD__AONMIX_TOP_TPM1_CH1 0x01D4 0x03D8 0x0000 0x03 0x00
+#define IMX95_PAD_UART1_TXD__AONMIX_TOP_GPIO1_IO_BIT5 0x01D4 0x03D8 0x0000 0x05 0x00
+
+#define IMX95_PAD_UART2_RXD__AONMIX_TOP_LPUART2_RX 0x01D8 0x03DC 0x0000 0x00 0x00
+#define IMX95_PAD_UART2_RXD__AONMIX_TOP_LPUART1_CTS_B 0x01D8 0x03DC 0x0000 0x01 0x00
+#define IMX95_PAD_UART2_RXD__AONMIX_TOP_LPSPI2_SOUT 0x01D8 0x03DC 0x0000 0x02 0x00
+#define IMX95_PAD_UART2_RXD__AONMIX_TOP_TPM1_CH2 0x01D8 0x03DC 0x0000 0x03 0x00
+#define IMX95_PAD_UART2_RXD__AONMIX_TOP_SAI1_MCLK 0x01D8 0x03DC 0x041C 0x04 0x00
+#define IMX95_PAD_UART2_RXD__AONMIX_TOP_GPIO1_IO_BIT6 0x01D8 0x03DC 0x0000 0x05 0x00
+
+#define IMX95_PAD_UART2_TXD__AONMIX_TOP_LPUART2_TX 0x01DC 0x03E0 0x0000 0x00 0x00
+#define IMX95_PAD_UART2_TXD__AONMIX_TOP_LPUART1_RTS_B 0x01DC 0x03E0 0x0000 0x01 0x00
+#define IMX95_PAD_UART2_TXD__AONMIX_TOP_LPSPI2_SCK 0x01DC 0x03E0 0x0000 0x02 0x00
+#define IMX95_PAD_UART2_TXD__AONMIX_TOP_TPM1_CH3 0x01DC 0x03E0 0x0000 0x03 0x00
+#define IMX95_PAD_UART2_TXD__AONMIX_TOP_GPIO1_IO_BIT7 0x01DC 0x03E0 0x0000 0x05 0x00
+
+#define IMX95_PAD_PDM_CLK__AONMIX_TOP_PDM_CLK 0x01E0 0x03E4 0x0000 0x00 0x00
+#define IMX95_PAD_PDM_CLK__AONMIX_TOP_MQS1_LEFT 0x01E0 0x03E4 0x0000 0x01 0x00
+#define IMX95_PAD_PDM_CLK__AONMIX_TOP_LPTMR1_ALT1 0x01E0 0x03E4 0x0000 0x04 0x00
+#define IMX95_PAD_PDM_CLK__AONMIX_TOP_GPIO1_IO_BIT8 0x01E0 0x03E4 0x0000 0x05 0x00
+#define IMX95_PAD_PDM_CLK__AONMIX_TOP_CAN1_TX 0x01E0 0x03E4 0x0000 0x06 0x00
+
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_PDM_BIT_STREAM_BIT0 0x01E4 0x03E8 0x040C 0x00 0x00
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_MQS1_RIGHT 0x01E4 0x03E8 0x0000 0x01 0x00
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_LPSPI1_PCS1 0x01E4 0x03E8 0x0000 0x02 0x00
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_TPM1_EXTCLK 0x01E4 0x03E8 0x0000 0x03 0x00
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_LPTMR1_ALT2 0x01E4 0x03E8 0x0000 0x04 0x00
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_GPIO1_IO_BIT9 0x01E4 0x03E8 0x0000 0x05 0x00
+#define IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_CAN1_RX 0x01E4 0x03E8 0x0408 0x06 0x00
+
+#define IMX95_PAD_PDM_BIT_STREAM1__AONMIX_TOP_PDM_BIT_STREAM_BIT1 0x01E8 0x03EC 0x0410 0x00 0x00
+#define IMX95_PAD_PDM_BIT_STREAM1__NMI_GLUE_NMI 0x01E8 0x03EC 0x0000 0x01 0x00
+#define IMX95_PAD_PDM_BIT_STREAM1__AONMIX_TOP_LPSPI2_PCS1 0x01E8 0x03EC 0x0000 0x02 0x00
+#define IMX95_PAD_PDM_BIT_STREAM1__AONMIX_TOP_TPM2_EXTCLK 0x01E8 0x03EC 0x0000 0x03 0x00
+#define IMX95_PAD_PDM_BIT_STREAM1__AONMIX_TOP_LPTMR1_ALT3 0x01E8 0x03EC 0x0000 0x04 0x00
+#define IMX95_PAD_PDM_BIT_STREAM1__AONMIX_TOP_GPIO1_IO_BIT10 0x01E8 0x03EC 0x0000 0x05 0x00
+#define IMX95_PAD_PDM_BIT_STREAM1__CCMSRCGPCMIX_TOP_EXT_CLK1 0x01E8 0x03EC 0x0420 0x06 0x00
+
+#define IMX95_PAD_SAI1_TXFS__AONMIX_TOP_SAI1_TX_SYNC 0x01EC 0x03F0 0x0000 0x00 0x00
+#define IMX95_PAD_SAI1_TXFS__AONMIX_TOP_SAI1_TX_DATA_BIT1 0x01EC 0x03F0 0x0000 0x01 0x00
+#define IMX95_PAD_SAI1_TXFS__AONMIX_TOP_LPSPI1_PCS0 0x01EC 0x03F0 0x0000 0x02 0x00
+#define IMX95_PAD_SAI1_TXFS__AONMIX_TOP_LPUART2_DTR_B 0x01EC 0x03F0 0x0000 0x03 0x00
+#define IMX95_PAD_SAI1_TXFS__AONMIX_TOP_MQS1_LEFT 0x01EC 0x03F0 0x0000 0x04 0x00
+#define IMX95_PAD_SAI1_TXFS__AONMIX_TOP_GPIO1_IO_BIT11 0x01EC 0x03F0 0x0000 0x05 0x00
+
+#define IMX95_PAD_SAI1_TXC__AONMIX_TOP_SAI1_TX_BCLK 0x01F0 0x03F4 0x0000 0x00 0x00
+#define IMX95_PAD_SAI1_TXC__AONMIX_TOP_LPUART2_CTS_B 0x01F0 0x03F4 0x0000 0x01 0x00
+#define IMX95_PAD_SAI1_TXC__AONMIX_TOP_LPSPI1_SIN 0x01F0 0x03F4 0x0000 0x02 0x00
+#define IMX95_PAD_SAI1_TXC__AONMIX_TOP_LPUART1_DSR_B 0x01F0 0x03F4 0x0000 0x03 0x00
+#define IMX95_PAD_SAI1_TXC__AONMIX_TOP_CAN1_RX 0x01F0 0x03F4 0x0408 0x04 0x01
+#define IMX95_PAD_SAI1_TXC__AONMIX_TOP_GPIO1_IO_BIT12 0x01F0 0x03F4 0x0000 0x05 0x00
+
+#define IMX95_PAD_SAI1_TXD0__AONMIX_TOP_SAI1_TX_DATA_BIT0 0x01F4 0x03F8 0x0000 0x00 0x00
+#define IMX95_PAD_SAI1_TXD0__AONMIX_TOP_LPUART2_RTS_B 0x01F4 0x03F8 0x0000 0x01 0x00
+#define IMX95_PAD_SAI1_TXD0__AONMIX_TOP_LPSPI1_SCK 0x01F4 0x03F8 0x0000 0x02 0x00
+#define IMX95_PAD_SAI1_TXD0__AONMIX_TOP_LPUART1_DTR_B 0x01F4 0x03F8 0x0000 0x03 0x00
+#define IMX95_PAD_SAI1_TXD0__AONMIX_TOP_CAN1_TX 0x01F4 0x03F8 0x0000 0x04 0x00
+#define IMX95_PAD_SAI1_TXD0__AONMIX_TOP_GPIO1_IO_BIT13 0x01F4 0x03F8 0x0000 0x05 0x00
+
+#define IMX95_PAD_SAI1_RXD0__AONMIX_TOP_SAI1_RX_DATA_BIT0 0x01F8 0x03FC 0x0000 0x00 0x00
+#define IMX95_PAD_SAI1_RXD0__AONMIX_TOP_SAI1_MCLK 0x01F8 0x03FC 0x041C 0x01 0x01
+#define IMX95_PAD_SAI1_RXD0__AONMIX_TOP_LPSPI1_SOUT 0x01F8 0x03FC 0x0000 0x02 0x00
+#define IMX95_PAD_SAI1_RXD0__AONMIX_TOP_LPUART2_DSR_B 0x01F8 0x03FC 0x0000 0x03 0x00
+#define IMX95_PAD_SAI1_RXD0__AONMIX_TOP_MQS1_RIGHT 0x01F8 0x03FC 0x0000 0x04 0x00
+#define IMX95_PAD_SAI1_RXD0__AONMIX_TOP_GPIO1_IO_BIT14 0x01F8 0x03FC 0x0000 0x05 0x00
+
+#define IMX95_PAD_WDOG_ANY__AONMIX_TOP_WDOG_ANY 0x01FC 0x0400 0x0000 0x00 0x00
+#define IMX95_PAD_WDOG_ANY__AONMIX_TOP_FCCU_EOUT1 0x01FC 0x0400 0x0000 0x01 0x00
+#define IMX95_PAD_WDOG_ANY__AONMIX_TOP_GPIO1_IO_BIT15 0x01FC 0x0400 0x0000 0x05 0x00
+#endif /* __DTS_IMX95_PINFUNC_H */
diff --git a/arch/arm64/boot/dts/freescale/imx95-power.h b/arch/arm64/boot/dts/freescale/imx95-power.h
new file mode 100644
index 000000000000..0b7f0bc30e19
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-power.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __IMX95_POWER_H__
+#define __IMX95_POWER_H__
+
+#define IMX95_PD_ANA 0
+#define IMX95_PD_AON 1
+#define IMX95_PD_BBSM 2
+#define IMX95_PD_CAMERA 3
+#define IMX95_PD_CCMSRCGPC 4
+#define IMX95_PD_A55C0 5
+#define IMX95_PD_A55C1 6
+#define IMX95_PD_A55C2 7
+#define IMX95_PD_A55C3 8
+#define IMX95_PD_A55C4 9
+#define IMX95_PD_A55C5 10
+#define IMX95_PD_A55P 11
+#define IMX95_PD_DDR 12
+#define IMX95_PD_DISPLAY 13
+#define IMX95_PD_GPU 14
+#define IMX95_PD_HSIO_TOP 15
+#define IMX95_PD_HSIO_WAON 16
+#define IMX95_PD_M7 17
+#define IMX95_PD_NETC 18
+#define IMX95_PD_NOC 19
+#define IMX95_PD_NPU 20
+#define IMX95_PD_VPU 21
+#define IMX95_PD_WAKEUP 22
+
+#define IMX95_PERF_ELE 0
+#define IMX95_PERF_M33 1
+#define IMX95_PERF_WAKEUP 2
+#define IMX95_PERF_M7 3
+#define IMX95_PERF_DRAM 4
+#define IMX95_PERF_HSIO 5
+#define IMX95_PERF_NPU 6
+#define IMX95_PERF_NOC 7
+#define IMX95_PERF_A55 8
+#define IMX95_PERF_GPU 9
+#define IMX95_PERF_VPU 10
+#define IMX95_PERF_CAM 11
+#define IMX95_PERF_DISP 12
+
+#endif
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
new file mode 100644
index 000000000000..1bbf9a0468f6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -0,0 +1,1192 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "imx95-clock.h"
+#include "imx95-pinfunc.h"
+#include "imx95-power.h"
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ A55_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0>;
+ enable-method = "psci";
+ #cooling-cells = <2>;
+ power-domains = <&scmi_devpd IMX95_PERF_A55>;
+ power-domain-names = "perf";
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l0>;
+ };
+
+ A55_1: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x100>;
+ enable-method = "psci";
+ #cooling-cells = <2>;
+ power-domains = <&scmi_devpd IMX95_PERF_A55>;
+ power-domain-names = "perf";
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l1>;
+ };
+
+ A55_2: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x200>;
+ enable-method = "psci";
+ #cooling-cells = <2>;
+ power-domains = <&scmi_devpd IMX95_PERF_A55>;
+ power-domain-names = "perf";
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l2>;
+ };
+
+ A55_3: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x300>;
+ enable-method = "psci";
+ #cooling-cells = <2>;
+ power-domains = <&scmi_devpd IMX95_PERF_A55>;
+ power-domain-names = "perf";
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l3>;
+ };
+
+ A55_4: cpu@400 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x400>;
+ power-domains = <&scmi_devpd IMX95_PERF_A55>;
+ power-domain-names = "perf";
+ enable-method = "psci";
+ #cooling-cells = <2>;
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l4>;
+ };
+
+ A55_5: cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x500>;
+ power-domains = <&scmi_devpd IMX95_PERF_A55>;
+ power-domain-names = "perf";
+ enable-method = "psci";
+ #cooling-cells = <2>;
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l5>;
+ };
+
+ l2_cache_l0: l2-cache-l0 {
+ compatible = "cache";
+ cache-size = <65536>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l1: l2-cache-l1 {
+ compatible = "cache";
+ cache-size = <65536>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l2: l2-cache-l2 {
+ compatible = "cache";
+ cache-size = <65536>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l3: l2-cache-l3 {
+ compatible = "cache";
+ cache-size = <65536>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l4: l2-cache-l4 {
+ compatible = "cache";
+ cache-size = <65536>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l5: l2-cache-l5 {
+ compatible = "cache";
+ cache-size = <65536>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l3_cache: l3-cache {
+ compatible = "cache";
+ cache-size = <524288>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ cache-level = <3>;
+ cache-unified;
+ };
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&A55_0>;
+ };
+
+ core1 {
+ cpu = <&A55_1>;
+ };
+
+ core2 {
+ cpu = <&A55_2>;
+ };
+
+ core3 {
+ cpu = <&A55_3>;
+ };
+
+ core4 {
+ cpu = <&A55_4>;
+ };
+
+ core5 {
+ cpu = <&A55_5>;
+ };
+ };
+ };
+ };
+
+ clk_ext1: clock-ext1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext1";
+ };
+
+ sai1_mclk: clock-sai-mclk1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency= <0>;
+ clock-output-names = "sai1_mclk";
+ };
+
+ sai2_mclk: clock-sai-mclk2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency= <0>;
+ clock-output-names = "sai2_mclk";
+ };
+
+ sai3_mclk: clock-sai-mclk3 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency= <0>;
+ clock-output-names = "sai3_mclk";
+ };
+
+ sai4_mclk: clock-sai-mclk4 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency= <0>;
+ clock-output-names = "sai4_mclk";
+ };
+
+ sai5_mclk: clock-sai-mclk5 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency= <0>;
+ clock-output-names = "sai5_mclk";
+ };
+
+ osc_24m: clock-24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc_24m";
+ };
+
+ sram1: sram@204c0000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x204c0000 0x0 0x18000>;
+ ranges = <0x0 0x0 0x204c0000 0x18000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ firmware {
+ scmi {
+ compatible = "arm,scmi";
+ mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>;
+ shmem = <&scmi_buf0>, <&scmi_buf1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_devpd: protocol@11 {
+ reg = <0x11>;
+ #power-domain-cells = <1>;
+ };
+
+ scmi_perf: protocol@13 {
+ reg = <0x13>;
+ #power-domain-cells = <1>;
+ };
+
+ scmi_clk: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
+ scmi_sensor: protocol@15 {
+ reg = <0x15>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ scmi_iomuxc: protocol@19 {
+ reg = <0x19>;
+ };
+
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ thermal-zones {
+ a55-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&scmi_sensor 1>;
+
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit0: trip1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <24000000>;
+ arm,no-tick-in-suspend;
+ interrupt-parent = <&gic>;
+ };
+
+ gic: interrupt-controller@48000000 {
+ compatible = "arm,gic-v3";
+ reg = <0 0x48000000 0 0x10000>,
+ <0 0x48060000 0 0xc0000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ dma-noncoherent;
+ ranges;
+
+ its: msi-controller@48040000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0 0x48040000 0 0x20000>;
+ msi-controller;
+ #msi-cells = <1>;
+ dma-noncoherent;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ aips2: bus@42000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ reg = <0x0 0x42000000 0x0 0x800000>;
+ ranges = <0x42000000 0x0 0x42000000 0x8000000>,
+ <0x28000000 0x0 0x28000000 0x10000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mu7: mailbox@42430000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x42430000 0x10000>;
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ wdog3: watchdog@42490000 {
+ compatible = "fsl,imx93-wdt";
+ reg = <0x42490000 0x10000>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ timeout-sec = <40>;
+ status = "disabled";
+ };
+
+ tpm3: pwm@424e0000 {
+ compatible = "fsl,imx7ulp-pwm";
+ reg = <0x424e0000 0x1000>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ tpm4: pwm@424f0000 {
+ compatible = "fsl,imx7ulp-pwm";
+ reg = <0x424f0000 0x1000>;
+ clocks = <&scmi_clk IMX95_CLK_TPM4>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ tpm5: pwm@42500000 {
+ compatible = "fsl,imx7ulp-pwm";
+ reg = <0x42500000 0x1000>;
+ clocks = <&scmi_clk IMX95_CLK_TPM5>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ tpm6: pwm@42510000 {
+ compatible = "fsl,imx7ulp-pwm";
+ reg = <0x42510000 0x1000>;
+ clocks = <&scmi_clk IMX95_CLK_TPM6>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ lpi2c3: i2c@42530000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x42530000 0x10000>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C3>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpi2c4: i2c@42540000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x42540000 0x10000>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C4>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpspi3: spi@42550000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x42550000 0x10000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI3>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpspi4: spi@42560000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x42560000 0x10000>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI4>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpuart3: serial@42570000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x42570000 0x1000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART3>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart4: serial@42580000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x42580000 0x1000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART4>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart5: serial@42590000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x42590000 0x1000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART5>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart6: serial@425a0000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x425a0000 0x1000>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART6>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart7: serial@42690000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x42690000 0x1000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART7>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart8: serial@426a0000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x426a0000 0x1000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART8>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpi2c5: i2c@426b0000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x426b0000 0x10000>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C5>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpi2c6: i2c@426c0000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x426c0000 0x10000>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C6>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpi2c7: i2c@426d0000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x426d0000 0x10000>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C7>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpi2c8: i2c@426e0000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x426e0000 0x10000>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C8>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpspi5: spi@426f0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x426f0000 0x10000>;
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI5>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpspi6: spi@42700000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x42700000 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI6>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpspi7: spi@42710000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x42710000 0x10000>;
+ interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI7>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpspi8: spi@42720000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x42720000 0x10000>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI8>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ mu8: mailbox@42730000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x42730000 0x10000>;
+ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+ };
+
+ aips3: bus@42800000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ reg = <0 0x42800000 0 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x42800000 0x0 0x42800000 0x800000>;
+
+ usdhc1: mmc@42850000 {
+ compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+ reg = <0x42850000 0x10000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+ <&scmi_clk IMX95_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&scmi_clk IMX95_CLK_USDHC1>;
+ assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <8>;
+ fsl,tuning-start-tap = <1>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ usdhc2: mmc@42860000 {
+ compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+ reg = <0x42860000 0x10000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+ <&scmi_clk IMX95_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&scmi_clk IMX95_CLK_USDHC2>;
+ assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <4>;
+ fsl,tuning-start-tap = <1>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ usdhc3: mmc@428b0000 {
+ compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+ reg = <0x428b0000 0x10000>;
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+ <&scmi_clk IMX95_CLK_USDHC3>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&scmi_clk IMX95_CLK_USDHC3>;
+ assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <4>;
+ fsl,tuning-start-tap = <1>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+ };
+
+ gpio2: gpio@43810000 {
+ compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x0 0x43810000 0x0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "gpio", "port";
+ gpio-ranges = <&scmi_iomuxc 0 4 32>;
+ };
+
+ gpio3: gpio@43820000 {
+ compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x0 0x43820000 0x0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "gpio", "port";
+ gpio-ranges = <&scmi_iomuxc 0 104 8>, <&scmi_iomuxc 8 74 18>,
+ <&scmi_iomuxc 26 42 2>, <&scmi_iomuxc 28 0 4>;
+ };
+
+ gpio4: gpio@43840000 {
+ compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x0 0x43840000 0x0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "gpio", "port";
+ gpio-ranges = <&scmi_iomuxc 0 46 28>, <&scmi_iomuxc 28 44 2>;
+ };
+
+ gpio5: gpio@43850000 {
+ compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x0 0x43850000 0x0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+ <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+ clock-names = "gpio", "port";
+ gpio-ranges = <&scmi_iomuxc 0 92 12>, <&scmi_iomuxc 12 36 6>;
+ };
+
+ aips1: bus@44000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ reg = <0x0 0x44000000 0x0 0x800000>;
+ ranges = <0x44000000 0x0 0x44000000 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mu1: mailbox@44220000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x44220000 0x10000>;
+ interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ tpm1: pwm@44310000 {
+ compatible = "fsl,imx7ulp-pwm";
+ reg = <0x44310000 0x1000>;
+ clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ tpm2: pwm@44320000 {
+ compatible = "fsl,imx7ulp-pwm";
+ reg = <0x44320000 0x1000>;
+ clocks = <&scmi_clk IMX95_CLK_TPM2>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ lpi2c1: i2c@44340000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x44340000 0x10000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C1>,
+ <&scmi_clk IMX95_CLK_BUSAON>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpi2c2: i2c@44350000 {
+ compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x44350000 0x10000>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPI2C2>,
+ <&scmi_clk IMX95_CLK_BUSAON>;
+ clock-names = "per", "ipg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ lpspi1: spi@44360000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x44360000 0x10000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI1>,
+ <&scmi_clk IMX95_CLK_BUSAON>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpspi2: spi@44370000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+ reg = <0x44370000 0x10000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPSPI2>,
+ <&scmi_clk IMX95_CLK_BUSAON>;
+ clock-names = "per", "ipg";
+ status = "disabled";
+ };
+
+ lpuart1: serial@44380000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x44380000 0x1000>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart2: serial@44390000 {
+ compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+ "fsl,imx7ulp-lpuart";
+ reg = <0x44390000 0x1000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_LPUART2>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ adc1: adc@44530000 {
+ compatible = "nxp,imx93-adc";
+ reg = <0x44530000 0x10000>;
+ interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_ADC>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ mu2: mailbox@445b0000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x445b0000 0x1000>;
+ ranges;
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #mbox-cells = <2>;
+
+ sram0: sram@445b1000 {
+ compatible = "mmio-sram";
+ reg = <0x445b1000 0x400>;
+ ranges = <0x0 0x445b1000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scmi_buf0: scmi-sram-section@0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0x80>;
+ };
+
+ scmi_buf1: scmi-sram-section@80 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x80 0x80>;
+ };
+ };
+
+ };
+
+ mu3: mailbox@445d0000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x445d0000 0x10000>;
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ mu4: mailbox@445f0000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x445f0000 0x10000>;
+ interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ mu6: mailbox@44630000 {
+ compatible = "fsl,imx95-mu";
+ reg = <0x44630000 0x10000>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+ };
+
+ mailbox@47320000 {
+ compatible = "fsl,imx95-mu-v2x";
+ reg = <0x0 0x47320000 0x0 0x10000>;
+ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ };
+
+ mailbox@47350000 {
+ compatible = "fsl,imx95-mu-v2x";
+ reg = <0x0 0x47350000 0x0 0x10000>;
+ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ };
+
+ /* GPIO1 is under exclusive control of System Manager */
+ gpio1: gpio@47400000 {
+ compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x0 0x47400000 0x0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&scmi_clk IMX95_CLK_M33>,
+ <&scmi_clk IMX95_CLK_M33>;
+ clock-names = "gpio", "port";
+ gpio-ranges = <&scmi_iomuxc 0 112 16>;
+ status = "disabled";
+ };
+
+ elemu0: mailbox@47520000 {
+ compatible = "fsl,imx95-mu-ele";
+ reg = <0x0 0x47520000 0x0 0x10000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ elemu1: mailbox@47530000 {
+ compatible = "fsl,imx95-mu-ele";
+ reg = <0x0 0x47530000 0x0 0x10000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ elemu2: mailbox@47540000 {
+ compatible = "fsl,imx95-mu-ele";
+ reg = <0x0 0x47540000 0x0 0x10000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ elemu3: mailbox@47550000 {
+ compatible = "fsl,imx95-mu-ele";
+ reg = <0x0 0x47550000 0x0 0x10000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ };
+
+ elemu4: mailbox@47560000 {
+ compatible = "fsl,imx95-mu-ele";
+ reg = <0x0 0x47560000 0x0 0x10000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ elemu5: mailbox@47570000 {
+ compatible = "fsl,imx95-mu-ele";
+ reg = <0x0 0x47570000 0x0 0x10000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ aips4: bus@49000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ reg = <0x0 0x49000000 0x0 0x800000>;
+ ranges = <0x49000000 0x0 0x49000000 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ smmu: iommu@490d0000 {
+ compatible = "arm,smmu-v3";
+ reg = <0x490d0000 0x100000>;
+ interrupts = <GIC_SPI 325 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 334 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 326 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+ };
+
+ pcie0: pcie@4c300000 {
+ compatible = "fsl,imx95-pcie";
+ reg = <0 0x4c300000 0 0x10000>,
+ <0 0x60100000 0 0xfe00000>,
+ <0 0x4c360000 0 0x10000>,
+ <0 0x4c340000 0 0x2000>;
+ reg-names = "dbi", "config", "atu", "app";
+ ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
+ <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <1>;
+ num-viewport = <8>;
+ interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
+ assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
+ assigned-clock-parents = <0>, <0>,
+ <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
+ power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+ fsl,max-link-speed = <3>;
+ status = "disabled";
+ };
+
+ pcie0_ep: pcie-ep@4c300000 {
+ compatible = "fsl,imx95-pcie-ep";
+ reg = <0 0x4c300000 0 0x10000>,
+ <0 0x4c360000 0 0x1000>,
+ <0 0x4c320000 0 0x1000>,
+ <0 0x4c340000 0 0x2000>,
+ <0 0x4c370000 0 0x10000>,
+ <0x9 0 1 0>;
+ reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space";
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
+ assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
+ assigned-clock-parents = <0>, <0>,
+ <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
+ power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+ status = "disabled";
+ };
+
+ pcie1: pcie@4c380000 {
+ compatible = "fsl,imx95-pcie";
+ reg = <0 0x4c380000 0 0x10000>,
+ <8 0x80100000 0 0xfe00000>,
+ <0 0x4c3e0000 0 0x10000>,
+ <0 0x4c3c0000 0 0x2000>;
+ reg-names = "dbi", "config", "atu", "app";
+ ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>,
+ <0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ linux,pci-domain = <1>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <1>;
+ num-viewport = <8>;
+ interrupts = <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic 0 0 GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic 0 0 GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic 0 0 GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
+ assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
+ assigned-clock-parents = <0>, <0>,
+ <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
+ power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+ fsl,max-link-speed = <3>;
+ status = "disabled";
+ };
+
+ pcie1_ep: pcie-ep@4c380000 {
+ compatible = "fsl,imx95-pcie-ep";
+ reg = <0 0x4c380000 0 0x10000>,
+ <0 0x4c3e0000 0 0x1000>,
+ <0 0x4c3a0000 0 0x1000>,
+ <0 0x4c3c0000 0 0x2000>,
+ <0 0x4c3f0000 0 0x10000>,
+ <0xa 0 1 0>;
+ reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
+ assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
+ assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
+ assigned-clock-parents = <0>, <0>,
+ <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
+ power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index 427467df42bf..815241526a0d 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -316,17 +316,11 @@
&mipi_dsi {
samsung,burst-clock-frequency = <891000000>;
samsung,esc-clock-frequency = <20000000>;
+};
- ports {
- port@1 {
- reg = <1>;
-
- mipi_dsi_out: endpoint {
- data-lanes = <1 2 3 4>;
- remote-endpoint = <&lvds_bridge_in>;
- };
- };
- };
+&mipi_dsi_out {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&lvds_bridge_in>;
};
&pwm3 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
index dbd2fc3ba790..65f7b5a50eb5 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
@@ -32,7 +32,7 @@ fman@1a00000 {
mdio@f1000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xf1000 0x1000>;
pcsphy6: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
index 6fc5d2560057..3f70482c98c3 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
@@ -32,7 +32,7 @@ fman@1a00000 {
mdio@f3000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xf3000 0x1000>;
pcsphy7: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi
index 4e02276fcf99..78841c1f3252 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi
@@ -31,7 +31,7 @@ fman@1a00000 {
mdio@e1000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xe1000 0x1000>;
pcsphy0: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi
index 0312fa43fa77..1f43fa666222 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi
@@ -31,7 +31,7 @@ fman@1a00000 {
mdio@e3000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xe3000 0x1000>;
pcsphy1: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi
index af2df07971dd..de0aa017701d 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi
@@ -31,7 +31,7 @@ fman@1a00000 {
mdio@e5000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xe5000 0x1000>;
pcsphy2: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi
index 4ac98dc8b227..6904aa5d8e54 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi
@@ -31,7 +31,7 @@ fman@1a00000 {
mdio@e7000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xe7000 0x1000>;
pcsphy3: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi
index bd932d8b0160..a3d29d470297 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi
@@ -31,7 +31,7 @@ fman@1a00000 {
mdio@e9000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xe9000 0x1000>;
pcsphy4: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi
index 7de1c5203f3e..01b78c0463a7 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi
@@ -31,7 +31,7 @@ fman@1a00000 {
mdio@eb000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xeb000 0x1000>;
pcsphy5: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
index ae1c2abaaf36..b0390b711fef 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
@@ -67,14 +67,14 @@ fman0: fman@1a00000 {
mdio0: mdio@fc000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xfc000 0x1000>;
};
xmdio0: mdio@fd000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ compatible = "fsl,fman-memac-mdio";
reg = <0xfd000 0x1000>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 5ac1cc9ff50e..fc19ae2e8d3b 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -3,7 +3,7 @@
* NXP S32G2 SoC family
*
* Copyright (c) 2021 SUSE LLC
- * Copyright (c) 2017-2021 NXP
+ * Copyright 2017-2021, 2024 NXP
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -14,6 +14,18 @@
#address-cells = <2>;
#size-cells = <2>;
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ scmi_buf: shm@d0000000 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0xd0000000 0x0 0x80>;
+ no-map;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -77,6 +89,19 @@
};
firmware {
+ scmi {
+ compatible = "arm,scmi-smc";
+ arm,smc-id = <0xc20000fe>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ shmem = <&scmi_buf>;
+
+ clks: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+ };
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -113,6 +138,16 @@
status = "disabled";
};
+ usdhc0: mmc@402f0000 {
+ compatible = "nxp,s32g2-usdhc";
+ reg = <0x402f0000 0x1000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 32>, <&clks 31>, <&clks 33>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <8>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@50800000 {
compatible = "arm,gic-v3";
reg = <0x50800000 0x10000>,
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
index 9118d8d2ee01..00070c949e2a 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
* Copyright (c) 2021 SUSE LLC
- * Copyright (c) 2019-2021 NXP
+ * Copyright 2019-2021, 2024 NXP
*/
/dts-v1/;
@@ -32,3 +32,7 @@
&uart0 {
status = "okay";
};
+
+&usdhc0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
index e05ee854cdf5..b3fc12899cae 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
* Copyright (c) 2021 SUSE LLC
- * Copyright (c) 2019-2021 NXP
+ * Copyright 2019-2021, 2024 NXP
*/
/dts-v1/;
@@ -38,3 +38,7 @@
&uart1 {
status = "okay";
};
+
+&usdhc0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
new file mode 100644
index 000000000000..c1b08992754b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2021-2023 NXP
+ *
+ * Authors: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
+ * Ciprian Costea <ciprianmarian.costea@nxp.com>
+ * Andra-Teodora Ilie <andra.ilie@nxp.com>
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "nxp,s32g3";
+ interrupt-parent = <&gic>;
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+
+ 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 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x2>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x3>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x100>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x101>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x102>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+
+ cpu7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x103>;
+ enable-method = "psci";
+ clocks = <&dfs 0>;
+ };
+ };
+
+ firmware {
+ scmi: scmi {
+ compatible = "arm,scmi-smc";
+ shmem = <&scmi_shmem>;
+ arm,smc-id = <0xc20000fe>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dfs: protocol@13 {
+ reg = <0x13>;
+ #clock-cells = <1>;
+ };
+
+ clks: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+ };
+
+ psci: psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+ };
+
+
+ pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ scmi_shmem: shm@d0000000 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0xd0000000 0x0 0x80>;
+ no-map;
+ };
+ };
+
+ soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x80000000>;
+
+ uart0: serial@401c8000 {
+ compatible = "nxp,s32g3-linflexuart",
+ "fsl,s32v234-linflexuart";
+ reg = <0x401c8000 0x3000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ uart1: serial@401cc000 {
+ compatible = "nxp,s32g3-linflexuart",
+ "fsl,s32v234-linflexuart";
+ reg = <0x401cc000 0x3000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ uart2: serial@402bc000 {
+ compatible = "nxp,s32g3-linflexuart",
+ "fsl,s32v234-linflexuart";
+ reg = <0x402bc000 0x3000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ usdhc0: mmc@402f0000 {
+ compatible = "nxp,s32g3-usdhc",
+ "nxp,s32g2-usdhc";
+ reg = <0x402f0000 0x1000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 32>,
+ <&clks 31>,
+ <&clks 33>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@50800000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x50800000 0x10000>,
+ <0x50900000 0x200000>,
+ <0x50400000 0x2000>,
+ <0x50410000 0x2000>,
+ <0x50420000 0x2000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* sec-phys */
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* phys */
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* virt */
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, /* hyp-phys */
+ <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; /* hyp-virt */
+ arm,no-tick-in-suspend;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
new file mode 100644
index 000000000000..9d674819876e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2021-2023 NXP
+ *
+ * NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)
+ */
+
+/dts-v1/;
+
+#include "s32g3.dtsi"
+
+/ {
+ model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
+ compatible = "nxp,s32g399a-rdb3", "nxp,s32g3";
+
+ aliases {
+ mmc0 = &usdhc0;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ /* 4GiB RAM */
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0 0x80000000>,
+ <0x8 0x80000000 0 0x80000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&usdhc0 {
+ bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/tqma8xx.dtsi b/arch/arm64/boot/dts/freescale/tqma8xx.dtsi
index d98469a7c47c..366912bf3d5e 100644
--- a/arch/arm64/boot/dts/freescale/tqma8xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/tqma8xx.dtsi
@@ -61,12 +61,16 @@
flash0: flash@0 {
reg = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "jedec,spi-nor";
spi-max-frequency = <66000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index 7e137a884ae5..957a1b41f19b 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -1161,7 +1161,7 @@
};
usb3_otg_bc: usb3_otg_bc@ff200000 {
- compatible = "syscon", "simple-mfd";
+ compatible = "hisilicon,hi3660-usb3-otg-bc", "syscon", "simple-mfd";
reg = <0x0 0xff200000 0x0 0x1000>;
usb_phy: usb-phy {
diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index ed1b5a7a6067..f6bc001c3832 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -31,6 +31,13 @@
device_type = "cpu";
reg = <0x0 0x0>;
enable-method = "psci";
+ d-cache-size = <0x8000>; /* 32 KiB */
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ i-cache-size = <0x8000>; /* 32 KiB */
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ next-level-cache = <&L2>;
};
cpu@1 {
@@ -38,6 +45,13 @@
device_type = "cpu";
reg = <0x0 0x1>;
enable-method = "psci";
+ d-cache-size = <0x8000>; /* 32 KiB */
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ i-cache-size = <0x8000>; /* 32 KiB */
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ next-level-cache = <&L2>;
};
cpu@2 {
@@ -45,6 +59,13 @@
device_type = "cpu";
reg = <0x0 0x2>;
enable-method = "psci";
+ d-cache-size = <0x8000>; /* 32 KiB */
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ i-cache-size = <0x8000>; /* 32 KiB */
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ next-level-cache = <&L2>;
};
cpu@3 {
@@ -52,13 +73,33 @@
device_type = "cpu";
reg = <0x0 0x3>;
enable-method = "psci";
+ d-cache-size = <0x8000>; /* 32 KiB */
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ i-cache-size = <0x8000>; /* 32 KiB */
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ next-level-cache = <&L2>;
};
};
+ L2: l2-cache {
+ compatible = "cache";
+ cache-unified;
+ cache-size = <0x80000>; /* 512 KiB */
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ cache-level = <2>;
+ };
+
gic: interrupt-controller@f1001000 {
compatible = "arm,gic-400";
reg = <0x0 0xf1001000 0x0 0x1000>, /* GICD */
- <0x0 0xf1002000 0x0 0x100>; /* GICC */
+ <0x0 0xf1002000 0x0 0x2000>, /* GICC */
+ <0x0 0xf1004000 0x0 0x2000>, /* GICH */
+ <0x0 0xf1006000 0x0 0x2000>; /* GICV */
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_HIGH)>;
#address-cells = <0>;
#interrupt-cells = <3>;
interrupt-controller;
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index f0672ec65b26..2d304efe081d 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -82,7 +82,7 @@
};
};
- reg_sys_5v: regulator@0 {
+ reg_sys_5v: regulator-0 {
compatible = "regulator-fixed";
regulator-name = "SYS_5V";
regulator-min-microvolt = <5000000>;
@@ -91,7 +91,7 @@
regulator-always-on;
};
- reg_vdd_3v3: regulator@1 {
+ reg_vdd_3v3: regulator-1 {
compatible = "regulator-fixed";
regulator-name = "VDD_3V3";
regulator-min-microvolt = <3300000>;
@@ -101,7 +101,7 @@
vin-supply = <&reg_sys_5v>;
};
- reg_5v_hub: regulator@2 {
+ reg_5v_hub: regulator-2 {
compatible = "regulator-fixed";
regulator-name = "5V_HUB";
regulator-min-microvolt = <5000000>;
@@ -514,6 +514,7 @@
#address-cells = <1>;
#size-cells = <0>;
port@0 {
+ reg = <0>;
adv7533_in: endpoint {
remote-endpoint = <&dsi_out0>;
};
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index be808bb2544e..a589954c29e2 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -852,7 +852,7 @@
clock-names = "wdog_clk", "apb_pclk";
};
- tsensor: tsensor@0,f7030700 {
+ tsensor: tsensor@f7030700 {
compatible = "hisilicon,tsensor";
reg = <0x0 0xf7030700 0x0 0x1000>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
index c4eaebbb448f..b7792d443189 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
+++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
@@ -54,7 +54,7 @@
ranges = <0 0 0x0 0x90000000 0x08000000>,
<1 0 0x0 0x98000000 0x08000000>;
- nor-flash@0,0 {
+ nor-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "numonyx,js28f00a", "cfi-flash";
@@ -75,7 +75,7 @@
};
};
- cpld@1,0 {
+ cpld@100000000 {
compatible = "hisilicon,hip05-cpld";
reg = <1 0x0 0x100>;
};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
index 65ddc0698f82..d0912ca5f237 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -279,6 +279,12 @@
};
};
+ refclk200mhz: refclk200mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
@@ -298,12 +304,6 @@
#size-cells = <2>;
ranges;
- refclk200mhz: refclk200mhz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-
uart0: serial@80300000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x80300000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index f46c33d10750..3d7285e6700e 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -258,6 +258,48 @@
};
};
+ eth2: ethernet-0 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <0>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth3: ethernet-1 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <1>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth0: ethernet-4 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <4>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth1: ethernet-5 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <5>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ refclk: refclk {
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ #clock-cells = <0>;
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
@@ -374,12 +416,6 @@
};
};
- refclk: refclk {
- compatible = "fixed-clock";
- clock-frequency = <50000000>;
- #clock-cells = <0>;
- };
-
usb_ohci: usb@a7030000 {
compatible = "generic-ohci";
reg = <0x0 0xa7030000 0x0 0x10000>;
@@ -436,7 +472,7 @@
};
};
- dsaf0: dsa@c7000000 {
+ dsaf0: dsa@c5000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "hisilicon,hns-dsaf-v2";
@@ -570,42 +606,6 @@
};
};
- eth0: ethernet-4 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <4>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
- eth1: ethernet-5 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <5>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
- eth2: ethernet-0 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <0>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
- eth3: ethernet-1 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <1>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
sas0: sas@c3000000 {
compatible = "hisilicon,hip06-sas-v2";
reg = <0 0xc3000000 0 0x10000>;
@@ -733,7 +733,7 @@
status = "disabled";
};
- pcie0: pcie@a0090000 {
+ pcie0: pcie@b0000000 {
compatible = "hisilicon,hip06-pcie-ecam";
reg = <0 0xb0000000 0 0x2000000>,
<0 0xa0090000 0 0x10000>;
diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
index 81d907ef43ed..00a6bfa7478c 100644
--- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
@@ -1013,6 +1013,42 @@
};
};
+ eth0: ethernet-0 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <4>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth1: ethernet-1 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <5>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth2: ethernet-2 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <0>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth3: ethernet-3 {
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <1>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
@@ -1343,7 +1379,7 @@
};
};
- dsaf0: dsa@c7000000 {
+ dsaf0: dsa@c5000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "hisilicon,hns-dsaf-v2";
@@ -1483,42 +1519,6 @@
};
};
- eth0: ethernet@4 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <4>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
- eth1: ethernet@5 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <5>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
- eth2: ethernet@0 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <0>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
- eth3: ethernet@1 {
- compatible = "hisilicon,hns-nic-v2";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <1>;
- local-mac-address = [00 00 00 00 00 00];
- status = "disabled";
- dma-coherent;
- };
-
infiniband@c4000000 {
compatible = "hisilicon,hns-roce-v1";
reg = <0x0 0xc4000000 0x0 0x100000>;
@@ -1724,7 +1724,7 @@
status = "disabled";
};
- p0_pcie2_a: pcie@a00a0000 {
+ p0_pcie2_a: pcie@af800000 {
compatible = "hisilicon,hip07-pcie-ecam";
reg = <0 0xaf800000 0 0x800000>,
<0 0xa00a0000 0 0x10000>;
@@ -1745,7 +1745,7 @@
0x0 0 0 4 &mbigen_pcie2_a 671 4>;
status = "disabled";
};
- p0_sec_a: crypto@d2000000 {
+ p0_sec_a: crypto@d0000000 {
compatible = "hisilicon,hip07-sec";
reg = <0x0 0xd0000000 0x0 0x10000>,
<0x0 0xd2000000 0x0 0x10000>,
@@ -1786,7 +1786,7 @@
<605 1>, <606 4>,
<607 1>, <608 4>;
};
- p0_sec_b: crypto@8,d2000000 {
+ p0_sec_b: crypto@8d0000000 {
compatible = "hisilicon,hip07-sec";
reg = <0x8 0xd0000000 0x0 0x10000>,
<0x8 0xd2000000 0x0 0x10000>,
@@ -1827,7 +1827,7 @@
<605 1>, <606 4>,
<607 1>, <608 4>;
};
- p1_sec_a: crypto@400,d2000000 {
+ p1_sec_a: crypto@400d0000000 {
compatible = "hisilicon,hip07-sec";
reg = <0x400 0xd0000000 0x0 0x10000>,
<0x400 0xd2000000 0x0 0x10000>,
@@ -1868,7 +1868,7 @@
<605 1>, <606 4>,
<607 1>, <608 4>;
};
- p1_sec_b: crypto@408,d2000000 {
+ p1_sec_b: crypto@408d0000000 {
compatible = "hisilicon,hip07-sec";
reg = <0x408 0xd0000000 0x0 0x10000>,
<0x408 0xd2000000 0x0 0x10000>,
diff --git a/arch/arm64/boot/dts/intel/keembay-soc.dtsi b/arch/arm64/boot/dts/intel/keembay-soc.dtsi
index 781761d2942b..ae00e9e54e82 100644
--- a/arch/arm64/boot/dts/intel/keembay-soc.dtsi
+++ b/arch/arm64/boot/dts/intel/keembay-soc.dtsi
@@ -70,7 +70,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_PPI 0x7 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
index 76aafa172eb0..2a5eeb21da47 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
@@ -80,7 +80,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
index ad99aefeb185..b31cfa6b802d 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
@@ -106,8 +106,6 @@
&qspi {
status = "okay";
flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "micron,mt25qu02g", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <100000000>;
diff --git a/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts
index 2d70a92c2090..7952c7f47cc2 100644
--- a/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts
+++ b/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts
@@ -83,8 +83,6 @@
&qspi {
status = "okay";
flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "micron,mt25qu02g", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <100000000>;
diff --git a/arch/arm64/boot/dts/lg/lg1312-ref.dts b/arch/arm64/boot/dts/lg/lg1312-ref.dts
index 260a2c5b19e5..cdd10f138098 100644
--- a/arch/arm64/boot/dts/lg/lg1312-ref.dts
+++ b/arch/arm64/boot/dts/lg/lg1312-ref.dts
@@ -22,7 +22,7 @@
serial2 = &uart2;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x00000000 0x20000000>;
};
diff --git a/arch/arm64/boot/dts/lg/lg1313-ref.dts b/arch/arm64/boot/dts/lg/lg1313-ref.dts
index e89ae853788a..6ace977ff4cf 100644
--- a/arch/arm64/boot/dts/lg/lg1313-ref.dts
+++ b/arch/arm64/boot/dts/lg/lg1313-ref.dts
@@ -22,7 +22,7 @@
serial2 = &uart2;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x00000000 0x20000000>;
};
diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile
index 99b8cb3c49e1..ce751b5028e2 100644
--- a/arch/arm64/boot/dts/marvell/Makefile
+++ b/arch/arm64/boot/dts/marvell/Makefile
@@ -28,3 +28,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += cn9130-crb-A.dtb
dtb-$(CONFIG_ARCH_MVEBU) += cn9130-crb-B.dtb
dtb-$(CONFIG_ARCH_MVEBU) += ac5x-rd-carrier-cn9131.dtb
dtb-$(CONFIG_ARCH_MVEBU) += ac5-98dx35xx-rd.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9130-cf-base.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9130-cf-pro.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9131-cf-solidwan.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9132-clearfog.dtb
diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
index 5591939e057b..75377c292bcb 100644
--- a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
@@ -68,7 +68,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts b/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
index d6d37a1f6f38..91c2f8b4edfa 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
@@ -25,8 +25,6 @@
/* Actual device is MV88E6361 */
switch: switch@0 {
compatible = "marvell,mv88e6190";
- #address-cells = <1>;
- #size-cells = <0>;
reg = <0>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts
index 870bb380a40a..b3cc2b7b5d19 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts
@@ -114,54 +114,84 @@
};
&mdio {
+ /* Switch is @3, not @1 */
+ /delete-node/ ethernet-switch@1;
extphy: ethernet-phy@1 {
reg = <1>;
reset-gpios = <&gpionb 2 GPIO_ACTIVE_LOW>;
};
-};
-&switch0 {
- reg = <3>;
+ switch0: ethernet-switch@3 {
+ compatible = "marvell,mv88e6085";
+ reg = <3>;
- reset-gpios = <&gpiosb 23 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpiosb 23 GPIO_ACTIVE_LOW>;
+ dsa,member = <0 0>;
- ethernet-ports {
- switch0port1: ethernet-port@1 {
- reg = <1>;
- label = "lan0";
- phy-handle = <&switch0phy0>;
- };
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch0port0: ethernet-port@0 {
+ reg = <0>;
+ label = "cpu";
+ ethernet = <&eth0>;
+ phy-mode = "rgmii-id";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
- switch0port2: ethernet-port@2 {
- reg = <2>;
- label = "lan1";
- phy-handle = <&switch0phy1>;
- };
+ switch0port1: ethernet-port@1 {
+ reg = <1>;
+ label = "lan0";
+ phy-handle = <&switch0phy0>;
+ };
- switch0port3: ethernet-port@3 {
- reg = <3>;
- label = "lan2";
- phy-handle = <&switch0phy2>;
- };
+ switch0port2: ethernet-port@2 {
+ reg = <2>;
+ label = "lan1";
+ phy-handle = <&switch0phy1>;
+ };
- switch0port4: ethernet-port@4 {
- reg = <4>;
- label = "lan3";
- phy-handle = <&switch0phy3>;
- };
+ switch0port3: ethernet-port@3 {
+ reg = <3>;
+ label = "lan2";
+ phy-handle = <&switch0phy2>;
+ };
- switch0port5: ethernet-port@5 {
- reg = <5>;
- label = "wan";
- phy-handle = <&extphy>;
- phy-mode = "sgmii";
+ switch0port4: ethernet-port@4 {
+ reg = <4>;
+ label = "lan3";
+ phy-handle = <&switch0phy3>;
+ };
+
+ switch0port5: ethernet-port@5 {
+ reg = <5>;
+ label = "wan";
+ phy-handle = <&extphy>;
+ phy-mode = "sgmii";
+ };
};
- };
- mdio {
- switch0phy3: ethernet-phy@14 {
- reg = <0x14>;
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch0phy0: ethernet-phy@11 {
+ reg = <0x11>;
+ };
+ switch0phy1: ethernet-phy@12 {
+ reg = <0x12>;
+ };
+ switch0phy2: ethernet-phy@13 {
+ reg = <0x13>;
+ };
+ switch0phy3: ethernet-phy@14 {
+ reg = <0x14>;
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts b/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
index 63fbc8352161..56930f2ce481 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
@@ -41,7 +41,7 @@
keys {
compatible = "gpio-keys";
- reset {
+ button-reset {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&gpionb 14 GPIO_ACTIVE_LOW>;
@@ -57,17 +57,17 @@
leds {
compatible = "gpio-leds";
- vpn {
+ led-vpn {
label = "green:vpn";
gpios = <&gpionb 11 GPIO_ACTIVE_LOW>;
};
- wan {
+ led-wan {
label = "green:wan";
gpios = <&gpionb 12 GPIO_ACTIVE_LOW>;
};
- led_power: power {
+ led_power: led-power {
label = "green:power";
gpios = <&gpionb 13 GPIO_ACTIVE_LOW>;
default-state = "on";
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index f1a9f2234359..54453b0a91f9 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -216,8 +216,6 @@
assigned-clock-rates = <20000000>;
flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <20000000>;
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 1cc3fa1c354d..9603223dd761 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -68,7 +68,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi b/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi
index 7ec7c789d87e..fdf88cd0eb02 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi
@@ -61,7 +61,7 @@
compatible = "simple-bus";
ranges = <0x0 0x0 0xf0000000 0x1000000>;
- smmu: iommu@5000000 {
+ smmu: iommu@100000 {
compatible = "marvell,ap806-smmu-500", "arm,mmu-500";
reg = <0x100000 0x100000>;
dma-coherent;
diff --git a/arch/arm64/boot/dts/marvell/cn9130-cf-base.dts b/arch/arm64/boot/dts/marvell/cn9130-cf-base.dts
new file mode 100644
index 000000000000..788a5c302b17
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9130-cf-base.dts
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ * DTS for SolidRun CN9130 Clearfog Base.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "cn9130.dtsi"
+#include "cn9130-sr-som.dtsi"
+#include "cn9130-cf.dtsi"
+
+/ {
+ model = "SolidRun CN9130 Clearfog Base";
+ compatible = "solidrun,cn9130-clearfog-base",
+ "solidrun,cn9130-sr-som", "marvell,cn9130";
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&rear_button_pins>;
+ pinctrl-names = "default";
+
+ button-0 {
+ /* The rear SW3 button */
+ label = "Rear Button";
+ gpios = <&cp0_gpio1 31 GPIO_ACTIVE_LOW>;
+ linux,can-disable;
+ linux,code = <BTN_0>;
+ };
+ };
+
+ rfkill-m2-gnss {
+ compatible = "rfkill-gpio";
+ label = "m.2 GNSS";
+ radio-type = "gps";
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&expander0 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* M.2 is B-keyed, so w-disable is for WWAN */
+ rfkill-m2-wwan {
+ compatible = "rfkill-gpio";
+ label = "m.2 WWAN";
+ radio-type = "wwan";
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&expander0 8 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+/* SRDS #3 - SGMII 1GE */
+&cp0_eth1 {
+ phy = <&phy1>;
+ phys = <&cp0_comphy3 1>;
+ phy-mode = "sgmii";
+ status = "okay";
+};
+
+&cp0_eth2_phy {
+ /*
+ * Configure LEDs default behaviour:
+ * - LED[0]: link/activity: On/blink (green)
+ * - LED[1]: link is 100/1000Mbps: On (yellow)
+ * - LED[2]: high impedance (floating)
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a61>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+ };
+};
+
+&cp0_gpio1 {
+ sim-select-hog {
+ gpio-hog;
+ gpios = <27 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "sim-select";
+ };
+};
+
+&cp0_mdio {
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ /*
+ * Configure LEDs default behaviour:
+ * - LED[0]: link/activity: On/blink (green)
+ * - LED[1]: link is 100/1000Mbps: On (yellow)
+ * - LED[2]: high impedance (floating)
+ *
+ * Configure LEDs electrical polarity
+ * - on-state: low
+ * - off-state: high (not hi-z, to avoid residual glow)
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a61>,
+ <3 17 0x003f 0x000a>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+};
+
+&cp0_pinctrl {
+ pinctrl-0 = <&sim_select_pins>;
+ pintrl-names = "default";
+
+ rear_button_pins: cp0-rear-button-pins {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ sim_select_pins: cp0-sim-select-pins {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+};
+
+/*
+ * SRDS #4 - USB 3.0 host on M.2 connector
+ * USB-2.0 Host on Type-A connector
+ */
+&cp0_usb3_1 {
+ phys = <&cp0_comphy4 1>, <&cp0_utmi1>;
+ phy-names = "comphy", "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&expander0 {
+ m2-full-card-power-off-hog {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "m2-full-card-power-off";
+ };
+
+ m2-reset-hog {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "m2-reset";
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-cf-pro.dts b/arch/arm64/boot/dts/marvell/cn9130-cf-pro.dts
new file mode 100644
index 000000000000..a27fe0042867
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9130-cf-pro.dts
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ * DTS for SolidRun CN9130 Clearfog Pro.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "cn9130.dtsi"
+#include "cn9130-sr-som.dtsi"
+#include "cn9130-cf.dtsi"
+
+/ {
+ model = "SolidRun CN9130 Clearfog Pro";
+ compatible = "solidrun,cn9130-clearfog-pro",
+ "solidrun,cn9130-sr-som", "marvell,cn9130";
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&rear_button_pins>;
+ pinctrl-names = "default";
+
+ button-0 {
+ /* The rear SW3 button */
+ label = "Rear Button";
+ gpios = <&cp0_gpio2 0 GPIO_ACTIVE_LOW>;
+ linux,can-disable;
+ linux,code = <BTN_0>;
+ };
+ };
+};
+
+/* SRDS #3 - SGMII 1GE to L2 switch */
+&cp0_eth1 {
+ phys = <&cp0_comphy3 1>;
+ phy-mode = "sgmii";
+ status = "okay";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&cp0_eth2_phy {
+ /*
+ * Configure LEDs default behaviour similar to switch ports:
+ * - LED[0]: link/activity: On/blink (green)
+ * - LED[1]: link is 100/1000Mbps: On (red)
+ * - LED[2]: high impedance (floating)
+ *
+ * Switch port defaults:
+ * - LED0: link/activity: On/blink (green)
+ * - LED1: link is 1000Mbps: On (red)
+ *
+ * Identical configuration is impossible with hardware offload.
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a61>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ label = "LED2";
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WAN;
+ label = "LED1";
+ default-state = "keep";
+ };
+ };
+};
+
+&cp0_mdio {
+ ethernet-switch@4 {
+ compatible = "marvell,mv88e6085";
+ reg = <4>;
+ pinctrl-0 = <&dsa_clk_pins &dsa_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&cp0_gpio1 27 GPIO_ACTIVE_LOW>;
+ interrupt-parent = <&cp0_gpio1>;
+ interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-port@0 {
+ reg = <0>;
+ label = "lan5";
+ phy = <&switch0phy0>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ label = "LED12";
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_LAN;
+ label = "LED11";
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@1 {
+ reg = <1>;
+ label = "lan4";
+ phy = <&switch0phy1>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ label = "LED10";
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_LAN;
+ label = "LED9";
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@2 {
+ reg = <2>;
+ label = "lan3";
+ phy = <&switch0phy2>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ label = "LED8";
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_LAN;
+ label = "LED7";
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@3 {
+ reg = <3>;
+ label = "lan2";
+ phy = <&switch0phy3>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ label = "LED6";
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_LAN;
+ label = "LED5";
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@4 {
+ reg = <4>;
+ label = "lan1";
+ phy = <&switch0phy4>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ label = "LED4";
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_LAN;
+ label = "LED3";
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@5 {
+ reg = <5>;
+ label = "cpu";
+ ethernet = <&cp0_eth1>;
+ phy-mode = "sgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ ethernet-port@6 {
+ reg = <6>;
+ label = "lan6";
+ phy-mode = "rgmii";
+
+ /*
+ * Because of mdio address conflict the
+ * external phy is not readable.
+ * Force a fixed link instead.
+ */
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch0phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ switch0phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ /*
+ * Indirectly configure default behaviour
+ * for port lan6 leds behind external phy.
+ * Internal PHYs are not using page 3,
+ * therefore writing to it is safe.
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a61>;
+ };
+
+ switch0phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ switch0phy3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+
+ switch0phy4: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+ };
+
+ /*
+ * There is an external phy on the switch mdio bus.
+ * Because its mdio address collides with internal phys,
+ * it is not readable.
+ *
+ * mdio-external {
+ * compatible = "marvell,mv88e6xxx-mdio-external";
+ * #address-cells = <1>;
+ * #size-cells = <0>;
+ *
+ * ethernet-phy@1 {
+ * reg = <0x1>;
+ * };
+ * };
+ */
+ };
+};
+
+/* SRDS #4 - miniPCIe (CON2) */
+&cp0_pcie1 {
+ num-lanes = <1>;
+ phys = <&cp0_comphy4 1>;
+ /* dw-pcie inverts internally */
+ reset-gpios = <&expander0 2 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&cp0_pinctrl {
+ dsa_clk_pins: cp0-dsa-clk-pins {
+ marvell,pins = "mpp40";
+ marvell,function = "synce1";
+ };
+
+ dsa_pins: cp0-dsa-pins {
+ marvell,pins = "mpp27", "mpp29";
+ marvell,function = "gpio";
+ };
+
+ rear_button_pins: cp0-rear-button-pins {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+
+ cp0_spi1_cs1_pins: cp0-spi1-cs1-pins {
+ marvell,pins = "mpp12";
+ marvell,function = "spi1";
+ };
+};
+
+&cp0_spi1 {
+ /* add pin for chip-select 1 on mikrobus */
+ pinctrl-0 = <&cp0_spi1_pins &cp0_spi1_cs1_pins>;
+};
+
+/* USB-2.0 Host on Type-A connector */
+&cp0_usb3_1 {
+ phys = <&cp0_utmi1>;
+ phy-names = "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&expander0 {
+ /* CON2 */
+ pcie1-0-clkreq-hog {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "pcie1.0-clkreq";
+ };
+
+ /* CON2 */
+ pcie1-0-w-disable-hog {
+ gpio-hog;
+ gpios = <7 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "pcie1.0-w-disable";
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-cf.dtsi b/arch/arm64/boot/dts/marvell/cn9130-cf.dtsi
new file mode 100644
index 000000000000..ad0ab34b6602
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9130-cf.dtsi
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ * DTS for common base of SolidRun CN9130 Clearfog Base and Pro.
+ *
+ */
+
+/ {
+ aliases {
+ /* label nics same order as armada 388 clearfog */
+ ethernet0 = &cp0_eth2;
+ ethernet1 = &cp0_eth1;
+ ethernet2 = &cp0_eth0;
+ i2c1 = &cp0_i2c1;
+ mmc1 = &cp0_sdhci0;
+ };
+
+ reg_usb3_vbus0: regulator-usb3-vbus0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbus0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpios = <&expander0 6 GPIO_ACTIVE_LOW>;
+ };
+
+ sfp: sfp {
+ compatible = "sff,sfp";
+ i2c-bus = <&cp0_i2c1>;
+ los-gpios = <&expander0 12 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&expander0 15 GPIO_ACTIVE_LOW>;
+ tx-disable-gpios = <&expander0 14 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&expander0 13 GPIO_ACTIVE_HIGH>;
+ maximum-power-milliwatt = <2000>;
+ };
+};
+
+/* SRDS #2 - SFP+ 10GE */
+&cp0_eth0 {
+ managed = "in-band-status";
+ phys = <&cp0_comphy2 0>;
+ phy-mode = "10gbase-r";
+ sfp = <&sfp>;
+ status = "okay";
+};
+
+&cp0_i2c0 {
+ expander0: gpio-expander@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-0 = <&expander0_pins>;
+ pinctrl-names = "default";
+ interrupt-parent = <&cp0_gpio1>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+
+ /* CON3 */
+ pcie2-0-clkreq-hog {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "pcie2.0-clkreq";
+ };
+
+ /* CON3 */
+ pcie2-0-w-disable-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "pcie2.0-w-disable";
+ };
+
+ usb3-ilimit-hog {
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "usb3-current-limit";
+ };
+
+ m2-devslp-hog {
+ gpio-hog;
+ gpios = <11 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "m.2 devslp";
+ };
+ };
+
+ /* The MCP3021 supports standard and fast modes */
+ adc@4c {
+ compatible = "microchip,mcp3021";
+ reg = <0x4c>;
+ };
+
+ carrier_eeprom: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <8>;
+ };
+};
+
+&cp0_i2c1 {
+ /*
+ * Routed to SFP, M.2, mikrobus, and miniPCIe
+ * SFP limits this to 100kHz, and requires an AT24C01A/02/04 with
+ * address pins tied low, which takes addresses 0x50 and 0x51.
+ * Mikrobus doesn't specify beyond an I2C bus being present.
+ * PCIe uses ARP to assign addresses, or 0x63-0x64.
+ */
+ clock-frequency = <100000>;
+ pinctrl-0 = <&cp0_i2c1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+/* SRDS #5 - miniPCIe (CON3) */
+&cp0_pcie2 {
+ num-lanes = <1>;
+ phys = <&cp0_comphy5 2>;
+ /* dw-pcie inverts internally */
+ reset-gpios = <&expander0 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&cp0_pinctrl {
+ cp0_i2c1_pins: cp0-i2c1-pins {
+ marvell,pins = "mpp35", "mpp36";
+ marvell,function = "i2c1";
+ };
+
+ cp0_mmc0_pins: cp0-mmc0-pins {
+ marvell,pins = "mpp43", "mpp56", "mpp57", "mpp58",
+ "mpp59", "mpp60", "mpp61";
+ marvell,function = "sdio";
+ };
+
+ mikro_spi_pins: cp0-spi1-cs1-pins {
+ marvell,pins = "mpp12";
+ marvell,function = "spi1";
+ };
+
+ mikro_uart_pins: cp0-uart-pins {
+ marvell,pins = "mpp2", "mpp3";
+ marvell,function = "uart1";
+ };
+
+ expander0_pins: cp0-expander0-pins {
+ marvell,pins = "mpp4";
+ marvell,function = "gpio";
+ };
+};
+
+/* SRDS #0 - SATA on M.2 connector */
+&cp0_sata0 {
+ phys = <&cp0_comphy0 1>;
+ status = "okay";
+
+ /* only port 1 is available */
+ /delete-node/ sata-port@0;
+};
+
+/* microSD */
+&cp0_sdhci0 {
+ pinctrl-0 = <&cp0_mmc0_pins>;
+ pinctrl-names = "default";
+ bus-width = <4>;
+ no-1-8-v;
+ status = "okay";
+};
+
+&cp0_spi1 {
+ /* CS1 for mikrobus */
+ pinctrl-0 = <&cp0_spi1_pins &mikro_spi_pins>;
+};
+
+/*
+ * SRDS #1 - USB-3.0 Host on Type-A connector
+ * USB-2.0 Host on mPCI-e connector (CON3)
+ */
+&cp0_usb3_0 {
+ phys = <&cp0_comphy1 0>, <&cp0_utmi0>;
+ phy-names = "comphy", "utmi";
+ vbus-supply = <&reg_usb3_vbus0>;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&cp0_utmi {
+ status = "okay";
+};
+
+/* mikrobus uart */
+&cp0_uart0 {
+ pinctrl-0 = <&mikro_uart_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
index 6fcc34f7b464..5e7d6de3cdde 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
@@ -26,7 +26,7 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
- ap0_reg_mmc_vccq: ap0_mmc_vccq@0 {
+ ap0_reg_mmc_vccq: regulator-1 {
compatible = "regulator-gpio";
regulator-name = "ap0_mmc_vccq";
regulator-min-microvolt = <1800000>;
@@ -36,7 +36,7 @@
3300000 0x0>;
};
- cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 {
+ cp0_reg_usb3_vbus1: regulator-2 {
compatible = "regulator-fixed";
regulator-name = "cp0-xhci1-vbus";
regulator-min-microvolt = <5000000>;
@@ -45,16 +45,16 @@
gpio = <&expander0 8 GPIO_ACTIVE_HIGH>;
};
- cp0_usb3_0_phy0: cp0_usb3_phy0 {
+ cp0_usb3_0_phy0: usb-phy-1 {
compatible = "usb-nop-xceiv";
};
- cp0_usb3_0_phy1: cp0_usb3_phy1 {
+ cp0_usb3_0_phy1: usb-phy-2 {
compatible = "usb-nop-xceiv";
vcc-supply = <&cp0_reg_usb3_vbus1>;
};
- cp0_reg_sd_vccq: cp0_sd_vccq@0 {
+ cp0_reg_sd_vccq: regulator-3 {
compatible = "regulator-gpio";
regulator-name = "cp0_sd_vccq";
regulator-min-microvolt = <1800000>;
@@ -64,7 +64,7 @@
3300000 0x0>;
};
- cp0_reg_sd_vcc: cp0_sd_vcc@0 {
+ cp0_reg_sd_vcc: regulator-4 {
compatible = "regulator-fixed";
regulator-name = "cp0_sd_vcc";
regulator-min-microvolt = <3300000>;
@@ -82,7 +82,6 @@
tx-disable-gpios = <&expander0 2 GPIO_ACTIVE_HIGH>;
tx-fault-gpios = <&cp0_gpio1 24 GPIO_ACTIVE_HIGH>;
maximum-power-milliwatt = <3000>;
- status = "okay";
};
};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
index 6eb6a175de38..be56a2336265 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
@@ -30,7 +30,7 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
- ap0_reg_sd_vccq: ap0_sd_vccq@0 {
+ ap0_reg_sd_vccq: regulator-1 {
compatible = "regulator-gpio";
regulator-name = "ap0_sd_vccq";
regulator-min-microvolt = <1800000>;
@@ -39,7 +39,7 @@
states = <1800000 0x1 3300000 0x0>;
};
- cp0_reg_usb3_vbus0: cp0_usb3_vbus@0 {
+ cp0_reg_usb3_vbus0: regulator-2 {
compatible = "regulator-fixed";
regulator-name = "cp0-xhci0-vbus";
regulator-min-microvolt = <5000000>;
@@ -48,12 +48,12 @@
gpio = <&expander0 0 GPIO_ACTIVE_HIGH>;
};
- cp0_usb3_0_phy0: cp0_usb3_phy@0 {
+ cp0_usb3_0_phy0: usb-phy-1 {
compatible = "usb-nop-xceiv";
vcc-supply = <&cp0_reg_usb3_vbus0>;
};
- cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 {
+ cp0_reg_usb3_vbus1: regulator-3 {
compatible = "regulator-fixed";
regulator-name = "cp0-xhci1-vbus";
regulator-min-microvolt = <5000000>;
@@ -62,12 +62,12 @@
gpio = <&expander0 1 GPIO_ACTIVE_HIGH>;
};
- cp0_usb3_0_phy1: cp0_usb3_phy@1 {
+ cp0_usb3_0_phy1: usb-phy-2 {
compatible = "usb-nop-xceiv";
vcc-supply = <&cp0_reg_usb3_vbus1>;
};
- cp0_reg_sd_vccq: cp0_sd_vccq@0 {
+ cp0_reg_sd_vccq: regulator-4 {
compatible = "regulator-gpio";
regulator-name = "cp0_sd_vccq";
regulator-min-microvolt = <1800000>;
@@ -77,7 +77,7 @@
3300000 0x0>;
};
- cp0_reg_sd_vcc: cp0_sd_vcc@0 {
+ cp0_reg_sd_vcc: regulator-5 {
compatible = "regulator-fixed";
regulator-name = "cp0_sd_vcc";
regulator-min-microvolt = <3300000>;
@@ -87,7 +87,7 @@
regulator-always-on;
};
- cp0_sfp_eth0: sfp-eth@0 {
+ cp0_sfp_eth0: sfp-eth-1 {
compatible = "sff,sfp";
i2c-bus = <&cp0_sfpp0_i2c>;
los-gpios = <&cp0_module_expander1 11 GPIO_ACTIVE_HIGH>;
@@ -311,8 +311,6 @@
reg = <0x700680 0x50>;
flash@0 {
- #address-cells = <0x1>;
- #size-cells = <0x1>;
compatible = "jedec,spi-nor";
reg = <0x0>;
/* On-board MUX does not allow higher frequencies */
diff --git a/arch/arm64/boot/dts/marvell/cn9130-sr-som.dtsi b/arch/arm64/boot/dts/marvell/cn9130-sr-som.dtsi
new file mode 100644
index 000000000000..4676e3488f54
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9130-sr-som.dtsi
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "SolidRun CN9130 SoM";
+ compatible = "solidrun,cn9130-sr-som", "marvell,cn9130";
+
+ aliases {
+ ethernet0 = &cp0_eth0;
+ ethernet1 = &cp0_eth1;
+ ethernet2 = &cp0_eth2;
+ i2c0 = &cp0_i2c0;
+ mmc0 = &ap_sdhci0;
+ rtc0 = &cp0_rtc;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ v_1_8: regulator-1-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ /* requires assembly of R9307 */
+ vhv: regulator-vhv-1-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vhv-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ pinctrl-0 = <&cp0_reg_vhv_pins>;
+ pinctrl-names = "default";
+ gpios = <&cp0_gpio2 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&ap_pinctrl {
+ ap_mmc0_pins: ap-mmc0-pins {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3", "mpp4", "mpp5",
+ "mpp6", "mpp7", "mpp8", "mpp9", "mpp10", "mpp12";
+ marvell,function = "sdio";
+ /*
+ * mpp12 is emmc reset, function should be sdio (hw_rst),
+ * but pinctrl-mvebu does not support this.
+ *
+ * From pinctrl-mvebu.h:
+ * "The name will be used to switch to this setting in DT description, e.g.
+ * marvell,function = "uart2". subname is only for debugging purposes."
+ */
+ };
+};
+
+&ap_sdhci0 {
+ bus-width = <8>;
+ pinctrl-0 = <&ap_mmc0_pins>;
+ pinctrl-names = "default";
+ vqmmc-supply = <&v_1_8>;
+ status = "okay";
+};
+
+&cp0_ethernet {
+ status = "okay";
+};
+
+/* for assembly with phy */
+&cp0_eth2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_eth2_pins>;
+ phy-mode = "rgmii-id";
+ phy = <&cp0_eth2_phy>;
+ status = "okay";
+};
+
+&cp0_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_i2c0_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ som_eeprom: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <8>;
+ };
+};
+
+&cp0_mdio {
+ pinctrl-0 = <&cp0_mdio_pins>;
+ status = "okay";
+
+ /* assembly option */
+ cp0_eth2_phy: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&cp0_spi1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_spi1_pins>;
+ /* max speed limited by a mux */
+ spi-max-frequency = <1800000000>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ /* read command supports max. 50MHz */
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&cp0_syscon0 {
+ cp0_pinctrl: pinctrl {
+ compatible = "marvell,cp115-standalone-pinctrl";
+
+ cp0_eth2_pins: cp0-ge2-rgmii-pins {
+ marvell,pins = "mpp44", "mpp45", "mpp46", "mpp47",
+ "mpp48", "mpp49", "mpp50", "mpp51",
+ "mpp52", "mpp53", "mpp54", "mpp55";
+ /* docs call it "ge2", but cp110-pinctrl "ge1" */
+ marvell,function = "ge1";
+ };
+
+ cp0_i2c0_pins: cp0-i2c0-pins {
+ marvell,pins = "mpp37", "mpp38";
+ marvell,function = "i2c0";
+ };
+
+ cp0_mdio_pins: cp0-mdio-pins {
+ marvell,pins = "mpp40", "mpp41";
+ marvell,function = "ge";
+ };
+
+ cp0_spi1_pins: cp0-spi1-pins {
+ marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+ marvell,function = "spi1";
+ };
+
+ cp0_reg_vhv_pins: cp0-reg-vhv-pins {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ };
+};
+
+/* AP default console */
+&uart0 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9131-cf-solidwan.dts b/arch/arm64/boot/dts/marvell/cn9131-cf-solidwan.dts
new file mode 100644
index 000000000000..b1ea7dcaed17
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9131-cf-solidwan.dts
@@ -0,0 +1,637 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ * DTS for SolidRun CN9130 Clearfog Base.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "cn9130.dtsi"
+#include "cn9130-sr-som.dtsi"
+
+/*
+ * Instantiate the external CP115
+ */
+
+#define CP11X_NAME cp1
+#define CP11X_BASE f4000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE f4600000
+#define CP11X_PCIE1_BASE f4620000
+#define CP11X_PCIE2_BASE f4640000
+
+#include "armada-cp115.dtsi"
+
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
+
+/ {
+ model = "SolidRun CN9131 SolidWAN";
+ compatible = "solidrun,cn9131-solidwan",
+ "solidrun,cn9130-sr-som", "marvell,cn9130";
+
+ aliases {
+ ethernet0 = &cp1_eth1;
+ ethernet1 = &cp1_eth2;
+ ethernet2 = &cp0_eth1;
+ ethernet3 = &cp0_eth2;
+ ethernet4 = &cp0_eth0;
+ ethernet5 = &cp1_eth0;
+ gpio0 = &ap_gpio;
+ gpio1 = &cp0_gpio1;
+ gpio2 = &cp0_gpio2;
+ gpio3 = &cp1_gpio1;
+ gpio4 = &cp1_gpio2;
+ gpio5 = &expander0;
+ i2c0 = &cp0_i2c0;
+ i2c1 = &cp0_i2c1;
+ i2c2 = &cp1_i2c1;
+ mmc0 = &ap_sdhci0;
+ mmc1 = &cp0_sdhci0;
+ rtc0 = &cp0_rtc;
+ rtc1 = &carrier_rtc;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_led_pins &cp1_led_pins>;
+
+ /* for sfp-1 (J42) */
+ led-sfp1-activity {
+ label = "sfp1:green";
+ gpios = <&cp0_gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* for sfp-1 (J42) */
+ led-sfp1-link {
+ label = "sfp1:yellow";
+ gpios = <&cp0_gpio1 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* (J28) */
+ led-sfp0-activity {
+ label = "sfp0:green";
+ gpios = <&cp1_gpio2 22 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* (J28) */
+ led-sfp0-link {
+ label = "sfp0:yellow";
+ gpios = <&cp1_gpio2 23 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ /* Type-A port on J53 */
+ reg_usb_a_vbus0: regulator-usb-a-vbus0 {
+ compatible = "regulator-fixed";
+ pinctrl-0 = <&cp0_reg_usb_a_vbus0_pins>;
+ pinctrl-names = "default";
+ regulator-name = "vbus0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpios = <&cp0_gpio1 27 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_usb_a_vbus1: regulator-usb-a-vbus1 {
+ compatible = "regulator-fixed";
+ pinctrl-0 = <&cp0_reg_usb_a_vbus1_pins>;
+ pinctrl-names = "default";
+ regulator-name = "vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpios = <&cp0_gpio1 28 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ sfp0: sfp-0 {
+ compatible = "sff,sfp";
+ pinctrl-0 = <&cp0_sfp0_pins>;
+ pinctrl-names = "default";
+ i2c-bus = <&cp0_i2c1>;
+ los-gpios = <&cp0_gpio2 2 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&cp0_gpio2 0 GPIO_ACTIVE_LOW>;
+ tx-disable-gpios = <&cp0_gpio2 1 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&cp0_gpio1 31 GPIO_ACTIVE_HIGH>;
+ maximum-power-milliwatt = <2000>;
+ };
+
+ sfp1: sfp-1 {
+ compatible = "sff,sfp";
+ pinctrl-0 = <&cp1_sfp1_pins>;
+ pinctrl-names = "default";
+ i2c-bus = <&cp1_i2c1>;
+ los-gpios = <&cp1_gpio2 2 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&cp1_gpio2 18 GPIO_ACTIVE_LOW>;
+ tx-disable-gpios = <&cp1_gpio2 1 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&cp1_gpio2 17 GPIO_ACTIVE_HIGH>;
+ maximum-power-milliwatt = <2000>;
+ };
+};
+
+&cp0_ethernet {
+ status = "okay";
+};
+
+/* SRDS #2 - SFP+ 10GE */
+&cp0_eth0 {
+ managed = "in-band-status";
+ phy-mode = "10gbase-r";
+ phys = <&cp0_comphy2 0>;
+ sfp = <&sfp0>;
+ status = "okay";
+};
+
+/* SRDS #3 - SGMII 1GE */
+&cp0_eth1 {
+ managed = "in-band-status";
+ phy-mode = "sgmii";
+ /* Without mdio phy access rely on sgmii auto-negotiation. */
+ phys = <&cp0_comphy3 1>;
+ status = "okay";
+};
+
+/* SRDS #1 - SGMII */
+&cp0_eth2 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ managed = "in-band-status";
+ phy-mode = "sgmii";
+ phy = <&cp0_phy1>;
+ phys = <&cp0_comphy1 2>;
+};
+
+&cp0_gpio1 {
+ pcie0-0-w-disable-hog {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "pcie0.0-w-disable";
+ };
+
+ /* J34 */
+ m2-full-card-power-off-hog {
+ gpio-hog;
+ gpios = <8 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "m2-full-card-power-off";
+ };
+};
+
+&cp0_i2c0 {
+ /* assembly option */
+ fan-controller@18 {
+ compatible = "ti,amc6821";
+ reg = <0x18>;
+ };
+
+ expander0: gpio@41 {
+ compatible = "nxp,pca9536";
+ reg = <0x41>;
+
+ usb-a-vbus0-ilimit-hog {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "vbus0-ilimit";
+ };
+
+ /* duplicate connection, controlled by soc gpio */
+ usb-vbus0-enable-hog {
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "vbus0-enable";
+ };
+
+ usb-a-vbus1-ilimit-hog {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "vbus1-ilimit";
+ };
+
+ /* duplicate connection, controlled by soc gpio */
+ usb-vbus1-enable-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "vbus1-enable";
+ };
+ };
+
+ carrier_eeprom: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <8>;
+ };
+
+ /* usb-hub@60 */
+
+ /* assembly option */
+ carrier_rtc: rtc@68 {
+ compatible = "st,m41t83";
+ reg = <0x68>;
+ pinctrl-0 = <&cp1_rtc_pins>;
+ pinctrl-names = "default";
+ interrupt-parent = <&cp1_gpio1>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&cp1_gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&cp0_i2c1 {
+ /*
+ * Routed to SFP.
+ * Limit to 100kHz for compatibility with SFP modules,
+ * featuring AT24C01A/02/04 at addresses 0x50/0x51.
+ */
+ clock-frequency = <100000>;
+ pinctrl-0 = <&cp0_i2c1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&cp0_mdio {
+ /*
+ * SoM + Carrier each have a PHY at address 0.
+ * Remove the SoM phy node, and skip adding the carrier node.
+ * SGMII Auto-Negotation is enabled by bootloader for
+ * autonomous operation without mdio control.
+ */
+ /delete-node/ ethernet-phy@0;
+
+ /* U17016 */
+ cp0_phy1: ethernet-phy@1 {
+ reg = <1>;
+ /*
+ * Configure LEDs default behaviour:
+ * - LED[0]: link is 1000Mbps: On (yellow)
+ * - LED[1]: link/activity: On/blink (green)
+ * - LED[2]: high impedance (floating)
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a17>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+};
+
+/* SRDS #0 - miniPCIe */
+&cp0_pcie0 {
+ num-lanes = <1>;
+ phys = <&cp0_comphy0 0>;
+ status = "okay";
+};
+
+/* SRDS #5 - M.2 B-Key (J34) */
+&cp0_pcie2 {
+ num-lanes = <1>;
+ phys = <&cp0_comphy5 2>;
+ status = "okay";
+};
+
+&cp0_pinctrl {
+ pinctrl-0 = <&cp0_m2_0_shutdown_pins &cp0_mpcie_rfkill_pins>;
+ pinctrl-names = "default";
+
+ cp0_i2c1_pins: cp0-i2c1-pins {
+ marvell,pins = "mpp35", "mpp36";
+ marvell,function = "i2c1";
+ };
+
+ cp0_led_pins: cp0-led-pins {
+ marvell,pins = "mpp4", "mpp7";
+ marvell,function = "gpio";
+ };
+
+ cp0_m2_0_shutdown_pins: cp0-m2-0-shutdown-pins {
+ marvell,pins = "mpp8";
+ marvell,function = "gpio";
+ };
+
+ cp0_mmc0_pins: cp0-mmc0-pins {
+ marvell,pins = "mpp43", "mpp56", "mpp57", "mpp58",
+ "mpp59", "mpp60", "mpp61";
+ marvell,function = "sdio";
+ };
+
+ cp0_mpcie_rfkill_pins: cp0-mpcie-rfkill-pins {
+ marvell,pins = "mpp6";
+ marvell,function = "gpio";
+ };
+
+ cp0_reg_usb_a_vbus0_pins: cp0-reg-usb-a-vbus0-pins {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+
+ cp0_reg_usb_a_vbus1_pins: cp0-reg-usb-a-vbus1-pins {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ cp0_sfp0_pins: cp0-sfp0-pins {
+ marvell,pins = "mpp31", "mpp32", "mpp33", "mpp34";
+ marvell,function = "gpio";
+ };
+
+ cp0_spi1_cs1_pins: cp0-spi1-cs1-pins {
+ marvell,pins = "mpp12";
+ marvell,function = "spi1";
+ };
+};
+
+/* microSD */
+&cp0_sdhci0 {
+ pinctrl-0 = <&cp0_mmc0_pins>;
+ pinctrl-names = "default";
+ bus-width = <4>;
+ no-1-8-v;
+ status = "okay";
+};
+
+&cp0_spi1 {
+ /* add pin for chip-select 1 */
+ pinctrl-0 = <&cp0_spi1_pins &cp0_spi1_cs1_pins>;
+
+ flash@1 {
+ compatible = "jedec,spi-nor";
+ reg = <1>;
+ /* read command supports max. 50MHz */
+ spi-max-frequency = <50000000>;
+ };
+};
+
+/* USB-2.0 Host to USB-Hub */
+&cp0_usb3_0 {
+ phys = <&cp0_utmi0>;
+ phy-names = "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* SRDS #4 - USB-3.0 Host to USB-Hub */
+&cp0_usb3_1 {
+ phys = <&cp0_comphy4 1>, <&cp0_utmi1>;
+ phy-names = "comphy", "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&cp0_utmi {
+ status = "okay";
+};
+
+&cp0_utmi1 {
+ status = "disabled";
+};
+
+&cp1_ethernet {
+ status = "okay";
+};
+
+/* SRDS #4 - SFP+ 10GE */
+&cp1_eth0 {
+ managed = "in-band-status";
+ phy-mode = "10gbase-r";
+ phys = <&cp1_comphy4 0>;
+ sfp = <&sfp1>;
+ status = "okay";
+};
+
+/* SRDS #3 - SGMII 1GE */
+&cp1_eth1 {
+ managed = "in-band-status";
+ phy-mode = "sgmii";
+ phy = <&cp1_phy0>;
+ phys = <&cp0_comphy3 1>;
+ status = "okay";
+};
+
+/* SRDS #5 - SGMII 1GE */
+&cp1_eth2 {
+ managed = "in-band-status";
+ phy-mode = "sgmii";
+ phy = <&cp1_phy1>;
+ phys = <&cp0_comphy5 2>;
+ status = "okay";
+};
+
+&cp1_gpio1 {
+ status = "okay";
+
+ /* J30 */
+ m2-full-card-power-off-hog-0 {
+ gpio-hog;
+ gpios = <29 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "m2-full-card-power-off";
+ };
+
+ /* J44 */
+ m2-full-card-power-off-hog-1 {
+ gpio-hog;
+ gpios = <30 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "m2-full-card-power-off";
+ };
+};
+
+&cp1_gpio2 {
+ status = "okay";
+};
+
+&cp1_i2c1 {
+ /*
+ * Routed to SFP.
+ * Limit to 100kHz for compatibility with SFP modules,
+ * featuring AT24C01A/02/04 at addresses 0x50/0x51.
+ */
+ clock-frequency = <100000>;
+ pinctrl-0 = <&cp1_i2c1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&cp1_mdio {
+ pinctrl-0 = <&cp1_mdio_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ cp1_phy0: ethernet-phy@0 {
+ reg = <0>;
+ /*
+ * Configure LEDs default behaviour:
+ * - LED[0]: link is 1000Mbps: On (yellow)
+ * - LED[1]: link/activity: On/blink (green)
+ * - LED[2]: high impedance (floating)
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a17>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+
+ cp1_phy1: ethernet-phy@1 {
+ reg = <1>;
+ /*
+ * Configure LEDs default behaviour:
+ * - LED[0]: link is 1000Mbps: On (yellow)
+ * - LED[1]: link/activity: On/blink (green)
+ * - LED[2]: high impedance (floating)
+ */
+ marvell,reg-init = <3 16 0xf000 0x0a17>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+};
+
+/* SRDS #0 - M.2 (J30) */
+&cp1_pcie0 {
+ num-lanes = <1>;
+ phys = <&cp1_comphy0 0>;
+ status = "okay";
+};
+
+&cp1_rtc {
+ status = "disabled";
+};
+
+/* SRDS #1 - SATA on M.2 (J44) */
+&cp1_sata0 {
+ phys = <&cp1_comphy1 0>;
+ status = "okay";
+
+ /* only port 0 is available */
+ /delete-node/ sata-port@1;
+};
+
+&cp1_syscon0 {
+ cp1_pinctrl: pinctrl {
+ compatible = "marvell,cp115-standalone-pinctrl";
+ pinctrl-0 = <&cp1_m2_1_shutdown_pins &cp1_m2_2_shutdown_pins>;
+ pinctrl-names = "default";
+
+ cp1_i2c1_pins: cp0-i2c1-pins {
+ marvell,pins = "mpp35", "mpp36";
+ marvell,function = "i2c1";
+ };
+
+ cp1_led_pins: cp1-led-pins {
+ marvell,pins = "mpp54", "mpp55";
+ marvell,function = "gpio";
+ };
+
+ cp1_m2_1_shutdown_pins: cp1-m2-1-shutdown-pins {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ cp1_m2_2_shutdown_pins: cp1-m2-2-shutdown-pins {
+ marvell,pins = "mpp30";
+ marvell,function = "gpio";
+ };
+
+ cp1_mdio_pins: cp1-mdio-pins {
+ marvell,pins = "mpp37", "mpp38";
+ marvell,function = "ge";
+ };
+
+ cp1_rtc_pins: cp1-rtc-pins {
+ marvell,pins = "mpp12", "mpp13";
+ marvell,function = "gpio";
+ };
+
+ cp1_sfp1_pins: cp1-sfp1-pins {
+ marvell,pins = "mpp33", "mpp34", "mpp49", "mpp50";
+ marvell,function = "gpio";
+ };
+ };
+};
+
+/*
+ * SRDS #2 - USB-3.0 Host to M.2 (J44)
+ * USB-2.0 Host to M.2 (J30)
+ */
+&cp1_usb3_0 {
+ phys = <&cp1_comphy2 0>, <&cp1_utmi0>;
+ phy-names = "comphy", "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* USB-2.0 Host to M.2 (J44) */
+&cp1_usb3_1 {
+ phys = <&cp1_utmi1>;
+ phy-names = "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&cp1_utmi {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9131-db.dtsi b/arch/arm64/boot/dts/marvell/cn9131-db.dtsi
index ff8422fae31b..ad7360c83048 100644
--- a/arch/arm64/boot/dts/marvell/cn9131-db.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9131-db.dtsi
@@ -18,7 +18,7 @@
ethernet4 = &cp1_eth1;
};
- cp1_reg_usb3_vbus0: cp1_usb3_vbus@0 {
+ cp1_reg_usb3_vbus0: regulator-6 {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&cp1_xhci0_vbus_pins>;
@@ -29,12 +29,12 @@
gpio = <&cp1_gpio1 3 GPIO_ACTIVE_HIGH>;
};
- cp1_usb3_0_phy0: cp1_usb3_phy0 {
+ cp1_usb3_0_phy0: usb-phy-3 {
compatible = "usb-nop-xceiv";
vcc-supply = <&cp1_reg_usb3_vbus0>;
};
- cp1_sfp_eth1: sfp-eth1 {
+ cp1_sfp_eth1: sfp-eth-2 {
compatible = "sff,sfp";
i2c-bus = <&cp1_i2c0>;
los-gpios = <&cp1_gpio1 11 GPIO_ACTIVE_HIGH>;
@@ -138,8 +138,6 @@
reg = <0x700680 0x50>;
flash@0 {
- #address-cells = <0x1>;
- #size-cells = <0x1>;
compatible = "jedec,spi-nor";
reg = <0x0>;
/* On-board MUX does not allow higher frequencies */
diff --git a/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts b/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts
new file mode 100644
index 000000000000..0f53745a6fa0
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts
@@ -0,0 +1,673 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ * DTS for SolidRun CN9132 Clearfog.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "cn9130.dtsi"
+#include "cn9132-sr-cex7.dtsi"
+
+/ {
+ model = "SolidRun CN9132 Clearfog";
+ compatible = "solidrun,cn9132-clearfog",
+ "solidrun,cn9132-sr-cex7", "marvell,cn9130";
+
+ aliases {
+ ethernet1 = &cp0_eth2;
+ ethernet2 = &cp0_eth0;
+ ethernet3 = &cp2_eth0;
+ ethernet4 = &cp1_eth0;
+ i2c7 = &carrier_mpcie_i2c;
+ i2c8 = &carrier_ptp_i2c;
+ mmc1 = &cp0_sdhci0;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_wake0_pins>;
+
+ button-0 {
+ label = "SW2";
+ gpios = <&cp1_gpio2 8 GPIO_ACTIVE_LOW>;
+ linux,can-disable;
+ linux,code = <BTN_2>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_batlow_pins &cp2_rsvd4_pins>;
+
+ /* LED11 */
+ led-io-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <0>;
+ default-state = "off";
+ gpios = <&cp1_gpio1 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* LED12 */
+ led-io-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <1>;
+ default-state = "off";
+ gpios = <&cp2_gpio1 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ /* CON4 W_DISABLE1/W_DISABLE2 */
+ rfkill-m2-wlan {
+ compatible = "rfkill-gpio";
+ label = "m.2 wlan (CON4)";
+ radio-type = "wlan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_10g_phy_rst_01_pins>;
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&cp1_gpio2 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* CON5 W_DISABLE1/W_DISABLE2 */
+ rfkill-m2-wlan {
+ compatible = "rfkill-gpio";
+ label = "m.2 wlan (CON5)";
+ radio-type = "wlan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_10g_phy_rst_23_pins>;
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&cp1_gpio2 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* J21 W_DISABLE1 */
+ rfkill-m2-wwan {
+ compatible = "rfkill-gpio";
+ label = "m.2 wwan (J21)";
+ radio-type = "wwan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp2_rsvd3_pins>;
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&cp2_gpio1 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* J21 W_DISABLE1 */
+ rfkill-m2-gnss {
+ compatible = "rfkill-gpio";
+ label = "m.2 gnss (J21)";
+ radio-type = "gps";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp2_rsvd8_pins>;
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&cp2_gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* J14 W_DISABLE */
+ rfkill-mpcie-wlan {
+ compatible = "rfkill-gpio";
+ label = "mpcie wlan (J14)";
+ radio-type = "wlan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp2_rsvd2_pins>;
+ /* rfkill-gpio inverts internally */
+ shutdown-gpios = <&cp2_gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp: sfp {
+ compatible = "sff,sfp";
+ i2c-bus = <&com_10g_sfp_i2c0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&com_10g_int0_pins>;
+ mod-def0-gpios = <&cp0_gpio1 24 GPIO_ACTIVE_LOW>;
+ maximum-power-milliwatt = <2000>;
+ };
+};
+
+&com_smbus {
+ /* This bus is also routed to STM32 BMC Microcontroller (U2) */
+
+ power-sensor@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ #io-channel-cells = <1>;
+ label = "vdd_12v0";
+ shunt-resistor = <2000>;
+ };
+
+ adc@48 {
+ compatible = "ti,tla2021";
+ reg = <0x48>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* supplied by chaoskey hardware noise generator circuit */
+ channel@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&cp0_eth_phy0 {
+ /*
+ * Configure LEDs default behaviour:
+ * - LED[0]: link is 1000Mbps: On (yellow): 0111
+ * - LED[1]: link/activity: On/Blink (green): 0001
+ * - LED[2]: Off (green): 1000
+ */
+ marvell,reg-init = <3 16 0xf000 0x0817>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ /* link */
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ /* act */
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@2 {
+ /* 1000 */
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+};
+
+/* SRDS #4 - 10GE */
+&cp0_eth0 {
+ phys = <&cp0_comphy4 0>;
+ phy-mode = "10gbase-r";
+ managed = "in-band-status";
+ sfp = <&sfp>;
+ status = "okay";
+};
+
+&cp0_eth2 {
+ phy-mode = "2500base-x";
+ phys = <&cp0_comphy5 2>;
+ status = "okay";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+};
+
+&cp0_i2c1 {
+ /*
+ * Both COM and Carrier Board have a PCA9547 i2c mux at 0x77.
+ * Describe them as a single device merging each child bus.
+ */
+
+ i2c-mux@77 {
+ i2c@0 {
+ /* Routed to Full PCIe (J4) */
+ };
+
+ i2c@1 {
+ /* Routed to USB Hub (U29) */
+ };
+
+ i2c@2 {
+ /* Routed to M.2 (CON4) */
+ };
+
+ i2c@3 {
+ /* Routed to M.2 (CON5) */
+ };
+
+ i2c@4 {
+ /* Routed to M.2 (J21) */
+ };
+
+ carrier_mpcie_i2c: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ /* Routed to mini-PCIe (J14) */
+ };
+
+ carrier_ptp_i2c: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ /* Routed to various optional PTP related components */
+ };
+ };
+};
+
+&cp0_mdio {
+ ethernet-switch@4 {
+ compatible = "marvell,mv88e6085";
+ reg = <4>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sw_phy1: ethernet-phy@1 {
+ reg = <0x11>;
+ };
+
+ sw_phy2: ethernet-phy@2 {
+ reg = <0x12>;
+ };
+
+ sw_phy3: ethernet-phy@3 {
+ reg = <0x13>;
+ };
+
+ sw_phy4: ethernet-phy@4 {
+ reg = <0x14>;
+ };
+ };
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-port@1 {
+ reg = <1>;
+ label = "lan1";
+ phy-handle = <&sw_phy1>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@2 {
+ reg = <2>;
+ label = "lan2";
+ phy-handle = <&sw_phy2>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@3 {
+ reg = <3>;
+ label = "lan3";
+ phy-handle = <&sw_phy3>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@4 {
+ reg = <4>;
+ label = "lan4";
+ phy-handle = <&sw_phy4>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+
+ ethernet-port@5 {
+ reg = <5>;
+ label = "cpu";
+ ethernet = <&cp0_eth2>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+ };
+};
+
+/* SRDS #0,#1,#2,#3 - PCIe */
+&cp0_pcie0 {
+ num-lanes = <4>;
+ phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>, <&cp0_comphy2 0>, <&cp0_comphy3 0>;
+ status = "okay";
+};
+
+&cp0_pinctrl {
+ /*
+ * configure unused gpios exposed via pin headers:
+ * - J7-10: PWRBTN
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_pwrbtn_pins>;
+};
+
+/* microSD */
+&cp0_sdhci0 {
+ pinctrl-0 = <&cp0_mmc0_pins>, <&cp0_mmc0_cd_pins>;
+ pinctrl-names = "default";
+ bus-width = <4>;
+ no-1-8-v;
+ status = "okay";
+};
+
+&cp0_spi1 {
+ /* add CS1 */
+ pinctrl-0 = <&cp0_spi1_pins>, <&cp0_spi1_cs1_pins>;
+
+ flash@1 {
+ compatible = "jedec,spi-nor";
+ reg = <1>;
+ /* read command supports max. 50MHz */
+ spi-max-frequency = <50000000>;
+ };
+};
+
+/* J38 */
+&cp0_uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_uart2_pins>;
+ status = "okay";
+};
+
+&cp0_utmi {
+ /* M.2 "CON5" swaps D+/D- */
+ swap-dx-lanes = <1>;
+};
+
+&cp1_ethernet {
+ status = "okay";
+};
+
+/* SRDS #2 - 5GE */
+&cp1_eth0 {
+ phys = <&cp1_comphy2 0>;
+ phy-mode = "5gbase-r";
+ phy = <&cp1_eth_phy0>;
+ managed = "in-band-status";
+ status = "okay";
+};
+
+/* SRDS #0,#1 - PCIe */
+&cp1_pcie0 {
+ num-lanes = <2>;
+ phys = <&cp1_comphy0 0>, <&cp1_comphy1 0>;
+ status = "okay";
+};
+
+/* SRDS #4 - PCIe */
+&cp1_pcie1 {
+ num-lanes = <1>;
+ phys = <&cp1_comphy4 1>;
+ status = "okay";
+};
+
+/* SRDS #5 - PCIe */
+&cp1_pcie2 {
+ num-lanes = <1>;
+ phys = <&cp1_comphy5 2>;
+ status = "okay";
+};
+
+&cp1_pinctrl {
+ /*
+ * configure unused gpios exposed via pin headers:
+ * - J7-8: RSVD16
+ * - J7-10: THRM
+ * - J10-1: WAKE1
+ * - J10-2: SATA_ACT
+ * - J10-8: THERMTRIP
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_rsvd16_pins &cp1_sata_act_pins &cp1_thrm_irq_pins>,
+ <&cp1_thrm_trip_pins &cp1_wake1_pins>;
+};
+
+/* SRDS #3 - SATA */
+&cp1_sata0 {
+ status = "okay";
+
+ /* only port 1 is available */
+ /delete-node/ sata-port@0;
+
+ sata-port@1 {
+ phys = <&cp1_comphy3 1>;
+ };
+};
+
+&cp1_utmi {
+ /* M.2 "CON4" swaps D+/D- */
+ swap-dx-lanes = <0>;
+};
+
+&cp1_xmdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_xmdio_pins>;
+ status = "okay";
+
+ cp1_eth_phy0: ethernet-phy@8 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&com_10g_int1_pins>;
+ interrupt-parent = <&cp1_gpio2>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+};
+
+&cp2_ethernet {
+ status = "okay";
+};
+
+/* SRDS #2 - 5GE */
+&cp2_eth0 {
+ phys = <&cp2_comphy2 0>;
+ phy-mode = "5gbase-r";
+ phy = <&cp2_eth_phy0>;
+ managed = "in-band-status";
+ status = "okay";
+};
+
+&cp2_gpio1 {
+ pinctrl-names= "default";
+ pinctrl-0 = <&cp2_rsvd9_pins>;
+
+ /* J21 */
+ m2-wwan-reset-hog {
+ gpio-hog;
+ gpios = <9 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+ output-low;
+ line-name = "m2-wwan-reset";
+ };
+};
+
+/* SRDS #0 - PCIe */
+&cp2_pcie0 {
+ num-lanes = <1>;
+ phys = <&cp2_comphy0 0>;
+ status = "okay";
+};
+
+/* SRDS #4 - PCIe */
+&cp2_pcie1 {
+ num-lanes = <1>;
+ phys = <&cp2_comphy4 1>;
+ status = "okay";
+};
+
+/* SRDS #5 - PCIe */
+&cp2_pcie2 {
+ num-lanes = <1>;
+ phys = <&cp2_comphy5 2>;
+ status = "okay";
+};
+
+&cp2_pinctrl {
+ /*
+ * configure unused gpios exposed via pin headers:
+ * - J7-1: RSVD10
+ * - J7-3: RSVD11
+ * - J7-5: RSVD56
+ * - J7-6: RSVD7
+ * - J7-7: RSVD27
+ * - J10-3: RSVD31
+ * - J10-5: RSVD5
+ * - J10-6: RSVD32
+ * - J10-7: RSVD0
+ * - J10-9: RSVD1
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp2_rsvd0_pins &cp2_rsvd1_pins &cp2_rsvd5_pins>,
+ <&cp2_rsvd7_pins &cp2_rsvd10_pins &cp2_rsvd11_pins>,
+ <&cp2_rsvd27_pins &cp2_rsvd31_pins &cp2_rsvd32_pins>,
+ <&cp2_rsvd56_pins>;
+};
+
+/* SRDS #3 - SATA */
+&cp2_sata0 {
+ status = "okay";
+
+ /* only port 1 is available */
+ /delete-node/ sata-port@0;
+
+ sata-port@1 {
+ phys = <&cp2_comphy3 1>;
+ };
+};
+
+&cp2_xmdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp2_xmdio_pins>;
+ status = "okay";
+
+ cp2_eth_phy0: ethernet-phy@8 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&com_10g_int2_pins>;
+ interrupt-parent = <&cp2_gpio2>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9132-db.dtsi b/arch/arm64/boot/dts/marvell/cn9132-db.dtsi
index 512a4fa2861e..e753cfdac697 100644
--- a/arch/arm64/boot/dts/marvell/cn9132-db.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9132-db.dtsi
@@ -17,7 +17,7 @@
ethernet5 = &cp2_eth0;
};
- cp2_reg_usb3_vbus0: cp2_usb3_vbus@0 {
+ cp2_reg_usb3_vbus0: regulator-7 {
compatible = "regulator-fixed";
regulator-name = "cp2-xhci0-vbus";
regulator-min-microvolt = <5000000>;
@@ -26,12 +26,12 @@
gpio = <&cp2_gpio1 2 GPIO_ACTIVE_HIGH>;
};
- cp2_usb3_0_phy0: cp2_usb3_phy0 {
+ cp2_usb3_0_phy0: usb-phy-4 {
compatible = "usb-nop-xceiv";
vcc-supply = <&cp2_reg_usb3_vbus0>;
};
- cp2_reg_usb3_vbus1: cp2_usb3_vbus@1 {
+ cp2_reg_usb3_vbus1: regulator-8 {
compatible = "regulator-fixed";
regulator-name = "cp2-xhci1-vbus";
regulator-min-microvolt = <5000000>;
@@ -40,12 +40,12 @@
gpio = <&cp2_gpio1 3 GPIO_ACTIVE_HIGH>;
};
- cp2_usb3_0_phy1: cp2_usb3_phy1 {
+ cp2_usb3_0_phy1: usb-phy-5 {
compatible = "usb-nop-xceiv";
vcc-supply = <&cp2_reg_usb3_vbus1>;
};
- cp2_reg_sd_vccq: cp2_sd_vccq@0 {
+ cp2_reg_sd_vccq: regulator-9 {
compatible = "regulator-gpio";
regulator-name = "cp2_sd_vcc";
regulator-min-microvolt = <1800000>;
@@ -54,7 +54,7 @@
states = <1800000 0x1 3300000 0x0>;
};
- cp2_sfp_eth0: sfp-eth0 {
+ cp2_sfp_eth0: sfp-eth-3 {
compatible = "sff,sfp";
i2c-bus = <&cp2_sfpp0_i2c>;
los-gpios = <&cp2_module_expander1 11 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/marvell/cn9132-sr-cex7.dtsi b/arch/arm64/boot/dts/marvell/cn9132-sr-cex7.dtsi
new file mode 100644
index 000000000000..afc041c1c448
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/cn9132-sr-cex7.dtsi
@@ -0,0 +1,712 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2024 Josua Mayer <josua@solid-run.com>
+ *
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Instantiate the first external CP115
+ */
+
+#define CP11X_NAME cp1
+#define CP11X_BASE f4000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE f4600000
+#define CP11X_PCIE1_BASE f4620000
+#define CP11X_PCIE2_BASE f4640000
+
+#include "armada-cp115.dtsi"
+
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
+
+/*
+ * Instantiate the second external CP115
+ */
+
+#define CP11X_NAME cp2
+#define CP11X_BASE f6000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xe5000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE f6600000
+#define CP11X_PCIE1_BASE f6620000
+#define CP11X_PCIE2_BASE f6640000
+
+#include "armada-cp115.dtsi"
+
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
+
+/ {
+ model = "SolidRun CN9132 COM Express Type 7 Module";
+ compatible = "solidrun,cn9132-sr-cex7", "marvell,cn9130";
+
+ aliases {
+ ethernet0 = &cp0_eth1;
+ gpio3 = &cp1_gpio1;
+ gpio4 = &cp1_gpio2;
+ gpio5 = &cp2_gpio1;
+ gpio6 = &cp2_gpio2;
+ i2c0 = &cp0_i2c0;
+ i2c1 = &cp0_i2c1;
+ i2c2 = &com_clkgen_i2c;
+ i2c3 = &com_10g_led_i2c;
+ i2c4 = &com_10g_sfp_i2c0;
+ i2c5 = &com_smbus;
+ i2c6 = &com_fanctrl_i2c;
+ mmc0 = &ap_sdhci0;
+ rtc0 = &cp0_rtc;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 51 102 153 204 255>;
+ #cooling-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_fan_pwm_pins &cp0_fan_tacho_pins>;
+ pwms = <&cp0_gpio2 7 40000>;
+ interrupt-parent = <&cp0_gpio1>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ v_1_8: regulator-1-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ap_vhv: regulator-ap-vhv-1-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "ap-vhv-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ pinctrl-0 = <&cp0_reg_ap_vhv_pins>;
+ pinctrl-names = "default";
+ gpios = <&cp0_gpio2 21 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ cp_vhv: regulator-cp-vhv-1-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "cp-vhv-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ pinctrl-0 = <&cp0_reg_cp_vhv_pins>;
+ pinctrl-names = "default";
+ gpios = <&cp0_gpio2 17 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&ap_pinctrl {
+ ap_mmc0_pins: ap-mmc0-pins {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3", "mpp4", "mpp5",
+ "mpp6", "mpp7", "mpp8", "mpp9", "mpp10", "mpp12";
+ marvell,function = "sdio";
+ /*
+ * mpp12 is emmc reset, function should be sdio (hw_rst),
+ * but pinctrl-mvebu does not support this.
+ *
+ * From pinctrl-mvebu.h:
+ * "The name will be used to switch to this setting in DT description, e.g.
+ * marvell,function = "uart2". subname is only for debugging purposes."
+ */
+ };
+};
+
+&ap_sdhci0 {
+ bus-width = <8>;
+ pinctrl-0 = <&ap_mmc0_pins>;
+ pinctrl-names = "default";
+ vqmmc-supply = <&v_1_8>;
+ status = "okay";
+};
+
+&ap_thermal_ic {
+ polling-delay = <1000>;
+
+ trips {
+ ap_active: trip-active {
+ temperature = <40000>;
+ hysteresis = <4000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&ap_active>;
+ cooling-device = <&fan THERMAL_NO_LIMIT 4>;
+ };
+
+ map1 {
+ trip = <&ap_crit>;
+ cooling-device = <&fan 4 5>;
+ };
+ };
+};
+
+&cp0_ethernet {
+ status = "okay";
+};
+
+&cp0_eth1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_eth1_pins>;
+ phy-mode = "rgmii-id";
+ phy = <&cp0_eth_phy0>;
+ status = "okay";
+};
+
+&cp0_gpio1 {
+ status = "okay";
+
+ /*
+ * Tacho signal used as interrupt source by pwm-fan driver.
+ * Hog IO as input to ensure mvebu-gpio irq driver`s
+ * irq_set_type can succeed.
+ */
+ pwm-tacho-irq-hog {
+ gpio-hog;
+ gpios = <26 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+ input;
+ line-name = "fan-tacho";
+ };
+};
+
+&cp0_gpio2 {
+ status = "okay";
+};
+
+&cp0_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_i2c0_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ com_eeprom: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
+
+ eeprom@53 {
+ compatible = "atmel,spd";
+ reg = <0x53>;
+ };
+};
+
+&cp0_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_i2c1_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ i2c-mux-idle-disconnect;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ com_clkgen_i2c: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ /* clock-controller@6b */
+ };
+
+ com_10g_led_i2c: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ /* Routed to B2B Connector as I2C_10G_LED_SCL/SDA */
+ };
+
+ com_10g_sfp_i2c0: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ /* Routed to B2B Connector as I2C_SFP0_CP0_SCL/SDA */
+ };
+
+ com_smbus: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ /* Routed to B2B Connector as SBM_CLK/DAT */
+ };
+
+ com_fanctrl_i2c: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ /* fan-controller@2f (assembly option) */
+ };
+ };
+};
+
+&cp0_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_mdio_pins>;
+ status = "okay";
+
+ cp0_eth_phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&cp0_spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp0_spi1_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ /* read command supports max. 50MHz */
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&cp0_syscon0 {
+ cp0_pinctrl: pinctrl {
+ compatible = "marvell,cp115-standalone-pinctrl";
+
+ com_10g_int0_pins: cp0-10g-int-pins {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ cp0_eth1_pins: cp0-eth1-pins {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3",
+ "mpp4", "mpp5", "mpp6", "mpp7",
+ "mpp8", "mpp9", "mpp10", "mpp11";
+ /* docs call it "ge1", but cp110-pinctrl "ge0" */
+ marvell,function = "ge0";
+ };
+
+ cp0_fan_pwm_pins: cp0-fan-pwm-pins {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ cp0_fan_tacho_pins: cp0-fan-tacho-pins {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+
+ cp0_i2c0_pins: cp0-i2c0-pins {
+ marvell,pins = "mpp37", "mpp38";
+ marvell,function = "i2c0";
+ };
+
+ cp0_i2c1_pins: cp0-i2c1-pins {
+ marvell,pins = "mpp35", "mpp36";
+ marvell,function = "i2c1";
+ };
+
+ cp0_mdio_pins: cp0-mdio-pins {
+ marvell,pins = "mpp40", "mpp41";
+ marvell,function = "ge";
+ };
+
+ cp0_mmc0_pins: cp0-mmc0-pins {
+ marvell,pins = "mpp56", "mpp57", "mpp58", "mpp59",
+ "mpp60", "mpp61";
+ marvell,function = "sdio";
+ };
+
+ cp0_mmc0_cd_pins: cp0-mmc0-cd-pins {
+ marvell,pins = "mpp55";
+ marvell,function = "sdio_cd";
+ };
+
+ cp0_pwrbtn_pins: cp0-pwrbtn-pins {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ cp0_reg_ap_vhv_pins: cp0-reg-ap-vhv-pins {
+ marvell,pins = "mpp53";
+ marvell,function = "gpio";
+ };
+
+ cp0_reg_cp_vhv_pins: cp0-reg-cp-vhv-pins {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+
+ cp0_spi1_pins: cp0-spi1-pins {
+ marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+ marvell,function = "spi1";
+ };
+
+ cp0_spi1_cs1_pins: cp0-spi1-cs1-pins {
+ marvell,pins = "mpp12";
+ marvell,function = "spi1";
+ };
+
+ cp0_uart2_pins: cp0-uart2-pins {
+ marvell,pins = "mpp50", "mpp51";
+ marvell,function = "uart2";
+ };
+ };
+};
+
+&cp0_thermal_ic {
+ polling-delay = <1000>;
+
+ trips {
+ cp0_active: trip-active {
+ temperature = <40000>;
+ hysteresis = <4000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cp0_active>;
+ cooling-device = <&fan THERMAL_NO_LIMIT 4>;
+ };
+
+ map1 {
+ trip = <&cp0_crit>;
+ cooling-device = <&fan 4 5>;
+ };
+ };
+};
+
+/* USB-2.0 Host */
+&cp0_usb3_0 {
+ phys = <&cp0_utmi0>;
+ phy-names = "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* USB-2.0 Host */
+&cp0_usb3_1 {
+ phys = <&cp0_utmi1>;
+ phy-names = "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&cp0_utmi {
+ status = "okay";
+};
+
+&cp1_gpio1 {
+ status = "okay";
+};
+
+&cp1_gpio2 {
+ status = "okay";
+};
+
+&cp1_rtc {
+ status = "disabled";
+};
+
+&cp1_spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_spi1_pins>;
+ status = "okay";
+
+ tpm@0 {
+ reg = <0>;
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ spi-max-frequency = <10000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cp1_tpm_irq_pins>;
+ interrupt-parent = <&cp1_gpio1>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&cp1_syscon0 {
+ cp1_pinctrl: pinctrl {
+ compatible = "marvell,cp115-standalone-pinctrl";
+
+ com_10g_int1_pins: cp1-10g-int-pins {
+ marvell,pins = "mpp50";
+ marvell,function = "gpio";
+ };
+
+ cp1_10g_phy_rst_01_pins: cp1-10g-phy-rst-01-pins {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+
+ cp1_10g_phy_rst_23_pins: cp1-10g-phy-rst-23-pins {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ cp1_batlow_pins: cp1-batlow-pins {
+ marvell,pins = "mpp11";
+ marvell,function = "gpio";
+ };
+
+ cp1_rsvd16_pins: cp1-rsvd16-pins {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ cp1_sata_act_pins: cp1-sata-act-pins {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ cp1_spi1_pins: cp1-spi1-pins {
+ marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+ marvell,function = "spi1";
+ };
+
+ cp1_thrm_irq_pins: cp1-thrm-irq-pins {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ cp1_thrm_trip_pins: cp1-thrm-trip-pins {
+ marvell,pins = "mpp33";
+ marvell,function = "gpio";
+ };
+
+ cp1_tpm_irq_pins: cp1-tpm-irq-pins {
+ marvell,pins = "mpp17";
+ marvell,function = "gpio";
+ };
+
+ cp1_wake0_pins: cp1-wake0-pins {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ cp1_wake1_pins: cp1-wake1-pins {
+ marvell,pins = "mpp51";
+ marvell,function = "gpio";
+ };
+
+ cp1_xmdio_pins: cp1-xmdio-pins {
+ marvell,pins = "mpp37", "mpp38";
+ marvell,function = "xg";
+ };
+ };
+};
+
+&cp1_thermal_ic {
+ polling-delay = <1000>;
+
+ trips {
+ cp1_active: trip-active {
+ temperature = <40000>;
+ hysteresis = <4000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cp1_active>;
+ cooling-device = <&fan THERMAL_NO_LIMIT 4>;
+ };
+
+ map1 {
+ trip = <&cp1_crit>;
+ cooling-device = <&fan 4 5>;
+ };
+ };
+};
+
+/* USB-2.0 Host */
+&cp1_usb3_0 {
+ phys = <&cp1_utmi0>;
+ phy-names = "utmi";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&cp1_utmi {
+ status = "okay";
+};
+
+&cp2_ethernet {
+ status = "okay";
+};
+
+&cp2_gpio1 {
+ status = "okay";
+};
+
+&cp2_gpio2 {
+ status = "okay";
+};
+
+&cp2_rtc {
+ status = "disabled";
+};
+
+&cp2_syscon0 {
+ cp2_pinctrl: pinctrl {
+ compatible = "marvell,cp115-standalone-pinctrl";
+
+ com_10g_int2_pins: cp2-10g-int-pins {
+ marvell,pins = "mpp50";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd0_pins: cp2-rsvd0-pins {
+ marvell,pins = "mpp0";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd1_pins: cp2-rsvd1-pins {
+ marvell,pins = "mpp1";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd2_pins: cp2-rsvd2-pins {
+ marvell,pins = "mpp2";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd3_pins: cp2-rsvd3-pins {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd4_pins: cp2-rsvd4-pins {
+ marvell,pins = "mpp4";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd5_pins: cp2-rsvd5-pins {
+ marvell,pins = "mpp54";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd7_pins: cp2-rsvd7-pins {
+ marvell,pins = "mpp7";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd8_pins: cp2-rsvd8-pins {
+ marvell,pins = "mpp8";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd9_pins: cp2-rsvd9-pins {
+ marvell,pins = "mpp9";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd10_pins: cp2-rsvd10-pins {
+ marvell,pins = "mpp10";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd11_pins: cp2-rsvd11-pins {
+ marvell,pins = "mpp11";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd27_pins: cp2-rsvd27-pins {
+ marvell,pins = "mpp11";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd31_pins: cp2-rsvd31-pins {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd32_pins: cp2-rsvd32-pins {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd55_pins: cp2-rsvd55-pins {
+ marvell,pins = "mpp55";
+ marvell,function = "gpio";
+ };
+
+ cp2_rsvd56_pins: cp2-rsvd56-pins {
+ marvell,pins = "mpp56";
+ marvell,function = "gpio";
+ };
+
+ cp2_xmdio_pins: cp2-xmdio-pins {
+ marvell,pins = "mpp37", "mpp38";
+ marvell,function = "xg";
+ };
+ };
+};
+
+&cp2_thermal_ic {
+ polling-delay = <1000>;
+
+ trips {
+ cp2_active: trip-active {
+ temperature = <40000>;
+ hysteresis = <4000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cp2_active>;
+ cooling-device = <&fan THERMAL_NO_LIMIT 4>;
+ };
+
+ map1 {
+ trip = <&cp2_crit>;
+ cooling-device = <&fan 4 5>;
+ };
+ };
+};
+
+/* USB-2.0/3.0 Host */
+&cp2_usb3_0 {
+ phys = <&cp2_utmi0>, <&cp2_comphy1 0>;
+ phy-names = "utmi", "comphy";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&cp2_utmi {
+ status = "okay";
+};
+
+/* AP default console */
+&uart0 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 37b4ca3a87c9..8fd7b2bb7a15 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -8,9 +8,12 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-openwrt-one.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-mini.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo
@@ -62,6 +65,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r1.dtb
@@ -69,6 +74,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r5-sku2.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-spherion-r0.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-spherion-r4.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-dojo-r1.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r1.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r2.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r3.dtb
@@ -76,5 +82,11 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8390-genio-700-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
+
+# Device tree overlays support
+DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@
+DTC_FLAGS_mt7986a-bananapi-bpi-r3-mini := -@
diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index 234e3b23d7a8..c84c47c1352f 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -137,7 +137,7 @@
<MT2712_PIN_74_GBE_TXD0__FUNC_GBE_TXD0>,
<MT2712_PIN_75_GBE_TXC__FUNC_GBE_TXC>,
<MT2712_PIN_76_GBE_TXEN__FUNC_GBE_TXEN>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
};
rx_pins {
pinmux = <MT2712_PIN_78_GBE_RXD3__FUNC_GBE_RXD3>,
@@ -151,7 +151,7 @@
mdio_pins {
pinmux = <MT2712_PIN_85_GBE_MDC__FUNC_GBE_MDC>,
<MT2712_PIN_86_GBE_MDIO__FUNC_GBE_MDIO>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
input-enable;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts b/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts
index 7364c7278276..91de920c2245 100644
--- a/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts
+++ b/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts
@@ -288,25 +288,25 @@
<PINMUX_GPIO161__FUNC_MSDC0_DAT7>,
<PINMUX_GPIO162__FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins-clk {
pinmux = <PINMUX_GPIO163__FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
pins-rst {
pinmux = <PINMUX_GPIO165__FUNC_MSDC0_RSTB>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
};
pins-ds {
pinmux = <PINMUX_GPIO164__FUNC_MSDC0_DSL>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
};
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 224bb289660c..d12eac9b3eeb 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -149,9 +149,9 @@
#address-cells = <1>;
#size-cells = <0>;
- switch@0 {
+ switch@1f {
compatible = "mediatek,mt7531";
- reg = <0>;
+ reg = <0x1f>;
interrupt-controller;
#interrupt-cells = <1>;
interrupts-extended = <&pio 53 IRQ_TYPE_LEVEL_HIGH>;
@@ -329,8 +329,8 @@
/* eMMC is shared pin with parallel NAND */
emmc_pins_default: emmc-pins-default {
mux {
- function = "emmc", "emmc_rst";
- groups = "emmc";
+ function = "emmc";
+ groups = "emmc", "emmc_rst";
};
/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index 41629769bdc8..8c3e2e2578bc 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -268,8 +268,8 @@
/* eMMC is shared pin with parallel NAND */
emmc_pins_default: emmc-pins-default {
mux {
- function = "emmc", "emmc_rst";
- groups = "emmc";
+ function = "emmc";
+ groups = "emmc", "emmc_rst";
};
/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
new file mode 100644
index 000000000000..54101cc08a25
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+#include "mt7981b.dtsi"
+
+/ {
+ compatible = "cudy,wr3000-v1", "mediatek,mt7981b";
+ model = "Cudy WR3000 V1";
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x10000000>;
+ device_type = "memory";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ key-wps {
+ label = "WPS";
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ key-reset {
+ label = "RESET";
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+ };
+
+ led-1 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+ };
+
+ led-2 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+ };
+
+ led-3 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_LAN;
+ gpios = <&pio 9 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+ };
+
+ led-5 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WAN_ONLINE;
+ gpios = <&pio 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts
new file mode 100644
index 000000000000..4f6cbb491287
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+/dts-v1/;
+
+#include "mt7981b.dtsi"
+
+/ {
+ compatible = "openwrt,one", "mediatek,mt7981b";
+ model = "OpenWrt One";
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x40000000>;
+ device_type = "memory";
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
index 4feff3d1c5f4..64aeeb24efac 100644
--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
@@ -2,6 +2,7 @@
#include <dt-bindings/clock/mediatek,mt7981-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/mt7986-resets.h>
/ {
compatible = "mediatek,mt7981b";
@@ -62,12 +63,19 @@
#clock-cells = <1>;
};
- clock-controller@1001b000 {
+ topckgen: clock-controller@1001b000 {
compatible = "mediatek,mt7981-topckgen", "syscon";
reg = <0 0x1001b000 0 0x1000>;
#clock-cells = <1>;
};
+ watchdog: watchdog@1001c000 {
+ compatible = "mediatek,mt7986-wdt";
+ reg = <0 0x1001c000 0 0x1000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
clock-controller@1001e000 {
compatible = "mediatek,mt7981-apmixedsys";
reg = <0 0x1001e000 0 0x1000>;
@@ -78,20 +86,80 @@
compatible = "mediatek,mt7981-pwm";
reg = <0 0x10048000 0 0x1000>;
clocks = <&infracfg CLK_INFRA_PWM_STA>,
- <&infracfg CLK_INFRA_PWM_HCK>,
- <&infracfg CLK_INFRA_PWM1_CK>,
- <&infracfg CLK_INFRA_PWM2_CK>,
- <&infracfg CLK_INFRA_PWM3_CK>;
+ <&infracfg CLK_INFRA_PWM_HCK>,
+ <&infracfg CLK_INFRA_PWM1_CK>,
+ <&infracfg CLK_INFRA_PWM2_CK>,
+ <&infracfg CLK_INFRA_PWM3_CK>;
clock-names = "top", "main", "pwm1", "pwm2", "pwm3";
#pwm-cells = <2>;
};
+ i2c@11007000 {
+ compatible = "mediatek,mt7981-i2c";
+ reg = <0 0x11007000 0 0x1000>,
+ <0 0x10217080 0 0x80>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_I2C0_CK>,
+ <&infracfg CLK_INFRA_AP_DMA_CK>,
+ <&infracfg CLK_INFRA_I2C_MCK_CK>,
+ <&infracfg CLK_INFRA_I2C_PCK_CK>;
+ clock-names = "main", "dma", "arb", "pmic";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pio: pinctrl@11d00000 {
+ compatible = "mediatek,mt7981-pinctrl";
+ reg = <0 0x11d00000 0 0x1000>,
+ <0 0x11c00000 0 0x1000>,
+ <0 0x11c10000 0 0x1000>,
+ <0 0x11d20000 0 0x1000>,
+ <0 0x11e00000 0 0x1000>,
+ <0 0x11e20000 0 0x1000>,
+ <0 0x11f00000 0 0x1000>,
+ <0 0x11f10000 0 0x1000>,
+ <0 0x1000b000 0 0x1000>;
+ reg-names = "gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb", "iocfg_lb",
+ "iocfg_bl", "iocfg_tm", "iocfg_tl", "eint";
+ interrupt-controller;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ gpio-ranges = <&pio 0 0 56>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ efuse@11f20000 {
+ compatible = "mediatek,mt7981-efuse", "mediatek,efuse";
+ reg = <0 0x11f20000 0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
clock-controller@15000000 {
compatible = "mediatek,mt7981-ethsys", "syscon";
reg = <0 0x15000000 0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
+
+ wifi@18000000 {
+ compatible = "mediatek,mt7981-wmac";
+ reg = <0 0x18000000 0 0x1000000>,
+ <0 0x10003000 0 0x1000>,
+ <0 0x11d10000 0 0x1000>;
+ interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_NETSYS_MCU_SEL>,
+ <&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
+ clock-names = "mcu", "ap2conn";
+ resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
+ reset-names = "consys";
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
index 779dc6782bb1..047a8388811e 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
@@ -9,21 +9,17 @@
/ {
compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
- fragment@0 {
- target-path = "/soc/mmc@11230000";
- __overlay__ {
- bus-width = <8>;
- max-frequency = <200000000>;
- cap-mmc-highspeed;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- hs400-ds-delay = <0x14014>;
- non-removable;
- no-sd;
- no-sdio;
- status = "okay";
- };
- };
};
+&{/soc/mmc@11230000} {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ hs400-ds-delay = <0x14014>;
+ non-removable;
+ no-sd;
+ no-sdio;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-mini.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-mini.dts
new file mode 100644
index 000000000000..e2a2fea7adf0
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-mini.dts
@@ -0,0 +1,493 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Authors: Frank Wunderlich <frank-w@public-files.de>
+ * Eric Woudstra <ericwouds@gmail.com>
+ * Tianling Shen <cnsztl@immortalwrt.org>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+#include "mt7986a.dtsi"
+
+/ {
+ model = "Bananapi BPI-R3 Mini";
+ chassis-type = "embedded";
+ compatible = "bananapi,bpi-r3mini", "mediatek,mt7986a";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ dcin: regulator-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "12vd";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ #cooling-cells = <2>;
+ /*
+ * The signal is inverted on this board and the PWM driver
+ * does not support polarity inversion.
+ */
+ /* cooling level (0, 1, 2) */
+ cooling-levels = <255 96 0>;
+ pwms = <&pwm 0 10000>;
+ };
+
+ reg_1p8v: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1.8vd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <&dcin>;
+ };
+
+ reg_3p3v: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3vd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <&dcin>;
+ };
+
+ usb_vbus: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpios = <&pio 20 GPIO_ACTIVE_LOW>;
+ regulator-boot-on;
+ };
+
+ en8811_a: regulator-phy1 {
+ compatible = "regulator-fixed";
+ regulator-name = "phy1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 16 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+
+ en8811_b: regulator-phy2 {
+ compatible = "regulator-fixed";
+ regulator-name = "phy2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 17 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ green_led: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset-key {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+};
+
+&cpu_thermal {
+ cooling-maps {
+ map0 {
+ /* active: set fan to cooling level 2 */
+ cooling-device = <&fan 2 2>;
+ trip = <&cpu_trip_active_high>;
+ };
+
+ map1 {
+ /* active: set fan to cooling level 1 */
+ cooling-device = <&fan 1 1>;
+ trip = <&cpu_trip_active_med>;
+ };
+
+ map2 {
+ /* active: set fan to cooling level 0 */
+ cooling-device = <&fan 0 0>;
+ trip = <&cpu_trip_active_low>;
+ };
+ };
+};
+
+&crypto {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+ phy-handle = <&phy0>;
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "2500base-x";
+ phy-handle = <&phy1>;
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc0_pins_default>;
+ pinctrl-1 = <&mmc0_pins_uhs>;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+};
+
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_pins>;
+ status = "okay";
+
+ /* MAC Address EEPROM */
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+
+ address-width = <8>;
+ pagesize = <8>;
+ size = <256>;
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@14 {
+ reg = <14>;
+ interrupts-extended = <&pio 48 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <20000>;
+ phy-mode = "2500base-x";
+ full-duplex;
+ pause;
+ airoha,pnswap-rx;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 { /* en8811_a_gpio5 */
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+ led@1 { /* en8811_a_gpio4 */
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+
+ phy1: ethernet-phy@15 {
+ reg = <15>;
+ interrupts-extended = <&pio 46 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pio 47 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <20000>;
+ phy-mode = "2500base-x";
+ full-duplex;
+ pause;
+ airoha,pnswap-rx;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 { /* en8811_b_gpio5 */
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_WAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+ led@1 { /* en8811_b_gpio4 */
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pins>;
+ status = "okay";
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+&pio {
+ i2c_pins: i2c-pins {
+ mux {
+ function = "i2c";
+ groups = "i2c";
+ };
+ };
+
+ mmc0_pins_default: mmc0-pins {
+ mux {
+ function = "emmc";
+ groups = "emmc_51";
+ };
+ conf-cmd-dat {
+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+ input-enable;
+ drive-strength = <4>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "EMMC_CK";
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ conf-ds {
+ pins = "EMMC_DSL";
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ conf-rst {
+ pins = "EMMC_RSTB";
+ drive-strength = <4>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ };
+
+ mmc0_pins_uhs: mmc0-uhs-pins {
+ mux {
+ function = "emmc";
+ groups = "emmc_51";
+ };
+ conf-cmd-dat {
+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+ input-enable;
+ drive-strength = <4>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "EMMC_CK";
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ conf-ds {
+ pins = "EMMC_DSL";
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ conf-rst {
+ pins = "EMMC_RSTB";
+ drive-strength = <4>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ };
+
+ pcie_pins: pcie-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie_clk", "pcie_wake", "pcie_pereset";
+ };
+ };
+
+ pwm_pins: pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0";
+ };
+ };
+
+ spi_flash_pins: spi-flash-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ };
+
+ usb_ngff_pins: usb-ngff-pins {
+ ngff-gnss-off-conf {
+ pins = "GPIO_6";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <1>;
+ };
+ ngff-pe-rst-conf {
+ pins = "GPIO_7";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <1>;
+ };
+ ngff-wwan-off-conf {
+ pins = "GPIO_8";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <1>;
+ };
+ ngff-pwr-off-conf {
+ pins = "GPIO_9";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <1>;
+ };
+ ngff-rst-conf {
+ pins = "GPIO_10";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <1>;
+ };
+ ngff-coex-conf {
+ pins = "SPI1_CS";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <1>;
+ };
+ };
+
+ wf_2g_5g_pins: wf-2g-5g-pins {
+ mux {
+ function = "wifi";
+ groups = "wf_2g", "wf_5g";
+ };
+ conf {
+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+ "WF1_TOP_CLK", "WF1_TOP_DATA";
+ drive-strength = <4>;
+ };
+ };
+
+ wf_dbdc_pins: wf-dbdc-pins {
+ mux {
+ function = "wifi";
+ groups = "wf_dbdc";
+ };
+ conf {
+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+ "WF1_TOP_CLK", "WF1_TOP_DATA";
+ drive-strength = <4>;
+ };
+ };
+
+ wf_led_pins: wf-led-pins {
+ mux {
+ function = "led";
+ groups = "wifi_led";
+ };
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "spi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+
+ spi-max-frequency = <20000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+};
+
+&ssusb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_ngff_pins>;
+ vusb33-supply = <&reg_3p3v>;
+ vbus-supply = <&usb_vbus>;
+ status = "okay";
+};
+
+&trng {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ status = "okay";
+ pinctrl-names = "default", "dbdc";
+ pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
+ pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
+
+ led {
+ led-active-low;
+ };
+};
+
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
index 7b97c5c91bd0..24398f8a7da4 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
@@ -9,46 +9,44 @@
/ {
compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi@1100a000} {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ spi_nand: flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ spi-tx-buswidth = <4>;
+ spi-rx-buswidth = <4>;
- fragment@0 {
- target-path = "/soc/spi@1100a000";
- __overlay__ {
+ partitions {
+ compatible = "fixed-partitions";
#address-cells = <1>;
- #size-cells = <0>;
- spi_nand: flash@0 {
- compatible = "spi-nand";
- reg = <0>;
- spi-max-frequency = <10000000>;
- spi-tx-buswidth = <4>;
- spi-rx-buswidth = <4>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "bl2";
- reg = <0x0 0x100000>;
- read-only;
- };
-
- partition@100000 {
- label = "reserved";
- reg = <0x100000 0x280000>;
- };
-
- partition@380000 {
- label = "fip";
- reg = <0x380000 0x200000>;
- read-only;
- };
-
- partition@580000 {
- label = "ubi";
- reg = <0x580000 0x7a80000>;
- };
- };
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "reserved";
+ reg = <0x100000 0x280000>;
+ };
+
+ partition@380000 {
+ label = "fip";
+ reg = <0x380000 0x200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ label = "ubi";
+ reg = <0x580000 0x7a80000>;
};
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
index e48881be4ed6..6a0d529b54ac 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
@@ -9,54 +9,52 @@
/ {
compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi@1100a000} {
+ #address-cells = <1>;
+ #size-cells = <0>;
- fragment@0 {
- target-path = "/soc/spi@1100a000";
- __overlay__ {
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
#address-cells = <1>;
- #size-cells = <0>;
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <10000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "bl2";
- reg = <0x0 0x40000>;
- read-only;
- };
-
- partition@40000 {
- label = "u-boot-env";
- reg = <0x40000 0x40000>;
- };
-
- partition@80000 {
- label = "reserved2";
- reg = <0x80000 0x80000>;
- };
-
- partition@100000 {
- label = "fip";
- reg = <0x100000 0x80000>;
- read-only;
- };
-
- partition@180000 {
- label = "recovery";
- reg = <0x180000 0xa80000>;
- };
-
- partition@c00000 {
- label = "fit";
- reg = <0xc00000 0x1400000>;
- };
- };
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "u-boot-env";
+ reg = <0x40000 0x40000>;
+ };
+
+ partition@80000 {
+ label = "reserved2";
+ reg = <0x80000 0x80000>;
+ };
+
+ partition@100000 {
+ label = "fip";
+ reg = <0x100000 0x80000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "recovery";
+ reg = <0x180000 0xa80000>;
+ };
+
+ partition@c00000 {
+ label = "fit";
+ reg = <0xc00000 0x1400000>;
};
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
index f623bce075ce..d9e01967acc4 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
@@ -9,15 +9,11 @@
/ {
compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
- fragment@0 {
- target-path = "/soc/mmc@11230000";
- __overlay__ {
- bus-width = <4>;
- max-frequency = <52000000>;
- cap-sd-highspeed;
- status = "okay";
- };
- };
};
+&{/soc/mmc@11230000} {
+ bus-width = <4>;
+ max-frequency = <52000000>;
+ cap-sd-highspeed;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index bba97de4fb44..aa728331e876 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT
+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
/ {
compatible = "mediatek,mt7988a";
@@ -78,7 +80,7 @@
#interrupt-cells = <3>;
};
- clock-controller@10001000 {
+ infracfg: clock-controller@10001000 {
compatible = "mediatek,mt7988-infracfg", "syscon";
reg = <0 0x10001000 0 0x1000>;
#clock-cells = <1>;
@@ -103,6 +105,92 @@
#clock-cells = <1>;
};
+ pwm@10048000 {
+ compatible = "mediatek,mt7988-pwm";
+ reg = <0 0x10048000 0 0x1000>;
+ clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
+ <&infracfg CLK_INFRA_66M_PWM_HCK>,
+ <&infracfg CLK_INFRA_66M_PWM_CK1>,
+ <&infracfg CLK_INFRA_66M_PWM_CK2>,
+ <&infracfg CLK_INFRA_66M_PWM_CK3>,
+ <&infracfg CLK_INFRA_66M_PWM_CK4>,
+ <&infracfg CLK_INFRA_66M_PWM_CK5>,
+ <&infracfg CLK_INFRA_66M_PWM_CK6>,
+ <&infracfg CLK_INFRA_66M_PWM_CK7>,
+ <&infracfg CLK_INFRA_66M_PWM_CK8>;
+ clock-names = "top", "main", "pwm1", "pwm2", "pwm3",
+ "pwm4", "pwm5", "pwm6", "pwm7", "pwm8";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ i2c@11003000 {
+ compatible = "mediatek,mt7981-i2c";
+ reg = <0 0x11003000 0 0x1000>,
+ <0 0x10217080 0 0x80>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_I2C_BCK>,
+ <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
+ clock-names = "main", "dma";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c@11004000 {
+ compatible = "mediatek,mt7981-i2c";
+ reg = <0 0x11004000 0 0x1000>,
+ <0 0x10217100 0 0x80>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_I2C_BCK>,
+ <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
+ clock-names = "main", "dma";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c@11005000 {
+ compatible = "mediatek,mt7981-i2c";
+ reg = <0 0x11005000 0 0x1000>,
+ <0 0x10217180 0 0x80>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_I2C_BCK>,
+ <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
+ clock-names = "main", "dma";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ usb@11190000 {
+ compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+ reg = <0 0x11190000 0 0x2e00>,
+ <0 0x11193e00 0 0x0100>;
+ reg-names = "mac", "ippc";
+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_USB_SYS>,
+ <&infracfg CLK_INFRA_USB_REF>,
+ <&infracfg CLK_INFRA_66M_USB_HCK>,
+ <&infracfg CLK_INFRA_133M_USB_HCK>,
+ <&infracfg CLK_INFRA_USB_XHCI>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+ };
+
+ usb@11200000 {
+ compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+ reg = <0 0x11200000 0 0x2e00>,
+ <0 0x11203e00 0 0x0100>;
+ reg-names = "mac", "ippc";
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_USB_SYS_CK_P1>,
+ <&infracfg CLK_INFRA_USB_CK_P1>,
+ <&infracfg CLK_INFRA_66M_USB_HCK_CK_P1>,
+ <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>,
+ <&infracfg CLK_INFRA_USB_XHCI_CK_P1>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+ };
+
clock-controller@11f40000 {
compatible = "mediatek,mt7988-xfi-pll";
reg = <0 0x11f40000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
index 90cbbc18a483..8d1cbc92bce3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
@@ -27,6 +27,15 @@
hid-descr-addr = <0x0020>;
interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>;
};
+
+ /* Lenovo Ideapad C330 uses G2Touch touchscreen as a 2nd source touchscreen */
+ touchscreen@40 {
+ compatible = "hid-over-i2c";
+ reg = <0x40>;
+ hid-descr-addr = <0x0001>;
+ interrupt-parent = <&pio>;
+ interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+ };
};
&i2c4 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
index 6d962d437e02..b4d85147b77b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -1134,12 +1134,6 @@
rtc: mt6397rtc {
compatible = "mediatek,mt6397-rtc";
};
-
- syscfg_pctl_pmic: syscon@c000 {
- compatible = "mediatek,mt6397-pctl-pmic-syscfg",
- "syscon";
- reg = <0 0x0000c000 0 0x0108>;
- };
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 3fab21f59d18..bb4671c18e3b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -213,14 +213,14 @@
<MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
<MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
};
pins_clk {
pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
bias-pull-down;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
};
pins_insert {
@@ -241,13 +241,13 @@
<MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7>,
<MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_2mA>;
+ drive-strength = <2>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins_clk {
pinmux = <MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_2mA>;
+ drive-strength = <2>;
bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
};
@@ -265,13 +265,13 @@
<MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
<MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
};
pins_clk {
pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_4mA>;
+ drive-strength = <4>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
index 681deddffc2a..f04baea5d6cb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
@@ -160,7 +160,6 @@
pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
<PINMUX_GPIO83__FUNC_SCL0>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -169,7 +168,6 @@
pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
<PINMUX_GPIO84__FUNC_SCL1>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -178,7 +176,6 @@
pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
<PINMUX_GPIO104__FUNC_SDA2>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -187,7 +184,6 @@
pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
<PINMUX_GPIO51__FUNC_SDA3>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -196,7 +192,6 @@
pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
<PINMUX_GPIO106__FUNC_SDA4>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -205,7 +200,6 @@
pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
<PINMUX_GPIO49__FUNC_SDA5>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
index 8b57706ac814..586eee79c73c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
@@ -27,7 +27,7 @@
dlg,btn-cfg = <50>;
dlg,mic-det-thr = <500>;
dlg,jack-ins-deb = <20>;
- dlg,jack-det-rate = "32ms_64ms";
+ dlg,jack-det-rate = "32_64";
dlg,jack-rem-deb = <1>;
dlg,a-d-btn-thr = <0xa>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
index 072133fb0f01..f34964afe39b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
@@ -9,6 +9,7 @@
/ {
model = "Google cozmo board";
+ chassis-type = "laptop";
compatible = "google,cozmo", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts
index b595622e7bee..72852b760038 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts
@@ -9,6 +9,7 @@
/ {
model = "Google fennel sku1 board";
+ chassis-type = "convertible";
compatible = "google,fennel-sku1", "google,fennel", "mediatek,mt8183";
pwmleds {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts
index 5a1c39318a6c..757d0afd14fb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts
@@ -9,6 +9,7 @@
/ {
model = "Google fennel sku6 board";
+ chassis-type = "convertible";
compatible = "google,fennel-sku6", "google,fennel", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts
index 3ea4fdb40118..6641b087e7c5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts
@@ -9,6 +9,7 @@
/ {
model = "Google fennel sku7 board";
+ chassis-type = "convertible";
compatible = "google,fennel-sku7", "google,fennel", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14-sku2.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14-sku2.dts
index 3fc5a6181d7e..877256eab262 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14-sku2.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14-sku2.dts
@@ -9,6 +9,7 @@
/ {
model = "Google fennel14 sku2 board";
+ chassis-type = "laptop";
compatible = "google,fennel-sku2", "google,fennel", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14.dts
index 23ad0b91e977..b981dd31a430 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel14.dts
@@ -9,6 +9,7 @@
/ {
model = "Google fennel14 sku0 board";
+ chassis-type = "laptop";
compatible = "google,fennel-sku0", "google,fennel", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts
index e5bd9191e426..f3ac9c074226 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts
@@ -9,6 +9,7 @@
/ {
model = "Google kappa board";
+ chassis-type = "laptop";
compatible = "google,kappa", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
index 8fa89db03e63..e8241587949b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
@@ -9,5 +9,6 @@
/ {
model = "Google kenzo sku17 board";
+ chassis-type = "laptop";
compatible = "google,juniper-sku17", "google,juniper", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku0.dts
index 4eb2a0d571af..ddb993521bbf 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku0.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku0.dts
@@ -19,6 +19,6 @@
&mmc1_pins_uhs {
pins-clk {
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku1.dts
index 6a733361e8ae..10c4f920a7d8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-makomo-sku1.dts
@@ -19,6 +19,6 @@
&mmc1_pins_uhs {
pins-clk {
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts
index a2e74b829320..cce326aec1aa 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts
@@ -17,7 +17,7 @@
pinctrl-names = "default";
pinctrl-0 = <&bt_pins_wakeup>;
- wobt {
+ event-wobt {
label = "Wake on BT";
gpios = <&pio 42 GPIO_ACTIVE_HIGH>;
linux,code = <KEY_WAKEUP>;
@@ -47,10 +47,8 @@
};
};
-&wifi_wakeup {
- wowlan {
- gpios = <&pio 113 GPIO_ACTIVE_LOW>;
- };
+&wifi_wakeup_event {
+ gpios = <&pio 113 GPIO_ACTIVE_LOW>;
};
&wifi_pwrseq {
@@ -68,21 +66,22 @@
&mmc1_pins_default {
pins-cmd-dat {
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
pins-clk {
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
};
&mmc1_pins_uhs {
pins-clk {
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
};
&mmc1 {
- bt_reset: bt-reset {
+ bluetooth@2 {
+ reg = <2>;
compatible = "mediatek,mt7921s-bluetooth";
pinctrl-names = "default";
pinctrl-0 = <&bt_pins_reset>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts
index 89208b843b27..928b205a616a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts
@@ -9,6 +9,7 @@
/ {
model = "Google willow board sku0";
+ chassis-type = "laptop";
compatible = "google,willow-sku0", "google,willow", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts
index c7b20441d053..71307a8052d6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts
@@ -9,5 +9,6 @@
/ {
model = "Google willow board sku1";
+ chassis-type = "laptop";
compatible = "google,willow-sku1", "google,willow", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
index 7592e3b86037..fa4ab4d2899f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
@@ -155,21 +155,24 @@
vdd18-supply = <&pp1800_mipibrdg>;
vdd33-supply = <&vddio_mipibrdg>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
- anx7625_in: endpoint {
- remote-endpoint = <&dsi_out>;
+ port@0 {
+ reg = <0>;
+
+ anx7625_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
};
- };
- port@1 {
- reg = <1>;
+ port@1 {
+ reg = <1>;
- anx7625_out: endpoint {
- remote-endpoint = <&panel_in>;
+ anx7625_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku32.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku32.dts
index 7739358008ee..5a416143b4a0 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku32.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku32.dts
@@ -12,6 +12,7 @@
/ {
model = "MediaTek kodama sku32 board";
+ chassis-type = "tablet";
compatible = "google,kodama-sku32", "google,kodama", "mediatek,mt8183";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index 100191c6453b..6345e969efae 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -152,7 +152,7 @@
pinctrl-names = "default";
pinctrl-0 = <&wifi_pins_wakeup>;
- button-wowlan {
+ wifi_wakeup_event: event-wowlan {
label = "Wake on WiFi";
gpios = <&pio 113 GPIO_ACTIVE_HIGH>;
linux,code = <KEY_WAKEUP>;
@@ -488,7 +488,7 @@
<PINMUX_GPIO172__FUNC_TDM_DATA1_2ND>,
<PINMUX_GPIO173__FUNC_TDM_DATA2_2ND>,
<PINMUX_GPIO10__FUNC_TDM_DATA3>; /*8ch-i2s to it6505*/
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
};
@@ -502,7 +502,7 @@
<PINMUX_GPIO10__FUNC_GPIO10>;
input-enable;
bias-pull-down;
- drive-strength = <MTK_DRIVE_2mA>;
+ drive-strength = <2>;
};
};
@@ -533,7 +533,6 @@
pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
<PINMUX_GPIO83__FUNC_SCL0>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -542,7 +541,6 @@
pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
<PINMUX_GPIO84__FUNC_SCL1>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -551,7 +549,6 @@
pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
<PINMUX_GPIO104__FUNC_SDA2>;
bias-disable;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -560,7 +557,6 @@
pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
<PINMUX_GPIO51__FUNC_SDA3>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -569,7 +565,6 @@
pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
<PINMUX_GPIO106__FUNC_SDA4>;
bias-disable;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -578,7 +573,6 @@
pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
<PINMUX_GPIO49__FUNC_SDA5>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -679,14 +673,14 @@
<PINMUX_GPIO34__FUNC_MSDC1_DAT1>,
<PINMUX_GPIO33__FUNC_MSDC1_DAT2>,
<PINMUX_GPIO30__FUNC_MSDC1_DAT3>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
input-enable;
mediatek,pull-up-adv = <10>;
};
pins-clk {
pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
mediatek,pull-down-adv = <10>;
input-enable;
};
@@ -803,7 +797,6 @@
};
pins-rts {
pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
- output-enable;
};
pins-cts {
pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
@@ -822,7 +815,6 @@
};
pins-rts {
pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
- output-enable;
};
pins-cts {
pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
index 333c516af490..1aa668c3ccf9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
@@ -197,7 +197,6 @@
pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
<PINMUX_GPIO83__FUNC_SCL0>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -206,7 +205,6 @@
pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
<PINMUX_GPIO84__FUNC_SCL1>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -215,7 +213,6 @@
pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
<PINMUX_GPIO104__FUNC_SDA2>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -224,7 +221,6 @@
pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
<PINMUX_GPIO51__FUNC_SDA3>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -233,7 +229,6 @@
pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
<PINMUX_GPIO106__FUNC_SDA4>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -242,7 +237,6 @@
pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
<PINMUX_GPIO49__FUNC_SDA5>;
mediatek,pull-up-adv = <3>;
- mediatek,drive-strength-adv = <00>;
};
};
@@ -356,14 +350,14 @@
<PINMUX_GPIO34__FUNC_MSDC1_DAT1>,
<PINMUX_GPIO33__FUNC_MSDC1_DAT2>,
<PINMUX_GPIO30__FUNC_MSDC1_DAT3>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
input-enable;
mediatek,pull-up-adv = <10>;
};
pins_clk {
pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
mediatek,pull-down-adv = <10>;
input-enable;
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 774ae5d9143f..fbf145639b8c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1183,7 +1183,7 @@
status = "disabled";
};
- thermal: thermal@1100b000 {
+ thermal: thermal-sensor@1100b000 {
#thermal-sensor-cells = <1>;
compatible = "mediatek,mt8183-thermal";
reg = <0 0x1100b000 0 0xc00>;
@@ -2090,61 +2090,129 @@
};
};
- /* The tzts1 ~ tzts6 don't need to polling */
- /* The tzts1 ~ tzts6 don't need to thermal throttle */
-
- tzts1: tzts1 {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ tzts1: soc-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <250>;
thermal-sensors = <&thermal 1>;
sustainable-power = <5000>;
- trips {};
- cooling-maps {};
+ trips {
+ soc_alert: trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ soc_crit: trip-crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
- tzts2: tzts2 {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ tzts2: gpu-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <250>;
thermal-sensors = <&thermal 2>;
sustainable-power = <5000>;
- trips {};
- cooling-maps {};
+
+ trips {
+ gpu_alert: trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ gpu_crit: trip-crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
- tzts3: tzts3 {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ tzts3: md1-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <250>;
thermal-sensors = <&thermal 3>;
sustainable-power = <5000>;
- trips {};
- cooling-maps {};
+
+ trips {
+ md1_alert: trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ md1_crit: trip-crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
- tzts4: tzts4 {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ tzts4: cpu-little-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <250>;
thermal-sensors = <&thermal 4>;
sustainable-power = <5000>;
- trips {};
- cooling-maps {};
+
+ trips {
+ cpul_alert: trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpul_crit: trip-crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
- tzts5: tzts5 {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ tzts5: cpu-big-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <250>;
thermal-sensors = <&thermal 5>;
sustainable-power = <5000>;
- trips {};
- cooling-maps {};
+
+ trips {
+ cpub_alert: trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpub_crit: trip-crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
- tztsABB: tztsABB {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ tztsABB: tsabb-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <250>;
thermal-sensors = <&thermal 6>;
sustainable-power = <5000>;
- trips {};
- cooling-maps {};
+
+ trips {
+ tsabb_alert: trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ tsabb_crit: trip-crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589824.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589824.dts
new file mode 100644
index 000000000000..d16834eec87a
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589824.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-voltorb.dtsi"
+
+/ {
+ model = "Google Voltorb sku589824 board";
+ compatible = "google,voltorb-sku589824", "google,voltorb",
+ "mediatek,mt8186";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts
new file mode 100644
index 000000000000..45e57f7706cc
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-voltorb.dtsi"
+
+/ {
+ model = "Google Voltorb sku589825 board";
+ compatible = "google,voltorb-sku589825", "google,voltorb",
+ "mediatek,mt8186";
+};
+
+&i2c1 {
+ touchscreen@10 {
+ compatible = "elan,ekth6915";
+ reg = <0x10>;
+ interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+ vcc33-supply = <&pp3300_s3>;
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi
new file mode 100644
index 000000000000..52ec58128d56
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/spmi/spmi.h>
+
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ chassis-type = "laptop";
+
+ max98360a: max98360a {
+ compatible = "maxim,max98360a";
+ sdmode-gpios = <&pio 150 GPIO_ACTIVE_HIGH>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&cpu6 {
+ proc-supply = <&mt6319_buck1>;
+};
+
+&cpu7 {
+ proc-supply = <&mt6319_buck1>;
+};
+
+&gpio_keys {
+ status = "disabled";
+};
+
+&keyboard_controller {
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x02, KEY_BACK)
+ MATRIX_KEY(0x03, 0x02, KEY_REFRESH)
+ MATRIX_KEY(0x02, 0x02, KEY_ZOOM)
+ MATRIX_KEY(0x01, 0x02, KEY_SCALE)
+ MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)
+ MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+ MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+ CROS_STD_MAIN_KEYMAP
+ >;
+};
+
+&mt6366_vproc11_reg {
+ status = "disabled";
+};
+
+&cluster1_opp_14 {
+ opp-hz = /bits/ 64 <2050000000>;
+ opp-microvolt = <1118750>;
+};
+
+&cluster1_opp_15 {
+ opp-hz = /bits/ 64 <2200000000>;
+};
+
+&rt1019p{
+ status = "disabled";
+};
+
+&sound {
+ compatible = "mediatek,mt8186-mt6366-rt5682s-max98360-sound";
+ status = "okay";
+
+ spk-hdmi-playback-dai-link {
+ codec {
+ sound-dai = <&it6505dptx>, <&max98360a>;
+ };
+ };
+};
+
+&spmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spmi_pins>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pmic@6 {
+ compatible = "mediatek,mt6319-regulator", "mediatek,mt6315-regulator";
+ reg = <0x6 SPMI_USID>;
+
+ regulators {
+ mt6319_buck1: vbuck1 {
+ regulator-name = "ppvar_dvdd_proc_bc_mt6319";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&touchscreen {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
index 1807e9d6cb0e..afdab5724eaa 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -42,7 +42,7 @@
default-brightness-level = <576>;
};
- bt-sco-codec {
+ bt-sco {
compatible = "linux,bt-sco";
#sound-dai-cells = <0>;
};
@@ -223,12 +223,44 @@
mediatek,adsp = <&adsp>;
mediatek,platform = <&afe>;
- playback-codecs {
- sound-dai = <&it6505dptx>, <&rt1019p>;
+ audio-routing =
+ "Headphone", "HPOL",
+ "Headphone", "HPOR",
+ "IN1P", "Headset Mic",
+ "Speakers", "Speaker",
+ "HDMI1", "TX";
+
+ hs-playback-dai-link {
+ link-name = "I2S0";
+ dai-format = "i2s";
+ mediatek,clk-provider = "cpu";
+ codec {
+ sound-dai = <&rt5682s 0>;
+ };
+ };
+
+ hs-capture-dai-link {
+ link-name = "I2S1";
+ dai-format = "i2s";
+ mediatek,clk-provider = "cpu";
+ codec {
+ sound-dai = <&rt5682s 0>;
+ };
};
- headset-codec {
- sound-dai = <&rt5682s 0>;
+ spk-share-dai-link {
+ link-name = "I2S2";
+ mediatek,clk-provider = "cpu";
+ };
+
+ spk-hdmi-playback-dai-link {
+ link-name = "I2S3";
+ dai-format = "i2s";
+ mediatek,clk-provider = "cpu";
+ /* RT1019P and IT6505 connected to the same I2S line */
+ codec {
+ sound-dai = <&it6505dptx>, <&rt1019p>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index b4315c9214dc..29d012d28edb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/clock/mediatek,mt8188-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/mailbox/mediatek,mt8188-gce.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h>
#include <dt-bindings/power/mediatek,mt8188-power.h>
@@ -293,6 +294,112 @@
clock-output-names = "clk32k";
};
+ gpu_opp_table: opp-table-gpu {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-390000000 {
+ opp-hz = /bits/ 64 <390000000>;
+ opp-microvolt = <575000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-431000000 {
+ opp-hz = /bits/ 64 <431000000>;
+ opp-microvolt = <587500>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-473000000 {
+ opp-hz = /bits/ 64 <473000000>;
+ opp-microvolt = <600000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-515000000 {
+ opp-hz = /bits/ 64 <515000000>;
+ opp-microvolt = <612500>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-556000000 {
+ opp-hz = /bits/ 64 <556000000>;
+ opp-microvolt = <625000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-598000000 {
+ opp-hz = /bits/ 64 <598000000>;
+ opp-microvolt = <637500>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-640000000 {
+ opp-hz = /bits/ 64 <640000000>;
+ opp-microvolt = <650000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-670000000 {
+ opp-hz = /bits/ 64 <670000000>;
+ opp-microvolt = <662500>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <675000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-730000000 {
+ opp-hz = /bits/ 64 <730000000>;
+ opp-microvolt = <687500>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-760000000 {
+ opp-hz = /bits/ 64 <760000000>;
+ opp-microvolt = <700000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-790000000 {
+ opp-hz = /bits/ 64 <790000000>;
+ opp-microvolt = <712500>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-835000000 {
+ opp-hz = /bits/ 64 <835000000>;
+ opp-microvolt = <731250>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-880000000 {
+ opp-hz = /bits/ 64 <880000000>;
+ opp-microvolt = <750000>;
+ opp-supported-hw = <0xff>;
+ };
+ opp-915000000 {
+ opp-hz = /bits/ 64 <915000000>;
+ opp-microvolt = <775000>;
+ opp-supported-hw = <0x8f>;
+ };
+ opp-915000000-5 {
+ opp-hz = /bits/ 64 <915000000>;
+ opp-microvolt = <762500>;
+ opp-supported-hw = <0x30>;
+ };
+ opp-915000000-6 {
+ opp-hz = /bits/ 64 <915000000>;
+ opp-microvolt = <750000>;
+ opp-supported-hw = <0x70>;
+ };
+ opp-950000000 {
+ opp-hz = /bits/ 64 <950000000>;
+ opp-microvolt = <800000>;
+ opp-supported-hw = <0x8f>;
+ };
+ opp-950000000-5 {
+ opp-hz = /bits/ 64 <950000000>;
+ opp-microvolt = <775000>;
+ opp-supported-hw = <0x30>;
+ };
+ opp-950000000-6 {
+ opp-hz = /bits/ 64 <950000000>;
+ opp-microvolt = <750000>;
+ opp-supported-hw = <0x70>;
+ };
+ };
+
pmu-a55 {
compatible = "arm,cortex-a55-pmu";
interrupt-parent = <&gic>;
@@ -383,6 +490,329 @@
#interrupt-cells = <2>;
};
+ scpsys: syscon@10006000 {
+ compatible = "mediatek,mt8188-scpsys", "syscon", "simple-mfd";
+ reg = <0 0x10006000 0 0x1000>;
+
+ /* System Power Manager */
+ spm: power-controller {
+ compatible = "mediatek,mt8188-power-controller";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ /* power domain of the SoC */
+ mfg0: power-domain@MT8188_POWER_DOMAIN_MFG0 {
+ reg = <MT8188_POWER_DOMAIN_MFG0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_MFG1 {
+ reg = <MT8188_POWER_DOMAIN_MFG1>;
+ clocks = <&topckgen CLK_APMIXED_MFGPLL>,
+ <&topckgen CLK_TOP_MFG_CORE_TMP>;
+ clock-names = "mfg", "alt";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_MFG2 {
+ reg = <MT8188_POWER_DOMAIN_MFG2>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_MFG3 {
+ reg = <MT8188_POWER_DOMAIN_MFG3>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_MFG4 {
+ reg = <MT8188_POWER_DOMAIN_MFG4>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_VPPSYS0 {
+ reg = <MT8188_POWER_DOMAIN_VPPSYS0>;
+ clocks = <&topckgen CLK_TOP_VPP>,
+ <&topckgen CLK_TOP_CAM>,
+ <&topckgen CLK_TOP_CCU>,
+ <&topckgen CLK_TOP_IMG>,
+ <&topckgen CLK_TOP_VENC>,
+ <&topckgen CLK_TOP_VDEC>,
+ <&topckgen CLK_TOP_WPE_VPP>,
+ <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VPP0>,
+ <&topckgen CLK_TOP_CFGREG_F26M_VPP0>,
+ <&vppsys0 CLK_VPP0_SMI_COMMON_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_VDO0_LARB0_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_VDO0_LARB1_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_VENCSYS_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_VENCSYS_CORE1_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_INFRA_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_CAMSYS_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_VPP1_LARB5_MMSRAM>,
+ <&vppsys0 CLK_VPP0_GALS_VPP1_LARB6_MMSRAM>,
+ <&vppsys0 CLK_VPP0_SMI_REORDER_MMSRAM>,
+ <&vppsys0 CLK_VPP0_SMI_IOMMU>,
+ <&vppsys0 CLK_VPP0_GALS_IMGSYS_CAMSYS>,
+ <&vppsys0 CLK_VPP0_GALS_EMI0_EMI1>,
+ <&vppsys0 CLK_VPP0_SMI_SUB_COMMON_REORDER>,
+ <&vppsys0 CLK_VPP0_SMI_RSI>,
+ <&vppsys0 CLK_VPP0_SMI_COMMON_LARB4>,
+ <&vppsys0 CLK_VPP0_GALS_VDEC_VDEC_CORE1>,
+ <&vppsys0 CLK_VPP0_GALS_VPP1_WPESYS>,
+ <&vppsys0 CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1>;
+ clock-names = "top", "cam", "ccu", "img", "venc",
+ "vdec", "wpe", "cfgck", "cfgxo",
+ "ss-sram-cmn", "ss-sram-v0l0", "ss-sram-v0l1",
+ "ss-sram-ve0", "ss-sram-ve1", "ss-sram-ifa",
+ "ss-sram-cam", "ss-sram-v1l5", "ss-sram-v1l6",
+ "ss-sram-rdr", "ss-iommu", "ss-imgcam",
+ "ss-emi", "ss-subcmn-rdr", "ss-rsi",
+ "ss-cmn-l4", "ss-vdec1", "ss-wpe",
+ "ss-cvdo-ve1";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_VDOSYS0 {
+ reg = <MT8188_POWER_DOMAIN_VDOSYS0>;
+ clocks = <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VDO0>,
+ <&topckgen CLK_TOP_CFGREG_F26M_VDO0>,
+ <&vdosys0 CLK_VDO0_SMI_GALS>,
+ <&vdosys0 CLK_VDO0_SMI_COMMON>,
+ <&vdosys0 CLK_VDO0_SMI_EMI>,
+ <&vdosys0 CLK_VDO0_SMI_IOMMU>,
+ <&vdosys0 CLK_VDO0_SMI_LARB>,
+ <&vdosys0 CLK_VDO0_SMI_RSI>,
+ <&vdosys0 CLK_VDO0_APB_BUS>;
+ clock-names = "cfgck", "cfgxo", "ss-gals",
+ "ss-cmn", "ss-emi", "ss-iommu",
+ "ss-larb", "ss-rsi", "ss-bus";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_VPPSYS1 {
+ reg = <MT8188_POWER_DOMAIN_VPPSYS1>;
+ clocks = <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VPP1>,
+ <&topckgen CLK_TOP_CFGREG_F26M_VPP1>,
+ <&vppsys1 CLK_VPP1_GALS5>,
+ <&vppsys1 CLK_VPP1_GALS6>,
+ <&vppsys1 CLK_VPP1_LARB5>,
+ <&vppsys1 CLK_VPP1_LARB6>;
+ clock-names = "cfgck", "cfgxo",
+ "ss-vpp1-g5", "ss-vpp1-g6",
+ "ss-vpp1-l5", "ss-vpp1-l6";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_VDEC1 {
+ reg = <MT8188_POWER_DOMAIN_VDEC1>;
+ clocks = <&vdecsys CLK_VDEC2_LARB1>;
+ clock-names = "ss-vdec";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_VDEC0 {
+ reg = <MT8188_POWER_DOMAIN_VDEC0>;
+ clocks = <&vdecsys_soc CLK_VDEC1_SOC_LARB1>;
+ clock-names = "ss-vdec";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ cam_vcore: power-domain@MT8188_POWER_DOMAIN_CAM_VCORE {
+ reg = <MT8188_POWER_DOMAIN_CAM_VCORE>;
+ clocks = <&topckgen CLK_TOP_CAM>,
+ <&topckgen CLK_TOP_CCU>,
+ <&topckgen CLK_TOP_CCU_AHB>,
+ <&topckgen CLK_TOP_CFGREG_CLOCK_ISP_AXI_GALS>;
+ clock-names = "cam", "ccu", "bus", "cfgck";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_CAM_MAIN {
+ reg = <MT8188_POWER_DOMAIN_CAM_MAIN>;
+ clocks = <&camsys CLK_CAM_MAIN_LARB13>,
+ <&camsys CLK_CAM_MAIN_LARB14>,
+ <&camsys CLK_CAM_MAIN_CAM2MM0_GALS>,
+ <&camsys CLK_CAM_MAIN_CAM2MM1_GALS>,
+ <&camsys CLK_CAM_MAIN_CAM2SYS_GALS>;
+ clock-names= "ss-cam-l13", "ss-cam-l14",
+ "ss-cam-mm0", "ss-cam-mm1",
+ "ss-camsys";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_CAM_SUBB {
+ reg = <MT8188_POWER_DOMAIN_CAM_SUBB>;
+ clocks = <&camsys CLK_CAM_MAIN_CAM_SUBB>,
+ <&camsys_rawb CLK_CAM_RAWB_LARBX>,
+ <&camsys_yuvb CLK_CAM_YUVB_LARBX>;
+ clock-names = "ss-camb-sub",
+ "ss-camb-raw",
+ "ss-camb-yuv";
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_CAM_SUBA {
+ reg =<MT8188_POWER_DOMAIN_CAM_SUBA>;
+ clocks = <&camsys CLK_CAM_MAIN_CAM_SUBA>,
+ <&camsys_rawa CLK_CAM_RAWA_LARBX>,
+ <&camsys_yuva CLK_CAM_YUVA_LARBX>;
+ clock-names = "ss-cama-sub",
+ "ss-cama-raw",
+ "ss-cama-yuv";
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_VDOSYS1 {
+ reg = <MT8188_POWER_DOMAIN_VDOSYS1>;
+ clocks = <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VDO1>,
+ <&topckgen CLK_TOP_CFGREG_F26M_VDO1>,
+ <&vdosys1 CLK_VDO1_SMI_LARB2>,
+ <&vdosys1 CLK_VDO1_SMI_LARB3>,
+ <&vdosys1 CLK_VDO1_GALS>;
+ clock-names = "cfgck", "cfgxo", "ss-larb2",
+ "ss-larb3", "ss-gals";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_HDMI_TX {
+ reg = <MT8188_POWER_DOMAIN_HDMI_TX>;
+ clocks = <&topckgen CLK_TOP_HDMI_APB>,
+ <&topckgen CLK_TOP_HDCP_24M>;
+ clock-names = "bus", "hdcp";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_DP_TX {
+ reg = <MT8188_POWER_DOMAIN_DP_TX>;
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_EDP_TX {
+ reg = <MT8188_POWER_DOMAIN_EDP_TX>;
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_VENC {
+ reg = <MT8188_POWER_DOMAIN_VENC>;
+ clocks = <&vencsys CLK_VENC1_LARB>,
+ <&vencsys CLK_VENC1_VENC>,
+ <&vencsys CLK_VENC1_GALS>,
+ <&vencsys CLK_VENC1_GALS_SRAM>;
+ clock-names = "ss-ve1-larb", "ss-ve1-core",
+ "ss-ve1-gals", "ss-ve1-sram";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_WPE {
+ reg = <MT8188_POWER_DOMAIN_WPE>;
+ clocks = <&wpesys CLK_WPE_TOP_SMI_LARB7>,
+ <&wpesys CLK_WPE_TOP_SMI_LARB7_PCLK_EN>;
+ clock-names = "ss-wpe-l7", "ss-wpe-l7pce";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_PEXTP_MAC_P0 {
+ reg = <MT8188_POWER_DOMAIN_PEXTP_MAC_P0>;
+ mediatek,infracfg = <&infracfg_ao>;
+ clocks = <&pericfg_ao CLK_PERI_AO_PCIE_P0_FMEM>;
+ clock-names = "ss-pextp-fmem";
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_CSIRX_TOP {
+ reg = <MT8188_POWER_DOMAIN_CSIRX_TOP>;
+ clocks = <&topckgen CLK_TOP_SENINF>,
+ <&topckgen CLK_TOP_SENINF1>;
+ clock-names = "seninf0", "seninf1";
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_PEXTP_PHY_TOP {
+ reg = <MT8188_POWER_DOMAIN_PEXTP_PHY_TOP>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_ADSP_AO {
+ reg = <MT8188_POWER_DOMAIN_ADSP_AO>;
+ clocks = <&topckgen CLK_TOP_AUDIO_LOCAL_BUS>,
+ <&topckgen CLK_TOP_ADSP>;
+ clock-names = "bus", "main";
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_ADSP_INFRA {
+ reg = <MT8188_POWER_DOMAIN_ADSP_INFRA>;
+ mediatek,infracfg = <&infracfg_ao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8188_POWER_DOMAIN_AUDIO_ASRC {
+ reg = <MT8188_POWER_DOMAIN_AUDIO_ASRC>;
+ clocks = <&topckgen CLK_TOP_ASM_H>;
+ clock-names = "asm";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_AUDIO {
+ reg = <MT8188_POWER_DOMAIN_AUDIO>;
+ clocks = <&topckgen CLK_TOP_A1SYS_HP>,
+ <&topckgen CLK_TOP_AUD_INTBUS>,
+ <&adsp_audio26m CLK_AUDIODSP_AUDIO26M>;
+ clock-names = "a1sys", "intbus", "adspck";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_ADSP {
+ reg = <MT8188_POWER_DOMAIN_ADSP>;
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ power-domain@MT8188_POWER_DOMAIN_ETHER {
+ reg = <MT8188_POWER_DOMAIN_ETHER>;
+ clocks = <&pericfg_ao CLK_PERI_AO_ETHERNET_MAC>;
+ clock-names = "ethermac";
+ mediatek,infracfg = <&infracfg_ao>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
watchdog: watchdog@10007000 {
compatible = "mediatek,mt8188-wdt";
reg = <0 0x10007000 0 0x100>;
@@ -413,6 +843,22 @@
clock-names = "spi", "wrap";
};
+ gce0: mailbox@10320000 {
+ compatible = "mediatek,mt8188-gce";
+ reg = <0 0x10320000 0 0x4000>;
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+ #mbox-cells = <2>;
+ clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
+ };
+
+ gce1: mailbox@10330000 {
+ compatible = "mediatek,mt8188-gce";
+ reg = <0 0x10330000 0 0x4000>;
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
+ #mbox-cells = <2>;
+ clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
+ };
+
scp: scp@10500000 {
compatible = "mediatek,mt8188-scp";
reg = <0 0x10500000 0 0x100000>,
@@ -827,6 +1273,23 @@
#clock-cells = <1>;
};
+ gpu: gpu@13000000 {
+ compatible = "mediatek,mt8188-mali", "arm,mali-valhall-jm";
+ reg = <0 0x13000000 0 0x4000>;
+
+ clocks = <&mfgcfg CLK_MFGCFG_BG3D>;
+ interrupts = <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "job", "mmu", "gpu";
+ operating-points-v2 = <&gpu_opp_table>;
+ power-domains = <&spm MT8188_POWER_DOMAIN_MFG2>,
+ <&spm MT8188_POWER_DOMAIN_MFG3>,
+ <&spm MT8188_POWER_DOMAIN_MFG4>;
+ power-domain-names = "core0", "core1", "core2";
+ status = "disabled";
+ };
+
mfgcfg: clock-controller@13fbf000 {
compatible = "mediatek,mt8188-mfgcfg";
reg = <0 0x13fbf000 0 0x1000>;
@@ -952,5 +1415,22 @@
reg = <0 0x1a000000 0 0x1000>;
#clock-cells = <1>;
};
+
+ vdosys0: syscon@1c01d000 {
+ compatible = "mediatek,mt8188-vdosys0", "syscon";
+ reg = <0 0x1c01d000 0 0x1000>;
+ #clock-cells = <1>;
+ mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
+ mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xd000 0x1000>;
+ };
+
+ vdosys1: syscon@1c100000 {
+ compatible = "mediatek,mt8188-vdosys1", "syscon";
+ reg = <0 0x1c100000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ mboxes = <&gce0 1 CMDQ_THR_PRIO_4>;
+ mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0 0x1000>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts
index fd2cb8765a15..ac2673e56fb8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts
@@ -7,6 +7,7 @@
/ {
model = "Google Hayato rev1";
+ chassis-type = "convertible";
compatible = "google,hayato-rev1", "google,hayato", "mediatek,mt8192";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts
index 3127ee5f6172..cd86ad9ba28a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts
@@ -7,6 +7,7 @@
/ {
model = "Google Hayato rev5";
+ chassis-type = "convertible";
compatible = "google,hayato-rev5-sku2", "google,hayato-sku2",
"google,hayato", "mediatek,mt8192";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts
index bc88866ab2f5..29aa87e93888 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts
@@ -8,6 +8,7 @@
/ {
model = "Google Spherion (rev0 - 3)";
+ chassis-type = "laptop";
compatible = "google,spherion-rev3", "google,spherion-rev2",
"google,spherion-rev1", "google,spherion-rev0",
"google,spherion", "mediatek,mt8192";
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts
index 0039158c9e60..5e9e598bab90 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts
@@ -8,6 +8,7 @@
/ {
model = "Google Spherion (rev4)";
+ chassis-type = "laptop";
compatible = "google,spherion-rev4", "google,spherion",
"mediatek,mt8192";
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index 7a704246678f..08d71ddf3668 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -147,6 +147,7 @@
regulator-boot-on;
gpio = <&pio 127 GPIO_ACTIVE_HIGH>;
vin-supply = <&pp3300_g>;
+ off-on-delay-us = <500000>;
};
/* separately switched 3.3V power rail */
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 84cbdf6e9eb0..47dea10dd3b8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -2234,7 +2234,7 @@
};
};
- gpu0-thermal {
+ gpu-thermal {
polling-delay = <1000>;
polling-delay-passive = <250>;
thermal-sensors = <&lvts_ap MT8192_AP_GPU0>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-dojo-r1.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-dojo-r1.dts
new file mode 100644
index 000000000000..88123842c818
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-dojo-r1.dts
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+#include "mt8195-cherry.dtsi"
+
+/ {
+ model = "HP Dojo (sku 1, 3, 5, 7) board";
+ chassis-type = "convertible";
+ compatible = "google,dojo-sku7", "google,dojo-sku5",
+ "google,dojo-sku3", "google,dojo-sku1",
+ "google,dojo", "mediatek,mt8195";
+};
+
+&audio_codec {
+ compatible = "realtek,rt5682s";
+ realtek,amic-delay-ms = <250>;
+};
+
+&i2c2 {
+ spk_r_amp: amplifier@38 {
+ compatible = "maxim,max98390";
+ reg = <0x38>;
+ reset-gpios = <&pio 100 GPIO_ACTIVE_LOW>;
+ sound-name-prefix = "Right";
+ #sound-dai-cells = <0>;
+ };
+
+ spk_l_amp: amplifier@39 {
+ compatible = "maxim,max98390";
+ reg = <0x39>;
+ sound-name-prefix = "Left";
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2c4 {
+ touchscreen@15 {
+ compatible = "hid-over-i2c";
+ reg = <0x15>;
+ hid-descr-addr = <0x0001>;
+ interrupts-extended = <&pio 92 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ post-power-on-delay-ms = <10>;
+ vdd-supply = <&pp3300_s3>;
+ };
+};
+
+&keyboard_controller {
+ linux,keymap = <
+ CROS_STD_MAIN_KEYMAP
+
+ MATRIX_KEY(0x00, 0x02, KEY_BACK)
+ MATRIX_KEY(0x03, 0x02, KEY_REFRESH)
+ MATRIX_KEY(0x02, 0x02, KEY_ZOOM)
+ MATRIX_KEY(0x01, 0x02, KEY_SCALE)
+ MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)
+ MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x02, 0x09, KEY_KBDILLUMTOGGLE)
+ MATRIX_KEY(0x01, 0x09, KEY_PLAYPAUSE)
+ MATRIX_KEY(0x00, 0x04, KEY_MICMUTE)
+ MATRIX_KEY(0x00, 0x01, KEY_MUTE)
+ MATRIX_KEY(0x01, 0x05, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x03, 0x05, KEY_VOLUMEUP)
+ >;
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins_default>;
+ status = "okay";
+};
+
+&pciephy {
+ status = "okay";
+};
+
+&pio_default {
+ pins-low-power-hdmi-disable {
+ pinmux = <PINMUX_GPIO31__FUNC_GPIO31>,
+ <PINMUX_GPIO32__FUNC_GPIO32>,
+ <PINMUX_GPIO33__FUNC_GPIO33>,
+ <PINMUX_GPIO34__FUNC_GPIO34>,
+ <PINMUX_GPIO35__FUNC_GPIO35>;
+ input-enable;
+ bias-pull-down;
+ };
+};
+
+&sound {
+ compatible = "mediatek,mt8195_mt6359_max98390_rt5682";
+ model = "m8195_m98390_5682s";
+
+ audio-routing =
+ "Headphone", "HPOL",
+ "Headphone", "HPOR",
+ "IN1P", "Headset Mic",
+ "Right Spk", "Right BE_OUT",
+ "Left Spk", "Left BE_OUT";
+
+ spk-playback-dai-link {
+ codec {
+ sound-dai = <&spk_r_amp>, <&spk_l_amp>;
+ };
+ };
+};
+
+&spk_amplifier {
+ /* Disable RT1019P, not present on Dojo */
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index 4a11918da370..fe5400e17b0f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -240,6 +240,7 @@
spk_amplifier: rt1019p {
compatible = "realtek,rt1019p";
label = "rt1019p";
+ #sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&rt1019p_pins_default>;
sdb-gpios = <&pio 100 GPIO_ACTIVE_HIGH>;
@@ -366,6 +367,7 @@
&dp_tx {
status = "okay";
+ #sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&dptx_pin>;
@@ -436,6 +438,7 @@
/* Realtek RT5682i or RT5682s, sharing the same configuration */
reg = <0x1a>;
interrupts-extended = <&pio 89 IRQ_TYPE_EDGE_BOTH>;
+ #sound-dai-cells = <0>;
realtek,jd-src = <1>;
AVDD-supply = <&mt6359_vio18_ldo_reg>;
@@ -1162,6 +1165,48 @@
"AFE_SOF_DL2", "AFE_SOF_DL3", "AFE_SOF_UL4", "AFE_SOF_UL5";
pinctrl-names = "default";
pinctrl-0 = <&aud_pins_default>;
+
+ audio-routing =
+ "Headphone", "HPOL",
+ "Headphone", "HPOR",
+ "IN1P", "Headset Mic",
+ "Ext Spk", "Speaker";
+
+ mm-dai-link {
+ link-name = "ETDM1_IN_BE";
+ mediatek,clk-provider = "cpu";
+ };
+
+ hs-playback-dai-link {
+ link-name = "ETDM1_OUT_BE";
+ mediatek,clk-provider = "cpu";
+ codec {
+ sound-dai = <&audio_codec>;
+ };
+ };
+
+ hs-capture-dai-link {
+ link-name = "ETDM2_IN_BE";
+ mediatek,clk-provider = "cpu";
+ codec {
+ sound-dai = <&audio_codec>;
+ };
+ };
+
+ spk-playback-dai-link {
+ link-name = "ETDM2_OUT_BE";
+ mediatek,clk-provider = "cpu";
+ codec {
+ sound-dai = <&spk_amplifier>;
+ };
+ };
+
+ displayport-dai-link {
+ link-name = "DPTX_BE";
+ codec {
+ sound-dai = <&dp_tx>;
+ };
+ };
};
&spi0 {
@@ -1389,6 +1434,11 @@
MATRIX_KEY(0x02, 0x09, 0) /* T8 */
MATRIX_KEY(0x01, 0x09, 0) /* T9 */
MATRIX_KEY(0x00, 0x04, 0) /* T10 */
+
+ /* T11 to T13 are present only on Dojo */
+ MATRIX_KEY(0x00, 0x01, 0) /* T11 */
+ MATRIX_KEY(0x01, 0x05, 0) /* T12 */
+ MATRIX_KEY(0x03, 0x05, 0) /* T13 */
>;
linux,keymap = <
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
index b82f7176b4a1..31d424b8fc7c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
@@ -305,14 +305,14 @@
<PINMUX_GPIO78__FUNC_GBE_TXD2>,
<PINMUX_GPIO79__FUNC_GBE_TXD1>,
<PINMUX_GPIO80__FUNC_GBE_TXD0>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
};
pins-cc {
pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
<PINMUX_GPIO88__FUNC_GBE_TXEN>,
<PINMUX_GPIO87__FUNC_GBE_RXDV>,
<PINMUX_GPIO86__FUNC_GBE_RXC>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
};
pins-rxd {
pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
@@ -377,7 +377,7 @@
mmc0_default_pins: mmc0-default-pins {
pins-clk {
pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -392,13 +392,13 @@
<PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
<PINMUX_GPIO121__FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins-rst {
pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
@@ -406,7 +406,7 @@
mmc0_uhs_pins: mmc0-uhs-pins {
pins-clk {
pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -421,19 +421,19 @@
<PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
<PINMUX_GPIO121__FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins-ds {
pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
pins-rst {
pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
@@ -441,7 +441,7 @@
mmc1_default_pins: mmc1-default-pins {
pins-clk {
pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -452,7 +452,7 @@
<PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
<PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
@@ -465,7 +465,7 @@
mmc1_uhs_pins: mmc1-uhs-pins {
pins-clk {
pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -476,7 +476,7 @@
<PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
<PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
index 341b6e074139..83456d649ff7 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
@@ -74,7 +74,6 @@
pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
<PINMUX_GPIO9__FUNC_SCL0>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
- mediatek,drive-strength-adv = <0>;
drive-strength = <6>;
};
};
@@ -84,7 +83,6 @@
pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
<PINMUX_GPIO11__FUNC_SCL1>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
- mediatek,drive-strength-adv = <0>;
drive-strength = <6>;
};
};
@@ -94,7 +92,7 @@
pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
<PINMUX_GPIO17__FUNC_SCL4>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
- mediatek,drive-strength-adv = <7>;
+ drive-strength-microamp = <1000>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 5d8b68f86ce4..2ee45752583c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -3880,7 +3880,7 @@
};
};
- gpu0-thermal {
+ gpu-thermal {
polling-delay = <1000>;
polling-delay-passive = <250>;
thermal-sensors = <&lvts_ap MT8195_AP_GPU0>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts
index 50cbaefa1a99..4211a992dd9d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts
@@ -308,7 +308,7 @@
mmc1_uhs_pins: mmc1-uhs-pins {
clk-pins {
pinmux = <MT8365_PIN_88_MSDC1_CLK__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -319,7 +319,7 @@
<MT8365_PIN_92_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
<MT8365_PIN_87_MSDC1_CMD__FUNC_MSDC1_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8365.dtsi b/arch/arm64/boot/dts/mediatek/mt8365.dtsi
index 24581f7410aa..eb449bfa8803 100644
--- a/arch/arm64/boot/dts/mediatek/mt8365.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8365.dtsi
@@ -300,9 +300,8 @@
};
scpsys: syscon@10006000 {
- compatible = "mediatek,mt8365-syscfg", "syscon", "simple-mfd";
+ compatible = "mediatek,mt8365-scpsys", "syscon", "simple-mfd";
reg = <0 0x10006000 0 0x1000>;
- #power-domain-cells = <1>;
/* System Power Manager */
spm: power-controller {
diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
new file mode 100644
index 000000000000..1474bef7e754
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
@@ -0,0 +1,880 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Chris Chen <chris-qj.chen@mediatek.com>
+ * Pablo Sun <pablo.sun@mediatek.com>
+ * Macpaul Lin <macpaul.lin@mediatek.com>
+ */
+/dts-v1/;
+
+#include "mt8188.dtsi"
+#include "mt6359.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/usb/pd.h>
+
+/ {
+ model = "MediaTek Genio-700 EVK";
+ compatible = "mediatek,mt8390-evk", "mediatek,mt8390",
+ "mediatek,mt8188";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:921600n8";
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0x2 0x00000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * 12 MiB reserved for OP-TEE (BL32)
+ * +-----------------------+ 0x43e0_0000
+ * | SHMEM 2MiB |
+ * +-----------------------+ 0x43c0_0000
+ * | | TA_RAM 8MiB |
+ * + TZDRAM +--------------+ 0x4340_0000
+ * | | TEE_RAM 2MiB |
+ * +-----------------------+ 0x4320_0000
+ */
+ optee_reserved: optee@43200000 {
+ no-map;
+ reg = <0 0x43200000 0 0x00c00000>;
+ };
+
+ scp_mem: memory@50000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x50000000 0 0x2900000>;
+ no-map;
+ };
+
+ /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+ bl31_secmon_reserved: memory@54600000 {
+ no-map;
+ reg = <0 0x54600000 0x0 0x200000>;
+ };
+
+ apu_mem: memory@55000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x55000000 0 0x1400000>; /* 20 MB */
+ };
+
+ vpu_mem: memory@57000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x57000000 0 0x1400000>; /* 20 MB */
+ };
+ };
+
+ common_fixed_5v: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5v_en";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pio 10 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ edp_panel_fixed_3v3: regulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "edp_panel_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 15 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&edp_panel_3v3_en_pins>;
+ };
+
+ gpio_fixed_3v3: regulator-2 {
+ compatible = "regulator-fixed";
+ regulator-name = "gpio_3v3_en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ sdio_fixed_1v8: regulator-3 {
+ compatible = "regulator-fixed";
+ regulator-name = "sdio_io";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ sdio_fixed_3v3: regulator-4 {
+ compatible = "regulator-fixed";
+ regulator-name = "sdio_card";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 74 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ touch0_fixed_3v3: regulator-5 {
+ compatible = "regulator-fixed";
+ regulator-name = "touch_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 119 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usb_hub_fixed_3v3: regulator-6 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_hub_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 112 GPIO_ACTIVE_HIGH>; /* HUB_3V3_EN */
+ startup-delay-us = <10000>;
+ enable-active-high;
+ };
+
+ usb_hub_reset_1v8: regulator-7 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_hub_reset";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&pio 7 GPIO_ACTIVE_HIGH>; /* HUB_RESET */
+ vin-supply = <&usb_hub_fixed_3v3>;
+ };
+
+ usb_p0_vbus: regulator-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_p0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pio 84 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usb_p1_vbus: regulator-9 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_p1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pio 87 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usb_p2_vbus: regulator-10 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_p2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ touchscreen@5d {
+ compatible = "goodix,gt9271";
+ reg = <0x5d>;
+ interrupt-parent = <&pio>;
+ interrupts-extended = <&pio 6 IRQ_TYPE_EDGE_RISING>;
+ irq-gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
+ AVDD28-supply = <&touch0_fixed_3v3>;
+ VDDIO-supply = <&mt6359_vio18_ldo_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_pins>;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+ pinctrl-1 = <&rt1715_int_pins>;
+ clock-frequency = <1000000>;
+ status = "okay";
+};
+
+&i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&i2c6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&mmc0 {
+ status = "okay";
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc0_default_pins>;
+ pinctrl-1 = <&mmc0_uhs_pins>;
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ supports-cqe;
+ cap-mmc-hw-reset;
+ no-sdio;
+ no-sd;
+ hs400-ds-delay = <0x1481b>;
+ vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+ vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+ non-removable;
+};
+
+&mmc1 {
+ status = "okay";
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_default_pins>;
+ pinctrl-1 = <&mmc1_uhs_pins>;
+ bus-width = <4>;
+ max-frequency = <200000000>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ no-mmc;
+ no-sdio;
+ cd-gpios = <&pio 2 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&mt6359_vpa_buck_reg>;
+ vqmmc-supply = <&mt6359_vsim1_ldo_reg>;
+};
+
+&mt6359_vbbck_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vcn18_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vcn33_2_bt_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vcore_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vpa_buck_reg {
+ regulator-max-microvolt = <3100000>;
+};
+
+&mt6359_vpu_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vsim1_ldo_reg {
+ regulator-enable-ramp-delay = <480>;
+};
+
+&mt6359_vufs_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359codec {
+ mediatek,mic-type-0 = <1>; /* ACC */
+ mediatek,mic-type-1 = <3>; /* DCC */
+};
+
+&pio {
+ audio_default_pins: audio-default-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO101__FUNC_O_AUD_CLK_MOSI>,
+ <PINMUX_GPIO102__FUNC_O_AUD_SYNC_MOSI>,
+ <PINMUX_GPIO103__FUNC_O_AUD_DAT_MOSI0>,
+ <PINMUX_GPIO104__FUNC_O_AUD_DAT_MOSI1>,
+ <PINMUX_GPIO105__FUNC_I0_AUD_DAT_MISO0>,
+ <PINMUX_GPIO106__FUNC_I0_AUD_DAT_MISO1>,
+ <PINMUX_GPIO107__FUNC_B0_I2SIN_MCK>,
+ <PINMUX_GPIO108__FUNC_B0_I2SIN_BCK>,
+ <PINMUX_GPIO109__FUNC_B0_I2SIN_WS>,
+ <PINMUX_GPIO110__FUNC_I0_I2SIN_D0>,
+ <PINMUX_GPIO114__FUNC_O_I2SO2_MCK>,
+ <PINMUX_GPIO115__FUNC_B0_I2SO2_BCK>,
+ <PINMUX_GPIO116__FUNC_B0_I2SO2_WS>,
+ <PINMUX_GPIO117__FUNC_O_I2SO2_D0>,
+ <PINMUX_GPIO118__FUNC_O_I2SO2_D1>,
+ <PINMUX_GPIO121__FUNC_B0_PCM_CLK>,
+ <PINMUX_GPIO122__FUNC_B0_PCM_SYNC>,
+ <PINMUX_GPIO124__FUNC_I0_PCM_DI>,
+ <PINMUX_GPIO125__FUNC_O_DMIC1_CLK>,
+ <PINMUX_GPIO126__FUNC_I0_DMIC1_DAT>,
+ <PINMUX_GPIO128__FUNC_O_DMIC2_CLK>,
+ <PINMUX_GPIO129__FUNC_I0_DMIC2_DAT>;
+ };
+ };
+
+ dptx_pins: dptx-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO46__FUNC_I0_DP_TX_HPD>;
+ bias-pull-up;
+ };
+ };
+
+ edp_panel_3v3_en_pins: edp-panel-3v3-en-pins {
+ pins1 {
+ pinmux = <PINMUX_GPIO15__FUNC_B_GPIO15>;
+ output-high;
+ };
+ };
+
+ eth_default_pins: eth-default-pins {
+ pins-cc {
+ pinmux = <PINMUX_GPIO139__FUNC_B0_GBE_TXC>,
+ <PINMUX_GPIO140__FUNC_I0_GBE_RXC>,
+ <PINMUX_GPIO141__FUNC_I0_GBE_RXDV>,
+ <PINMUX_GPIO142__FUNC_O_GBE_TXEN>;
+ drive-strength = <8>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO143__FUNC_O_GBE_MDC>,
+ <PINMUX_GPIO144__FUNC_B1_GBE_MDIO>;
+ drive-strength = <8>;
+ input-enable;
+ };
+
+ pins-power {
+ pinmux = <PINMUX_GPIO145__FUNC_B_GPIO145>,
+ <PINMUX_GPIO146__FUNC_B_GPIO146>;
+ output-high;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO135__FUNC_I0_GBE_RXD3>,
+ <PINMUX_GPIO136__FUNC_I0_GBE_RXD2>,
+ <PINMUX_GPIO137__FUNC_I0_GBE_RXD1>,
+ <PINMUX_GPIO138__FUNC_I0_GBE_RXD0>;
+ drive-strength = <8>;
+ };
+
+ pins-txd {
+ pinmux = <PINMUX_GPIO131__FUNC_O_GBE_TXD3>,
+ <PINMUX_GPIO132__FUNC_O_GBE_TXD2>,
+ <PINMUX_GPIO133__FUNC_O_GBE_TXD1>,
+ <PINMUX_GPIO134__FUNC_O_GBE_TXD0>;
+ drive-strength = <8>;
+ };
+ };
+
+ eth_sleep_pins: eth-sleep-pins {
+ pins-cc {
+ pinmux = <PINMUX_GPIO139__FUNC_B_GPIO139>,
+ <PINMUX_GPIO140__FUNC_B_GPIO140>,
+ <PINMUX_GPIO141__FUNC_B_GPIO141>,
+ <PINMUX_GPIO142__FUNC_B_GPIO142>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO143__FUNC_B_GPIO143>,
+ <PINMUX_GPIO144__FUNC_B_GPIO144>;
+ input-disable;
+ bias-disable;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO135__FUNC_B_GPIO135>,
+ <PINMUX_GPIO136__FUNC_B_GPIO136>,
+ <PINMUX_GPIO137__FUNC_B_GPIO137>,
+ <PINMUX_GPIO138__FUNC_B_GPIO138>;
+ };
+
+ pins-txd {
+ pinmux = <PINMUX_GPIO131__FUNC_B_GPIO131>,
+ <PINMUX_GPIO132__FUNC_B_GPIO132>,
+ <PINMUX_GPIO133__FUNC_B_GPIO133>,
+ <PINMUX_GPIO134__FUNC_B_GPIO134>;
+ };
+ };
+
+ i2c0_pins: i2c0-pins {
+ pins {
+ pinmux = <PINMUX_GPIO56__FUNC_B1_SDA0>,
+ <PINMUX_GPIO55__FUNC_B1_SCL0>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c1_pins: i2c1-pins {
+ pins {
+ pinmux = <PINMUX_GPIO58__FUNC_B1_SDA1>,
+ <PINMUX_GPIO57__FUNC_B1_SCL1>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c2_pins: i2c2-pins {
+ pins {
+ pinmux = <PINMUX_GPIO60__FUNC_B1_SDA2>,
+ <PINMUX_GPIO59__FUNC_B1_SCL2>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c3_pins: i2c3-pins {
+ pins {
+ pinmux = <PINMUX_GPIO62__FUNC_B1_SDA3>,
+ <PINMUX_GPIO61__FUNC_B1_SCL3>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c4_pins: i2c4-pins {
+ pins {
+ pinmux = <PINMUX_GPIO64__FUNC_B1_SDA4>,
+ <PINMUX_GPIO63__FUNC_B1_SCL4>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c5_pins: i2c5-pins {
+ pins {
+ pinmux = <PINMUX_GPIO66__FUNC_B1_SDA5>,
+ <PINMUX_GPIO65__FUNC_B1_SCL5>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c6_pins: i2c6-pins {
+ pins {
+ pinmux = <PINMUX_GPIO68__FUNC_B1_SDA6>,
+ <PINMUX_GPIO67__FUNC_B1_SCL6>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ gpio_key_pins: gpio-key-pins {
+ pins {
+ pinmux = <PINMUX_GPIO42__FUNC_B1_KPCOL0>,
+ <PINMUX_GPIO43__FUNC_B1_KPCOL1>,
+ <PINMUX_GPIO44__FUNC_B1_KPROW0>;
+ };
+ };
+
+ mmc0_default_pins: mmc0-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO157__FUNC_B1_MSDC0_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0>,
+ <PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1>,
+ <PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2>,
+ <PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3>,
+ <PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4>,
+ <PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5>,
+ <PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6>,
+ <PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7>,
+ <PINMUX_GPIO156__FUNC_B1_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO155__FUNC_O_MSDC0_RSTB>;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc0_uhs_pins: mmc0-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO157__FUNC_B1_MSDC0_CLK>;
+ drive-strength = <8>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0>,
+ <PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1>,
+ <PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2>,
+ <PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3>,
+ <PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4>,
+ <PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5>,
+ <PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6>,
+ <PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7>,
+ <PINMUX_GPIO156__FUNC_B1_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <8>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-ds {
+ pinmux = <PINMUX_GPIO162__FUNC_B0_MSDC0_DSL>;
+ drive-strength = <8>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO155__FUNC_O_MSDC0_RSTB>;
+ drive-strength = <8>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_default_pins: mmc1-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO164__FUNC_B1_MSDC1_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO163__FUNC_B1_MSDC1_CMD>,
+ <PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0>,
+ <PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1>,
+ <PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2>,
+ <PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-insert {
+ pinmux = <PINMUX_GPIO2__FUNC_B_GPIO2>;
+ bias-pull-up;
+ };
+ };
+
+ mmc1_uhs_pins: mmc1-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO164__FUNC_B1_MSDC1_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO163__FUNC_B1_MSDC1_CMD>,
+ <PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0>,
+ <PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1>,
+ <PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2>,
+ <PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc2_default_pins: mmc2-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO170__FUNC_B1_MSDC2_CLK>;
+ drive-strength = <4>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO169__FUNC_B1_MSDC2_CMD>,
+ <PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0>,
+ <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>,
+ <PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2>,
+ <PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-pcm {
+ pinmux = <PINMUX_GPIO123__FUNC_O_PCM_DO>;
+ };
+ };
+
+ mmc2_uhs_pins: mmc2-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO170__FUNC_B1_MSDC2_CLK>;
+ drive-strength = <4>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO169__FUNC_B1_MSDC2_CMD>,
+ <PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0>,
+ <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>,
+ <PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2>,
+ <PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc2_eint_pins: mmc2-eint-pins {
+ pins-dat1 {
+ pinmux = <PINMUX_GPIO172__FUNC_B_GPIO172>;
+ input-enable;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc2_dat1_pins: mmc2-dat1-pins {
+ pins-dat1 {
+ pinmux = <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ panel_default_pins: panel-default-pins {
+ pins-dcdc {
+ pinmux = <PINMUX_GPIO45__FUNC_B_GPIO45>;
+ output-low;
+ };
+
+ pins-en {
+ pinmux = <PINMUX_GPIO111__FUNC_B_GPIO111>;
+ output-low;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO25__FUNC_B_GPIO25>;
+ output-high;
+ };
+ };
+
+ rt1715_int_pins: rt1715-int-pins {
+ pins_cmd0_dat {
+ pinmux = <PINMUX_GPIO12__FUNC_B_GPIO12>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+
+ spi0_pins: spi0-pins {
+ pins-spi {
+ pinmux = <PINMUX_GPIO69__FUNC_O_SPIM0_CSB>,
+ <PINMUX_GPIO70__FUNC_O_SPIM0_CLK>,
+ <PINMUX_GPIO71__FUNC_B0_SPIM0_MOSI>,
+ <PINMUX_GPIO72__FUNC_B0_SPIM0_MISO>;
+ bias-disable;
+ };
+ };
+
+ spi1_pins: spi1-pins {
+ pins-spi {
+ pinmux = <PINMUX_GPIO75__FUNC_O_SPIM1_CSB>,
+ <PINMUX_GPIO76__FUNC_O_SPIM1_CLK>,
+ <PINMUX_GPIO77__FUNC_B0_SPIM1_MOSI>,
+ <PINMUX_GPIO78__FUNC_B0_SPIM1_MISO>;
+ bias-disable;
+ };
+ };
+
+ spi2_pins: spi2-pins {
+ pins-spi {
+ pinmux = <PINMUX_GPIO79__FUNC_O_SPIM2_CSB>,
+ <PINMUX_GPIO80__FUNC_O_SPIM2_CLK>,
+ <PINMUX_GPIO81__FUNC_B0_SPIM2_MOSI>,
+ <PINMUX_GPIO82__FUNC_B0_SPIM2_MISO>;
+ bias-disable;
+ };
+ };
+
+ touch_pins: touch-pins {
+ pins-irq {
+ pinmux = <PINMUX_GPIO6__FUNC_B_GPIO6>;
+ input-enable;
+ bias-disable;
+ };
+
+ pins-reset {
+ pinmux = <PINMUX_GPIO5__FUNC_B_GPIO5>;
+ output-high;
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ pins {
+ pinmux = <PINMUX_GPIO31__FUNC_O_UTXD0>,
+ <PINMUX_GPIO32__FUNC_I1_URXD0>;
+ bias-pull-up;
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ pins {
+ pinmux = <PINMUX_GPIO33__FUNC_O_UTXD1>,
+ <PINMUX_GPIO34__FUNC_I1_URXD1>;
+ bias-pull-up;
+ };
+ };
+
+ uart2_pins: uart2-pins {
+ pins {
+ pinmux = <PINMUX_GPIO35__FUNC_O_UTXD2>,
+ <PINMUX_GPIO36__FUNC_I1_URXD2>;
+ bias-pull-up;
+ };
+ };
+
+ usb_default_pins: usb-default-pins {
+ pins-iddig {
+ pinmux = <PINMUX_GPIO83__FUNC_B_GPIO83>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-valid {
+ pinmux = <PINMUX_GPIO85__FUNC_I0_VBUSVALID>;
+ input-enable;
+ };
+
+ pins-vbus {
+ pinmux = <PINMUX_GPIO84__FUNC_O_USB_DRVVBUS>;
+ output-high;
+ };
+
+ };
+
+ usb1_default_pins: usb1-default-pins {
+ pins-valid {
+ pinmux = <PINMUX_GPIO88__FUNC_I0_VBUSVALID_1P>;
+ input-enable;
+ };
+
+ pins-usb-hub-3v3-en {
+ pinmux = <PINMUX_GPIO112__FUNC_B_GPIO112>;
+ output-high;
+ };
+ };
+
+ wifi_pwrseq_pins: wifi-pwrseq-pins {
+ pins-wifi-enable {
+ pinmux = <PINMUX_GPIO127__FUNC_B_GPIO127>;
+ output-low;
+ };
+ };
+};
+
+&pmic {
+ interrupt-parent = <&pio>;
+ interrupts = <222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+ memory-region = <&scp_mem>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spi2 {
+ pinctrl-0 = <&spi2_pins>;
+ pinctrl-names = "default";
+ mediatek,pad-select = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+};
+
+&u3phy0 {
+ status = "okay";
+};
+
+&u3phy1 {
+ status = "okay";
+};
+
+&u3phy2 {
+ status = "okay";
+};
+
+&xhci0 {
+ status = "okay";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+};
+
+&xhci1 {
+ status = "okay";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ vbus-supply = <&usb_hub_reset_1v8>;
+};
+
+&xhci2 {
+ status = "okay";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
index 1558649f633c..a06610fff8ad 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
@@ -475,7 +475,7 @@
<PINMUX_GPIO86__FUNC_GBE_RXC>,
<PINMUX_GPIO87__FUNC_GBE_RXDV>,
<PINMUX_GPIO88__FUNC_GBE_TXEN>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
};
pins-mdio {
@@ -502,7 +502,7 @@
<PINMUX_GPIO78__FUNC_GBE_TXD2>,
<PINMUX_GPIO79__FUNC_GBE_TXD1>,
<PINMUX_GPIO80__FUNC_GBE_TXD0>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
};
};
@@ -567,7 +567,7 @@
pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
<PINMUX_GPIO13__FUNC_SCL2>;
bias-pull-up = <MTK_PULL_SET_RSEL_111>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
};
};
@@ -582,7 +582,7 @@
mmc0_default_pins: mmc0-default-pins {
pins-clk {
pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -597,13 +597,13 @@
<PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
<PINMUX_GPIO121__FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins-rst {
pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
- drive-strength = <MTK_DRIVE_6mA>;
+ drive-strength = <6>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
@@ -611,7 +611,7 @@
mmc0_uhs_pins: mmc0-uhs-pins {
pins-clk {
pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -626,19 +626,19 @@
<PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
<PINMUX_GPIO121__FUNC_MSDC0_CMD>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
pins-ds {
pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
pins-rst {
pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
@@ -646,7 +646,7 @@
mmc1_default_pins: mmc1-default-pins {
pins-clk {
pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -657,7 +657,7 @@
<PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
<PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
@@ -665,7 +665,7 @@
mmc1_uhs_pins: mmc1-uhs-pins {
pins-clk {
pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
};
@@ -676,7 +676,7 @@
<PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
<PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
input-enable;
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <8>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
};
};
@@ -854,6 +854,10 @@
&u3phy1 {
status = "okay";
+
+ u3port1: usb-phy@700 {
+ mediatek,force-mode;
+ };
};
&u3phy2 {
@@ -900,6 +904,8 @@
};
&xhci1 {
+ phys = <&u2port1 PHY_TYPE_USB2>,
+ <&u3port1 PHY_TYPE_USB3>;
vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
new file mode 100644
index 000000000000..e4b2af9489a8
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
@@ -0,0 +1,1127 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 Kontron Europe GmbH
+ *
+ * Author: Michael Walle <mwalle@kernel.org>
+ */
+/dts-v1/;
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+ model = "Kontron 3.5\"-SBC-i1200";
+ compatible = "kontron,3-5-sbc-i1200", "mediatek,mt8395", "mediatek,mt8195";
+
+ aliases {
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pins>;
+
+ key-0 {
+ gpios = <&pio 106 GPIO_ACTIVE_LOW>;
+ label = "volume_up";
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
+ debounce-interval = <15>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ led-0 {
+ gpios = <&pio 107 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0x0 0x80000000>;
+ };
+
+ vsys: regulator-vsys {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * 12 MiB reserved for OP-TEE (BL32)
+ * +-----------------------+ 0x43e0_0000
+ * | SHMEM 2MiB |
+ * +-----------------------+ 0x43c0_0000
+ * | | TA_RAM 8MiB |
+ * + TZDRAM +--------------+ 0x4340_0000
+ * | | TEE_RAM 2MiB |
+ * +-----------------------+ 0x4320_0000
+ */
+ optee_reserved: optee@43200000 {
+ no-map;
+ reg = <0 0x43200000 0 0x00c00000>;
+ };
+
+ scp_mem: memory@50000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x50000000 0 0x2900000>;
+ no-map;
+ };
+
+ vpu_mem: memory@53000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
+ };
+
+ /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+ bl31_secmon_mem: memory@54600000 {
+ no-map;
+ reg = <0 0x54600000 0x0 0x200000>;
+ };
+
+ snd_dma_mem: memory@60000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x60000000 0 0x1100000>;
+ no-map;
+ };
+
+ apu_mem: memory@62000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
+ };
+ };
+
+ thermal_sensor0: thermal-sensor-0 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&auxadc 0>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = <(-25000) 1474
+ (-20000) 1374
+ (-15000) 1260
+ (-10000) 1134
+ (-5000) 1004
+ 0 874
+ 5000 750
+ 10000 635
+ 15000 532
+ 20000 443
+ 25000 367
+ 30000 303
+ 35000 250
+ 40000 206
+ 45000 170
+ 50000 141
+ 55000 117
+ 60000 97
+ 65000 81
+ 70000 68
+ 75000 57
+ 80000 48
+ 85000 41
+ 90000 35
+ 95000 30
+ 100000 25
+ 105000 22
+ 110000 19
+ 115000 16
+ 120000 14
+ 125000 12
+ 130000 10
+ 135000 9
+ 140000 8
+ 145000 7
+ 150000 6>;
+ };
+
+ thermal_sensor1: thermal-sensor-1 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&auxadc 1>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = <(-25000) 1474
+ (-20000) 1374
+ (-15000) 1260
+ (-10000) 1134
+ (-5000) 1004
+ 0 874
+ 5000 750
+ 10000 635
+ 15000 532
+ 20000 443
+ 25000 367
+ 30000 303
+ 35000 250
+ 40000 206
+ 45000 170
+ 50000 141
+ 55000 117
+ 60000 97
+ 65000 81
+ 70000 68
+ 75000 57
+ 80000 48
+ 85000 41
+ 90000 35
+ 95000 30
+ 100000 25
+ 105000 22
+ 110000 19
+ 115000 16
+ 120000 14
+ 125000 12
+ 130000 10
+ 135000 9
+ 140000 8
+ 145000 7
+ 150000 6>;
+ };
+
+ thermal_sensor2: thermal-sensor-2 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&auxadc 2>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = <(-25000) 1474
+ (-20000) 1374
+ (-15000) 1260
+ (-10000) 1134
+ (-5000) 1004
+ 0 874
+ 5000 750
+ 10000 635
+ 15000 532
+ 20000 443
+ 25000 367
+ 30000 303
+ 35000 250
+ 40000 206
+ 45000 170
+ 50000 141
+ 55000 117
+ 60000 97
+ 65000 81
+ 70000 68
+ 75000 57
+ 80000 48
+ 85000 41
+ 90000 35
+ 95000 30
+ 100000 25
+ 105000 22
+ 110000 19
+ 115000 16
+ 120000 14
+ 125000 12
+ 130000 10
+ 135000 9
+ 140000 8
+ 145000 7
+ 150000 6>;
+ };
+};
+
+&auxadc {
+ status = "okay";
+};
+
+&eth {
+ phy-mode ="rgmii-id";
+ phy-handle = <&ethernet_phy0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&eth_default_pins>;
+ pinctrl-1 = <&eth_sleep_pins>;
+ status = "okay";
+
+ mdio {
+ ethernet_phy0: ethernet-phy@1 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&pio 93 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&gpu {
+ status = "okay";
+ mali-supply = <&mt6315_7_vbuck1>;
+};
+
+/* CSI1/CSI2 connector */
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+};
+
+/* CSI3 connector */
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ /* LVDS bridge @f */
+};
+
+/* Touch panel connector */
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+};
+
+/* B2B connector */
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c4_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c6 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c6_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ mt6360: pmic@34 {
+ compatible = "mediatek,mt6360";
+ reg = <0x34>;
+ interrupt-controller;
+ interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-names = "IRQB";
+ #interrupt-cells = <1>;
+
+ regulator {
+ compatible = "mediatek,mt6360-regulator";
+ LDO_VIN1-supply = <&vsys>;
+ LDO_VIN2-supply = <&vsys>;
+ LDO_VIN3-supply = <&vsys>;
+
+ mt6360_buck1: BUCK1 {
+ regulator-name = "emi_vdd2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP
+ MT6360_OPMODE_ULP>;
+ regulator-always-on;
+ };
+
+ mt6360_buck2: BUCK2 {
+ regulator-name = "emi_vddq";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP
+ MT6360_OPMODE_ULP>;
+ regulator-always-on;
+ };
+
+ mt6360_ldo1: LDO1 {
+ regulator-name = "mt6360_ldo1"; /* Test point */
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo2: LDO2 {
+ regulator-name = "panel1_p1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo3: LDO3 {
+ regulator-name = "vmc_pmu";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo5: LDO5 {
+ regulator-name = "vmch_pmu";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo6: LDO6 {
+ regulator-name = "mt6360_ldo6"; /* Test point */
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2100000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo7: LDO7 {
+ regulator-name = "emi_vmddr_en";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc0_default_pins>;
+ pinctrl-1 = <&mmc0_uhs_pins>;
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ hs400-ds-delay = <0x14c11>;
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ no-sdio;
+ no-sd;
+ non-removable;
+ vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+ vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_default_pins>, <&mmc1_detect_pins>;
+ pinctrl-1 = <&mmc1_default_pins>;
+ cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ max-frequency = <200000000>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ no-mmc;
+ vmmc-supply = <&mt6360_ldo5>;
+ vqmmc-supply = <&mt6360_ldo3>;
+ status = "okay";
+};
+
+&mt6359_vbbck_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vcore_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vproc1_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vproc2_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vpu_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vsram_md_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vsram_others_ldo_reg {
+ regulator-always-on;
+};
+
+&nor_flash {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nor_pins_default>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-rx-bus-width = <2>;
+ spi-tx-bus-width = <2>;
+ };
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins_default>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins_default>;
+ status = "okay";
+};
+
+&pciephy {
+ status = "okay";
+};
+
+&pio {
+ eth_default_pins: eth-default-pins {
+ pins-txd {
+ pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
+ <PINMUX_GPIO78__FUNC_GBE_TXD2>,
+ <PINMUX_GPIO79__FUNC_GBE_TXD1>,
+ <PINMUX_GPIO80__FUNC_GBE_TXD0>;
+ drive-strength = <8>;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+ <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+ <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+ <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+ };
+
+ pins-cc {
+ pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
+ <PINMUX_GPIO86__FUNC_GBE_RXC>,
+ <PINMUX_GPIO87__FUNC_GBE_RXDV>,
+ <PINMUX_GPIO88__FUNC_GBE_TXEN>;
+ drive-strength = <8>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
+ <PINMUX_GPIO90__FUNC_GBE_MDIO>;
+ input-enable;
+ };
+
+ pins-power {
+ pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
+ <PINMUX_GPIO92__FUNC_GPIO92>;
+ output-high;
+ };
+
+ pins-reset {
+ pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
+ output-high;
+ };
+
+ pins-interrupt {
+ pinmux = <PINMUX_GPIO94__FUNC_GPIO94>;
+ input-enable;
+ };
+ };
+
+ eth_sleep_pins: eth-sleep-pins {
+ pins-txd {
+ pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+ <PINMUX_GPIO78__FUNC_GPIO78>,
+ <PINMUX_GPIO79__FUNC_GPIO79>,
+ <PINMUX_GPIO80__FUNC_GPIO80>;
+ };
+
+ pins-cc {
+ pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+ <PINMUX_GPIO88__FUNC_GPIO88>,
+ <PINMUX_GPIO87__FUNC_GPIO87>,
+ <PINMUX_GPIO86__FUNC_GPIO86>;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+ <PINMUX_GPIO82__FUNC_GPIO82>,
+ <PINMUX_GPIO83__FUNC_GPIO83>,
+ <PINMUX_GPIO84__FUNC_GPIO84>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+ <PINMUX_GPIO90__FUNC_GPIO90>;
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ gpio_keys_pins: gpio-keys-pins {
+ pins {
+ pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
+ input-enable;
+ };
+ };
+
+ i2c0_pins: i2c0-pins {
+ pins {
+ pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+ <PINMUX_GPIO9__FUNC_SCL0>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c1_pins: i2c1-pins {
+ pins {
+ pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
+ <PINMUX_GPIO11__FUNC_SCL1>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c2_pins: i2c2-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+ <PINMUX_GPIO13__FUNC_SCL2>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c3_pins: i2c3-pins {
+ pins {
+ pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
+ <PINMUX_GPIO15__FUNC_SCL3>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c4_pins: i2c4-pins {
+ pins {
+ pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+ <PINMUX_GPIO17__FUNC_SCL4>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c6_pins: i2c6-pins {
+ pins {
+ pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+ <PINMUX_GPIO26__FUNC_SCL6>;
+ bias-pull-up;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ mmc0_default_pins: mmc0-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+ <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+ <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+ <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+ <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+ <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+ <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+ <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+ <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc0_uhs_pins: mmc0-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+ drive-strength = <8>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+ <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+ <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+ <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+ <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+ <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+ <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+ <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+ <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <8>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-ds {
+ pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+ drive-strength = <8>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+ drive-strength = <8>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_default_pins: mmc1-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+ drive-strength = <8>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+ <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+ <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+ <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+ <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+ input-enable;
+ drive-strength = <8>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_detect_pins: mmc1-detect-pins {
+ pins-insert {
+ pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
+ bias-pull-up;
+ };
+ };
+
+ nor_pins_default: nor-default-pins {
+ pins-ck-io {
+ pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+ <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+ <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ pins-cs {
+ pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>;
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
+ pcie0_pins_default: pcie0-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+ <PINMUX_GPIO20__FUNC_PERSTN>,
+ <PINMUX_GPIO21__FUNC_CLKREQN>;
+ bias-pull-up;
+ };
+ };
+
+ pcie1_pins_default: pcie1-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
+ <PINMUX_GPIO1__FUNC_CLKREQN_1>,
+ <PINMUX_GPIO2__FUNC_WAKEN_1>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ led_pins: led-pins {
+ pins-power-en {
+ pinmux = <PINMUX_GPIO107__FUNC_GPIO107>;
+ output-high;
+ };
+ };
+
+ spi0_pins: spi0-default-pins {
+ pins-cs-mosi-clk {
+ pinmux = <PINMUX_GPIO132__FUNC_SPIM0_CSB>,
+ <PINMUX_GPIO134__FUNC_SPIM0_MO>,
+ <PINMUX_GPIO133__FUNC_SPIM0_CLK>;
+ bias-disable;
+ };
+
+ pins-miso {
+ pinmux = <PINMUX_GPIO135__FUNC_SPIM0_MI>;
+ bias-pull-down;
+ };
+ };
+
+ spi1_pins: spi1-default-pins {
+ pins-cs-mosi-clk {
+ pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+ <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+ <PINMUX_GPIO137__FUNC_SPIM1_CLK>;
+ bias-disable;
+ };
+
+ pins-miso {
+ pinmux = <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+ bias-pull-down;
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ pins-rx {
+ pinmux = <PINMUX_GPIO99__FUNC_URXD0>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-tx {
+ pinmux = <PINMUX_GPIO98__FUNC_UTXD0>;
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ pins-rx {
+ pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-tx {
+ pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
+ };
+
+ pins-rts {
+ pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
+ };
+
+ pins-cts {
+ pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
+ input-enable;
+ };
+ };
+
+ uart2_pins: uart2-pins {
+ pins-rx {
+ pinmux = <PINMUX_GPIO68__FUNC_URXD2>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-tx {
+ pinmux = <PINMUX_GPIO67__FUNC_UTXD2>;
+ };
+
+ pins-rts {
+ pinmux = <PINMUX_GPIO66__FUNC_URTS2>;
+ };
+
+ pins-cts {
+ pinmux = <PINMUX_GPIO65__FUNC_UCTS2>;
+ input-enable;
+ };
+ };
+
+ uart3_pins: uart3-pins {
+ pins-rx {
+ pinmux = <PINMUX_GPIO5__FUNC_URXD3>;
+ input-enable;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-tx {
+ pinmux = <PINMUX_GPIO4__FUNC_UTXD3>;
+ };
+ };
+
+ uart4_pins: uart4-pins {
+ pins-rx {
+ pinmux = <PINMUX_GPIO7__FUNC_URXD4>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-tx {
+ pinmux = <PINMUX_GPIO6__FUNC_UTXD4>;
+ };
+ };
+};
+
+&pmic {
+ interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+ memory-region = <&scp_mem>;
+ firmware-name = "mediatek/mt8195/scp.img";
+ status = "okay";
+};
+
+&spmi {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ mt6315@6 {
+ compatible = "mediatek,mt6315-regulator";
+ reg = <0x6 SPMI_USID>;
+
+ regulators {
+ mt6315_6_vbuck1: vbuck1 {
+ regulator-name = "Vbcpu";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-ramp-delay = <6250>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ mt6315@7 {
+ compatible = "mediatek,mt6315-regulator";
+ reg = <0x7 SPMI_USID>;
+
+ regulators {
+ mt6315_7_vbuck1: vbuck1 {
+ regulator-name = "Vgpu";
+ regulator-min-microvolt = <625000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-ramp-delay = <6250>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+/* USB3.2 front port */
+&ssusb0 {
+ dr_mode = "host";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+/* USB2.0 M.2 Key-E */
+&ssusb2 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+/* USB2.0 to on-board usb hub */
+&ssusb3 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ mediatek,pad-select = <0>;
+ status = "okay";
+
+ tpm: tpm@0 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ reg = <0>;
+ spi-max-frequency = <18500000>;
+ };
+};
+
+/* B2B connector */
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ mediatek,pad-select = <0>;
+ status = "okay";
+};
+
+&thermal_zones {
+ cpu-thermal {
+ polling-delay = <1000>; /* milliseconds */
+ polling-delay-passive = <0>; /* milliseconds */
+ thermal-sensors = <&thermal_sensor0>;
+
+ trips {
+ trip-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pcb-top-thermal {
+ polling-delay = <1000>; /* milliseconds */
+ polling-delay-passive = <0>; /* milliseconds */
+ thermal-sensors = <&thermal_sensor1>;
+
+ trips {
+ trip-alert {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-crit {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pcb-bottom-thermal {
+ polling-delay = <1000>; /* milliseconds */
+ polling-delay-passive = <0>; /* milliseconds */
+ thermal-sensors = <&thermal_sensor2>;
+
+ trips {
+ trip-alert {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-crit {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+ status = "okay";
+};
+
+/* USB3 */
+&u3phy0 {
+ status = "okay";
+};
+
+/* PCIe1/USB2 */
+&u3phy1 {
+ status = "okay";
+};
+
+/* USB2 */
+&u3phy2 {
+ status = "okay";
+};
+
+/* USB2 */
+&u3phy3 {
+ status = "okay";
+};
+
+/* USB3.2 front port */
+&xhci0 {
+ status = "okay";
+};
+
+/* USB2.0 M.2 Key-B */
+&xhci1 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ mediatek,u3p-dis-msk = <0x01>;
+ status = "okay";
+};
+
+/* USB2.0 M.2 Key-E */
+&xhci2 {
+ status = "okay";
+};
+
+/* USB2.0 to on-board usb hub */
+&xhci3 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
index e5d9b671a405..4b5f6cf16f70 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
@@ -140,6 +140,38 @@
};
};
+&cpu0 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu1 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu2 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu3 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu4 {
+ cpu-supply = <&mt6315_6_vbuck1>;
+};
+
+&cpu5 {
+ cpu-supply = <&mt6315_6_vbuck1>;
+};
+
+&cpu6 {
+ cpu-supply = <&mt6315_6_vbuck1>;
+};
+
+&cpu7 {
+ cpu-supply = <&mt6315_6_vbuck1>;
+};
+
&eth {
phy-mode = "rgmii-rxid";
phy-handle = <&rgmii_phy>;
@@ -343,6 +375,14 @@
};
};
+&mfg0 {
+ domain-supply = <&mt6315_7_vbuck1>;
+};
+
+&mfg1 {
+ domain-supply = <&mt6359_vsram_others_ldo_reg>;
+};
+
/* MMC0 Controller: eMMC (HS400). Power lines are shared with UFS! */
&mmc0 {
pinctrl-names = "default", "state_uhs";
@@ -434,6 +474,8 @@
};
&pio {
+ mediatek,rsel-resistance-in-si-unit;
+
eth_default_pins: eth-default-pins {
pins-cc {
pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
@@ -509,7 +551,7 @@
pins-bus {
pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
<PINMUX_GPIO13__FUNC_SCL2>;
- bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ bias-pull-up = <1000>;
drive-strength = <6>;
drive-strength-microamp = <1000>;
};
@@ -519,7 +561,7 @@
pins-bus {
pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
<PINMUX_GPIO17__FUNC_SCL4>;
- bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ bias-pull-up = <1000>;
drive-strength-microamp = <1000>;
};
};
@@ -528,7 +570,7 @@
pins {
pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
<PINMUX_GPIO26__FUNC_SCL6>;
- bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ bias-disable;
};
};
@@ -683,6 +725,26 @@
};
};
+ usb3_port0_pins: usb3p0-default-pins {
+ pins-vbus {
+ pinmux = <PINMUX_GPIO63__FUNC_VBUSVALID>;
+ input-enable;
+ };
+ };
+
+ usb2_port0_pins: usb2p0-default-pins {
+ pins-iddig {
+ pinmux = <PINMUX_GPIO130__FUNC_IDDIG_1P>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-vbus {
+ pinmux = <PINMUX_GPIO131__FUNC_USB_DRVVBUS_1P>;
+ output-low;
+ };
+ };
+
wifi_vreg_pins: wifi-vreg-pins {
pins-wifi-pmu-en {
pinmux = <PINMUX_GPIO65__FUNC_GPIO65>;
@@ -707,6 +769,10 @@
status = "okay";
};
+&pciephy {
+ status = "okay";
+};
+
&pmic {
interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -774,6 +840,18 @@
};
};
+&u3phy0 {
+ status = "okay";
+};
+
+&u3phy1 {
+ status = "okay";
+};
+
+&u3phy2 {
+ status = "okay";
+};
+
&uart0 {
/* Exposed at 40 pin connector */
pinctrl-0 = <&uart0_pins>;
@@ -789,6 +867,8 @@
};
&ssusb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb3_port0_pins>;
role-switch-default-mode = "host";
usb-role-switch;
vusb33-supply = <&mt6359_vusb_ldo_reg>;
@@ -802,6 +882,8 @@
};
&ssusb2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_port0_pins>;
vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index 9cbd6dd8f671..d0b03dc4d3f4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -165,7 +165,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a35-pmu";
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 5 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 6 IRQ_TYPE_LEVEL_LOW>,
diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index 24075cd91420..c3029e0abacc 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -447,7 +447,7 @@
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
- reg = <0x6 0x110102d4 0x24>;
+ reg = <0x6 0x110102f8 0x24>;
};
mdio3: mdio@61101031c {
@@ -460,7 +460,7 @@
reg = <0x6 0x1101031c 0x24>;
};
- serdes: serdes@10808000 {
+ serdes: serdes@610808000 {
compatible = "microchip,sparx5-serdes";
#phy-cells = <1>;
clocks = <&sys_clk>;
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
index f3e226de5e5e..e60acc74e822 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
@@ -13,241 +13,435 @@
priority = <200>;
};
+ i2c0_imux: i2c-mux-0 {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-parent = <&i2c0>;
+ };
+
+ i2c0_emux: i2c-mux-1 {
+ compatible = "i2c-mux-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-parent = <&i2c0>;
+ };
+
leds {
compatible = "gpio-leds";
- led@0 {
+ led-0 {
label = "twr0:green";
gpios = <&sgpio_out0 8 0 GPIO_ACTIVE_LOW>;
};
- led@1 {
+ led-1 {
label = "twr0:yellow";
gpios = <&sgpio_out0 8 1 GPIO_ACTIVE_LOW>;
};
- led@2 {
+ led-2 {
label = "twr1:green";
gpios = <&sgpio_out0 9 0 GPIO_ACTIVE_LOW>;
};
- led@3 {
+ led-3 {
label = "twr1:yellow";
gpios = <&sgpio_out0 9 1 GPIO_ACTIVE_LOW>;
};
- led@4 {
+ led-4 {
label = "twr2:green";
gpios = <&sgpio_out0 10 0 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "twr2:yellow";
gpios = <&sgpio_out0 10 1 GPIO_ACTIVE_LOW>;
};
- led@6 {
+ led-6 {
label = "twr3:green";
gpios = <&sgpio_out0 11 0 GPIO_ACTIVE_LOW>;
};
- led@7 {
+ led-7 {
label = "twr3:yellow";
gpios = <&sgpio_out0 11 1 GPIO_ACTIVE_LOW>;
};
- led@8 {
+ led-8 {
label = "eth12:green";
gpios = <&sgpio_out0 12 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@9 {
+ led-9 {
label = "eth12:yellow";
gpios = <&sgpio_out0 12 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@10 {
+ led-10 {
label = "eth13:green";
gpios = <&sgpio_out0 13 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@11 {
+ led-11 {
label = "eth13:yellow";
gpios = <&sgpio_out0 13 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@12 {
+ led-12 {
label = "eth14:green";
gpios = <&sgpio_out0 14 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@13 {
+ led-13 {
label = "eth14:yellow";
gpios = <&sgpio_out0 14 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@14 {
+ led-14 {
label = "eth15:green";
gpios = <&sgpio_out0 15 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@15 {
+ led-15 {
label = "eth15:yellow";
gpios = <&sgpio_out0 15 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@16 {
+ led-16 {
label = "eth48:green";
gpios = <&sgpio_out1 16 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@17 {
+ led-17 {
label = "eth48:yellow";
gpios = <&sgpio_out1 16 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@18 {
+ led-18 {
label = "eth49:green";
gpios = <&sgpio_out1 17 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@19 {
+ led-19 {
label = "eth49:yellow";
gpios = <&sgpio_out1 17 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@20 {
+ led-20 {
label = "eth50:green";
gpios = <&sgpio_out1 18 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@21 {
+ led-21 {
label = "eth50:yellow";
gpios = <&sgpio_out1 18 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@22 {
+ led-22 {
label = "eth51:green";
gpios = <&sgpio_out1 19 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@23 {
+ led-23 {
label = "eth51:yellow";
gpios = <&sgpio_out1 19 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@24 {
+ led-24 {
label = "eth52:green";
gpios = <&sgpio_out1 20 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@25 {
+ led-25 {
label = "eth52:yellow";
gpios = <&sgpio_out1 20 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@26 {
+ led-26 {
label = "eth53:green";
gpios = <&sgpio_out1 21 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@27 {
+ led-27 {
label = "eth53:yellow";
gpios = <&sgpio_out1 21 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@28 {
+ led-28 {
label = "eth54:green";
gpios = <&sgpio_out1 22 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@29 {
+ led-29 {
label = "eth54:yellow";
gpios = <&sgpio_out1 22 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@30 {
+ led-30 {
label = "eth55:green";
gpios = <&sgpio_out1 23 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@31 {
+ led-31 {
label = "eth55:yellow";
gpios = <&sgpio_out1 23 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@32 {
+ led-32 {
label = "eth56:green";
gpios = <&sgpio_out1 24 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@33 {
+ led-33 {
label = "eth56:yellow";
gpios = <&sgpio_out1 24 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@34 {
+ led-34 {
label = "eth57:green";
gpios = <&sgpio_out1 25 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@35 {
+ led-35 {
label = "eth57:yellow";
gpios = <&sgpio_out1 25 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@36 {
+ led-36 {
label = "eth58:green";
gpios = <&sgpio_out1 26 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@37 {
+ led-37 {
label = "eth58:yellow";
gpios = <&sgpio_out1 26 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@38 {
+ led-38 {
label = "eth59:green";
gpios = <&sgpio_out1 27 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@39 {
+ led-39 {
label = "eth59:yellow";
gpios = <&sgpio_out1 27 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@40 {
+ led-40 {
label = "eth60:green";
gpios = <&sgpio_out1 28 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@41 {
+ led-41 {
label = "eth60:yellow";
gpios = <&sgpio_out1 28 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@42 {
+ led-42 {
label = "eth61:green";
gpios = <&sgpio_out1 29 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@43 {
+ led-43 {
label = "eth61:yellow";
gpios = <&sgpio_out1 29 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@44 {
+ led-44 {
label = "eth62:green";
gpios = <&sgpio_out1 30 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@45 {
+ led-45 {
label = "eth62:yellow";
gpios = <&sgpio_out1 30 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@46 {
+ led-46 {
label = "eth63:green";
gpios = <&sgpio_out1 31 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led@47 {
+ led-47 {
label = "eth63:yellow";
gpios = <&sgpio_out1 31 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
+
+ sfp_eth12: sfp-eth12 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp1>;
+ tx-disable-gpios = <&sgpio_out2 11 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 11 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 11 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 12 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth13: sfp-eth13 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp2>;
+ tx-disable-gpios = <&sgpio_out2 12 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 12 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 12 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 13 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth14: sfp-eth14 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp3>;
+ tx-disable-gpios = <&sgpio_out2 13 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 13 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 13 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 14 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth15: sfp-eth15 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp4>;
+ tx-disable-gpios = <&sgpio_out2 14 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 14 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 14 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 15 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth48: sfp-eth48 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp5>;
+ tx-disable-gpios = <&sgpio_out2 15 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 15 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 15 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 16 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth49: sfp-eth49 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp6>;
+ tx-disable-gpios = <&sgpio_out2 16 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 16 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 16 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 17 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth50: sfp-eth50 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp7>;
+ tx-disable-gpios = <&sgpio_out2 17 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 17 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 17 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 18 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth51: sfp-eth51 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp8>;
+ tx-disable-gpios = <&sgpio_out2 18 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 18 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 18 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 19 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth52: sfp-eth52 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp9>;
+ tx-disable-gpios = <&sgpio_out2 19 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 19 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 19 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 20 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth53: sfp-eth53 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp10>;
+ tx-disable-gpios = <&sgpio_out2 20 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 20 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 20 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 21 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth54: sfp-eth54 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp11>;
+ tx-disable-gpios = <&sgpio_out2 21 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 21 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 21 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 22 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth55: sfp-eth55 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp12>;
+ tx-disable-gpios = <&sgpio_out2 22 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 22 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 22 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 23 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth56: sfp-eth56 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp13>;
+ tx-disable-gpios = <&sgpio_out2 23 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 23 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 23 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 24 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth57: sfp-eth57 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp14>;
+ tx-disable-gpios = <&sgpio_out2 24 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 24 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 24 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 25 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth58: sfp-eth58 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp15>;
+ tx-disable-gpios = <&sgpio_out2 25 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 25 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 25 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 26 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth59: sfp-eth59 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp16>;
+ tx-disable-gpios = <&sgpio_out2 26 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 26 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 26 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 27 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth60: sfp-eth60 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp17>;
+ tx-disable-gpios = <&sgpio_out2 27 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 27 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 27 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 28 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth61: sfp-eth61 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp18>;
+ tx-disable-gpios = <&sgpio_out2 28 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 28 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 28 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 29 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth62: sfp-eth62 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp19>;
+ tx-disable-gpios = <&sgpio_out2 29 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 29 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 29 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 30 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth63: sfp-eth63 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp20>;
+ tx-disable-gpios = <&sgpio_out2 30 1 GPIO_ACTIVE_LOW>;
+ los-gpios = <&sgpio_in2 30 1 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 30 2 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 31 0 GPIO_ACTIVE_HIGH>;
+ };
};
&sgpio0 {
@@ -274,15 +468,6 @@
&spi0 {
status = "okay";
- flash@0 {
- compatible = "jedec,spi-nor";
- spi-max-frequency = <8000000>;
- reg = <0>;
- };
-};
-
-&spi0 {
- status = "okay";
spi@0 {
compatible = "spi-mux";
mux-controls = <&mux>;
@@ -394,21 +579,6 @@
};
};
-&axi {
- i2c0_imux: i2c0-imux@0 {
- compatible = "i2c-mux-pinctrl";
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-parent = <&i2c0>;
- };
- i2c0_emux: i2c0-emux@0 {
- compatible = "i2c-mux-gpio";
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-parent = <&i2c0>;
- };
-};
-
&i2c0_imux {
pinctrl-names =
"i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4",
@@ -427,62 +597,62 @@
pinctrl-10 = <&i2cmux_10>;
pinctrl-11 = <&i2cmux_11>;
pinctrl-12 = <&i2cmux_pins_i>;
- i2c_sfp1: i2c_sfp1 {
+ i2c_sfp1: i2c@0 {
reg = <0x0>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp2: i2c_sfp2 {
+ i2c_sfp2: i2c@1 {
reg = <0x1>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp3: i2c_sfp3 {
+ i2c_sfp3: i2c@2 {
reg = <0x2>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp4: i2c_sfp4 {
+ i2c_sfp4: i2c@3 {
reg = <0x3>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp5: i2c_sfp5 {
+ i2c_sfp5: i2c@4 {
reg = <0x4>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp6: i2c_sfp6 {
+ i2c_sfp6: i2c@5 {
reg = <0x5>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp7: i2c_sfp7 {
+ i2c_sfp7: i2c@6 {
reg = <0x6>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp8: i2c_sfp8 {
+ i2c_sfp8: i2c@7 {
reg = <0x7>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp9: i2c_sfp9 {
+ i2c_sfp9: i2c@8 {
reg = <0x8>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp10: i2c_sfp10 {
+ i2c_sfp10: i2c@9 {
reg = <0x9>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp11: i2c_sfp11 {
+ i2c_sfp11: i2c@a {
reg = <0xa>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp12: i2c_sfp12 {
+ i2c_sfp12: i2c@b {
reg = <0xb>;
#address-cells = <1>;
#size-cells = <0>;
@@ -495,42 +665,42 @@
&gpio 61 GPIO_ACTIVE_HIGH
&gpio 54 GPIO_ACTIVE_HIGH>;
idle-state = <0x8>;
- i2c_sfp13: i2c_sfp13 {
+ i2c_sfp13: i2c@0 {
reg = <0x0>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp14: i2c_sfp14 {
+ i2c_sfp14: i2c@1 {
reg = <0x1>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp15: i2c_sfp15 {
+ i2c_sfp15: i2c@2 {
reg = <0x2>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp16: i2c_sfp16 {
+ i2c_sfp16: i2c@3 {
reg = <0x3>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp17: i2c_sfp17 {
+ i2c_sfp17: i2c@4 {
reg = <0x4>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp18: i2c_sfp18 {
+ i2c_sfp18: i2c@5 {
reg = <0x5>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp19: i2c_sfp19 {
+ i2c_sfp19: i2c@6 {
reg = <0x6>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp20: i2c_sfp20 {
+ i2c_sfp20: i2c@7 {
reg = <0x7>;
#address-cells = <1>;
#size-cells = <0>;
@@ -544,169 +714,6 @@
};
};
-&axi {
- sfp_eth12: sfp-eth12 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp1>;
- tx-disable-gpios = <&sgpio_out2 11 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 11 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 11 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 12 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth13: sfp-eth13 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp2>;
- tx-disable-gpios = <&sgpio_out2 12 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 12 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 12 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 13 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth14: sfp-eth14 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp3>;
- tx-disable-gpios = <&sgpio_out2 13 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 13 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 13 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 14 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth15: sfp-eth15 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp4>;
- tx-disable-gpios = <&sgpio_out2 14 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 14 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 14 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 15 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth48: sfp-eth48 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp5>;
- tx-disable-gpios = <&sgpio_out2 15 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 15 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 15 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 16 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth49: sfp-eth49 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp6>;
- tx-disable-gpios = <&sgpio_out2 16 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 16 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 16 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 17 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth50: sfp-eth50 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp7>;
- tx-disable-gpios = <&sgpio_out2 17 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 17 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 17 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 18 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth51: sfp-eth51 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp8>;
- tx-disable-gpios = <&sgpio_out2 18 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 18 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 18 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 19 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth52: sfp-eth52 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp9>;
- tx-disable-gpios = <&sgpio_out2 19 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 19 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 19 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 20 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth53: sfp-eth53 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp10>;
- tx-disable-gpios = <&sgpio_out2 20 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 20 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 20 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 21 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth54: sfp-eth54 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp11>;
- tx-disable-gpios = <&sgpio_out2 21 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 21 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 21 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 22 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth55: sfp-eth55 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp12>;
- tx-disable-gpios = <&sgpio_out2 22 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 22 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 22 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 23 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth56: sfp-eth56 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp13>;
- tx-disable-gpios = <&sgpio_out2 23 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 23 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 23 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 24 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth57: sfp-eth57 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp14>;
- tx-disable-gpios = <&sgpio_out2 24 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 24 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 24 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 25 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth58: sfp-eth58 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp15>;
- tx-disable-gpios = <&sgpio_out2 25 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 25 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 25 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 26 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth59: sfp-eth59 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp16>;
- tx-disable-gpios = <&sgpio_out2 26 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 26 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 26 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 27 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth60: sfp-eth60 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp17>;
- tx-disable-gpios = <&sgpio_out2 27 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 27 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 27 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 28 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth61: sfp-eth61 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp18>;
- tx-disable-gpios = <&sgpio_out2 28 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 28 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 28 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 29 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth62: sfp-eth62 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp19>;
- tx-disable-gpios = <&sgpio_out2 29 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 29 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 29 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 30 0 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth63: sfp-eth63 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp20>;
- tx-disable-gpios = <&sgpio_out2 30 1 GPIO_ACTIVE_LOW>;
- los-gpios = <&sgpio_in2 30 1 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 30 2 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 31 0 GPIO_ACTIVE_HIGH>;
- };
-};
-
&switch {
ethernet-ports {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
index 82ce007d9959..196868898f49 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
@@ -13,49 +13,96 @@
priority = <200>;
};
+ i2c0_imux: i2c-mux {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-parent = <&i2c0>;
+ };
+
leds {
compatible = "gpio-leds";
- led@0 {
+ led-0 {
label = "eth60:yellow";
gpios = <&sgpio_out1 28 0 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@1 {
+ led-1 {
label = "eth60:green";
gpios = <&sgpio_out1 28 1 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@2 {
+ led-2 {
label = "eth61:yellow";
gpios = <&sgpio_out1 29 0 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@3 {
+ led-3 {
label = "eth61:green";
gpios = <&sgpio_out1 29 1 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@4 {
+ led-4 {
label = "eth62:yellow";
gpios = <&sgpio_out1 30 0 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@5 {
+ led-5 {
label = "eth62:green";
gpios = <&sgpio_out1 30 1 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@6 {
+ led-6 {
label = "eth63:yellow";
gpios = <&sgpio_out1 31 0 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- led@7 {
+ led-7 {
label = "eth63:green";
gpios = <&sgpio_out1 31 1 GPIO_ACTIVE_LOW>;
default-state = "off";
};
};
+
+ sfp_eth60: sfp-eth60 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp1>;
+ tx-disable-gpios = <&sgpio_out2 28 0 GPIO_ACTIVE_LOW>;
+ rate-select0-gpios = <&sgpio_out2 28 1 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&sgpio_in2 28 0 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 28 1 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 28 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth61: sfp-eth61 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp2>;
+ tx-disable-gpios = <&sgpio_out2 29 0 GPIO_ACTIVE_LOW>;
+ rate-select0-gpios = <&sgpio_out2 29 1 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&sgpio_in2 29 0 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 29 1 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 29 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth62: sfp-eth62 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp3>;
+ tx-disable-gpios = <&sgpio_out2 30 0 GPIO_ACTIVE_LOW>;
+ rate-select0-gpios = <&sgpio_out2 30 1 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&sgpio_in2 30 0 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 30 1 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 30 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp_eth63: sfp-eth63 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp4>;
+ tx-disable-gpios = <&sgpio_out2 31 0 GPIO_ACTIVE_LOW>;
+ rate-select0-gpios = <&sgpio_out2 31 1 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&sgpio_in2 31 0 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&sgpio_in2 31 1 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&sgpio_in2 31 2 GPIO_ACTIVE_HIGH>;
+ };
};
&gpio {
@@ -89,15 +136,6 @@
&spi0 {
status = "okay";
- flash@0 {
- compatible = "jedec,spi-nor";
- spi-max-frequency = <8000000>;
- reg = <0>;
- };
-};
-
-&spi0 {
- status = "okay";
spi@0 {
compatible = "spi-mux";
mux-controls = <&mux>;
@@ -128,15 +166,6 @@
microchip,sgpio-port-ranges = <0 0>, <16 18>, <28 31>;
};
-&axi {
- i2c0_imux: i2c0-imux@0 {
- compatible = "i2c-mux-pinctrl";
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-parent = <&i2c0>;
- };
-};
-
&i2c0_imux {
pinctrl-names =
"i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4",
@@ -146,67 +175,28 @@
pinctrl-2 = <&i2cmux_s31>;
pinctrl-3 = <&i2cmux_s32>;
pinctrl-4 = <&i2cmux_pins_i>;
- i2c_sfp1: i2c_sfp1 {
+ i2c_sfp1: i2c@0 {
reg = <0x0>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp2: i2c_sfp2 {
+ i2c_sfp2: i2c@1 {
reg = <0x1>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp3: i2c_sfp3 {
+ i2c_sfp3: i2c@2 {
reg = <0x2>;
#address-cells = <1>;
#size-cells = <0>;
};
- i2c_sfp4: i2c_sfp4 {
+ i2c_sfp4: i2c@3 {
reg = <0x3>;
#address-cells = <1>;
#size-cells = <0>;
};
};
-&axi {
- sfp_eth60: sfp-eth60 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp1>;
- tx-disable-gpios = <&sgpio_out2 28 0 GPIO_ACTIVE_LOW>;
- rate-select0-gpios = <&sgpio_out2 28 1 GPIO_ACTIVE_HIGH>;
- los-gpios = <&sgpio_in2 28 0 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 28 1 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 28 2 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth61: sfp-eth61 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp2>;
- tx-disable-gpios = <&sgpio_out2 29 0 GPIO_ACTIVE_LOW>;
- rate-select0-gpios = <&sgpio_out2 29 1 GPIO_ACTIVE_HIGH>;
- los-gpios = <&sgpio_in2 29 0 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 29 1 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 29 2 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth62: sfp-eth62 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp3>;
- tx-disable-gpios = <&sgpio_out2 30 0 GPIO_ACTIVE_LOW>;
- rate-select0-gpios = <&sgpio_out2 30 1 GPIO_ACTIVE_HIGH>;
- los-gpios = <&sgpio_in2 30 0 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 30 1 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 30 2 GPIO_ACTIVE_HIGH>;
- };
- sfp_eth63: sfp-eth63 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp4>;
- tx-disable-gpios = <&sgpio_out2 31 0 GPIO_ACTIVE_LOW>;
- rate-select0-gpios = <&sgpio_out2 31 1 GPIO_ACTIVE_HIGH>;
- los-gpios = <&sgpio_in2 31 0 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&sgpio_in2 31 1 GPIO_ACTIVE_LOW>;
- tx-fault-gpios = <&sgpio_in2 31 2 GPIO_ACTIVE_HIGH>;
- };
-};
-
&mdio0 {
status = "okay";
phy0: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
index a5ab2bc0f835..eeceb5b292a8 100644
--- a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
+++ b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
@@ -16,7 +16,7 @@
stdout-path = &serial0;
};
- memory {
+ memory@0 {
reg = <0x0 0x0 0x0 0x40000000>;
};
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
index 14d58859bb55..683ac124523b 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
@@ -9,8 +9,8 @@
compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124";
aliases {
- rtc0 = "/i2c@7000d000/as3722@40";
- rtc1 = "/rtc@7000e000";
+ rtc0 = &as3722;
+ rtc1 = &tegra_rtc;
serial0 = &uarta;
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
index 7e24a212c7e4..5bcccfef3f7f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -572,7 +572,7 @@
status = "disabled";
};
- rtc@7000e000 {
+ tegra_rtc: rtc@7000e000 {
compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
reg = <0x0 0x7000e000 0x0 0x100>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index 9ebb7369256e..2e5b6b2c1f56 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -25,7 +25,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0xc0000000>;
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 47f8268e46bf..882b1d1f4ada 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -2004,7 +2004,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a57-pmu";
interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts
index 1607ee14216f..82a59e33c46c 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
-#include <dt-bindings/input/linux-event-codes.h>
-#include <dt-bindings/input/gpio-keys.h>
-
-#include "tegra234-p3767.dtsi"
-#include "tegra234-p3768-0000.dtsi"
+#include "tegra234-p3768-0000+p3767.dtsi"
/ {
compatible = "nvidia,p3768-0000+p3767-0000", "nvidia,p3767-0000", "nvidia,tegra234";
@@ -29,83 +25,12 @@
status = "okay";
};
- pwm@32a0000 {
- assigned-clocks = <&bpmp TEGRA234_CLK_PWM3>;
- assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
- status = "okay";
- };
-
hda@3510000 {
nvidia,model = "NVIDIA Jetson Orin NX HDA";
};
-
- padctl@3520000 {
- status = "okay";
- };
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- key-force-recovery {
- label = "Force Recovery";
- gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>;
- linux,input-type = <EV_KEY>;
- linux,code = <BTN_1>;
- };
-
- key-power {
- label = "Power";
- gpios = <&gpio_aon TEGRA234_AON_GPIO(EE, 4) GPIO_ACTIVE_LOW>;
- linux,input-type = <EV_KEY>;
- linux,code = <KEY_POWER>;
- wakeup-event-action = <EV_ACT_ASSERTED>;
- wakeup-source;
- };
-
- key-suspend {
- label = "Suspend";
- gpios = <&gpio TEGRA234_MAIN_GPIO(G, 2) GPIO_ACTIVE_LOW>;
- linux,input-type = <EV_KEY>;
- linux,code = <KEY_SLEEP>;
- };
- };
-
- pwm-fan {
- cooling-levels = <0 88 187 255>;
- };
-
- vdd_3v3_pcie: regulator-vdd-3v3-pcie {
- compatible = "regulator-fixed";
- regulator-name = "VDD_3V3_PCIE";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- gpio = <&gpio_aon TEGRA234_AON_GPIO(AA, 5) GPIO_ACTIVE_HIGH>;
- enable-active-high;
};
sound {
label = "NVIDIA Jetson Orin NX APE";
};
-
- thermal-zones {
- tj-thermal {
- cooling-maps {
- map-active-0 {
- cooling-device = <&fan 0 1>;
- trip = <&tj_trip_active0>;
- };
-
- map-active-1 {
- cooling-device = <&fan 1 2>;
- trip = <&tj_trip_active1>;
- };
-
- map-active-2 {
- cooling-device = <&fan 2 3>;
- trip = <&tj_trip_active2>;
- };
- };
- };
- };
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0005.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0005.dts
index dc2d4bef1e83..9f5e07012b87 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0005.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0005.dts
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
-#include <dt-bindings/input/linux-event-codes.h>
-#include <dt-bindings/input/gpio-keys.h>
-
-#include "tegra234-p3767.dtsi"
-#include "tegra234-p3768-0000.dtsi"
+#include "tegra234-p3768-0000+p3767.dtsi"
/ {
compatible = "nvidia,p3768-0000+p3767-0005", "nvidia,p3767-0005", "nvidia,tegra234";
@@ -17,32 +13,7 @@
};
};
- pwm-fan {
- cooling-levels = <0 88 187 255>;
- };
-
sound {
label = "NVIDIA Jetson Orin Nano APE";
};
-
- thermal-zones {
- tj-thermal {
- cooling-maps {
- map-active-0 {
- cooling-device = <&fan 0 1>;
- trip = <&tj_trip_active0>;
- };
-
- map-active-1 {
- cooling-device = <&fan 1 2>;
- trip = <&tj_trip_active1>;
- };
-
- map-active-2 {
- cooling-device = <&fan 2 3>;
- trip = <&tj_trip_active2>;
- };
- };
- };
- };
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi
index 5d0298b6c30d..6d64a24fa251 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi
@@ -1,7 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/input/gpio-keys.h>
+
+#include "tegra234-p3767.dtsi"
+
/ {
- compatible = "nvidia,p3768-0000";
aliases {
serial0 = &tcu;
@@ -210,6 +214,7 @@
compatible = "pwm-fan";
pwms = <&pwm3 0 45334>;
#cooling-cells = <2>;
+ cooling-levels = <0 88 187 255>;
};
vdd_1v8_sys: regulator-vdd-1v8-sys {
@@ -241,4 +246,25 @@
serial {
status = "okay";
};
+
+ thermal-zones {
+ tj-thermal {
+ cooling-maps {
+ map-active-0 {
+ cooling-device = <&fan 0 1>;
+ trip = <&tj_trip_active0>;
+ };
+
+ map-active-1 {
+ cooling-device = <&fan 1 2>;
+ trip = <&tj_trip_active1>;
+ };
+
+ map-active-2 {
+ cooling-device = <&fan 2 3>;
+ trip = <&tj_trip_active2>;
+ };
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
index 78cbfdd98dd1..f2e2d8d6845b 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
@@ -4406,6 +4406,22 @@
*/
status = "disabled";
};
+
+ crypto@15820000 {
+ compatible = "nvidia,tegra234-se-aes";
+ reg = <0x00 0x15820000 0x00 0x10000>;
+ clocks = <&bpmp TEGRA234_CLK_SE>;
+ iommus = <&smmu_niso1 TEGRA234_SID_SES_SE1>;
+ dma-coherent;
+ };
+
+ crypto@15840000 {
+ compatible = "nvidia,tegra234-se-hash";
+ reg = <0x00 0x15840000 0x00 0x10000>;
+ clocks = <&bpmp TEGRA234_CLK_SE>;
+ iommus = <&smmu_niso1 TEGRA234_SID_SES_SE2>;
+ dma-coherent;
+ };
};
pcie@140a0000 {
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 7d40ec5e7d21..0e5c810304fb 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -5,11 +5,13 @@ apq8016-sbc-usb-host-dtbs := apq8016-sbc.dtb apq8016-sbc-usb-host.dtbo
dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc-usb-host.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc-d3-camera-mezzanine.dtb
+dtb-$(CONFIG_ARCH_QCOM) += apq8016-schneider-hmibsc.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8039-t2.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8094-sony-xperia-kitakami-karin_windy.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq5018-rdp432-c2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += ipq5018-tplink-archer-ax55-v1.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq5332-rdp441.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq5332-rdp442.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq5332-rdp468.dtb
@@ -29,8 +31,13 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-alcatel-idol347.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-asus-z00l.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-gplus-fl8005a.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-huawei-g7.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-lg-c50.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-lg-m216.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-longcheer-l8150.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-longcheer-l8910.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-motorola-harpia.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-motorola-osprey.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-motorola-surnia.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
@@ -93,9 +100,11 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-poplar.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8998-xiaomi-sagit.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcm6490-fairphone-fp5.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcm6490-idp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcm6490-shift-otter.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb
dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb
dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb
dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb
@@ -106,6 +115,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sa8155p-adp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sa8295p-adp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sa8540p-ride.dtb
dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-acer-aspire1.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-idp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-coachz-r1.dtb
@@ -175,6 +185,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sc8180x-primus.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc8280xp-crd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc8280xp-lenovo-thinkpad-x13s.dtb
dtb-$(CONFIG_ARCH_QCOM) += sda660-inforce-ifc6560.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sdm450-lenovo-tbx605f.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm450-motorola-ali.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-ganges-kirin.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-discovery.dtb
@@ -241,7 +252,16 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8450-sony-xperia-nagara-pdx224.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8550-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8550-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8550-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8550-samsung-q5q.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8550-sony-xperia-yodo-pdx234.dtb
+
+sm8650-hdk-display-card-dtbs := sm8650-hdk.dtb sm8650-hdk-display-card.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += sm8650-hdk-display-card.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8650-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM) += x1e80100-asus-vivobook-s15.dtb
dtb-$(CONFIG_ARCH_QCOM) += x1e80100-crd.dtb
+dtb-$(CONFIG_ARCH_QCOM) += x1e80100-lenovo-yoga-slim7x.dtb
dtb-$(CONFIG_ARCH_QCOM) += x1e80100-qcp.dtb
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
index 9ffad7d1f2b6..aba08424aa38 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
@@ -91,7 +91,7 @@
compatible = "gpio-leds";
- led@1 {
+ led-1 {
label = "apq8016-sbc:green:user1";
function = LED_FUNCTION_HEARTBEAT;
color = <LED_COLOR_ID_GREEN>;
@@ -100,7 +100,7 @@
default-state = "off";
};
- led@2 {
+ led-2 {
label = "apq8016-sbc:green:user2";
function = LED_FUNCTION_DISK_ACTIVITY;
color = <LED_COLOR_ID_GREEN>;
@@ -109,7 +109,7 @@
default-state = "off";
};
- led@3 {
+ led-3 {
label = "apq8016-sbc:green:user3";
function = LED_FUNCTION_DISK_ACTIVITY;
color = <LED_COLOR_ID_GREEN>;
@@ -118,7 +118,7 @@
default-state = "off";
};
- led@4 {
+ led-4 {
label = "apq8016-sbc:green:user4";
color = <LED_COLOR_ID_GREEN>;
gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>;
@@ -127,7 +127,7 @@
default-state = "off";
};
- led@5 {
+ led-5 {
label = "apq8016-sbc:yellow:wlan";
function = LED_FUNCTION_WLAN;
color = <LED_COLOR_ID_YELLOW>;
@@ -136,7 +136,7 @@
default-state = "off";
};
- led@6 {
+ led-6 {
label = "apq8016-sbc:blue:bt";
function = LED_FUNCTION_BLUETOOTH;
color = <LED_COLOR_ID_BLUE>;
diff --git a/arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts b/arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts
new file mode 100644
index 000000000000..75c6137e5a11
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Linaro Ltd.
+ */
+
+/dts-v1/;
+
+#include "msm8916-pm8916.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
+#include <dt-bindings/sound/apq8016-lpass.h>
+
+/ {
+ model = "Schneider Electric HMIBSC Board";
+ compatible = "schneider,apq8016-hmibsc", "qcom,apq8016";
+
+ aliases {
+ i2c1 = &blsp_i2c6;
+ i2c3 = &blsp_i2c4;
+ i2c4 = &blsp_i2c3;
+ mmc0 = &sdhc_1; /* eMMC */
+ mmc1 = &sdhc_2; /* SD card */
+ serial0 = &blsp_uart1;
+ serial1 = &blsp_uart2;
+ spi0 = &blsp_spi5;
+ usid0 = &pm8916_0;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con: endpoint {
+ remote-endpoint = <&adv7533_out>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+ pinctrl-0 = <&msm_key_volp_n_default>;
+ pinctrl-names = "default";
+
+ button {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pm8916_mpps_leds>;
+ pinctrl-names = "default";
+
+ led-1 {
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_YELLOW>;
+ gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "phy0tx";
+ default-state = "off";
+ };
+
+ led-2 {
+ function = LED_FUNCTION_BLUETOOTH;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "bluetooth-power";
+ default-state = "off";
+ };
+ };
+
+ memory@80000000 {
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+
+ reserved-memory {
+ ramoops@bff00000 {
+ compatible = "ramoops";
+ reg = <0x0 0xbff00000 0x0 0x100000>;
+ record-size = <0x20000>;
+ console-size = <0x20000>;
+ ftrace-size = <0x20000>;
+ ecc-size = <16>;
+ };
+ };
+
+ usb-hub {
+ compatible = "smsc,usb3503";
+ reset-gpios = <&pm8916_gpios 1 GPIO_ACTIVE_LOW>;
+ initial-mode = <1>;
+ };
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&usb_id_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_i2c3 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c32";
+ reg = <0x50>;
+ };
+};
+
+&blsp_i2c4 {
+ status = "okay";
+
+ adv_bridge: bridge@39 {
+ compatible = "adi,adv7533";
+ reg = <0x39>;
+ interrupts-extended = <&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+
+ adi,dsi-lanes = <4>;
+ clocks = <&rpmcc RPM_SMD_BB_CLK2>;
+ clock-names = "cec";
+ pd-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+
+ avdd-supply = <&pm8916_l6>;
+ a2vdd-supply = <&pm8916_l6>;
+ dvdd-supply = <&pm8916_l6>;
+ pvdd-supply = <&pm8916_l6>;
+ v1p2-supply = <&pm8916_l6>;
+ v3p3-supply = <&pm8916_l17>;
+
+ pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>;
+ pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>;
+ pinctrl-names = "default","sleep";
+ #sound-dai-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7533_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7533_out: endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
+};
+
+&blsp_i2c6 {
+ status = "okay";
+
+ rtc@30 {
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+};
+
+&blsp_spi5 {
+ cs-gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ tpm@0 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ reg = <0>;
+ spi-max-frequency = <500000>;
+ };
+};
+
+&blsp_uart1 {
+ label = "UART0";
+ status = "okay";
+};
+
+&blsp_uart2 {
+ label = "UART1";
+ status = "okay";
+};
+
+&lpass {
+ status = "okay";
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0_out {
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&adv7533_in>;
+};
+
+&pm8916_codec {
+ qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
+ qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
+ status = "okay";
+};
+
+&pm8916_gpios {
+ gpio-line-names =
+ "USB_HUB_RESET_N_PM",
+ "USB_SW_SEL_PM",
+ "NC",
+ "NC";
+
+ usb_hub_reset_pm: usb-hub-reset-pm-state {
+ pins = "gpio1";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ input-disable;
+ output-high;
+ };
+
+ usb_hub_reset_pm_device: usb-hub-reset-pm-device-state {
+ pins = "gpio1";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ input-disable;
+ output-low;
+ };
+
+ usb_sw_sel_pm: usb-sw-sel-pm-state {
+ pins = "gpio2";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ power-source = <PM8916_GPIO_VPH>;
+ input-disable;
+ output-high;
+ };
+
+ usb_sw_sel_pm_device: usb-sw-sel-pm-device-state {
+ pins = "gpio2";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ power-source = <PM8916_GPIO_VPH>;
+ input-disable;
+ output-low;
+ };
+};
+
+&pm8916_mpps {
+ gpio-line-names =
+ "NC",
+ "WLAN_LED_CTRL",
+ "BT_LED_CTRL",
+ "NC";
+
+ pm8916_mpps_leds: pm8916-mpps-state {
+ pins = "mpp2", "mpp3";
+ function = "digital";
+ output-low;
+ };
+};
+
+&pm8916_resin {
+ linux,code = <KEY_POWER>;
+ status = "okay";
+};
+
+&pm8916_rpm_regulators {
+ pm8916_l17: l17 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&sdhc_1 {
+ status = "okay";
+};
+
+&sdhc_2 {
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&sound {
+ pinctrl-0 = <&cdc_pdm_default &sec_mi2s_default>;
+ pinctrl-1 = <&cdc_pdm_sleep &sec_mi2s_sleep>;
+ pinctrl-names = "default", "sleep";
+ model = "HMIBSC";
+ audio-routing =
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+ status = "okay";
+
+ quaternary-dai-link {
+ link-name = "ADV7533";
+ cpu {
+ sound-dai = <&lpass MI2S_QUATERNARY>;
+ };
+ codec {
+ sound-dai = <&adv_bridge 0>;
+ };
+ };
+
+ primary-dai-link {
+ link-name = "WCD";
+ cpu {
+ sound-dai = <&lpass MI2S_PRIMARY>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 0>, <&pm8916_codec 0>;
+ };
+ };
+
+ tertiary-dai-link {
+ link-name = "WCD-Capture";
+ cpu {
+ sound-dai = <&lpass MI2S_TERTIARY>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 1>, <&pm8916_codec 1>;
+ };
+ };
+};
+
+&tlmm {
+ pinctrl-0 = <&uart1_mux0_rs232_high &uart1_mux1_rs232_low>;
+ pinctrl-names = "default";
+
+ adv7533_int_active: adv533-int-active-state {
+ pins = "gpio31";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ adv7533_int_suspend: adv7533-int-suspend-state {
+ pins = "gpio31";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ adv7533_switch_active: adv7533-switch-active-state {
+ pins = "gpio32";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ adv7533_switch_suspend: adv7533-switch-suspend-state {
+ pins = "gpio32";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ msm_key_volp_n_default: msm-key-volp-n-default-state {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ /*
+ * UART1 being the debug console supports various modes of
+ * operation (RS-232/485/422) controlled via GPIOs configured
+ * mux as follows:
+ *
+ * gpio100 gpio99 UART mode
+ * 0 0 loopback
+ * 0 1 RS-232
+ * 1 0 RS-485
+ * 1 1 RS-422
+ *
+ * The default mode configured here is RS-232 mode.
+ */
+ uart1_mux0_rs232_high: uart1-mux0-rs232-state {
+ bootph-all;
+ pins = "gpio99";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-high;
+ };
+
+ uart1_mux1_rs232_low: uart1-mux1-rs232-state {
+ bootph-all;
+ pins = "gpio100";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+
+ usb_id_default: usb-id-default-state {
+ pins = "gpio110";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+};
+
+&usb {
+ extcon = <&usb_id>, <&usb_id>;
+ pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>;
+ pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>;
+ pinctrl-names = "default", "device";
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&usb_id>;
+};
+
+&wcnss {
+ firmware-name = "qcom/apq8016/wcnss.mbn";
+ status = "okay";
+};
+
+&wcnss_ctrl {
+ firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3620";
+};
+
+&wcnss_mem {
+ status = "okay";
+};
+
+/* PINCTRL - additions to nodes defined in msm8916.dtsi */
+
+/*
+ * 2mA drive strength is not enough when connecting multiple
+ * I2C devices with different pull up resistors.
+ */
+&blsp_i2c4_default {
+ drive-strength = <16>;
+};
+
+&blsp_i2c6_default {
+ drive-strength = <16>;
+};
+
+&blsp_uart1_default {
+ bootph-all;
+};
+
+/* 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"; };
+&stm { status = "okay"; };
+&tpiu { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/ipq5018-tplink-archer-ax55-v1.dts b/arch/arm64/boot/dts/qcom/ipq5018-tplink-archer-ax55-v1.dts
new file mode 100644
index 000000000000..5bb021cb29cd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/ipq5018-tplink-archer-ax55-v1.dts
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "ipq5018.dtsi"
+
+/ {
+ model = "TP-Link Archer AX55 v1";
+ compatible = "tplink,archer-ax55-v1", "qcom,ipq5018";
+
+ aliases {
+ serial0 = &blsp1_uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN_ONLINE;
+ gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-2 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ gpios = <&tlmm 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-3 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-4 {
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&tlmm 22 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-5 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_USB;
+ gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-6 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ buttons {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&button_pins>;
+ pinctrl-names = "default";
+
+ button-reset {
+ debounce-interval = <60>;
+ gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ };
+
+ button-wps {
+ debounce-interval = <60>;
+ gpios = <&tlmm 31 GPIO_ACTIVE_LOW>;
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+ };
+};
+
+&blsp1_uart1 {
+ pinctrl-0 = <&uart_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sleep_clk {
+ clock-frequency = <32000>;
+};
+
+&tlmm {
+ button_pins: button-pins-state {
+ pins = "gpio25", "gpio31";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ led_pins: led-pins-state {
+ pins = "gpio10", "gpio11", "gpio13", "gpio18", "gpio22",
+ "gpio38", "gpio39";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ uart_pins: uart-pins-state {
+ pins = "gpio20", "gpio21";
+ function = "blsp0_uart0";
+ drive-strength = <8>;
+ bias-disable;
+ };
+};
+
+&xo_board_clk {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
index 32b178b639f0..7e6e2c121979 100644
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -179,7 +179,6 @@
<0>;
#clock-cells = <1>;
#reset-cells = <1>;
- #power-domain-cells = <1>;
};
tcsr_mutex: hwlock@1905000 {
diff --git a/arch/arm64/boot/dts/qcom/ipq5332.dtsi b/arch/arm64/boot/dts/qcom/ipq5332.dtsi
index 770d9c2fb456..573656587c0d 100644
--- a/arch/arm64/boot/dts/qcom/ipq5332.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5332.dtsi
@@ -208,7 +208,6 @@
reg = <0x01800000 0x80000>;
#clock-cells = <1>;
#reset-cells = <1>;
- #power-domain-cells = <1>;
clocks = <&xo_board>,
<&sleep_clk>,
<0>,
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 4e29adea570a..e1e45da7f787 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -396,7 +396,7 @@
};
};
- gcc: gcc@1800000 {
+ gcc: clock-controller@1800000 {
compatible = "qcom,gcc-ipq6018";
reg = <0x0 0x01800000 0x0 0x80000>;
clocks = <&xo>, <&sleep_clk>;
@@ -457,6 +457,25 @@
};
};
+ sdhc: mmc@7804000 {
+ compatible = "qcom,ipq6018-sdhci", "qcom,sdhci-msm-v5";
+ reg = <0x0 0x07804000 0x0 0x1000>,
+ <0x0 0x07805000 0x0 0x1000>;
+ reg-names = "hc", "cqhci";
+
+ 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_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>,
+ <&xo>;
+ clock-names = "iface", "core", "xo";
+ resets = <&gcc GCC_SDCC1_BCR>;
+ max-frequency = <192000000>;
+ status = "disabled";
+ };
+
blsp_dma: dma-controller@7884000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x0 0x07884000 0x0 0x2b000>;
@@ -685,6 +704,7 @@
clocks = <&xo>;
clock-names = "ref";
tx-fifo-resize;
+ snps,parkmode-disable-ss-quirk;
snps,is-utmi-l1-suspend;
snps,hird-threshold = /bits/ 8 <0x0>;
snps,dis_u2_susphy_quirk;
@@ -907,13 +927,22 @@
"axi_s_sticky";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
};
thermal-zones {
nss-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 4>;
trips {
@@ -927,7 +956,6 @@
nss-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 5>;
trips {
@@ -941,7 +969,6 @@
wcss-phya0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 7>;
trips {
@@ -969,7 +996,6 @@
cpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 13>;
trips {
@@ -999,7 +1025,6 @@
lpass-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 14>;
trips {
@@ -1013,7 +1038,6 @@
ddrss-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 15>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi b/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
index 1b8379ba87f9..34e2f80514a3 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
@@ -16,7 +16,7 @@
stdout-path = "serial0";
};
- memory {
+ memory@40000000 {
device_type = "memory";
reg = <0x0 0x40000000 0x0 0x20000000>;
};
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index e5b89753aa5c..284a4553070f 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -323,6 +323,13 @@
bias-disable;
};
+ serial_5_pins: serial5-state {
+ pins = "gpio9", "gpio16";
+ function = "blsp5_uart";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
i2c_0_pins: i2c-0-state {
pins = "gpio42", "gpio43";
function = "blsp1_i2c";
@@ -349,14 +356,14 @@
"gpio5", "gpio6", "gpio7",
"gpio8", "gpio10", "gpio11",
"gpio12", "gpio13", "gpio14",
- "gpio15", "gpio16", "gpio17";
+ "gpio15", "gpio17";
function = "qpic";
drive-strength = <8>;
bias-disable;
};
};
- gcc: gcc@1800000 {
+ gcc: clock-controller@1800000 {
compatible = "qcom,gcc-ipq8074";
reg = <0x01800000 0x80000>;
clocks = <&xo>,
@@ -471,6 +478,18 @@
status = "disabled";
};
+ blsp1_uart6: serial@78b4000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x078b4000 0x200>;
+ interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP1_UART6_APPS_CLK>,
+ <&gcc GCC_BLSP1_AHB_CLK>;
+ clock-names = "core", "iface";
+ pinctrl-0 = <&serial_5_pins>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
blsp1_spi1: spi@78b5000 {
compatible = "qcom,spi-qup-v2.2.1";
#address-cells = <1>;
@@ -647,6 +666,7 @@
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
phys = <&qusb_phy_0>, <&ssphy_0>;
phy-names = "usb2-phy", "usb3-phy";
+ snps,parkmode-disable-ss-quirk;
snps,is-utmi-l1-suspend;
snps,hird-threshold = /bits/ 8 <0x0>;
snps,dis_u2_susphy_quirk;
@@ -696,6 +716,7 @@
interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
phys = <&qusb_phy_1>, <&ssphy_1>;
phy-names = "usb2-phy", "usb3-phy";
+ snps,parkmode-disable-ss-quirk;
snps,is-utmi-l1-suspend;
snps,hird-threshold = /bits/ 8 <0x0>;
snps,dis_u2_susphy_quirk;
@@ -864,6 +885,16 @@
"ahb",
"axi_m_sticky";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0: pcie@20000000 {
@@ -929,6 +960,16 @@
"axi_m_sticky",
"axi_s_sticky";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
};
@@ -943,7 +984,6 @@
thermal-zones {
nss-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 4>;
@@ -958,7 +998,6 @@
nss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 5>;
@@ -973,7 +1012,6 @@
nss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 6>;
@@ -988,7 +1026,6 @@
wcss-phya0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 7>;
@@ -1003,7 +1040,6 @@
wcss-phya1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 8>;
@@ -1018,7 +1054,6 @@
cpu0_thermal: cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 9>;
@@ -1033,7 +1068,6 @@
cpu1_thermal: cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 10>;
@@ -1048,7 +1082,6 @@
cpu2_thermal: cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 11>;
@@ -1063,7 +1096,6 @@
cpu3_thermal: cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 12>;
@@ -1078,7 +1110,6 @@
cluster_thermal: cluster-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 13>;
@@ -1093,7 +1124,6 @@
wcss-phyb0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 14>;
@@ -1108,7 +1138,6 @@
wcss-phyb1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 15>;
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
index 7f2e5cbf3bbb..48dfafea46a7 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/clock/qcom,apss-ipq.h>
#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
+#include <dt-bindings/interconnect/qcom,ipq9574.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/qcom,ipq9574-gcc.h>
#include <dt-bindings/thermal/thermal.h>
@@ -232,6 +233,16 @@
clock-names = "core";
};
+ mdio: mdio@90000 {
+ compatible = "qcom,ipq9574-mdio", "qcom,ipq4019-mdio";
+ reg = <0x00090000 0x64>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&gcc GCC_MDIO_AHB_CLK>;
+ clock-names = "gcc_mdio_ahb_clk";
+ status = "disabled";
+ };
+
qfprom: efuse@a4000 {
compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
reg = <0x000a4000 0x5a1>;
@@ -305,7 +316,7 @@
<0>;
#clock-cells = <1>;
#reset-cells = <1>;
- #power-domain-cells = <1>;
+ #interconnect-cells = <1>;
};
tcsr_mutex: hwlock@1905000 {
@@ -749,8 +760,6 @@
thermal-zones {
nss-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 3>;
trips {
@@ -763,8 +772,6 @@
};
ubi-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 4>;
trips {
@@ -777,8 +784,6 @@
};
ubi-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 5>;
trips {
@@ -791,8 +796,6 @@
};
ubi-2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 6>;
trips {
@@ -805,8 +808,6 @@
};
ubi-3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 7>;
trips {
@@ -819,8 +820,6 @@
};
cpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 8>;
trips {
@@ -833,8 +832,6 @@
};
cpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 9>;
trips {
@@ -847,8 +844,6 @@
};
cpu0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 10>;
trips {
@@ -877,8 +872,6 @@
};
cpu1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 11>;
trips {
@@ -907,8 +900,6 @@
};
cpu2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 12>;
trips {
@@ -937,8 +928,6 @@
};
cpu3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 13>;
trips {
@@ -967,8 +956,6 @@
};
wcss-phyb-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 14>;
trips {
@@ -981,8 +968,6 @@
};
top-glue-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens 15>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts b/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts
index 366914be7d53..fba68bf8bf79 100644
--- a/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts
+++ b/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts
@@ -9,3 +9,17 @@
compatible = "samsung,fortuna3g", "qcom,msm8916";
chassis-type = "handset";
};
+
+&battery {
+ charge-term-current-microamp = <200000>;
+ constant-charge-current-max-microamp = <1000000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
+&st_accel {
+ status = "okay";
+};
+
+&st_magn {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
index b32c7a97394d..b4ce14a79370 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
@@ -3,6 +3,7 @@
/dts-v1/;
#include "msm8916-pm8916.dtsi"
+#include "msm8916-modem-qdsp6.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
@@ -135,6 +136,17 @@
status = "okay";
};
+&mpss_mem {
+ reg = <0x0 0x86800000 0x0 0x4500000>;
+};
+
+&pm8916_codec {
+ qcom,micbias-lvl = <2800>;
+ qcom,mbhc-vthreshold-low = <150 237 450 500 590>;
+ qcom,mbhc-vthreshold-high = <150 237 450 500 590>;
+ qcom,hphl-jack-type-normally-open;
+};
+
&pm8916_resin {
linux,code = <KEY_VOLUMEDOWN>;
status = "okay";
@@ -170,6 +182,20 @@
status = "okay";
};
+&sound {
+ model = "acer-a1-724";
+ audio-routing =
+ "DMIC1", "MIC BIAS External1",
+ "DMIC1", "Digital Mic1",
+ "AMIC2", "MIC BIAS Internal2",
+ "DMIC2", "MIC BIAS External1",
+ "DMIC2", "Digital Mic2";
+
+ pinctrl-0 = <&cdc_pdm_default &sec_mi2s_default &pri_mi2s_mclk_default &cdc_dmic_default>;
+ pinctrl-1 = <&cdc_pdm_sleep &sec_mi2s_sleep &pri_mi2s_mclk_sleep &cdc_dmic_sleep>;
+ pinctrl-names = "default", "sleep";
+};
+
&usb {
extcon = <&usb_id>, <&usb_id>;
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
index b748d140b52e..f7be7e371820 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
@@ -3,6 +3,7 @@
/dts-v1/;
#include "msm8916-pm8916.dtsi"
+#include "msm8916-modem-qdsp6.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
@@ -23,6 +24,28 @@
stdout-path = "serial0";
};
+ battery: battery {
+ compatible = "simple-battery";
+ device-chemistry = "lithium-ion-polymer";
+ voltage-min-design-microvolt = <3700000>;
+ voltage-max-design-microvolt = <4200000>;
+ energy-full-design-microwatt-hours = <13690000>;
+ charge-full-design-microamp-hours = <3700000>;
+
+ ocv-capacity-celsius = <25>;
+ ocv-capacity-table-0 =
+ <4186000 100>, <4126000 95>, <4078000 90>,
+ <4036000 85>, <3997000 80>, <3962000 75>,
+ <3932000 70>, <3904000 65>, <3874000 60>,
+ <3839000 55>, <3809000 50>, <3792000 45>,
+ <3780000 40>, <3772000 35>, <3764000 30>,
+ <3752000 25>, <3731000 20>, <3704000 16>,
+ <3677000 13>, <3670000 11>, <3668000 10>,
+ <3666000 9>, <3662000 8>, <3658000 7>, <3648000 6>,
+ <3624000 5>, <3580000 4>, <3518000 3>, <3434000 2>,
+ <3310000 1>, <3000000 0>;
+ };
+
flash-led-controller {
/* Actually qcom,leds-gpio-flash */
compatible = "sgmicro,sgm3140";
@@ -111,6 +134,22 @@
status = "okay";
};
+&mpss_mem {
+ reg = <0x0 0x86800000 0x0 0x5000000>;
+};
+
+&pm8916_bms {
+ monitored-battery = <&battery>;
+ status = "okay";
+};
+
+&pm8916_codec {
+ qcom,micbias-lvl = <2800>;
+ qcom,mbhc-vthreshold-low = <150 180 237 450 500>;
+ qcom,mbhc-vthreshold-high = <150 180 237 450 500>;
+ qcom,hphl-jack-type-normally-open;
+};
+
&pm8916_resin {
linux,code = <KEY_VOLUMEDOWN>;
status = "okay";
@@ -141,6 +180,14 @@
status = "okay";
};
+&sound {
+ model = "msm8916-1mic";
+ audio-routing =
+ "AMIC1", "MIC BIAS External1",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+};
+
&usb {
extcon = <&usb_id>, <&usb_id>;
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-lg-c50.dts b/arch/arm64/boot/dts/qcom/msm8916-lg-c50.dts
new file mode 100644
index 000000000000..a823a1c40208
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-lg-c50.dts
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-pm8916.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "LG Leon LTE";
+ compatible = "lg,c50", "qcom,msm8916";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1; /* eMMC */
+ mmc1 = &sdhc_2; /* SD card */
+ serial0 = &blsp_uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Buttons";
+
+ volume-up-button {
+ label = "Volume Up";
+ gpios = <&tlmm 108 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down-button {
+ label = "Volume Down";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ reg_sd_vmmc: regulator-sdcard-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "sdcard-vmmc";
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ gpio = <&tlmm 60 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ startup-delay-us = <5000>;
+
+ pinctrl-0 = <&sd_vmmc_en_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_uart2 {
+ status = "okay";
+};
+
+&pm8916_usbin {
+ status = "okay";
+};
+
+&pm8916_vib {
+ status = "okay";
+};
+
+&sdhc_1 {
+ status = "okay";
+};
+
+&sdhc_2 {
+ vmmc-supply = <&reg_sd_vmmc>;
+
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
+
+ status = "okay";
+};
+
+&usb {
+ dr_mode = "peripheral";
+ extcon = <&pm8916_usbin>;
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&pm8916_usbin>;
+};
+
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
+&wcnss {
+ status = "okay";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3620";
+};
+
+&wcnss_mem {
+ status = "okay";
+};
+
+&tlmm {
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107", "gpio108";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ sd_vmmc_en_default: sd-vmmc-en-default-state {
+ pins = "gpio60";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-lg-m216.dts b/arch/arm64/boot/dts/qcom/msm8916-lg-m216.dts
new file mode 100644
index 000000000000..07345e694f6f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-lg-m216.dts
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-pm8916.dtsi"
+#include "msm8916-modem-qdsp6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "LG K10 (K420n)";
+ compatible = "lg,m216", "qcom,msm8916";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1; /* eMMC */
+ mmc1 = &sdhc_2; /* SD card */
+ serial0 = &blsp_uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ voltage-min-design-microvolt = <3300000>;
+ voltage-max-design-microvolt = <4350000>;
+ energy-full-design-microwatt-hours = <8800000>;
+ charge-full-design-microamp-hours = <2300000>;
+
+ ocv-capacity-celsius = <25>;
+ ocv-capacity-table-0 = <4342000 100>, <4266000 95>, <4206000 90>,
+ <4148000 85>, <4094000 80>, <4046000 75>, <3994000 70>,
+ <3956000 65>, <3916000 60>, <3866000 55>, <3831000 50>,
+ <3808000 45>, <3789000 40>, <3776000 35>, <3769000 30>,
+ <3760000 25>, <3740000 20>, <3712000 16>, <3684000 13>,
+ <3676000 11>, <3674000 10>, <3672000 9>, <3669000 8>,
+ <3665000 7>, <3660000 6>, <3643000 5>, <3602000 4>,
+ <3542000 3>, <3458000 2>, <3326000 1>, <3000000 0>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Buttons";
+
+ volume-up-button {
+ label = "Volume Up";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down-button {
+ label = "Volume Down";
+ gpios = <&tlmm 108 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+};
+
+&blsp_i2c2 {
+ status = "okay";
+
+ accelerometer@11 {
+ compatible = "bosch,bmc150_accel";
+ reg = <0x11>;
+
+ interrupts-extended = <&tlmm 115 IRQ_TYPE_EDGE_RISING>;
+
+ mount-matrix = "0", "1", "0",
+ "-1", "0", "0",
+ "0", "0", "1";
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+ };
+
+ magnetometer@13 {
+ compatible = "bosch,bmc150_magn";
+ reg = <0x13>;
+
+ interrupts-extended = <&tlmm 69 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+
+ pinctrl-0 = <&magn_int_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_i2c5 {
+ status = "okay";
+
+ touchscreen@34 {
+ compatible = "melfas,mip4_ts";
+ reg = <0x34>;
+
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>;
+ ce-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&touchscreen_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_uart2 {
+ status = "okay";
+};
+
+&mpss_mem {
+ reg = <0x0 0x86800000 0x0 0x4a00000>;
+};
+
+&pm8916_bms {
+ monitored-battery = <&battery>;
+ power-supplies = <&pm8916_charger>;
+
+ status = "okay";
+};
+
+&pm8916_charger {
+ qcom,fast-charge-safe-current = <700000>;
+ qcom,fast-charge-safe-voltage = <4300000>;
+
+ monitored-battery = <&battery>;
+ status = "okay";
+};
+
+&pm8916_codec {
+ qcom,micbias1-ext-cap;
+ qcom,micbias-lvl = <2800>;
+ qcom,mbhc-vthreshold-low = <75 100 120 180 500>;
+ qcom,mbhc-vthreshold-high = <75 100 120 180 500>;
+ qcom,hphl-jack-type-normally-open;
+};
+
+&pm8916_rpm_regulators {
+ pm8916_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+};
+
+&pm8916_vib {
+ status = "okay";
+};
+
+&sdhc_1 {
+ status = "okay";
+};
+
+&sdhc_2 {
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ status = "okay";
+};
+
+&sound {
+ audio-routing =
+ "AMIC1", "MIC BIAS External1",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+};
+
+&usb {
+ dr_mode = "peripheral";
+ extcon = <&pm8916_charger>;
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&pm8916_charger>;
+};
+
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
+&wcnss {
+ status = "okay";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3620";
+};
+
+&wcnss_mem {
+ status = "okay";
+};
+
+&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107", "gpio108";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ magn_int_default: magn-int-default-state {
+ pins = "gpio69";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ touchscreen_default: touchscreen-default-state {
+ touchscreen-pins {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ ce-pins {
+ pins = "gpio12";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
index 3a3e794c022f..7f0c2c1b8a94 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
@@ -12,7 +12,7 @@
/ {
model = "Longcheer L8150";
- compatible = "longcheer,l8150", "qcom,msm8916-v1-qrd/9-v1", "qcom,msm8916";
+ compatible = "longcheer,l8150", "qcom,msm8916";
chassis-type = "handset";
aliases {
diff --git a/arch/arm64/boot/dts/qcom/msm8916-motorola-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-motorola-common.dtsi
new file mode 100644
index 000000000000..6a27d0ecd2ad
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-motorola-common.dtsi
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "msm8916-pm8916.dtsi"
+#include "msm8916-modem-qdsp6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ aliases {
+ mmc0 = &sdhc_1; /* eMMC */
+ mmc1 = &sdhc_2; /* SD card */
+ serial0 = &blsp_uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Buttons";
+
+ volume-up-button {
+ label = "Volume Up";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&usb_id_default>;
+ pinctrl-1 = <&usb_id_sleep>;
+ pinctrl-names = "default", "sleep";
+ };
+};
+
+&blsp_i2c2 {
+ status = "okay";
+
+ touchscreen: touchscreen@20 {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vio-supply = <&pm8916_l6>;
+
+ syna,startup-delay-ms = <100>;
+
+ rmi4-f01@1 {
+ reg = <1>;
+ syna,nosleep-mode = <1>; /* Allow sleeping */
+ };
+
+ rmi4-f11@11 {
+ reg = <11>;
+ syna,sensor-type = <1>; /* Touchscreen */
+ };
+ };
+};
+
+&blsp_uart1 {
+ status = "okay";
+};
+
+&mpss_mem {
+ reg = <0x0 0x86800000 0x0 0x5500000>;
+};
+
+&pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm8916_rpm_regulators {
+ pm8916_l16: l16 {
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&pm8916_vib {
+ status = "okay";
+};
+
+&sdhc_1 {
+ status = "okay";
+};
+
+&sdhc_2 {
+ status = "okay";
+};
+
+&usb {
+ extcon = <&usb_id>, <&usb_id>;
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&usb_id>;
+};
+
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
+&wcnss {
+ status = "okay";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3620";
+};
+
+&wcnss_mem {
+ status = "okay";
+};
+
+/* CTS/RTX are not used */
+&blsp_uart1_default {
+ pins = "gpio0", "gpio1";
+};
+&blsp_uart1_sleep {
+ pins = "gpio0", "gpio1";
+};
+
+&tlmm {
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ usb_id_default: usb-id-default-state {
+ pins = "gpio91";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ usb_id_sleep: usb-id-sleep-state {
+ pins = "gpio91";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-motorola-harpia.dts b/arch/arm64/boot/dts/qcom/msm8916-motorola-harpia.dts
new file mode 100644
index 000000000000..8380451ebbf6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-motorola-harpia.dts
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-motorola-common.dtsi"
+
+/ {
+ model = "Motorola Moto G4 Play";
+ compatible = "motorola,harpia", "qcom,msm8916";
+ chassis-type = "handset";
+};
+
+&blsp_i2c1 {
+ status = "okay";
+
+ battery@36 {
+ compatible = "maxim,max17050";
+ reg = <0x36>;
+
+ interrupts-extended = <&tlmm 62 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&battery_alert_default>;
+ pinctrl-names = "default";
+
+ maxim,rsns-microohm = <10000>;
+ maxim,over-heat-temp = <600>;
+ maxim,cold-temp = <(-200)>;
+ maxim,dead-volt = <3200>;
+ maxim,over-volt = <4500>;
+ };
+
+ /* charger@6b */
+};
+
+&blsp_i2c4 {
+ status = "okay";
+
+ accelerometer@19 {
+ compatible = "bosch,bma253";
+ reg = <0x19>;
+
+ interrupts-extended = <&tlmm 115 IRQ_TYPE_EDGE_RISING>,
+ <&tlmm 119 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+
+ mount-matrix = "1", "0", "0",
+ "0", "-1", "0",
+ "0", "0", "1";
+
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+ };
+
+ /* proximity@49 */
+};
+
+&pm8916_codec {
+ qcom,micbias-lvl = <2800>;
+ qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
+ qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
+ qcom,micbias1-ext-cap;
+};
+
+&pm8916_rpm_regulators {
+ pm8916_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+};
+
+&sdhc_2 {
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+
+ cd-gpios = <&tlmm 118 GPIO_ACTIVE_LOW>;
+};
+
+&sound {
+ audio-routing =
+ "AMIC1", "MIC BIAS External1",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+
+ pinctrl-0 = <&cdc_pdm_default &headset_switch_supply_en
+ &headset_switch_in>;
+ pinctrl-1 = <&cdc_pdm_sleep &headset_switch_supply_en
+ &headset_switch_in>;
+ pinctrl-names = "default", "sleep";
+};
+
+&touchscreen {
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&pm8916_l16>;
+
+ pinctrl-0 = <&ts_int_default>;
+ pinctrl-names = "default";
+};
+
+&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115", "gpio119";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ battery_alert_default: battery-alert-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ headset_switch_in: headset-switch-in-state {
+ pins = "gpio112";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+
+ headset_switch_supply_en: headset-switch-supply-en-state {
+ pins = "gpio111";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio118";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ ts_int_default: ts-int-default-state {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-motorola-osprey.dts b/arch/arm64/boot/dts/qcom/msm8916-motorola-osprey.dts
new file mode 100644
index 000000000000..ec5589fc69bd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-motorola-osprey.dts
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-motorola-common.dtsi"
+
+/ {
+ model = "Motorola Moto G 2015";
+ compatible = "motorola,osprey", "qcom,msm8916";
+ chassis-type = "handset";
+
+ reg_touch_vdda: regulator-touch-vdda {
+ compatible = "regulator-fixed";
+ regulator-name = "touch_vdda";
+ gpio = <&tlmm 114 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-0 = <&touch_vdda_default>;
+ pinctrl-names = "default";
+ startup-delay-us = <300>;
+ vin-supply = <&pm8916_l16>;
+ };
+};
+
+&blsp_i2c1 {
+ status = "okay";
+
+ battery@36 {
+ compatible = "maxim,max17050";
+ reg = <0x36>;
+
+ interrupts-extended = <&tlmm 49 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&battery_alert_default>;
+ pinctrl-names = "default";
+
+ maxim,rsns-microohm = <10000>;
+ maxim,over-heat-temp = <600>;
+ maxim,cold-temp = <(-200)>;
+ maxim,dead-volt = <3200>;
+ maxim,over-volt = <4500>;
+
+ };
+};
+
+&blsp_i2c6 {
+ /* magnetometer@c */
+};
+
+&pm8916_codec {
+ qcom,micbias1-ext-cap;
+ qcom,micbias2-ext-cap;
+};
+
+&sdhc_2 {
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+
+ cd-gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
+};
+
+&sound {
+ audio-routing =
+ "AMIC1", "MIC BIAS External1",
+ "AMIC3", "MIC BIAS External1";
+};
+
+&touchscreen {
+ interrupts-extended = <&tlmm 21 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&reg_touch_vdda>;
+
+ pinctrl-0 = <&ts_int_default>;
+ pinctrl-names = "default";
+};
+
+&tlmm {
+ battery_alert_default: battery-alert-default-state {
+ pins = "gpio49";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio25";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ ts_int_default: ts-int-default-state {
+ pins = "gpio21";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ touch_vdda_default: touch-vdda-default-state {
+ pins = "gpio114";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-motorola-surnia.dts b/arch/arm64/boot/dts/qcom/msm8916-motorola-surnia.dts
new file mode 100644
index 000000000000..eecf78ba45bb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-motorola-surnia.dts
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-motorola-common.dtsi"
+
+/ {
+ model = "Motorola Moto E 2015 LTE";
+ compatible = "motorola,surnia", "qcom,msm8916";
+ chassis-type = "handset";
+};
+
+&blsp_i2c4 {
+ status = "okay";
+
+ battery@36 {
+ compatible = "maxim,max17050";
+ reg = <0x36>;
+
+ interrupts-extended = <&tlmm 12 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&battery_alert_default>;
+ pinctrl-names = "default";
+
+ maxim,rsns-microohm = <10000>;
+ maxim,over-heat-temp = <600>;
+ maxim,cold-temp = <(-200)>;
+ maxim,dead-volt = <3200>;
+ maxim,over-volt = <4500>;
+
+ };
+};
+
+&pm8916_codec {
+ qcom,micbias1-ext-cap;
+ qcom,micbias2-ext-cap;
+};
+
+&sdhc_2 {
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+
+ cd-gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
+};
+
+&sound {
+ audio-routing =
+ "AMIC1", "MIC BIAS External1",
+ "AMIC3", "MIC BIAS External1";
+};
+
+&touchscreen {
+ interrupts-extended = <&tlmm 21 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&pm8916_l16>;
+
+ pinctrl-0 = <&ts_int_default>;
+ pinctrl-names = "default";
+};
+
+&tlmm {
+ battery_alert_default: battery-alert-default-state {
+ pins = "gpio12";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio25";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ ts_int_default: ts-int-default-state {
+ pins = "gpio21";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
index ac527a3a0826..c11a845e91bb 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
@@ -9,7 +9,7 @@
/ {
model = "Qualcomm Technologies, Inc. MSM 8916 MTP";
- compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp/1", "qcom,msm8916";
+ compatible = "qcom,msm8916-mtp", "qcom,msm8916";
chassis-type = "handset";
aliases {
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 2937495940ea..e6355e5e2177 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
@@ -28,6 +28,12 @@
};
};
+ battery: battery {
+ compatible = "simple-battery";
+ precharge-current-microamp = <450000>;
+ precharge-upper-limit-microvolt = <3500000>;
+ };
+
clk_pwm: pwm {
compatible = "clk-pwm";
#pwm-cells = <2>;
@@ -128,6 +134,12 @@
pinctrl-names = "default";
pinctrl-0 = <&muic_int_default>;
+
+ usb_con: connector {
+ compatible = "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ };
};
};
@@ -239,7 +251,7 @@
&blsp_i2c4 {
status = "okay";
- battery@35 {
+ fuel-gauge@35 {
compatible = "richtek,rt5033-battery";
reg = <0x35>;
interrupt-parent = <&tlmm>;
@@ -247,6 +259,44 @@
pinctrl-names = "default";
pinctrl-0 = <&fg_alert_default>;
+
+ power-supplies = <&charger>;
+ };
+};
+
+&blsp_i2c6 {
+ status = "okay";
+
+ pmic@34 {
+ compatible = "richtek,rt5033";
+ reg = <0x34>;
+
+ interrupts-extended = <&tlmm 62 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&pmic_int_default>;
+ pinctrl-names = "default";
+
+ regulators {
+ rt5033_reg_safe_ldo: SAFE_LDO {
+ regulator-min-microvolt = <4900000>;
+ regulator-max-microvolt = <4900000>;
+ regulator-always-on;
+ };
+
+ /*
+ * Needed for camera, but not used yet.
+ * Define empty nodes to allow disabling the unused
+ * regulators.
+ */
+ LDO {};
+ BUCK {};
+ };
+
+ charger: charger {
+ compatible = "richtek,rt5033-charger";
+ monitored-battery = <&battery>;
+ richtek,usb-connector = <&usb_con>;
+ };
};
};
@@ -470,6 +520,13 @@
bias-disable;
};
+ pmic_int_default: pmic-int-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
sdc2_cd_default: sdc2-cd-default-state {
pins = "gpio38";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
index 3b934f5eba47..906d31f1ea21 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
@@ -55,6 +55,12 @@
"0", "0", "1";
};
+&battery {
+ charge-term-current-microamp = <150000>;
+ constant-charge-current-max-microamp = <1000000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
&blsp_i2c5 {
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
index 391befa22bb4..fe39be7a742b 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
@@ -29,6 +29,12 @@
"0", "0", "1";
};
+&battery {
+ charge-term-current-microamp = <200000>;
+ constant-charge-current-max-microamp = <1500000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
&blsp_i2c5 {
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
index 3c49dac92d2d..c50f81a68897 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
@@ -23,6 +23,12 @@
pinctrl-names = "default";
pinctrl-0 = <&muic_int_default>;
+
+ usb_con: connector {
+ compatible = "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e5.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-e5.dts
index fad2535255f7..800cb1038da0 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e5.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e5.dts
@@ -23,6 +23,12 @@
chassis-type = "handset";
};
+&battery {
+ charge-term-current-microamp = <200000>;
+ constant-charge-current-max-microamp = <1500000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
&blsp_i2c5 {
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e7.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-e7.dts
index b412b61ca258..ec1debd2e245 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e7.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e7.dts
@@ -23,6 +23,13 @@
chassis-type = "handset";
};
+&battery {
+ charge-term-current-microamp = <200000>;
+ constant-charge-current-max-microamp = <1500000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
+
&pm8916_l17 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
index c2800ad2dd5b..81b3e0760154 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
/ {
aliases {
@@ -26,6 +27,36 @@
};
};
+ battery: battery {
+ compatible = "simple-battery";
+ precharge-current-microamp = <450000>;
+ precharge-upper-limit-microvolt = <3500000>;
+ };
+
+ clk_pwm_backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&clk_pwm 0 100000>;
+
+ enable-gpios = <&tlmm 98 GPIO_ACTIVE_HIGH>;
+
+ brightness-levels = <0 255>;
+ num-interpolated-steps = <255>;
+ default-brightness-level = <128>;
+
+ pinctrl-0 = <&backlight_en_default>;
+ pinctrl-names = "default";
+ };
+
+ clk_pwm: pwm {
+ compatible = "clk-pwm";
+ #pwm-cells = <2>;
+
+ clocks = <&gcc GCC_GP2_CLK>;
+
+ pinctrl-0 = <&backlight_pwm_default>;
+ pinctrl-names = "default";
+ };
+
gpio-keys {
compatible = "gpio-keys";
@@ -54,6 +85,35 @@
max-microvolt = <3300000>;
};
+ i2c_nfc: i2c-nfc {
+ compatible = "i2c-gpio";
+ sda-gpios = <&tlmm 0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&tlmm 1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-0 = <&nfc_i2c_default>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ s3fwrn5_nfc: nfc@27 {
+ compatible = "samsung,s3fwrn5-i2c";
+ reg = <0x27>;
+
+ interrupts-extended = <&tlmm 21 IRQ_TYPE_EDGE_RISING>;
+
+ en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+ wake-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>;
+
+ clocks = <&rpmcc RPM_SMD_BB_CLK2_PIN>;
+
+ pinctrl-0 = <&nfc_default>, <&nfc_clk_req>;
+ pinctrl-names = "default";
+
+ status = "disabled";
+ };
+ };
+
reg_motor_vdd: regulator-motor-vdd {
compatible = "regulator-fixed";
regulator-name = "motor_vdd";
@@ -66,6 +126,19 @@
pinctrl-0 = <&motor_en_default>;
pinctrl-names = "default";
};
+
+ reg_vdd_tsp_a: regulator-vdd-tsp-a {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_tsp_a";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+ gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&tsp_en_default>;
+ pinctrl-names = "default";
+ };
};
&blsp_i2c1 {
@@ -77,6 +150,82 @@
interrupts-extended = <&tlmm 12 IRQ_TYPE_EDGE_FALLING>;
pinctrl-0 = <&muic_int_default>;
pinctrl-names = "default";
+
+ usb_con: connector {
+ compatible = "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ };
+ };
+};
+
+&blsp_i2c2 {
+ /* Available sensors vary depending on model variant */
+ status = "okay";
+
+ bosch_accel: accelerometer@10 {
+ compatible = "bosch,bmc150_accel";
+ reg = <0x10>;
+ interrupts-extended = <&tlmm 115 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l5>;
+ vddio-supply = <&pm8916_l5>;
+
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+
+ mount-matrix = "0", "-1", "0",
+ "-1", "0", "0",
+ "0", "0", "1";
+
+ status = "disabled";
+ };
+
+ bosch_magn: magnetometer@12 {
+ compatible = "bosch,bmc150_magn";
+ reg = <0x12>;
+
+ vdd-supply = <&pm8916_l5>;
+ vddio-supply = <&pm8916_l5>;
+
+ mount-matrix = "0", "-1", "0",
+ "-1", "0", "0",
+ "0", "0", "1";
+
+ status = "disabled";
+ };
+
+ st_accel: accelerometer@1d {
+ compatible = "st,lsm303c-accel";
+ reg = <0x1d>;
+ interrupts-extended = <&tlmm 115 IRQ_TYPE_LEVEL_HIGH>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l5>;
+
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+
+ st,drdy-int-pin = <1>;
+ mount-matrix = "0", "-1", "0",
+ "1", "0", "0",
+ "0", "0", "-1";
+
+ status = "disabled";
+ };
+
+ st_magn: magnetometer@1e {
+ compatible = "st,lsm303c-magn";
+ reg = <0x1e>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l5>;
+
+ mount-matrix = "0", "-1", "0",
+ "1", "0", "0",
+ "0", "0", "-1";
+
+ status = "disabled";
};
};
@@ -91,6 +240,64 @@
pinctrl-0 = <&fg_alert_default>;
pinctrl-names = "default";
+
+ power-supplies = <&charger>;
+ };
+};
+
+&blsp_i2c5 {
+ status = "okay";
+
+ touchscreen: touchscreen@20 {
+ compatible = "zinitix,bt541";
+ reg = <0x20>;
+
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>;
+
+ touchscreen-size-x = <540>;
+ touchscreen-size-y = <960>;
+
+ vcca-supply = <&reg_vdd_tsp_a>;
+ vdd-supply = <&pm8916_l6>;
+
+ pinctrl-0 = <&tsp_int_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_i2c6 {
+ status = "okay";
+
+ pmic@34 {
+ compatible = "richtek,rt5033";
+ reg = <0x34>;
+
+ interrupts-extended = <&tlmm 62 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&pmic_int_default>;
+ pinctrl-names = "default";
+
+ regulators {
+ rt5033_reg_safe_ldo: SAFE_LDO {
+ regulator-min-microvolt = <4900000>;
+ regulator-max-microvolt = <4900000>;
+ regulator-always-on;
+ };
+
+ /*
+ * Needed for camera, but not used yet.
+ * Define empty nodes to allow disabling the unused
+ * regulators.
+ */
+ LDO {};
+ BUCK {};
+ };
+
+ charger: charger {
+ compatible = "richtek,rt5033-charger";
+ monitored-battery = <&battery>;
+ richtek,usb-connector = <&usb_con>;
+ };
};
};
@@ -166,6 +373,25 @@
};
&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ backlight_en_default: backlight-en-default-state {
+ pins = "gpio98";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ backlight_pwm_default: backlight-pwm-default-state {
+ pins = "gpio50";
+ function = "gcc_gp2_clk_a";
+ };
+
fg_alert_default: fg-alert-default-state {
pins = "gpio121";
function = "gpio";
@@ -194,10 +420,64 @@
bias-disable;
};
+ nfc_default: nfc-default-state {
+ irq-pins {
+ pins = "gpio21";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ nfc-pins {
+ pins = "gpio20", "gpio49";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ nfc_i2c_default: nfc-i2c-default-state {
+ pins = "gpio0", "gpio1";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ pmic_int_default: pmic-int-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
sdc2_cd_default: sdc2-cd-default-state {
pins = "gpio38";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
+
+ tsp_en_default: tsp-en-default-state {
+ pins = "gpio73";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ tsp_int_default: tsp-int-default-state {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
+
+&pm8916_gpios {
+ nfc_clk_req: nfc-clk-req-state {
+ pins = "gpio2";
+ function = "func1";
+ power-source = <PM8916_GPIO_L2>;
+ bias-disable;
+ input-enable;
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts
index 9d65fa58ba92..677e4e286ac0 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts
@@ -21,6 +21,76 @@
};
};
+&battery {
+ charge-term-current-microamp = <200000>;
+ constant-charge-current-max-microamp = <1000000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
+&bosch_accel {
+ status = "okay";
+};
+
+&bosch_magn {
+ status = "okay";
+};
+
+&blsp_i2c6 {
+ /* pmic@34 is on i2c_nfc instead */
+ /delete-node/ pmic@34;
+
+ nfc@27 {
+ compatible = "samsung,s3fwrn5-i2c";
+ reg = <0x27>;
+
+ interrupts-extended = <&tlmm 21 IRQ_TYPE_EDGE_RISING>;
+
+ en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+ wake-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>;
+
+ clocks = <&rpmcc RPM_SMD_BB_CLK2_PIN>;
+
+ pinctrl-0 = <&nfc_default>, <&nfc_clk_req>;
+ pinctrl-names = "default";
+ };
+};
+
+&i2c_nfc {
+ /* nfc@27 is on &blsp_i2c6 */
+
+ pmic@34 {
+ compatible = "richtek,rt5033";
+ reg = <0x34>;
+
+ interrupts-extended = <&tlmm 62 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&pmic_int_default>;
+ pinctrl-names = "default";
+
+ regulators {
+ rt5033_reg_safe_ldo: SAFE_LDO {
+ regulator-min-microvolt = <4900000>;
+ regulator-max-microvolt = <4900000>;
+ regulator-always-on;
+ };
+
+ /*
+ * Needed for camera, but not used yet.
+ * Define empty nodes to allow disabling the unused
+ * regulators.
+ */
+ LDO {};
+ BUCK {};
+ };
+
+ charger: charger {
+ compatible = "richtek,rt5033-charger";
+ monitored-battery = <&battery>;
+ richtek,usb-connector = <&usb_con>;
+ };
+ };
+};
+
&mpss_mem {
/* Firmware for gprimeltecan needs more space */
reg = <0x0 0x86800000 0x0 0x5400000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts
index 5882b3a593b8..135df1739dbd 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts
@@ -41,6 +41,12 @@
};
};
+&battery {
+ charge-term-current-microamp = <150000>;
+ constant-charge-current-max-microamp = <1000000>;
+ constant-charge-voltage-max-microvolt = <4400000>;
+};
+
&reg_motor_vdd {
gpio = <&tlmm 72 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts
index a66ce4b13547..582bfcb09684 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts
@@ -10,6 +10,20 @@
chassis-type = "handset";
};
+&battery {
+ charge-term-current-microamp = <200000>;
+ constant-charge-current-max-microamp = <1000000>;
+ constant-charge-voltage-max-microvolt = <4350000>;
+};
+
+&bosch_accel {
+ status = "okay";
+};
+
+&bosch_magn {
+ status = "okay";
+};
+
&mpss_mem {
/* Firmware for grandprimelte needs more space */
reg = <0x0 0x86800000 0x0 0x5400000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi
index 42843771ae2a..e7f265e3c2ab 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi
@@ -5,6 +5,9 @@
/* SM5504 MUIC instead of SM5502 */
/delete-node/ &muic;
+/* Touchscreen varies depending on model variant */
+/delete-node/ &touchscreen;
+
&blsp_i2c1 {
muic: extcon@14 {
compatible = "siliconmitus,sm5504-muic";
@@ -12,5 +15,32 @@
interrupts-extended = <&tlmm 12 IRQ_TYPE_EDGE_FALLING>;
pinctrl-0 = <&muic_int_default>;
pinctrl-names = "default";
+
+ usb_con: connector {
+ compatible = "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ };
};
};
+
+/* On rossa backlight is controlled with MIPI DCS commands */
+&clk_pwm {
+ status = "disabled";
+};
+
+&clk_pwm_backlight {
+ status = "disabled";
+};
+
+&s3fwrn5_nfc {
+ status = "okay";
+};
+
+&st_accel {
+ compatible = "st,lis2hh12";
+ mount-matrix = "1", "0", "0",
+ "0", "-1", "0",
+ "0", "0", "1";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts
index ebaa13c6b016..1981bb71f6a9 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts
@@ -10,6 +10,12 @@
chassis-type = "handset";
};
+&battery {
+ charge-term-current-microamp = <150000>;
+ constant-charge-current-max-microamp = <700000>;
+ constant-charge-voltage-max-microvolt = <4400000>;
+};
+
&mpss_mem {
/* Firmware for rossa needs more space */
reg = <0x0 0x86800000 0x0 0x5800000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index cedff4166bfb..7383bcc603ab 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -308,7 +308,7 @@
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 0>;
+ mboxes = <&apcs 0>;
qcom,smd-edge = <15>;
rpm_requests: rpm-requests {
@@ -360,7 +360,7 @@
interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 14>;
+ mboxes = <&apcs 14>;
qcom,local-pid = <0>;
qcom,remote-pid = <1>;
@@ -385,7 +385,7 @@
interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 18>;
+ mboxes = <&apcs 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
@@ -410,8 +410,7 @@
#address-cells = <1>;
#size-cells = <0>;
- qcom,ipc-1 = <&apcs 8 13>;
- qcom,ipc-3 = <&apcs 8 19>;
+ mboxes = <0>, <&apcs 13>, <0>, <&apcs 19>;
apps_smsm: apps@0 {
reg = <0>;
@@ -1978,7 +1977,7 @@
interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
qcom,smd-edge = <0>;
- qcom,ipc = <&apcs 8 12>;
+ mboxes = <&apcs 12>;
qcom,remote-pid = <1>;
label = "hexagon";
@@ -2459,7 +2458,7 @@
smd-edge {
interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 17>;
+ mboxes = <&apcs 17>;
qcom,smd-edge = <6>;
qcom,remote-pid = <4>;
@@ -2626,7 +2625,6 @@
thermal-zones {
cpu0-1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 5>;
@@ -2656,7 +2654,6 @@
cpu2-3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 4>;
@@ -2686,7 +2683,6 @@
gpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 2>;
@@ -2713,7 +2709,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 1>;
@@ -2728,7 +2723,6 @@
modem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 0>;
diff --git a/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts b/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
index aa6c39482a2f..91acdb160227 100644
--- a/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
+++ b/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
@@ -33,6 +33,15 @@
};
};
+ battery: battery {
+ compatible = "simple-battery";
+ charge-term-current-microamp = <150000>;
+ constant-charge-current-max-microamp = <1500000>;
+ constant-charge-voltage-max-microvolt = <4300000>;
+ precharge-current-microamp = <450000>;
+ precharge-upper-limit-microvolt = <3500000>;
+ };
+
gpio-hall-sensor {
compatible = "gpio-keys";
@@ -82,7 +91,7 @@
#address-cells = <1>;
#size-cells = <0>;
- battery@35 {
+ fuel-gauge@35 {
compatible = "richtek,rt5033-battery";
reg = <0x35>;
@@ -91,6 +100,8 @@
pinctrl-0 = <&fg_alert_default>;
pinctrl-names = "default";
+
+ power-supplies = <&charger>;
};
};
@@ -286,6 +297,12 @@
pinctrl-0 = <&muic_int_default>;
pinctrl-names = "default";
+
+ usb_con: connector {
+ compatible = "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ };
};
};
@@ -319,6 +336,42 @@
};
};
+&blsp_i2c6 {
+ status = "okay";
+
+ pmic@34 {
+ compatible = "richtek,rt5033";
+ reg = <0x34>;
+
+ interrupts-extended = <&tlmm 62 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&pmic_int_default>;
+ pinctrl-names = "default";
+
+ regulators {
+ rt5033_reg_safe_ldo: SAFE_LDO {
+ regulator-min-microvolt = <4900000>;
+ regulator-max-microvolt = <4900000>;
+ regulator-always-on;
+ };
+
+ /*
+ * Needed for camera, but not used yet.
+ * Define empty nodes to allow disabling the unused
+ * regulators.
+ */
+ LDO {};
+ BUCK {};
+ };
+
+ charger: charger {
+ compatible = "richtek,rt5033-charger";
+ monitored-battery = <&battery>;
+ richtek,usb-connector = <&usb_con>;
+ };
+ };
+};
+
&blsp_uart2 {
status = "okay";
};
@@ -504,6 +557,13 @@
bias-disable;
};
+ pmic_int_default: pmic-int-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
reg_tsp_en_default: reg-tsp-en-default-state {
pins = "gpio73";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi
index dd45975682b2..46d9480cd464 100644
--- a/arch/arm64/boot/dts/qcom/msm8939.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi
@@ -248,7 +248,7 @@
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs1_mbox 8 0>;
+ mboxes = <&apcs1_mbox 0>;
qcom,smd-edge = <15>;
rpm_requests: rpm-requests {
@@ -443,8 +443,7 @@
#address-cells = <1>;
#size-cells = <0>;
- qcom,ipc-1 = <&apcs1_mbox 8 13>;
- qcom,ipc-3 = <&apcs1_mbox 8 19>;
+ mboxes = <0>, <&apcs1_mbox 13>, <0>, <&apcs1_mbox 19>;
apps_smsm: apps@0 {
reg = <0>;
@@ -2067,7 +2066,7 @@
smd-edge {
interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs1_mbox 8 17>;
+ mboxes = <&apcs1_mbox 17>;
qcom,smd-edge = <6>;
qcom,remote-pid = <4>;
@@ -2299,7 +2298,6 @@
thermal_zones: thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 5>;
@@ -2330,7 +2328,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 6>;
@@ -2361,7 +2358,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 7>;
@@ -2392,7 +2388,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 8>;
@@ -2423,7 +2418,6 @@
cpu4567-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 9>;
@@ -2454,7 +2448,6 @@
gpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 3>;
@@ -2482,7 +2475,6 @@
modem1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 0>;
@@ -2497,7 +2489,6 @@
modem2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 2>;
@@ -2512,7 +2503,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts b/arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts
index 711d84dad9d7..2edf804eb7c9 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts
@@ -301,5 +301,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts
index a5957e79b818..336b916729e4 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts
@@ -321,5 +321,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts
index 6b9245cd8b0c..bdf1bfc79c56 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts
@@ -326,5 +326,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts
index 9ac4f507e321..fccb9c4360ca 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts
@@ -322,5 +322,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts
index b0588f30f8f1..d46325e79917 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts
@@ -357,5 +357,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index f1011bb641c6..a4bfb624fb8a 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -195,7 +195,7 @@
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 0>;
+ mboxes = <&apcs 0>;
qcom,smd-edge = <15>;
rpm_requests: rpm-requests {
@@ -361,7 +361,7 @@
interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 14>;
+ mboxes = <&apcs 14>;
qcom,local-pid = <0>;
qcom,remote-pid = <1>;
@@ -386,7 +386,7 @@
interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 18>;
+ mboxes = <&apcs 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
@@ -411,8 +411,7 @@
#address-cells = <1>;
#size-cells = <0>;
- qcom,ipc-1 = <&apcs 8 13>;
- qcom,ipc-3 = <&apcs 8 19>;
+ mboxes = <0>, <&apcs 13>, <0>, <&apcs 19>;
apps_smsm: apps@0 {
reg = <0>;
@@ -1267,7 +1266,7 @@
interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
qcom,smd-edge = <0>;
- qcom,ipc = <&apcs 8 12>;
+ mboxes = <&apcs 12>;
qcom,remote-pid = <1>;
label = "modem";
@@ -1323,6 +1322,20 @@
snps,hird-threshold = /bits/ 8 <0x00>;
maximum-speed = "high-speed";
+
+ usb-role-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_dwc3_hs: endpoint {
+ };
+ };
+ };
};
};
@@ -1734,7 +1747,7 @@
smd-edge {
interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 17>;
+ mboxes = <&apcs 17>;
qcom,smd-edge = <6>;
qcom,remote-pid = <4>;
@@ -1954,8 +1967,9 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens0 9>;
+
trips {
cpu0_alert: trip-point0 {
temperature = <80000>;
@@ -1977,8 +1991,9 @@
};
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens0 10>;
+
trips {
cpu1_alert: trip-point0 {
temperature = <80000>;
@@ -2000,8 +2015,9 @@
};
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens0 11>;
+
trips {
cpu2_alert: trip-point0 {
temperature = <80000>;
@@ -2023,8 +2039,9 @@
};
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens0 12>;
+
trips {
cpu3_alert: trip-point0 {
temperature = <80000>;
@@ -2046,7 +2063,6 @@
};
cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
trips {
cpu4_alert: trip-point0 {
@@ -2069,7 +2085,6 @@
};
cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
trips {
cpu5_alert: trip-point0 {
@@ -2092,7 +2107,6 @@
};
cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
trips {
cpu6_alert: trip-point0 {
@@ -2115,7 +2129,6 @@
};
cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
trips {
cpu7_alert: trip-point0 {
@@ -2139,7 +2152,6 @@
gpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 15>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/msm8956.dtsi b/arch/arm64/boot/dts/qcom/msm8956.dtsi
index 668e05185c21..fa36b62156bb 100644
--- a/arch/arm64/boot/dts/qcom/msm8956.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8956.dtsi
@@ -8,8 +8,8 @@
#include "msm8976.dtsi"
-&pmu {
- interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+&pmu_a72 {
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_RAW(0x30) | IRQ_TYPE_LEVEL_HIGH)>;
};
&tsens {
diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi
index d2bb1ada361a..d62dcb76fa48 100644
--- a/arch/arm64/boot/dts/qcom/msm8976.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi
@@ -222,11 +222,17 @@
reg = <0x0 0x80000000 0x0 0x0>;
};
- pmu: pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ pmu-a53 {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
+ pmu_a72: pmu-a72 {
+ compatible = "arm,cortex-a72-pmu";
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_RAW(0xf0) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -237,7 +243,7 @@
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 0>;
+ mboxes = <&apcs 0>;
qcom,smd-edge = <15>;
rpm_requests: rpm-requests {
@@ -361,7 +367,7 @@
smp2p-hexagon {
compatible = "qcom,smp2p";
interrupts = <GIC_SPI 291 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 10>;
+ mboxes = <&apcs 10>;
qcom,local-pid = <0>;
qcom,remote-pid = <2>;
@@ -384,7 +390,7 @@
smp2p-modem {
compatible = "qcom,smp2p";
interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 14>;
+ mboxes = <&apcs 14>;
qcom,local-pid = <0>;
qcom,remote-pid = <1>;
@@ -407,7 +413,7 @@
smp2p-wcnss {
compatible = "qcom,smp2p";
interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 18>;
+ mboxes = <&apcs 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
@@ -433,9 +439,7 @@
#address-cells = <1>;
#size-cells = <0>;
- qcom,ipc-1 = <&apcs 8 13>;
- qcom,ipc-2 = <&apcs 8 9>;
- qcom,ipc-3 = <&apcs 8 19>;
+ mboxes = <0>, <&apcs 13>, <&apcs 9>, <&apcs 19>;
apps_smsm: apps@0 {
reg = <0>;
@@ -771,6 +775,36 @@
drive-strength = <2>;
bias-disable;
};
+
+ wcss_wlan_default: wcss-wlan-default-state {
+ wcss-wlan2-pins {
+ pins = "gpio40";
+ function = "wcss_wlan2";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ wcss-wlan1-pins {
+ pins = "gpio41";
+ function = "wcss_wlan1";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ wcss-wlan0-pins {
+ pins = "gpio42";
+ function = "wcss_wlan0";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ wcss-wlan-pins {
+ pins = "gpio43", "gpio44";
+ function = "wcss_wlan";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
};
gcc: clock-controller@1800000 {
@@ -785,10 +819,10 @@
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
<&rpmcc RPM_SMD_XO_A_CLK_SRC>,
- <0>,
- <0>,
- <0>,
- <0>;
+ <&mdss_dsi0_phy 1>,
+ <&mdss_dsi0_phy 0>,
+ <&mdss_dsi1_phy 1>,
+ <&mdss_dsi1_phy 0>;
clock-names = "xo",
"xo_a",
"dsi0pll",
@@ -808,6 +842,430 @@
reg = <0x01937000 0x30000>;
};
+ mdss: display-subsystem@1a00000 {
+ compatible = "qcom,mdss";
+
+ reg = <0x01a00000 0x1000>,
+ <0x01ab0000 0x3000>;
+ reg-names = "mdss_phys", "vbif_phys";
+
+ power-domains = <&gcc MDSS_GDSC>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_VSYNC_CLK>,
+ <&gcc GCC_MDSS_MDP_CLK>;
+ clock-names = "iface",
+ "bus",
+ "vsync",
+ "core";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ status = "disabled";
+
+ mdss_mdp: display-controller@1a01000 {
+ compatible = "qcom,msm8976-mdp5", "qcom,mdp5";
+ reg = <0x01a01000 0x89000>;
+ reg-names = "mdp_phys";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <0>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_MDP_CLK>,
+ <&gcc GCC_MDSS_VSYNC_CLK>,
+ <&gcc GCC_MDP_TBU_CLK>,
+ <&gcc GCC_MDP_RT_TBU_CLK>;
+ clock-names = "iface",
+ "bus",
+ "core",
+ "vsync",
+ "tbu",
+ "tbu_rt";
+
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&gcc MDSS_GDSC>;
+
+ iommus = <&apps_iommu 22>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_mdp5_intf1_out: endpoint {
+ remote-endpoint = <&mdss_dsi0_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_mdp5_intf2_out: endpoint {
+ remote-endpoint = <&mdss_dsi1_in>;
+ };
+ };
+ };
+
+ mdp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-177780000 {
+ opp-hz = /bits/ 64 <177780000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-270000000 {
+ opp-hz = /bits/ 64 <270000000>;
+ required-opps = <&rpmpd_opp_svs_plus>;
+ };
+
+ opp-320000000 {
+ opp-hz = /bits/ 64 <320000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+
+ opp-360000000 {
+ opp-hz = /bits/ 64 <360000000>;
+ required-opps = <&rpmpd_opp_turbo>;
+ };
+ };
+ };
+
+ mdss_dsi0: dsi@1a94000 {
+ compatible = "qcom,msm8976-dsi-ctrl", "qcom,mdss-dsi-ctrl";
+ reg = <0x01a94000 0x300>;
+ reg-names = "dsi_ctrl";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <4>;
+
+ 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";
+
+ assigned-clocks = <&gcc GCC_MDSS_BYTE0_CLK_SRC>,
+ <&gcc GCC_MDSS_PCLK0_CLK_SRC>;
+ assigned-clock-parents = <&mdss_dsi0_phy 0>,
+ <&mdss_dsi0_phy 1>;
+
+ phys = <&mdss_dsi0_phy>;
+
+ operating-points-v2 = <&dsi0_opp_table>;
+ power-domains = <&gcc MDSS_GDSC>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_dsi0_in: endpoint {
+ remote-endpoint = <&mdss_mdp5_intf1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dsi0_out: endpoint {
+ };
+ };
+ };
+
+ dsi0_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-125000000 {
+ opp-hz = /bits/ 64 <125000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-161250000 {
+ opp-hz = /bits/ 64 <161250000>;
+ required-opps = <&rpmpd_opp_svs_plus>;
+ };
+
+ opp-187500000 {
+ opp-hz = /bits/ 64 <187500000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+ };
+ };
+
+ mdss_dsi1: dsi@1a96000 {
+ compatible = "qcom,msm8976-dsi-ctrl", "qcom,mdss-dsi-ctrl";
+ reg = <0x01a96000 0x300>;
+ reg-names = "dsi_ctrl";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <5>;
+
+ clocks = <&gcc GCC_MDSS_MDP_CLK>,
+ <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_BYTE1_CLK>,
+ <&gcc GCC_MDSS_PCLK1_CLK>,
+ <&gcc GCC_MDSS_ESC1_CLK>;
+ clock-names = "mdp_core",
+ "iface",
+ "bus",
+ "byte",
+ "pixel",
+ "core";
+
+ assigned-clocks = <&gcc GCC_MDSS_BYTE1_CLK_SRC>,
+ <&gcc GCC_MDSS_PCLK1_CLK_SRC>;
+ assigned-clock-parents = <&mdss_dsi1_phy 0>,
+ <&mdss_dsi1_phy 1>;
+
+ phys = <&mdss_dsi1_phy>;
+
+ operating-points-v2 = <&dsi0_opp_table>;
+ power-domains = <&gcc MDSS_GDSC>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_dsi1_in: endpoint {
+ remote-endpoint = <&mdss_mdp5_intf2_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dsi1_out: endpoint {
+ };
+ };
+ };
+ };
+
+ mdss_dsi0_phy: phy@1a94a00 {
+ compatible = "qcom,dsi-phy-28nm-hpm-fam-b";
+ reg = <0x01a94a00 0xd4>,
+ <0x01a94400 0x280>,
+ <0x01a94b80 0x30>;
+ reg-names = "dsi_pll",
+ "dsi_phy",
+ "dsi_phy_regulator";
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "iface", "ref";
+
+ status = "disabled";
+ };
+
+ mdss_dsi1_phy: phy@1a96a00 {
+ compatible = "qcom,dsi-phy-28nm-hpm-fam-b";
+ reg = <0x01a96a00 0xd4>,
+ <0x01a96400 0x280>,
+ <0x01a96b80 0x30>;
+ reg-names = "dsi_pll",
+ "dsi_phy",
+ "dsi_phy_regulator";
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "iface", "ref";
+
+ status = "disabled";
+ };
+ };
+
+ adreno_gpu: gpu@1c00000 {
+ compatible = "qcom,adreno-510.0", "qcom,adreno";
+
+ reg = <0x01c00000 0x40000>;
+ reg-names = "kgsl_3d0_reg_memory";
+
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "kgsl_3d0_irq";
+
+ clocks = <&gcc GCC_GFX3D_OXILI_CLK>,
+ <&gcc GCC_GFX3D_OXILI_AHB_CLK>,
+ <&gcc GCC_GFX3D_OXILI_GMEM_CLK>,
+ <&gcc GCC_GFX3D_BIMC_CLK>,
+ <&gcc GCC_GFX3D_OXILI_TIMER_CLK>,
+ <&gcc GCC_GFX3D_OXILI_AON_CLK>;
+ clock-names = "core",
+ "iface",
+ "mem",
+ "mem_iface",
+ "rbbmtimer",
+ "alwayson";
+
+ power-domains = <&gcc OXILI_GX_GDSC>;
+
+ iommus = <&gpu_iommu 0>;
+
+ operating-points-v2 = <&gpu_opp_table>;
+
+ status = "disabled";
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ opp-supported-hw = <0xff>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ opp-supported-hw = <0xff>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ opp-supported-hw = <0xff>;
+ };
+
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ required-opps = <&rpmpd_opp_nom_plus>;
+ opp-supported-hw = <0xff>;
+ };
+
+ opp-540000000 {
+ opp-hz = /bits/ 64 <540000000>;
+ required-opps = <&rpmpd_opp_turbo>;
+ opp-supported-hw = <0xff>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ required-opps = <&rpmpd_opp_turbo>;
+ opp-supported-hw = <0xff>;
+ };
+ };
+ };
+
+ apps_iommu: iommu@1ee0000 {
+ compatible = "qcom,msm8976-iommu", "qcom,msm-iommu-v2";
+ reg = <0x01ee0000 0x3000>;
+ ranges = <0 0x01e20000 0x20000>;
+
+ clocks = <&gcc GCC_SMMU_CFG_CLK>,
+ <&gcc GCC_APSS_TCU_CLK>;
+ clock-names = "iface", "bus";
+
+ qcom,iommu-secure-id = <17>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #iommu-cells = <1>;
+
+ /* VFE */
+ iommu-ctx@15000 {
+ compatible = "qcom,msm-iommu-v2-ns";
+ reg = <0x15000 0x1000>;
+ qcom,ctx-asid = <20>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* VENUS NS */
+ iommu-ctx@16000 {
+ compatible = "qcom,msm-iommu-v2-ns";
+ reg = <0x16000 0x1000>;
+ qcom,ctx-asid = <21>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* MDP0 */
+ iommu-ctx@17000 {
+ compatible = "qcom,msm-iommu-v2-ns";
+ reg = <0x17000 0x1000>;
+ qcom,ctx-asid = <22>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpu_iommu: iommu@1f08000 {
+ compatible = "qcom,msm8976-iommu", "qcom,msm-iommu-v2";
+ ranges = <0 0x01f08000 0x8000>;
+
+ clocks = <&gcc GCC_SMMU_CFG_CLK>,
+ <&gcc GCC_GFX3D_TCU_CLK>;
+ clock-names = "iface", "bus";
+
+ power-domains = <&gcc OXILI_CX_GDSC>;
+
+ qcom,iommu-secure-id = <18>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #iommu-cells = <1>;
+
+ /* gfx3d user */
+ iommu-ctx@0 {
+ compatible = "qcom,msm-iommu-v2-ns";
+ reg = <0x0 0x1000>;
+ qcom,ctx-asid = <0>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* gfx3d secure */
+ iommu-ctx@1000 {
+ compatible = "qcom,msm-iommu-v2-sec";
+ reg = <0x1000 0x1000>;
+ qcom,ctx-asid = <2>;
+ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* gfx3d priv */
+ iommu-ctx@2000 {
+ compatible = "qcom,msm-iommu-v2-sec";
+ reg = <0x2000 0x1000>;
+ qcom,ctx-asid = <1>;
+ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
spmi_bus: spmi@200f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0200f000 0x1000>,
@@ -1034,6 +1492,81 @@
status = "disabled";
};
+ wcnss: remoteproc@a204000 {
+ compatible = "qcom,pronto-v3-pil", "qcom,pronto";
+ reg = <0x0a204000 0x2000>,
+ <0x0a202000 0x1000>,
+ <0x0a21b000 0x3000>;
+ reg-names = "ccu",
+ "dxe",
+ "pmu";
+
+ memory-region = <&wcnss_fw_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";
+
+ power-domains = <&rpmpd MSM8976_VDDCX>,
+ <&rpmpd MSM8976_VDDMX>;
+ power-domain-names = "cx", "mx";
+
+ qcom,smem-states = <&wcnss_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
+ pinctrl-0 = <&wcss_wlan_default>;
+ pinctrl-names = "default";
+
+ status = "disabled";
+
+ wcnss_iris: iris {
+ /* Separate chip, compatible is board-specific */
+ clocks = <&rpmcc RPM_SMD_RF_CLK2>;
+ clock-names = "xo";
+ };
+
+ smd-edge {
+ interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
+
+ mboxes = <&apcs 17>;
+ qcom,smd-edge = <6>;
+ qcom,remote-pid = <4>;
+
+ label = "pronto";
+
+ wcnss_ctrl: wcnss {
+ compatible = "qcom,wcnss";
+ qcom,smd-channels = "WCNSS_CTRL";
+
+ qcom,mmio = <&wcnss>;
+
+ wcnss_bt: bluetooth {
+ compatible = "qcom,wcnss-bt";
+ };
+
+ wcnss_wifi: 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";
reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
@@ -1124,7 +1657,6 @@
thermal-zones {
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 0>;
@@ -1139,7 +1671,6 @@
modem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 1>;
trips {
@@ -1153,7 +1684,6 @@
qdsp-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 2>;
trips {
@@ -1167,7 +1697,6 @@
cam-isp-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 3>;
trips {
@@ -1181,7 +1710,7 @@
cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 4>;
trips {
@@ -1205,7 +1734,7 @@
cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 5>;
trips {
@@ -1229,7 +1758,7 @@
cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 6>;
trips {
@@ -1253,7 +1782,7 @@
cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 7>;
trips {
@@ -1277,7 +1806,7 @@
big-l2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 8>;
trips {
@@ -1301,7 +1830,7 @@
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 9>;
trips {
@@ -1325,7 +1854,7 @@
gpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
+
thermal-sensors = <&tsens 10>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
index 695e541832ad..917fa246857d 100644
--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -183,7 +183,7 @@
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 0>;
+ mboxes = <&apcs 0>;
qcom,smd-edge = <15>;
qcom,remote-pid = <6>;
@@ -300,7 +300,7 @@
interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 10>;
+ mboxes = <&apcs 10>;
qcom,local-pid = <0>;
qcom,remote-pid = <2>;
@@ -325,7 +325,7 @@
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 14>;
+ mboxes = <&apcs 14>;
qcom,local-pid = <0>;
qcom,remote-pid = <1>;
@@ -1093,10 +1093,10 @@
timer: timer {
compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 2 0xff08>,
- <GIC_PPI 3 0xff08>,
- <GIC_PPI 4 0xff08>,
- <GIC_PPI 1 0xff08>;
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
};
vph_pwr: vph-pwr-regulator {
diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
index 5ab583be9e0a..0386636a29f0 100644
--- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
@@ -405,7 +405,6 @@
&hsusb_phy1 {
status = "okay";
- extcon = <&typec>;
vdda-pll-supply = <&vreg_l12a_1p8>;
vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 1601e46549e7..0fd2b1b944a5 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -982,6 +982,8 @@
<&mmcc MDSS_MDP_CLK>;
clock-names = "iface", "core";
+ resets = <&mmcc MDSS_BCR>;
+
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -1929,6 +1931,16 @@
"cfg",
"bus_master",
"bus_slave";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1: pcie@608000 {
@@ -1982,6 +1994,16 @@
"cfg",
"bus_master",
"bus_slave";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie2: pcie@610000 {
@@ -2032,6 +2054,16 @@
"cfg",
"bus_master",
"bus_slave";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
};
@@ -2047,24 +2079,20 @@
power-domains = <&gcc UFS_GDSC>;
clock-names =
- "core_clk_src",
"core_clk",
"bus_clk",
"bus_aggr_clk",
"iface_clk",
- "core_clk_unipro_src",
"core_clk_unipro",
"core_clk_ice",
"ref_clk",
"tx_lane0_sync_clk",
"rx_lane0_sync_clk";
clocks =
- <&gcc UFS_AXI_CLK_SRC>,
<&gcc GCC_UFS_AXI_CLK>,
<&gcc GCC_SYS_NOC_UFS_AXI_CLK>,
<&gcc GCC_AGGRE2_UFS_AXI_CLK>,
<&gcc GCC_UFS_AHB_CLK>,
- <&gcc UFS_ICE_CORE_CLK_SRC>,
<&gcc GCC_UFS_UNIPRO_CORE_CLK>,
<&gcc GCC_UFS_ICE_CORE_CLK>,
<&rpmcc RPM_SMD_LN_BB_CLK>,
@@ -2075,10 +2103,8 @@
<0 0>,
<0 0>,
<0 0>,
- <0 0>,
- <150000000 300000000>,
<75000000 150000000>,
- <0 0>,
+ <150000000 300000000>,
<0 0>,
<0 0>,
<0 0>;
@@ -2453,6 +2479,13 @@
status = "disabled";
+ glink-edge {
+ interrupts = <GIC_SPI 179 IRQ_TYPE_EDGE_RISING>;
+ label = "dsps";
+ qcom,remote-pid = <3>;
+ mboxes = <&apcs_glb 27>;
+ };
+
smd-edge {
interrupts = <GIC_SPI 176 IRQ_TYPE_EDGE_RISING>;
@@ -2522,6 +2555,13 @@
memory-region = <&mdata_mem>;
};
+ glink-edge {
+ interrupts = <GIC_SPI 452 IRQ_TYPE_EDGE_RISING>;
+ label = "modem";
+ qcom,remote-pid = <1>;
+ mboxes = <&apcs_glb 15>;
+ };
+
smd-edge {
interrupts = <GIC_SPI 449 IRQ_TYPE_EDGE_RISING>;
@@ -3061,6 +3101,7 @@
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
snps,is-utmi-l1-suspend;
+ snps,parkmode-disable-ss-quirk;
tx-fifo-resize;
};
};
@@ -3467,6 +3508,14 @@
status = "disabled";
+ glink-edge {
+ interrupts = <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>;
+ label = "lpass";
+ qcom,remote-pid = <2>;
+ mboxes = <&apcs_glb 9>;
+ };
+
+
smd-edge {
interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
@@ -3523,6 +3572,63 @@
};
};
};
+
+ fastrpc {
+ compatible = "qcom,fastrpc";
+ qcom,smd-channels = "fastrpcsmd-apps-dsp";
+ label = "adsp";
+ qcom,non-secure-domain;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cb@5 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <5>;
+ iommus = <&lpass_q6_smmu 5>;
+ };
+
+ cb@6 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <6>;
+ iommus = <&lpass_q6_smmu 6>;
+ };
+
+ cb@7 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <7>;
+ iommus = <&lpass_q6_smmu 7>;
+ };
+
+ cb@8 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <8>;
+ iommus = <&lpass_q6_smmu 8>;
+ };
+
+ cb@9 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <9>;
+ iommus = <&lpass_q6_smmu 9>;
+ };
+
+ cb@10 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <10>;
+ iommus = <&lpass_q6_smmu 10>;
+ };
+
+ cb@11 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <11>;
+ iommus = <&lpass_q6_smmu 11>;
+ };
+
+ cb@12 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <12>;
+ iommus = <&lpass_q6_smmu 12>;
+ };
+ };
};
};
@@ -3624,7 +3730,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -3645,7 +3750,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -3666,7 +3770,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -3687,7 +3790,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -3708,7 +3810,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -3730,7 +3831,6 @@
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 7>;
@@ -3752,7 +3852,6 @@
m4m-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -3767,7 +3866,6 @@
l3-or-venus-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -3782,7 +3880,6 @@
cluster0-l2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -3797,7 +3894,6 @@
cluster1-l2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -3812,7 +3908,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -3827,7 +3922,6 @@
q6-dsp-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -3842,7 +3936,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -3857,7 +3950,6 @@
modemtx-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi
index 876c6921ddf0..d8cc0d729e99 100644
--- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi
@@ -98,30 +98,35 @@
gpio-keys {
compatible = "gpio-keys";
label = "Side buttons";
+ pinctrl-0 = <&focus_n &snapshot_n &vol_down_n &vol_up_n>;
pinctrl-names = "default";
- pinctrl-0 = <&vol_down_n &focus_n &snapshot_n>;
- button-vol-down {
- label = "Volume Down";
- gpios = <&pm8998_gpios 5 GPIO_ACTIVE_LOW>;
- linux,input-type = <EV_KEY>;
- linux,code = <KEY_VOLUMEDOWN>;
- wakeup-source;
+ button-camera-focus {
+ label = "Camera Focus";
+ gpios = <&pm8998_gpios 8 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_CAMERA_FOCUS>;
debounce-interval = <15>;
};
button-camera-snapshot {
label = "Camera Snapshot";
gpios = <&pm8998_gpios 7 GPIO_ACTIVE_LOW>;
- linux,input-type = <EV_KEY>;
linux,code = <KEY_CAMERA>;
debounce-interval = <15>;
};
- button-camera-focus {
- label = "Camera Focus";
- gpios = <&pm8998_gpios 8 GPIO_ACTIVE_LOW>;
- linux,input-type = <EV_KEY>;
- linux,code = <KEY_CAMERA_FOCUS>;
+ button-vol-down {
+ label = "Volume Down";
+ gpios = <&pm8998_gpios 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ wakeup-source;
+ debounce-interval = <15>;
+ };
+
+ button-vol-up {
+ label = "Volume Up";
+ gpios = <&pm8998_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
debounce-interval = <15>;
};
};
@@ -345,6 +350,14 @@
qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
};
+ vol_up_n: vol-up-n-state {
+ pins = "gpio6";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ bias-pull-up;
+ input-enable;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+ };
+
focus_n: focus-n-state {
pins = "gpio7";
function = PMIC_GPIO_FUNC_NORMAL;
@@ -405,9 +418,33 @@
};
};
-&pm8998_resin {
- linux,code = <KEY_VOLUMEUP>;
+&pmi8998_lpg {
+ qcom,power-source = <1>;
+
status = "okay";
+
+ multi-led {
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_STATUS;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ led@4 {
+ reg = <4>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@5 {
+ reg = <5>;
+ color = <LED_COLOR_ID_RED>;
+ };
+ };
};
&qusb2phy {
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
index 4dfe2d09ac28..7f44807b1b97 100644
--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -488,7 +488,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -509,7 +508,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -530,7 +528,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -551,7 +548,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -572,7 +568,6 @@
cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -593,7 +588,6 @@
cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -614,7 +608,6 @@
cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -635,7 +628,6 @@
cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -656,7 +648,6 @@
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -671,7 +662,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 13>;
@@ -686,7 +676,6 @@
clust0-mhm-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -701,7 +690,6 @@
clust1-mhm-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -716,7 +704,6 @@
cluster1-l2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 11>;
@@ -731,7 +718,6 @@
modem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -746,7 +732,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -761,7 +746,6 @@
wlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -776,7 +760,6 @@
q6-dsp-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
@@ -791,7 +774,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 5>;
@@ -806,7 +788,6 @@
multimedia-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -972,6 +953,16 @@
power-domains = <&gcc PCIE_0_GDSC>;
iommu-map = <0x100 &anoc1_smmu 0x1480 1>;
perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie_phy: phy@1c06000 {
@@ -1580,7 +1571,6 @@
* SoC VDDMX RPM Power Domain in the Adreno driver.
*/
power-domains = <&gpucc GPU_GX_GDSC>;
- status = "disabled";
};
gpucc: clock-controller@5065000 {
@@ -2154,6 +2144,7 @@
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
+ snps,parkmode-disable-ss-quirk;
phys = <&qusb2phy>, <&usb3phy>;
phy-names = "usb2-phy", "usb3-phy";
snps,has-lpm-erratum;
@@ -3010,6 +3001,54 @@
};
};
+ venus: video-codec@cc00000 {
+ compatible = "qcom,msm8998-venus";
+ reg = <0x0cc00000 0xff000>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&mmcc VIDEO_TOP_GDSC>;
+ clocks = <&mmcc VIDEO_CORE_CLK>,
+ <&mmcc VIDEO_AHB_CLK>,
+ <&mmcc VIDEO_AXI_CLK>,
+ <&mmcc VIDEO_MAXI_CLK>;
+ clock-names = "core", "iface", "bus", "mbus";
+ iommus = <&mmss_smmu 0x400>,
+ <&mmss_smmu 0x401>,
+ <&mmss_smmu 0x40a>,
+ <&mmss_smmu 0x407>,
+ <&mmss_smmu 0x40e>,
+ <&mmss_smmu 0x40f>,
+ <&mmss_smmu 0x408>,
+ <&mmss_smmu 0x409>,
+ <&mmss_smmu 0x40b>,
+ <&mmss_smmu 0x40c>,
+ <&mmss_smmu 0x40d>,
+ <&mmss_smmu 0x410>,
+ <&mmss_smmu 0x421>,
+ <&mmss_smmu 0x428>,
+ <&mmss_smmu 0x429>,
+ <&mmss_smmu 0x42b>,
+ <&mmss_smmu 0x42c>,
+ <&mmss_smmu 0x42d>,
+ <&mmss_smmu 0x411>,
+ <&mmss_smmu 0x431>;
+ memory-region = <&venus_mem>;
+ status = "disabled";
+
+ video-decoder {
+ compatible = "venus-decoder";
+ clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
+ clock-names = "core";
+ power-domains = <&mmcc VIDEO_SUBCORE0_GDSC>;
+ };
+
+ video-encoder {
+ compatible = "venus-encoder";
+ clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
+ clock-names = "core";
+ power-domains = <&mmcc VIDEO_SUBCORE1_GDSC>;
+ };
+ };
+
mmss_smmu: iommu@cd00000 {
compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2";
reg = <0x0cd00000 0x40000>;
@@ -3185,6 +3224,7 @@
iommus = <&anoc2_smmu 0x1900>,
<&anoc2_smmu 0x1901>;
qcom,snoc-host-cap-8bit-quirk;
+ qcom,no-msa-ready-indicator;
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm6125.dtsi b/arch/arm64/boot/dts/qcom/pm6125.dtsi
index 99369a0cdb61..d0db28336fa9 100644
--- a/arch/arm64/boot/dts/qcom/pm6125.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6125.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm6125-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm6125_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi
index 11158c2bd524..59524609fb1e 100644
--- a/arch/arm64/boot/dts/qcom/pm6150.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi
@@ -13,7 +13,7 @@
thermal-zones {
pm6150_thermal: pm6150-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm6150_temp>;
trips {
@@ -64,15 +64,15 @@
};
pm6150_vbus: usb-vbus-regulator@1100 {
- compatible = "qcom,pm6150-vbus-reg,
- qcom,pm8150b-vbus-reg";
+ compatible = "qcom,pm6150-vbus-reg",
+ "qcom,pm8150b-vbus-reg";
reg = <0x1100>;
status = "disabled";
};
pm6150_typec: typec@1500 {
- compatible = "qcom,pm6150-typec,
- qcom,pm8150b-typec";
+ compatible = "qcom,pm6150-typec",
+ "qcom,pm8150b-typec";
reg = <0x1500>, <0x1700>;
interrupts = <0x0 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
<0x0 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
@@ -166,5 +166,11 @@
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
+
+ pm6150_vib: vibrator@5300 {
+ compatible = "qcom,pm6150-vib", "qcom,pmi632-vib";
+ reg = <0x5300>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
index d13a1ab7c20b..334f976f1154 100644
--- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
@@ -10,9 +10,6 @@
/ {
thermal-zones {
pm6150l-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm6150l_temp>;
trips {
@@ -118,6 +115,16 @@
status = "disabled";
};
+ pm6150l_lpg: pwm {
+ compatible = "qcom,pm6150l-lpg", "qcom,pm8150l-lpg";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #pwm-cells = <2>;
+
+ status = "disabled";
+ };
+
pm6150l_wled: leds@d800 {
compatible = "qcom,pm6150l-wled";
reg = <0xd800>, <0xd900>;
diff --git a/arch/arm64/boot/dts/qcom/pm6350.dtsi b/arch/arm64/boot/dts/qcom/pm6350.dtsi
index 3a2a841e83f1..a20ee2457101 100644
--- a/arch/arm64/boot/dts/qcom/pm6350.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6350.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm6350-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm6350_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
index 98dc04962fe3..156b2ddff0dc 100644
--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
@@ -13,7 +13,6 @@
thermal-zones {
pm660-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&pm660_temp>;
@@ -74,6 +73,23 @@
};
};
+ pm660_charger: charger@1000 {
+ compatible = "qcom,pm660-charger";
+ reg = <0x1000>;
+
+ interrupts = <0x0 0x13 0x4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x16 0x1 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x13 0x6 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "usb-plugin", "bat-ov", "wdog-bark", "usbin-icl-change";
+
+ io-channels = <&pm660_rradc 3>,
+ <&pm660_rradc 4>;
+ io-channel-names = "usbin_i", "usbin_v";
+
+ status = "disabled";
+ };
+
pm660_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
@@ -181,6 +197,14 @@
};
};
+ pm660_rradc: adc@4500 {
+ compatible = "qcom,pm660-rradc";
+ reg = <0x4500>;
+ #io-channel-cells = <1>;
+
+ status = "disabled";
+ };
+
pm660_gpios: gpio@c000 {
compatible = "qcom,pm660-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi
index 6fdbf507c262..0094e0ef058b 100644
--- a/arch/arm64/boot/dts/qcom/pm660l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi
@@ -13,7 +13,6 @@
thermal-zones {
pm660l-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&pm660l_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm7250b.dtsi b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
index 3bf7cf5d1700..0761e6b5fd8d 100644
--- a/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
@@ -11,7 +11,6 @@
thermal-zones {
pm7250b-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm7250b_temp>;
@@ -45,6 +44,52 @@
#address-cells = <1>;
#size-cells = <0>;
+ pm7250b_vbus: usb-vbus-regulator@1100 {
+ compatible = "qcom,pm7250b-vbus-reg", "qcom,pm8150b-vbus-reg";
+ reg = <0x1100>;
+ status = "disabled";
+ };
+
+ pm7250b_typec: typec@1500 {
+ compatible = "qcom,pm7250b-typec", "qcom,pm8150b-typec";
+ reg = <0x1500>,
+ <0x1700>;
+ interrupts = <PM7250B_SID 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
+ <PM7250B_SID 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
+ <PM7250B_SID 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
+ <PM7250B_SID 0x15 0x07 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x00 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x01 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x02 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x03 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x04 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x05 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x06 IRQ_TYPE_EDGE_RISING>,
+ <PM7250B_SID 0x17 0x07 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "or-rid-detect-change",
+ "vpd-detect",
+ "cc-state-change",
+ "vconn-oc",
+ "vbus-change",
+ "attach-detach",
+ "legacy-cable-detect",
+ "try-snk-src-detect",
+ "sig-tx",
+ "sig-rx",
+ "msg-tx",
+ "msg-rx",
+ "msg-tx-failed",
+ "msg-tx-discarded",
+ "msg-rx-discarded",
+ "fr-swap";
+ vdd-vbus-supply = <&pm7250b_vbus>;
+ status = "disabled";
+ };
+
pm7250b_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
diff --git a/arch/arm64/boot/dts/qcom/pm7325.dtsi b/arch/arm64/boot/dts/qcom/pm7325.dtsi
index d1c5476af5ee..6e29468505b2 100644
--- a/arch/arm64/boot/dts/qcom/pm7325.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7325.dtsi
@@ -35,7 +35,7 @@
&thermal_zones {
pm7325_thermal: pm7325-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm7325_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pm7550ba.dtsi b/arch/arm64/boot/dts/qcom/pm7550ba.dtsi
index 8b00ece987d1..853a1d83a7f0 100644
--- a/arch/arm64/boot/dts/qcom/pm7550ba.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7550ba.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm7550ba-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm7550ba_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8010.dtsi b/arch/arm64/boot/dts/qcom/pm8010.dtsi
index 0ea641e12209..ef330194946b 100644
--- a/arch/arm64/boot/dts/qcom/pm8010.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8010.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm8010-m-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8010_m_temp_alarm>;
@@ -31,7 +30,6 @@
pm8010-n-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8010_n_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi
index 3ba3ba5d8fce..a74a7ff660d2 100644
--- a/arch/arm64/boot/dts/qcom/pm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8150.dtsi
@@ -13,7 +13,6 @@
thermal-zones {
pm8150-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8150_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
index 1aee3270ce7b..3f7b0b6a1d10 100644
--- a/arch/arm64/boot/dts/qcom/pm8150b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
@@ -12,7 +12,6 @@
thermal-zones {
pm8150b-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8150b_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/pm8150l.dtsi
index ac08a09c64c2..3911d6d0d2e2 100644
--- a/arch/arm64/boot/dts/qcom/pm8150l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8150l.dtsi
@@ -12,7 +12,6 @@
thermal-zones {
pm8150l-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8150l_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm8350.dtsi b/arch/arm64/boot/dts/qcom/pm8350.dtsi
index 9ed9ba23e81e..cb55b23688d6 100644
--- a/arch/arm64/boot/dts/qcom/pm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8350.dtsi
@@ -10,7 +10,7 @@
thermal-zones {
pm8350_thermal: pm8350-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm8350_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pm8350b.dtsi b/arch/arm64/boot/dts/qcom/pm8350b.dtsi
index 05c105898892..cf82f8a64a9b 100644
--- a/arch/arm64/boot/dts/qcom/pm8350b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8350b.dtsi
@@ -10,7 +10,7 @@
thermal-zones {
pm8350b_thermal: pm8350b-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm8350b_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
index aa74e21fe0dc..1a24e6439e36 100644
--- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
@@ -48,7 +48,7 @@
thermal-zones {
pm8350c_thermal: pm8350c-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm8350c_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pm8450.dtsi b/arch/arm64/boot/dts/qcom/pm8450.dtsi
index ae5bce3cf46e..decb8809fd36 100644
--- a/arch/arm64/boot/dts/qcom/pm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8450.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm8450-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8450_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8550.dtsi b/arch/arm64/boot/dts/qcom/pm8550.dtsi
index 797a18c249a4..896bcacb6490 100644
--- a/arch/arm64/boot/dts/qcom/pm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8550.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm8550-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8550b.dtsi b/arch/arm64/boot/dts/qcom/pm8550b.dtsi
index 72609f31c890..74d23b8970f4 100644
--- a/arch/arm64/boot/dts/qcom/pm8550b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8550b.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm8550b-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550b_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8550ve.dtsi b/arch/arm64/boot/dts/qcom/pm8550ve.dtsi
index 4dc1f03ab2c7..9d4734eabf5a 100644
--- a/arch/arm64/boot/dts/qcom/pm8550ve.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8550ve.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm8550ve-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550ve_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8550vs.dtsi b/arch/arm64/boot/dts/qcom/pm8550vs.dtsi
index 97b1c18aa7d8..6426b431616b 100644
--- a/arch/arm64/boot/dts/qcom/pm8550vs.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8550vs.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pm8550vs-c-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550vs_c_temp_alarm>;
@@ -31,7 +30,6 @@
pm8550vs-d-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550vs_d_temp_alarm>;
@@ -52,7 +50,6 @@
pm8550vs-e-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550vs_e_temp_alarm>;
@@ -73,7 +70,6 @@
pm8550vs-g-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pm8550vs_g_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
index 4b2e8fb47d2d..f8e4829ff7f7 100644
--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
@@ -4,8 +4,37 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
-&spmi_bus {
+/ {
+ thermal-zones {
+ pm8916-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pm8916_temp>;
+
+ trips {
+ trip0 {
+ temperature = <105000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+
+ trip2 {
+ temperature = <145000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+ };
+};
+&spmi_bus {
pm8916_0: pmic@0 {
compatible = "qcom,pm8916", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
index 1067e141be6c..64258505f9ba 100644
--- a/arch/arm64/boot/dts/qcom/pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -9,9 +9,6 @@
/ {
thermal-zones {
pm8953-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm8953_temp>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi
index d44a95caf04a..353e4a6bd088 100644
--- a/arch/arm64/boot/dts/qcom/pm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi
@@ -8,7 +8,6 @@
thermal-zones {
pm8994-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&pm8994_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
index 3f82715392c6..3ecb330590e5 100644
--- a/arch/arm64/boot/dts/qcom/pm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi
@@ -11,7 +11,6 @@
thermal-zones {
pm8998-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&pm8998_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index 94d53b1cf6c8..8c899d148e46 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -11,7 +11,6 @@
thermal-zones {
pmi632-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmi632_temp>;
@@ -200,5 +199,11 @@
status = "disabled";
};
+
+ pmi632_vib: vibrator@5700 {
+ compatible = "qcom,pmi632-vib";
+ reg = <0x5700>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
index 1029f3b1bb9a..b4822cb17a37 100644
--- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
@@ -84,6 +84,14 @@
#address-cells = <1>;
#size-cells = <0>;
+ pmi8950_pwm: pwm@b000 {
+ compatible = "qcom,pmi8950-pwm";
+ reg = <0xb000 0x100>;
+ #pwm-cells = <2>;
+
+ status = "disabled";
+ };
+
pmi8950_wled: leds@d800 {
compatible = "qcom,pmi8950-wled";
reg = <0xd800>, <0xd900>;
diff --git a/arch/arm64/boot/dts/qcom/pmm8155au_1.dtsi b/arch/arm64/boot/dts/qcom/pmm8155au_1.dtsi
index dbd4b91dfe06..5084de66fc46 100644
--- a/arch/arm64/boot/dts/qcom/pmm8155au_1.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmm8155au_1.dtsi
@@ -12,7 +12,6 @@
thermal-zones {
pmm8155au-1-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmm8155au_1_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pmm8155au_2.dtsi b/arch/arm64/boot/dts/qcom/pmm8155au_2.dtsi
index 1cee20ac2c9c..555e4a456ef1 100644
--- a/arch/arm64/boot/dts/qcom/pmm8155au_2.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmm8155au_2.dtsi
@@ -11,7 +11,6 @@
thermal-zones {
pmm8155au-2-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmm8155au_2_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pmr735a.dtsi b/arch/arm64/boot/dts/qcom/pmr735a.dtsi
index febda50779f9..f8efd8e5e68f 100644
--- a/arch/arm64/boot/dts/qcom/pmr735a.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmr735a.dtsi
@@ -36,7 +36,7 @@
thermal-zones {
pmr735a_thermal: pmr735a-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pmr735a_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pmr735b.dtsi b/arch/arm64/boot/dts/qcom/pmr735b.dtsi
index f7473e247322..09affc05b397 100644
--- a/arch/arm64/boot/dts/qcom/pmr735b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmr735b.dtsi
@@ -10,7 +10,7 @@
thermal-zones {
pmr735b_thermal: pmr735b-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pmr735b_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/pmr735d_a.dtsi b/arch/arm64/boot/dts/qcom/pmr735d_a.dtsi
index 37daaefe3431..f9f1793d310e 100644
--- a/arch/arm64/boot/dts/qcom/pmr735d_a.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmr735d_a.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pmr735d-k-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmr735d_k_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi b/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi
index 3b470f6ac46f..d91fbd3bff10 100644
--- a/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pmr735d-l-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmr735d_l_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/pms405.dtsi b/arch/arm64/boot/dts/qcom/pms405.dtsi
index 461ad97032f7..3f9100c7eff4 100644
--- a/arch/arm64/boot/dts/qcom/pms405.dtsi
+++ b/arch/arm64/boot/dts/qcom/pms405.dtsi
@@ -12,7 +12,6 @@
thermal-zones {
pms405-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&pms405_temp>;
diff --git a/arch/arm64/boot/dts/qcom/pmx75.dtsi b/arch/arm64/boot/dts/qcom/pmx75.dtsi
index 373e45f63dff..2e61b7849c92 100644
--- a/arch/arm64/boot/dts/qcom/pmx75.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmx75.dtsi
@@ -10,7 +10,6 @@
thermal-zones {
pmx75-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmx75_temp_alarm>;
diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
index 89beac833d43..8f3be4c75db3 100644
--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
@@ -7,6 +7,7 @@
#include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
+#include <dt-bindings/clock/qcom,qcm2290-gpucc.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/firmware/qcom,scm.h>
@@ -165,7 +166,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_PPI 6 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -694,10 +695,31 @@
clock-output-names = "usb3_phy_pipe_clk_src";
#phy-cells = <0>;
+ orientation-switch;
qcom,tcsr-reg = <&tcsr_regs 0xb244>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_dwc3_ss>;
+ };
+ };
+ };
};
system_noc: interconnect@1880000 {
@@ -737,6 +759,11 @@
reg = <0x25b 0x1>;
bits = <1 4>;
};
+
+ gpu_speed_bin: gpu-speed-bin@2006 {
+ reg = <0x2006 0x2>;
+ bits = <5 8>;
+ };
};
pmu@1b8e300 {
@@ -1380,9 +1407,178 @@
snps,usb3_lpm_capable;
maximum-speed = "super-speed";
dr_mode = "otg";
+ usb-role-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_qmpphy_usb_ss_in>;
+ };
+ };
+ };
};
};
+ gpu: gpu@5900000 {
+ compatible = "qcom,adreno-07000200", "qcom,adreno";
+ reg = <0x0 0x05900000 0x0 0x40000>;
+ reg-names = "kgsl_3d0_reg_memory";
+
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gpucc GPU_CC_GX_GFX3D_CLK>,
+ <&gpucc GPU_CC_AHB_CLK>,
+ <&gcc GCC_BIMC_GPU_AXI_CLK>,
+ <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&gpucc GPU_CC_CX_GMU_CLK>,
+ <&gpucc GPU_CC_CXO_CLK>;
+ clock-names = "core",
+ "iface",
+ "mem_iface",
+ "alt_mem_iface",
+ "gmu",
+ "xo";
+
+ interconnects = <&bimc MASTER_GFX3D RPM_ALWAYS_TAG
+ &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>;
+ interconnect-names = "gfx-mem";
+
+ iommus = <&adreno_smmu 0 1>,
+ <&adreno_smmu 2 0>;
+ operating-points-v2 = <&gpu_opp_table>;
+ power-domains = <&rpmpd QCM2290_VDDCX>;
+ qcom,gmu = <&gmu_wrapper>;
+
+ nvmem-cells = <&gpu_speed_bin>;
+ nvmem-cell-names = "speed_bin";
+ #cooling-cells = <2>;
+
+ status = "disabled";
+
+ zap-shader {
+ memory-region = <&pil_gpu_mem>;
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* TODO: Scale RPM_SMD_BIMC_GPU_CLK w/ turbo freqs */
+ opp-1123200000 {
+ opp-hz = /bits/ 64 <1123200000>;
+ required-opps = <&rpmpd_opp_turbo_plus>;
+ opp-peak-kBps = <6881000>;
+ opp-supported-hw = <0x3>;
+ turbo-mode;
+ };
+
+ opp-1017600000 {
+ opp-hz = /bits/ 64 <1017600000>;
+ required-opps = <&rpmpd_opp_turbo>;
+ opp-peak-kBps = <6881000>;
+ opp-supported-hw = <0x3>;
+ turbo-mode;
+ };
+
+ opp-921600000 {
+ opp-hz = /bits/ 64 <921600000>;
+ required-opps = <&rpmpd_opp_nom_plus>;
+ opp-peak-kBps = <6881000>;
+ opp-supported-hw = <0x3>;
+ };
+
+ opp-844800000 {
+ opp-hz = /bits/ 64 <844800000>;
+ required-opps = <&rpmpd_opp_nom>;
+ opp-peak-kBps = <6881000>;
+ opp-supported-hw = <0x7>;
+ };
+
+ opp-672000000 {
+ opp-hz = /bits/ 64 <672000000>;
+ required-opps = <&rpmpd_opp_svs_plus>;
+ opp-peak-kBps = <3879000>;
+ opp-supported-hw = <0xf>;
+ };
+
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ required-opps = <&rpmpd_opp_svs>;
+ opp-peak-kBps = <2929000>;
+ opp-supported-hw = <0xf>;
+ };
+
+ opp-355200000 {
+ opp-hz = /bits/ 64 <355200000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ opp-peak-kBps = <1720000>;
+ opp-supported-hw = <0xf>;
+ };
+ };
+ };
+
+ gmu_wrapper: gmu@596a000 {
+ compatible = "qcom,adreno-gmu-wrapper";
+ reg = <0x0 0x0596a000 0x0 0x30000>;
+ reg-names = "gmu";
+ power-domains = <&gpucc GPU_CX_GDSC>,
+ <&gpucc GPU_GX_GDSC>;
+ power-domain-names = "cx",
+ "gx";
+ };
+
+ gpucc: clock-controller@5990000 {
+ compatible = "qcom,qcm2290-gpucc";
+ reg = <0x0 0x05990000 0x0 0x9000>;
+ clocks = <&gcc GCC_GPU_CFG_AHB_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+ <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+ power-domains = <&rpmpd QCM2290_VDDCX>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ adreno_smmu: iommu@59a0000 {
+ compatible = "qcom,qcm2290-smmu-500", "qcom,adreno-smmu",
+ "qcom,smmu-500", "arm,mmu-500";
+ reg = <0x0 0x059a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+ <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>;
+
+ clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+ <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>;
+ clock-names = "mem",
+ "hlos",
+ "iface";
+
+ power-domains = <&gpucc GPU_CX_GDSC>;
+
+ #global-interrupts = <1>;
+ #iommu-cells = <2>;
+ };
+
mdss: display-subsystem@5e00000 {
compatible = "qcom,qcm2290-mdss";
reg = <0x0 0x05e00000 0x0 0x1000>;
@@ -1858,7 +2054,7 @@
compatible = "qcom,qcm2290-cpufreq-hw", "qcom,cpufreq-hw";
reg = <0x0 0x0f521000 0x0 0x1000>;
reg-names = "freq-domain0";
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts-extended = <&lmh_cluster 0>;
interrupt-names = "dcvsh-irq-0";
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&gcc GPLL0>;
clock-names = "xo", "alternate";
@@ -1866,13 +2062,22 @@
#freq-domain-cells = <1>;
#clock-cells = <1>;
};
+
+ lmh_cluster: lmh@f550800 {
+ compatible = "qcom,qcm2290-lmh", "qcom,sm8150-lmh";
+ reg = <0x0 0x0f550800 0x0 0x400>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ cpus = <&CPU0>;
+ qcom,lmh-temp-arm-millicelsius = <65000>;
+ qcom,lmh-temp-low-millicelsius = <94500>;
+ qcom,lmh-temp-high-millicelsius = <95000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
};
thermal-zones {
mapss-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 0>;
trips {
@@ -1897,9 +2102,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 1>;
trips {
@@ -1924,9 +2126,6 @@
};
wlan-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 2>;
trips {
@@ -1951,9 +2150,6 @@
};
cpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 3>;
trips {
@@ -1978,9 +2174,6 @@
};
cpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 4>;
trips {
@@ -2005,9 +2198,6 @@
};
mdm0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 5>;
trips {
@@ -2032,9 +2222,6 @@
};
mdm1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 6>;
trips {
@@ -2059,9 +2246,6 @@
};
gpu-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 7>;
trips {
@@ -2086,9 +2270,6 @@
};
hm-center-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 8>;
trips {
@@ -2113,9 +2294,6 @@
};
camera-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 9>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
index 4ff9fc24e50e..8ab30c01712e 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
@@ -77,6 +77,8 @@
#address-cells = <1>;
#size-cells = <0>;
+ orientation-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
+
connector@0 {
compatible = "usb-c-connector";
reg = <0>;
@@ -165,7 +167,7 @@
thermal-zones {
camera-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 2>;
trips {
@@ -179,7 +181,7 @@
chg-skin-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pm7250b_adc_tm 0>;
trips {
@@ -193,7 +195,7 @@
conn-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pm7250b_adc_tm 1>;
trips {
@@ -205,9 +207,28 @@
};
};
+ pm8008-thermal {
+ polling-delay-passive = <100>;
+ thermal-sensors = <&pm8008>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
quiet-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 1>;
trips {
@@ -221,7 +242,7 @@
rear-cam-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 4>;
trips {
@@ -235,7 +256,7 @@
sdm-skin-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 3>;
trips {
@@ -249,7 +270,7 @@
xo-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 0>;
trips {
@@ -269,46 +290,54 @@
qcom,pmic-id = "b";
vreg_s1b: smps1 {
+ regulator-name = "vreg_s1b";
regulator-min-microvolt = <1840000>;
regulator-max-microvolt = <2040000>;
};
vreg_s7b: smps7 {
+ regulator-name = "vreg_s7b";
regulator-min-microvolt = <535000>;
regulator-max-microvolt = <1120000>;
};
vreg_s8b: smps8 {
+ regulator-name = "vreg_s8b";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
};
vreg_l1b: ldo1 {
+ regulator-name = "vreg_l1b";
regulator-min-microvolt = <825000>;
regulator-max-microvolt = <925000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2b: ldo2 {
+ regulator-name = "vreg_l2b";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3b: ldo3 {
+ regulator-name = "vreg_l3b";
regulator-min-microvolt = <312000>;
regulator-max-microvolt = <910000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6b: ldo6 {
+ regulator-name = "vreg_l6b";
regulator-min-microvolt = <1140000>;
regulator-max-microvolt = <1260000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7b: ldo7 {
+ regulator-name = "vreg_l7b";
/* Constrained for UFS VCC, at least until UFS driver scales voltage */
regulator-min-microvolt = <2952000>;
regulator-max-microvolt = <2952000>;
@@ -316,66 +345,77 @@
};
vreg_l8b: ldo8 {
+ regulator-name = "vreg_l8b";
regulator-min-microvolt = <870000>;
regulator-max-microvolt = <970000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9b: ldo9 {
+ regulator-name = "vreg_l9b";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11b: ldo11 {
+ regulator-name = "vreg_l11b";
regulator-min-microvolt = <1504000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12b: ldo12 {
+ regulator-name = "vreg_l12b";
regulator-min-microvolt = <751000>;
regulator-max-microvolt = <824000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13b: ldo13 {
+ regulator-name = "vreg_l13b";
regulator-min-microvolt = <530000>;
regulator-max-microvolt = <824000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l14b: ldo14 {
+ regulator-name = "vreg_l14b";
regulator-min-microvolt = <1080000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l15b: ldo15 {
+ regulator-name = "vreg_l15b";
regulator-min-microvolt = <765000>;
regulator-max-microvolt = <1020000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l16b: ldo16 {
+ regulator-name = "vreg_l16b";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l17b: ldo17 {
+ regulator-name = "vreg_l17b";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l18b: ldo18 {
+ regulator-name = "vreg_l18b";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l19b: ldo19 {
+ regulator-name = "vreg_l19b";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -387,60 +427,70 @@
qcom,pmic-id = "c";
vreg_s1c: smps1 {
+ regulator-name = "vreg_s1c";
regulator-min-microvolt = <2190000>;
regulator-max-microvolt = <2210000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_s9c: smps9 {
+ regulator-name = "vreg_s9c";
regulator-min-microvolt = <1010000>;
regulator-max-microvolt = <1170000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l1c: ldo1 {
+ regulator-name = "vreg_l1c";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2c: ldo2 {
+ regulator-name = "vreg_l2c";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1950000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3c: ldo3 {
+ regulator-name = "vreg_l3c";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3400000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4c: ldo4 {
+ regulator-name = "vreg_l4c";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l5c: ldo5 {
+ regulator-name = "vreg_l5c";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6c: ldo6 {
+ regulator-name = "vreg_l6c";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7c: ldo7 {
+ regulator-name = "vreg_l7c";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8c: ldo8 {
+ regulator-name = "vreg_l8c";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -449,36 +499,42 @@
};
vreg_l9c: ldo9 {
+ regulator-name = "vreg_l9c";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l10c: ldo10 {
+ regulator-name = "vreg_l10c";
regulator-min-microvolt = <720000>;
regulator-max-microvolt = <1050000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11c: ldo11 {
+ regulator-name = "vreg_l11c";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12c: ldo12 {
+ regulator-name = "vreg_l12c";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13c: ldo13 {
+ regulator-name = "vreg_l13c";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_bob: bob {
+ regulator-name = "vreg_bob";
regulator-min-microvolt = <3008000>;
regulator-max-microvolt = <3960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
@@ -520,7 +576,76 @@
&i2c1 {
status = "okay";
- /* PM8008 PMIC @ 8 and 9 */
+ pm8008: pmic@8 {
+ compatible = "qcom,pm8008";
+ reg = <0x8>;
+
+ interrupts-extended = <&tlmm 25 IRQ_TYPE_EDGE_RISING>;
+ reset-gpios = <&pm8350c_gpios 3 GPIO_ACTIVE_LOW>;
+
+ vdd-l1-l2-supply = <&vreg_s8b>;
+ vdd-l3-l4-supply = <&vreg_bob>;
+ vdd-l5-supply = <&vreg_bob>;
+ vdd-l6-supply = <&vreg_s1b>;
+ vdd-l7-supply = <&vreg_bob>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm8008_int_default>, <&pm8008_reset_n_default>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pm8008 0 0 2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ #thermal-sensor-cells = <0>;
+
+ regulators {
+ vreg_l1p: ldo1 {
+ regulator-name = "vreg_l1p";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l2p: ldo2 {
+ regulator-name = "vreg_l2p";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1152000>;
+ };
+
+ vreg_l3p: ldo3 {
+ regulator-name = "vreg_l3p";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vreg_l4p: ldo4 {
+ regulator-name = "vreg_l4p";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ vreg_l5p: ldo5 {
+ regulator-name = "vreg_l5p";
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ vreg_l6p: ldo6 {
+ regulator-name = "vreg_l6p";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1904000>;
+ };
+
+ vreg_l7p: ldo7 {
+ regulator-name = "vreg_l7p";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ };
+ };
+
/* Pixelworks @ 26 */
/* FSA4480 USB audio switch @ 42 */
/* AW86927FCR haptics @ 5a */
@@ -549,7 +674,7 @@
&ipa {
qcom,gsi-loader = "self";
memory-region = <&ipa_fw_mem>;
- firmware-name = "qcom/qcm6490/fairphone5/ipa_fws.mdt";
+ firmware-name = "qcom/qcm6490/fairphone5/ipa_fws.mbn";
status = "okay";
};
@@ -651,6 +776,14 @@
};
};
+&pm8350c_gpios {
+ pm8008_reset_n_default: pm8008-reset-n-default-state {
+ pins = "gpio3";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ bias-pull-down;
+ };
+};
+
&pmk8350_rtc {
status = "okay";
};
@@ -808,6 +941,13 @@
bias-pull-up;
};
+ pm8008_int_default: pm8008-int-default-state {
+ pins = "gpio25";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
qup_uart7_sleep_cts: qup-uart7-sleep-cts-state {
pins = "gpio28";
function = "gpio";
@@ -862,7 +1002,6 @@
};
&uart5 {
- compatible = "qcom,geni-debug-uart";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
index e4bfad50a669..a0668f767e4b 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -9,7 +9,9 @@
#define PM7250B_SID 8
#define PM7250B_SID1 9
+#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "sc7280.dtsi"
#include "pm7250b.dtsi"
@@ -35,10 +37,45 @@
serial0 = &uart5;
};
+ pm8350c_pwm_backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pm8350c_pwm 3 65535>;
+ enable-gpios = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&pmic_lcd_bl_en>;
+ pinctrl-names = "default";
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
+ lcd_disp_bias: regulator-lcd-disp-bias {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd_disp_bias";
+ regulator-min-microvolt = <5500000>;
+ regulator-max-microvolt = <5500000>;
+ gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-0 = <&lcd_disp_bias_en>;
+ pinctrl-names = "default";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&key_vol_up_default>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume_up";
+ gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
+ };
+
reserved-memory {
xbl_mem: xbl@80700000 {
reg = <0x0 0x80700000 0x0 0x100000>;
@@ -158,129 +195,151 @@
vdd-l14-l16-supply = <&vreg_s8b_1p272>;
vreg_s1b_1p872: smps1 {
+ regulator-name = "vreg_s1b_1p872";
regulator-min-microvolt = <1840000>;
regulator-max-microvolt = <2040000>;
};
vreg_s2b_0p876: smps2 {
+ regulator-name = "vreg_s2b_0p876";
regulator-min-microvolt = <570070>;
regulator-max-microvolt = <1050000>;
};
vreg_s7b_0p972: smps7 {
+ regulator-name = "vreg_s7b_0p972";
regulator-min-microvolt = <535000>;
regulator-max-microvolt = <1120000>;
};
vreg_s8b_1p272: smps8 {
+ regulator-name = "vreg_s8b_1p272";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
};
vreg_l1b_0p912: ldo1 {
+ regulator-name = "vreg_l1b_0p912";
regulator-min-microvolt = <825000>;
regulator-max-microvolt = <925000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2b_3p072: ldo2 {
+ regulator-name = "vreg_l2b_3p072";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3b_0p504: ldo3 {
+ regulator-name = "vreg_l3b_0p504";
regulator-min-microvolt = <312000>;
regulator-max-microvolt = <910000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4b_0p752: ldo4 {
+ regulator-name = "vreg_l4b_0p752";
regulator-min-microvolt = <752000>;
regulator-max-microvolt = <820000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
reg_l5b_0p752: ldo5 {
+ regulator-name = "reg_l5b_0p752";
regulator-min-microvolt = <552000>;
regulator-max-microvolt = <832000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6b_1p2: ldo6 {
+ regulator-name = "vreg_l6b_1p2";
regulator-min-microvolt = <1140000>;
regulator-max-microvolt = <1260000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7b_2p952: ldo7 {
+ regulator-name = "vreg_l7b_2p952";
regulator-min-microvolt = <2400000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8b_0p904: ldo8 {
+ regulator-name = "vreg_l8b_0p904";
regulator-min-microvolt = <870000>;
regulator-max-microvolt = <970000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9b_1p2: ldo9 {
+ regulator-name = "vreg_l9b_1p2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11b_1p504: ldo11 {
+ regulator-name = "vreg_l11b_1p504";
regulator-min-microvolt = <1504000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12b_0p751: ldo12 {
+ regulator-name = "vreg_l12b_0p751";
regulator-min-microvolt = <751000>;
regulator-max-microvolt = <824000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13b_0p53: ldo13 {
+ regulator-name = "vreg_l13b_0p53";
regulator-min-microvolt = <530000>;
regulator-max-microvolt = <824000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l14b_1p08: ldo14 {
+ regulator-name = "vreg_l14b_1p08";
regulator-min-microvolt = <1080000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l15b_0p765: ldo15 {
+ regulator-name = "vreg_l15b_0p765";
regulator-min-microvolt = <765000>;
regulator-max-microvolt = <1020000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l16b_1p1: ldo16 {
+ regulator-name = "vreg_l16b_1p1";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l17b_1p7: ldo17 {
+ regulator-name = "vreg_l17b_1p7";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l18b_1p8: ldo18 {
+ regulator-name = "vreg_l18b_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l19b_1p8: ldo19 {
+ regulator-name = "vreg_l19b_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -312,116 +371,217 @@
vdd-bob-supply = <&vph_pwr>;
vreg_s1c_2p19: smps1 {
+ regulator-name = "vreg_s1c_2p19";
regulator-min-microvolt = <2190000>;
regulator-max-microvolt = <2210000>;
};
vreg_s2c_0p752: smps2 {
+ regulator-name = "vreg_s2c_0p752";
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <800000>;
};
vreg_s5c_0p752: smps5 {
+ regulator-name = "vreg_s5c_0p752";
regulator-min-microvolt = <465000>;
regulator-max-microvolt = <1050000>;
};
vreg_s7c_0p752: smps7 {
+ regulator-name = "vreg_s7c_0p752";
regulator-min-microvolt = <465000>;
regulator-max-microvolt = <800000>;
};
vreg_s9c_1p084: smps9 {
+ regulator-name = "vreg_s9c_1p084";
regulator-min-microvolt = <1010000>;
regulator-max-microvolt = <1170000>;
};
vreg_l1c_1p8: ldo1 {
+ regulator-name = "vreg_l1c_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2c_1p62: ldo2 {
+ regulator-name = "vreg_l2c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3c_2p8: ldo3 {
+ regulator-name = "vreg_l3c_2p8";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3540000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4c_1p62: ldo4 {
+ regulator-name = "vreg_l4c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l5c_1p62: ldo5 {
+ regulator-name = "vreg_l5c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6c_2p96: ldo6 {
+ regulator-name = "vreg_l6c_2p96";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7c_3p0: ldo7 {
+ regulator-name = "vreg_l7c_3p0";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8c_1p62: ldo8 {
+ regulator-name = "vreg_l8c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9c_2p96: ldo9 {
+ regulator-name = "vreg_l9c_2p96";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <35440000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l10c_0p88: ldo10 {
+ regulator-name = "vreg_l10c_0p88";
regulator-min-microvolt = <720000>;
regulator-max-microvolt = <1050000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11c_2p8: ldo11 {
+ regulator-name = "vreg_l11c_2p8";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12c_1p65: ldo12 {
+ regulator-name = "vreg_l12c_1p65";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13c_2p7: ldo13 {
+ regulator-name = "vreg_l13c_2p7";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_bob_3p296: bob {
+ regulator-name = "vreg_bob_3p296";
regulator-min-microvolt = <3008000>;
regulator-max-microvolt = <3960000>;
};
};
};
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi {
+ vdda-supply = <&vreg_l6b_1p2>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "novatek,nt36672e";
+ reg = <0>;
+
+ reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
+
+ vddi-supply = <&vreg_l8c_1p62>;
+ avdd-supply = <&lcd_disp_bias>;
+ avee-supply = <&lcd_disp_bias>;
+
+ backlight = <&pm8350c_pwm_backlight>;
+
+ port {
+ panel0_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&panel0_in>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+ vdds-supply = <&vreg_l10c_0p88>;
+ status = "okay";
+};
+
+&pm7250b_gpios {
+ lcd_disp_bias_en: lcd-disp-bias-en-state {
+ pins = "gpio2";
+ function = "func1";
+ bias-disable;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ input-disable;
+ output-enable;
+ power-source = <0>;
+ };
+};
+
+&pm8350c_gpios {
+ pmic_lcd_bl_en: pmic-lcd-bl-en-state {
+ pins = "gpio7";
+ function = "normal";
+ bias-disable;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ output-low;
+ power-source = <0>;
+ };
+
+ pmic_lcd_bl_pwm: pmic-lcd-bl-pwm-state {
+ pins = "gpio8";
+ function = "func1";
+ bias-disable;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ output-low;
+ power-source = <0>;
+ };
+};
+
+&pm7325_gpios {
+ key_vol_up_default: key-vol-up-state {
+ pins = "gpio6";
+ function = "normal";
+ input-enable;
+ bias-pull-up;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ };
+};
+
&pm8350c_pwm {
+ pinctrl-0 = <&pmic_lcd_bl_pwm>;
+ pinctrl-names = "default";
status = "okay";
multi-led {
@@ -448,10 +608,39 @@
};
};
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
&qupv3_id_0 {
status = "okay";
};
+&remoteproc_adsp {
+ firmware-name = "qcom/qcm6490/adsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/qcm6490/cdsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/qcm6490/modem.mbn";
+ status = "okay";
+};
+
+&remoteproc_wpss {
+ firmware-name = "qcom/qcm6490/wpss.mbn";
+ status = "okay";
+};
+
&sdhc_1 {
non-removable;
no-sd;
@@ -469,7 +658,6 @@
};
&uart5 {
- compatible = "qcom,geni-debug-uart";
status = "okay";
};
@@ -478,6 +666,7 @@
};
&usb_1_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts
new file mode 100644
index 000000000000..4667e47a74bc
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts
@@ -0,0 +1,961 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Luca Weiss <luca.weiss@fairphone.com>
+ * Copyright (c) 2024, Caleb Connolly <caleb@postmarketos.org>
+ */
+
+/dts-v1/;
+
+#define PM7250B_SID 8
+#define PM7250B_SID1 9
+
+#include <dt-bindings/iio/qcom,spmi-adc7-pm7325.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sc7280.dtsi"
+#include "pm7250b.dtsi"
+#include "pm7325.dtsi"
+#include "pm8350c.dtsi" /* PM7350C */
+#include "pmk8350.dtsi" /* PMK7325 */
+
+/delete-node/ &rmtfs_mem;
+
+/ {
+ model = "SHIFT SHIFTphone 8";
+ compatible = "shift,otter", "qcom,qcm6490";
+ chassis-type = "handset";
+
+ aliases {
+ serial0 = &uart5;
+ serial1 = &uart7;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ stdout-path = "serial0:115200n8";
+
+ framebuffer0: framebuffer@a000000 {
+ compatible = "simple-framebuffer";
+ reg = <0x0 0xe1000000 0x0 (2400 * 1080 * 4)>;
+ width = <1080>;
+ height = <2400>;
+ stride = <(1080 * 4)>;
+ format = "a8r8g8b8";
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&volume_down_default>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume up";
+ gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ pmic-glink {
+ compatible = "qcom,qcm6490-pmic-glink", "qcom,pmic-glink";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss_in: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&fsa4480_sbu_mux>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ cont_splash_mem: cont-splash@e1000000 {
+ reg = <0x0 0xe1000000 0x0 0x2300000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp@88f00000 {
+ reg = <0x0 0x88f00000 0x0 0x1e00000>;
+ no-map;
+ };
+
+ rmtfs_mem: rmtfs@f8500000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0xf8500000 0x0 0x600000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>, <QCOM_SCM_VMID_NAV>;
+ };
+ };
+
+ thermal-zones {
+ camera-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pmk8350_adc_tm 2>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ chg-skin-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm7250b_adc_tm 0>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ conn-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm7250b_adc_tm 1>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ quiet-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pmk8350_adc_tm 1>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ rear-cam-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pmk8350_adc_tm 4>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ sdm-skin-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pmk8350_adc_tm 3>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ xo-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pmk8350_adc_tm 0>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm7325-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vreg_s1b: smps1 {
+ regulator-name = "vreg_s1b";
+ regulator-min-microvolt = <1840000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vreg_s7b: smps7 {
+ regulator-name = "vreg_s7b";
+ regulator-min-microvolt = <535000>;
+ regulator-max-microvolt = <1120000>;
+ };
+
+ vreg_s8b: smps8 {
+ regulator-name = "vreg_s8b";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
+ };
+
+ vreg_l1b: ldo1 {
+ regulator-name = "vreg_l1b";
+ regulator-min-microvolt = <825000>;
+ regulator-max-microvolt = <925000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b: ldo2 {
+ regulator-name = "vreg_l2b";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3b: ldo3 {
+ regulator-name = "vreg_l3b";
+ regulator-min-microvolt = <312000>;
+ regulator-max-microvolt = <910000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b: ldo6 {
+ regulator-name = "vreg_l6b";
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1260000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b: ldo7 {
+ regulator-name = "vreg_l7b";
+ /* Constrained for UFS VCC, at least until UFS driver scales voltage */
+ regulator-min-microvolt = <2952000>;
+ regulator-max-microvolt = <2952000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b: ldo8 {
+ regulator-name = "vreg_l8b";
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <970000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b: ldo9 {
+ regulator-name = "vreg_l9b";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11b: ldo11 {
+ regulator-name = "vreg_l11b";
+ regulator-min-microvolt = <1504000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b: ldo12 {
+ regulator-name = "vreg_l12b";
+ regulator-min-microvolt = <751000>;
+ regulator-max-microvolt = <824000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b: ldo13 {
+ regulator-name = "vreg_l13b";
+ regulator-min-microvolt = <530000>;
+ regulator-max-microvolt = <824000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b: ldo14 {
+ regulator-name = "vreg_l14b";
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b: ldo15 {
+ regulator-name = "vreg_l15b";
+ regulator-min-microvolt = <765000>;
+ regulator-max-microvolt = <1020000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16b: ldo16 {
+ regulator-name = "vreg_l16b";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b: ldo17 {
+ regulator-name = "vreg_l17b";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l18b: ldo18 {
+ regulator-name = "vreg_l18b";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l19b: ldo19 {
+ regulator-name = "vreg_l19b";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8350c-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_s1c: smps1 {
+ regulator-name = "vreg_s1c";
+ regulator-min-microvolt = <2190000>;
+ regulator-max-microvolt = <2210000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s9c: smps9 {
+ regulator-name = "vreg_s9c";
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1170000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1c: ldo1 {
+ regulator-name = "vreg_l1c";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c: ldo2 {
+ regulator-name = "vreg_l2c";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c: ldo3 {
+ regulator-name = "vreg_l3c";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c: ldo4 {
+ regulator-name = "vreg_l4c";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5c: ldo5 {
+ regulator-name = "vreg_l5c";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6c: ldo6 {
+ regulator-name = "vreg_l6c";
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c: ldo7 {
+ regulator-name = "vreg_l7c";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c: ldo8 {
+ regulator-name = "vreg_l8c";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c: ldo9 {
+ regulator-name = "vreg_l9c";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c: ldo10 {
+ regulator-name = "vreg_l10c";
+ regulator-min-microvolt = <720000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11c: ldo11 {
+ regulator-name = "vreg_l11c";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12c: ldo12 {
+ regulator-name = "vreg_l12c";
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13c: ldo13 {
+ regulator-name = "vreg_l13c";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob: bob {
+ regulator-name = "vreg_bob";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+ };
+};
+
+&gcc {
+ protected-clocks = <GCC_CFG_NOC_LPASS_CLK>,
+ <GCC_EDP_CLKREF_EN>,
+ <GCC_MSS_CFG_AHB_CLK>,
+ <GCC_MSS_GPLL0_MAIN_DIV_CLK_SRC>,
+ <GCC_MSS_OFFLINE_AXI_CLK>,
+ <GCC_MSS_Q6SS_BOOT_CLK_SRC>,
+ <GCC_MSS_Q6_MEMNOC_AXI_CLK>,
+ <GCC_MSS_SNOC_AXI_CLK>,
+ <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+ <GCC_QSPI_CORE_CLK>,
+ <GCC_QSPI_CORE_CLK_SRC>,
+ <GCC_SEC_CTRL_CLK_SRC>,
+ <GCC_WPSS_AHB_BDG_MST_CLK>,
+ <GCC_WPSS_AHB_CLK>,
+ <GCC_WPSS_RSCP_CLK>;
+};
+
+&gpi_dma0 {
+ status = "okay";
+};
+
+&gpi_dma1 {
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+};
+
+&gpu_zap_shader {
+ firmware-name = "qcom/qcm6490/SHIFT/otter/a660_zap.mbn";
+};
+
+&i2c1 {
+ status = "okay";
+
+ /* PM8008 PMIC @ 8 and 9 */
+ /* rtc6226 FM receiver @ 64 */
+
+ typec-mux@42 {
+ compatible = "fcs,fsa4480";
+ reg = <0x42>;
+
+ vcc-supply = <&vreg_bob>;
+
+ mode-switch;
+ orientation-switch;
+
+ port {
+ fsa4480_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_sbu>;
+ };
+ };
+ };
+};
+
+&i2c4 {
+ status = "okay";
+
+ /* tas2563 audio codec @ 4d */
+};
+
+&i2c9 {
+ status = "okay";
+
+ /* TMS(?) NFC @ 28 */
+ /* Ti drv2624 haptics @ 5a */
+};
+
+&i2c13 {
+ status = "okay";
+
+ /* focaltech FT3658U @ 38 */
+};
+
+&ipa {
+ qcom,gsi-loader = "self";
+ memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/qcm6490/SHIFT/otter/ipa_fws.mbn";
+ status = "okay";
+};
+
+&pm7250b_adc {
+ channel@4d {
+ reg = <ADC5_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "charger_skin_therm";
+ };
+
+ channel@4f {
+ reg = <ADC5_AMUX_THM3_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "conn_therm";
+ };
+};
+
+&pm7250b_adc_tm {
+ status = "okay";
+
+ charger-skin-therm@0 {
+ reg = <0>;
+ io-channels = <&pm7250b_adc ADC5_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+
+ conn-therm@1 {
+ reg = <1>;
+ io-channels = <&pm7250b_adc ADC5_AMUX_THM3_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+};
+
+&pm7325_gpios {
+ volume_down_default: volume-down-default-state {
+ pins = "gpio6";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pmk8350_adc_tm {
+ status = "okay";
+
+ xo-therm@0 {
+ reg = <0>;
+ io-channels = <&pmk8350_vadc PMK8350_ADC7_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+
+ quiet-therm@1 {
+ reg = <1>;
+ io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+
+ cam-flash-therm@2 {
+ reg = <2>;
+ io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM2_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+
+ sdm-skin-therm@3 {
+ reg = <3>;
+ io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM3_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+
+ wide-rfc-therm@4 {
+ reg = <4>;
+ io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM4_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+};
+
+&pmk8350_rtc {
+ status = "okay";
+};
+
+&pmk8350_vadc {
+ status = "okay";
+
+ channel@44 {
+ reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "pmk8350_xo_therm";
+ };
+
+ channel@144 {
+ reg = <PM7325_ADC7_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "pm7325_quiet_therm";
+ };
+
+ channel@145 {
+ reg = <PM7325_ADC7_AMUX_THM2_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "pm7325_cam_flash_therm";
+ };
+
+ channel@146 {
+ reg = <PM7325_ADC7_AMUX_THM3_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "pm7325_sdm_skin_therm";
+ };
+
+ channel@147 {
+ reg = <PM7325_ADC7_AMUX_THM4_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ label = "pm7325_wide_rfc_therm";
+ };
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&qup_spi13_cs {
+ drive-strength = <6>;
+ bias-disable;
+};
+
+&qup_spi13_data_clk {
+ drive-strength = <6>;
+ bias-disable;
+};
+
+&qup_uart5_rx {
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qup_uart5_tx {
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/qcm6490/SHIFT/otter/adsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/qcm6490/SHIFT/otter/cdsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/qcm6490/SHIFT/otter/modem.mbn";
+ status = "okay";
+};
+
+&remoteproc_wpss {
+ firmware-name = "qcom/qcm6490/SHIFT/otter/wpss.mbn";
+ status = "okay";
+};
+
+&sdc2_clk {
+ drive-strength = <16>;
+ bias-disable;
+};
+
+&sdc2_cmd {
+ drive-strength = <10>;
+ bias-pull-up;
+};
+
+&sdc2_data {
+ drive-strength = <10>;
+ bias-pull-up;
+};
+
+&sdhc_2 {
+ vmmc-supply = <&vreg_l9c>;
+ vqmmc-supply = <&vreg_l6c>;
+
+ pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>;
+ pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>;
+
+ status = "okay";
+};
+
+&tlmm {
+ /*
+ * 48-52: protected by XPU, not sure why.
+ */
+ gpio-reserved-ranges = <48 4>;
+
+ bluetooth_enable_default: bluetooth-enable-default-state {
+ pins = "gpio85";
+ function = "gpio";
+ output-low;
+ bias-disable;
+ };
+
+ qup_uart7_sleep_cts: qup-uart7-sleep-cts-state {
+ pins = "gpio28";
+ function = "gpio";
+ /*
+ * Configure a bias-bus-hold on CTS to lower power
+ * usage when Bluetooth is turned off. Bus hold will
+ * maintain a low power state regardless of whether
+ * the Bluetooth module drives the pin in either
+ * direction or leaves the pin fully unpowered.
+ */
+ bias-bus-hold;
+ };
+
+ qup_uart7_sleep_rts: qup-uart7-sleep-rts-state {
+ pins = "gpio29";
+ function = "gpio";
+ /*
+ * 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).
+ */
+ bias-pull-down;
+ };
+
+ qup_uart7_sleep_tx: qup-uart7-sleep-tx-state {
+ pins = "gpio30";
+ function = "gpio";
+ /*
+ * Configure pull-up on TX when it isn't actively driven
+ * to prevent BT SoC from receiving garbage during sleep.
+ */
+ bias-pull-up;
+ };
+
+ qup_uart7_sleep_rx: qup-uart7-sleep-rx-state {
+ pins = "gpio31";
+ function = "gpio";
+ /*
+ * 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.
+ */
+ bias-pull-up;
+ };
+
+ sw_ctrl_default: sw-ctrl-default-state {
+ pins = "gpio86";
+ function = "gpio";
+ bias-pull-down;
+ };
+};
+
+&uart5 {
+ compatible = "qcom,geni-debug-uart";
+ status = "okay";
+};
+
+&uart7 {
+ /delete-property/interrupts;
+ interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>,
+ <&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>, <&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+
+ bluetooth: bluetooth {
+ compatible = "qcom,wcn6750-bt";
+
+ pinctrl-0 = <&bluetooth_enable_default>, <&sw_ctrl_default>;
+ pinctrl-names = "default";
+
+ enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+
+ vddio-supply = <&vreg_l19b>;
+ vddaon-supply = <&vreg_s7b>;
+ vddbtcxmx-supply = <&vreg_s7b>;
+ vddrfacmn-supply = <&vreg_s7b>;
+ vddrfa0p8-supply = <&vreg_s7b>;
+ vddrfa1p7-supply = <&vreg_s1b>;
+ vddrfa1p2-supply = <&vreg_s8b>;
+ vddrfa2p2-supply = <&vreg_s1c>;
+ vddasd-supply = <&vreg_l11c>;
+
+ max-speed = <3200000>;
+ };
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l7b>;
+ vcc-max-microamp = <800000>;
+ /*
+ * Technically l9b enables an eLDO (supplied by s1b) which then powers
+ * VCCQ2 of the UFS.
+ */
+ vccq-supply = <&vreg_l9b>;
+ vccq-max-microamp = <900000>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l10c>;
+ vdda-pll-supply = <&vreg_l6b>;
+
+ status = "okay";
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "otg";
+ usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss_in>;
+};
+
+&usb_1_hsphy {
+ vdda-pll-supply = <&vreg_l10c>;
+ vdda18-supply = <&vreg_l1c>;
+ vdda33-supply = <&vreg_l2b>;
+
+ qcom,hs-crossover-voltage-microvolt = <28000>;
+ qcom,hs-output-impedance-micro-ohms = <2600000>;
+ qcom,hs-rise-fall-time-bp = <5430>;
+ qcom,hs-disconnect-bp = <1743>;
+ qcom,hs-amplitude-bp = <2430>;
+
+ qcom,pre-emphasis-amplitude-bp = <20000>;
+ qcom,pre-emphasis-duration-bp = <20000>;
+
+ qcom,squelch-detector-bp = <(-2090)>;
+
+ orientation-switch;
+
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vreg_l6b>;
+ vdda-pll-supply = <&vreg_l1b>;
+
+ status = "okay";
+};
+
+&wifi {
+ qcom,ath11k-calibration-variant = "SHIFTphone_8";
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
index 10655401528e..a22b4501ce1e 100644
--- a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
@@ -62,7 +62,7 @@
vddrf-supply = <&vreg_l1_1p3>;
vddch0-supply = <&vdd_ch0_3p3>;
- local-bd-address = [ 02 00 00 00 5a ad ];
+ local-bd-address = [ 00 00 00 00 00 00 ];
max-speed = <3200000>;
};
diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index a05d0234f7fc..c291bbed6073 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -1324,7 +1324,7 @@
};
apcs_hfpll: clock-controller@b016000 {
- compatible = "qcom,hfpll";
+ compatible = "qcom,qcs404-hfpll";
reg = <0x0b016000 0x30>;
#clock-cells = <0>;
clock-output-names = "apcs_hfpll";
@@ -1516,15 +1516,25 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
};
timer {
compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 2 0xff08>,
- <GIC_PPI 3 0xff08>,
- <GIC_PPI 4 0xff08>,
- <GIC_PPI 1 0xff08>;
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
};
smp2p-adsp {
@@ -1590,7 +1600,6 @@
thermal-zones {
aoss-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 0>;
@@ -1605,7 +1614,6 @@
q6-hvx-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 1>;
@@ -1620,7 +1628,6 @@
lpass-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 2>;
@@ -1635,7 +1642,6 @@
wlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 3>;
@@ -1650,7 +1656,6 @@
cluster-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 4>;
@@ -1684,7 +1689,6 @@
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 5>;
@@ -1718,7 +1722,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 6>;
@@ -1752,7 +1755,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 7>;
@@ -1786,7 +1788,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 8>;
@@ -1820,7 +1821,6 @@
gpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 9>;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index 97824c769ba3..0d45662b8028 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -17,7 +17,6 @@
#include "pmk8350.dtsi"
/delete-node/ &ipa_fw_mem;
-/delete-node/ &remoteproc_mpss;
/delete-node/ &rmtfs_mem;
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
@@ -39,6 +38,39 @@
stdout-path = "serial0:115200n8";
};
+ dp-connector {
+ compatible = "dp-connector";
+ label = "DP";
+ type = "mini";
+
+ hpd-gpios = <&tlmm 60 GPIO_ACTIVE_HIGH>;
+
+ port {
+ dp_connector_in: endpoint {
+ remote-endpoint = <&mdss_edp_out>;
+ };
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con: endpoint {
+ remote-endpoint = <&lt9611_out>;
+ };
+ };
+ };
+
+ lt9611_1v2: lt9611-vdd12-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "LT9611_1V2";
+
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
reserved-memory {
xbl_mem: xbl@80700000 {
reg = <0x0 0x80700000 0x0 0x100000>;
@@ -121,6 +153,49 @@
};
};
+ pmic-glink {
+ compatible = "qcom,qcm6490-pmic-glink", "qcom,pmic-glink";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss_in: endpoint {
+ remote-endpoint = <&redriver_usb_con_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu_in: endpoint {
+ remote-endpoint = <&redriver_usb_con_sbu>;
+ };
+ };
+ };
+ };
+ };
+
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
@@ -153,129 +228,154 @@
vdd-l14-l16-supply = <&vreg_s8b_1p272>;
vreg_s1b_1p872: smps1 {
+ regulator-name = "vreg_s1b_1p872";
regulator-min-microvolt = <1840000>;
regulator-max-microvolt = <2040000>;
};
vreg_s2b_0p876: smps2 {
+ regulator-name = "vreg_s2b_0p876";
regulator-min-microvolt = <570070>;
regulator-max-microvolt = <1050000>;
};
vreg_s7b_0p972: smps7 {
+ regulator-name = "vreg_s7b_0p972";
regulator-min-microvolt = <535000>;
regulator-max-microvolt = <1120000>;
};
vreg_s8b_1p272: smps8 {
+ regulator-name = "vreg_s8b_1p272";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
};
vreg_l1b_0p912: ldo1 {
+ regulator-name = "vreg_l1b_0p912";
regulator-min-microvolt = <825000>;
regulator-max-microvolt = <925000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2b_3p072: ldo2 {
+ regulator-name = "vreg_l2b_3p072";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3b_0p504: ldo3 {
+ regulator-name = "vreg_l3b_0p504";
regulator-min-microvolt = <312000>;
regulator-max-microvolt = <910000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4b_0p752: ldo4 {
+ regulator-name = "vreg_l4b_0p752";
regulator-min-microvolt = <752000>;
regulator-max-microvolt = <820000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
reg_l5b_0p752: ldo5 {
+ regulator-name = "reg_l5b_0p752";
regulator-min-microvolt = <552000>;
regulator-max-microvolt = <832000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6b_1p2: ldo6 {
+ regulator-name = "vreg_l6b_1p2";
regulator-min-microvolt = <1140000>;
regulator-max-microvolt = <1260000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7b_2p952: ldo7 {
- regulator-min-microvolt = <2400000>;
- regulator-max-microvolt = <3544000>;
+ regulator-name = "vreg_l7b_2p952";
+ regulator-min-microvolt = <2952000>;
+ regulator-max-microvolt = <2952000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8b_0p904: ldo8 {
+ regulator-name = "vreg_l8b_0p904";
regulator-min-microvolt = <870000>;
regulator-max-microvolt = <970000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9b_1p2: ldo9 {
+ regulator-name = "vreg_l9b_1p2";
regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1304000>;
+ regulator-max-microvolt = <1200000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11b_1p504: ldo11 {
+ regulator-name = "vreg_l11b_1p504";
regulator-min-microvolt = <1504000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12b_0p751: ldo12 {
+ regulator-name = "vreg_l12b_0p751";
regulator-min-microvolt = <751000>;
regulator-max-microvolt = <824000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13b_0p53: ldo13 {
+ regulator-name = "vreg_l13b_0p53";
regulator-min-microvolt = <530000>;
regulator-max-microvolt = <824000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l14b_1p08: ldo14 {
+ regulator-name = "vreg_l14b_1p08";
regulator-min-microvolt = <1080000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l15b_0p765: ldo15 {
+ regulator-name = "vreg_l15b_0p765";
regulator-min-microvolt = <765000>;
regulator-max-microvolt = <1020000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l16b_1p1: ldo16 {
+ regulator-name = "vreg_l16b_1p1";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l17b_1p7: ldo17 {
+ regulator-name = "vreg_l17b_1p7";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l18b_1p8: ldo18 {
+ regulator-name = "vreg_l18b_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l19b_1p8: ldo19 {
+ regulator-name = "vreg_l19b_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -304,109 +404,128 @@
vdd-bob-supply = <&vph_pwr>;
vreg_s1c_2p19: smps1 {
+ regulator-name = "vreg_s1c_2p19";
regulator-min-microvolt = <2190000>;
regulator-max-microvolt = <2210000>;
};
vreg_s2c_0p752: smps2 {
+ regulator-name = "vreg_s2c_0p752";
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <800000>;
};
vreg_s5c_0p752: smps5 {
+ regulator-name = "vreg_s5c_0p752";
regulator-min-microvolt = <465000>;
regulator-max-microvolt = <1050000>;
};
vreg_s7c_0p752: smps7 {
+ regulator-name = "vreg_s7c_0p752";
regulator-min-microvolt = <465000>;
regulator-max-microvolt = <800000>;
};
vreg_s9c_1p084: smps9 {
+ regulator-name = "vreg_s9c_1p084";
regulator-min-microvolt = <1010000>;
regulator-max-microvolt = <1170000>;
};
vreg_l1c_1p8: ldo1 {
+ regulator-name = "vreg_l1c_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2c_1p62: ldo2 {
+ regulator-name = "vreg_l2c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3c_2p8: ldo3 {
+ regulator-name = "vreg_l3c_2p8";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3540000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4c_1p62: ldo4 {
+ regulator-name = "vreg_l4c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l5c_1p62: ldo5 {
+ regulator-name = "vreg_l5c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6c_2p96: ldo6 {
+ regulator-name = "vreg_l6c_2p96";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7c_3p0: ldo7 {
+ regulator-name = "vreg_l7c_3p0";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8c_1p62: ldo8 {
+ regulator-name = "vreg_l8c_1p62";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9c_2p96: ldo9 {
+ regulator-name = "vreg_l9c_2p96";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <35440000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l10c_0p88: ldo10 {
+ regulator-name = "vreg_l10c_0p88";
regulator-min-microvolt = <720000>;
regulator-max-microvolt = <1050000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11c_2p8: ldo11 {
+ regulator-name = "vreg_l11c_2p8";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12c_1p65: ldo12 {
+ regulator-name = "vreg_l12c_1p65";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13c_2p7: ldo13 {
+ regulator-name = "vreg_l13c_2p7";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_bob_3p296: bob {
+ regulator-name = "vreg_bob_3p296";
regulator-min-microvolt = <3008000>;
regulator-max-microvolt = <3960000>;
};
@@ -430,17 +549,179 @@
<GCC_WPSS_RSCP_CLK>;
};
+&gpi_dma0 {
+ status = "okay";
+};
+
+&gpi_dma1 {
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ lt9611_codec: hdmi-bridge@2b {
+ compatible = "lontium,lt9611uxc";
+ reg = <0x2b>;
+
+ interrupts-extended = <&tlmm 24 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+
+ vdd-supply = <&lt9611_1v2>;
+ vcc-supply = <&vreg_l11c_2p8>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lt9611_irq_pin &lt9611_rst_pin>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lt9611_a: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ lt9611_out: endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ typec-mux@1c {
+ compatible = "onnn,nb7vpq904m";
+ reg = <0x1c>;
+
+ vcc-supply = <&vreg_l18b_1p8>;
+
+ retimer-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ redriver_usb_con_ss: endpoint {
+ remote-endpoint = <&pmic_glink_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ redriver_phy_con_ss: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ redriver_usb_con_sbu: endpoint {
+ remote-endpoint = <&pmic_glink_sbu_in>;
+ };
+ };
+ };
+ };
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dp {
+ status = "okay";
+};
+
+&mdss_dp_out {
+ data-lanes = <0 1>;
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+};
+
+&mdss_dsi {
+ vdda-supply = <&vreg_l6b_1p2>;
+ status = "okay";
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&lt9611_a>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+ vdds-supply = <&vreg_l10c_0p88>;
+ status = "okay";
+};
+
+&mdss_edp {
+ status = "okay";
+};
+
+&mdss_edp_out {
+ data-lanes = <0 1 2 3>;
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
+ remote-endpoint = <&dp_connector_in>;
+};
+
+&mdss_edp_phy {
+ status = "okay";
+};
+
+&pmk8350_rtc {
+ status = "okay";
+};
+
&qupv3_id_0 {
status = "okay";
};
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/qcs6490/adsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/qcs6490/cdsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/qcs6490/modem.mdt";
+ status = "okay";
+};
+
+&remoteproc_wpss {
+ firmware-name = "qcom/qcs6490/wpss.mbn";
+ status = "okay";
+};
+
&tlmm {
gpio-reserved-ranges = <32 2>, /* ADSP */
<48 4>; /* NFC */
};
&uart5 {
- compatible = "qcom,geni-debug-uart";
status = "okay";
};
@@ -449,7 +730,16 @@
};
&usb_1_dwc3 {
- dr_mode = "peripheral";
+ dr_mode = "otg";
+ usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_dwc3_ss {
+ remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
&usb_1_hsphy {
@@ -464,9 +754,69 @@
vdda-phy-supply = <&vreg_l6b_1p2>;
vdda-pll-supply = <&vreg_l1b_0p912>;
+ orientation-switch;
+
+ status = "okay";
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&redriver_phy_con_ss>;
+};
+
+&usb_dp_qmpphy_usb_ss_in {
+ remote-endpoint = <&usb_1_dwc3_ss>;
+};
+
+&usb_dp_qmpphy_dp_in {
+ remote-endpoint = <&mdss_dp_out>;
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+ vcc-supply = <&vreg_l7b_2p952>;
+ vcc-max-microamp = <800000>;
+ vccq-supply = <&vreg_l9b_1p2>;
+ vccq-max-microamp = <900000>;
+ vccq2-supply = <&vreg_l9b_1p2>;
+ vccq2-max-microamp = <900000>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l10c_0p88>;
+ vdda-pll-supply = <&vreg_l6b_1p2>;
+
status = "okay";
};
&wifi {
memory-region = <&wlan_fw_mem>;
};
+
+/* PINCTRL - ADDITIONS TO NODES IN PARENT DEVICE TREE FILES */
+
+&edp_hot_plug_det {
+ function = "gpio";
+ bias-disable;
+};
+
+&pm7250b_gpios {
+ lt9611_rst_pin: lt9611-rst-state {
+ pins = "gpio2";
+ function = "normal";
+
+ output-high;
+ input-disable;
+ power-source = <0>;
+ };
+};
+
+&tlmm {
+ lt9611_irq_pin: lt9611-irq-state {
+ pins = "gpio24";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-aim300-aiot.dts b/arch/arm64/boot/dts/qcom/qcs8550-aim300-aiot.dts
new file mode 100644
index 000000000000..2e2e46f214c7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8550-aim300-aiot.dts
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "qcs8550-aim300.dtsi"
+#include "pm8010.dtsi"
+#include "pmr735d_a.dtsi"
+#include "pmr735d_b.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS8550 AIM300 AIOT";
+ compatible = "qcom,qcs8550-aim300-aiot", "qcom,qcs8550-aim300", "qcom,qcs8550",
+ "qcom,sm8550";
+
+ aliases {
+ serial0 = &uart7;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&volume_up_n>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume Up";
+ debounce-interval = <15>;
+ gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ pmic-glink {
+ compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss_in: endpoint {
+ remote-endpoint = <&redriver_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&fsa4480_sbu_mux>;
+ };
+ };
+ };
+ };
+ };
+
+ vph_pwr: regulator-vph-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
+ };
+
+ regulators-3 {
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ };
+
+ regulators-4 {
+ vdd-s4-supply = <&vph_pwr>;
+ };
+
+ regulators-5 {
+ 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>;
+ };
+};
+
+&i2c_hub_2 {
+ status = "okay";
+
+ typec-mux@42 {
+ compatible = "fcs,fsa4480";
+ reg = <0x42>;
+
+ vcc-supply = <&vreg_bob1>;
+
+ mode-switch;
+ orientation-switch;
+
+ port {
+ fsa4480_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_sbu>;
+ };
+ };
+ };
+
+ typec-retimer@1c {
+ compatible = "onnn,nb7vpq904m";
+ reg = <0x1c>;
+
+ vcc-supply = <&vreg_l15b_1p8>;
+
+ orientation-switch;
+ retimer-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ redriver_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ redriver_ss_in: endpoint {
+ data-lanes = <3 2 1 0>;
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ };
+ };
+ };
+ };
+};
+
+&mdss_dsi0 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "visionox,vtdr6130";
+ reg = <0>;
+
+ pinctrl-0 = <&dsi_active>, <&te_default>;
+ pinctrl-1 = <&dsi_suspend>, <&te_default>;
+ pinctrl-names = "default", "sleep";
+
+ reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+
+ vci-supply = <&vreg_l13b_3p0>;
+ vdd-supply = <&vreg_l11b_1p2>;
+ vddio-supply = <&vreg_l12b_1p8>;
+
+ port {
+ panel0_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&panel0_in>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+};
+
+&pcie0_phy {
+ status = "okay";
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&pcie1_phy {
+ status = "okay";
+};
+
+&pm8550_gpios {
+ volume_up_n: volume-up-n-state {
+ pins = "gpio6";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+
+ status = "okay";
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/qcs8550/adsp.mbn",
+ "qcom/qcs8550/adsp_dtb.mbn";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/qcs8550/cdsp.mbn",
+ "qcom/qcs8550/cdsp_dtb.mbn";
+ status = "okay";
+};
+
+&swr1 {
+ status = "okay";
+};
+
+&swr2 {
+ status = "okay";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <32 8>;
+
+ dsi_active: dsi-active-state {
+ pins = "gpio133";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ dsi_suspend: dsi-suspend-state {
+ pins = "gpio133";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ te_default: te-default-state {
+ pins = "gpio86";
+ function = "mdp_vsync";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+};
+
+&uart7 {
+ status = "okay";
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_hsphy {
+ status = "okay";
+};
+
+&usb_dp_qmpphy {
+ status = "okay";
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&redriver_ss_in>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi b/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi
new file mode 100644
index 000000000000..f6960e2d466a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "qcs8550.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 5
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-l1-l4-l10-supply = <&vreg_s6g_1p86>;
+ vdd-l2-l13-l14-supply = <&vreg_bob1>;
+ vdd-l3-supply = <&vreg_s4g_1p25>;
+ vdd-l5-l16-supply = <&vreg_bob1>;
+ vdd-l6-l7-supply = <&vreg_bob1>;
+ vdd-l8-l9-supply = <&vreg_bob1>;
+ vdd-l11-supply = <&vreg_s4g_1p25>;
+ vdd-l12-supply = <&vreg_s6g_1p86>;
+ vdd-l15-supply = <&vreg_s6g_1p86>;
+ vdd-l17-supply = <&vreg_bob2>;
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3296000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2720000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1b_1p8: ldo1 {
+ regulator-name = "vreg_l1b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5b_3p1: ldo5 {
+ regulator-name = "vreg_l5b_3p1";
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p8: ldo6 {
+ regulator-name = "vreg_l6b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_1p8: ldo7 {
+ regulator-name = "vreg_l7b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b_1p8: ldo8 {
+ regulator-name = "vreg_l8b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_2p9: ldo9 {
+ regulator-name = "vreg_l9b_2p9";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11b_1p2: ldo11 {
+ regulator-name = "vreg_l11b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b_1p8: ldo12 {
+ regulator-name = "vreg_l12b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b_3p0: ldo13 {
+ regulator-name = "vreg_l13b_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p2: ldo14 {
+ regulator-name = "vreg_l14b_3p2";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b_1p8: ldo15 {
+ regulator-name = "vreg_l15b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16b_2p8: ldo16 {
+ regulator-name = "vreg_l16b_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b_2p5: ldo17 {
+ regulator-name = "vreg_l17b_2p5";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-l1-supply = <&vreg_s4g_1p25>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4e_0p95>;
+
+ vreg_l3c_0p9: ldo3 {
+ regulator-name = "vreg_l3c_0p9";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ vdd-l1-supply = <&vreg_s4e_0p95>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4e_0p95>;
+
+ vreg_l1d_0p88: ldo1 {
+ regulator-name = "vreg_l1d_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vdd-l1-supply = <&vreg_s4e_0p95>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4g_1p25>;
+
+ vreg_s4e_0p95: smps4 {
+ regulator-name = "vreg_s4e_0p95";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <984000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5e_1p08: smps5 {
+ regulator-name = "vreg_s5e_1p08";
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1e_0p88: ldo1 {
+ regulator-name = "vreg_l1e_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2e_0p9: ldo2 {
+ regulator-name = "vreg_l2e_0p9";
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <970000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vdd-l1-supply = <&vreg_s4e_0p95>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4e_0p95>;
+
+ vreg_s4f_0p5: smps4 {
+ regulator-name = "vreg_s4f_0p5";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <700000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1f_0p9: ldo1 {
+ regulator-name = "vreg_l1f_0p9";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2f_0p88: ldo2 {
+ regulator-name = "vreg_l2f_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3f_0p88: ldo3 {
+ regulator-name = "vreg_l3f_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-5 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "g";
+ vdd-l1-supply = <&vreg_s4g_1p25>;
+ vdd-l2-supply = <&vreg_s4g_1p25>;
+ vdd-l3-supply = <&vreg_s4g_1p25>;
+
+ vreg_s1g_1p25: smps1 {
+ regulator-name = "vreg_s1g_1p25";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s2g_0p85: smps2 {
+ regulator-name = "vreg_s2g_0p85";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1036000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s3g_0p8: smps3 {
+ regulator-name = "vreg_s3g_0p8";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s4g_1p25: smps4 {
+ regulator-name = "vreg_s4g_1p25";
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1408000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5g_0p85: smps5 {
+ regulator-name = "vreg_s5g_0p85";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s6g_1p86: smps6 {
+ regulator-name = "vreg_s6g_1p86";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1g_1p2: ldo1 {
+ regulator-name = "vreg_l1g_1p2";
+ regulator-min-microvolt = <1128000>;
+ regulator-max-microvolt = <1272000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2g_1p2: ldo2 {
+ regulator-name = "vreg_l2g_1p2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3g_1p2: ldo3 {
+ regulator-name = "vreg_l3g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&vreg_l3e_1p2>;
+};
+
+&mdss_dsi0_phy {
+ vdds-supply = <&vreg_l1e_0p88>;
+};
+
+&pcie0 {
+ perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l1e_0p88>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+};
+
+&pcie1 {
+ perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&pcie1_default_state>;
+ pinctrl-names = "default";
+};
+
+&pcie1_phy {
+ vdda-phy-supply = <&vreg_l3c_0p9>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+ vdda-qref-supply = <&vreg_l1e_0p88>;
+};
+
+&pm8550b_eusb2_repeater {
+ vdd18-supply = <&vreg_l15b_1p8>;
+ vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&sleep_clk {
+ clock-frequency = <32000>;
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+ vcc-supply = <&vreg_l17b_2p5>;
+ vcc-max-microamp = <1300000>;
+ vccq-supply = <&vreg_l1g_1p2>;
+ vccq-max-microamp = <1200000>;
+ vdd-hba-supply = <&vreg_l3g_1p2>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l1d_0p88>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_hsphy {
+ phys = <&pm8550b_eusb2_repeater>;
+
+ vdd-supply = <&vreg_l1e_0p88>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+};
+
+&usb_dp_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l3f_0p88>;
+};
+
+&xo_board {
+ clock-frequency = <76800000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550.dtsi b/arch/arm64/boot/dts/qcom/qcs8550.dtsi
new file mode 100644
index 000000000000..07b314834d88
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8550.dtsi
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "sm8550.dtsi"
+
+/delete-node/ &reserved_memory;
+
+/ {
+ reserved_memory: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+
+ /* These are 3 types of reserved memory regions here:
+ * 1. Firmware related regions which aren't shared with kernel.
+ * The device tree source in kernel doesn't need to have node to
+ * indicate the firmware related reserved information. Bootloader
+ * conveys the information by updating devicetree at runtime.
+ * This will be described as: UEFI saves the physical address of
+ * the UEFI System Table to dts file's chosen node. Kernel read this
+ * table and add reserved memory regions to efi config table. Current
+ * reserved memory region may have reserved region which was not yet
+ * used, release note of the firmware have such kind of information.
+ * 2. Firmware related memory regions which are shared with Kernel
+ * The device tree source in the kernel needs to include nodes
+ * that indicate fimware-related shared information. A label name
+ * is suggested because this type of shared information needs to
+ * be referenced by specific drivers for handling purposes.
+ * Unlike previous platforms, QCS8550 boots using EFI and describes
+ * most reserved regions in the ESRT memory map. As a result, reserved
+ * memory regions which aren't relevant to the kernel(like the hypervisor
+ ( region) don't need to be described in DT.
+ * 3. Remoteproc regions.
+ * Remoteproc regions will be reserved and then assigned to
+ * subsystem firmware later.
+ * Here is a reserved memory map for this platform:
+ * 0x80000000 +-------------------+
+ * | |
+ * | Firmware Related |
+ * | |
+ * 0x8a800000 +-------------------+
+ * | |
+ * | Remoteproc Region |
+ * | |
+ * 0xa7000000 +-------------------+
+ * | |
+ * | Kernel Available |
+ * | |
+ * 0xd4d00000 +-------------------+
+ * | |
+ * | Firmware Related |
+ * | |
+ * 0x100000000 +-------------------+
+ */
+
+ aop_image_mem: aop-image-region@81c00000 {
+ reg = <0x0 0x81c00000 0x0 0x60000>;
+ no-map;
+ };
+
+ aop_cmd_db_mem: aop-cmd-db-region@81c60000 {
+ compatible = "qcom,cmd-db";
+ reg = <0x0 0x81c60000 0x0 0x20000>;
+ no-map;
+ };
+
+ aop_config_mem: aop-config-region@81c80000 {
+ no-map;
+ reg = <0x0 0x81c80000 0x0 0x20000>;
+ };
+
+ smem_mem: smem-region@81d00000 {
+ compatible = "qcom,smem";
+ reg = <0x0 0x81d00000 0x0 0x200000>;
+ hwlocks = <&tcsr_mutex 3>;
+ no-map;
+ };
+
+ adsp_mhi_mem: adsp-mhi-region@81f00000 {
+ reg = <0x0 0x81f00000 0x0 0x20000>;
+ no-map;
+ };
+
+ mpss_mem: mpss-region@8a800000 {
+ reg = <0x0 0x8a800000 0x0 0x10800000>;
+ no-map;
+ };
+
+ q6_mpss_dtb_mem: q6-mpss-dtb-region@9b000000 {
+ reg = <0x0 0x9b000000 0x0 0x80000>;
+ no-map;
+ };
+
+ ipa_fw_mem: ipa-fw-region@9b080000 {
+ reg = <0x0 0x9b080000 0x0 0x10000>;
+ no-map;
+ };
+
+ ipa_gsi_mem: ipa-gsi-region@9b090000 {
+ reg = <0x0 0x9b090000 0x0 0xa000>;
+ no-map;
+ };
+
+ gpu_micro_code_mem: gpu-micro-code-region@9b09a000 {
+ reg = <0x0 0x9b09a000 0x0 0x2000>;
+ no-map;
+ };
+
+ spss_region_mem: spss-region@9b100000 {
+ reg = <0x0 0x9b100000 0x0 0x180000>;
+ no-map;
+ };
+
+ spu_secure_shared_memory_mem: spu-secure-shared-memory-region@9b280000 {
+ reg = <0x0 0x9b280000 0x0 0x80000>;
+ no-map;
+ };
+
+ camera_mem: camera-region@9b300000 {
+ reg = <0x0 0x9b300000 0x0 0x800000>;
+ no-map;
+ };
+
+ video_mem: video-region@9bb00000 {
+ reg = <0x0 0x9bb00000 0x0 0x700000>;
+ no-map;
+ };
+
+ cvp_mem: cvp-region@9c200000 {
+ reg = <0x0 0x9c200000 0x0 0x700000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp-region@9c900000 {
+ reg = <0x0 0x9c900000 0x0 0x2000000>;
+ no-map;
+ };
+
+ q6_cdsp_dtb_mem: q6-cdsp-dtb-region@9e900000 {
+ reg = <0x0 0x9e900000 0x0 0x80000>;
+ no-map;
+ };
+
+ q6_adsp_dtb_mem: q6-adsp-dtb-region@9e980000 {
+ reg = <0x0 0x9e980000 0x0 0x80000>;
+ no-map;
+ };
+
+ adspslpi_mem: adspslpi-region@9ea00000 {
+ reg = <0x0 0x9ea00000 0x0 0x4080000>;
+ no-map;
+ };
+
+ mpss_dsm_mem: mpss_dsm_region@d4d00000 {
+ reg = <0x0 0xd4d00000 0x0 0x3300000>;
+ no-map;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/qdu1000-idp.dts b/arch/arm64/boot/dts/qcom/qdu1000-idp.dts
index 5a25cdec969e..e65305f8136c 100644
--- a/arch/arm64/boot/dts/qcom/qdu1000-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qdu1000-idp.dts
@@ -500,3 +500,26 @@
&uart7 {
status = "okay";
};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+ vdda-pll-supply = <&vreg_l8a_0p91>;
+ vdda18-supply = <&vreg_l14a_1p8>;
+ vdda33-supply = <&vreg_l2a_2p3>;
+
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vreg_l8a_0p91>;
+ vdda-pll-supply = <&vreg_l3a_1p2>;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
index 832f472c4b7a..642ca8f0236b 100644
--- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi
+++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
@@ -6,6 +6,8 @@
#include <dt-bindings/clock/qcom,qdu1000-gcc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,qdu1000-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
@@ -177,7 +179,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -913,6 +915,126 @@
};
};
+ usb_1_hsphy: phy@88e3000 {
+ compatible = "qcom,qdu1000-usb-hs-phy",
+ "qcom,usb-snps-hs-7nm-phy";
+ reg = <0x0 0x088e3000 0x0 0x120>;
+ #phy-cells = <0>;
+
+ clocks =<&gcc GCC_USB2_CLKREF_EN>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+
+ status = "disabled";
+ };
+
+ usb_1_qmpphy: phy@88e5000 {
+ compatible = "qcom,qdu1000-qmp-usb3-uni-phy";
+ reg = <0x0 0x088e5000 0x0 0x2000>;
+
+ clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+ <&gcc GCC_USB2_CLKREF_EN>,
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "pipe";
+
+ resets = <&gcc GCC_USB3_PHY_PRIM_BCR>,
+ <&gcc GCC_USB3PHY_PHY_PRIM_BCR>;
+ reset-names = "phy",
+ "phy_phy";
+
+ #clock-cells = <0>;
+ clock-output-names = "usb3_uni_phy_pipe_clk_src";
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
+ usb_1: usb@a6f8800 {
+ compatible = "qcom,qdu1000-dwc3", "qcom,dwc3";
+ reg = <0 0x0a6f8800 0 0x400>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+ <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+ <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>;
+ clock-names = "cfg_noc",
+ "core",
+ "sleep",
+ "mock_utmi";
+
+ assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 6 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "hs_phy_irq",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq",
+ "ss_phy_irq";
+
+ power-domains = <&gcc USB30_PRIM_GDSC>;
+ required-opps = <&rpmhpd_opp_nom>;
+
+ resets = <&gcc GCC_USB30_PRIM_BCR>;
+
+ interconnects = <&system_noc MASTER_USB3 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_USB3_0 QCOM_ICC_TAG_ALWAYS>;
+
+ interconnect-names = "usb-ddr",
+ "apps-usb";
+
+ status = "disabled";
+
+ usb_1_dwc3: usb@a600000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a600000 0 0xcd00>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&apps_smmu 0xc0 0x0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ phys = <&usb_1_hsphy>,
+ <&usb_1_qmpphy>;
+ phy-names = "usb2-phy",
+ "usb3-phy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_dwc3_ss: endpoint {
+ };
+ };
+ };
+ };
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,qdu1000-pdc", "qcom,pdc";
reg = <0x0 0xb220000 0x0 0x30000>, <0x0 0x174000f0 0x0 0x64>;
@@ -1459,11 +1581,40 @@
system-cache-controller@19200000 {
compatible = "qcom,qdu1000-llcc";
- reg = <0 0x19200000 0 0xd80000>,
+ reg = <0 0x19200000 0 0x80000>,
+ <0 0x19300000 0 0x80000>,
+ <0 0x19600000 0 0x80000>,
+ <0 0x19700000 0 0x80000>,
+ <0 0x19a00000 0 0x80000>,
+ <0 0x19b00000 0 0x80000>,
+ <0 0x19e00000 0 0x80000>,
+ <0 0x19f00000 0 0x80000>,
<0 0x1a200000 0 0x80000>;
reg-names = "llcc0_base",
+ "llcc1_base",
+ "llcc2_base",
+ "llcc3_base",
+ "llcc4_base",
+ "llcc5_base",
+ "llcc6_base",
+ "llcc7_base",
"llcc_broadcast_base";
interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+
+ nvmem-cells = <&multi_chan_ddr>;
+ nvmem-cell-names = "multi-chan-ddr";
+ };
+
+ sec_qfprom: efuse@221c8000 {
+ compatible = "qcom,qdu1000-sec-qfprom", "qcom,sec-qfprom";
+ reg = <0 0x221c8000 0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ multi_chan_ddr: multi-chan-ddr@12b {
+ reg = <0x12b 0x1>;
+ bits = <0 2>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
index 6e9dd0312adc..e19790464a11 100644
--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -59,6 +59,17 @@
};
};
+ i2c2_gpio: i2c {
+ compatible = "i2c-gpio";
+
+ sda-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
leds {
compatible = "gpio-leds";
@@ -199,7 +210,15 @@
status = "okay";
};
-&i2c2 {
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ firmware-name = "qcom/qcm2290/a702_zap.mbn";
+ };
+};
+
+&i2c2_gpio {
clock-frequency = <400000>;
status = "okay";
@@ -262,6 +281,46 @@
status = "okay";
};
+&pm4125_typec {
+ status = "okay";
+
+ connector {
+ compatible = "usb-c-connector";
+
+ power-role = "dual";
+ data-role = "dual";
+ self-powered;
+
+ typec-power-opmode = "default";
+ pd-disable;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ pm4125_hs_in: endpoint {
+ remote-endpoint = <&usb_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ pm4125_ss_in: endpoint {
+ remote-endpoint = <&usb_qmpphy_out>;
+ };
+ };
+ };
+ };
+};
+
+&pm4125_vbus {
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <500000>;
+ status = "okay";
+};
+
&qupv3_id_0 {
status = "okay";
};
@@ -535,14 +594,8 @@
status = "okay";
};
-&usb_qmpphy {
- vdda-phy-supply = <&pm4125_l12>;
- vdda-pll-supply = <&pm4125_l13>;
- status = "okay";
-};
-
-&usb_dwc3 {
- dr_mode = "host";
+&usb_dwc3_hs {
+ remote-endpoint = <&pm4125_hs_in>;
};
&usb_hsphy {
@@ -552,12 +605,23 @@
status = "okay";
};
+&usb_qmpphy {
+ vdda-phy-supply = <&pm4125_l12>;
+ vdda-pll-supply = <&pm4125_l13>;
+ status = "okay";
+};
+
+&usb_qmpphy_out {
+ remote-endpoint = <&pm4125_ss_in>;
+};
+
&wifi {
vdd-0.8-cx-mx-supply = <&pm4125_l7>;
vdd-1.8-xo-supply = <&pm4125_l13>;
vdd-1.3-rfa-supply = <&pm4125_l10>;
vdd-3.3-ch0-supply = <&pm4125_l22>;
qcom,ath10k-calibration-variant = "Thundercomm_RB1";
+ firmware-name = "qcm2290";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
index 696d6d43c56b..1888d99d398b 100644
--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
+++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
@@ -60,6 +60,17 @@
};
};
+ i2c2_gpio: i2c {
+ compatible = "i2c-gpio";
+
+ sda-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
leds {
compatible = "gpio-leds";
@@ -190,7 +201,7 @@
};
};
-&i2c2 {
+&i2c2_gpio {
clock-frequency = <400000>;
status = "okay";
@@ -294,7 +305,7 @@
&pmi632_vbus {
regulator-min-microamp = <500000>;
- regulator-max-microamp = <3000000>;
+ regulator-max-microamp = <1000000>;
status = "okay";
};
@@ -403,6 +414,8 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-allow-set-load;
+ regulator-always-on;
+ regulator-boot-on;
};
vreg_l10a_1p8: l10 {
@@ -678,6 +691,7 @@
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
vdd-3.3-ch0-supply = <&vreg_l23a_3p3>;
qcom,ath10k-calibration-variant = "Thundercomm_RB2";
+ firmware-name = "qrb4210";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index cd0db4f31d4a..ccff6cd73fdf 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -108,10 +108,69 @@
regulator-always-on;
};
+ qca6390-pmu {
+ compatible = "qcom,qca6390-pmu";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_en_state>, <&wlan_en_state>;
+
+ vddaon-supply = <&vreg_s6a_0p95>;
+ vddpmu-supply = <&vreg_s2f_0p95>;
+ vddrfa0p95-supply = <&vreg_s2f_0p95>;
+ vddrfa1p3-supply = <&vreg_s8c_1p3>;
+ vddrfa1p9-supply = <&vreg_s5a_1p9>;
+ vddpcie1p3-supply = <&vreg_s8c_1p3>;
+ vddpcie1p9-supply = <&vreg_s5a_1p9>;
+ vddio-supply = <&vreg_s4a_1p8>;
+
+ wlan-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+ bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+ regulators {
+ vreg_pmu_rfa_cmn: ldo0 {
+ regulator-name = "vreg_pmu_rfa_cmn";
+ };
+
+ vreg_pmu_aon_0p59: ldo1 {
+ regulator-name = "vreg_pmu_aon_0p59";
+ };
+
+ vreg_pmu_wlcx_0p8: ldo2 {
+ regulator-name = "vreg_pmu_wlcx_0p8";
+ };
+
+ vreg_pmu_wlmx_0p85: ldo3 {
+ regulator-name = "vreg_pmu_wlmx_0p85";
+ };
+
+ vreg_pmu_btcmx_0p85: ldo4 {
+ regulator-name = "vreg_pmu_btcmx_0p85";
+ };
+
+ vreg_pmu_rfa_0p8: ldo5 {
+ regulator-name = "vreg_pmu_rfa_0p8";
+ };
+
+ vreg_pmu_rfa_1p2: ldo6 {
+ regulator-name = "vreg_pmu_rfa_1p2";
+ };
+
+ vreg_pmu_rfa_1p7: ldo7 {
+ regulator-name = "vreg_pmu_rfa_1p7";
+ };
+
+ vreg_pmu_pcie_0p9: ldo8 {
+ regulator-name = "vreg_pmu_pcie_0p9";
+ };
+
+ vreg_pmu_pcie_1p8: ldo9 {
+ regulator-name = "vreg_pmu_pcie_1p8";
+ };
+ };
+ };
+
thermal-zones {
conn-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150b_adc_tm 0>;
trips {
@@ -124,8 +183,6 @@
};
pm8150l-pcb-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150l_adc_tm 1>;
trips {
@@ -138,8 +195,6 @@
};
skin-msm-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150l_adc_tm 0>;
trips {
@@ -152,8 +207,6 @@
};
wifi-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150_adc_tm 1>;
trips {
@@ -166,8 +219,6 @@
};
xo-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150_adc_tm 0>;
trips {
@@ -734,6 +785,23 @@
vdda-pll-supply = <&vreg_l9a_1p2>;
};
+&pcieport0 {
+ wifi@0 {
+ compatible = "pci17cb,1101";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ };
+};
+
&pcie1 {
status = "okay";
};
@@ -1303,6 +1371,14 @@
function = "gpio";
bias-pull-up;
};
+
+ wlan_en_state: wlan-default-state {
+ pins = "gpio20";
+ function = "gpio";
+ drive-strength = <16>;
+ output-low;
+ bias-pull-up;
+ };
};
&uart6 {
@@ -1311,17 +1387,12 @@
bluetooth {
compatible = "qcom,qca6390-bt";
- pinctrl-names = "default";
- pinctrl-0 = <&bt_en_state>;
-
- enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
-
- vddio-supply = <&vreg_s4a_1p8>;
- vddpmu-supply = <&vreg_s2f_0p95>;
- vddaon-supply = <&vreg_s6a_0p95>;
- vddrfa0p9-supply = <&vreg_s2f_0p95>;
- vddrfa1p3-supply = <&vreg_s8c_1p3>;
- vddrfa1p9-supply = <&vreg_s5a_1p9>;
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
};
};
@@ -1356,8 +1427,8 @@
usb-role-switch;
};
-&usb_1_role_switch_out {
- remote-endpoint = <&pm8150b_role_switch_in>;
+&usb_1_dwc3_hs_out {
+ remote-endpoint = <&pm8150b_hs_in>;
};
&usb_1_hsphy {
@@ -1373,7 +1444,6 @@
vdda-phy-supply = <&vreg_l9a_1p2>;
vdda-pll-supply = <&vreg_l18a_0p92>;
- orientation-switch;
};
&usb_1_qmpphy_out {
@@ -1465,8 +1535,8 @@
port@0 {
reg = <0>;
- pm8150b_role_switch_in: endpoint {
- remote-endpoint = <&usb_1_role_switch_out>;
+ pm8150b_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs_out>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/qru1000-idp.dts b/arch/arm64/boot/dts/qcom/qru1000-idp.dts
index 2a862c83309e..1c781d9e24cf 100644
--- a/arch/arm64/boot/dts/qcom/qru1000-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qru1000-idp.dts
@@ -467,3 +467,26 @@
&uart7 {
status = "okay";
};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+ vdda-pll-supply = <&vreg_l8a_0p91>;
+ vdda18-supply = <&vreg_l14a_1p8>;
+ vdda33-supply = <&vreg_l2a_2p3>;
+
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vreg_l8a_0p91>;
+ vdda-pll-supply = <&vreg_l3a_1p2>;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
index 5e4287f8c8cd..9e9c7f81096b 100644
--- a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
+++ b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
@@ -283,7 +283,7 @@
vreg_l13c_2p96: ldo13 {
regulator-name = "vreg_l13c_2p96";
- regulator-min-microvolt = <2504000>;
+ regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
@@ -367,6 +367,16 @@
};
};
+&pmm8155au_1_gpios {
+ pmm8155au_1_sdc2_cd: sdc2-cd-default-state {
+ pins = "gpio4";
+ function = "normal";
+ input-enable;
+ bias-pull-up;
+ power-source = <0>;
+ };
+};
+
&qupv3_id_1 {
status = "okay";
};
@@ -384,10 +394,10 @@
&sdhc_2 {
status = "okay";
- cd-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+ cd-gpios = <&pmm8155au_1_gpios 4 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc2_on>;
- pinctrl-1 = <&sdc2_off>;
+ pinctrl-0 = <&sdc2_on &pmm8155au_1_sdc2_cd>;
+ pinctrl-1 = <&sdc2_off &pmm8155au_1_sdc2_cd>;
vqmmc-supply = <&vreg_l13c_2p96>; /* IO line power */
vmmc-supply = <&vreg_l17a_2p96>; /* Card power line */
bus-width = <4>;
@@ -505,13 +515,6 @@
bias-pull-up; /* pull up */
drive-strength = <16>; /* 16 MA */
};
-
- sd-cd-pins {
- pins = "gpio96";
- function = "gpio";
- bias-pull-up; /* pull up */
- drive-strength = <2>; /* 2 MA */
- };
};
sdc2_off: sdc2-off-state {
@@ -532,13 +535,6 @@
bias-pull-up; /* pull up */
drive-strength = <2>; /* 2 MA */
};
-
- sd-cd-pins {
- pins = "gpio96";
- function = "gpio";
- bias-pull-up; /* pull up */
- drive-strength = <2>; /* 2 MA */
- };
};
usb2phy_ac_en1_default: usb2phy-ac-en1-default-state {
diff --git a/arch/arm64/boot/dts/qcom/sa8155p.dtsi b/arch/arm64/boot/dts/qcom/sa8155p.dtsi
index ffb7ab695213..9e70effc72e1 100644
--- a/arch/arm64/boot/dts/qcom/sa8155p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8155p.dtsi
@@ -38,3 +38,7 @@
*/
compatible = "qcom,sa8155p-rpmhpd";
};
+
+&videocc {
+ power-domains = <&rpmhpd SA8155P_CX>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi b/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi
index eaa43f022a65..1369c3d43f86 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi
@@ -10,7 +10,7 @@
thermal-zones {
pmm8654au_0_thermal: pm8775-0-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pmm8654au_0_temp_alarm>;
trips {
@@ -30,7 +30,7 @@
pmm8654au_1_thermal: pm8775-1-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pmm8654au_1_temp_alarm>;
trips {
@@ -50,7 +50,7 @@
pmm8654au_2_thermal: pm8775-2-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pmm8654au_2_temp_alarm>;
trips {
@@ -70,7 +70,7 @@
pmm8654au_3_thermal: pm8775-3-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pmm8654au_3_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts b/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts
new file mode 100644
index 000000000000..ae065ae92478
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include "sa8775p-ride.dtsi"
+
+/ {
+ model = "Qualcomm SA8775P Ride Rev3";
+ compatible = "qcom,sa8775p-ride-r3", "qcom,sa8775p";
+};
+
+&ethernet0 {
+ phy-mode = "2500base-x";
+};
+
+&ethernet1 {
+ phy-mode = "2500base-x";
+};
+
+&mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sgmii_phy0: phy@8 {
+ compatible = "ethernet-phy-id31c3.1c33";
+ reg = <0x8>;
+ device_type = "ethernet-phy";
+ interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <11000>;
+ reset-deassert-us = <70000>;
+ };
+
+ sgmii_phy1: phy@0 {
+ compatible = "ethernet-phy-id31c3.1c33";
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <11000>;
+ reset-deassert-us = <70000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
index 26ad05bd3b3f..2e87fd760dbd 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
+++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
@@ -5,835 +5,43 @@
/dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
-
-#include "sa8775p.dtsi"
-#include "sa8775p-pmics.dtsi"
+#include "sa8775p-ride.dtsi"
/ {
model = "Qualcomm SA8775P Ride";
compatible = "qcom,sa8775p-ride", "qcom,sa8775p";
-
- aliases {
- ethernet0 = &ethernet0;
- ethernet1 = &ethernet1;
- i2c11 = &i2c11;
- i2c18 = &i2c18;
- serial0 = &uart10;
- serial1 = &uart12;
- serial2 = &uart17;
- spi16 = &spi16;
- ufshc1 = &ufs_mem_hc;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-};
-
-&apps_rsc {
- regulators-0 {
- compatible = "qcom,pmm8654au-rpmh-regulators";
- qcom,pmic-id = "a";
-
- vreg_s4a: smps4 {
- regulator-name = "vreg_s4a";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1816000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_s5a: smps5 {
- regulator-name = "vreg_s5a";
- regulator-min-microvolt = <1850000>;
- regulator-max-microvolt = <1996000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_s9a: smps9 {
- regulator-name = "vreg_s9a";
- regulator-min-microvolt = <535000>;
- regulator-max-microvolt = <1120000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l4a: ldo4 {
- regulator-name = "vreg_l4a";
- regulator-min-microvolt = <788000>;
- regulator-max-microvolt = <1050000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l5a: ldo5 {
- regulator-name = "vreg_l5a";
- regulator-min-microvolt = <870000>;
- regulator-max-microvolt = <950000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l6a: ldo6 {
- regulator-name = "vreg_l6a";
- regulator-min-microvolt = <870000>;
- regulator-max-microvolt = <970000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l7a: ldo7 {
- regulator-name = "vreg_l7a";
- regulator-min-microvolt = <720000>;
- regulator-max-microvolt = <950000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l8a: ldo8 {
- regulator-name = "vreg_l8a";
- regulator-min-microvolt = <2504000>;
- regulator-max-microvolt = <3300000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l9a: ldo9 {
- regulator-name = "vreg_l9a";
- regulator-min-microvolt = <2970000>;
- regulator-max-microvolt = <3544000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
- };
-
- regulators-1 {
- compatible = "qcom,pmm8654au-rpmh-regulators";
- qcom,pmic-id = "c";
-
- vreg_l1c: ldo1 {
- regulator-name = "vreg_l1c";
- regulator-min-microvolt = <1140000>;
- regulator-max-microvolt = <1260000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l2c: ldo2 {
- regulator-name = "vreg_l2c";
- regulator-min-microvolt = <900000>;
- regulator-max-microvolt = <1100000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l3c: ldo3 {
- regulator-name = "vreg_l3c";
- regulator-min-microvolt = <1100000>;
- regulator-max-microvolt = <1300000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l4c: ldo4 {
- regulator-name = "vreg_l4c";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- /*
- * FIXME: This should have regulator-allow-set-load but
- * we're getting an over-current fault from the PMIC
- * when switching to LPM.
- */
- };
-
- vreg_l5c: ldo5 {
- regulator-name = "vreg_l5c";
- regulator-min-microvolt = <1100000>;
- regulator-max-microvolt = <1300000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l6c: ldo6 {
- regulator-name = "vreg_l6c";
- regulator-min-microvolt = <1620000>;
- regulator-max-microvolt = <1980000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l7c: ldo7 {
- regulator-name = "vreg_l7c";
- regulator-min-microvolt = <1620000>;
- regulator-max-microvolt = <2000000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l8c: ldo8 {
- regulator-name = "vreg_l8c";
- regulator-min-microvolt = <2400000>;
- regulator-max-microvolt = <3300000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l9c: ldo9 {
- regulator-name = "vreg_l9c";
- regulator-min-microvolt = <1650000>;
- regulator-max-microvolt = <2700000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
- };
-
- regulators-2 {
- compatible = "qcom,pmm8654au-rpmh-regulators";
- qcom,pmic-id = "e";
-
- vreg_s4e: smps4 {
- regulator-name = "vreg_s4e";
- regulator-min-microvolt = <970000>;
- regulator-max-microvolt = <1520000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_s7e: smps7 {
- regulator-name = "vreg_s7e";
- regulator-min-microvolt = <1010000>;
- regulator-max-microvolt = <1170000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_s9e: smps9 {
- regulator-name = "vreg_s9e";
- regulator-min-microvolt = <300000>;
- regulator-max-microvolt = <570000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l6e: ldo6 {
- regulator-name = "vreg_l6e";
- regulator-min-microvolt = <1280000>;
- regulator-max-microvolt = <1450000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
-
- vreg_l8e: ldo8 {
- regulator-name = "vreg_l8e";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1950000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- regulator-allow-set-load;
- regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
- RPMH_REGULATOR_MODE_HPM>;
- };
- };
};
&ethernet0 {
phy-mode = "sgmii";
- phy-handle = <&sgmii_phy0>;
-
- pinctrl-0 = <&ethernet0_default>;
- pinctrl-names = "default";
-
- snps,mtl-rx-config = <&mtl_rx_setup>;
- snps,mtl-tx-config = <&mtl_tx_setup>;
- snps,ps-speed = <1000>;
-
- status = "okay";
-
- mdio {
- compatible = "snps,dwmac-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
-
- sgmii_phy0: phy@8 {
- compatible = "ethernet-phy-id0141.0dd4";
- reg = <0x8>;
- device_type = "ethernet-phy";
- interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
- reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
- reset-assert-us = <11000>;
- reset-deassert-us = <70000>;
- };
-
- sgmii_phy1: phy@a {
- compatible = "ethernet-phy-id0141.0dd4";
- reg = <0xa>;
- device_type = "ethernet-phy";
- interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
- reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
- reset-assert-us = <11000>;
- reset-deassert-us = <70000>;
- };
- };
-
- mtl_rx_setup: rx-queues-config {
- snps,rx-queues-to-use = <4>;
- snps,rx-sched-sp;
-
- queue0 {
- snps,dcb-algorithm;
- snps,map-to-dma-channel = <0x0>;
- snps,route-up;
- snps,priority = <0x1>;
- };
-
- queue1 {
- snps,dcb-algorithm;
- snps,map-to-dma-channel = <0x1>;
- snps,route-ptp;
- };
-
- queue2 {
- snps,avb-algorithm;
- snps,map-to-dma-channel = <0x2>;
- snps,route-avcp;
- };
-
- queue3 {
- snps,avb-algorithm;
- snps,map-to-dma-channel = <0x3>;
- snps,priority = <0xc>;
- };
- };
-
- mtl_tx_setup: tx-queues-config {
- snps,tx-queues-to-use = <4>;
- snps,tx-sched-sp;
-
- queue0 {
- snps,dcb-algorithm;
- };
-
- queue1 {
- snps,dcb-algorithm;
- };
-
- queue2 {
- snps,avb-algorithm;
- snps,send_slope = <0x1000>;
- snps,idle_slope = <0x1000>;
- snps,high_credit = <0x3e800>;
- snps,low_credit = <0xffc18000>;
- };
-
- queue3 {
- snps,avb-algorithm;
- snps,send_slope = <0x1000>;
- snps,idle_slope = <0x1000>;
- snps,high_credit = <0x3e800>;
- snps,low_credit = <0xffc18000>;
- };
- };
};
&ethernet1 {
phy-mode = "sgmii";
- phy-handle = <&sgmii_phy1>;
-
- snps,mtl-rx-config = <&mtl_rx_setup1>;
- snps,mtl-tx-config = <&mtl_tx_setup1>;
- snps,ps-speed = <1000>;
-
- status = "okay";
-
- mtl_rx_setup1: rx-queues-config {
- snps,rx-queues-to-use = <4>;
- snps,rx-sched-sp;
-
- queue0 {
- snps,dcb-algorithm;
- snps,map-to-dma-channel = <0x0>;
- snps,route-up;
- snps,priority = <0x1>;
- };
-
- queue1 {
- snps,dcb-algorithm;
- snps,map-to-dma-channel = <0x1>;
- snps,route-ptp;
- };
-
- queue2 {
- snps,avb-algorithm;
- snps,map-to-dma-channel = <0x2>;
- snps,route-avcp;
- };
-
- queue3 {
- snps,avb-algorithm;
- snps,map-to-dma-channel = <0x3>;
- snps,priority = <0xc>;
- };
- };
-
- mtl_tx_setup1: tx-queues-config {
- snps,tx-queues-to-use = <4>;
- snps,tx-sched-sp;
-
- queue0 {
- snps,dcb-algorithm;
- };
-
- queue1 {
- snps,dcb-algorithm;
- };
-
- queue2 {
- snps,avb-algorithm;
- snps,send_slope = <0x1000>;
- snps,idle_slope = <0x1000>;
- snps,high_credit = <0x3e800>;
- snps,low_credit = <0xffc18000>;
- };
-
- queue3 {
- snps,avb-algorithm;
- snps,send_slope = <0x1000>;
- snps,idle_slope = <0x1000>;
- snps,high_credit = <0x3e800>;
- snps,low_credit = <0xffc18000>;
- };
- };
-};
-
-&i2c11 {
- clock-frequency = <400000>;
- pinctrl-0 = <&qup_i2c11_default>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&i2c18 {
- clock-frequency = <400000>;
- pinctrl-0 = <&qup_i2c18_default>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&pmm8654au_0_gpios {
- gpio-line-names = "DS_EN",
- "POFF_COMPLETE",
- "UFS0_VER_ID",
- "FAST_POFF",
- "DBU1_PON_DONE",
- "AOSS_SLEEP",
- "CAM_DES0_EN",
- "CAM_DES1_EN",
- "CAM_DES2_EN",
- "CAM_DES3_EN",
- "UEFI",
- "ANALOG_PON_OPT";
-};
-
-&pmm8654au_0_pon_resin {
- linux,code = <KEY_VOLUMEDOWN>;
- status = "okay";
-};
-
-&pmm8654au_1_gpios {
- gpio-line-names = "PMIC_C_ID0",
- "PMIC_C_ID1",
- "UFS1_VER_ID",
- "IPA_PWR",
- "",
- "WLAN_DBU4_EN",
- "WLAN_EN",
- "BT_EN",
- "USB2_PWR_EN",
- "USB2_FAULT";
-
- usb2_en_state: usb2-en-state {
- pins = "gpio9";
- function = "normal";
- output-high;
- power-source = <0>;
- };
-};
-
-&pmm8654au_2_gpios {
- gpio-line-names = "PMIC_E_ID0",
- "PMIC_E_ID1",
- "USB0_PWR_EN",
- "USB0_FAULT",
- "SENSOR_IRQ_1",
- "SENSOR_IRQ_2",
- "SENSOR_RST",
- "SGMIIO0_RST",
- "SGMIIO1_RST",
- "USB1_PWR_ENABLE",
- "USB1_FAULT",
- "VMON_SPX8";
-
- usb0_en_state: usb0-en-state {
- pins = "gpio3";
- function = "normal";
- output-high;
- power-source = <0>;
- };
-
- usb1_en_state: usb1-en-state {
- pins = "gpio10";
- function = "normal";
- output-high;
- power-source = <0>;
- };
-};
-
-&pmm8654au_3_gpios {
- gpio-line-names = "PMIC_G_ID0",
- "PMIC_G_ID1",
- "GNSS_RST",
- "GNSS_EN",
- "GNSS_BOOT_MODE";
-};
-
-&qupv3_id_1 {
- status = "okay";
-};
-
-&qupv3_id_2 {
- status = "okay";
-};
-
-&serdes0 {
- phy-supply = <&vreg_l5a>;
- status = "okay";
-};
-
-&serdes1 {
- phy-supply = <&vreg_l5a>;
- status = "okay";
-};
-
-&sleep_clk {
- clock-frequency = <32764>;
-};
-
-&spi16 {
- pinctrl-0 = <&qup_spi16_default>;
- pinctrl-names = "default";
- status = "okay";
};
-&tlmm {
- ethernet0_default: ethernet0-default-state {
- ethernet0_mdc: ethernet0-mdc-pins {
- pins = "gpio8";
- function = "emac0_mdc";
- drive-strength = <16>;
- bias-pull-up;
- };
-
- ethernet0_mdio: ethernet0-mdio-pins {
- pins = "gpio9";
- function = "emac0_mdio";
- drive-strength = <16>;
- bias-pull-up;
- };
- };
-
- qup_uart10_default: qup-uart10-state {
- pins = "gpio46", "gpio47";
- function = "qup1_se3";
- };
-
- qup_spi16_default: qup-spi16-state {
- pins = "gpio86", "gpio87", "gpio88", "gpio89";
- function = "qup2_se2";
- drive-strength = <6>;
- bias-disable;
- };
-
- qup_i2c11_default: qup-i2c11-state {
- pins = "gpio48", "gpio49";
- function = "qup1_se4";
- drive-strength = <2>;
- bias-pull-up;
- };
-
- qup_i2c18_default: qup-i2c18-state {
- pins = "gpio95", "gpio96";
- function = "qup2_se4";
- drive-strength = <2>;
- bias-pull-up;
- };
-
- qup_uart12_default: qup-uart12-state {
- qup_uart12_cts: qup-uart12-cts-pins {
- pins = "gpio52";
- function = "qup1_se5";
- bias-disable;
- };
-
- qup_uart12_rts: qup-uart12-rts-pins {
- pins = "gpio53";
- function = "qup1_se5";
- bias-pull-down;
- };
-
- qup_uart12_tx: qup-uart12-tx-pins {
- pins = "gpio54";
- function = "qup1_se5";
- bias-pull-up;
- };
-
- qup_uart12_rx: qup-uart12-rx-pins {
- pins = "gpio55";
- function = "qup1_se5";
- bias-pull-down;
- };
- };
-
- qup_uart17_default: qup-uart17-state {
- qup_uart17_cts: qup-uart17-cts-pins {
- pins = "gpio91";
- function = "qup2_se3";
- bias-disable;
- };
-
- qup_uart17_rts: qup0-uart17-rts-pins {
- pins = "gpio92";
- function = "qup2_se3";
- bias-pull-down;
- };
-
- qup_uart17_tx: qup0-uart17-tx-pins {
- pins = "gpio93";
- function = "qup2_se3";
- bias-pull-up;
- };
-
- qup_uart17_rx: qup0-uart17-rx-pins {
- pins = "gpio94";
- function = "qup2_se3";
- bias-pull-down;
- };
- };
+&mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
- pcie0_default_state: pcie0-default-state {
- perst-pins {
- pins = "gpio2";
- function = "gpio";
- drive-strength = <2>;
- bias-pull-down;
- };
-
- clkreq-pins {
- pins = "gpio1";
- function = "pcie0_clkreq";
- drive-strength = <2>;
- bias-pull-up;
- };
-
- wake-pins {
- pins = "gpio0";
- function = "gpio";
- drive-strength = <2>;
- bias-pull-up;
- };
+ sgmii_phy0: phy@8 {
+ compatible = "ethernet-phy-id0141.0dd4";
+ reg = <0x8>;
+ device_type = "ethernet-phy";
+ interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <11000>;
+ reset-deassert-us = <70000>;
};
- pcie1_default_state: pcie1-default-state {
- perst-pins {
- pins = "gpio4";
- function = "gpio";
- drive-strength = <2>;
- bias-pull-down;
- };
-
- clkreq-pins {
- pins = "gpio3";
- function = "pcie1_clkreq";
- drive-strength = <2>;
- bias-pull-up;
- };
-
- wake-pins {
- pins = "gpio5";
- function = "gpio";
- drive-strength = <2>;
- bias-pull-up;
- };
+ sgmii_phy1: phy@a {
+ compatible = "ethernet-phy-id0141.0dd4";
+ reg = <0xa>;
+ device_type = "ethernet-phy";
+ interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <11000>;
+ reset-deassert-us = <70000>;
};
};
-
-&pcie0 {
- perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
- wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&pcie0_default_state>;
-
- status = "okay";
-};
-
-&pcie1 {
- perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
- wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&pcie1_default_state>;
-
- status = "okay";
-};
-
-&pcie0_phy {
- vdda-phy-supply = <&vreg_l5a>;
- vdda-pll-supply = <&vreg_l1c>;
-
- status = "okay";
-};
-
-&pcie1_phy {
- vdda-phy-supply = <&vreg_l5a>;
- vdda-pll-supply = <&vreg_l1c>;
-
- status = "okay";
-};
-
-&uart10 {
- compatible = "qcom,geni-debug-uart";
- pinctrl-0 = <&qup_uart10_default>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&uart12 {
- pinctrl-0 = <&qup_uart12_default>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&uart17 {
- pinctrl-0 = <&qup_uart17_default>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&ufs_mem_hc {
- reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
- vcc-supply = <&vreg_l8a>;
- vcc-max-microamp = <1100000>;
- vccq-supply = <&vreg_l4c>;
- vccq-max-microamp = <1200000>;
-
- status = "okay";
-};
-
-&ufs_mem_phy {
- vdda-phy-supply = <&vreg_l4a>;
- vdda-pll-supply = <&vreg_l1c>;
-
- status = "okay";
-};
-
-&usb_0 {
- pinctrl-names = "default";
- pinctrl-0 = <&usb0_en_state>;
-
- status = "okay";
-};
-
-&usb_0_dwc3 {
- dr_mode = "peripheral";
-};
-
-&usb_0_hsphy {
- vdda-pll-supply = <&vreg_l7a>;
- vdda18-supply = <&vreg_l6c>;
- vdda33-supply = <&vreg_l9a>;
-
- status = "okay";
-};
-
-&usb_0_qmpphy {
- vdda-phy-supply = <&vreg_l1c>;
- vdda-pll-supply = <&vreg_l7a>;
-
- status = "okay";
-};
-
-&usb_1 {
- pinctrl-names = "default";
- pinctrl-0 = <&usb1_en_state>;
-
- status = "okay";
-};
-
-&usb_1_dwc3 {
- dr_mode = "host";
-};
-
-&usb_1_hsphy {
- vdda-pll-supply = <&vreg_l7a>;
- vdda18-supply = <&vreg_l6c>;
- vdda33-supply = <&vreg_l9a>;
-
- status = "okay";
-};
-
-&usb_1_qmpphy {
- vdda-phy-supply = <&vreg_l1c>;
- vdda-pll-supply = <&vreg_l7a>;
-
- status = "okay";
-};
-
-&usb_2 {
- pinctrl-names = "default";
- pinctrl-0 = <&usb2_en_state>;
-
- status = "okay";
-};
-
-&usb_2_dwc3 {
- dr_mode = "host";
-};
-
-&usb_2_hsphy {
- vdda-pll-supply = <&vreg_l7a>;
- vdda18-supply = <&vreg_l6c>;
- vdda33-supply = <&vreg_l9a>;
-
- status = "okay";
-};
-
-&xo_board_clk {
- clock-frequency = <38400000>;
-};
diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi b/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi
new file mode 100644
index 000000000000..2a6170623ea9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi
@@ -0,0 +1,814 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "sa8775p.dtsi"
+#include "sa8775p-pmics.dtsi"
+
+/ {
+ aliases {
+ ethernet0 = &ethernet0;
+ ethernet1 = &ethernet1;
+ i2c11 = &i2c11;
+ i2c18 = &i2c18;
+ serial0 = &uart10;
+ serial1 = &uart12;
+ serial2 = &uart17;
+ spi16 = &spi16;
+ ufshc1 = &ufs_mem_hc;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pmm8654au-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vreg_s4a: smps4 {
+ regulator-name = "vreg_s4a";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1816000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5a: smps5 {
+ regulator-name = "vreg_s5a";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1996000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s9a: smps9 {
+ regulator-name = "vreg_s9a";
+ regulator-min-microvolt = <535000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4a: ldo4 {
+ regulator-name = "vreg_l4a";
+ regulator-min-microvolt = <788000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5a: ldo5 {
+ regulator-name = "vreg_l5a";
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6a: ldo6 {
+ regulator-name = "vreg_l6a";
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <970000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7a: ldo7 {
+ regulator-name = "vreg_l7a";
+ regulator-min-microvolt = <720000>;
+ regulator-max-microvolt = <950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8a: ldo8 {
+ regulator-name = "vreg_l8a";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9a: ldo9 {
+ regulator-name = "vreg_l9a";
+ regulator-min-microvolt = <2970000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pmm8654au-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_l1c: ldo1 {
+ regulator-name = "vreg_l1c";
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1260000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c: ldo2 {
+ regulator-name = "vreg_l2c";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c: ldo3 {
+ regulator-name = "vreg_l3c";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c: ldo4 {
+ regulator-name = "vreg_l4c";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ /*
+ * FIXME: This should have regulator-allow-set-load but
+ * we're getting an over-current fault from the PMIC
+ * when switching to LPM.
+ */
+ };
+
+ vreg_l5c: ldo5 {
+ regulator-name = "vreg_l5c";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6c: ldo6 {
+ regulator-name = "vreg_l6c";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c: ldo7 {
+ regulator-name = "vreg_l7c";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c: ldo8 {
+ regulator-name = "vreg_l8c";
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c: ldo9 {
+ regulator-name = "vreg_l9c";
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pmm8654au-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vreg_s4e: smps4 {
+ regulator-name = "vreg_s4e";
+ regulator-min-microvolt = <970000>;
+ regulator-max-microvolt = <1520000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s7e: smps7 {
+ regulator-name = "vreg_s7e";
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1170000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s9e: smps9 {
+ regulator-name = "vreg_s9e";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <570000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6e: ldo6 {
+ regulator-name = "vreg_l6e";
+ regulator-min-microvolt = <1280000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8e: ldo8 {
+ regulator-name = "vreg_l8e";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&ethernet0 {
+ phy-handle = <&sgmii_phy0>;
+
+ pinctrl-0 = <&ethernet0_default>;
+ pinctrl-names = "default";
+
+ snps,mtl-rx-config = <&mtl_rx_setup>;
+ snps,mtl-tx-config = <&mtl_tx_setup>;
+ snps,ps-speed = <1000>;
+
+ status = "okay";
+
+ mdio: mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mtl_rx_setup: rx-queues-config {
+ snps,rx-queues-to-use = <4>;
+ snps,rx-sched-sp;
+
+ queue0 {
+ snps,dcb-algorithm;
+ snps,map-to-dma-channel = <0x0>;
+ snps,route-up;
+ snps,priority = <0x1>;
+ };
+
+ queue1 {
+ snps,dcb-algorithm;
+ snps,map-to-dma-channel = <0x1>;
+ snps,route-ptp;
+ };
+
+ queue2 {
+ snps,avb-algorithm;
+ snps,map-to-dma-channel = <0x2>;
+ snps,route-avcp;
+ };
+
+ queue3 {
+ snps,avb-algorithm;
+ snps,map-to-dma-channel = <0x3>;
+ snps,priority = <0xc>;
+ };
+ };
+
+ mtl_tx_setup: tx-queues-config {
+ snps,tx-queues-to-use = <4>;
+ snps,tx-sched-sp;
+
+ queue0 {
+ snps,dcb-algorithm;
+ };
+
+ queue1 {
+ snps,dcb-algorithm;
+ };
+
+ queue2 {
+ snps,avb-algorithm;
+ snps,send_slope = <0x1000>;
+ snps,idle_slope = <0x1000>;
+ snps,high_credit = <0x3e800>;
+ snps,low_credit = <0xffc18000>;
+ };
+
+ queue3 {
+ snps,avb-algorithm;
+ snps,send_slope = <0x1000>;
+ snps,idle_slope = <0x1000>;
+ snps,high_credit = <0x3e800>;
+ snps,low_credit = <0xffc18000>;
+ };
+ };
+};
+
+&ethernet1 {
+ phy-handle = <&sgmii_phy1>;
+
+ snps,mtl-rx-config = <&mtl_rx_setup1>;
+ snps,mtl-tx-config = <&mtl_tx_setup1>;
+ snps,ps-speed = <1000>;
+
+ status = "okay";
+
+ mtl_rx_setup1: rx-queues-config {
+ snps,rx-queues-to-use = <4>;
+ snps,rx-sched-sp;
+
+ queue0 {
+ snps,dcb-algorithm;
+ snps,map-to-dma-channel = <0x0>;
+ snps,route-up;
+ snps,priority = <0x1>;
+ };
+
+ queue1 {
+ snps,dcb-algorithm;
+ snps,map-to-dma-channel = <0x1>;
+ snps,route-ptp;
+ };
+
+ queue2 {
+ snps,avb-algorithm;
+ snps,map-to-dma-channel = <0x2>;
+ snps,route-avcp;
+ };
+
+ queue3 {
+ snps,avb-algorithm;
+ snps,map-to-dma-channel = <0x3>;
+ snps,priority = <0xc>;
+ };
+ };
+
+ mtl_tx_setup1: tx-queues-config {
+ snps,tx-queues-to-use = <4>;
+ snps,tx-sched-sp;
+
+ queue0 {
+ snps,dcb-algorithm;
+ };
+
+ queue1 {
+ snps,dcb-algorithm;
+ };
+
+ queue2 {
+ snps,avb-algorithm;
+ snps,send_slope = <0x1000>;
+ snps,idle_slope = <0x1000>;
+ snps,high_credit = <0x3e800>;
+ snps,low_credit = <0xffc18000>;
+ };
+
+ queue3 {
+ snps,avb-algorithm;
+ snps,send_slope = <0x1000>;
+ snps,idle_slope = <0x1000>;
+ snps,high_credit = <0x3e800>;
+ snps,low_credit = <0xffc18000>;
+ };
+ };
+};
+
+&i2c11 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&qup_i2c11_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c18 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&qup_i2c18_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pmm8654au_0_gpios {
+ gpio-line-names = "DS_EN",
+ "POFF_COMPLETE",
+ "UFS0_VER_ID",
+ "FAST_POFF",
+ "DBU1_PON_DONE",
+ "AOSS_SLEEP",
+ "CAM_DES0_EN",
+ "CAM_DES1_EN",
+ "CAM_DES2_EN",
+ "CAM_DES3_EN",
+ "UEFI",
+ "ANALOG_PON_OPT";
+};
+
+&pmm8654au_0_pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pmm8654au_1_gpios {
+ gpio-line-names = "PMIC_C_ID0",
+ "PMIC_C_ID1",
+ "UFS1_VER_ID",
+ "IPA_PWR",
+ "",
+ "WLAN_DBU4_EN",
+ "WLAN_EN",
+ "BT_EN",
+ "USB2_PWR_EN",
+ "USB2_FAULT";
+
+ usb2_en_state: usb2-en-state {
+ pins = "gpio9";
+ function = "normal";
+ output-high;
+ power-source = <0>;
+ };
+};
+
+&pmm8654au_2_gpios {
+ gpio-line-names = "PMIC_E_ID0",
+ "PMIC_E_ID1",
+ "USB0_PWR_EN",
+ "USB0_FAULT",
+ "SENSOR_IRQ_1",
+ "SENSOR_IRQ_2",
+ "SENSOR_RST",
+ "SGMIIO0_RST",
+ "SGMIIO1_RST",
+ "USB1_PWR_ENABLE",
+ "USB1_FAULT",
+ "VMON_SPX8";
+
+ usb0_en_state: usb0-en-state {
+ pins = "gpio3";
+ function = "normal";
+ output-high;
+ power-source = <0>;
+ };
+
+ usb1_en_state: usb1-en-state {
+ pins = "gpio10";
+ function = "normal";
+ output-high;
+ power-source = <0>;
+ };
+};
+
+&pmm8654au_3_gpios {
+ gpio-line-names = "PMIC_G_ID0",
+ "PMIC_G_ID1",
+ "GNSS_RST",
+ "GNSS_EN",
+ "GNSS_BOOT_MODE";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&qupv3_id_2 {
+ status = "okay";
+};
+
+&serdes0 {
+ phy-supply = <&vreg_l5a>;
+ status = "okay";
+};
+
+&serdes1 {
+ phy-supply = <&vreg_l5a>;
+ status = "okay";
+};
+
+&sleep_clk {
+ clock-frequency = <32764>;
+};
+
+&spi16 {
+ pinctrl-0 = <&qup_spi16_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tlmm {
+ ethernet0_default: ethernet0-default-state {
+ ethernet0_mdc: ethernet0-mdc-pins {
+ pins = "gpio8";
+ function = "emac0_mdc";
+ drive-strength = <16>;
+ bias-pull-up;
+ };
+
+ ethernet0_mdio: ethernet0-mdio-pins {
+ pins = "gpio9";
+ function = "emac0_mdio";
+ drive-strength = <16>;
+ bias-pull-up;
+ };
+ };
+
+ qup_uart10_default: qup-uart10-state {
+ pins = "gpio46", "gpio47";
+ function = "qup1_se3";
+ };
+
+ qup_spi16_default: qup-spi16-state {
+ pins = "gpio86", "gpio87", "gpio88", "gpio89";
+ function = "qup2_se2";
+ drive-strength = <6>;
+ bias-disable;
+ };
+
+ qup_i2c11_default: qup-i2c11-state {
+ pins = "gpio48", "gpio49";
+ function = "qup1_se4";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_i2c18_default: qup-i2c18-state {
+ pins = "gpio95", "gpio96";
+ function = "qup2_se4";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_uart12_default: qup-uart12-state {
+ qup_uart12_cts: qup-uart12-cts-pins {
+ pins = "gpio52";
+ function = "qup1_se5";
+ bias-disable;
+ };
+
+ qup_uart12_rts: qup-uart12-rts-pins {
+ pins = "gpio53";
+ function = "qup1_se5";
+ bias-pull-down;
+ };
+
+ qup_uart12_tx: qup-uart12-tx-pins {
+ pins = "gpio54";
+ function = "qup1_se5";
+ bias-pull-up;
+ };
+
+ qup_uart12_rx: qup-uart12-rx-pins {
+ pins = "gpio55";
+ function = "qup1_se5";
+ bias-pull-down;
+ };
+ };
+
+ qup_uart17_default: qup-uart17-state {
+ qup_uart17_cts: qup-uart17-cts-pins {
+ pins = "gpio91";
+ function = "qup2_se3";
+ bias-disable;
+ };
+
+ qup_uart17_rts: qup0-uart17-rts-pins {
+ pins = "gpio92";
+ function = "qup2_se3";
+ bias-pull-down;
+ };
+
+ qup_uart17_tx: qup0-uart17-tx-pins {
+ pins = "gpio93";
+ function = "qup2_se3";
+ bias-pull-up;
+ };
+
+ qup_uart17_rx: qup0-uart17-rx-pins {
+ pins = "gpio94";
+ function = "qup2_se3";
+ bias-pull-down;
+ };
+ };
+
+ pcie0_default_state: pcie0-default-state {
+ perst-pins {
+ pins = "gpio2";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ clkreq-pins {
+ pins = "gpio1";
+ function = "pcie0_clkreq";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ wake-pins {
+ pins = "gpio0";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ pcie1_default_state: pcie1-default-state {
+ perst-pins {
+ pins = "gpio4";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ clkreq-pins {
+ pins = "gpio3";
+ function = "pcie1_clkreq";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ wake-pins {
+ pins = "gpio5";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+};
+
+&pcie0 {
+ perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_default_state>;
+
+ status = "okay";
+};
+
+&pcie1 {
+ perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_default_state>;
+
+ status = "okay";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l5a>;
+ vdda-pll-supply = <&vreg_l1c>;
+
+ status = "okay";
+};
+
+&pcie1_phy {
+ vdda-phy-supply = <&vreg_l5a>;
+ vdda-pll-supply = <&vreg_l1c>;
+
+ status = "okay";
+};
+
+&uart10 {
+ compatible = "qcom,geni-debug-uart";
+ pinctrl-0 = <&qup_uart10_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart12 {
+ pinctrl-0 = <&qup_uart12_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart17 {
+ pinctrl-0 = <&qup_uart17_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
+ vcc-supply = <&vreg_l8a>;
+ vcc-max-microamp = <1100000>;
+ vccq-supply = <&vreg_l4c>;
+ vccq-max-microamp = <1200000>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l4a>;
+ vdda-pll-supply = <&vreg_l1c>;
+
+ status = "okay";
+};
+
+&usb_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_en_state>;
+
+ status = "okay";
+};
+
+&usb_0_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_0_hsphy {
+ vdda-pll-supply = <&vreg_l7a>;
+ vdda18-supply = <&vreg_l6c>;
+ vdda33-supply = <&vreg_l9a>;
+
+ status = "okay";
+};
+
+&usb_0_qmpphy {
+ vdda-phy-supply = <&vreg_l1c>;
+ vdda-pll-supply = <&vreg_l7a>;
+
+ status = "okay";
+};
+
+&usb_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_en_state>;
+
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_hsphy {
+ vdda-pll-supply = <&vreg_l7a>;
+ vdda18-supply = <&vreg_l6c>;
+ vdda33-supply = <&vreg_l9a>;
+
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vreg_l1c>;
+ vdda-pll-supply = <&vreg_l7a>;
+
+ status = "okay";
+};
+
+&usb_2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_en_state>;
+
+ status = "okay";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_2_hsphy {
+ vdda-pll-supply = <&vreg_l7a>;
+ vdda18-supply = <&vreg_l6c>;
+ vdda33-supply = <&vreg_l9a>;
+
+ status = "okay";
+};
+
+&xo_board_clk {
+ clock-frequency = <38400000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
index 231cea1f0fa8..23f1b2e5e624 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
@@ -205,9 +205,23 @@
};
};
+ dummy-sink {
+ compatible = "arm,coresight-dummy-sink";
+
+ in-ports {
+ port {
+ eud_in: endpoint {
+ remote-endpoint =
+ <&swao_rep_out1>;
+ };
+ };
+ };
+ };
+
firmware {
scm {
compatible = "qcom,scm-sa8775p", "qcom,scm";
+ memory-region = <&tz_ffi_mem>;
};
};
@@ -418,6 +432,12 @@
no-map;
};
+ tz_ffi_mem: tz-ffi@91c00000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0x91c00000 0x0 0x1400000>;
+ no-map;
+ };
+
lpass_machine_learning_mem: lpass-machine-learning@93b00000 {
reg = <0x0 0x93b00000 0x0 0xf00000>;
no-map;
@@ -1644,6 +1664,919 @@
clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
};
+ stm: stm@4002000 {
+ compatible = "arm,coresight-stm", "arm,primecell";
+ reg = <0x0 0x4002000 0x0 0x1000>,
+ <0x0 0x16280000 0x0 0x180000>;
+ reg-names = "stm-base", "stm-stimulus-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ stm_out: endpoint {
+ remote-endpoint =
+ <&funnel0_in7>;
+ };
+ };
+ };
+ };
+
+ tpdm@4003000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x4003000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <32>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ qdss_tpdm0_out: endpoint {
+ remote-endpoint =
+ <&qdss_tpda_in0>;
+ };
+ };
+ };
+ };
+
+ tpda@4004000 {
+ compatible = "qcom,coresight-tpda", "arm,primecell";
+ reg = <0x0 0x4004000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ qdss_tpda_out: endpoint {
+ remote-endpoint =
+ <&funnel0_in6>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ qdss_tpda_in0: endpoint {
+ remote-endpoint =
+ <&qdss_tpdm0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ qdss_tpda_in1: endpoint {
+ remote-endpoint =
+ <&qdss_tpdm1_out>;
+ };
+ };
+ };
+ };
+
+ tpdm@400f000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x400f000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <32>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ qdss_tpdm1_out: endpoint {
+ remote-endpoint =
+ <&qdss_tpda_in1>;
+ };
+ };
+ };
+ };
+
+ funnel@4041000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0x0 0x4041000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel0_out: endpoint {
+ remote-endpoint =
+ <&qdss_funnel_in0>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@6 {
+ reg = <6>;
+ funnel0_in6: endpoint {
+ remote-endpoint =
+ <&qdss_tpda_out>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ funnel0_in7: endpoint {
+ remote-endpoint =
+ <&stm_out>;
+ };
+ };
+ };
+ };
+
+ funnel@4042000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0x0 0x4042000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel1_out: endpoint {
+ remote-endpoint =
+ <&qdss_funnel_in1>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@4 {
+ reg = <4>;
+ funnel1_in4: endpoint {
+ remote-endpoint =
+ <&apss_funnel1_out>;
+ };
+ };
+ };
+ };
+
+ funnel@4045000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0x0 0x4045000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ qdss_funnel_out: endpoint {
+ remote-endpoint =
+ <&aoss_funnel_in7>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ qdss_funnel_in0: endpoint {
+ remote-endpoint =
+ <&funnel0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ qdss_funnel_in1: endpoint {
+ remote-endpoint =
+ <&funnel1_out>;
+ };
+ };
+ };
+ };
+
+ funnel@4b04000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0x0 0x4b04000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ aoss_funnel_out: endpoint {
+ remote-endpoint =
+ <&etf0_in>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@6 {
+ reg = <6>;
+ aoss_funnel_in6: endpoint {
+ remote-endpoint =
+ <&aoss_tpda_out>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ aoss_funnel_in7: endpoint {
+ remote-endpoint =
+ <&qdss_funnel_out>;
+ };
+ };
+ };
+ };
+
+ tmc_etf: tmc@4b05000 {
+ compatible = "arm,coresight-tmc", "arm,primecell";
+ reg = <0x0 0x4b05000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ etf0_out: endpoint {
+ remote-endpoint =
+ <&swao_rep_in>;
+ };
+ };
+ };
+
+ in-ports {
+ port {
+ etf0_in: endpoint {
+ remote-endpoint =
+ <&aoss_funnel_out>;
+ };
+ };
+ };
+ };
+
+ replicator@4b06000 {
+ compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+ reg = <0x0 0x4b06000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ swao_rep_out1: endpoint {
+ remote-endpoint =
+ <&eud_in>;
+ };
+ };
+ };
+
+ in-ports {
+ port {
+ swao_rep_in: endpoint {
+ remote-endpoint =
+ <&etf0_out>;
+ };
+ };
+ };
+ };
+
+ tpda@4b08000 {
+ compatible = "qcom,coresight-tpda", "arm,primecell";
+ reg = <0x0 0x4b08000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ aoss_tpda_out: endpoint {
+ remote-endpoint =
+ <&aoss_funnel_in6>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ aoss_tpda_in0: endpoint {
+ remote-endpoint =
+ <&aoss_tpdm0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ aoss_tpda_in1: endpoint {
+ remote-endpoint =
+ <&aoss_tpdm1_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ aoss_tpda_in2: endpoint {
+ remote-endpoint =
+ <&aoss_tpdm2_out>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ aoss_tpda_in3: endpoint {
+ remote-endpoint =
+ <&aoss_tpdm3_out>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ aoss_tpda_in4: endpoint {
+ remote-endpoint =
+ <&aoss_tpdm4_out>;
+ };
+ };
+ };
+ };
+
+ tpdm@4b09000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x4b09000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <64>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ aoss_tpdm0_out: endpoint {
+ remote-endpoint =
+ <&aoss_tpda_in0>;
+ };
+ };
+ };
+ };
+
+ tpdm@4b0a000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x4b0a000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <64>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ aoss_tpdm1_out: endpoint {
+ remote-endpoint =
+ <&aoss_tpda_in1>;
+ };
+ };
+ };
+ };
+
+ tpdm@4b0b000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x4b0b000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <64>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ aoss_tpdm2_out: endpoint {
+ remote-endpoint =
+ <&aoss_tpda_in2>;
+ };
+ };
+ };
+ };
+
+ tpdm@4b0c000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x4b0c000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <64>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ aoss_tpdm3_out: endpoint {
+ remote-endpoint =
+ <&aoss_tpda_in3>;
+ };
+ };
+ };
+ };
+
+ tpdm@4b0d000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x4b0d000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,dsb-element-bits = <32>;
+ qcom,dsb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ aoss_tpdm4_out: endpoint {
+ remote-endpoint =
+ <&aoss_tpda_in4>;
+ };
+ };
+ };
+ };
+
+ aoss_cti: cti@4b13000 {
+ compatible = "arm,coresight-cti", "arm,primecell";
+ reg = <0x0 0x4b13000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ };
+
+ etm@6040000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6040000 0x0 0x1000>;
+ cpu = <&CPU0>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm0_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in0>;
+ };
+ };
+ };
+ };
+
+ etm@6140000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6140000 0x0 0x1000>;
+ cpu = <&CPU1>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm1_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in1>;
+ };
+ };
+ };
+ };
+
+ etm@6240000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6240000 0x0 0x1000>;
+ cpu = <&CPU2>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm2_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in2>;
+ };
+ };
+ };
+ };
+
+ etm@6340000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6340000 0x0 0x1000>;
+ cpu = <&CPU3>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm3_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in3>;
+ };
+ };
+ };
+ };
+
+ etm@6440000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6440000 0x0 0x1000>;
+ cpu = <&CPU4>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm4_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in4>;
+ };
+ };
+ };
+ };
+
+ etm@6540000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6540000 0x0 0x1000>;
+ cpu = <&CPU5>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm5_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in5>;
+ };
+ };
+ };
+ };
+
+ etm@6640000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6640000 0x0 0x1000>;
+ cpu = <&CPU6>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm6_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in6>;
+ };
+ };
+ };
+ };
+
+ etm@6740000 {
+ compatible = "arm,primecell";
+ reg = <0x0 0x6740000 0x0 0x1000>;
+ cpu = <&CPU7>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+ qcom,skip-power-up;
+
+ out-ports {
+ port {
+ etm7_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_in7>;
+ };
+ };
+ };
+ };
+
+ funnel@6800000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0x0 0x6800000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ apss_funnel0_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel1_in0>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ apss_funnel0_in0: endpoint {
+ remote-endpoint =
+ <&etm0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ apss_funnel0_in1: endpoint {
+ remote-endpoint =
+ <&etm1_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ apss_funnel0_in2: endpoint {
+ remote-endpoint =
+ <&etm2_out>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ apss_funnel0_in3: endpoint {
+ remote-endpoint =
+ <&etm3_out>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ apss_funnel0_in4: endpoint {
+ remote-endpoint =
+ <&etm4_out>;
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+ apss_funnel0_in5: endpoint {
+ remote-endpoint =
+ <&etm5_out>;
+ };
+ };
+
+ port@6 {
+ reg = <6>;
+ apss_funnel0_in6: endpoint {
+ remote-endpoint =
+ <&etm6_out>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ apss_funnel0_in7: endpoint {
+ remote-endpoint =
+ <&etm7_out>;
+ };
+ };
+ };
+ };
+
+ funnel@6810000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0x0 0x6810000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ apss_funnel1_out: endpoint {
+ remote-endpoint =
+ <&funnel1_in4>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ apss_funnel1_in0: endpoint {
+ remote-endpoint =
+ <&apss_funnel0_out>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ apss_funnel1_in3: endpoint {
+ remote-endpoint =
+ <&apss_tpda_out>;
+ };
+ };
+ };
+ };
+
+ tpdm@6860000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x6860000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <64>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ apss_tpdm3_out: endpoint {
+ remote-endpoint =
+ <&apss_tpda_in3>;
+ };
+ };
+ };
+ };
+
+ tpdm@6861000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x6861000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,dsb-element-bits = <32>;
+ qcom,dsb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ apss_tpdm4_out: endpoint {
+ remote-endpoint =
+ <&apss_tpda_in4>;
+ };
+ };
+ };
+ };
+
+ tpda@6863000 {
+ compatible = "qcom,coresight-tpda", "arm,primecell";
+ reg = <0x0 0x6863000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ apss_tpda_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel1_in3>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ apss_tpda_in0: endpoint {
+ remote-endpoint =
+ <&apss_tpdm0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ apss_tpda_in1: endpoint {
+ remote-endpoint =
+ <&apss_tpdm1_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ apss_tpda_in2: endpoint {
+ remote-endpoint =
+ <&apss_tpdm2_out>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ apss_tpda_in3: endpoint {
+ remote-endpoint =
+ <&apss_tpdm3_out>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ apss_tpda_in4: endpoint {
+ remote-endpoint =
+ <&apss_tpdm4_out>;
+ };
+ };
+ };
+ };
+
+ tpdm@68a0000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x68a0000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <32>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ apss_tpdm0_out: endpoint {
+ remote-endpoint =
+ <&apss_tpda_in0>;
+ };
+ };
+ };
+ };
+
+ tpdm@68b0000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x68b0000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,cmb-element-bits = <32>;
+ qcom,cmb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ apss_tpdm1_out: endpoint {
+ remote-endpoint =
+ <&apss_tpda_in1>;
+ };
+ };
+ };
+ };
+
+ tpdm@68c0000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x0 0x68c0000 0x0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,dsb-element-bits = <32>;
+ qcom,dsb-msrs-num = <32>;
+
+ out-ports {
+ port {
+ apss_tpdm2_out: endpoint {
+ remote-endpoint =
+ <&apss_tpda_in2>;
+ };
+ };
+ };
+ };
+
usb_0_hsphy: phy@88e4000 {
compatible = "qcom,sa8775p-usb-hs-phy",
"qcom,usb-snps-hs-5nm-phy";
@@ -1959,6 +2892,25 @@
status = "disabled";
};
+ llcc: system-cache-controller@9200000 {
+ compatible = "qcom,sa8775p-llcc";
+ reg = <0x0 0x09200000 0x0 0x80000>,
+ <0x0 0x09300000 0x0 0x80000>,
+ <0x0 0x09400000 0x0 0x80000>,
+ <0x0 0x09500000 0x0 0x80000>,
+ <0x0 0x09600000 0x0 0x80000>,
+ <0x0 0x09700000 0x0 0x80000>,
+ <0x0 0x09a00000 0x0 0x80000>;
+ reg-names = "llcc0_base",
+ "llcc1_base",
+ "llcc2_base",
+ "llcc3_base",
+ "llcc4_base",
+ "llcc5_base",
+ "llcc_broadcast_base";
+ interrupts = <GIC_SPI 580 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,sa8775p-pdc", "qcom,pdc";
reg = <0x0 0x0b220000 0x0 0x30000>,
@@ -2099,6 +3051,20 @@
wakeup-parent = <&pdc>;
};
+ sram: sram@146d8000 {
+ compatible = "qcom,sa8775p-imem", "syscon", "simple-mfd";
+ reg = <0x0 0x146d8000 0x0 0x1000>;
+ ranges = <0x0 0x0 0x146d8000 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pil-reloc@94c {
+ compatible = "qcom,pil-reloc-info";
+ reg = <0x94c 0xc8>;
+ };
+ };
+
apps_smmu: iommu@15000000 {
compatible = "qcom,sa8775p-smmu-500", "qcom,smmu-500", "arm,mmu-500";
reg = <0x0 0x15000000 0x0 0x100000>;
@@ -2504,6 +3470,7 @@
phy-names = "serdes";
iommus = <&apps_smmu 0x140 0xf>;
+ dma-coherent;
snps,tso;
snps,pbl = <32>;
@@ -2538,6 +3505,7 @@
phy-names = "serdes";
iommus = <&apps_smmu 0x120 0xf>;
+ dma-coherent;
snps,tso;
snps,pbl = <32>;
@@ -2550,9 +3518,6 @@
thermal-zones {
aoss-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 0>;
trips {
@@ -2572,7 +3537,6 @@
cpu-0-0-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
@@ -2593,7 +3557,6 @@
cpu-0-1-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
@@ -2614,7 +3577,6 @@
cpu-0-2-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
@@ -2635,7 +3597,6 @@
cpu-0-3-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
@@ -2656,7 +3617,6 @@
gpuss-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
@@ -2677,7 +3637,6 @@
gpuss-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
@@ -2698,7 +3657,6 @@
gpuss-2-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
@@ -2718,9 +3676,6 @@
};
audio-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 8>;
trips {
@@ -2739,9 +3694,6 @@
};
camss-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 9>;
trips {
@@ -2760,9 +3712,6 @@
};
pcie-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 10>;
trips {
@@ -2781,9 +3730,6 @@
};
cpuss-0-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 11>;
trips {
@@ -2802,9 +3748,6 @@
};
aoss-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 0>;
trips {
@@ -2824,7 +3767,6 @@
cpu-0-0-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
@@ -2845,7 +3787,6 @@
cpu-0-1-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
@@ -2866,7 +3807,6 @@
cpu-0-2-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 3>;
@@ -2887,7 +3827,6 @@
cpu-0-3-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 4>;
@@ -2908,7 +3847,6 @@
gpuss-3-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 5>;
@@ -2929,7 +3867,6 @@
gpuss-4-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 6>;
@@ -2950,7 +3887,6 @@
gpuss-5-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 7>;
@@ -2970,9 +3906,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 8>;
trips {
@@ -2991,9 +3924,6 @@
};
camss-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 9>;
trips {
@@ -3012,9 +3942,6 @@
};
pcie-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 10>;
trips {
@@ -3033,9 +3960,6 @@
};
cpuss-0-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 11>;
trips {
@@ -3054,9 +3978,6 @@
};
aoss-2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens2 0>;
trips {
@@ -3076,7 +3997,6 @@
cpu-1-0-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 1>;
@@ -3097,7 +4017,6 @@
cpu-1-1-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 2>;
@@ -3118,7 +4037,6 @@
cpu-1-2-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 3>;
@@ -3139,7 +4057,6 @@
cpu-1-3-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 4>;
@@ -3160,7 +4077,6 @@
nsp-0-0-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 5>;
@@ -3181,7 +4097,6 @@
nsp-0-1-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 6>;
@@ -3202,7 +4117,6 @@
nsp-0-2-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 7>;
@@ -3223,7 +4137,6 @@
nsp-1-0-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 8>;
@@ -3244,7 +4157,6 @@
nsp-1-1-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 9>;
@@ -3265,7 +4177,6 @@
nsp-1-2-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 10>;
@@ -3285,9 +4196,6 @@
};
ddrss-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens2 11>;
trips {
@@ -3306,9 +4214,6 @@
};
cpuss-1-0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens2 12>;
trips {
@@ -3327,9 +4232,6 @@
};
aoss-3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens3 0>;
trips {
@@ -3349,7 +4251,6 @@
cpu-1-0-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 1>;
@@ -3370,7 +4271,6 @@
cpu-1-1-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 2>;
@@ -3391,7 +4291,6 @@
cpu-1-2-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 3>;
@@ -3412,7 +4311,6 @@
cpu-1-3-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 4>;
@@ -3433,7 +4331,6 @@
nsp-0-0-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 5>;
@@ -3454,7 +4351,6 @@
nsp-0-1-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 6>;
@@ -3475,7 +4371,6 @@
nsp-0-2-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 7>;
@@ -3496,7 +4391,6 @@
nsp-1-0-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 8>;
@@ -3517,7 +4411,6 @@
nsp-1-1-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 9>;
@@ -3538,7 +4431,6 @@
nsp-1-2-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
thermal-sensors = <&tsens3 10>;
@@ -3558,9 +4450,6 @@
};
ddrss-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens3 11>;
trips {
@@ -3579,9 +4468,6 @@
};
cpuss-1-1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens3 12>;
trips {
@@ -3605,7 +4491,7 @@
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 12 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
};
pcie0: pcie@1c00000 {
@@ -3677,6 +4563,63 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
+ };
+
+ pcie0_ep: pcie-ep@1c00000 {
+ compatible = "qcom,sa8775p-pcie-ep";
+ reg = <0x0 0x01c00000 0x0 0x3000>,
+ <0x0 0x40000000 0x0 0xf20>,
+ <0x0 0x40000f20 0x0 0xa8>,
+ <0x0 0x40001000 0x0 0x4000>,
+ <0x0 0x40200000 0x0 0x100000>,
+ <0x0 0x01c03000 0x0 0x1000>,
+ <0x0 0x40005000 0x0 0x2000>;
+ reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+ "mmio", "dma";
+
+ clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+ <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>;
+
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a";
+
+ interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 630 IRQ_TYPE_LEVEL_HIGH>;
+
+ interrupt-names = "global", "doorbell", "dma";
+
+ interconnects = <&pcie_anoc MASTER_PCIE_0 0 &mc_virt SLAVE_EBI1 0>,
+ <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_PCIE_0 0>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+
+ dma-coherent;
+ iommus = <&pcie_smmu 0x0000 0x7f>;
+ resets = <&gcc GCC_PCIE_0_BCR>;
+ reset-names = "core";
+ power-domains = <&gcc PCIE_0_GDSC>;
+ phys = <&pcie0_phy>;
+ phy-names = "pciephy";
+ max-link-speed = <3>; /* FIXME: Limiting the Gen speed due to stability issues */
+ num-lanes = <2>;
+
+ status = "disabled";
};
pcie0_phy: phy@1c04000 {
@@ -3777,6 +4720,63 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
+ };
+
+ pcie1_ep: pcie-ep@1c10000 {
+ compatible = "qcom,sa8775p-pcie-ep";
+ reg = <0x0 0x01c10000 0x0 0x3000>,
+ <0x0 0x60000000 0x0 0xf20>,
+ <0x0 0x60000f20 0x0 0xa8>,
+ <0x0 0x60001000 0x0 0x4000>,
+ <0x0 0x60200000 0x0 0x100000>,
+ <0x0 0x01c13000 0x0 0x1000>,
+ <0x0 0x60005000 0x0 0x2000>;
+ reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+ "mmio", "dma";
+
+ clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+ <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>;
+
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a";
+
+ interrupts = <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+
+ interrupt-names = "global", "doorbell", "dma";
+
+ interconnects = <&pcie_anoc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI1 0>,
+ <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_PCIE_1 0>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+
+ dma-coherent;
+ iommus = <&pcie_smmu 0x80 0x7f>;
+ resets = <&gcc GCC_PCIE_1_BCR>;
+ reset-names = "core";
+ power-domains = <&gcc PCIE_1_GDSC>;
+ phys = <&pcie1_phy>;
+ phy-names = "pciephy";
+ max-link-speed = <3>; /* FIXME: Limiting the Gen speed due to stability issues */
+ num-lanes = <4>;
+
+ status = "disabled";
};
pcie1_phy: phy@1c14000 {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts b/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts
index 5afcb8212f49..3f0d3e33894a 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts
@@ -255,7 +255,25 @@
clock-frequency = <400000>;
status = "okay";
- /* embedded-controller@76 */
+ embedded-controller@76 {
+ compatible = "acer,aspire1-ec";
+ reg = <0x76>;
+
+ interrupts-extended = <&tlmm 30 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&ec_int_default>;
+ pinctrl-names = "default";
+
+ connector {
+ compatible = "usb-c-connector";
+
+ port {
+ ec_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp_out>;
+ };
+ };
+ };
+ };
};
&i2c4 {
@@ -419,6 +437,19 @@
status = "okay";
};
+&mdss_dp {
+ data-lanes = <0 1>;
+
+ vdda-1p2-supply = <&vreg_l3c_1p2>;
+ vdda-0p9-supply = <&vreg_l4a_0p8>;
+
+ status = "okay";
+};
+
+&mdss_dp_out {
+ remote-endpoint = <&ec_dp_in>;
+};
+
&mdss_dsi0 {
vdda-supply = <&vreg_l3c_1p2>;
status = "okay";
@@ -857,6 +888,13 @@
bias-disable;
};
+ ec_int_default: ec-int-default-state {
+ pins = "gpio30";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
edp_bridge_irq_default: edp-bridge-irq-default-state {
pins = "gpio11";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
new file mode 100644
index 000000000000..d91533b80e76
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Trogdor dts fragment for clamshells
+ *
+ * Copyright 2024 Google LLC.
+ */
+
+/* This file must be included after sc7180-trogdor.dtsi to modify cros_ec */
+#include <arm/cros-ec-keyboard.dtsi>
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
index 7765c8f64905..3c124bbe2f4c 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
@@ -7,6 +7,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
/* Deleted nodes from sc7180-trogdor.dtsi */
@@ -25,7 +26,6 @@
thermal-zones {
skin_temp_thermal: skin-temp-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&pm6150_adc_tm 1>;
sustainable-power = <965>;
@@ -80,10 +80,6 @@
};
&cros_ec {
- keyboard-controller {
- compatible = "google,cros-ec-keyb-switches";
- };
-
cros_ec_proximity: proximity {
compatible = "google,cros-ec-mkbp-proximity";
label = "proximity-wifi";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
new file mode 100644
index 000000000000..7c5d8a57ef7f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Trogdor dts fragment for detachables
+ *
+ * Copyright 2024 Google LLC.
+ */
+
+/* This file must be included after sc7180-trogdor.dtsi to modify cros_ec */
+&cros_ec {
+ keyboard-controller {
+ compatible = "google,cros-ec-keyb-switches";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
index 2ba3bbf3b9ad..b2df22faafe8 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -5,9 +5,8 @@
* Copyright 2021 Google LLC.
*/
-/* This file must be included after sc7180-trogdor.dtsi */
-
#include "sc7180-trogdor-rt5682i-sku.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
/ {
/* BOARD-SPECIFIC TOP LEVEL NODES */
@@ -45,7 +44,6 @@
thermal-zones {
skin_temp_thermal: skin-temp-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&pm6150_adc_tm 1>;
sustainable-power = <965>;
@@ -135,12 +133,6 @@ ap_ts_pen_1v8: &i2c4 {
status = "okay";
};
-&cros_ec {
- keyboard-controller {
- compatible = "google,cros-ec-keyb-switches";
- };
-};
-
&panel {
compatible = "samsung,atna33xc20";
enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
index d6db7d83adcf..655bea928e52 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
@@ -9,7 +9,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-parade-ps8640.dtsi"
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
#include "sc7180-trogdor-rt5682s-sku.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts
index 919bfaea6189..340cb119d0a0 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts
@@ -12,6 +12,6 @@
compatible = "google,lazor-rev1-sku2", "google,lazor-rev2-sku2", "qcom,sc7180";
};
-&keyboard_backlight {
+&pwmleds {
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
index eb20157f6af9..d45e60e3eb9e 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts
@@ -17,6 +17,6 @@
status = "okay";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
index 45d34718a1bc..e906ce877b8c 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
@@ -18,6 +18,6 @@
compatible = "google,lazor-sku2", "qcom,sc7180";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
index 79028d0dd1b0..4b9ee15b09f6 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
@@ -22,6 +22,6 @@
status = "okay";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
index 3459b81c5628..a960553f3994 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
@@ -21,6 +21,6 @@
"qcom,sc7180";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
index ff8f47da109d..82bd9ed7e21a 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
@@ -25,6 +25,6 @@
status = "okay";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
index faf527972977..6278c1715d3f 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
@@ -18,6 +18,6 @@
compatible = "google,lazor-rev9-sku2", "qcom,sc7180";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
index d737fd0637fb..0ec1697ae2c9 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
@@ -22,6 +22,6 @@
status = "okay";
};
-&keyboard_backlight {
+&pwmleds {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
index e9f213d27711..c3fd6760de7a 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
@@ -5,8 +5,7 @@
* Copyright 2020 Google LLC.
*/
-/* This file must be included after sc7180-trogdor.dtsi */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
&ap_sar_sensor {
semtech,cs0-ground;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
index 8823edbb4d6e..cc2c5610a279 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
@@ -5,8 +5,7 @@
* Copyright 2021 Google LLC.
*/
-/* This file must be included after sc7180-trogdor.dtsi */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
&ap_sar_sensor {
compatible = "semtech,sx9324";
@@ -83,6 +82,8 @@
gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
};
+/* PINCTRL - modifications to sc7180-trogdor.dtsi */
+
&en_pp3300_dx_edp {
pins = "gpio67";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
index 067813f5f437..ac8d4589e3fb 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
@@ -6,17 +6,13 @@
*/
#include "sc7180-trogdor.dtsi"
-/* Must come after sc7180-trogdor.dtsi to modify cros_ec */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
/ {
thermal-zones {
5v-choke-thermal {
- polling-delay-passive = <0>;
- polling-delay = <250>;
-
thermal-sensors = <&pm6150_adc_tm 1>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
index 5f06842c683b..00229b1515e6 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
@@ -9,9 +9,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-rt5682i-sku.dtsi"
-
-/* This board only has 1 USB Type-C port. */
-/delete-node/ &usb_c1;
+#include "sc7180-trogdor-detachable.dtsi"
/ {
ppvar_lcd: ppvar-lcd-regulator {
@@ -47,12 +45,6 @@
status = "okay";
};
-&cros_ec {
- keyboard-controller {
- compatible = "google,cros-ec-keyb-switches";
- };
-};
-
&gpio_keys {
status = "okay";
};
@@ -136,6 +128,11 @@ pp3300_disp_on: &pp3300_dx_edp {
gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
};
+/* This board only has 1 USB Type-C port. */
+&usb_c1 {
+ status = "disabled";
+};
+
/* PINCTRL - modifications to sc7180-trogdor.dtsi */
/*
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
index c9667751a990..d393a2712ce6 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
@@ -8,8 +8,7 @@
/dts-v1/;
#include "sc7180-trogdor.dtsi"
-/* Must come after sc7180-trogdor.dtsi to modify cros_ec */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
index 305ad127246e..af89d80426ab 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
@@ -8,6 +8,7 @@
/dts-v1/;
#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
/ {
avdd_lcd: avdd-lcd-regulator {
@@ -50,7 +51,6 @@
thermal-zones {
skin_temp_thermal: skin-temp-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&pm6150_adc_tm 1>;
sustainable-power = <574>;
@@ -104,10 +104,6 @@
base_detection: cbas {
compatible = "google,cros-cbas";
};
-
- keyboard-controller {
- compatible = "google,cros-ec-keyb-switches";
- };
};
&i2c4 {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 5260c63db007..74ab321d3333 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -21,9 +21,6 @@
/ {
thermal-zones {
charger_thermal: charger-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm6150_adc_tm 0>;
trips {
@@ -359,10 +356,11 @@
#sound-dai-cells = <0>;
};
- pwmleds {
+ pwmleds: pwmleds {
compatible = "pwm-leds";
+ status = "disabled";
+
keyboard_backlight: led-0 {
- status = "disabled";
label = "cros_ec::kbd_backlight";
function = LED_FUNCTION_KBD_BACKLIGHT;
pwms = <&cros_ec_pwm 0>;
@@ -1167,6 +1165,7 @@ ap_spi_fp: &spi10 {
};
&pm6150l_gpios {
+ status = "disabled"; /* No GPIOs are consumed or configured */
gpio-line-names = "AP_SUSPEND",
"",
"",
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 2b481e20ae38..b5ebf8980325 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -1582,12 +1582,14 @@
};
ufs_mem_phy: phy@1d87000 {
- compatible = "qcom,sc7180-qmp-ufs-phy",
- "qcom,sm7150-qmp-ufs-phy";
+ compatible = "qcom,sc7180-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
- clock-names = "ref", "ref_aux";
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
power-domains = <&gcc UFS_PHY_GDSC>;
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -2309,6 +2311,7 @@
compatible = "qcom,sc7180-dcc", "qcom,dcc";
reg = <0x0 0x010a2000 0x0 0x1000>,
<0x0 0x010ae000 0x0 0x2000>;
+ status = "disabled";
};
stm@6002000 {
@@ -3063,6 +3066,7 @@
iommus = <&apps_smmu 0x540 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
+ snps,parkmode-disable-ss-quirk;
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
@@ -4032,7 +4036,6 @@
thermal-zones {
cpu0_thermal: cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
sustainable-power = <1052>;
@@ -4081,7 +4084,6 @@
cpu1_thermal: cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
sustainable-power = <1052>;
@@ -4130,7 +4132,6 @@
cpu2_thermal: cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
sustainable-power = <1052>;
@@ -4179,7 +4180,6 @@
cpu3_thermal: cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
sustainable-power = <1052>;
@@ -4228,7 +4228,6 @@
cpu4_thermal: cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
sustainable-power = <1052>;
@@ -4277,7 +4276,6 @@
cpu5_thermal: cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
sustainable-power = <1052>;
@@ -4326,7 +4324,6 @@
cpu6_thermal: cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
sustainable-power = <1425>;
@@ -4367,7 +4364,6 @@
cpu7_thermal: cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
sustainable-power = <1425>;
@@ -4408,7 +4404,6 @@
cpu8_thermal: cpu8-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
sustainable-power = <1425>;
@@ -4449,7 +4444,6 @@
cpu9_thermal: cpu9-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
sustainable-power = <1425>;
@@ -4490,7 +4484,6 @@
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 0>;
@@ -4511,7 +4504,6 @@
cpuss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
@@ -4531,7 +4523,6 @@
cpuss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
@@ -4551,7 +4542,6 @@
gpuss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 13>;
@@ -4579,7 +4569,6 @@
gpuss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 14>;
@@ -4607,7 +4596,6 @@
aoss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 0>;
@@ -4628,7 +4616,6 @@
cwlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
@@ -4649,7 +4636,6 @@
audio-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
@@ -4670,7 +4656,6 @@
ddr-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 3>;
@@ -4691,7 +4676,6 @@
q6-hvx-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 4>;
@@ -4712,7 +4696,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 5>;
@@ -4733,7 +4716,6 @@
mdm-core-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 6>;
@@ -4754,7 +4736,6 @@
mdm-dsp-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 7>;
@@ -4775,7 +4756,6 @@
npu-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 8>;
@@ -4796,7 +4776,6 @@
video-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 9>;
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
index a0059527d9e4..7370aa0dbf0e 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
@@ -495,7 +495,6 @@
};
&uart5 {
- compatible = "qcom,geni-debug-uart";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
index f9b96bd2477e..7d1d5bbbbbd9 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
@@ -427,7 +427,6 @@
};
uart_dbg: &uart5 {
- compatible = "qcom,geni-debug-uart";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 41f51d326111..3d8410683402 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -24,6 +24,7 @@
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/reset/qcom,sdm845-aoss.h>
#include <dt-bindings/reset/qcom,sdm845-pdc.h>
+#include <dt-bindings/soc/qcom,apr.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
#include <dt-bindings/sound/qcom,lpass.h>
#include <dt-bindings/thermal/thermal.h>
@@ -710,6 +711,7 @@
firmware {
scm: scm {
compatible = "qcom,scm-sc7280", "qcom,scm";
+ qcom,dload-mode = <&tcsr_2 0x13000>;
};
};
@@ -1440,12 +1442,12 @@
};
uart5: serial@994000 {
- compatible = "qcom,geni-uart";
+ compatible = "qcom,geni-debug-uart";
reg = <0 0x00994000 0 0x4000>;
clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
clock-names = "se";
pinctrl-names = "default";
- pinctrl-0 = <&qup_uart5_cts>, <&qup_uart5_rts>, <&qup_uart5_tx>, <&qup_uart5_rx>;
+ pinctrl-0 = <&qup_uart5_tx>, <&qup_uart5_rx>;
interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&rpmhpd SC7280_CX>;
operating-points-v2 = <&qup_opp_table>;
@@ -2129,6 +2131,8 @@
reg = <0 0x016e0000 0 0x1c080>;
#interconnect-cells = <2>;
qcom,bcm-voters = <&apps_bcm_voter>;
+ clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+ <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
};
aggre2_noc: interconnect@1700000 {
@@ -2136,6 +2140,7 @@
compatible = "qcom,sc7280-aggre2-noc";
#interconnect-cells = <2>;
qcom,bcm-voters = <&apps_bcm_voter>;
+ clocks = <&rpmhcc RPMH_IPA_CLK>;
};
mmss_noc: interconnect@1740000 {
@@ -2273,6 +2278,16 @@
<0x100 &apps_smmu 0x1c81 0x1>;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -2352,6 +2367,8 @@
<0 0>,
<0 0>,
<0 0>;
+ qcom,ice = <&ice>;
+
status = "disabled";
};
@@ -2374,6 +2391,13 @@
status = "disabled";
};
+ ice: crypto@1d88000 {
+ compatible = "qcom,sc7280-inline-crypto-engine",
+ "qcom,inline-crypto-engine";
+ reg = <0 0x01d88000 0 0x8000>;
+ clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+ };
+
cryptobam: dma-controller@1dc4000 {
compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
reg = <0x0 0x01dc4000 0x0 0x28000>;
@@ -2970,6 +2994,18 @@
dma-coherent;
};
+ gfx_0_tbu: tbu@3dd9000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x3dd9000 0x0 0x1000>;
+ qcom,stream-id-range = <&adreno_smmu 0x0 0x400>;
+ };
+
+ gfx_1_tbu: tbu@3ddd000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x3ddd000 0x0 0x1000>;
+ qcom,stream-id-range = <&adreno_smmu 0x400 0x400>;
+ };
+
remoteproc_mpss: remoteproc@4080000 {
compatible = "qcom,sc7280-mpss-pas";
reg = <0 0x04080000 0 0x10000>;
@@ -3743,6 +3779,75 @@
label = "lpass";
qcom,remote-pid = <2>;
+ apr {
+ compatible = "qcom,apr-v2";
+ qcom,glink-channels = "apr_audio_svc";
+ qcom,domain = <APR_DOMAIN_ADSP>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ service@3 {
+ reg = <APR_SVC_ADSP_CORE>;
+ compatible = "qcom,q6core";
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+ };
+
+ q6afe: service@4 {
+ compatible = "qcom,q6afe";
+ reg = <APR_SVC_AFE>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+ q6afedai: dais {
+ compatible = "qcom,q6afe-dais";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ };
+
+ q6afecc: clock-controller {
+ compatible = "qcom,q6afe-clocks";
+ #clock-cells = <2>;
+ };
+ };
+
+ q6asm: service@7 {
+ compatible = "qcom,q6asm";
+ reg = <APR_SVC_ASM>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+ q6asmdai: dais {
+ compatible = "qcom,q6asm-dais";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ iommus = <&apps_smmu 0x1801 0x0>;
+
+ dai@0 {
+ reg = <0>;
+ };
+
+ dai@1 {
+ reg = <1>;
+ };
+
+ dai@2 {
+ reg = <2>;
+ };
+ };
+ };
+
+ q6adm: service@8 {
+ compatible = "qcom,q6adm";
+ reg = <APR_SVC_ADM>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+ q6routing: routing {
+ compatible = "qcom,q6adm-routing";
+ #sound-dai-cells = <0>;
+ };
+ };
+ };
+
fastrpc {
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
@@ -4131,6 +4236,7 @@
iommus = <&apps_smmu 0xe0 0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
+ snps,parkmode-disable-ss-quirk;
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
@@ -4458,6 +4564,11 @@
opp-hz = /bits/ 64 <506666667>;
required-opps = <&rpmhpd_opp_nom>;
};
+
+ opp-608000000 {
+ opp-hz = /bits/ 64 <608000000>;
+ required-opps = <&rpmhpd_opp_turbo>;
+ };
};
};
@@ -5383,16 +5494,6 @@
function = "qup04";
};
- qup_uart5_cts: qup-uart5-cts-state {
- pins = "gpio20";
- function = "qup05";
- };
-
- qup_uart5_rts: qup-uart5-rts-state {
- pins = "gpio21";
- function = "qup05";
- };
-
qup_uart5_tx: qup-uart5-tx-state {
pins = "gpio22";
function = "qup05";
@@ -5778,6 +5879,83 @@
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
};
+ anoc_1_tbu: tbu@151dd000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151dd000 0x0 0x1000>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &cnoc3 SLAVE_TCU QCOM_ICC_TAG_ACTIVE_ONLY>;
+ qcom,stream-id-range = <&apps_smmu 0x0 0x400>;
+ };
+
+ anoc_2_tbu: tbu@151e1000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151e1000 0x0 0x1000>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &cnoc3 SLAVE_TCU QCOM_ICC_TAG_ACTIVE_ONLY>;
+ qcom,stream-id-range = <&apps_smmu 0x400 0x400>;
+ };
+
+ mnoc_hf_0_tbu: tbu@151e5000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151e5000 0x0 0x1000>;
+ interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x800 0x400>;
+ };
+
+ mnoc_hf_1_tbu: tbu@151e9000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151e9000 0x0 0x1000>;
+ interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0xc00 0x400>;
+ };
+
+ compute_dsp_1_tbu: tbu@151ed000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151ed000 0x0 0x1000>;
+ interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_TURING_MMU_TBU1_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x1000 0x400>;
+ };
+
+ compute_dsp_0_tbu: tbu@151f1000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151f1000 0x0 0x1000>;
+ interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_TURING_MMU_TBU0_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x1400 0x400>;
+ };
+
+ adsp_tbu: tbu@151f5000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151f5000 0x0 0x1000>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &lpass_ag_noc SLAVE_LPASS_CORE_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ qcom,stream-id-range = <&apps_smmu 0x1800 0x400>;
+ };
+
+ anoc_1_pcie_tbu: tbu@151f9000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151f9000 0x0 0x1000>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &cnoc3 SLAVE_TCU QCOM_ICC_TAG_ACTIVE_ONLY>;
+ qcom,stream-id-range = <&apps_smmu 0x1c00 0x400>;
+ };
+
+ mnoc_sf_0_tbu: tbu@151fd000 {
+ compatible = "qcom,sc7280-tbu";
+ reg = <0x0 0x151fd000 0x0 0x1000>;
+ interconnects = <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ACTIVE_ONLY
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x2000 0x400>;
+ };
+
intc: interrupt-controller@17a00000 {
compatible = "arm,gic-v3";
reg = <0 0x17a00000 0 0x10000>, /* GICD */
@@ -5967,10 +6145,12 @@
};
};
+ sound: sound {
+ };
+
thermal_zones: thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
@@ -6014,7 +6194,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
@@ -6058,7 +6237,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
@@ -6102,7 +6280,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
@@ -6146,7 +6323,6 @@
cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
@@ -6190,7 +6366,6 @@
cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
@@ -6234,7 +6409,6 @@
cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
@@ -6278,7 +6452,6 @@
cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
@@ -6322,7 +6495,6 @@
cpu8-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
@@ -6366,7 +6538,6 @@
cpu9-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
@@ -6410,7 +6581,6 @@
cpu10-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 13>;
@@ -6454,7 +6624,6 @@
cpu11-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 14>;
@@ -6498,7 +6667,6 @@
aoss0-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 0>;
@@ -6519,7 +6687,6 @@
aoss1-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 0>;
@@ -6540,7 +6707,6 @@
cpuss0-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
@@ -6560,7 +6726,6 @@
cpuss1-thermal {
polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
@@ -6580,7 +6745,6 @@
gpuss0-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
@@ -6608,7 +6772,6 @@
gpuss1-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
@@ -6635,9 +6798,6 @@
};
nspss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 3>;
trips {
@@ -6656,9 +6816,6 @@
};
nspss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 4>;
trips {
@@ -6677,9 +6834,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 5>;
trips {
@@ -6698,9 +6852,6 @@
};
ddr-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 6>;
trips {
@@ -6719,9 +6870,6 @@
};
mdmss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 7>;
trips {
@@ -6740,9 +6888,6 @@
};
mdmss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 8>;
trips {
@@ -6761,9 +6906,6 @@
};
mdmss2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 9>;
trips {
@@ -6782,9 +6924,6 @@
};
mdmss3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 10>;
trips {
@@ -6803,9 +6942,6 @@
};
camera0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 11>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
index 0c22f3efec20..5b226577f9d8 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
+++ b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
@@ -51,6 +51,8 @@
#address-cells = <1>;
#size-cells = <0>;
+ orientation-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>,
+ <&tlmm 58 GPIO_ACTIVE_HIGH>;
connector@0 {
compatible = "usb-c-connector";
@@ -66,7 +68,7 @@
reg = <0>;
pmic_glink_con0_hs: endpoint {
- remote-endpoint = <&usb_prim_role_switch>;
+ remote-endpoint = <&usb_prim_dwc3_hs>;
};
};
@@ -101,7 +103,7 @@
reg = <0>;
pmic_glink_con1_hs: endpoint {
- remote-endpoint = <&usb_sec_role_switch>;
+ remote-endpoint = <&usb_sec_dwc3_hs>;
};
};
@@ -329,12 +331,18 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
};
vreg_l10e_2p9: ldo10 {
regulator-min-microvolt = <2904000>;
regulator-max-microvolt = <2904000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
};
vreg_l16e_3p0: ldo16 {
@@ -350,49 +358,58 @@
zap-shader {
memory-region = <&gpu_mem>;
- firmware-name = "qcom/sc8180x/qcdxkmsuc8180.mbn";
+ firmware-name = "qcom/sc8180x/LENOVO/82AK/qcdxkmsuc8180.mbn";
};
};
&i2c1 {
clock-frequency = <100000>;
- pinctrl-0 = <&i2c1_active>, <&i2c1_hid_active>;
+ pinctrl-0 = <&i2c1_active>;
pinctrl-names = "default";
status = "okay";
- hid@10 {
+ touchscreen@10 {
compatible = "hid-over-i2c";
reg = <0x10>;
hid-descr-addr = <0x1>;
interrupts-extended = <&tlmm 122 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&ts_int_default>;
+ pinctrl-names = "default";
};
};
&i2c7 {
- clock-frequency = <100000>;
+ clock-frequency = <1000000>;
- pinctrl-0 = <&i2c7_active>, <&i2c7_hid_active>;
+ pinctrl-0 = <&i2c7_active>;
pinctrl-names = "default";
status = "okay";
- hid@5 {
+ keyboard@5 {
compatible = "hid-over-i2c";
reg = <0x5>;
hid-descr-addr = <0x20>;
interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&kb_int_default>;
+ pinctrl-names = "default";
};
- hid@2c {
+ touchpad@2c {
compatible = "hid-over-i2c";
reg = <0x2c>;
hid-descr-addr = <0x20>;
interrupts-extended = <&tlmm 24 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&tp_int_default>;
+ pinctrl-names = "default";
};
};
@@ -565,6 +582,10 @@
dr_mode = "host";
};
+&usb_prim_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con0_hs>;
+};
+
&usb_prim_qmpphy_dp_in {
remote-endpoint = <&mdss_dp0_out>;
};
@@ -573,8 +594,8 @@
remote-endpoint = <&pmic_glink_con0_ss>;
};
-&usb_prim_role_switch {
- remote-endpoint = <&pmic_glink_con0_hs>;
+&usb_sec_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con1_hs>;
};
&usb_sec_hsphy {
@@ -602,10 +623,6 @@
remote-endpoint = <&pmic_glink_con1_ss>;
};
-&usb_sec_role_switch {
- remote-endpoint = <&pmic_glink_con1_hs>;
-};
-
&usb_sec {
status = "okay";
};
@@ -669,14 +686,6 @@
drive-strength = <2>;
};
- i2c1_hid_active: i2c1-hid-active-state {
- pins = "gpio122";
- function = "gpio";
-
- bias-pull-up;
- drive-strength = <2>;
- };
-
i2c7_active: i2c7-active-state {
pins = "gpio98", "gpio99";
function = "qup7";
@@ -685,8 +694,8 @@
drive-strength = <2>;
};
- i2c7_hid_active: i2c7-hid-active-state {
- pins = "gpio37", "gpio24";
+ kb_int_default: kb-int-default-state {
+ pins = "gpio37";
function = "gpio";
bias-pull-up;
@@ -718,6 +727,22 @@
};
};
+ tp_int_default: tp-int-default-state {
+ pins = "gpio24";
+ function = "gpio";
+
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ ts_int_default: ts-int-default-state {
+ pins = "gpio122";
+ function = "gpio";
+
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
usbprim_sbu_default: usbprim-sbu-state {
oe-n-pins {
pins = "gpio152";
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-pmics.dtsi b/arch/arm64/boot/dts/qcom/sc8180x-pmics.dtsi
index ddc84282f142..1c6f12fafe1d 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8180x-pmics.dtsi
@@ -13,7 +13,6 @@
thermal-zones {
pmc8180-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmc8180_temp>;
@@ -40,7 +39,6 @@
pmc8180c-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
thermal-sensors = <&pmc8180c_temp>;
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
index bfee60c93ccc..65d923497a05 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
+++ b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
@@ -71,7 +71,7 @@
reg = <0>;
pmic_glink_con0_hs: endpoint {
- remote-endpoint = <&usb_prim_role_switch>;
+ remote-endpoint = <&usb_prim_dwc3_hs>;
};
};
@@ -106,7 +106,7 @@
reg = <0>;
pmic_glink_con1_hs: endpoint {
- remote-endpoint = <&usb_sec_role_switch>;
+ remote-endpoint = <&usb_sec_dwc3_hs>;
};
};
@@ -648,6 +648,10 @@
dr_mode = "host";
};
+&usb_prim_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con0_hs>;
+};
+
&usb_prim_qmpphy_dp_in {
remote-endpoint = <&mdss_dp0_out>;
};
@@ -656,10 +660,6 @@
remote-endpoint = <&pmic_glink_con0_ss>;
};
-&usb_prim_role_switch {
- remote-endpoint = <&pmic_glink_con0_hs>;
-};
-
&usb_sec_hsphy {
vdda-pll-supply = <&vreg_l5e_0p88>;
vdda18-supply = <&vreg_l12a_1p8>;
@@ -685,10 +685,6 @@
remote-endpoint = <&pmic_glink_con1_ss>;
};
-&usb_sec_role_switch {
- remote-endpoint = <&pmic_glink_con1_hs>;
-};
-
&usb_sec {
status = "okay";
};
@@ -697,6 +693,10 @@
dr_mode = "host";
};
+&usb_sec_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con1_hs>;
+};
+
&wifi {
memory-region = <&wlan_mem>;
diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
index 053f7861c3ce..6e707d993aeb 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sc8180x.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
#include <dt-bindings/thermal/thermal.h>
@@ -1777,6 +1778,16 @@
dma-coherent;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -1880,7 +1891,7 @@
power-domains = <&gcc PCIE_3_GDSC>;
interconnects = <&aggre2_noc MASTER_PCIE_3 0 &mc_virt SLAVE_EBI_CH0 0>,
- <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_3 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
phys = <&pcie3_phy>;
@@ -1888,6 +1899,16 @@
dma-coherent;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie3_phy: phy@1c0c000 {
@@ -1992,7 +2013,7 @@
power-domains = <&gcc PCIE_1_GDSC>;
interconnects = <&aggre2_noc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI_CH0 0>,
- <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_1 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
phys = <&pcie1_phy>;
@@ -2000,6 +2021,16 @@
dma-coherent;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c16000 {
@@ -2104,7 +2135,7 @@
power-domains = <&gcc PCIE_2_GDSC>;
interconnects = <&aggre2_noc MASTER_PCIE_2 0 &mc_virt SLAVE_EBI_CH0 0>,
- <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_2 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
phys = <&pcie2_phy>;
@@ -2112,6 +2143,16 @@
dma-coherent;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie2_phy: phy@1c1c000 {
@@ -2205,18 +2246,13 @@
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
#phy-cells = <0>;
status = "disabled";
};
- ipa_virt: interconnect@1e00000 {
- compatible = "qcom,sc8180x-ipa-virt";
- reg = <0 0x01e00000 0 0x1000>;
- #interconnect-cells = <2>;
- qcom,bcm-voters = <&apps_bcm_voter>;
- };
-
tcsr_mutex: hwlock@1f40000 {
compatible = "qcom,tcsr-mutex";
reg = <0x0 0x01f40000 0x0 0x40000>;
@@ -2225,7 +2261,6 @@
gpu: gpu@2c00000 {
compatible = "qcom,adreno-680.1", "qcom,adreno";
- #stream-id-cells = <16>;
reg = <0 0x02c00000 0 0x40000>;
reg-names = "kgsl_3d0_reg_memory";
@@ -2472,28 +2507,25 @@
status = "disabled";
};
- usb_prim_qmpphy: phy@88e9000 {
+ usb_prim_qmpphy: phy@88e8000 {
compatible = "qcom,sc8180x-qmp-usb3-dp-phy";
- reg = <0 0x088e9000 0 0x18c>,
- <0 0x088e8000 0 0x38>,
- <0 0x088ea000 0 0x40>;
- reg-names = "reg-base", "dp_com";
+ reg = <0 0x088e8000 0 0x3000>;
+
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
- <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_USB3_PRIM_CLKREF_CLK>,
- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
clock-names = "aux",
- "ref_clk_src",
"ref",
- "com_aux";
+ "com_aux",
+ "usb3_pipe";
+
resets = <&gcc GCC_USB3_DP_PHY_PRIM_SP0_BCR>,
<&gcc GCC_USB3_PHY_PRIM_SP0_BCR>;
reset-names = "phy", "common";
#clock-cells = <1>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ #phy-cells = <1>;
status = "disabled";
@@ -2507,59 +2539,40 @@
usb_prim_qmpphy_out: endpoint {};
};
+ port@1 {
+ reg = <1>;
+
+ usb_prim_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_prim_dwc3_ss>;
+ };
+ };
+
port@2 {
reg = <2>;
usb_prim_qmpphy_dp_in: endpoint {};
};
};
-
- usb_prim_ssphy: usb3-phy@88e9200 {
- reg = <0 0x088e9200 0 0x200>,
- <0 0x088e9400 0 0x200>,
- <0 0x088e9c00 0 0x218>,
- <0 0x088e9600 0 0x200>,
- <0 0x088e9800 0 0x200>,
- <0 0x088e9a00 0 0x100>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_prim_phy_pipe_clk_src";
- };
-
- usb_prim_dpphy: dp-phy@88ea200 {
- reg = <0 0x088ea200 0 0x200>,
- <0 0x088ea400 0 0x200>,
- <0 0x088eaa00 0 0x200>,
- <0 0x088ea600 0 0x200>,
- <0 0x088ea800 0 0x200>;
- #clock-cells = <1>;
- #phy-cells = <0>;
- };
};
usb_sec_qmpphy: phy@88ee000 {
compatible = "qcom,sc8180x-qmp-usb3-dp-phy";
- reg = <0 0x088ee000 0 0x18c>,
- <0 0x088ed000 0 0x10>,
- <0 0x088ef000 0 0x40>;
- reg-names = "reg-base", "dp_com";
+ reg = <0 0x088ed000 0 0x3000>;
+
clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>,
- <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_USB3_SEC_CLKREF_CLK>,
- <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>;
+ <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
clock-names = "aux",
- "ref_clk_src",
"ref",
- "com_aux";
+ "com_aux",
+ "usb3_pipe";
resets = <&gcc GCC_USB3_DP_PHY_SEC_BCR>,
<&gcc GCC_USB3_PHY_SEC_BCR>;
reset-names = "phy", "common";
#clock-cells = <1>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ #phy-cells = <1>;
status = "disabled";
@@ -2573,46 +2586,32 @@
usb_sec_qmpphy_out: endpoint {};
};
+ port@1 {
+ reg = <1>;
+
+ usb_sec_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_sec_dwc3_ss>;
+ };
+ };
+
port@2 {
reg = <2>;
usb_sec_qmpphy_dp_in: endpoint {};
};
};
-
- usb_sec_ssphy: usb3-phy@88e9200 {
- reg = <0 0x088ee200 0 0x200>,
- <0 0x088ee400 0 0x200>,
- <0 0x088eec00 0 0x218>,
- <0 0x088ee600 0 0x200>,
- <0 0x088ee800 0 0x200>,
- <0 0x088eea00 0 0x100>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_sec_phy_pipe_clk_src";
- };
-
- usb_sec_dpphy: dp-phy@88ef200 {
- reg = <0 0x088ef200 0 0x200>,
- <0 0x088ef400 0 0x200>,
- <0 0x088efa00 0 0x200>,
- <0 0x088ef600 0 0x200>,
- <0 0x088ef800 0 0x200>;
- #clock-cells = <1>;
- #phy-cells = <0>;
- clock-output-names = "qmp_dptx1_phy_pll_link_clk",
- "qmp_dptx1_phy_pll_vco_div_clk";
- };
};
system-cache-controller@9200000 {
compatible = "qcom,sc8180x-llcc";
- reg = <0 0x09200000 0 0x50000>, <0 0x09280000 0 0x50000>,
- <0 0x09300000 0 0x50000>, <0 0x09380000 0 0x50000>,
- <0 0x09600000 0 0x50000>;
+ reg = <0 0x09200000 0 0x58000>, <0 0x09280000 0 0x58000>,
+ <0 0x09300000 0 0x58000>, <0 0x09380000 0 0x58000>,
+ <0 0x09400000 0 0x58000>, <0 0x09480000 0 0x58000>,
+ <0 0x09500000 0 0x58000>, <0 0x09580000 0 0x58000>,
+ <0 0x09600000 0 0x58000>;
reg-names = "llcc0_base", "llcc1_base", "llcc2_base",
- "llcc3_base", "llcc_broadcast_base";
+ "llcc3_base", "llcc4_base", "llcc5_base",
+ "llcc6_base", "llcc7_base", "llcc_broadcast_base";
interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -2672,11 +2671,26 @@
iommus = <&apps_smmu 0x140 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_prim_hsphy>, <&usb_prim_ssphy>;
+ phys = <&usb_prim_hsphy>, <&usb_prim_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
- port {
- usb_prim_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_prim_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_prim_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_prim_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -2729,11 +2743,26 @@
iommus = <&apps_smmu 0x160 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_sec_hsphy>, <&usb_sec_ssphy>;
+ phys = <&usb_sec_hsphy>, <&usb_sec_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
- port {
- usb_sec_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_sec_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_sec_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_sec_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -2805,7 +2834,7 @@
power-domains = <&rpmhpd SC8180X_MMCX>;
interrupt-parent = <&mdss>;
- interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <0>;
ports {
#address-cells = <1>;
@@ -2878,7 +2907,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>,
@@ -2964,7 +2993,7 @@
reg-names = "dsi_ctrl";
interrupt-parent = <&mdss>;
- interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <5>;
clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
<&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
@@ -3030,7 +3059,8 @@
reg = <0 0xae90000 0 0x200>,
<0 0xae90200 0 0x200>,
<0 0xae90400 0 0x600>,
- <0 0xae90a00 0 0x400>;
+ <0 0xae90a00 0 0x400>,
+ <0 0xae91000 0 0x400>;
interrupt-parent = <&mdss>;
interrupts = <12>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
@@ -3046,9 +3076,10 @@
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
- assigned-clock-parents = <&usb_prim_dpphy 0>, <&usb_prim_dpphy 1>;
+ assigned-clock-parents = <&usb_prim_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_prim_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
- phys = <&usb_prim_dpphy>;
+ phys = <&usb_prim_qmpphy QMP_USB43DP_DP_PHY>;
phy-names = "dp";
#sound-dai-cells = <0>;
@@ -3106,7 +3137,8 @@
reg = <0 0xae98000 0 0x200>,
<0 0xae98200 0 0x200>,
<0 0xae98400 0 0x600>,
- <0 0xae98a00 0 0x400>;
+ <0 0xae98a00 0 0x400>,
+ <0 0xae99000 0 0x400>;
interrupt-parent = <&mdss>;
interrupts = <13>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
@@ -3122,9 +3154,10 @@
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK1_CLK_SRC>,
<&dispcc DISP_CC_MDSS_DP_PIXEL2_CLK_SRC>;
- assigned-clock-parents = <&usb_sec_dpphy 0>, <&usb_sec_dpphy 1>;
+ assigned-clock-parents = <&usb_sec_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_sec_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
- phys = <&usb_sec_dpphy>;
+ phys = <&usb_sec_qmpphy QMP_USB43DP_DP_PHY>;
phy-names = "dp";
#sound-dai-cells = <0>;
@@ -3267,21 +3300,27 @@
compatible = "qcom,sc8180x-dispcc";
reg = <0 0x0af00000 0 0x20000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
- <&sleep_clk>,
- <&usb_prim_dpphy 0>,
- <&usb_prim_dpphy 1>,
- <&usb_sec_dpphy 0>,
- <&usb_sec_dpphy 1>,
+ <&mdss_dsi0_phy 0>,
+ <&mdss_dsi0_phy 1>,
+ <&mdss_dsi1_phy 0>,
+ <&mdss_dsi1_phy 1>,
+ <&usb_prim_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_prim_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>,
<&edp_phy 0>,
- <&edp_phy 1>;
+ <&edp_phy 1>,
+ <&usb_sec_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_sec_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
clock-names = "bi_tcxo",
- "sleep_clk",
+ "dsi0_phy_pll_out_byteclk",
+ "dsi0_phy_pll_out_dsiclk",
+ "dsi1_phy_pll_out_byteclk",
+ "dsi1_phy_pll_out_dsiclk",
"dp_phy_pll_link_clk",
"dp_phy_pll_vco_div_clk",
- "dptx1_phy_pll_link_clk",
- "dptx1_phy_pll_vco_div_clk",
"edp_phy_pll_link_clk",
- "edp_phy_pll_vco_div_clk";
+ "edp_phy_pll_vco_div_clk",
+ "dptx1_phy_pll_link_clk",
+ "dptx1_phy_pll_vco_div_clk";
power-domains = <&rpmhpd SC8180X_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
#clock-cells = <1>;
@@ -3327,7 +3366,6 @@
mboxes = <&apss_shared 0>;
#clock-cells = <0>;
- #power-domain-cells = <1>;
};
sram@c3f0000 {
@@ -3730,7 +3768,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -3745,7 +3782,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -3760,7 +3796,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -3775,7 +3810,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -3790,7 +3824,6 @@
cpu4-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -3805,7 +3838,6 @@
cpu5-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -3820,7 +3852,6 @@
cpu6-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -3835,7 +3866,6 @@
cpu7-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -3850,7 +3880,6 @@
cpu4-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 11>;
@@ -3865,7 +3894,6 @@
cpu5-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -3880,7 +3908,6 @@
cpu6-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 13>;
@@ -3895,7 +3922,6 @@
cpu7-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 14>;
@@ -3910,7 +3936,6 @@
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 0>;
@@ -3925,7 +3950,6 @@
cluster0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -3940,7 +3964,6 @@
cluster1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -3955,7 +3978,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 15>;
@@ -3968,16 +3990,27 @@
trips {
gpu_top_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
aoss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 0>;
@@ -3992,7 +4025,6 @@
wlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -4007,7 +4039,6 @@
video-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -4022,7 +4053,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -4037,7 +4067,6 @@
q6-hvx-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
@@ -4052,7 +4081,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 5>;
@@ -4067,7 +4095,6 @@
compute-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -4082,7 +4109,6 @@
mdm-dsp-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 7>;
@@ -4097,7 +4123,6 @@
npu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 8>;
@@ -4112,7 +4137,6 @@
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 11>;
@@ -4125,10 +4149,22 @@
trips {
gpu_bottom_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
index 41215567b3ae..b98b2f7752b5 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
@@ -56,7 +56,7 @@
reg = <0>;
pmic_glink_con0_hs: endpoint {
- remote-endpoint = <&usb_0_role_switch>;
+ remote-endpoint = <&usb_0_dwc3_hs>;
};
};
@@ -91,7 +91,7 @@
reg = <0>;
pmic_glink_con1_hs: endpoint {
- remote-endpoint = <&usb_1_role_switch>;
+ remote-endpoint = <&usb_1_dwc3_hs>;
};
};
@@ -675,6 +675,10 @@
dr_mode = "host";
};
+&usb_0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con0_hs>;
+};
+
&usb_0_hsphy {
vdda-pll-supply = <&vreg_l9d>;
vdda18-supply = <&vreg_l1c>;
@@ -700,10 +704,6 @@
remote-endpoint = <&pmic_glink_con0_ss>;
};
-&usb_0_role_switch {
- remote-endpoint = <&pmic_glink_con0_hs>;
-};
-
&usb_1 {
status = "okay";
};
@@ -712,6 +712,10 @@
dr_mode = "host";
};
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con1_hs>;
+};
+
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l4b>;
vdda18-supply = <&vreg_l1c>;
@@ -737,10 +741,6 @@
remote-endpoint = <&pmic_glink_con1_ss>;
};
-&usb_1_role_switch {
- remote-endpoint = <&pmic_glink_con1_hs>;
-};
-
&xo_board_clk {
clock-frequency = <38400000>;
};
@@ -977,8 +977,7 @@
reset-n-pins {
pins = "gpio99";
function = "gpio";
- output-high;
- drive-strength = <16>;
+ bias-disable;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
index 15ae94c1602d..b27143f81867 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
@@ -100,6 +100,8 @@
#address-cells = <1>;
#size-cells = <0>;
+ orientation-gpios = <&tlmm 166 GPIO_ACTIVE_HIGH>,
+ <&tlmm 49 GPIO_ACTIVE_HIGH>;
connector@0 {
compatible = "usb-c-connector";
@@ -115,7 +117,7 @@
reg = <0>;
pmic_glink_con0_hs: endpoint {
- remote-endpoint = <&usb_0_role_switch>;
+ remote-endpoint = <&usb_0_dwc3_hs>;
};
};
@@ -150,7 +152,7 @@
reg = <0>;
pmic_glink_con1_hs: endpoint {
- remote-endpoint = <&usb_1_role_switch>;
+ remote-endpoint = <&usb_1_dwc3_hs>;
};
};
@@ -295,9 +297,30 @@
};
thermal-zones {
+ pm8008-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&pm8008>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
skin-temp-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8280_adc_tm 5>;
trips {
@@ -414,6 +437,13 @@
regulator-always-on;
};
+ vreg_l1b: ldo1 {
+ regulator-name = "vreg_l1b";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
vreg_l3b: ldo3 {
regulator-name = "vreg_l3b";
regulator-min-microvolt = <1200000>;
@@ -464,6 +494,13 @@
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
+ vreg_l8c: ldo8 {
+ regulator-name = "vreg_l8c";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
vreg_l12c: ldo12 {
regulator-name = "vreg_l12c";
regulator-min-microvolt = <1800000>;
@@ -497,6 +534,13 @@
vdd-l6-l9-l10-supply = <&vreg_s12b>;
vdd-l8-supply = <&vreg_s12b>;
+ vreg_l2d: ldo2 {
+ regulator-name = "vreg_l2d";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
vreg_l3d: ldo3 {
regulator-name = "vreg_l3d";
regulator-min-microvolt = <1200000>;
@@ -525,12 +569,26 @@
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
+ vreg_l8d: ldo8 {
+ regulator-name = "vreg_l8d";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
vreg_l9d: ldo9 {
regulator-name = "vreg_l9d";
regulator-min-microvolt = <912000>;
regulator-max-microvolt = <912000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
+
+ vreg_l10d: ldo10 {
+ regulator-name = "vreg_l10d";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
};
};
@@ -618,21 +676,101 @@
status = "okay";
- /* FIXME: verify */
touchscreen@10 {
- compatible = "hid-over-i2c";
+ compatible = "elan,ekth5015m", "elan,ekth6915";
reg = <0x10>;
- hid-descr-addr = <0x1>;
interrupts-extended = <&tlmm 175 IRQ_TYPE_LEVEL_LOW>;
- vdd-supply = <&vreg_misc_3p3>;
- vddl-supply = <&vreg_s10b>;
+ reset-gpios = <&tlmm 99 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+ no-reset-on-power-off;
+
+ vcc33-supply = <&vreg_misc_3p3>;
+ vccio-supply = <&vreg_misc_3p3>;
pinctrl-names = "default";
pinctrl-0 = <&ts0_default>;
};
};
+&i2c11 {
+ clock-frequency = <400000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c11_default>;
+
+ status = "okay";
+
+ pm8008: pmic@c {
+ compatible = "qcom,pm8008";
+ reg = <0xc>;
+
+ interrupts-extended = <&tlmm 41 IRQ_TYPE_EDGE_RISING>;
+ reset-gpios = <&tlmm 42 GPIO_ACTIVE_LOW>;
+
+ vdd-l1-l2-supply = <&vreg_s11b>;
+ vdd-l3-l4-supply = <&vreg_bob>;
+ vdd-l5-supply = <&vreg_bob>;
+ vdd-l6-supply = <&vreg_bob>;
+ vdd-l7-supply = <&vreg_bob>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm8008_default>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pm8008 0 0 2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ #thermal-sensor-cells = <0>;
+
+ regulators {
+ vreg_l1q: ldo1 {
+ regulator-name = "vreg_l1q";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l2q: ldo2 {
+ regulator-name = "vreg_l2q";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l3q: ldo3 {
+ regulator-name = "vreg_l3q";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vreg_l4q: ldo4 {
+ regulator-name = "vreg_l4q";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vreg_l5q: ldo5 {
+ regulator-name = "vreg_l5q";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vreg_l6q: ldo6 {
+ regulator-name = "vreg_l6q";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vreg_l7q: ldo7 {
+ regulator-name = "vreg_l7q";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
+ };
+};
+
&i2c21 {
clock-frequency = <400000>;
@@ -731,22 +869,14 @@
pinctrl-0 = <&pcie4_default>;
status = "okay";
+};
- pcie@0 {
- device_type = "pci";
- reg = <0x0 0x0 0x0 0x0 0x0>;
- #address-cells = <3>;
- #size-cells = <2>;
- ranges;
-
- bus-range = <0x01 0xff>;
-
- wifi@0 {
- compatible = "pci17cb,1103";
- reg = <0x10000 0x0 0x0 0x0 0x0>;
+&pcie4_port0 {
+ wifi@0 {
+ compatible = "pci17cb,1103";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
- qcom,ath11k-calibration-variant = "LE_X13S";
- };
+ qcom,ath11k-calibration-variant = "LE_X13S";
};
};
@@ -1102,6 +1232,10 @@
dr_mode = "host";
};
+&usb_0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con0_hs>;
+};
+
&usb_0_hsphy {
vdda-pll-supply = <&vreg_l9d>;
vdda18-supply = <&vreg_l1c>;
@@ -1127,10 +1261,6 @@
remote-endpoint = <&pmic_glink_con0_ss>;
};
-&usb_0_role_switch {
- remote-endpoint = <&pmic_glink_con0_hs>;
-};
-
&usb_1 {
status = "okay";
};
@@ -1139,6 +1269,10 @@
dr_mode = "host";
};
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_con1_hs>;
+};
+
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l4b>;
vdda18-supply = <&vreg_l1c>;
@@ -1164,8 +1298,54 @@
remote-endpoint = <&pmic_glink_con1_ss>;
};
-&usb_1_role_switch {
- remote-endpoint = <&pmic_glink_con1_hs>;
+&usb_2 {
+ status = "okay";
+};
+
+&usb_2_hsphy0 {
+ vdda-pll-supply = <&vreg_l1b>;
+ vdda18-supply = <&vreg_l1c>;
+ vdda33-supply = <&vreg_l7d>;
+
+ status = "okay";
+};
+
+&usb_2_hsphy1 {
+ vdda-pll-supply = <&vreg_l8d>;
+ vdda18-supply = <&vreg_l1c>;
+ vdda33-supply = <&vreg_l7d>;
+
+ status = "okay";
+};
+
+&usb_2_hsphy2 {
+ vdda-pll-supply = <&vreg_l10d>;
+ vdda18-supply = <&vreg_l8c>;
+ vdda33-supply = <&vreg_l2d>;
+
+ status = "okay";
+};
+
+&usb_2_hsphy3 {
+ vdda-pll-supply = <&vreg_l10d>;
+ vdda18-supply = <&vreg_l8c>;
+ vdda33-supply = <&vreg_l2d>;
+
+ status = "okay";
+};
+
+&usb_2_qmpphy0 {
+ vdda-phy-supply = <&vreg_l1b>;
+ vdda-pll-supply = <&vreg_l4d>;
+
+ status = "okay";
+};
+
+&usb_2_qmpphy1 {
+ vdda-phy-supply = <&vreg_l8d>;
+ vdda-pll-supply = <&vreg_l4d>;
+
+ status = "okay";
};
&vamacro {
@@ -1276,6 +1456,13 @@
bias-disable;
};
+ i2c11_default: i2c11-default-state {
+ pins = "gpio18", "gpio19";
+ function = "qup11";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
i2c21_default: i2c21-default-state {
pins = "gpio81", "gpio82";
function = "qup21";
@@ -1379,6 +1566,22 @@
};
};
+ pm8008_default: pm8008-default-state {
+ int-pins {
+ pins = "gpio41";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ reset-n-pins {
+ pins = "gpio42";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
spkr_1_sd_n_default: spkr-1-sd-n-default-state {
perst-n-pins {
pins = "gpio178";
@@ -1417,8 +1620,8 @@
reset-n-pins {
pins = "gpio99";
function = "gpio";
- output-high;
- drive-strength = <16>;
+ drive-strength = <2>;
+ bias-disable;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
index 945de77911de..1e3babf2e40d 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
@@ -14,7 +14,7 @@
thermal-zones {
pm8280_1_thermal: pm8280-1-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm8280_1_temp_alarm>;
trips {
@@ -34,7 +34,7 @@
pm8280_2_thermal: pm8280-2-thermal {
polling-delay-passive = <100>;
- polling-delay = <0>;
+
thermal-sensors = <&pm8280_2_temp_alarm>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
index d0f82e12289e..80a57aa22839 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
@@ -50,7 +50,8 @@
reg = <0x0 0x0>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- capacity-dmips-mhz = <602>;
+ capacity-dmips-mhz = <981>;
+ dynamic-power-coefficient = <549>;
next-level-cache = <&L2_0>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
@@ -77,7 +78,8 @@
reg = <0x0 0x100>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- capacity-dmips-mhz = <602>;
+ capacity-dmips-mhz = <981>;
+ dynamic-power-coefficient = <549>;
next-level-cache = <&L2_100>;
power-domains = <&CPU_PD1>;
power-domain-names = "psci";
@@ -99,7 +101,8 @@
reg = <0x0 0x200>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- capacity-dmips-mhz = <602>;
+ capacity-dmips-mhz = <981>;
+ dynamic-power-coefficient = <549>;
next-level-cache = <&L2_200>;
power-domains = <&CPU_PD2>;
power-domain-names = "psci";
@@ -121,7 +124,8 @@
reg = <0x0 0x300>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- capacity-dmips-mhz = <602>;
+ capacity-dmips-mhz = <981>;
+ dynamic-power-coefficient = <549>;
next-level-cache = <&L2_300>;
power-domains = <&CPU_PD3>;
power-domain-names = "psci";
@@ -144,6 +148,7 @@
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <590>;
next-level-cache = <&L2_400>;
power-domains = <&CPU_PD4>;
power-domain-names = "psci";
@@ -166,6 +171,7 @@
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <590>;
next-level-cache = <&L2_500>;
power-domains = <&CPU_PD5>;
power-domain-names = "psci";
@@ -188,6 +194,7 @@
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <590>;
next-level-cache = <&L2_600>;
power-domains = <&CPU_PD6>;
power-domain-names = "psci";
@@ -210,6 +217,7 @@
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <590>;
next-level-cache = <&L2_700>;
power-domains = <&CPU_PD7>;
power-domain-names = "psci";
@@ -300,6 +308,7 @@
scm: scm {
compatible = "qcom,scm-sc8280xp", "qcom,scm";
interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
+ qcom,dload-mode = <&tcsr 0x13000>;
};
};
@@ -862,6 +871,18 @@
#mbox-cells = <2>;
};
+ qfprom: efuse@784000 {
+ compatible = "qcom,sc8280xp-qfprom", "qcom,qfprom";
+ reg = <0 0x00784000 0 0x3000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gpu_speed_bin: gpu-speed-bin@18b {
+ reg = <0x18b 0x1>;
+ bits = <5 3>;
+ };
+ };
+
qup2: geniqup@8c0000 {
compatible = "qcom,geni-se-qup";
reg = <0 0x008c0000 0 0x2000>;
@@ -1731,6 +1752,8 @@
linux,pci-domain = <6>;
num-lanes = <1>;
+ msi-map = <0x0 &its 0xe0000 0x10000>;
+
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
@@ -1780,6 +1803,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie4_port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie4_phy: phy@1c06000 {
@@ -1832,6 +1865,8 @@
linux,pci-domain = <5>;
num-lanes = <2>;
+ msi-map = <0x0 &its 0xd0000 0x10000>;
+
interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
@@ -1879,6 +1914,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie3b_port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie3b_phy: phy@1c0e000 {
@@ -1931,6 +1976,8 @@
linux,pci-domain = <4>;
num-lanes = <4>;
+ msi-map = <0x0 &its 0xc0000 0x10000>;
+
interrupts = <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
@@ -1978,6 +2025,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie3a_port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie3a_phy: phy@1c14000 {
@@ -2033,6 +2090,8 @@
linux,pci-domain = <3>;
num-lanes = <2>;
+ msi-map = <0x0 &its 0xb0000 0x10000>;
+
interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
@@ -2080,6 +2139,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie2b_port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie2b_phy: phy@1c1e000 {
@@ -2132,6 +2201,8 @@
linux,pci-domain = <2>;
num-lanes = <4>;
+ msi-map = <0x0 &its 0xa0000 0x10000>;
+
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 523 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 524 IRQ_TYPE_LEVEL_HIGH>,
@@ -2179,6 +2250,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie2a_port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie2a_phy: phy@1c24000 {
@@ -3141,6 +3222,14 @@
usb_0_qmpphy_out: endpoint {};
};
+ port@1 {
+ reg = <1>;
+
+ usb_0_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_0_dwc3_ss>;
+ };
+ };
+
port@2 {
reg = <2>;
@@ -3194,6 +3283,14 @@
usb_1_qmpphy_out: endpoint {};
};
+ port@1 {
+ reg = <1>;
+
+ usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
+ };
+ };
+
port@2 {
reg = <2>;
@@ -3342,6 +3439,88 @@
interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
};
+ usb_2: usb@a4f8800 {
+ compatible = "qcom,sc8280xp-dwc3-mp", "qcom,dwc3";
+ reg = <0 0x0a4f8800 0 0x400>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_MP_AXI_CLK>,
+ <&gcc GCC_USB30_MP_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_MP_AXI_CLK>,
+ <&gcc GCC_USB30_MP_SLEEP_CLK>,
+ <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_NORTH_AXI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_SOUTH_AXI_CLK>,
+ <&gcc GCC_SYS_NOC_USB_AXI_CLK>;
+ clock-names = "cfg_noc", "core", "iface", "sleep", "mock_utmi",
+ "noc_aggr", "noc_aggr_north", "noc_aggr_south", "noc_sys";
+
+ assigned-clocks = <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_MP_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 857 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 859 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 127 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 126 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 129 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 128 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 131 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 130 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 133 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 132 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+
+ interrupt-names = "pwr_event_1", "pwr_event_2",
+ "pwr_event_3", "pwr_event_4",
+ "hs_phy_1", "hs_phy_2",
+ "hs_phy_3", "hs_phy_4",
+ "dp_hs_phy_1", "dm_hs_phy_1",
+ "dp_hs_phy_2", "dm_hs_phy_2",
+ "dp_hs_phy_3", "dm_hs_phy_3",
+ "dp_hs_phy_4", "dm_hs_phy_4",
+ "ss_phy_1", "ss_phy_2";
+
+ power-domains = <&gcc USB30_MP_GDSC>;
+ required-opps = <&rpmhpd_opp_nom>;
+
+ resets = <&gcc GCC_USB30_MP_BCR>;
+
+ interconnects = <&aggre1_noc MASTER_USB3_MP 0 &mc_virt SLAVE_EBI1 0>,
+ <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_MP 0>;
+ interconnect-names = "usb-ddr", "apps-usb";
+
+ wakeup-source;
+
+ status = "disabled";
+
+ usb_2_dwc3: usb@a400000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a400000 0 0xcd00>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&apps_smmu 0x800 0x0>;
+ phys = <&usb_2_hsphy0>, <&usb_2_qmpphy0>,
+ <&usb_2_hsphy1>, <&usb_2_qmpphy1>,
+ <&usb_2_hsphy2>,
+ <&usb_2_hsphy3>;
+ phy-names = "usb2-0", "usb3-0",
+ "usb2-1", "usb3-1",
+ "usb2-2",
+ "usb2-3";
+ dr_mode = "host";
+ };
+ };
+
usb_0: usb@a6f8800 {
compatible = "qcom,sc8280xp-dwc3", "qcom,dwc3";
reg = <0 0x0a6f8800 0 0x400>;
@@ -3366,10 +3545,12 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 804 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 805 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 14 IRQ_TYPE_EDGE_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
<&pdc 138 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq",
"ss_phy_irq";
@@ -3395,8 +3576,23 @@
phys = <&usb_0_hsphy>, <&usb_0_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
- port {
- usb_0_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_0_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_0_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_0_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -3426,10 +3622,12 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 811 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 790 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 12 IRQ_TYPE_EDGE_BOTH>,
<&pdc 13 IRQ_TYPE_EDGE_BOTH>,
<&pdc 136 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq",
"ss_phy_irq";
@@ -3455,8 +3653,23 @@
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
- port {
- usb_1_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -4453,6 +4666,13 @@
#thermal-sensor-cells = <1>;
};
+ restart@c264000 {
+ compatible = "qcom,pshold";
+ reg = <0 0x0c264000 0 0x4>;
+ /* TZ seems to block access */
+ status = "reserved";
+ };
+
tsens1: thermal-sensor@c265000 {
compatible = "qcom,sc8280xp-tsens", "qcom,tsens-v2";
reg = <0 0x0c265000 0 0x1ff>, /* TM */
@@ -4804,7 +5024,7 @@
#size-cells = <2>;
ranges;
- msi-controller@17a40000 {
+ its: msi-controller@17a40000 {
compatible = "arm,gic-v3-its";
reg = <0 0x17a40000 0 0x20000>;
msi-controller;
@@ -4971,6 +5191,11 @@
<0 0x18592000 0 0x1000>;
reg-names = "freq-domain0", "freq-domain1";
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dcvsh-irq-0",
+ "dcvsh-irq-1";
+
clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
clock-names = "xo", "alternate";
@@ -5654,7 +5879,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -5669,7 +5893,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -5684,7 +5907,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -5699,7 +5921,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -5714,7 +5935,6 @@
cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -5729,7 +5949,6 @@
cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -5744,7 +5963,6 @@
cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -5759,7 +5977,6 @@
cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -5774,7 +5991,6 @@
cluster0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -5788,13 +6004,25 @@
};
gpu-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ polling-delay-passive = <250>;
thermal-sensors = <&tsens2 2>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu-crit {
+ gpu_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -5804,7 +6032,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 15>;
diff --git a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
index 702ab49bbc59..60412281ab27 100644
--- a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
+++ b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
@@ -96,6 +96,18 @@
vin-supply = <&vph_pwr>;
};
+
+ /*
+ * this is also used for APC1 CPU power, touching it resets the board
+ */
+ vreg_l10a_1p8: vreg-l10a-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_l10a_1p8";
+ regulator-min-microvolt = <1804000>;
+ regulator-max-microvolt = <1896000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&adsp_pil {
@@ -220,6 +232,7 @@
status = "okay";
vdd-supply = <&vreg_l1b_0p925>;
+ vdda-pll-supply = <&vreg_l10a_1p8>;
vdda-phy-dpdm-supply = <&vreg_l7b_3p125>;
};
@@ -227,6 +240,7 @@
status = "okay";
vdd-supply = <&vreg_l1b_0p925>;
+ vdda-pll-supply = <&vreg_l10a_1p8>;
vdda-phy-dpdm-supply = <&vreg_l7b_3p125>;
};
@@ -464,5 +478,6 @@
&usb3_qmpphy {
vdda-phy-supply = <&vreg_l1b_0p925>;
+ vdda-pll-supply = <&vreg_l10a_1p8>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-lenovo-tbx605f.dts b/arch/arm64/boot/dts/qcom/sdm450-lenovo-tbx605f.dts
new file mode 100644
index 000000000000..175befc02b22
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm450-lenovo-tbx605f.dts
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Neil Armstrong <neil.armstrong@linaro.org>
+ */
+/dts-v1/;
+
+#include "sdm450.dtsi"
+#include "pm8953.dtsi"
+#include "pmi8950.dtsi"
+
+/ {
+ model = "Lenovo Smart Tab M10";
+ compatible = "lenovo,tbx605f", "qcom,sdm450";
+ chassis-type = "tablet";
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ framebuffer@90001000 {
+ compatible = "simple-framebuffer";
+ reg = <0 0x90001000 0 (1200 * 1920 * 3)>;
+
+ width = <1200>;
+ height = <1920>;
+ stride = <(1200 * 3)>;
+ format = "r8g8b8";
+
+ power-domains = <&gcc MDSS_GDSC>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_VSYNC_CLK>,
+ <&gcc GCC_MDSS_MDP_CLK>,
+ <&gcc GCC_MDSS_BYTE0_CLK>,
+ <&gcc GCC_MDSS_PCLK0_CLK>,
+ <&gcc GCC_MDSS_ESC0_CLK>;
+ };
+ };
+
+ reserved-memory {
+ other_ext_region@0 {
+ no-map;
+ reg = <0x00 0x84500000 0x00 0x2300000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ key-volume-up {
+ label = "volume_up";
+ gpios = <&tlmm 85 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&hsusb_phy {
+ vdd-supply = <&pm8953_l3>;
+ vdda-pll-supply = <&pm8953_l7>;
+ vdda-phy-dpdm-supply = <&pm8953_l13>;
+
+ status = "okay";
+};
+
+&i2c_3 {
+ status = "okay";
+
+ touchscreen@38 {
+ compatible = "edt,edt-ft5506";
+ reg = <0x38>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <65 IRQ_TYPE_EDGE_FALLING>;
+ vcc-supply = <&pm8953_l10>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_int_active &ts_reset_active>;
+
+ reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <1200>;
+ touchscreen-size-y = <1920>;
+ };
+};
+
+&pm8953_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8953-regulators";
+
+ 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_l1-supply = <&pm8953_s3>;
+ vdd_l2_l3-supply = <&pm8953_s3>;
+ vdd_l4_l5_l6_l7_l16_l19-supply = <&pm8953_s4>;
+ vdd_l8_l11_l12_l13_l14_l15-supply = <&vph_pwr>;
+ vdd_l9_l10_l17_l18_l22-supply = <&vph_pwr>;
+
+ pm8953_s1: s1 {
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <1156000>;
+ };
+
+ pm8953_s3: s3 {
+ regulator-min-microvolt = <1224000>;
+ regulator-max-microvolt = <1224000>;
+ };
+
+ pm8953_s4: s4 {
+ regulator-min-microvolt = <1900000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8953_l1: l1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ pm8953_l2: l2 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8953_l3: l3 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <925000>;
+ };
+
+ pm8953_l5: l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8953_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8953_l7: l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1900000>;
+ };
+
+ pm8953_l8: l8 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ pm8953_l9: l9 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8953_l10: l10 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8953_l11: l11 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8953_l12: l12 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8953_l13: l13 {
+ regulator-min-microvolt = <3125000>;
+ regulator-max-microvolt = <3125000>;
+ };
+
+ pm8953_l16: l16 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8953_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8953_l19: l19 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8953_l22: l22 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8953_l23: l23 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1225000>;
+ };
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8953_l8>;
+ vqmmc-supply = <&pm8953_l5>;
+
+ status = "okay";
+};
+
+&sdhc_2 {
+ vmmc-supply = <&pm8953_l11>;
+ vqmmc-supply = <&pm8953_l12>;
+
+ cd-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_off>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ status = "okay";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <0 4>, <135 4>;
+
+ ts_int_active: ts-int-active-state {
+ pins = "gpio65";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ ts_reset_active: ts-reset-active-state {
+ pins = "gpio64";
+ function = "gpio";
+ drive-strength = <0x08>;
+ bias-pull-up;
+ };
+};
+
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&wcnss {
+ vddpx-supply = <&pm8953_l5>;
+
+ status = "okay";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3660b";
+
+ vddxo-supply = <&pm8953_l7>;
+ vddrfa-supply = <&pm8953_l19>;
+ vddpa-supply = <&pm8953_l9>;
+ vdddig-supply = <&pm8953_l5>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts b/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
index e27f3c5d5bba..a288d52fb6d7 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
@@ -248,5 +248,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi b/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
index 819a5f8825e7..a4b722e0fc1e 100644
--- a/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
@@ -90,6 +90,8 @@
gpio-keys {
compatible = "gpio-keys";
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
key-camera-focus {
label = "Camera Focus";
@@ -645,6 +647,13 @@
bias-disable;
};
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio64", "gpio113";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
imx300_vana_default: imx300-vana-default-state {
pins = "gpio50";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index f5921b80ef94..c7e3764a8cf3 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1302,6 +1302,7 @@
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
+ snps,parkmode-disable-ss-quirk;
phys = <&qusb2phy0>, <&usb3_qmpphy>;
phy-names = "usb2-phy", "usb3-phy";
@@ -2422,7 +2423,6 @@
thermal-zones {
aoss-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 0>;
@@ -2437,7 +2437,6 @@
cpuss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 1>;
@@ -2452,7 +2451,6 @@
cpuss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 2>;
@@ -2467,7 +2465,6 @@
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 3>;
@@ -2488,7 +2485,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 4>;
@@ -2509,7 +2505,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 5>;
@@ -2530,7 +2525,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 6>;
@@ -2557,7 +2551,6 @@
pwr-cluster-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 7>;
@@ -2578,7 +2571,6 @@
gpu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens 8>;
@@ -2591,20 +2583,32 @@
trips {
gpu_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
};
timer {
compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 1 0xf08>,
- <GIC_PPI 2 0xf08>,
- <GIC_PPI 3 0xf08>,
- <GIC_PPI 0 0xf08>;
+ interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <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 0 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts b/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts
index 057579ae3013..2c1172aa97e4 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts
+++ b/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts
@@ -116,6 +116,37 @@
};
};
+&pmi632_typec {
+ status = "okay";
+
+ connector {
+ compatible = "usb-c-connector";
+
+ power-role = "dual";
+ data-role = "dual";
+ self-powered;
+
+ typec-power-opmode = "default";
+ pd-disable;
+
+ port {
+ pmi632_hs_in: endpoint {
+ remote-endpoint = <&usb_dwc3_hs>;
+ };
+ };
+ };
+};
+
+&pmi632_vbus {
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <1000000>;
+ status = "okay";
+};
+
+&pmi632_vib {
+ status = "okay";
+};
+
&sdhc_1 {
status = "okay";
vmmc-supply = <&pm8953_l8>;
@@ -240,8 +271,8 @@
status = "okay";
};
-&usb3_dwc3 {
- dr_mode = "peripheral";
+&usb_dwc3_hs {
+ remote-endpoint = <&pmi632_hs_in>;
};
&wcnss {
diff --git a/arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts b/arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts
index c82d6e628d2c..2f55db0c8ce3 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts
+++ b/arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts
@@ -287,5 +287,6 @@
};
&usb3_dwc3 {
+ /delete-property/ usb-role-switch;
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts b/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
index 32a7bd59e1ec..176b0119fe6d 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
@@ -441,6 +441,47 @@
};
};
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&vreg_l1a_1p225>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "samsung,s6e3fa7-ams559nk06";
+ reg = <0>;
+
+ reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_default>;
+
+ power-supply = <&vreg_l6b_3p3>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&panel_in>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+ vdds-supply = <&vreg_l1b_0p925>;
+ status = "okay";
+};
+
+&mdss_mdp {
+ status = "okay";
+};
+
&pm660l_gpios {
vol_up_pin: vol-up-state {
pins = "gpio7";
@@ -481,6 +522,29 @@
&tlmm {
gpio-reserved-ranges = <0 4>, <81 4>;
+ panel_default: panel-default-state {
+ te-pins {
+ pins = "gpio10";
+ function = "mdp_vsync";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ reset-pins {
+ pins = "gpio75";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ mode-pins {
+ pins = "gpio76";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
touchscreen_default: ts-default-state {
ts-reset-pins {
pins = "gpio99";
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 80e81c4233b3..187c6698835d 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -509,6 +509,18 @@
no-map;
};
+ smem@86000000 {
+ compatible = "qcom,smem";
+ reg = <0 0x86000000 0 0x200000>;
+ no-map;
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
+ tz_mem: tz@86200000 {
+ reg = <0 0x86200000 0 0x2d00000>;
+ no-map;
+ };
+
camera_mem: camera-mem@8ab00000 {
reg = <0 0x8ab00000 0 0x500000>;
no-map;
@@ -1139,6 +1151,12 @@
qcom,bcm-voters = <&apps_bcm_voter>;
};
+ tcsr_mutex: hwlock@1f40000 {
+ compatible = "qcom,tcsr-mutex";
+ reg = <0 0x01f40000 0 0x20000>;
+ #hwlock-cells = <1>;
+ };
+
tlmm: pinctrl@3400000 {
compatible = "qcom,sdm670-tlmm";
reg = <0 0x03400000 0 0xc00000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
index 1f517328199b..9a6d3d0c0ee4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -195,6 +195,12 @@
gpio = <&tlmm 90 GPIO_ACTIVE_HIGH>;
enable-active-high;
+ /*
+ * FIXME: this regulator is responsible for VBUS on the left USB
+ * port. Keep it always on until we can correctly model this
+ * relationship.
+ */
+ regulator-always-on;
pinctrl-names = "default";
pinctrl-0 = <&pcie0_pwren_state>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index 76bfa786612c..2391f842c903 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -51,9 +51,6 @@
thermal-zones {
xo_thermal: xo-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm8998_adc_tm 1>;
trips {
@@ -66,9 +63,6 @@
};
msm_thermal: msm-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm8998_adc_tm 2>;
trips {
@@ -81,9 +75,6 @@
};
pa_thermal: pa-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm8998_adc_tm 3>;
trips {
@@ -96,9 +87,6 @@
};
quiet_thermal: quiet-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&pm8998_adc_tm 4>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 2f20be99ee7e..54077549b9da 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -15,6 +15,7 @@
#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sdm845.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -2375,6 +2376,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -2479,6 +2490,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0a000 {
@@ -2646,6 +2667,8 @@
"ref_aux",
"qref";
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -4008,6 +4031,35 @@
#clock-cells = <1>;
#phy-cells = <1>;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_1_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&dp_out>;
+ };
+ };
+ };
};
usb_2_qmpphy: phy@88eb000 {
@@ -4086,8 +4138,29 @@
iommus = <&apps_smmu 0x740 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
+ snps,parkmode-disable-ss-quirk;
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
+ };
+ };
+ };
};
};
@@ -4141,6 +4214,7 @@
iommus = <&apps_smmu 0x760 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
+ snps,parkmode-disable-ss-quirk;
phys = <&usb_2_hsphy>, <&usb_2_qmpphy>;
phy-names = "usb2-phy", "usb3-phy";
};
@@ -4578,7 +4652,9 @@
port@1 {
reg = <1>;
- dp_out: endpoint { };
+ dp_out: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_dp_in>;
+ };
};
};
@@ -5085,6 +5161,78 @@
<GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
};
+ anoc_1_tbu: tbu@150c5000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150c5000 0x0 0x1000>;
+ interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x0 0x400>;
+ };
+
+ anoc_2_tbu: tbu@150c9000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150c9000 0x0 0x1000>;
+ interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x400 0x400>;
+ };
+
+ mnoc_hf_0_tbu: tbu@150cd000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150cd000 0x0 0x1000>;
+ interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+ &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x800 0x400>;
+ };
+
+ mnoc_hf_1_tbu: tbu@150d1000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150d1000 0x0 0x1000>;
+ interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+ &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0xc00 0x400>;
+ };
+
+ mnoc_sf_0_tbu: tbu@150d5000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150d5000 0x0 0x1000>;
+ interconnects = <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ACTIVE_ONLY
+ &mmss_noc SLAVE_MNOC_SF_MEM_NOC QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x1000 0x400>;
+ };
+
+ compute_dsp_tbu: tbu@150d9000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150d9000 0x0 0x1000>;
+ interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ qcom,stream-id-range = <&apps_smmu 0x1400 0x400>;
+ };
+
+ adsp_tbu: tbu@150dd000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150dd000 0x0 0x1000>;
+ interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x1800 0x400>;
+ };
+
+ anoc_1_pcie_tbu: tbu@150e1000 {
+ compatible = "qcom,sdm845-tbu";
+ reg = <0x0 0x150e1000 0x0 0x1000>;
+ clocks = <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>;
+ interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC>;
+ qcom,stream-id-range = <&apps_smmu 0x1c00 0x400>;
+ };
+
lpasscc: clock-controller@17014000 {
compatible = "qcom,sdm845-lpasscc";
reg = <0 0x17014000 0 0x1f004>, <0 0x17300000 0 0x200>;
@@ -5338,7 +5486,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -5365,7 +5512,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -5392,7 +5538,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -5419,7 +5564,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -5446,7 +5590,6 @@
cpu4-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -5473,7 +5616,6 @@
cpu5-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -5500,7 +5642,6 @@
cpu6-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -5527,7 +5668,6 @@
cpu7-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -5554,7 +5694,6 @@
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 0>;
@@ -5569,7 +5708,6 @@
cluster0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -5589,7 +5727,6 @@
cluster1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -5609,7 +5746,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 11>;
@@ -5622,16 +5758,27 @@
trips {
gpu_top_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -5644,16 +5791,27 @@
trips {
gpu_bottom_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
aoss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 0>;
@@ -5668,7 +5826,6 @@
q6-modem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -5683,7 +5840,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -5698,7 +5854,6 @@
wlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -5713,7 +5868,6 @@
q6-hvx-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
@@ -5728,7 +5882,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 5>;
@@ -5743,7 +5896,6 @@
video-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -5758,7 +5910,6 @@
modem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 7>;
diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
index 47dc42f6e936..f18050848cd8 100644
--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
@@ -370,6 +370,66 @@
&i2c1 {
status = "okay";
clock-frequency = <400000>;
+
+ embedded-controller@70 {
+ compatible = "lenovo,yoga-c630-ec";
+ reg = <0x70>;
+
+ interrupts-extended = <&tlmm 20 IRQ_TYPE_LEVEL_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ec_int_state>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "host";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ucsi0_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ ucsi0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ ucsi0_sbu: endpoint {
+ };
+ };
+ };
+ };
+
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "host";
+
+ /*
+ * connected to the onboard USB hub, orientation is
+ * handled by the controller
+ */
+ };
+ };
};
&i2c3 {
@@ -494,6 +554,7 @@
&ipa {
qcom,gsi-loader = "self";
memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/sdm850/LENOVO/81JL/ipa_fws.elf";
status = "okay";
};
@@ -694,6 +755,13 @@
bias-disable;
};
+
+ ec_int_state: ec-int-state {
+ pins = "gpio20";
+ function = "gpio";
+
+ bias-disable;
+ };
};
&uart6 {
@@ -741,6 +809,10 @@
dr_mode = "host";
};
+&usb_1_dwc3_hs {
+ remote-endpoint = <&ucsi0_hs_in>;
+};
+
&usb_1_hsphy {
status = "okay";
@@ -761,6 +833,10 @@
vdda-pll-supply = <&vdda_usb1_ss_core>;
};
+&usb_1_qmpphy_out {
+ remote-endpoint = <&ucsi0_ss_in>;
+};
+
&usb_2 {
status = "okay";
};
@@ -834,6 +910,7 @@
vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
qcom,snoc-host-cap-8bit-quirk;
+ qcom,ath10k-calibration-variant = "Lenovo_C630";
};
&crypto {
diff --git a/arch/arm64/boot/dts/qcom/sdx75-idp.dts b/arch/arm64/boot/dts/qcom/sdx75-idp.dts
index f76e72fb2072..fde16308c7e2 100644
--- a/arch/arm64/boot/dts/qcom/sdx75-idp.dts
+++ b/arch/arm64/boot/dts/qcom/sdx75-idp.dts
@@ -41,6 +41,29 @@
vin-supply = <&vph_ext>;
};
+
+ reg_2v952_vcc: regulator-2v952-vcc {
+ compatible = "regulator-gpio";
+ regulator-name = "2v952_vcc";
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <3600000>;
+ enable-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>;
+ gpios = <&tlmm 84 GPIO_ACTIVE_HIGH>;
+ states = <1650000 0>, <3600000 1>;
+ startup-delay-us = <5000>;
+ enable-active-high;
+ regulator-boot-on;
+
+ vin-supply = <&vph_ext>;
+ };
+
+ reg_2v95_vdd: regulator-2v95-vdd {
+ compatible = "regulator-fixed";
+ regulator-name = "2v95_vdd";
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ vin-supply = <&reg_2v952_vcc>;
+ };
};
&apps_rsc {
@@ -259,8 +282,30 @@
status = "okay";
};
+&sdhc {
+ cd-gpios = <&tlmm 103 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_2v95_vdd>;
+ vqmmc-supply = <&reg_2v952_vcc>;
+ bus-width = <4>;
+ no-sdio;
+ no-mmc;
+
+ pinctrl-0 = <&sdc1_default &sd_cd>;
+ pinctrl-1 = <&sdc1_sleep &sd_cd>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+};
+
&tlmm {
gpio-reserved-ranges = <110 6>;
+
+ sd_cd: sd-cd-state {
+ pins = "gpio103";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
};
&uart1 {
diff --git a/arch/arm64/boot/dts/qcom/sdx75.dtsi b/arch/arm64/boot/dts/qcom/sdx75.dtsi
index 7dbdf8ca6de6..9b93f6501d55 100644
--- a/arch/arm64/boot/dts/qcom/sdx75.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdx75.dtsi
@@ -8,9 +8,12 @@
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,sdx75-gcc.h>
+#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,sdx75.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
@@ -224,7 +227,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -405,13 +408,48 @@
};
};
- smem: qcom,smem {
+ smp2p-modem {
+ compatible = "qcom,smp2p";
+ qcom,smem = <435>, <428>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_MPSS
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_MPSS
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <1>;
+
+ smp2p_modem_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ smp2p_modem_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ ipa_smp2p_out: ipa-ap-to-modem {
+ qcom,entry-name = "ipa";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ ipa_smp2p_in: ipa-modem-to-ap {
+ qcom,entry-name = "ipa";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ smem: smem {
compatible = "qcom,smem";
memory-region = <&smem_mem>;
hwlocks = <&tcsr_mutex 3>;
};
- soc: soc {
+ soc: soc@0 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
@@ -441,6 +479,37 @@
#power-domain-cells = <1>;
};
+ ipcc: mailbox@408000 {
+ compatible = "qcom,sdx75-ipcc", "qcom,ipcc";
+ reg = <0 0x00408000 0 0x1000>;
+ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #mbox-cells = <2>;
+ };
+
+ gpi_dma: dma-controller@900000 {
+ compatible = "qcom,sdx75-gpi-dma", "qcom,sm6350-gpi-dma";
+ reg = <0x0 0x00900000 0x0 0x60000>;
+ #dma-cells = <3>;
+ interrupts = <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 350 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+ dma-channels = <12>;
+ dma-channel-mask = <0x7f>;
+ iommus = <&apps_smmu 0xf6 0x0>;
+ status = "disabled";
+ };
+
qupv3_id_0: geniqup@9c0000 {
compatible = "qcom,geni-se-qup";
reg = <0x0 0x009c0000 0x0 0x2000>;
@@ -457,6 +526,52 @@
ranges;
status = "disabled";
+ i2c0: i2c@980000 {
+ compatible = "qcom,geni-i2c";
+ reg = <0x0 0x00980000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_i2c0_data_clk>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 0 QCOM_GPI_I2C>,
+ <&gpi_dma 1 0 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi0: spi@980000 {
+ compatible = "qcom,geni-spi";
+ reg = <0x0 0x00980000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 0 QCOM_GPI_SPI>,
+ <&gpi_dma 1 0 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
uart1: serial@984000 {
compatible = "qcom,geni-debug-uart";
reg = <0x0 0x00984000 0x0 0x4000>;
@@ -475,6 +590,229 @@
"sleep";
status = "disabled";
};
+
+ i2c2: i2c@988000 {
+ compatible = "qcom,geni-i2c";
+ reg = <0x0 0x00988000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_i2c2_data_clk>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 2 QCOM_GPI_I2C>,
+ <&gpi_dma 1 2 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi2: spi@988000 {
+ compatible = "qcom,geni-spi";
+ reg = <0x0 0x00988000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 2 QCOM_GPI_SPI>,
+ <&gpi_dma 1 2 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c3: i2c@98c000 {
+ compatible = "qcom,geni-i2c";
+ reg = <0x0 0x0098c000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_i2c3_data_clk>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 3 QCOM_GPI_I2C>,
+ <&gpi_dma 1 3 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi3: spi@98c000 {
+ compatible = "qcom,geni-spi";
+ reg = <0x0 0x0098c000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 3 QCOM_GPI_SPI>,
+ <&gpi_dma 1 3 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ uart4: serial@990000 {
+ compatible = "qcom,geni-uart";
+ reg = <0x0 0x00990000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-0 = <&qup_uart4_default>, <&qup_uart4_cts_rts>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config";
+ status = "disabled";
+ };
+
+ i2c5: i2c@994000 {
+ compatible = "qcom,geni-i2c";
+ reg = <0x0 0x00994000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_i2c5_data_clk>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 5 QCOM_GPI_I2C>,
+ <&gpi_dma 1 5 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c6: i2c@998000 {
+ compatible = "qcom,geni-i2c";
+ reg = <0x0 0x00998000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_i2c6_data_clk>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 6 QCOM_GPI_I2C>,
+ <&gpi_dma 1 6 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi6: spi@998000 {
+ compatible = "qcom,geni-spi";
+ reg = <0x0 0x00998000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 6 QCOM_GPI_SPI>,
+ <&gpi_dma 1 6 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c7: i2c@99c000 {
+ compatible = "qcom,geni-i2c";
+ reg = <0x0 0x0099c000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_i2c7_data_clk>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 7 QCOM_GPI_I2C>,
+ <&gpi_dma 1 7 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi7: spi@99c000 {
+ compatible = "qcom,geni-spi";
+ reg = <0x0 0x0099c000 0x0 0x4000>;
+ clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+ clock-names = "se";
+ interrupts = <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&qup_spi7_data_clk>, <&qup_spi7_cs>;
+ pinctrl-names = "default";
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &system_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+ <&system_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core", "qup-config", "qup-memory";
+ dmas = <&gpi_dma 0 7 QCOM_GPI_SPI>,
+ <&gpi_dma 1 7 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
};
usb_hsphy: phy@ff4000 {
@@ -538,6 +876,59 @@
#hwlock-cells = <1>;
};
+ tcsr: syscon@1fc0000 {
+ compatible = "qcom,sdx75-tcsr", "syscon";
+ reg = <0x0 0x01fc0000 0x0 0x30000>;
+ };
+
+ sdhc: mmc@8804000 {
+ compatible = "qcom,sdx75-sdhci", "qcom,sdhci-msm-v5";
+ reg = <0x0 0x08804000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq",
+ "pwr_irq";
+
+ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "iface",
+ "core",
+ "xo";
+ iommus = <&apps_smmu 0x00a0 0x0>;
+ qcom,dll-config = <0x0007442c>;
+ qcom,ddr-config = <0x80040868>;
+ power-domains = <&rpmhpd RPMHPD_CX>;
+ operating-points-v2 = <&sdhc1_opp_table>;
+
+ interconnects = <&system_noc MASTER_SDCC_1 &mc_virt SLAVE_EBI1>,
+ <&gem_noc MASTER_APPSS_PROC &system_noc SLAVE_SDCC_1>;
+ interconnect-names = "sdhc-ddr",
+ "cpu-sdhc";
+ bus-width = <4>;
+ dma-coherent;
+
+ /* Forbid SDR104/SDR50 - broken hw! */
+ sdhci-caps-mask = <0x3 0>;
+
+ status = "disabled";
+
+ sdhc1_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+ };
+
usb: usb@a6f8800 {
compatible = "qcom,sdx75-dwc3", "qcom,dwc3";
reg = <0x0 0x0a6f8800 0x0 0x400>;
@@ -627,6 +1018,17 @@
interrupt-controller;
};
+ aoss_qmp: power-controller@c310000 {
+ compatible = "qcom,sdx75-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c310000 0 0x1000>;
+ interrupt-parent = <&ipcc>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+ #clock-cells = <0>;
+ };
+
spmi_bus: spmi@c400000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0 0x0c400000 0x0 0x3000>,
@@ -661,6 +1063,145 @@
#interrupt-cells = <2>;
wakeup-parent = <&pdc>;
+ qup_i2c0_data_clk: qup-i2c0-data-clk-state {
+ /* SDA, SCL */
+ pins = "gpio8", "gpio9";
+ function = "qup_se0";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_i2c2_data_clk: qup-i2c2-data-clk-state {
+ /* SDA, SCL */
+ pins = "gpio14", "gpio15";
+ function = "qup_se2";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_i2c3_data_clk: qup-i2c3-data-clk-state {
+ /* SDA, SCL */
+ pins = "gpio52", "gpio53";
+ function = "qup_se3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_i2c5_data_clk: qup-i2c5-data-clk-state {
+ /* SDA, SCL */
+ pins = "gpio110", "gpio111";
+ function = "qup_se5";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_i2c6_data_clk: qup-i2c6-data-clk-state {
+ /* SDA, SCL */
+ pins = "gpio112", "gpio113";
+ function = "qup_se6";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_i2c7_data_clk: qup-i2c7-data-clk-state {
+ /* SDA, SCL */
+ pins = "gpio116", "gpio117";
+ function = "qup_se7";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_spi0_cs: qup-spi0-cs-state {
+ pins = "gpio11";
+ function = "qup_se0";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi0_data_clk: qup-spi0-data-clk-state {
+ /* MISO, MOSI, CLK */
+ pins = "gpio8", "gpio9", "gpio10";
+ function = "qup_se0";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi2_cs: qup-spi2-cs-state {
+ pins = "gpio17";
+ function = "qup_se2";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi2_data_clk: qup-spi2-data-clk-state {
+ /* MISO, MOSI, CLK */
+ pins = "gpio14", "gpio15", "gpio16";
+ function = "qup_se2";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi3_cs: qup-spi3-cs-state {
+ pins = "gpio55";
+ function = "qup_se3";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi3_data_clk: qup-spi3-data-clk-state {
+ /* MISO, MOSI, CLK */
+ pins = "gpio52", "gpio53", "gpio54";
+ function = "qup_se3";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi6_cs: qup-spi6-cs-state {
+ pins = "gpio115";
+ function = "qup_se6";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi6_data_clk: qup-spi6-data-clk-state {
+ /* MISO, MOSI, CLK */
+ pins = "gpio112", "gpio113", "gpio114";
+ function = "qup_se6";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi7_cs: qup-spi7-cs-state {
+ pins = "gpio119";
+ function = "qup_se7";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_spi7_data_clk: qup-spi7-data-clk-state {
+ /* MISO, MOSI, CLK */
+ pins = "gpio116", "gpio117", "gpio118";
+ function = "qup_se7";
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ qup_uart4_cts_rts: qup-uart4-cts-rts-state {
+ /* CTS, RTS */
+ pins = "gpio52", "gpio53";
+ function = "qup_se3";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ qup_uart4_default: qup-uart4-default-state {
+ /* TX, RX */
+ pins = "gpio54", "gpio55";
+ function = "qup_se3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
qupv3_se1_2uart_active: qupv3-se1-2uart-active-state {
tx-pins {
pins = "gpio12";
@@ -683,6 +1224,46 @@
drive-strength = <2>;
bias-pull-down;
};
+
+ sdc1_default: sdc1-default-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ cmd-pins {
+ pins = "sdc1_cmd";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+
+ data-pins {
+ pins = "sdc1_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ sdc1_sleep: sdc1-sleep-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cmd-pins {
+ pins = "sdc1_cmd";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ data-pins {
+ pins = "sdc1_data";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
apps_smmu: iommu@15000000 {
diff --git a/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts b/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
index 2c7a12983dae..9153a5a55ed9 100644
--- a/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
+++ b/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
@@ -240,6 +240,7 @@
};
&usb_dwc3 {
+ /delete-property/ usb-role-switch;
maximum-speed = "high-speed";
dr_mode = "peripheral";
diff --git a/arch/arm64/boot/dts/qcom/sm4450.dtsi b/arch/arm64/boot/dts/qcom/sm4450.dtsi
index 603c962661cc..9c9919e78fbd 100644
--- a/arch/arm64/boot/dts/qcom/sm4450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm4450.dtsi
@@ -29,6 +29,14 @@
clock-frequency = <32000>;
#clock-cells = <0>;
};
+
+ bi_tcxo_div2: bi-tcxo-div2-clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
};
cpus {
@@ -39,10 +47,12 @@
device_type = "cpu";
compatible = "arm,cortex-a55";
reg = <0x0 0x0>;
+ clocks = <&cpufreq_hw 0>;
enable-method = "psci";
next-level-cache = <&L2_0>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
L2_0: l2-cache {
@@ -63,10 +73,12 @@
device_type = "cpu";
compatible = "arm,cortex-a55";
reg = <0x0 0x100>;
+ clocks = <&cpufreq_hw 0>;
enable-method = "psci";
next-level-cache = <&L2_100>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
L2_100: l2-cache {
@@ -81,10 +93,12 @@
device_type = "cpu";
compatible = "arm,cortex-a55";
reg = <0x0 0x200>;
+ clocks = <&cpufreq_hw 0>;
enable-method = "psci";
next-level-cache = <&L2_200>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
L2_200: l2-cache {
@@ -99,10 +113,12 @@
device_type = "cpu";
compatible = "arm,cortex-a55";
reg = <0x0 0x300>;
+ clocks = <&cpufreq_hw 0>;
enable-method = "psci";
next-level-cache = <&L2_300>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
L2_300: l2-cache {
@@ -117,10 +133,12 @@
device_type = "cpu";
compatible = "arm,cortex-a55";
reg = <0x0 0x400>;
+ clocks = <&cpufreq_hw 0>;
enable-method = "psci";
next-level-cache = <&L2_400>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
L2_400: l2-cache {
@@ -135,10 +153,12 @@
device_type = "cpu";
compatible = "arm,cortex-a55";
reg = <0x0 0x500>;
+ clocks = <&cpufreq_hw 0>;
enable-method = "psci";
next-level-cache = <&L2_500>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
L2_500: l2-cache {
@@ -153,10 +173,12 @@
device_type = "cpu";
compatible = "arm,cortex-a78";
reg = <0x0 0x600>;
+ clocks = <&cpufreq_hw 1>;
enable-method = "psci";
next-level-cache = <&L2_600>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 1>;
#cooling-cells = <2>;
L2_600: l2-cache {
@@ -171,10 +193,12 @@
device_type = "cpu";
compatible = "arm,cortex-a78";
reg = <0x0 0x700>;
+ clocks = <&cpufreq_hw 1>;
enable-method = "psci";
next-level-cache = <&L2_700>;
power-domains = <&CPU_PD0>;
power-domain-names = "psci";
+ qcom,freq-domain = <&cpufreq_hw 1>;
#cooling-cells = <2>;
L2_700: l2-cache {
@@ -268,9 +292,14 @@
reg = <0x0 0xa0000000 0x0 0x0>;
};
- pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-a78 {
+ compatible = "arm,cortex-a78-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
psci {
@@ -526,6 +555,19 @@
};
};
+ cpufreq_hw: cpufreq@17d91000 {
+ compatible = "qcom,sm4450-cpufreq-epss", "qcom,cpufreq-epss";
+ reg = <0 0x17d91000 0 0x1000>,
+ <0 0x17d92000 0 0x1000>;
+ reg-names = "freq-domain0", "freq-domain1";
+ clocks = <&bi_tcxo_div2>, <&gcc GCC_GPLL0>;
+ clock-names = "xo", "alternate";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1";
+ #freq-domain-cells = <1>;
+ #clock-cells = <1>;
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts b/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
index 98eb072fa912..4a30024aa48f 100644
--- a/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
+++ b/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
@@ -234,6 +234,7 @@
};
&usb_dwc3 {
+ /delete-property/ usb-role-switch;
maximum-speed = "high-speed";
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi
index aca0a87092e4..e374733f3b85 100644
--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -1088,8 +1088,11 @@
<&gcc GCC_SDCC1_ICE_CORE_CLK>;
clock-names = "iface", "core", "xo", "ice";
+ resets = <&gcc GCC_SDCC1_BCR>;
+
power-domains = <&rpmpd SM6115_VDDCX>;
operating-points-v2 = <&sdhc1_opp_table>;
+ iommus = <&apps_smmu 0x00c0 0x0>;
interconnects = <&system_noc MASTER_SDCC_1 RPM_ALWAYS_TAG
&bimc SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
<&bimc MASTER_AMPSS_M0 RPM_ALWAYS_TAG
@@ -1230,6 +1233,8 @@
"ref_aux",
"qref";
+ power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -1655,6 +1660,7 @@
snps,has-lpm-erratum;
snps,hird-threshold = /bits/ 8 <0x10>;
snps,usb3_lpm_capable;
+ snps,parkmode-disable-ss-quirk;
usb-role-switch;
@@ -3011,8 +3017,6 @@
thermal-zones {
mapss-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 0>;
trips {
@@ -3031,8 +3035,6 @@
};
cdsp-hvx-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
trips {
@@ -3051,8 +3053,6 @@
};
wlan-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
trips {
@@ -3071,8 +3071,6 @@
};
camera-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
trips {
@@ -3091,8 +3089,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
trips {
@@ -3111,8 +3107,6 @@
};
modem1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
trips {
@@ -3131,8 +3125,6 @@
};
cpu4-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
trips {
@@ -3157,8 +3149,6 @@
};
cpu5-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
trips {
@@ -3183,8 +3173,6 @@
};
cpu6-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
trips {
@@ -3209,8 +3197,6 @@
};
cpu7-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
trips {
@@ -3235,8 +3221,6 @@
};
cpu45-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
trips {
@@ -3261,8 +3245,6 @@
};
cpu67-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
trips {
@@ -3287,8 +3269,6 @@
};
cpu0123-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
trips {
@@ -3313,8 +3293,6 @@
};
modem0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 13>;
trips {
@@ -3333,8 +3311,6 @@
};
display-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 14>;
trips {
@@ -3353,8 +3329,8 @@
};
gpu-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ polling-delay-passive = <250>;
+
thermal-sensors = <&tsens0 15>;
cooling-maps {
@@ -3366,13 +3342,13 @@
trips {
gpu_alert0: trip-point0 {
- temperature = <115000>;
- hysteresis = <5000>;
+ temperature = <85000>;
+ hysteresis = <1000>;
type = "passive";
};
trip-point1 {
- temperature = <125000>;
+ temperature = <110000>;
hysteresis = <1000>;
type = "critical";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
index 54da053a8042..9d78bb3f7190 100644
--- a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
+++ b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
@@ -359,6 +359,7 @@
};
&usb_dwc3 {
+ /delete-property/ usb-role-switch;
maximum-speed = "high-speed";
dr_mode = "peripheral";
diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
index 08046f866f60..dcd05f303b78 100644
--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
@@ -90,8 +90,6 @@
thermal-zones {
rf-pa0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm6125_adc_tm 0>;
trips {
@@ -104,8 +102,6 @@
};
quiet-thermal {
- polling-delay-passive = <0>;
- polling-delay = <5000>;
thermal-sensors = <&pm6125_adc_tm 1>;
trips {
@@ -118,8 +114,6 @@
};
xo-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm6125_adc_tm 2>;
trips {
@@ -132,8 +126,6 @@
};
rf-pa1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm6125_adc_tm 3>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts b/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
index a49d3ebb1931..994fb0412fcb 100644
--- a/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
+++ b/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
@@ -84,8 +84,6 @@
thermal-zones {
rf-pa0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm6125_adc_tm 0>;
trips {
@@ -98,8 +96,6 @@
};
quiet-thermal {
- polling-delay-passive = <0>;
- polling-delay = <5000>;
thermal-sensors = <&pm6125_adc_tm 1>;
trips {
@@ -112,8 +108,6 @@
};
xo-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm6125_adc_tm 2>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
index 98ab08356088..777c380c2fa0 100644
--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
@@ -1588,10 +1588,10 @@
timer {
compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 1 0xf08
- GIC_PPI 2 0xf08
- GIC_PPI 3 0xf08
- GIC_PPI 0 0xf08>;
+ interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <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 0 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
clock-frequency = <19200000>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts b/arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts
index dddd6e44d280..bf23033a294e 100644
--- a/arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts
+++ b/arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts
@@ -293,7 +293,7 @@
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&tlmm>;
- interrupts = <22 0x2008>;
+ interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&pm6350_l11>;
avdd-supply = <&touch_en_vreg>;
@@ -375,6 +375,7 @@
};
&usb_1_dwc3 {
+ /delete-property/ usb-role-switch;
maximum-speed = "super-speed";
dr_mode = "peripheral";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
index 0be053555602..7986ddb30f6e 100644
--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
@@ -1197,6 +1197,8 @@
"ref_aux",
"qref";
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -1205,6 +1207,37 @@
status = "disabled";
};
+ cryptobam: dma-controller@1dc4000 {
+ compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
+ reg = <0 0x01dc4000 0 0x24000>;
+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ qcom,ee = <0>;
+ qcom,controlled-remotely;
+ num-channels = <16>;
+ qcom,num-ees = <4>;
+ iommus = <&apps_smmu 0x426 0x11>,
+ <&apps_smmu 0x432 0x0>,
+ <&apps_smmu 0x436 0x11>,
+ <&apps_smmu 0x438 0x1>,
+ <&apps_smmu 0x43f 0x0>;
+ };
+
+ crypto: crypto@1dfa000 {
+ compatible = "qcom,sm6350-qce", "qcom,sm8150-qce", "qcom,qce";
+ reg = <0 0x01dfa000 0 0x6000>;
+ dmas = <&cryptobam 4>, <&cryptobam 5>;
+ dma-names = "rx", "tx";
+ iommus = <&apps_smmu 0x426 0x11>,
+ <&apps_smmu 0x432 0x0>,
+ <&apps_smmu 0x436 0x11>,
+ <&apps_smmu 0x438 0x1>,
+ <&apps_smmu 0x43f 0x0>;
+ interconnects = <&aggre2_noc MASTER_CRYPTO_CORE_0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "memory";
+ };
+
ipa: ipa@1e40000 {
compatible = "qcom,sm6350-ipa";
@@ -1290,6 +1323,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "adsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -1549,6 +1583,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "cdsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -1682,10 +1717,39 @@
<&gcc GCC_USB3_DP_PHY_PRIM_BCR>;
reset-names = "phy", "common";
+ orientation-switch;
+
#clock-cells = <1>;
#phy-cells = <1>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_1_qmpphy_dp_in: endpoint {
+ };
+ };
+ };
};
dc_noc: interconnect@9160000 {
@@ -1859,8 +1923,30 @@
snps,dis_enblslpm_quirk;
snps,has-lpm-erratum;
snps,hird-threshold = /bits/ 8 <0x10>;
+ snps,parkmode-disable-ss-quirk;
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
+ usb-role-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_dwc3_hs_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_dwc3_ss_out: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
+ };
+ };
+ };
};
};
@@ -2033,6 +2119,14 @@
remote-endpoint = <&mdss_dsi0_in>;
};
};
+
+ port@2 {
+ reg = <2>;
+
+ dpu_intf0_out: endpoint {
+ remote-endpoint = <&mdss_dp_in>;
+ };
+ };
};
mdp_opp_table: opp-table {
@@ -2070,6 +2164,86 @@
};
};
+ mdss_dp: displayport-controller@ae90000 {
+ compatible = "qcom,sm6350-dp", "qcom,sm8350-dp";
+ reg = <0 0xae90000 0 0x200>,
+ <0 0xae90200 0 0x200>,
+ <0 0xae90400 0 0x600>,
+ <0 0xae91000 0 0x400>,
+ <0 0xae91400 0 0x400>;
+ interrupt-parent = <&mdss>;
+ interrupts = <12>;
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+
+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>;
+ phy-names = "dp";
+
+ #sound-dai-cells = <0>;
+
+ operating-points-v2 = <&dp_opp_table>;
+ power-domains = <&rpmhpd SM6350_CX>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_dp_in: endpoint {
+ remote-endpoint = <&dpu_intf0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dp_out: endpoint {
+ };
+ };
+ };
+
+ dp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-160000000 {
+ opp-hz = /bits/ 64 <160000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-270000000 {
+ opp-hz = /bits/ 64 <270000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-540000000 {
+ opp-hz = /bits/ 64 <540000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-810000000 {
+ opp-hz = /bits/ 64 <810000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+ };
+
mdss_dsi0: dsi@ae94000 {
compatible = "qcom,sm6350-dsi-ctrl", "qcom,mdss-dsi-ctrl";
reg = <0 0x0ae94000 0 0x400>;
@@ -2712,9 +2886,6 @@
thermal-zones {
aoss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 0>;
trips {
@@ -2727,9 +2898,6 @@
};
aoss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 0>;
trips {
@@ -2742,9 +2910,6 @@
};
audio-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 2>;
trips {
@@ -2757,9 +2922,6 @@
};
camera-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 5>;
trips {
@@ -2772,9 +2934,6 @@
};
cpu0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 1>;
trips {
@@ -2800,9 +2959,6 @@
};
cpu1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 2>;
trips {
@@ -2828,9 +2984,6 @@
};
cpu2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 3>;
trips {
@@ -2856,9 +3009,6 @@
};
cpu3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 4>;
trips {
@@ -2884,9 +3034,6 @@
};
cpu4-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 5>;
trips {
@@ -2912,9 +3059,6 @@
};
cpu5-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 6>;
trips {
@@ -2940,9 +3084,6 @@
};
cpu6-left-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 9>;
trips {
@@ -2968,9 +3109,6 @@
};
cpu6-right-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 10>;
trips {
@@ -2996,9 +3134,6 @@
};
cpu7-left-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 11>;
trips {
@@ -3024,9 +3159,6 @@
};
cpu7-right-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 12>;
trips {
@@ -3052,9 +3184,6 @@
};
cpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 7>;
trips {
@@ -3067,9 +3196,6 @@
};
cpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 8>;
trips {
@@ -3082,9 +3208,6 @@
};
cwlan-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 1>;
trips {
@@ -3097,9 +3220,6 @@
};
ddr-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 3>;
trips {
@@ -3112,21 +3232,20 @@
};
gpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ polling-delay-passive = <250>;
thermal-sensors = <&tsens0 13>;
trips {
gpuss0_alert0: trip-point0 {
- temperature = <95000>;
+ temperature = <85000>;
hysteresis = <2000>;
type = "passive";
};
gpuss0-crit {
- temperature = <115000>;
- hysteresis = <0>;
+ temperature = <110000>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -3140,21 +3259,20 @@
};
gpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ polling-delay-passive = <250>;
thermal-sensors = <&tsens0 14>;
trips {
gpuss1_alert0: trip-point0 {
- temperature = <95000>;
+ temperature = <85000>;
hysteresis = <2000>;
type = "passive";
};
gpuss1-crit {
- temperature = <115000>;
- hysteresis = <0>;
+ temperature = <110000>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -3168,9 +3286,6 @@
};
modem-core0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 6>;
trips {
@@ -3183,9 +3298,6 @@
};
modem-core1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 7>;
trips {
@@ -3198,9 +3310,6 @@
};
modem-scl-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 9>;
trips {
@@ -3213,9 +3322,6 @@
};
modem-vec-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 8>;
trips {
@@ -3228,9 +3334,6 @@
};
npu-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 10>;
trips {
@@ -3243,9 +3346,6 @@
};
q6-hvx-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 4>;
trips {
@@ -3258,9 +3358,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 11>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sm6375-sony-xperia-murray-pdx225.dts b/arch/arm64/boot/dts/qcom/sm6375-sony-xperia-murray-pdx225.dts
index cca2c2eb88ad..e04a3b8f81c5 100644
--- a/arch/arm64/boot/dts/qcom/sm6375-sony-xperia-murray-pdx225.dts
+++ b/arch/arm64/boot/dts/qcom/sm6375-sony-xperia-murray-pdx225.dts
@@ -142,7 +142,7 @@
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&tlmm>;
- interrupts = <22 0x2008>;
+ interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&pm6125_l13>;
avdd-supply = <&touch_avdd>;
diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi
index f40509d91bbd..ddea681b536d 100644
--- a/arch/arm64/boot/dts/qcom/sm6375.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi
@@ -1837,9 +1837,6 @@
thermal-zones {
mapss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 0>;
trips {
@@ -1864,9 +1861,6 @@
};
cpu0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 1>;
trips {
@@ -1891,9 +1885,6 @@
};
cpu1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 2>;
trips {
@@ -1918,9 +1909,6 @@
};
cpu2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 3>;
trips {
@@ -1945,9 +1933,6 @@
};
cpu3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 4>;
trips {
@@ -1972,9 +1957,6 @@
};
cpu4-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 5>;
trips {
@@ -1999,9 +1981,6 @@
};
cpu5-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 6>;
trips {
@@ -2026,9 +2005,6 @@
};
cluster0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 7>;
trips {
@@ -2053,9 +2029,6 @@
};
cluster1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 8>;
trips {
@@ -2080,9 +2053,6 @@
};
cpu6-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 9>;
trips {
@@ -2107,9 +2077,6 @@
};
cpu7-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 10>;
trips {
@@ -2134,9 +2101,6 @@
};
cpu-unk0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 11>;
trips {
@@ -2161,9 +2125,6 @@
};
cpu-unk1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 12>;
trips {
@@ -2188,9 +2149,6 @@
};
gpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 13>;
trips {
@@ -2215,9 +2173,6 @@
};
gpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens0 14>;
trips {
@@ -2242,9 +2197,6 @@
};
mapss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 0>;
trips {
@@ -2269,9 +2221,6 @@
};
cwlan-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 1>;
trips {
@@ -2296,9 +2245,6 @@
};
audio-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 2>;
trips {
@@ -2323,9 +2269,6 @@
};
ddr-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 3>;
trips {
@@ -2350,9 +2293,6 @@
};
q6hvx-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 4>;
trips {
@@ -2377,9 +2317,6 @@
};
camera-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 5>;
trips {
@@ -2404,9 +2341,6 @@
};
mdm-core0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 6>;
trips {
@@ -2431,9 +2365,6 @@
};
mdm-core1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 7>;
trips {
@@ -2458,9 +2389,6 @@
};
mdm-vec-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 8>;
trips {
@@ -2485,9 +2413,6 @@
};
msm-scl-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 9>;
trips {
@@ -2512,9 +2437,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
-
thermal-sensors = <&tsens1 10>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
index bc67e8c1fe4d..2ee2561b57b1 100644
--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -19,6 +19,7 @@
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/usb/pd.h>
#include "sm7225.dtsi"
#include "pm6150l.dtsi"
#include "pm6350.dtsi"
@@ -92,10 +93,22 @@
};
};
+ msm_therm_sensor: thermal-sensor-msm {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&pm6150l_adc ADC5_AMUX_THM2_100K_PU>;
+ io-channel-names = "sensor-channel";
+ };
+
+ rear_cam_sensor: thermal-sensor-rear-cam {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&pm6150l_adc ADC5_GPIO2_100K_PU>;
+ io-channel-names = "sensor-channel";
+ };
+
thermal-zones {
chg-skin-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm7250b_adc_tm 0>;
trips {
@@ -108,8 +121,6 @@
};
conn-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm7250b_adc_tm 1>;
trips {
@@ -120,6 +131,119 @@
};
};
};
+
+ pa0-thermal {
+ thermal-sensors = <&pm6150l_adc_tm 1>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ pa1-thermal {
+ thermal-sensors = <&pm6150l_adc_tm 0>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ pm8008-thermal {
+ polling-delay-passive = <100>;
+ thermal-sensors = <&pm8008>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ quiet-thermal {
+ thermal-sensors = <&pm6150l_adc_tm 3>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ rear-cam-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&rear_cam_sensor>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ rfc-flash-thermal {
+ thermal-sensors = <&pm6150l_adc_tm 2>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ sdm-skin-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&msm_therm_sensor>;
+
+ trips {
+ trip0 {
+ temperature = <45000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <55000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ xo-thermal {
+ thermal-sensors = <&pmk8350_adc_tm 0>;
+
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
};
};
@@ -134,124 +258,145 @@
qcom,pmic-id = "a";
vreg_s1a: smps1 {
+ regulator-name = "vreg_s1a";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1200000>;
};
vreg_s2a: smps2 {
+ regulator-name = "vreg_s2a";
regulator-min-microvolt = <1503000>;
regulator-max-microvolt = <2048000>;
};
vreg_l2a: ldo2 {
+ regulator-name = "vreg_l2a";
regulator-min-microvolt = <1503000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3a: ldo3 {
+ regulator-name = "vreg_l3a";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4a: ldo4 {
+ regulator-name = "vreg_l4a";
regulator-min-microvolt = <352000>;
regulator-max-microvolt = <801000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l5a: ldo5 {
+ regulator-name = "vreg_l5a";
regulator-min-microvolt = <1503000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6a: ldo6 {
+ regulator-name = "vreg_l6a";
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7a: ldo7 {
+ regulator-name = "vreg_l7a";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8a: ldo8 {
+ regulator-name = "vreg_l8a";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9a: ldo9 {
+ regulator-name = "vreg_l9a";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <3401000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11a: ldo11 {
+ regulator-name = "vreg_l11a";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l12a: ldo12 {
+ regulator-name = "vreg_l12a";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13a: ldo13 {
+ regulator-name = "vreg_l13a";
regulator-min-microvolt = <570000>;
regulator-max-microvolt = <650000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l14a: ldo14 {
+ regulator-name = "vreg_l14a";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l15a: ldo15 {
+ regulator-name = "vreg_l15a";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1305000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l16a: ldo16 {
+ regulator-name = "vreg_l16a";
regulator-min-microvolt = <830000>;
regulator-max-microvolt = <921000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l18a: ldo18 {
+ regulator-name = "vreg_l18a";
regulator-min-microvolt = <788000>;
regulator-max-microvolt = <1049000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l19a: ldo19 {
+ regulator-name = "vreg_l19a";
regulator-min-microvolt = <1080000>;
regulator-max-microvolt = <1305000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l20a: ldo20 {
+ regulator-name = "vreg_l20a";
regulator-min-microvolt = <530000>;
regulator-max-microvolt = <801000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l21a: ldo21 {
+ regulator-name = "vreg_l21a";
regulator-min-microvolt = <751000>;
regulator-max-microvolt = <825000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l22a: ldo22 {
+ regulator-name = "vreg_l22a";
regulator-min-microvolt = <1080000>;
regulator-max-microvolt = <1305000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -263,41 +408,48 @@
qcom,pmic-id = "e";
vreg_s8e: smps8 {
+ regulator-name = "vreg_s8e";
regulator-min-microvolt = <313000>;
regulator-max-microvolt = <1395000>;
};
vreg_l1e: ldo1 {
+ regulator-name = "vreg_l1e";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <1980000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l2e: ldo2 {
+ regulator-name = "vreg_l2e";
regulator-min-microvolt = <1170000>;
regulator-max-microvolt = <1305000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l3e: ldo3 {
+ regulator-name = "vreg_l3e";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1299000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4e: ldo4 {
+ regulator-name = "vreg_l4e";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l5e: ldo5 {
+ regulator-name = "vreg_l5e";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l6e: ldo6 {
+ regulator-name = "vreg_l6e";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2950000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -307,18 +459,21 @@
};
vreg_l7e: ldo7 {
+ regulator-name = "vreg_l7e";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3544000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8e: ldo8 {
+ regulator-name = "vreg_l8e";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <2000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9e: ldo9 {
+ regulator-name = "vreg_l9e";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -328,18 +483,21 @@
};
vreg_l10e: ldo10 {
+ regulator-name = "vreg_l10e";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3401000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11e: ldo11 {
+ regulator-name = "vreg_l11e";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3401000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_bob: bob {
+ regulator-name = "vreg_bob";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <5492000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
@@ -407,7 +565,79 @@
};
&i2c10 {
- /* PM8008 PMIC @ 8 and 9 */
+ clock-frequency = <400000>;
+ status = "okay";
+
+ pm8008: pmic@8 {
+ compatible = "qcom,pm8008";
+ reg = <0x8>;
+
+ interrupts-extended = <&tlmm 59 IRQ_TYPE_EDGE_RISING>;
+ reset-gpios = <&tlmm 58 GPIO_ACTIVE_LOW>;
+
+ vdd-l1-l2-supply = <&vreg_s8e>;
+ vdd-l3-l4-supply = <&vreg_bob>;
+ vdd-l5-supply = <&vreg_bob>;
+ vdd-l6-supply = <&vreg_s2a>;
+ vdd-l7-supply = <&vreg_bob>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm8008_default>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pm8008 0 0 2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ #thermal-sensor-cells = <0>;
+
+ regulators {
+ vreg_l1p: ldo1 {
+ regulator-name = "vreg_l1p";
+ regulator-min-microvolt = <528000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l2p: ldo2 {
+ regulator-name = "vreg_l2p";
+ regulator-min-microvolt = <528000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l3p: ldo3 {
+ regulator-name = "vreg_l3p";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vreg_l4p: ldo4 {
+ regulator-name = "vreg_l4p";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2904000>;
+ };
+
+ vreg_l5p: ldo5 {
+ regulator-name = "vreg_l5p";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ vreg_l6p: ldo6 {
+ regulator-name = "vreg_l6p";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vreg_l7p: ldo7 {
+ regulator-name = "vreg_l7p";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <3140000>;
+ };
+ };
+ };
+
/* PX8618 @ 26 */
/* SMB1395 PMIC @ 34 */
/* awinic,aw8695 @ 5a */
@@ -462,6 +692,91 @@
status = "okay";
};
+&pm6150l_adc {
+ pinctrl-0 = <&pm6150l_adc_default>;
+ pinctrl-names = "default";
+
+ channel@4d {
+ reg = <ADC5_AMUX_THM1_100K_PU>;
+ label = "pa_therm1";
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ qcom,ratiometric;
+ };
+
+ channel@4e {
+ reg = <ADC5_AMUX_THM2_100K_PU>;
+ label = "msm_therm";
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ qcom,ratiometric;
+ };
+
+ channel@4f {
+ reg = <ADC5_AMUX_THM3_100K_PU>;
+ label = "pa_therm0";
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ qcom,ratiometric;
+ };
+
+ channel@53 {
+ reg = <ADC5_GPIO2_100K_PU>;
+ label = "rear_cam_therm";
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ qcom,ratiometric;
+ };
+
+ channel@54 {
+ reg = <ADC5_GPIO3_100K_PU>;
+ label = "rear_cam_flash_therm";
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ qcom,ratiometric;
+ };
+
+ channel@55 {
+ reg = <ADC5_GPIO4_100K_PU>;
+ label = "quiet_therm";
+ qcom,hw-settle-time = <200>;
+ qcom,pre-scaling = <1 1>;
+ qcom,ratiometric;
+ };
+};
+
+&pm6150l_adc_tm {
+ status = "okay";
+
+ pa-therm1@0 {
+ reg = <0>;
+ io-channels = <&pm6150l_adc ADC5_AMUX_THM1_100K_PU>;
+ qcom,hw-settle-time-us = <200>;
+ qcom,ratiometric;
+ };
+
+ pa-therm0@1 {
+ reg = <1>;
+ io-channels = <&pm6150l_adc ADC5_AMUX_THM3_100K_PU>;
+ qcom,hw-settle-time-us = <200>;
+ qcom,ratiometric;
+ };
+
+ rear-cam-flash-therm@2 {
+ reg = <2>;
+ io-channels = <&pm6150l_adc ADC5_GPIO3_100K_PU>;
+ qcom,hw-settle-time-us = <200>;
+ qcom,ratiometric;
+ };
+
+ quiet-therm@3 {
+ reg = <3>;
+ io-channels = <&pm6150l_adc ADC5_GPIO4_100K_PU>;
+ qcom,hw-settle-time-us = <200>;
+ qcom,ratiometric;
+ };
+};
+
&pm6150l_flash {
status = "okay";
@@ -484,6 +799,14 @@
};
};
+&pm6150l_gpios {
+ pm6150l_adc_default: adc-default-state {
+ pins = "gpio6", "gpio7", "gpio10";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ bias-high-impedance;
+ };
+};
+
&pm6150l_wled {
qcom,switching-freq = <800>;
qcom,current-limit-microamp = <20000>;
@@ -543,6 +866,64 @@
};
};
+&pm7250b_typec {
+ vdd-pdphy-supply = <&vreg_l3a>;
+
+ status = "okay";
+
+ connector {
+ compatible = "usb-c-connector";
+
+ power-role = "dual";
+ data-role = "dual";
+ self-powered;
+
+ /*
+ * Disable USB Power Delivery for now, seems to need extra work
+ * to support role switching while also letting the battery
+ * charge still - without charger driver
+ */
+ typec-power-opmode = "default";
+ pd-disable;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ pm7250b_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ pm7250b_ss_in: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_out>;
+ };
+ };
+ };
+ };
+};
+
+&pm7250b_vbus {
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <1500000>;
+ status = "okay";
+};
+
+&pmk8350_adc_tm {
+ status = "okay";
+
+ xo-therm@0 {
+ reg = <0>;
+ io-channels = <&pmk8350_vadc PMK8350_ADC7_AMUX_THM1_100K_PU>;
+ qcom,hw-settle-time-us = <200>;
+ qcom,ratiometric;
+ };
+};
+
&pmk8350_rtc {
status = "okay";
};
@@ -673,6 +1054,22 @@
*/
bias-pull-up;
};
+
+ pm8008_default: pm8008-default-state {
+ int-pins {
+ pins = "gpio59";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ reset-n-pins {
+ pins = "gpio58";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
};
&uart1 {
@@ -726,7 +1123,11 @@
&usb_1_dwc3 {
maximum-speed = "super-speed";
- dr_mode = "peripheral";
+ dr_mode = "otg";
+};
+
+&usb_1_dwc3_hs_out {
+ remote-endpoint = <&pm7250b_hs_in>;
};
&usb_1_hsphy {
@@ -744,6 +1145,10 @@
status = "okay";
};
+&usb_1_qmpphy_out {
+ remote-endpoint = <&pm7250b_ss_in>;
+};
+
&wifi {
vdd-0.8-cx-mx-supply = <&vreg_l4a>;
vdd-1.8-xo-supply = <&vreg_l7a>;
diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts
index de670b407ef1..bac08f00b303 100644
--- a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts
@@ -470,7 +470,6 @@
&mdss_dp_out {
data-lanes = <0 1>;
- remote-endpoint = <&usb_1_qmpphy_dp_in>;
};
&mdss_dsi0 {
@@ -556,7 +555,7 @@
port@0 {
reg = <0>;
- pm8150b_role_switch_in: endpoint {
+ pm8150b_hs_in: endpoint {
remote-endpoint = <&usb_1_dwc3_hs>;
};
};
@@ -609,6 +608,11 @@
firmware-name = "qcom/sm8150/cdsp.mbn";
};
+&remoteproc_mpss {
+ firmware-name = "qcom/sm8150/modem.mbn";
+ status = "okay";
+};
+
&remoteproc_slpi {
status = "okay";
@@ -671,18 +675,10 @@
orientation-switch;
};
-&usb_1_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp_out>;
-};
-
&usb_1_qmpphy_out {
remote-endpoint = <&pm8150b_typec_mux_in>;
};
-&usb_1_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&usb_2_qmpphy {
status = "okay";
vdda-phy-supply = <&vreg_l3c_1p2>;
@@ -703,13 +699,20 @@
};
&usb_1_dwc3_hs {
- remote-endpoint = <&pm8150b_role_switch_in>;
-};
-
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
+ remote-endpoint = <&pm8150b_hs_in>;
};
&usb_2_dwc3 {
dr_mode = "host";
};
+
+&wifi {
+ status = "okay";
+
+ vdd-0.8-cx-mx-supply = <&vreg_l1a_0p75>;
+ vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+ vdd-1.3-rfa-supply = <&vreg_l2c_1p3>;
+ vdd-3.3-ch0-supply = <&vreg_l11c_3p3>;
+
+ qcom,ath10k-calibration-variant = "Qualcomm_sm8150hdk";
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index a35c0852b5a1..3e236adb9397 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/clock/qcom,dispcc-sm8150.h>
#include <dt-bindings/clock/qcom,gcc-sm8150.h>
#include <dt-bindings/clock/qcom,gpucc-sm8150.h>
+#include <dt-bindings/clock/qcom,videocc-sm8150.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sm8150.h>
#include <dt-bindings/thermal/thermal.h>
@@ -1901,6 +1902,16 @@
pinctrl-0 = <&pcie0_default_state>;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -2011,6 +2022,16 @@
pinctrl-0 = <&pcie1_default_state>;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -3487,6 +3508,7 @@
reg = <1>;
usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
};
};
@@ -3494,6 +3516,7 @@
reg = <2>;
usb_1_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp_out>;
};
};
};
@@ -3652,6 +3675,7 @@
reg = <1>;
usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
};
};
};
@@ -3715,6 +3739,19 @@
};
};
+ videocc: clock-controller@ab00000 {
+ compatible = "qcom,sm8150-videocc";
+ reg = <0 0x0ab00000 0 0x10000>;
+ clocks = <&gcc GCC_VIDEO_AHB_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "iface", "bi_tcxo";
+ power-domains = <&rpmhpd SM8150_MMCX>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
camnoc_virt: interconnect@ac00000 {
compatible = "qcom,sm8150-camnoc-virt";
reg = <0 0x0ac00000 0 0x1000>;
@@ -3874,6 +3911,7 @@
reg = <1>;
mdss_dp_out: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_dp_in>;
};
};
};
@@ -4557,7 +4595,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -4601,7 +4638,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -4645,7 +4681,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -4689,7 +4724,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -4733,7 +4767,6 @@
cpu4-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -4777,7 +4810,6 @@
cpu5-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -4821,7 +4853,6 @@
cpu6-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -4865,7 +4896,6 @@
cpu7-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -4909,7 +4939,6 @@
cpu4-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 11>;
@@ -4953,7 +4982,6 @@
cpu5-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -4997,7 +5025,6 @@
cpu6-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 13>;
@@ -5041,7 +5068,6 @@
cpu7-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 14>;
@@ -5085,7 +5111,6 @@
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 0>;
@@ -5100,7 +5125,6 @@
cluster0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -5120,7 +5144,6 @@
cluster1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -5140,7 +5163,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 15>;
@@ -5153,16 +5175,27 @@
trips {
gpu_top_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
aoss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 0>;
@@ -5177,7 +5210,6 @@
wlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -5192,7 +5224,6 @@
video-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -5207,7 +5238,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -5222,7 +5252,6 @@
q6-hvx-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
@@ -5237,7 +5266,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 5>;
@@ -5252,7 +5280,6 @@
compute-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -5267,7 +5294,6 @@
modem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 7>;
@@ -5282,7 +5308,6 @@
npu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 8>;
@@ -5297,7 +5322,6 @@
modem-vec-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 9>;
@@ -5312,7 +5336,6 @@
modem-scl-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 10>;
@@ -5327,7 +5350,6 @@
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 11>;
@@ -5340,10 +5362,22 @@
trips {
gpu_bottom_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
index 7ef99038cb37..21b2ca1def83 100644
--- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
@@ -53,8 +53,6 @@
thermal-zones {
camera-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150l_adc_tm 0>;
trips {
@@ -67,8 +65,6 @@
};
conn-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150b_adc_tm 0>;
trips {
@@ -81,8 +77,6 @@
};
mmw-pa1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150_adc_tm 2>;
trips {
@@ -95,8 +89,6 @@
};
mmw-pa2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150l_adc_tm 2>;
trips {
@@ -109,8 +101,6 @@
};
skin-msm-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150l_adc_tm 1>;
trips {
@@ -123,8 +113,6 @@
};
skin-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150_adc_tm 1>;
trips {
@@ -137,8 +125,6 @@
};
xo-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pm8150_adc_tm 0>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
index e07d0311ecb5..f6870d3f2886 100644
--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
@@ -520,7 +520,7 @@
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&tlmm>;
- interrupts = <39 0x2008>;
+ interrupts = <39 IRQ_TYPE_LEVEL_LOW>;
/* It's "vddio" downstream but it works anyway! */
vdd-supply = <&vreg_l1c_1p8>;
avdd-supply = <&vreg_l10c_3p3>;
diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi
index 6f54f50a70b0..3596dd328c31 100644
--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi
@@ -636,7 +636,8 @@
connector {
compatible = "usb-c-connector";
- power-role = "source";
+ op-sink-microwatt = <10000000>;
+ power-role = "dual";
data-role = "dual";
self-powered;
@@ -645,6 +646,12 @@
PDO_FIXED_USB_COMM |
PDO_FIXED_DATA_SWAP)>;
+ sink-pdos = <PDO_FIXED(5000, 3000,
+ PDO_FIXED_DUAL_ROLE |
+ PDO_FIXED_USB_COMM |
+ PDO_FIXED_DATA_SWAP)
+ PDO_VAR(5000, 12000, 5000)>;
+
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -652,8 +659,8 @@
port@0 {
reg = <0>;
- pm8150b_role_switch_in: endpoint {
- remote-endpoint = <&usb_1_role_switch_out>;
+ pm8150b_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs_out>;
};
};
};
@@ -661,6 +668,8 @@
};
&pm8150b_vbus {
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <3000000>;
status = "okay";
};
@@ -716,8 +725,8 @@
status = "okay";
};
-&usb_1_role_switch_out {
- remote-endpoint = <&pm8150b_role_switch_in>;
+&usb_1_dwc3_hs_out {
+ remote-endpoint = <&pm8150b_hs_in>;
};
&ufs_mem_hc {
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 7f2333c9d17d..9d6c97d1fd9d 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -2203,6 +2203,16 @@
dma-coherent;
status = "disabled";
+
+ pcieport0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -2318,6 +2328,16 @@
dma-coherent;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -2433,6 +2453,16 @@
dma-coherent;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie2_phy: phy@1c16000 {
@@ -2550,6 +2580,8 @@
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
#phy-cells = <0>;
status = "disabled";
@@ -3906,6 +3938,8 @@
#clock-cells = <1>;
#phy-cells = <1>;
+ orientation-switch;
+
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -3917,6 +3951,10 @@
port@1 {
reg = <1>;
+
+ usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss_out>;
+ };
};
port@2 {
@@ -4195,8 +4233,24 @@
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
- port {
- usb_1_role_switch_out: endpoint {};
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_dwc3_hs_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_dwc3_ss_out: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
+ };
+ };
};
};
};
@@ -6245,7 +6299,6 @@
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -6289,7 +6342,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -6333,7 +6385,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -6377,7 +6428,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -6421,7 +6471,6 @@
cpu4-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -6465,7 +6514,6 @@
cpu5-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -6509,7 +6557,6 @@
cpu6-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -6553,7 +6600,6 @@
cpu7-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -6597,7 +6643,6 @@
cpu4-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 11>;
@@ -6641,7 +6686,6 @@
cpu5-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -6685,7 +6729,6 @@
cpu6-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 13>;
@@ -6729,7 +6772,6 @@
cpu7-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 14>;
@@ -6773,7 +6815,6 @@
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 0>;
@@ -6788,7 +6829,6 @@
cluster0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -6808,7 +6848,6 @@
cluster1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -6828,7 +6867,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 15>;
@@ -6841,16 +6879,27 @@
trips {
gpu_top_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
aoss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 0>;
@@ -6865,7 +6914,6 @@
wlan-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -6880,7 +6928,6 @@
video-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -6895,7 +6942,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -6910,7 +6956,6 @@
q6-hvx-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
@@ -6925,7 +6970,6 @@
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 5>;
@@ -6940,7 +6984,6 @@
compute-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -6955,7 +6998,6 @@
npu-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 7>;
@@ -6970,7 +7012,6 @@
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 8>;
@@ -6983,10 +7024,22 @@
trips {
gpu_bottom_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
index b43d264ed42b..895adce59e75 100644
--- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
@@ -42,6 +42,7 @@
compatible = "qcom,sm8350-pmic-glink", "qcom,pmic-glink";
#address-cells = <1>;
#size-cells = <0>;
+ orientation-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>;
connector@0 {
compatible = "usb-c-connector";
@@ -485,17 +486,10 @@
&mdss_dp {
status = "okay";
+};
- ports {
- port@1 {
- reg = <1>;
-
- mdss_dp0_out: endpoint {
- data-lanes = <0 1>;
- remote-endpoint = <&usb_1_qmpphy_dp_in>;
- };
- };
- };
+&mdss_dp_out {
+ data-lanes = <0 1>;
};
&mpss {
@@ -863,10 +857,6 @@
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
-};
-
&usb_1_hsphy {
status = "okay";
@@ -880,22 +870,12 @@
vdda-phy-supply = <&vreg_l6b_1p2>;
vdda-pll-supply = <&vreg_l1b_0p88>;
-
- orientation-switch;
-};
-
-&usb_1_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp0_out>;
};
&usb_1_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
-&usb_1_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&usb_2 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
index a5e7dbbd8c6c..38ee0850c335 100644
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,sm8350.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
@@ -300,8 +301,18 @@
reg = <0x0 0x80000000 0x0 0x0>;
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-a78 {
+ compatible = "arm,cortex-a78-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-x1 {
+ compatible = "arm,cortex-x1-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
@@ -1572,6 +1583,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -1669,6 +1690,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -1730,6 +1761,11 @@
<&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
<&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
<&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+ interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "ufs-ddr", "cpu-ufs";
freq-table-hz =
<75000000 300000000>,
<0 0>,
@@ -1753,6 +1789,8 @@
"ref_aux",
"qref";
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -2230,6 +2268,8 @@
#clock-cells = <1>;
#phy-cells = <1>;
+ orientation-switch;
+
status = "disabled";
ports {
@@ -2247,6 +2287,7 @@
reg = <1>;
usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
};
};
@@ -2254,6 +2295,7 @@
reg = <2>;
usb_1_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp_out>;
};
};
};
@@ -2379,6 +2421,7 @@
reg = <1>;
usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
};
};
};
@@ -2600,6 +2643,14 @@
remote-endpoint = <&dpu_intf0_out>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dp_out: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_dp_in>;
+ };
+ };
};
dp_opp_table: opp-table {
@@ -3639,7 +3690,6 @@
thermal_zones: thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
@@ -3683,7 +3733,6 @@
cpu1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 2>;
@@ -3727,7 +3776,6 @@
cpu2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 3>;
@@ -3771,7 +3819,6 @@
cpu3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 4>;
@@ -3815,7 +3862,6 @@
cpu4-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 7>;
@@ -3859,7 +3905,6 @@
cpu5-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 8>;
@@ -3903,7 +3948,6 @@
cpu6-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 9>;
@@ -3947,7 +3991,6 @@
cpu7-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 10>;
@@ -3991,7 +4034,6 @@
cpu4-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 11>;
@@ -4035,7 +4077,6 @@
cpu5-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 12>;
@@ -4079,7 +4120,6 @@
cpu6-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 13>;
@@ -4123,7 +4163,6 @@
cpu7-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 14>;
@@ -4167,7 +4206,6 @@
aoss0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 0>;
@@ -4182,7 +4220,6 @@
cluster0-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 5>;
@@ -4202,7 +4239,6 @@
cluster1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens0 6>;
@@ -4222,7 +4258,6 @@
aoss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 0>;
@@ -4237,7 +4272,6 @@
gpu-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 1>;
@@ -4250,16 +4284,27 @@
trips {
gpu_top_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
gpu-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 2>;
@@ -4272,16 +4317,27 @@
trips {
gpu_bottom_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
hysteresis = <1000>;
type = "hot";
};
+
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
};
};
nspss1-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 3>;
@@ -4296,7 +4352,6 @@
nspss2-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 4>;
@@ -4311,7 +4366,6 @@
nspss3-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 5>;
@@ -4326,7 +4380,6 @@
video-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 6>;
@@ -4341,7 +4394,6 @@
mem-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 7>;
@@ -4356,7 +4408,6 @@
modem1-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 8>;
@@ -4371,7 +4422,6 @@
modem2-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 9>;
@@ -4386,7 +4436,6 @@
modem3-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 10>;
@@ -4401,7 +4450,6 @@
modem4-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 11>;
@@ -4416,7 +4464,6 @@
camera-top-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 12>;
@@ -4431,7 +4478,6 @@
cam-bottom-thermal {
polling-delay-passive = <250>;
- polling-delay = <1000>;
thermal-sensors = <&tsens1 13>;
diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
index 0786cff07b89..a754b8fe9167 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -95,6 +95,7 @@
compatible = "qcom,sm8450-pmic-glink", "qcom,pmic-glink";
#address-cells = <1>;
#size-cells = <0>;
+ orientation-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
connector@0 {
compatible = "usb-c-connector";
@@ -137,7 +138,7 @@
thermal-zones {
camera-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 2>;
trips {
@@ -151,7 +152,7 @@
rear-tof-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 5>;
trips {
@@ -165,7 +166,7 @@
skin-msm-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 1>;
trips {
@@ -179,7 +180,7 @@
therm1-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 3>;
trips {
@@ -193,7 +194,7 @@
therm2-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 6>;
trips {
@@ -207,7 +208,7 @@
usb-conn-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 7>;
trips {
@@ -221,7 +222,7 @@
wide-rfc-thermal {
polling-delay-passive = <250>;
- polling-delay = <0>;
+
thermal-sensors = <&pmk8350_adc_tm 4>;
trips {
@@ -234,8 +235,6 @@
};
xo-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&pmk8350_adc_tm 0>;
trips {
@@ -673,17 +672,10 @@
&mdss_dp0 {
status = "okay";
+};
- ports {
- port@1 {
- reg = <1>;
-
- mdss_dp0_out: endpoint {
- data-lanes = <0 1>;
- remote-endpoint = <&usb_1_qmpphy_dp_in>;
- };
- };
- };
+&mdss_dp0_out {
+ data-lanes = <0 1>;
};
&pcie0 {
@@ -1113,10 +1105,6 @@
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
-};
-
&usb_1_hsphy {
status = "okay";
@@ -1130,22 +1118,12 @@
vdda-phy-supply = <&vreg_l6b_1p2>;
vdda-pll-supply = <&vreg_l1b_0p91>;
-
- orientation-switch;
-};
-
-&usb_1_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp0_out>;
};
&usb_1_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
-&usb_1_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&vamacro {
pinctrl-0 = <&dmic01_default>, <&dmic23_default>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/qcom/sm8450-qrd.dts b/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
index c7d05945aa51..7b62ead68e77 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
@@ -467,6 +467,14 @@
vdda-pll-supply = <&vreg_l5b_0p88>;
vdda18-supply = <&vreg_l1c_1p8>;
vdda33-supply = <&vreg_l2b_3p07>;
+ qcom,squelch-detector-bp = <(-2090)>;
+ qcom,hs-disconnect-bp = <1743>;
+ qcom,pre-emphasis-amplitude-bp = <40000>;
+ qcom,pre-emphasis-duration-bp = <20000>;
+ qcom,hs-amplitude-bp = <2000>;
+ qcom,hs-output-impedance-micro-ohms = <2600000>;
+ qcom,hs-crossover-voltage-microvolt = <(-31000)>;
+ qcom,hs-rise-fall-time-bp = <(-4100)>;
};
&usb_1_qmpphy {
diff --git a/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi b/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi
index 8b29fcf483a3..17dbb67868ae 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi
@@ -488,7 +488,7 @@
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&tlmm>;
- interrupts = <21 0x2008>;
+ interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&pm8350c_l2>;
avdd-supply = <&pm8350c_l3>;
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 024d2653cc30..9bafb3b350ff 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -754,8 +754,8 @@
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&sleep_clk>,
<&pcie0_phy>,
- <&pcie1_phy>,
- <0>,
+ <&pcie1_phy QMP_PCIE_PIPE_CLK>,
+ <&pcie1_phy QMP_PCIE_PHY_AUX_CLK>,
<&ufs_mem_phy 0>,
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
@@ -1803,6 +1803,12 @@
<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+ interconnects = <&pcie_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_PCIE_0 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+
clocks = <&gcc GCC_PCIE_0_PIPE_CLK>,
<&gcc GCC_PCIE_0_PIPE_CLK_SRC>,
<&pcie0_phy>,
@@ -1845,7 +1851,44 @@
pinctrl-names = "default";
pinctrl-0 = <&pcie0_default_state>;
+ operating-points-v2 = <&pcie0_opp_table>;
+
status = "disabled";
+
+ pcie0_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* GEN 1 x1 */
+ opp-2500000 {
+ opp-hz = /bits/ 64 <2500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <250000 1>;
+ };
+
+ /* GEN 2 x1 */
+ opp-5000000 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ };
+
+ /* GEN 3 x1 */
+ opp-8000000 {
+ opp-hz = /bits/ 64 <8000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <984500 1>;
+ };
+ };
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -1922,6 +1965,12 @@
<0 0 0 3 &intc 0 0 0 438 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
<0 0 0 4 &intc 0 0 0 439 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+ interconnects = <&pcie_noc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_PCIE_1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+
clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
<&gcc GCC_PCIE_1_PIPE_CLK_SRC>,
<&pcie1_phy>,
@@ -1962,7 +2011,65 @@
pinctrl-names = "default";
pinctrl-0 = <&pcie1_default_state>;
+ operating-points-v2 = <&pcie1_opp_table>;
+
status = "disabled";
+
+ pcie1_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* GEN 1 x1 */
+ opp-2500000 {
+ opp-hz = /bits/ 64 <2500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <250000 1>;
+ };
+
+ /* GEN 1 x2 and GEN 2 x1 */
+ opp-5000000 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ };
+
+ /* GEN 2 x2 */
+ opp-10000000 {
+ opp-hz = /bits/ 64 <10000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <1000000 1>;
+ };
+
+ /* GEN 3 x1 */
+ opp-8000000 {
+ opp-hz = /bits/ 64 <8000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <984500 1>;
+ };
+
+ /* GEN 3 x2 and GEN 4 x1 */
+ opp-16000000 {
+ opp-hz = /bits/ 64 <16000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <1969000 1>;
+ };
+
+ /* GEN 4 x2 */
+ opp-32000000 {
+ opp-hz = /bits/ 64 <32000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <3938000 1>;
+ };
+ };
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -1981,7 +2088,7 @@
"pipe";
clock-output-names = "pcie_1_pipe_clk";
- #clock-cells = <0>;
+ #clock-cells = <1>;
#phy-cells = <0>;
@@ -2284,6 +2391,8 @@
#clock-cells = <1>;
#phy-cells = <1>;
+ orientation-switch;
+
status = "disabled";
ports {
@@ -2301,6 +2410,7 @@
reg = <1>;
usb_1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
};
};
@@ -2308,6 +2418,7 @@
reg = <2>;
usb_1_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp0_out>;
};
};
};
@@ -2355,6 +2466,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "sdsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -2657,6 +2769,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "adsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -2723,6 +2836,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "cdsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -3096,6 +3210,14 @@
remote-endpoint = <&dpu_intf0_out>;
};
};
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dp0_out: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_dp_in>;
+ };
+ };
};
dp_opp_table: opp-table {
@@ -4339,9 +4461,10 @@
compatible = "qcom,sm8450-llcc";
reg = <0 0x19200000 0 0x80000>, <0 0x19600000 0 0x80000>,
<0 0x19300000 0 0x80000>, <0 0x19700000 0 0x80000>,
- <0 0x19a00000 0 0x80000>;
+ <0 0x19a00000 0 0x80000>, <0 0x19c00000 0 0x80000>;
reg-names = "llcc0_base", "llcc1_base", "llcc2_base",
- "llcc3_base", "llcc_broadcast_base";
+ "llcc3_base", "llcc_broadcast_base",
+ "llcc_broadcast_and_base";
interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -4406,6 +4529,8 @@
<&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
<&gcc GCC_UFS_0_CLKREF_EN>;
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -4561,6 +4686,7 @@
reg = <1>;
usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_usb_ss_in>;
};
};
};
@@ -4587,8 +4713,6 @@
thermal-zones {
aoss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 0>;
trips {
@@ -4607,8 +4731,6 @@
};
cpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
trips {
@@ -4627,8 +4749,6 @@
};
cpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
trips {
@@ -4647,8 +4767,6 @@
};
cpuss3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
trips {
@@ -4667,8 +4785,6 @@
};
cpuss4-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
trips {
@@ -4687,8 +4803,6 @@
};
cpu4-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
trips {
@@ -4713,8 +4827,6 @@
};
cpu4-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
trips {
@@ -4739,8 +4851,6 @@
};
cpu5-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
trips {
@@ -4765,8 +4875,6 @@
};
cpu5-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
trips {
@@ -4791,8 +4899,6 @@
};
cpu6-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
trips {
@@ -4817,8 +4923,6 @@
};
cpu6-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
trips {
@@ -4843,8 +4947,6 @@
};
cpu7-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
trips {
@@ -4869,8 +4971,6 @@
};
cpu7-middle-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
trips {
@@ -4895,8 +4995,6 @@
};
cpu7-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 13>;
trips {
@@ -4922,7 +5020,7 @@
gpu-top-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens0 14>;
cooling-maps {
@@ -4933,35 +5031,29 @@
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu_top_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
+ type = "hot";
};
- reset-mon-cfg {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
- };
-
- gpu_top_alert0: trip-point0 {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpu-bottom-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens0 15>;
cooling-maps {
@@ -4972,35 +5064,27 @@
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu_bottom_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
- };
-
- reset-mon-cfg {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
+ type = "hot";
};
- gpu_bottom_alert0: trip-point0 {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
aoss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 0>;
trips {
@@ -5019,8 +5103,6 @@
};
cpu0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
trips {
@@ -5045,8 +5127,6 @@
};
cpu1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
trips {
@@ -5071,8 +5151,6 @@
};
cpu2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 3>;
trips {
@@ -5097,8 +5175,6 @@
};
cpu3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 4>;
trips {
@@ -5124,7 +5200,7 @@
cdsp0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 5>;
trips {
@@ -5156,7 +5232,7 @@
cdsp1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 6>;
trips {
@@ -5188,7 +5264,7 @@
cdsp2-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 7>;
trips {
@@ -5219,8 +5295,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 8>;
trips {
@@ -5240,7 +5314,7 @@
mem-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 9>;
trips {
@@ -5265,8 +5339,6 @@
};
modem0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 10>;
trips {
@@ -5297,8 +5369,6 @@
};
modem1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 11>;
trips {
@@ -5329,8 +5399,6 @@
};
modem2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 12>;
trips {
@@ -5361,8 +5429,6 @@
};
modem3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 13>;
trips {
@@ -5393,8 +5459,6 @@
};
camera0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 14>;
trips {
@@ -5413,8 +5477,6 @@
};
camera1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 15>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts
index 12d60a0ee095..2e12219006c9 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts
@@ -940,7 +940,6 @@
};
&mdss_dp0_out {
- remote-endpoint = <&usb_dp_qmpphy_dp_in>;
data-lanes = <0 1>;
};
@@ -979,10 +978,6 @@
status = "okay";
};
-&pcie_1_phy_aux_clk {
- clock-frequency = <1000>;
-};
-
&pm8550_gpios {
sdc2_card_det_n: sdc2-card-det-state {
pins = "gpio12";
@@ -1111,6 +1106,7 @@
#sound-dai-cells = <0>;
sound-name-prefix = "SpkrLeft";
+ qcom,port-mapping = <1 2 3 7 10 13>;
};
/* WSA8845, Speaker South */
@@ -1128,6 +1124,7 @@
#sound-dai-cells = <0>;
sound-name-prefix = "SpkrRight";
+ qcom,port-mapping = <4 5 6 7 11 13>;
};
};
@@ -1258,19 +1255,10 @@
status = "okay";
};
-&usb_1_dwc3 {
- dr_mode = "otg";
- usb-role-switch;
-};
-
&usb_1_dwc3_hs {
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
-};
-
&usb_1_hsphy {
vdd-supply = <&vreg_l1e_0p88>;
vdda12-supply = <&vreg_l3e_1p2>;
@@ -1284,23 +1272,13 @@
vdda-phy-supply = <&vreg_l3e_1p2>;
vdda-pll-supply = <&vreg_l3f_0p88>;
- orientation-switch;
-
status = "okay";
};
-&usb_dp_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp0_out>;
-};
-
&usb_dp_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
-&usb_dp_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&xo_board {
clock-frequency = <76800000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
index 3d4ad5aac70f..ab447fc252f7 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
@@ -736,11 +736,6 @@
&mdss_dp0_out {
data-lanes = <0 1>;
- remote-endpoint = <&usb_dp_qmpphy_dp_in>;
-};
-
-&pcie_1_phy_aux_clk {
- clock-frequency = <1000>;
};
&pcie0 {
@@ -847,6 +842,7 @@
sound-name-prefix = "SpkrLeft";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3g_1p2>;
+ qcom,port-mapping = <1 2 3 7 10 13>;
};
/* WSA8845 */
@@ -860,6 +856,7 @@
sound-name-prefix = "SpkrRight";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3g_1p2>;
+ qcom,port-mapping = <4 5 6 7 11 13>;
};
};
@@ -951,19 +948,10 @@
status = "okay";
};
-&usb_1_dwc3 {
- dr_mode = "otg";
- usb-role-switch;
-};
-
&usb_1_dwc3_hs {
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
-};
-
&usb_1_hsphy {
vdd-supply = <&vreg_l1e_0p88>;
vdda12-supply = <&vreg_l3e_1p2>;
@@ -977,23 +965,13 @@
vdda-phy-supply = <&vreg_l3e_1p2>;
vdda-pll-supply = <&vreg_l3f_0p91>;
- orientation-switch;
-
status = "okay";
};
-&usb_dp_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp0_out>;
-};
-
&usb_dp_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
-&usb_dp_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&xo_board {
clock-frequency = <76800000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
index 92f015017418..774bdfcffec3 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -214,6 +214,68 @@
regulator-always-on;
regulator-boot-on;
};
+
+ wcn7850-pmu {
+ compatible = "qcom,wcn7850-pmu";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_en>, <&pmk8550_sleep_clk>;
+
+ wlan-enable-gpios = <&tlmm 80 GPIO_ACTIVE_HIGH>;
+ /*
+ * TODO Add bt-enable-gpios once the Bluetooth driver is
+ * converted to using the power sequencer.
+ */
+
+ vdd-supply = <&vreg_s5g_0p85>;
+ vddio-supply = <&vreg_l15b_1p8>;
+ vddaon-supply = <&vreg_s2g_0p85>;
+ vdddig-supply = <&vreg_s4e_0p95>;
+ vddrfa1p2-supply = <&vreg_s4g_1p25>;
+ vddrfa1p8-supply = <&vreg_s6g_1p86>;
+
+ regulators {
+ vreg_pmu_rfa_cmn: ldo0 {
+ regulator-name = "vreg_pmu_rfa_cmn";
+ };
+
+ vreg_pmu_aon_0p59: ldo1 {
+ regulator-name = "vreg_pmu_aon_0p59";
+ };
+
+ vreg_pmu_wlcx_0p8: ldo2 {
+ regulator-name = "vreg_pmu_wlcx_0p8";
+ };
+
+ vreg_pmu_wlmx_0p85: ldo3 {
+ regulator-name = "vreg_pmu_wlmx_0p85";
+ };
+
+ vreg_pmu_btcmx_0p85: ldo4 {
+ regulator-name = "vreg_pmu_btcmx_0p85";
+ };
+
+ vreg_pmu_rfa_0p8: ldo5 {
+ regulator-name = "vreg_pmu_rfa_0p8";
+ };
+
+ vreg_pmu_rfa_1p2: ldo6 {
+ regulator-name = "vreg_pmu_rfa_1p2";
+ };
+
+ vreg_pmu_rfa_1p8: ldo7 {
+ regulator-name = "vreg_pmu_rfa_1p8";
+ };
+
+ vreg_pmu_pcie_0p9: ldo8 {
+ regulator-name = "vreg_pmu_pcie_0p9";
+ };
+
+ vreg_pmu_pcie_1p8: ldo9 {
+ regulator-name = "vreg_pmu_pcie_1p8";
+ };
+ };
+ };
};
&apps_rsc {
@@ -720,17 +782,6 @@
status = "okay";
};
-&gcc {
- clocks = <&bi_tcxo_div2>, <&sleep_clk>,
- <&pcie0_phy>,
- <&pcie1_phy>,
- <0>,
- <&ufs_mem_phy 0>,
- <&ufs_mem_phy 1>,
- <&ufs_mem_phy 2>,
- <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
-};
-
&gpi_dma1 {
status = "okay";
};
@@ -807,11 +858,6 @@
&mdss_dp0_out {
data-lanes = <0 1>;
- remote-endpoint = <&usb_dp_qmpphy_dp_in>;
-};
-
-&pcie_1_phy_aux_clk {
- status = "disabled";
};
&pcie0 {
@@ -824,6 +870,23 @@
status = "okay";
};
+&pcieport0 {
+ wifi@0 {
+ compatible = "pci17cb,1107";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ };
+};
+
&pcie0_phy {
vdda-phy-supply = <&vreg_l1e_0p88>;
vdda-pll-supply = <&vreg_l3e_1p2>;
@@ -907,8 +970,15 @@
status = "okay";
};
-&pcie_1_phy_aux_clk {
- clock-frequency = <1000>;
+&pmk8550_gpios {
+ pmk8550_sleep_clk: sleep-clk-state {
+ pins = "gpio3";
+ function = "func1";
+ input-disable;
+ output-enable;
+ bias-disable;
+ power-source = <0>;
+ };
};
&qupv3_id_0 {
@@ -955,6 +1025,7 @@
sound-name-prefix = "SpkrLeft";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3g_1p2>;
+ qcom,port-mapping = <1 2 3 7 10 13>;
};
/* WSA8845, Speaker South */
@@ -968,6 +1039,7 @@
sound-name-prefix = "SpkrRight";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3g_1p2>;
+ qcom,port-mapping = <4 5 6 7 11 13>;
};
};
@@ -1084,6 +1156,13 @@
bias-disable;
output-low;
};
+
+ wlan_en: wlan-en-state {
+ pins = "gpio80";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
};
&uart7 {
@@ -1135,19 +1214,10 @@
status = "okay";
};
-&usb_1_dwc3 {
- dr_mode = "otg";
- usb-role-switch;
-};
-
&usb_1_dwc3_hs {
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
-};
-
&usb_1_hsphy {
vdd-supply = <&vreg_l1e_0p88>;
vdda12-supply = <&vreg_l3e_1p2>;
@@ -1161,23 +1231,13 @@
vdda-phy-supply = <&vreg_l3e_1p2>;
vdda-pll-supply = <&vreg_l3f_0p88>;
- orientation-switch;
-
status = "okay";
};
-&usb_dp_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp0_out>;
-};
-
&usb_dp_qmpphy_out {
remote-endpoint = <&redriver_ss_in>;
};
-&usb_dp_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&xo_board {
clock-frequency = <76800000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts b/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts
new file mode 100644
index 000000000000..3d351e90bb39
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts
@@ -0,0 +1,593 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
+ * Copyright (c) 2024, David Wronek <david@mainlining.org>
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8550.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+/delete-node/ &adspslpi_mem;
+/delete-node/ &cdsp_mem;
+/delete-node/ &mpss_dsm_mem;
+/delete-node/ &mpss_mem;
+/delete-node/ &rmtfs_mem;
+
+/ {
+ model = "Samsung Galaxy Z Fold5";
+ compatible = "samsung,q5q", "qcom,sm8550";
+ chassis-type = "handset";
+
+ aliases {
+ serial0 = &uart7;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ framebuffer: framebuffer@b8000000 {
+ compatible = "simple-framebuffer";
+ reg = <0x0 0xb8000000 0x0 0x2b00000>;
+ width = <2176>;
+ height = <1812>;
+ stride = <(2176 * 4)>;
+ format = "a8r8g8b8";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&volume_up_n>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reserved-memory {
+ adspslpi_mem: adspslpi@9ea00000 {
+ reg = <0x0 0x9ea00000 0x0 0x59b4000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp-region@9c900000 {
+ reg = <0 0x9c900000 0 0x2000000>;
+ no-map;
+ };
+
+ mpss_dsm_mem: mpss-dsm@d4d00000 {
+ reg = <0x0 0xd4d00000 0x0 0x3300000>;
+ no-map;
+ };
+
+ mpss_mem: mpss@8b400000 {
+ reg = <0x0 0x8b400000 0x0 0xfc00000>;
+ no-map;
+ };
+
+ rmtfs_mem: rmtfs-region@d4a80000 {
+ reg = <0x0 0xd4a80000 0x0 0x280000>;
+ no-map;
+ };
+
+ /*
+ * The bootloader will only keep display hardware enabled
+ * if this memory region is named exactly 'splash_region'
+ */
+ splash_region@b8000000 {
+ reg = <0x0 0xb8000000 0x0 0x2b00000>;
+ no-map;
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3296000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2720000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1b_1p8: ldo1 {
+ regulator-name = "vreg_l1b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5b_3p1: ldo5 {
+ regulator-name = "vreg_l5b_3p1";
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p8: ldo6 {
+ regulator-name = "vreg_l6b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_1p8: ldo7 {
+ regulator-name = "vreg_l7b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b_1p8: ldo8 {
+ regulator-name = "vreg_l8b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_2p9: ldo9 {
+ regulator-name = "vreg_l9b_2p9";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11b_1p2: ldo11 {
+ regulator-name = "vreg_l11b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b_1p8: ldo12 {
+ regulator-name = "vreg_l12b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b_3p0: ldo13 {
+ regulator-name = "vreg_l13b_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p2: ldo14 {
+ regulator-name = "vreg_l14b_3p2";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b_1p8: ldo15 {
+ regulator-name = "vreg_l15b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ regulator-always-on;
+ };
+
+ vreg_l16b_2p8: ldo16 {
+ regulator-name = "vreg_l16b_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b_2p5: ldo17 {
+ regulator-name = "vreg_l17b_2p5";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_l3c_0p91: ldo3 {
+ regulator-name = "vreg_l3c_0p9";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ vreg_l1d_0p88: ldo1 {
+ regulator-name = "vreg_l1d_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vreg_s4e_0p9: smps4 {
+ regulator-name = "vreg_s4e_0p9";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <984000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5e_1p1: smps5 {
+ regulator-name = "vreg_s5e_1p1";
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1e_0p88: ldo1 {
+ regulator-name = "vreg_l1e_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2e_0p9: ldo2 {
+ regulator-name = "vreg_l2e_0p9";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <970000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vreg_s4f_0p5: smps4 {
+ regulator-name = "vreg_s4f_0p5";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <700000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1f_0p9: ldo1 {
+ regulator-name = "vreg_l1f_0p9";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2f_0p88: ldo2 {
+ regulator-name = "vreg_l2f_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3f_0p91: ldo3 {
+ regulator-name = "vreg_l3f_0p91";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-5 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "g";
+
+ vreg_s1g_1p2: smps1 {
+ regulator-name = "vreg_s1g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s2g_0p8: smps2 {
+ regulator-name = "vreg_s2g_0p8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s3g_0p7: smps3 {
+ regulator-name = "vreg_s3g_0p7";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s4g_1p3: smps4 {
+ regulator-name = "vreg_s4g_1p3";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1352000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5g_0p8: smps5 {
+ regulator-name = "vreg_s5g_0p8";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s6g_1p8: smps6 {
+ regulator-name = "vreg_s6g_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1g_1p2: ldo1 {
+ regulator-name = "vreg_l1g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2g_1p2: ldo2 {
+ regulator-name = "vreg_l2g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3g_1p2: ldo3 {
+ regulator-name = "vreg_l3g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-6 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+ qcom,pmic-id = "m";
+
+ vreg_l1m_1p056: ldo1 {
+ regulator-name = "vreg_l1m_1p056";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2m_1p056: ldo2 {
+ regulator-name = "vreg_l2m_1p056";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3m_2p8: ldo3 {
+ regulator-name = "vreg_l3m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4m_2p8: ldo4 {
+ regulator-name = "vreg_l4m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5m_1p8: ldo5 {
+ regulator-name = "vreg_l5m_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6m_1p8: ldo6 {
+ regulator-name = "vreg_l6m_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7m_2p9: ldo7 {
+ regulator-name = "vreg_l7m_2p9";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-7 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+ qcom,pmic-id = "n";
+
+ vreg_l1n_1p1: ldo1 {
+ regulator-name = "vreg_l1n_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2n_1p1: ldo2 {
+ regulator-name = "vreg_l2n_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3n_2p8: ldo3 {
+ regulator-name = "vreg_l3n_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4n_2p8: ldo4 {
+ regulator-name = "vreg_l4n_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5n_1p8: ldo5 {
+ regulator-name = "vreg_l5n_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6n_3p3: ldo6 {
+ regulator-name = "vreg_l6n_3p3";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7n_2p96: ldo7 {
+ regulator-name = "vreg_l7n_2p96";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&dispcc {
+ status = "disabled";
+};
+
+&i2c_master_hub_0 {
+ status = "okay";
+};
+
+&pcie0 {
+ wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l1e_0p88>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+ status = "okay";
+};
+
+&pm8550_gpios {
+ volume_up_n: volume-up-n-state {
+ pins = "gpio6";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ status = "okay";
+ linux,code = <KEY_VOLUMEDOWN>;
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/sm8550/adsp.mdt",
+ "qcom/sm8550/adsp_dtb.mdt";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/sm8550/cdsp.mdt",
+ "qcom/sm8550/cdsp_dtb.mdt";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/sm8550/modem.mdt",
+ "qcom/sm8550/modem_dtb.mdt";
+ status = "okay";
+};
+
+&sleep_clk {
+ clock-frequency = <32000>;
+};
+
+&tlmm {
+ gpio-reserved-ranges = <36 4>, <50 2>;
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+ vcc-supply = <&vreg_l17b_2p5>;
+ vcc-max-microamp = <1300000>;
+ vccq-supply = <&vreg_l1g_1p2>;
+ vccq-max-microamp = <1200000>;
+ vdd-hba-supply = <&vreg_l3g_1p2>;
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l1d_0p88>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+ status = "okay";
+};
+
+&xo_board {
+ clock-frequency = <76800000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
new file mode 100644
index 000000000000..85d487ef80a0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
@@ -0,0 +1,765 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/sound/cs35l45.h>
+#include "sm8550.dtsi"
+#include "pm8010.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 5
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+/* TODO: Only one SID of PMR735D seems accessible? */
+
+/delete-node/ &hwfence_shbuf;
+/delete-node/ &mpss_mem;
+/delete-node/ &rmtfs_mem;
+/ {
+ model = "Sony Xperia 1 V";
+ compatible = "sony,pdx234", "qcom,sm8550";
+ chassis-type = "handset";
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c4 = &i2c4;
+ i2c10 = &i2c10;
+ i2c11 = &i2c11;
+ i2c16 = &i2c_hub_2;
+ serial0 = &uart7;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ label = "gpio-keys";
+
+ pinctrl-0 = <&focus_n &snapshot_n &vol_down_n>;
+ pinctrl-names = "default";
+
+ key-camera-focus {
+ label = "Camera Focus";
+ linux,code = <KEY_CAMERA_FOCUS>;
+ gpios = <&pm8550b_gpios 8 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+
+ key-camera-snapshot {
+ label = "Camera Snapshot";
+ gpios = <&pm8550b_gpios 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_CAMERA>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ pmic-glink {
+ compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink";
+ orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss_in: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ mpss_mem: mpss-region@89800000 {
+ reg = <0x0 0x89800000 0x0 0x10800000>;
+ no-map;
+ };
+
+ splash@b8000000 {
+ reg = <0x0 0xb8000000 0x0 0x2b00000>;
+ no-map;
+ };
+
+ hwfence_shbuf: hwfence-shbuf-region@e6440000 {
+ reg = <0x0 0xe6440000 0x0 0x2dd000>;
+ no-map;
+ };
+
+ rmtfs_mem: memory@f8b00000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0xf8b00000 0x0 0x280000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
+ };
+
+ ramoops@ffd00000 {
+ compatible = "ramoops";
+ reg = <0x0 0xffd00000 0x0 0xc0000>;
+ console-size = <0x40000>;
+ record-size = <0x1000>;
+ pmsg-size = <0x40000>;
+ ecc-size = <16>;
+ };
+
+ rdtag-store-region@ffdc0000 {
+ reg = <0x0 0xffdc0000 0x0 0x40000>;
+ no-map;
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ pm8550_bob1: bob1 {
+ regulator-name = "pm8550_bob1";
+ regulator-min-microvolt = <3416000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ /* TODO: bob2 @ 2.704-3.008V doesn't fall into the vreg driver constraints */
+
+ pm8550_l1: ldo1 {
+ regulator-name = "pm8550_l1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l2: ldo2 {
+ regulator-name = "pm8550_l2";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ /* L4 exists in cmd-db, but the board seems to crash on access */
+
+ pm8550_l5: ldo5 {
+ regulator-name = "pm8550_l5";
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l6: ldo6 {
+ regulator-name = "pm8550_l6";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l7: ldo7 {
+ regulator-name = "pm8550_l7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l8: ldo8 {
+ regulator-name = "pm8550_l8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l9: ldo9 {
+ regulator-name = "pm8550_l9";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l10: ldo10 {
+ regulator-name = "pm8550_l10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l11: ldo11 {
+ regulator-name = "pm8550_l11";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l12: ldo12 {
+ regulator-name = "pm8550_l12";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l13: ldo13 {
+ regulator-name = "pm8550_l13";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l14: ldo14 {
+ regulator-name = "pm8550_l14";
+ regulator-min-microvolt = <3304000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l15: ldo15 {
+ regulator-name = "pm8550_l15";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l16: ldo16 {
+ regulator-name = "pm8550_l16";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550_l17: ldo17 {
+ regulator-name = "pm8550_l17";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ pm8550vs_0_l1: ldo1 {
+ regulator-name = "pm8550vs_0_l1";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_0_l3: ldo3 {
+ regulator-name = "pm8550vs_0_l3";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ pm8550vs_1_l1: ldo1 {
+ regulator-name = "pm8550vs_1_l1";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ /* L3 exists in cmd-db, but the board seems to crash on access */
+ };
+
+ regulators-3 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ pm8550vs_2_s4: smps4 {
+ regulator-name = "pm8550vs_2_s4";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <984000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_2_s5: smps5 {
+ regulator-name = "pm8550vs_2_s5";
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_2_l1: ldo1 {
+ regulator-name = "pm8550vs_2_l1";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_2_l2: ldo2 {
+ regulator-name = "pm8550vs_2_l2";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <968000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_2_l3: ldo3 {
+ regulator-name = "pm8550vs_2_l3";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ pm8550ve_s4: smps4 {
+ regulator-name = "pm8550ve_s4";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <700000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550ve_l1: ldo1 {
+ regulator-name = "pm8550ve_l1";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550ve_l2: ldo2 {
+ regulator-name = "pm8550ve_l2";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550ve_l3: ldo3 {
+ regulator-name = "pm8550ve_l3";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-5 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "g";
+
+ pm8550vs_3_s1: smps1 {
+ regulator-name = "pm8550vs_3_s1";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_s2: smps2 {
+ regulator-name = "pm8550vs_3_s2";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1036000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_s3: smps3 {
+ regulator-name = "pm8550vs_3_s3";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_s4: smps4 {
+ regulator-name = "pm8550vs_3_s4";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1352000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_s5: smps5 {
+ regulator-name = "pm8550vs_3_s5";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_s6: smps6 {
+ regulator-name = "pm8550vs_3_s6";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_l1: ldo1 {
+ regulator-name = "pm8550vs_3_l1";
+ regulator-min-microvolt = <1144000>;
+ regulator-max-microvolt = <1256000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_l2: ldo2 {
+ regulator-name = "pm8550vs_3_l2";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pm8550vs_3_l3: ldo3 {
+ regulator-name = "pm8550vs_3_l3";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ /* TODO: Unknown PMIC @ k, l, PM8010 @ m, n */
+};
+
+&gpi_dma1 {
+ status = "okay";
+};
+
+&gpi_dma2 {
+ status = "okay";
+};
+
+&i2c_hub_2 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ pmic@75 {
+ compatible = "dlg,slg51000";
+ reg = <0x75>;
+ dlg,cs-gpios = <&pm8550vs_g_gpios 4 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&cam_pwr_a_cs>;
+ pinctrl-names = "default";
+
+ regulators {
+ slg51000_a_ldo1: ldo1 {
+ regulator-name = "slg51000_a_ldo1";
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ slg51000_a_ldo2: ldo2 {
+ regulator-name = "slg51000_a_ldo2";
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ slg51000_a_ldo3: ldo3 {
+ regulator-name = "slg51000_a_ldo3";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3750000>;
+ };
+
+ slg51000_a_ldo4: ldo4 {
+ regulator-name = "slg51000_a_ldo4";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3750000>;
+ };
+
+ slg51000_a_ldo5: ldo5 {
+ regulator-name = "slg51000_a_ldo5";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ slg51000_a_ldo6: ldo6 {
+ regulator-name = "slg51000_a_ldo6";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ slg51000_a_ldo7: ldo7 {
+ regulator-name = "slg51000_a_ldo7";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3750000>;
+ };
+ };
+ };
+};
+
+&i2c_master_hub_0 {
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <1000000>;
+ status = "okay";
+
+ /* NXP NFC @ 28 */
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ /* LX Semi SW82907 touchscreen @ 28 */
+};
+
+&i2c10 {
+ clock-frequency = <1000000>;
+ status = "okay";
+
+ /* Cirrus Logic CS40L25A boosted haptics driver @ 40 */
+};
+
+&i2c11 {
+ clock-frequency = <1000000>;
+ status = "okay";
+
+ cs35l41_l: speaker-amp@30 {
+ compatible = "cirrus,cs35l45";
+ reg = <0x30>;
+ interrupts-extended = <&tlmm 182 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&tlmm 183 GPIO_ACTIVE_HIGH>;
+ cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED | CS35L45_ASP_TX_HIZ_DISABLED)>;
+ #sound-dai-cells = <1>;
+
+ cirrus,gpio-ctrl2 {
+ gpio-ctrl = <0x2>;
+ };
+ };
+
+ cs35l41_r: speaker-amp@31 {
+ compatible = "cirrus,cs35l45";
+ reg = <0x31>;
+ interrupts-extended = <&tlmm 182 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&tlmm 183 GPIO_ACTIVE_HIGH>;
+ cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED | CS35L45_ASP_TX_HIZ_DISABLED)>;
+ #sound-dai-cells = <1>;
+
+ cirrus,gpio-ctrl2 {
+ gpio-ctrl = <0x2>;
+ };
+ };
+};
+
+&pcie0 {
+ wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&pm8550vs_2_l1>;
+ vdda-pll-supply = <&pm8550vs_2_l3>;
+
+ status = "okay";
+};
+
+&pm8550_flash {
+ status = "okay";
+
+ led-0 {
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_WHITE>;
+ led-sources = <1>, <4>;
+ led-max-microamp = <500000>;
+ flash-max-microamp = <1000000>;
+ flash-max-timeout-us = <1280000>;
+ function-enumerator = <0>;
+ };
+
+ led-1 {
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_YELLOW>;
+ led-sources = <2>, <3>;
+ led-max-microamp = <500000>;
+ flash-max-microamp = <1000000>;
+ flash-max-timeout-us = <1280000>;
+ function-enumerator = <1>;
+ };
+};
+
+&pm8550_gpios {
+ vol_down_n: volume-down-n-state {
+ pins = "gpio6";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+
+ sdc2_card_det_n: sd-card-det-n-state {
+ pins = "gpio12";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-down;
+ output-disable;
+ input-enable;
+ };
+};
+
+&pm8550b_gpios {
+ snapshot_n: snapshot-n-state {
+ pins = "gpio7";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+
+ focus_n: focus-n-state {
+ pins = "gpio8";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pm8550vs_g_gpios {
+ cam_pwr_a_cs: cam-pwr-a-cs-state {
+ pins = "gpio4";
+ function = "normal";
+ power-source = <0x01>;
+ drive-push-pull;
+ output-low;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+ };
+};
+
+&pm8550b_eusb2_repeater {
+ qcom,tune-usb2-disc-thres = /bits/ 8 <0x6>;
+ qcom,tune-usb2-amplitude = /bits/ 8 <0xf>;
+ qcom,tune-usb2-preem = /bits/ 8 <0x7>;
+ vdd18-supply = <&pm8550_l15>;
+ vdd3-supply = <&pm8550_l5>;
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEUP>;
+ status = "okay";
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/sm8550/Sony/yodo/adsp.mbn",
+ "qcom/sm8550/Sony/yodo/adsp_dtb.mbn";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/sm8550/Sony/yodo/cdsp.mbn",
+ "qcom/sm8550/Sony/yodo/cdsp_dtb.mbn";
+ status = "okay";
+};
+
+&sdhc_2 {
+ cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&sdc2_default &sdc2_card_det_n>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_card_det_n>;
+ pinctrl-names = "default", "sleep";
+ vmmc-supply = <&pm8550_l9>;
+ vqmmc-supply = <&pm8550_l8>;
+ no-sdio;
+ no-mmc;
+ status = "okay";
+};
+
+&sleep_clk {
+ clock-frequency = <32000>;
+};
+
+&tlmm {
+ gpio-reserved-ranges = <32 8>;
+};
+
+&uart7 {
+ status = "okay";
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_hsphy {
+ vdd-supply = <&pm8550vs_2_l1>;
+ vdda12-supply = <&pm8550vs_2_l3>;
+ phys = <&pm8550b_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_dp_qmpphy {
+ vdda-phy-supply = <&pm8550vs_2_l3>;
+ vdda-pll-supply = <&pm8550ve_l3>;
+
+ status = "okay";
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss_in>;
+};
+
+&xo_board {
+ clock-frequency = <76800000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index 3348bc06db48..4c9820adcf52 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -58,11 +58,6 @@
clock-mult = <1>;
clock-div = <2>;
};
-
- pcie_1_phy_aux_clk: pcie-1-phy-aux-clk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- };
};
cpus {
@@ -357,8 +352,23 @@
reg = <0 0xa0000000 0 0>;
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu-a510 {
+ compatible = "arm,cortex-a510-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-a710 {
+ compatible = "arm,cortex-a710-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-a715 {
+ compatible = "arm,cortex-a715-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-x3 {
+ compatible = "arm,cortex-x3-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
@@ -776,8 +786,8 @@
#power-domain-cells = <1>;
clocks = <&bi_tcxo_div2>, <&sleep_clk>,
<&pcie0_phy>,
- <&pcie1_phy>,
- <&pcie_1_phy_aux_clk>,
+ <&pcie1_phy QMP_PCIE_PIPE_CLK>,
+ <&pcie1_phy QMP_PCIE_PHY_AUX_CLK>,
<&ufs_mem_phy 0>,
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
@@ -812,6 +822,7 @@
dma-channels = <12>;
dma-channel-mask = <0x3e>;
iommus = <&apps_smmu 0x436 0>;
+ dma-coherent;
status = "disabled";
};
@@ -823,6 +834,7 @@
clocks = <&gcc GCC_QUPV3_WRAP_2_M_AHB_CLK>,
<&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>;
iommus = <&apps_smmu 0x423 0>;
+ dma-coherent;
#address-cells = <2>;
#size-cells = <2>;
status = "disabled";
@@ -1322,6 +1334,7 @@
dma-channels = <12>;
dma-channel-mask = <0x1e>;
iommus = <&apps_smmu 0xb6 0>;
+ dma-coherent;
status = "disabled";
};
@@ -1335,6 +1348,7 @@
iommus = <&apps_smmu 0xa3 0>;
interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>;
interconnect-names = "qup-core";
+ dma-coherent;
#address-cells = <2>;
#size-cells = <2>;
status = "disabled";
@@ -1769,6 +1783,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcieport0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -1881,6 +1905,16 @@
phy-names = "pciephy";
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -1904,7 +1938,7 @@
power-domains = <&gcc PCIE_1_PHY_GDSC>;
- #clock-cells = <0>;
+ #clock-cells = <1>;
clock-output-names = "pcie1_pipe_clk";
#phy-cells = <0>;
@@ -2886,6 +2920,7 @@
port@1 {
reg = <1>;
mdss_dp0_out: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
};
};
};
@@ -3145,6 +3180,8 @@
#clock-cells = <1>;
#phy-cells = <1>;
+ orientation-switch;
+
status = "disabled";
ports {
@@ -3162,6 +3199,7 @@
reg = <1>;
usb_dp_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
};
};
@@ -3169,6 +3207,7 @@
reg = <2>;
usb_dp_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp0_out>;
};
};
};
@@ -3225,12 +3264,22 @@
reg = <0x0 0x0a600000 0x0 0xcd00>;
interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&apps_smmu 0x40 0x0>;
- snps,dis_u2_susphy_quirk;
- snps,dis_enblslpm_quirk;
- snps,usb3_lpm_capable;
phys = <&usb_1_hsphy>,
<&usb_dp_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
+ snps,hird-threshold = /bits/ 8 <0x0>;
+ snps,usb2-gadget-lpm-disable;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ snps,is-utmi-l1-suspend;
+ snps,usb3_lpm_capable;
+ snps,usb2-lpm-disable;
+ snps,has-lpm-erratum;
+ tx-fifo-resize;
+ dma-coherent;
+ usb-role-switch;
ports {
#address-cells = <1>;
@@ -3247,6 +3296,7 @@
reg = <1>;
usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
};
};
@@ -3966,6 +4016,7 @@
<GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>;
+ dma-coherent;
};
intc: interrupt-controller@17100000 {
@@ -4261,12 +4312,14 @@
<0 0x25200000 0 0x200000>,
<0 0x25400000 0 0x200000>,
<0 0x25600000 0 0x200000>,
- <0 0x25800000 0 0x200000>;
+ <0 0x25800000 0 0x200000>,
+ <0 0x25a00000 0 0x200000>;
reg-names = "llcc0_base",
"llcc1_base",
"llcc2_base",
"llcc3_base",
- "llcc_broadcast_base";
+ "llcc_broadcast_base",
+ "llcc_broadcast_and_base";
interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -4314,6 +4367,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "adsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -4452,6 +4506,7 @@
compatible = "qcom,fastrpc";
qcom,glink-channels = "fastrpcglink-apps-dsp";
label = "cdsp";
+ qcom,non-secure-domain;
#address-cells = <1>;
#size-cells = <0>;
@@ -4535,8 +4590,6 @@
thermal-zones {
aoss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 0>;
trips {
@@ -4555,8 +4608,6 @@
};
cpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
trips {
@@ -4575,8 +4626,6 @@
};
cpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
trips {
@@ -4595,8 +4644,6 @@
};
cpuss2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
trips {
@@ -4615,8 +4662,6 @@
};
cpuss3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
trips {
@@ -4635,8 +4680,6 @@
};
cpu3-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
trips {
@@ -4661,8 +4704,6 @@
};
cpu3-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
trips {
@@ -4687,8 +4728,6 @@
};
cpu4-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
trips {
@@ -4713,8 +4752,6 @@
};
cpu4-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
trips {
@@ -4739,8 +4776,6 @@
};
cpu5-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
trips {
@@ -4765,8 +4800,6 @@
};
cpu5-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
trips {
@@ -4791,8 +4824,6 @@
};
cpu6-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
trips {
@@ -4817,8 +4848,6 @@
};
cpu6-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
trips {
@@ -4843,8 +4872,6 @@
};
cpu7-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 13>;
trips {
@@ -4869,8 +4896,6 @@
};
cpu7-middle-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 14>;
trips {
@@ -4895,8 +4920,6 @@
};
cpu7-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 15>;
trips {
@@ -4921,8 +4944,6 @@
};
aoss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 0>;
trips {
@@ -4941,8 +4962,6 @@
};
cpu0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
trips {
@@ -4967,8 +4986,6 @@
};
cpu1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
trips {
@@ -4993,8 +5010,6 @@
};
cpu2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 3>;
trips {
@@ -5020,7 +5035,7 @@
cdsp0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 4>;
trips {
@@ -5052,7 +5067,7 @@
cdsp1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 5>;
trips {
@@ -5084,7 +5099,7 @@
cdsp2-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 6>;
trips {
@@ -5116,7 +5131,7 @@
cdsp3-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 7>;
trips {
@@ -5147,8 +5162,6 @@
};
video-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 8>;
trips {
@@ -5168,7 +5181,7 @@
mem-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 9>;
trips {
@@ -5193,8 +5206,6 @@
};
modem0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 10>;
trips {
@@ -5225,8 +5236,6 @@
};
modem1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 11>;
trips {
@@ -5257,8 +5266,6 @@
};
modem2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 12>;
trips {
@@ -5289,8 +5296,6 @@
};
modem3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 13>;
trips {
@@ -5321,8 +5326,6 @@
};
camera0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 14>;
trips {
@@ -5341,8 +5344,6 @@
};
camera1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 15>;
trips {
@@ -5361,8 +5362,6 @@
};
aoss2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 0>;
trips {
@@ -5382,312 +5381,264 @@
gpuss-0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 1>;
cooling-maps {
map0 {
- trip = <&gpu0_junction_config>;
+ trip = <&gpu0_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu0_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
+ type = "hot";
};
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
- };
-
- gpu0_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 2>;
cooling-maps {
map0 {
- trip = <&gpu1_junction_config>;
+ trip = <&gpu1_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu1_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
- };
-
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
+ type = "hot";
};
- gpu1_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-2-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 3>;
cooling-maps {
map0 {
- trip = <&gpu2_junction_config>;
+ trip = <&gpu2_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu2_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
+ type = "hot";
};
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
- };
-
- gpu2_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-3-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 4>;
cooling-maps {
map0 {
- trip = <&gpu3_junction_config>;
+ trip = <&gpu3_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu3_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
- };
-
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
+ type = "hot";
};
- gpu3_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-4-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 5>;
cooling-maps {
map0 {
- trip = <&gpu4_junction_config>;
+ trip = <&gpu4_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu4_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
- };
-
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
+ type = "hot";
};
- gpu4_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-5-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 6>;
cooling-maps {
map0 {
- trip = <&gpu5_junction_config>;
+ trip = <&gpu5_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu5_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
+ type = "hot";
};
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
- };
-
- gpu5_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-6-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 7>;
cooling-maps {
map0 {
- trip = <&gpu6_junction_config>;
+ trip = <&gpu6_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu6_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
- };
-
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
+ type = "hot";
};
- gpu6_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
gpuss-7-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 8>;
cooling-maps {
map0 {
- trip = <&gpu7_junction_config>;
+ trip = <&gpu7_alert0>;
cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
trips {
- thermal-engine-config {
- temperature = <125000>;
+ gpu7_alert0: trip-point0 {
+ temperature = <85000>;
hysteresis = <1000>;
type = "passive";
};
- thermal-hal-config {
- temperature = <125000>;
+ trip-point1 {
+ temperature = <90000>;
hysteresis = <1000>;
- type = "passive";
+ type = "hot";
};
- reset-mon-config {
- temperature = <115000>;
- hysteresis = <5000>;
- type = "passive";
- };
-
- gpu7_junction_config: junction-config {
- temperature = <95000>;
- hysteresis = <5000>;
- type = "passive";
+ trip-point2 {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk-display-card.dtso b/arch/arm64/boot/dts/qcom/sm8650-hdk-display-card.dtso
new file mode 100644
index 000000000000..cb102535838d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8650-hdk-display-card.dtso
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+/*
+ * Display Card kit overlay
+ * This requires S5702 Switch 7 to be turned to OFF to route DSI0 to the display panel
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/dts-v1/;
+/plugin/;
+
+/* Disable HDMI bridge related nodes (mutually exclusive with the display card) */
+
+&i2c6 {
+ status = "disabled";
+};
+
+&lt9611_1v2 {
+ status = "disabled";
+};
+
+&lt9611_3v3 {
+ status = "disabled";
+};
+
+&vreg_bob_3v3 {
+ status = "disabled";
+};
+
+&lt9611_codec {
+ status = "disabled";
+};
+
+&mdss_dsi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "visionox,vtdr6130";
+ reg = <0>;
+
+ reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+
+ vddio-supply = <&vreg_l12b_1p8>;
+ vci-supply = <&vreg_l13b_3p0>;
+ vdd-supply = <&vreg_l11b_1p2>;
+
+ pinctrl-0 = <&disp0_reset_n_active>, <&mdp_vsync>;
+ pinctrl-1 = <&disp0_reset_n_suspend>, <&mdp_vsync>;
+ pinctrl-names = "default", "sleep";
+
+ port {
+ panel0_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dsi0_out: endpoint {
+ remote-endpoint = <&panel0_in>;
+ };
+ };
+ };
+};
+
+&spi4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "okay";
+
+ touchscreen@0 {
+ compatible = "goodix,gt9916";
+ reg = <0>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <162 IRQ_TYPE_LEVEL_LOW>;
+
+ reset-gpios = <&tlmm 161 GPIO_ACTIVE_LOW>;
+
+ avdd-supply = <&vreg_l14b_3p2>;
+
+ spi-max-frequency = <1000000>;
+
+ touchscreen-size-x = <1080>;
+ touchscreen-size-y = <2400>;
+
+ pinctrl-0 = <&ts_irq>, <&ts_reset>;
+ pinctrl-names = "default";
+ };
+};
+
+&tlmm {
+ disp0_reset_n_active: disp0-reset-n-active-state {
+ pins = "gpio133";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ disp0_reset_n_suspend: disp0-reset-n-suspend-state {
+ pins = "gpio133";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ mdp_vsync: mdp-vsync-state {
+ pins = "gpio86";
+ function = "mdp_vsync";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ ts_irq: ts-irq-state {
+ pins = "gpio161";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ output-disable;
+ };
+
+ ts_reset: ts-reset-state {
+ pins = "gpio162";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
new file mode 100644
index 000000000000..591e6ab9bf5b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
@@ -0,0 +1,1355 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8650.dtsi"
+#include "pm8010.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 8
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SM8650 HDK";
+ compatible = "qcom,sm8650-hdk", "qcom,sm8650";
+ chassis-type = "embedded";
+
+ aliases {
+ serial0 = &uart15;
+ serial1 = &uart14;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_out: endpoint {
+ remote-endpoint = <&lt9611_out>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&volume_up_n>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_BLUETOOTH;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "bluetooth-power";
+ default-state = "off";
+ };
+
+ led-1 {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pm8550b_gpios 9 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ panic-indicator;
+ };
+
+ led-2 {
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_ORANGE>;
+ gpios = <&pm8550b_gpios 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "phy0tx";
+ default-state = "off";
+ };
+ };
+
+ pmic-glink {
+ compatible = "qcom,sm8650-pmic-glink",
+ "qcom,sm8550-pmic-glink",
+ "qcom,pmic-glink";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ orientation-gpios = <&tlmm 29 GPIO_ACTIVE_HIGH>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_hs_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss_in: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&wcd_usbss_sbu_mux>;
+ };
+ };
+ };
+ };
+ };
+
+ lt9611_1v2: regulator-lt9611-1v2 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "LT9611_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ vin-supply = <&vph_pwr>;
+ gpio = <&tlmm 79 GPIO_ACTIVE_HIGH>;
+
+ enable-active-high;
+ };
+
+ lt9611_3v3: regulator-lt9611-3v3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "LT9611_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ vin-supply = <&vreg_bob_3v3>;
+ gpio = <&tlmm 78 GPIO_ACTIVE_HIGH>;
+
+ enable-active-high;
+ };
+
+ sound {
+ compatible = "qcom,sm8650-sndcard", "qcom,sm8450-sndcard";
+ model = "SM8650-HDK";
+ audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT",
+ "SpkrRight IN", "WSA_SPK2 OUT",
+ "IN1_HPHL", "HPHL_OUT",
+ "IN2_HPHR", "HPHR_OUT",
+ "AMIC1", "MIC BIAS1",
+ "AMIC2", "MIC BIAS2",
+ "AMIC5", "MIC BIAS4",
+ "TX SWR_INPUT0", "ADC1_OUTPUT",
+ "TX SWR_INPUT1", "ADC2_OUTPUT",
+ "TX SWR_INPUT3", "ADC4_OUTPUT";
+
+ wcd-playback-dai-link {
+ link-name = "WCD Playback";
+
+ cpu {
+ sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>;
+ };
+
+ codec {
+ sound-dai = <&wcd939x 0>, <&swr1 0>, <&lpass_rxmacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ wcd-capture-dai-link {
+ link-name = "WCD Capture";
+
+ cpu {
+ sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+ };
+
+ codec {
+ sound-dai = <&wcd939x 1>, <&swr2 0>, <&lpass_txmacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ wsa-dai-link {
+ link-name = "WSA Playback";
+
+ cpu {
+ sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>;
+ };
+
+ codec {
+ sound-dai = <&north_spkr>, <&south_spkr>, <&swr0 0>, <&lpass_wsamacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+ };
+
+ vph_pwr: regulator-vph-pwr {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vreg_bob_3v3: regulator-vreg-bob-3v3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_BOB_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ vin-supply = <&vph_pwr>;
+ };
+
+ wcd939x: audio-codec {
+ compatible = "qcom,wcd9395-codec", "qcom,wcd9390-codec";
+
+ pinctrl-0 = <&wcd_default>;
+ pinctrl-names = "default";
+
+ qcom,micbias1-microvolt = <1800000>;
+ qcom,micbias2-microvolt = <1800000>;
+ qcom,micbias3-microvolt = <1800000>;
+ qcom,micbias4-microvolt = <1800000>;
+ qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>;
+ qcom,mbhc-headset-vthreshold-microvolt = <1700000>;
+ qcom,mbhc-headphone-vthreshold-microvolt = <50000>;
+ qcom,rx-device = <&wcd_rx>;
+ qcom,tx-device = <&wcd_tx>;
+
+ reset-gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+
+ vdd-buck-supply = <&vreg_l15b_1p8>;
+ vdd-rxtx-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l15b_1p8>;
+ vdd-mic-bias-supply = <&vreg_bob1>;
+
+ #sound-dai-cells = <1>;
+ };
+
+ wcn7850-pmu {
+ compatible = "qcom,wcn7850-pmu";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_en>;
+
+ wlan-enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>;
+ /*
+ * TODO Add bt-enable-gpios once the Bluetooth driver is
+ * converted to using the power sequencer.
+ */
+
+ vdd-supply = <&vreg_s4i_0p85>;
+ vddio-supply = <&vreg_l15b_1p8>;
+ vddio1p2-supply = <&vreg_l3c_1p2>;
+ vddaon-supply = <&vreg_s2c_0p8>;
+ vdddig-supply = <&vreg_s3c_0p9>;
+ vddrfa1p2-supply = <&vreg_s1c_1p2>;
+ vddrfa1p8-supply = <&vreg_s6c_1p8>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK1>;
+
+ regulators {
+ vreg_pmu_rfa_cmn: ldo0 {
+ regulator-name = "vreg_pmu_rfa_cmn";
+ };
+
+ vreg_pmu_aon_0p59: ldo1 {
+ regulator-name = "vreg_pmu_aon_0p59";
+ };
+
+ vreg_pmu_wlcx_0p8: ldo2 {
+ regulator-name = "vreg_pmu_wlcx_0p8";
+ };
+
+ vreg_pmu_wlmx_0p85: ldo3 {
+ regulator-name = "vreg_pmu_wlmx_0p85";
+ };
+
+ vreg_pmu_btcmx_0p85: ldo4 {
+ regulator-name = "vreg_pmu_btcmx_0p85";
+ };
+
+ vreg_pmu_rfa_0p8: ldo5 {
+ regulator-name = "vreg_pmu_rfa_0p8";
+ };
+
+ vreg_pmu_rfa_1p2: ldo6 {
+ regulator-name = "vreg_pmu_rfa_1p2";
+ };
+
+ vreg_pmu_rfa_1p8: ldo7 {
+ regulator-name = "vreg_pmu_rfa_1p8";
+ };
+
+ vreg_pmu_pcie_0p9: ldo8 {
+ regulator-name = "vreg_pmu_pcie_0p9";
+ };
+
+ vreg_pmu_pcie_1p8: ldo9 {
+ regulator-name = "vreg_pmu_pcie_1p8";
+ };
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
+ vdd-l2-l13-l14-supply = <&vreg_bob1>;
+ vdd-l3-supply = <&vreg_s1c_1p2>;
+ vdd-l5-l16-supply = <&vreg_bob1>;
+ vdd-l6-l7-supply = <&vreg_bob1>;
+ vdd-l8-l9-supply = <&vreg_bob1>;
+ vdd-l11-supply = <&vreg_s1c_1p2>;
+ vdd-l12-supply = <&vreg_s6c_1p8>;
+ vdd-l15-supply = <&vreg_s6c_1p8>;
+ vdd-l17-supply = <&vreg_bob2>;
+
+ qcom,pmic-id = "b";
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3296000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2720000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5b_3p1: ldo5 {
+ regulator-name = "vreg_l5b_3p1";
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p8: ldo6 {
+ regulator-name = "vreg_l6b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_1p8: ldo7 {
+ regulator-name = "vreg_l7b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b_1p8: ldo8 {
+ regulator-name = "vreg_l8b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_2p9: ldo9 {
+ regulator-name = "vreg_l9b_2p9";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11b_1p2: ldo11 {
+ regulator-name = "vreg_l11b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b_1p8: ldo12 {
+ regulator-name = "vreg_l12b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b_3p0: ldo13 {
+ regulator-name = "vreg_l13b_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p2: ldo14 {
+ regulator-name = "vreg_l14b_3p2";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b_1p8: ldo15 {
+ regulator-name = "vreg_l15b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16b_2p8: ldo16 {
+ regulator-name = "vreg_l16b_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b_2p5: ldo17 {
+ regulator-name = "vreg_l17b_2p5";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s1c_1p2>;
+ vdd-l2-supply = <&vreg_s1c_1p2>;
+ vdd-l3-supply = <&vreg_s1c_1p2>;
+ 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>;
+
+ qcom,pmic-id = "c";
+
+ vreg_s1c_1p2: smps1 {
+ regulator-name = "vreg_s1c_1p2";
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1348000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s2c_0p8: smps2 {
+ regulator-name = "vreg_s2c_0p8";
+ regulator-min-microvolt = <852000>;
+ regulator-max-microvolt = <1036000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s3c_0p9: smps3 {
+ regulator-name = "vreg_s3c_0p9";
+ regulator-min-microvolt = <976000>;
+ regulator-max-microvolt = <1064000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s4c_1p2: smps4 {
+ regulator-name = "vreg_s4c_1p2";
+ regulator-min-microvolt = <1224000>;
+ regulator-max-microvolt = <1280000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5c_0p7: smps5 {
+ regulator-name = "vreg_s5c_0p7";
+ regulator-min-microvolt = <752000>;
+ regulator-max-microvolt = <900000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s6c_1p8: smps6 {
+ regulator-name = "vreg_s6c_1p8";
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1c_1p2: ldo1 {
+ regulator-name = "vreg_l1c_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_1p2: ldo3 {
+ regulator-name = "vreg_l3c_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s3c_0p9>;
+
+ qcom,pmic-id = "d";
+
+ vreg_l1d_0p88: ldo1 {
+ regulator-name = "vreg_l1d_0p88";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l3-supply = <&vreg_s3c_0p9>;
+
+ qcom,pmic-id = "e";
+
+ vreg_l3e_0p9: ldo3 {
+ regulator-name = "vreg_l3e_0p9";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s3c_0p9>;
+ vdd-l3-supply = <&vreg_s3c_0p9>;
+
+ qcom,pmic-id = "g";
+
+ vreg_l1g_0p91: ldo1 {
+ regulator-name = "vreg_l1g_0p91";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3g_0p91: ldo3 {
+ regulator-name = "vreg_l3g_0p91";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-5 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s3c_0p9>;
+ vdd-l2-supply = <&vreg_s3c_0p9>;
+ vdd-l3-supply = <&vreg_s1c_1p2>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ qcom,pmic-id = "i";
+
+ vreg_s4i_0p85: smps4 {
+ regulator-name = "vreg_s4i_0p85";
+ regulator-min-microvolt = <852000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1i_0p88: ldo1 {
+ regulator-name = "vreg_l1i_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2i_0p88: ldo2 {
+ regulator-name = "vreg_l2i_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3i_1p2: ldo3 {
+ regulator-name = "vreg_l3i_0p91";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-6 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+ qcom,pmic-id = "m";
+
+ vdd-l1-l2-supply = <&vreg_s1c_1p2>;
+ vdd-l3-l4-supply = <&vreg_bob2>;
+ vdd-l5-supply = <&vreg_s6c_1p8>;
+ vdd-l6-supply = <&vreg_bob1>;
+ vdd-l7-supply = <&vreg_bob1>;
+
+ vreg_l1m_1p1: ldo1 {
+ regulator-name = "vreg_l1m_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2m_1p056: ldo2 {
+ regulator-name = "vreg_l2m_1p056";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3m_2p8: ldo3 {
+ regulator-name = "vreg_l3m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4m_2p8: ldo4 {
+ regulator-name = "vreg_l4m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5m_1p8: ldo5 {
+ regulator-name = "vreg_l5m_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6m_2p8: ldo6 {
+ regulator-name = "vreg_l6m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7m_2p96: ldo7 {
+ regulator-name = "vreg_l7m_2p96";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-7 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+ qcom,pmic-id = "n";
+
+ vdd-l1-l2-supply = <&vreg_s1c_1p2>;
+ vdd-l3-l4-supply = <&vreg_s6c_1p8>;
+ vdd-l5-supply = <&vreg_bob2>;
+ vdd-l6-supply = <&vreg_bob2>;
+ vdd-l7-supply = <&vreg_bob1>;
+
+ vreg_l1n_1p1: ldo1 {
+ regulator-name = "vreg_l1n_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2n_1p056: ldo2 {
+ regulator-name = "vreg_l2n_1p056";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3n_1p8: ldo3 {
+ regulator-name = "vreg_l3n_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4n_1p8: ldo4 {
+ regulator-name = "vreg_l4n_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5n_2p8: ldo5 {
+ regulator-name = "vreg_l5n_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6n_2p8: ldo6 {
+ regulator-name = "vreg_l6n_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7n_3p3: ldo7 {
+ regulator-name = "vreg_l7n_3p3";
+ regulator-min-microvolt = <3304000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&dispcc {
+ status = "okay";
+};
+
+&gpi_dma1 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+
+ wcd_usbss: typec-mux@e {
+ compatible = "qcom,wcd9395-usbss", "qcom,wcd9390-usbss";
+ reg = <0xe>;
+
+ vdd-supply = <&vreg_l15b_1p8>;
+ reset-gpios = <&tlmm 152 GPIO_ACTIVE_HIGH>;
+
+ mode-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ wcd_usbss_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_sbu>;
+ };
+ };
+ };
+ };
+};
+
+&i2c6 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ lt9611_codec: hdmi-bridge@2b {
+ compatible = "lontium,lt9611uxc";
+ reg = <0x2b>;
+
+ interrupts-extended = <&tlmm 85 IRQ_TYPE_EDGE_FALLING>;
+
+ reset-gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>;
+
+ vdd-supply = <&lt9611_1v2>;
+ vcc-supply = <&lt9611_3v3>;
+
+ pinctrl-0 = <&lt9611_irq_pin>, <&lt9611_rst_pin>;
+ pinctrl-names = "default";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lt9611_a: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ lt9611_out: endpoint {
+ remote-endpoint = <&hdmi_connector_out>;
+ };
+ };
+ };
+ };
+};
+
+&ipa {
+ qcom,gsi-loader = "self";
+ memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/sm8650/ipa_fws.mbn";
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ firmware-name = "qcom/sm8650/gen70900_zap.mbn";
+ };
+};
+
+&lpass_tlmm {
+ spkr_1_sd_n_active: spkr-1-sd-n-active-state {
+ pins = "gpio21";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&vreg_l3i_1p2>;
+
+ status = "okay";
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&lt9611_a>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+ vdds-supply = <&vreg_l1i_0p88>;
+
+ status = "okay";
+};
+
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ data-lanes = <0 1>;
+};
+
+&pcie0 {
+ wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcieport0 {
+ wifi@0 {
+ compatible = "pci17cb,1107";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ };
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l1i_0p88>;
+ vdda-pll-supply = <&vreg_l3i_1p2>;
+
+ status = "okay";
+};
+
+&pcie1 {
+ wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&pcie1_default_state>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcie1_phy {
+ vdda-phy-supply = <&vreg_l3e_0p9>;
+ vdda-pll-supply = <&vreg_l3i_1p2>;
+ vdda-qref-supply = <&vreg_l1i_0p88>;
+
+ status = "okay";
+};
+
+&pm8550_gpios {
+ sdc2_card_det_n: sdc2-card-det-state {
+ pins = "gpio12";
+ function = "normal";
+ bias-pull-up;
+ input-enable;
+ output-disable;
+ power-source = <1>; /* 1.8 V */
+ };
+
+ volume_up_n: volume-up-n-state {
+ pins = "gpio6";
+ function = "normal";
+ bias-pull-up;
+ input-enable;
+ power-source = <1>;
+ };
+};
+
+/* The RGB signals are routed to 3 separate LEDs on the HDK8650 */
+&pm8550_pwm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "okay";
+
+ led@1 {
+ reg = <1>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ default-state = "off";
+ };
+
+ led@2 {
+ reg = <2>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "off";
+ };
+
+ led@3 {
+ reg = <3>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "off";
+ };
+};
+
+&pm8550b_eusb2_repeater {
+ vdd18-supply = <&vreg_l15b_1p8>;
+ vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&pmk8550_rtc {
+ status = "okay";
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+
+ status = "okay";
+};
+
+&qup_i2c3_data_clk {
+ /* Use internal I2C pull-up */
+ bias-pull-up = <2200>;
+};
+
+&qupv3_id_0 {
+ iommus = <&apps_smmu 0xa3 0x3>;
+
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/sm8650/adsp.mbn",
+ "qcom/sm8650/adsp_dtb.mbn";
+
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/sm8650/cdsp.mbn",
+ "qcom/sm8650/cdsp_dtb.mbn";
+
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/sm8650/modem.mbn",
+ "qcom/sm8650/modem_dtb.mbn";
+
+ status = "okay";
+};
+
+&sdhc_2 {
+ cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_HIGH>;
+
+ vmmc-supply = <&vreg_l9b_2p9>;
+ vqmmc-supply = <&vreg_l8b_1p8>;
+ bus-width = <4>;
+ no-sdio;
+ no-mmc;
+
+ pinctrl-0 = <&sdc2_default>, <&sdc2_card_det_n>;
+ pinctrl-1 = <&sdc2_sleep>, <&sdc2_card_det_n>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+};
+
+&sleep_clk {
+ clock-frequency = <32000>;
+};
+
+&swr0 {
+ status = "okay";
+
+ /* WSA8845, Speaker North */
+ north_spkr: speaker@0,0 {
+ compatible = "sdw20217020400";
+ reg = <0 0>;
+ pinctrl-0 = <&spkr_1_sd_n_active>;
+ pinctrl-names = "default";
+ powerdown-gpios = <&lpass_tlmm 21 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SpkrLeft";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l3c_1p2>;
+
+ /*
+ * WSA8845 Port 1 (DAC) <=> SWR0 Port 1 (SPKR_L)
+ * WSA8845 Port 2 (COMP) <=> SWR0 Port 2 (SPKR_L_COMP)
+ * WSA8845 Port 3 (BOOST) <=> SWR0 Port 3 (SPKR_L_BOOST)
+ * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR)
+ * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 10 (SPKR_L_VI)
+ * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS)
+ */
+ qcom,port-mapping = <1 2 3 7 10 13>;
+ };
+
+ /* WSA8845, Speaker South */
+ south_spkr: speaker@0,1 {
+ compatible = "sdw20217020400";
+ reg = <0 1>;
+ pinctrl-0 = <&spkr_2_sd_n_active>;
+ pinctrl-names = "default";
+ powerdown-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SpkrRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l3c_1p2>;
+
+ /*
+ * WSA8845 Port 1 (DAC) <=> SWR0 Port 4 (SPKR_R)
+ * WSA8845 Port 2 (COMP) <=> SWR0 Port 5 (SPKR_R_COMP)
+ * WSA8845 Port 3 (BOOST) <=> SWR0 Port 6 (SPKR_R_BOOST)
+ * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR)
+ * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 11 (SPKR_R_VI)
+ * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS)
+ */
+ qcom,port-mapping = <4 5 6 7 11 13>;
+ };
+};
+
+&swr1 {
+ status = "okay";
+
+ /* WCD9395 RX */
+ wcd_rx: codec@0,4 {
+ compatible = "sdw20217010e00";
+ reg = <0 4>;
+
+ /*
+ * WCD9395 RX Port 1 (HPH_L/R) <=> SWR1 Port 1 (HPH_L/R)
+ * WCD9395 RX Port 2 (CLSH) <=> SWR1 Port 2 (CLSH)
+ * WCD9395 RX Port 3 (COMP_L/R) <=> SWR1 Port 3 (COMP_L/R)
+ * WCD9395 RX Port 4 (LO) <=> SWR1 Port 4 (LO)
+ * WCD9395 RX Port 5 (DSD_L/R) <=> SWR1 Port 5 (DSD_L/R)
+ * WCD9395 RX Port 6 (HIFI_PCM_L/R) <=> SWR1 Port 9 (HIFI_PCM_L/R)
+ */
+ qcom,rx-port-mapping = <1 2 3 4 5 9>;
+ };
+};
+
+&swr2 {
+ status = "okay";
+
+ /* WCD9395 TX */
+ wcd_tx: codec@0,3 {
+ compatible = "sdw20217010e00";
+ reg = <0 3>;
+
+ /*
+ * WCD9395 TX Port 1 (ADC1,2,3,4) <=> SWR2 Port 2 (TX SWR_INPUT 0,1,2,3)
+ * WCD9395 TX Port 2 (ADC3,4 & DMIC0,1) <=> SWR2 Port 2 (TX SWR_INPUT 0,1,2,3)
+ * WCD9395 TX Port 3 (DMIC0,1,2,3 & MBHC) <=> SWR2 Port 3 (TX SWR_INPUT 4,5,6,7)
+ * WCD9395 TX Port 4 (DMIC4,5,6,7) <=> SWR2 Port 4 (TX SWR_INPUT 8,9,10,11)
+ */
+ qcom,tx-port-mapping = <2 2 3 4>;
+ };
+};
+
+&tlmm {
+ /* Reserved I/Os for NFC */
+ gpio-reserved-ranges = <32 8>, <74 1>;
+
+ bt_default: bt-default-state {
+ bt-en-pins {
+ pins = "gpio17";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ sw-ctrl-pins {
+ pins = "gpio18";
+ function = "gpio";
+ bias-pull-down;
+ };
+ };
+
+ lt9611_irq_pin: lt9611-irq-state {
+ pins = "gpio85";
+ function = "gpio";
+ bias-disable;
+ };
+
+ lt9611_rst_pin: lt9611-rst-state {
+ pins = "gpio28";
+ function = "gpio";
+ output-high;
+ };
+
+ spkr_2_sd_n_active: spkr-2-sd-n-active-state {
+ pins = "gpio77";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+
+ wcd_default: wcd-reset-n-active-state {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+
+ wlan_en: wlan-en-state {
+ pins = "gpio16";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+};
+
+&uart14 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn7850-bt";
+
+ vddio-supply = <&vreg_l3c_1p2>;
+ vddaon-supply = <&vreg_l15b_1p8>;
+ vdddig-supply = <&vreg_s3c_0p9>;
+ vddrfa0p8-supply = <&vreg_s3c_0p9>;
+ vddrfa1p2-supply = <&vreg_s1c_1p2>;
+ vddrfa1p9-supply = <&vreg_s6c_1p8>;
+
+ max-speed = <3200000>;
+
+ enable-gpios = <&tlmm 17 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&bt_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&uart15 {
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l17b_2p5>;
+ vcc-max-microamp = <1300000>;
+ vccq-supply = <&vreg_l1c_1p2>;
+ vccq-max-microamp = <1200000>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l1d_0p88>;
+ vdda-pll-supply = <&vreg_l3i_1p2>;
+
+ status = "okay";
+};
+
+/*
+ * DPAUX -> WCD9395 -> USB_SBU -> USB-C
+ * eUSB2 DP/DM -> PM85550HS -> eUSB2 DP/DM -> WCD9395 -> USB-C
+ * USB SS -> USB-C
+ */
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "otg";
+ usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_hsphy {
+ vdd-supply = <&vreg_l1i_0p88>;
+ vdda12-supply = <&vreg_l3i_1p2>;
+
+ phys = <&pm8550b_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_dp_qmpphy {
+ vdda-phy-supply = <&vreg_l3i_1p2>;
+ vdda-pll-supply = <&vreg_l3g_0p91>;
+
+ status = "okay";
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss_in>;
+};
+
+&xo_board {
+ clock-frequency = <76800000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
index 4450273f9667..c63822f5b127 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
@@ -59,7 +59,7 @@
reg = <1>;
pmic_glink_ss_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_ss>;
+ remote-endpoint = <&usb_dp_qmpphy_out>;
};
};
};
@@ -641,14 +641,6 @@
status = "okay";
};
-&mdss_mdp {
- status = "okay";
-};
-
-&pcie_1_phy_aux_clk {
- clock-frequency = <1000>;
-};
-
&pcie0 {
wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
@@ -759,6 +751,16 @@
sound-name-prefix = "SpkrLeft";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3c_1p2>;
+
+ /*
+ * WSA8845 Port 1 (DAC) <=> SWR0 Port 1 (SPKR_L)
+ * WSA8845 Port 2 (COMP) <=> SWR0 Port 2 (SPKR_L_COMP)
+ * WSA8845 Port 3 (BOOST) <=> SWR0 Port 3 (SPKR_L_BOOST)
+ * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR)
+ * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 10 (SPKR_L_VI)
+ * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS)
+ */
+ qcom,port-mapping = <1 2 3 7 10 13>;
};
/* WSA8845, Speaker Right */
@@ -772,6 +774,16 @@
sound-name-prefix = "SpkrRight";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3c_1p2>;
+
+ /*
+ * WSA8845 Port 1 (DAC) <=> SWR0 Port 4 (SPKR_R)
+ * WSA8845 Port 2 (COMP) <=> SWR0 Port 5 (SPKR_R_COMP)
+ * WSA8845 Port 3 (BOOST) <=> SWR0 Port 6 (SPKR_R_BOOST)
+ * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR)
+ * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 11 (SPKR_R_VI)
+ * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS)
+ */
+ qcom,port-mapping = <4 5 6 7 11 13>;
};
};
@@ -857,10 +869,6 @@
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&pmic_glink_ss_in>;
-};
-
&usb_1_hsphy {
vdd-supply = <&vreg_l1i_0p88>;
vdda12-supply = <&vreg_l3i_1p2>;
@@ -877,6 +885,10 @@
status = "okay";
};
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss_in>;
+};
+
&xo_board {
clock-frequency = <76800000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index b07cac2e5bc8..b0d7927b708f 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -203,6 +203,71 @@
};
};
};
+
+ wcn7850-pmu {
+ compatible = "qcom,wcn7850-pmu";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_en>;
+
+ wlan-enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>;
+ /*
+ * TODO Add bt-enable-gpios once the Bluetooth driver is
+ * converted to using the power sequencer.
+ */
+
+ vdd-supply = <&vreg_s4i_0p85>;
+ vddio-supply = <&vreg_l15b_1p8>;
+ vddio1p2-supply = <&vreg_l3c_1p2>;
+ vddaon-supply = <&vreg_s2c_0p8>;
+ vdddig-supply = <&vreg_s3c_0p9>;
+ vddrfa1p2-supply = <&vreg_s1c_1p2>;
+ vddrfa1p8-supply = <&vreg_s6c_1p8>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK1>;
+
+ regulators {
+ vreg_pmu_rfa_cmn: ldo0 {
+ regulator-name = "vreg_pmu_rfa_cmn";
+ };
+
+ vreg_pmu_aon_0p59: ldo1 {
+ regulator-name = "vreg_pmu_aon_0p59";
+ };
+
+ vreg_pmu_wlcx_0p8: ldo2 {
+ regulator-name = "vreg_pmu_wlcx_0p8";
+ };
+
+ vreg_pmu_wlmx_0p85: ldo3 {
+ regulator-name = "vreg_pmu_wlmx_0p85";
+ };
+
+ vreg_pmu_btcmx_0p85: ldo4 {
+ regulator-name = "vreg_pmu_btcmx_0p85";
+ };
+
+ vreg_pmu_rfa_0p8: ldo5 {
+ regulator-name = "vreg_pmu_rfa_0p8";
+ };
+
+ vreg_pmu_rfa_1p2: ldo6 {
+ regulator-name = "vreg_pmu_rfa_1p2";
+ };
+
+ vreg_pmu_rfa_1p8: ldo7 {
+ regulator-name = "vreg_pmu_rfa_1p8";
+ };
+
+ vreg_pmu_pcie_0p9: ldo8 {
+ regulator-name = "vreg_pmu_pcie_0p9";
+ };
+
+ vreg_pmu_pcie_1p8: ldo9 {
+ regulator-name = "vreg_pmu_pcie_1p8";
+ };
+ };
+ };
};
&apps_rsc {
@@ -766,6 +831,14 @@
status = "okay";
};
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ firmware-name = "qcom/sm8650/gen70900_zap.mbn";
+ };
+};
+
&lpass_tlmm {
spkr_1_sd_n_active: spkr-1-sd-n-active-state {
pins = "gpio21";
@@ -824,15 +897,6 @@
&mdss_dp0_out {
data-lanes = <0 1>;
- remote-endpoint = <&usb_dp_qmpphy_dp_in>;
-};
-
-&mdss_mdp {
- status = "okay";
-};
-
-&pcie_1_phy_aux_clk {
- clock-frequency = <1000>;
};
&pcie0 {
@@ -845,6 +909,23 @@
status = "okay";
};
+&pcieport0 {
+ wifi@0 {
+ compatible = "pci17cb,1107";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ };
+};
+
&pcie0_phy {
vdda-phy-supply = <&vreg_l1i_0p88>;
vdda-pll-supply = <&vreg_l3i_1p2>;
@@ -1008,6 +1089,16 @@
sound-name-prefix = "SpkrLeft";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3c_1p2>;
+
+ /*
+ * WSA8845 Port 1 (DAC) <=> SWR0 Port 1 (SPKR_L)
+ * WSA8845 Port 2 (COMP) <=> SWR0 Port 2 (SPKR_L_COMP)
+ * WSA8845 Port 3 (BOOST) <=> SWR0 Port 3 (SPKR_L_BOOST)
+ * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR)
+ * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 10 (SPKR_L_VI)
+ * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS)
+ */
+ qcom,port-mapping = <1 2 3 7 10 13>;
};
/* WSA8845, Speaker Right */
@@ -1021,6 +1112,16 @@
sound-name-prefix = "SpkrRight";
vdd-1p8-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l3c_1p2>;
+
+ /*
+ * WSA8845 Port 1 (DAC) <=> SWR0 Port 4 (SPKR_R)
+ * WSA8845 Port 2 (COMP) <=> SWR0 Port 5 (SPKR_R_COMP)
+ * WSA8845 Port 3 (BOOST) <=> SWR0 Port 6 (SPKR_R_BOOST)
+ * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR)
+ * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 11 (SPKR_R_VI)
+ * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS)
+ */
+ qcom,port-mapping = <4 5 6 7 11 13>;
};
};
@@ -1139,6 +1240,13 @@
bias-disable;
output-low;
};
+
+ wlan_en: wlan-en-state {
+ pins = "gpio16";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
};
&uart14 {
@@ -1207,10 +1315,6 @@
remote-endpoint = <&pmic_glink_hs_in>;
};
-&usb_1_dwc3_ss {
- remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
-};
-
&usb_1_hsphy {
vdd-supply = <&vreg_l1i_0p88>;
vdda12-supply = <&vreg_l3i_1p2>;
@@ -1224,23 +1328,13 @@
vdda-phy-supply = <&vreg_l3i_1p2>;
vdda-pll-supply = <&vreg_l3g_0p91>;
- orientation-switch;
-
status = "okay";
};
-&usb_dp_qmpphy_dp_in {
- remote-endpoint = <&mdss_dp0_out>;
-};
-
&usb_dp_qmpphy_out {
remote-endpoint = <&redriver_ss_in>;
};
-&usb_dp_qmpphy_usb_ss_in {
- remote-endpoint = <&usb_1_dwc3_ss>;
-};
-
&xo_board {
clock-frequency = <76800000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index eb117866e59f..9d9bbb9aca64 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -4,10 +4,12 @@
*/
#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/clock/qcom,sm8650-camcc.h>
#include <dt-bindings/clock/qcom,sm8650-dispcc.h>
#include <dt-bindings/clock/qcom,sm8650-gcc.h>
#include <dt-bindings/clock/qcom,sm8650-gpucc.h>
#include <dt-bindings/clock/qcom,sm8650-tcsr.h>
+#include <dt-bindings/clock/qcom,sm8650-videocc.h>
#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
@@ -60,11 +62,6 @@
clock-mult = <1>;
clock-div = <2>;
};
-
- pcie_1_phy_aux_clk: pcie-1-phy-aux-clk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- };
};
cpus {
@@ -371,6 +368,7 @@
firmware {
scm: scm {
compatible = "qcom,scm-sm8650", "qcom,scm";
+ qcom,dload-mode = <&tcsr 0x19000>;
interconnects = <&aggre2_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
};
@@ -394,8 +392,18 @@
reg = <0 0xa0000000 0 0>;
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu-a520 {
+ compatible = "arm,cortex-a520-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-a720 {
+ compatible = "arm,cortex-a720-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu-x4 {
+ compatible = "arm,cortex-x4-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
@@ -485,9 +493,9 @@
no-map;
};
- /* Merged aop_config, tme_crash_dump, tme_log and uefi_log regions */
+ /* Merged aop_config, tme_crash_dump, tme_log, uefi_log, and chipinfo regions */
aop_tme_uefi_merged_mem: aop-tme-uefi-merged@81c80000 {
- reg = <0 0x81c80000 0 0x74000>;
+ reg = <0 0x81c80000 0 0x75000>;
no-map;
};
@@ -758,8 +766,8 @@
<&bi_tcxo_ao_div2>,
<&sleep_clk>,
<&pcie0_phy>,
- <&pcie1_phy>,
- <&pcie_1_phy_aux_clk>,
+ <&pcie1_phy QMP_PCIE_PIPE_CLK>,
+ <&pcie1_phy QMP_PCIE_PHY_AUX_CLK>,
<&ufs_mem_phy 0>,
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
@@ -2208,7 +2216,7 @@
reg = <0 0x010c3000 0 0x1000>;
};
- pcie0: pci@1c00000 {
+ pcie0: pcie@1c00000 {
device_type = "pci";
compatible = "qcom,pcie-sm8650", "qcom,pcie-sm8550";
reg = <0 0x01c00000 0 0x3000>,
@@ -2293,6 +2301,16 @@
dma-coherent;
status = "disabled";
+
+ pcieport0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_phy: phy@1c06000 {
@@ -2326,7 +2344,7 @@
status = "disabled";
};
- pcie1: pci@1c08000 {
+ pcie1: pcie@1c08000 {
device_type = "pci";
compatible = "qcom,pcie-sm8650", "qcom,pcie-sm8550";
reg = <0 0x01c08000 0 0x3000>,
@@ -2420,6 +2438,16 @@
<0x02000000 0 0x40300000 0 0x40300000 0 0x1fd00000>;
status = "disabled";
+
+ pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_phy: phy@1c0e000 {
@@ -2447,7 +2475,7 @@
power-domains = <&gcc PCIE_1_PHY_GDSC>;
- #clock-cells = <0>;
+ #clock-cells = <1>;
clock-output-names = "pcie1_pipe_clk";
#phy-cells = <0>;
@@ -2589,6 +2617,144 @@
#reset-cells = <1>;
};
+ gpu: gpu@3d00000 {
+ compatible = "qcom,adreno-43051401", "qcom,adreno";
+ reg = <0x0 0x03d00000 0x0 0x40000>,
+ <0x0 0x03d9e000 0x0 0x2000>,
+ <0x0 0x03d61000 0x0 0x800>;
+ reg-names = "kgsl_3d0_reg_memory",
+ "cx_mem",
+ "cx_dbgc";
+
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&adreno_smmu 0 0x0>,
+ <&adreno_smmu 1 0x0>;
+
+ operating-points-v2 = <&gpu_opp_table>;
+
+ qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
+
+ status = "disabled";
+
+ zap-shader {
+ memory-region = <&gpu_micro_code_mem>;
+ };
+
+ /* Speedbin needs more work on A740+, keep only lower freqs */
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-231000000 {
+ opp-hz = /bits/ 64 <231000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+ };
+
+ opp-310000000 {
+ opp-hz = /bits/ 64 <310000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+ };
+
+ opp-366000000 {
+ opp-hz = /bits/ 64 <366000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+ };
+
+ opp-422000000 {
+ opp-hz = /bits/ 64 <422000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+ };
+
+ opp-578000000 {
+ opp-hz = /bits/ 64 <578000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ };
+
+ opp-629000000 {
+ opp-hz = /bits/ 64 <629000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+ };
+
+ opp-680000000 {
+ opp-hz = /bits/ 64 <680000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+ };
+
+ opp-720000000 {
+ opp-hz = /bits/ 64 <720000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+ };
+
+ opp-770000000 {
+ opp-hz = /bits/ 64 <770000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+ };
+
+ opp-834000000 {
+ opp-hz = /bits/ 64 <834000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+ };
+ };
+ };
+
+ gmu: gmu@3d6a000 {
+ compatible = "qcom,adreno-gmu-750.1", "qcom,adreno-gmu";
+ reg = <0x0 0x03d6a000 0x0 0x35000>,
+ <0x0 0x03d50000 0x0 0x10000>,
+ <0x0 0x0b280000 0x0 0x10000>;
+ reg-names = "gmu", "rscc", "gmu_pdc";
+
+ interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hfi", "gmu";
+
+ 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>,
+ <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+ <&gpucc GPU_CC_DEMET_CLK>;
+ clock-names = "ahb",
+ "gmu",
+ "cxo",
+ "axi",
+ "memnoc",
+ "hub",
+ "demet";
+
+ power-domains = <&gpucc GPU_CX_GDSC>,
+ <&gpucc GPU_GX_GDSC>;
+ power-domain-names = "cx",
+ "gx";
+
+ iommus = <&adreno_smmu 5 0x0>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ operating-points-v2 = <&gmu_opp_table>;
+
+ gmu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-260000000 {
+ opp-hz = /bits/ 64 <260000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ };
+
+ opp-625000000 {
+ opp-hz = /bits/ 64 <625000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ };
+ };
+ };
+
gpucc: clock-controller@3d90000 {
compatible = "qcom,sm8650-gpucc";
reg = <0 0x03d90000 0 0xa000>;
@@ -2602,6 +2768,50 @@
#power-domain-cells = <1>;
};
+ adreno_smmu: iommu@3da0000 {
+ compatible = "qcom,sm8650-smmu-500", "qcom,adreno-smmu",
+ "qcom,smmu-500", "arm,mmu-500";
+ reg = <0x0 0x03da0000 0x0 0x40000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <1>;
+ interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+ <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+ <&gpucc GPU_CC_AHB_CLK>;
+ clock-names = "hlos",
+ "bus",
+ "iface",
+ "ahb";
+ power-domains = <&gpucc GPU_CX_GDSC>;
+ dma-coherent;
+ };
+
ipa: ipa@3f40000 {
compatible = "qcom,sm8650-ipa", "qcom,sm8550-ipa";
@@ -3108,6 +3318,30 @@
};
};
+ videocc: clock-controller@aaf0000 {
+ compatible = "qcom,sm8650-videocc";
+ reg = <0 0x0aaf0000 0 0x10000>;
+ clocks = <&bi_tcxo_div2>,
+ <&gcc GCC_VIDEO_AHB_CLK>;
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ camcc: clock-controller@ade0000 {
+ compatible = "qcom,sm8650-camcc";
+ reg = <0 0x0ade0000 0 0x20000>;
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&bi_tcxo_div2>,
+ <&bi_tcxo_ao_div2>,
+ <&sleep_clk>;
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
mdss: display-subsystem@ae00000 {
compatible = "qcom,sm8650-mdss";
reg = <0 0x0ae00000 0 0x1000>;
@@ -3474,6 +3708,7 @@
reg = <1>;
mdss_dp0_out: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
};
};
};
@@ -3549,6 +3784,8 @@
#clock-cells = <1>;
#phy-cells = <1>;
+ orientation-switch;
+
status = "disabled";
ports {
@@ -3566,6 +3803,7 @@
reg = <1>;
usb_dp_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_dwc3_ss>;
};
};
@@ -3573,6 +3811,7 @@
reg = <2>;
usb_dp_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp0_out>;
};
};
};
@@ -3582,14 +3821,16 @@
compatible = "qcom,sm8650-dwc3", "qcom,dwc3";
reg = <0 0x0a6f8800 0 0x400>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 14 IRQ_TYPE_EDGE_RISING>,
<&pdc 15 IRQ_TYPE_EDGE_RISING>,
- <&pdc 14 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "hs_phy_irq",
- "ss_phy_irq",
+ <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "hs_phy_irq",
+ "dp_hs_phy_irq",
"dm_hs_phy_irq",
- "dp_hs_phy_irq";
+ "ss_phy_irq";
clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_MASTER_CLK>,
@@ -3661,6 +3902,7 @@
reg = <1>;
usb_1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
};
};
@@ -4779,12 +5021,14 @@
<0 0x25400000 0 0x200000>,
<0 0x25200000 0 0x200000>,
<0 0x25600000 0 0x200000>,
- <0 0x25800000 0 0x200000>;
+ <0 0x25800000 0 0x200000>,
+ <0 0x25a00000 0 0x200000>;
reg-names = "llcc0_base",
"llcc1_base",
"llcc2_base",
"llcc3_base",
- "llcc_broadcast_base";
+ "llcc_broadcast_base",
+ "llcc_broadcast_and_base";
interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -4843,6 +5087,8 @@
label = "adsp";
+ qcom,non-secure-domain;
+
#address-cells = <1>;
#size-cells = <0>;
@@ -5000,6 +5246,8 @@
label = "cdsp";
+ qcom,non-secure-domain;
+
#address-cells = <1>;
#size-cells = <0>;
@@ -5082,6 +5330,38 @@
<&apps_smmu 0x19c8 0x0>;
dma-coherent;
};
+
+ /* note: secure cb9 in downstream */
+
+ compute-cb@10 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <12>;
+
+ iommus = <&apps_smmu 0x196c 0x0>,
+ <&apps_smmu 0x0c0c 0x20>,
+ <&apps_smmu 0x19cc 0x0>;
+ dma-coherent;
+ };
+
+ compute-cb@11 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <13>;
+
+ iommus = <&apps_smmu 0x196d 0x0>,
+ <&apps_smmu 0x0c0d 0x20>,
+ <&apps_smmu 0x19cd 0x0>;
+ dma-coherent;
+ };
+
+ compute-cb@12 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <14>;
+
+ iommus = <&apps_smmu 0x196e 0x0>,
+ <&apps_smmu 0x0c0e 0x20>,
+ <&apps_smmu 0x19ce 0x0>;
+ dma-coherent;
+ };
};
};
};
@@ -5089,8 +5369,6 @@
thermal-zones {
aoss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 0>;
trips {
@@ -5109,8 +5387,6 @@
};
cpuss0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 1>;
trips {
@@ -5129,8 +5405,6 @@
};
cpuss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 2>;
trips {
@@ -5149,8 +5423,6 @@
};
cpuss2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 3>;
trips {
@@ -5169,8 +5441,6 @@
};
cpuss3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
trips {
@@ -5189,8 +5459,6 @@
};
cpu2-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
trips {
@@ -5215,8 +5483,6 @@
};
cpu2-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
trips {
@@ -5241,8 +5507,6 @@
};
cpu3-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
trips {
@@ -5267,8 +5531,6 @@
};
cpu3-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
trips {
@@ -5293,8 +5555,6 @@
};
cpu4-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
trips {
@@ -5319,8 +5579,6 @@
};
cpu4-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
trips {
@@ -5345,8 +5603,6 @@
};
cpu5-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
trips {
@@ -5371,8 +5627,6 @@
};
cpu5-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
trips {
@@ -5397,8 +5651,6 @@
};
cpu6-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 13>;
trips {
@@ -5423,8 +5675,6 @@
};
cpu6-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens0 14>;
trips {
@@ -5449,8 +5699,6 @@
};
aoss1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 0>;
trips {
@@ -5469,8 +5717,6 @@
};
cpu7-top-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
trips {
@@ -5495,8 +5741,6 @@
};
cpu7-middle-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
trips {
@@ -5521,8 +5765,6 @@
};
cpu7-bottom-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 3>;
trips {
@@ -5547,8 +5789,6 @@
};
cpu0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 4>;
trips {
@@ -5573,8 +5813,6 @@
};
cpu1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 5>;
trips {
@@ -5600,7 +5838,7 @@
nsphvx0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 6>;
trips {
@@ -5620,7 +5858,7 @@
nsphvx1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 7>;
trips {
@@ -5640,7 +5878,7 @@
nsphmx0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 8>;
trips {
@@ -5660,7 +5898,7 @@
nsphmx1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 9>;
trips {
@@ -5680,7 +5918,7 @@
nsphmx2-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 10>;
trips {
@@ -5700,7 +5938,7 @@
nsphmx3-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 11>;
trips {
@@ -5720,7 +5958,7 @@
video-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 12>;
trips {
@@ -5740,7 +5978,7 @@
ddr-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens1 13>;
trips {
@@ -5759,8 +5997,6 @@
};
camera0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 14>;
trips {
@@ -5779,8 +6015,6 @@
};
camera1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens1 15>;
trips {
@@ -5799,8 +6033,6 @@
};
aoss2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 0>;
trips {
@@ -5820,19 +6052,32 @@
gpuss0-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 1>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu0_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu0_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss0-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5840,19 +6085,32 @@
gpuss1-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 2>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu1_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu1_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss1-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5860,19 +6118,32 @@
gpuss2-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 3>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu2_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu2_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss2-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5880,19 +6151,32 @@
gpuss3-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 4>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu3_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu3_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss3-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5900,19 +6184,32 @@
gpuss4-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 5>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu4_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu4_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss4-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5920,19 +6217,32 @@
gpuss5-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 6>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu5_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu5_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss5-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5940,19 +6250,32 @@
gpuss6-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 7>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu6_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu6_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss6-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
@@ -5960,27 +6283,38 @@
gpuss7-thermal {
polling-delay-passive = <10>;
- polling-delay = <0>;
+
thermal-sensors = <&tsens2 8>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu7_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu7_alert0: trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
temperature = <90000>;
- hysteresis = <2000>;
+ hysteresis = <1000>;
type = "hot";
};
- gpuss7-critical {
+ trip-point2 {
temperature = <110000>;
- hysteresis = <0>;
+ hysteresis = <1000>;
type = "critical";
};
};
};
modem0-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 9>;
trips {
@@ -5999,8 +6333,6 @@
};
modem1-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 10>;
trips {
@@ -6019,8 +6351,6 @@
};
modem2-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 11>;
trips {
@@ -6039,8 +6369,6 @@
};
modem3-thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
thermal-sensors = <&tsens2 12>;
trips {
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts
new file mode 100644
index 000000000000..7fb980fcb307
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts
@@ -0,0 +1,616 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2024, Xilin Wu <wuxilin123@gmail.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "x1e80100.dtsi"
+#include "x1e80100-pmics.dtsi"
+
+/ {
+ model = "ASUS Vivobook S 15";
+ compatible = "asus,vivobook-s15", "qcom,x1e80100";
+ chassis-type = "laptop";
+
+ pmic-glink {
+ compatible = "qcom,x1e80100-pmic-glink",
+ "qcom,sm8550-pmic-glink",
+ "qcom,pmic-glink";
+ orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>,
+ <&tlmm 123 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* Left-side port, closer to the screen */
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss0_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ /* Left-side port, farther from the screen */
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss1_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ size = <0x0 0x8000000>;
+ reusable;
+ linux,cma-default;
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vreg_edp_3p3: regulator-edp-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_EDP_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&edp_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vreg_nvme: regulator-nvme {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_NVME_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&nvme_reg_en>;
+ pinctrl-names = "default";
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
+ vdd-l1-l4-l10-supply = <&vreg_s4c_1p8>;
+ vdd-l2-l13-l14-supply = <&vreg_bob1>;
+ vdd-l5-l16-supply = <&vreg_bob1>;
+ vdd-l6-l7-supply = <&vreg_bob2>;
+ vdd-l8-l9-supply = <&vreg_bob1>;
+ vdd-l12-supply = <&vreg_s5j_1p2>;
+ vdd-l15-supply = <&vreg_s4c_1p8>;
+ vdd-l17-supply = <&vreg_bob2>;
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p0: ldo14 {
+ regulator-name = "vreg_l14b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-l1-supply = <&vreg_s5j_1p2>;
+ vdd-l2-supply = <&vreg_s1f_0p7>;
+ vdd-l3-supply = <&vreg_s1f_0p7>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ vreg_s4c_1p8: smps4 {
+ regulator-name = "vreg_s4c_1p8";
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ vdd-l1-supply = <&vreg_s1f_0p7>;
+ vdd-l2-supply = <&vreg_s1f_0p7>;
+ vdd-l3-supply = <&vreg_s4c_1p8>;
+ vdd-s1-supply = <&vph_pwr>;
+
+ vreg_l1d_0p8: ldo1 {
+ regulator-name = "vreg_l1d_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2d_0p9: ldo2 {
+ regulator-name = "vreg_l2d_0p9";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3d_1p8: ldo3 {
+ regulator-name = "vreg_l3d_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vdd-l2-supply = <&vreg_s1f_0p7>;
+ vdd-l3-supply = <&vreg_s5j_1p2>;
+
+ vreg_l2e_0p8: ldo2 {
+ regulator-name = "vreg_l2e_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vdd-l1-supply = <&vreg_s5j_1p2>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-l3-supply = <&vreg_s5j_1p2>;
+ vdd-s1-supply = <&vph_pwr>;
+
+ vreg_s1f_0p7: smps1 {
+ regulator-name = "vreg_s1f_0p7";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-6 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "i";
+
+ vdd-l1-supply = <&vreg_s4c_1p8>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-l3-supply = <&vreg_s1f_0p7>;
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ };
+
+ regulators-7 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "j";
+
+ vdd-l1-supply = <&vreg_s1f_0p7>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-l3-supply = <&vreg_s1f_0p7>;
+ vdd-s5-supply = <&vph_pwr>;
+
+ vreg_s5j_1p2: smps5 {
+ regulator-name = "vreg_s5j_1p2";
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1j_0p8: ldo1 {
+ regulator-name = "vreg_l1j_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2j_1p2: ldo2 {
+ regulator-name = "vreg_l2j_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3j_0p8: ldo3 {
+ regulator-name = "vreg_l3j_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ touchpad@15 {
+ compatible = "hid-over-i2c";
+ reg = <0x15>;
+
+ hid-descr-addr = <0x1>;
+ interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&tpad_default>;
+ pinctrl-names = "default";
+
+ wakeup-source;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ /* PS8830 USB4 Retimer? @ 0x8 */
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ /* PS8830 USB4 Retimer? @ 0x8 */
+};
+
+&i2c5 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ keyboard@3a {
+ compatible = "hid-over-i2c";
+ reg = <0x3a>;
+
+ hid-descr-addr = <0x1>;
+ interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&kybd_default>;
+ pinctrl-names = "default";
+
+ wakeup-source;
+ };
+
+ /* EC? @ 0x5b, 0x76 */
+};
+
+&i2c7 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ /* PS8830 USB4 Retimer? @ 0x8 */
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dp3 {
+ compatible = "qcom,x1e80100-dp";
+ /delete-property/ #sound-dai-cells;
+
+ status = "okay";
+
+ aux-bus {
+ panel {
+ compatible = "edp-panel";
+ power-supply = <&vreg_edp_3p3>;
+
+ port {
+ edp_panel_in: endpoint {
+ remote-endpoint = <&mdss_dp3_out>;
+ };
+ };
+ };
+ };
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ mdss_dp3_out: endpoint {
+ data-lanes = <0 1 2 3>;
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
+ remote-endpoint = <&edp_panel_in>;
+ };
+ };
+ };
+};
+
+&mdss_dp3_phy {
+ vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-pll-supply = <&vreg_l2j_1p2>;
+
+ status = "okay";
+};
+
+&pcie4 {
+ status = "okay";
+};
+
+&pcie4_phy {
+ vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&pcie6a {
+ perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
+
+ vddpe-3v3-supply = <&vreg_nvme>;
+
+ pinctrl-0 = <&pcie6a_default>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcie6a_phy {
+ vdda-phy-supply = <&vreg_l1d_0p8>;
+ vdda-pll-supply = <&vreg_l2j_1p2>;
+
+ status = "okay";
+};
+
+&qupv3_0 {
+ status = "okay";
+};
+
+&qupv3_1 {
+ status = "okay";
+};
+
+&qupv3_2 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/x1e80100/ASUSTeK/vivobook-s15/qcadsp8380.mbn",
+ "qcom/x1e80100/ASUSTeK/vivobook-s15/adsp_dtbs.elf";
+
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/x1e80100/ASUSTeK/vivobook-s15/qccdsp8380.mbn",
+ "qcom/x1e80100/ASUSTeK/vivobook-s15/cdsp_dtbs.elf";
+
+ status = "okay";
+};
+
+&smb2360_0_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&smb2360_2 {
+ status = "disabled";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <34 2>, /* Unused */
+ <44 4>, /* SPI (TPM) */
+ <238 1>; /* UFS Reset */
+
+ edp_reg_en: edp-reg-en-state {
+ pins = "gpio70";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ kybd_default: kybd-default-state {
+ pins = "gpio67";
+ function = "gpio";
+ bias-disable;
+ };
+
+ nvme_reg_en: nvme-reg-en-state {
+ pins = "gpio18";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ pcie6a_default: pcie2a-default-state {
+ clkreq-n-pins {
+ pins = "gpio153";
+ function = "pcie6a_clk";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio152";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ wake-n-pins {
+ pins = "gpio154";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ tpad_default: tpad-default-state {
+ pins = "gpio3";
+ function = "gpio";
+ bias-disable;
+ };
+};
+
+&usb_1_ss0_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_0_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss0_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l1j_0p8>;
+
+ orientation-switch;
+
+ status = "okay";
+};
+
+&usb_1_ss0 {
+ status = "okay";
+};
+
+&usb_1_ss0_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_ss0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss0_hs_in>;
+};
+
+&usb_1_ss0_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
+};
+
+&usb_1_ss1_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_1_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss1_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
+ orientation-switch;
+
+ status = "okay";
+};
+
+&usb_1_ss1 {
+ status = "okay";
+};
+
+&usb_1_ss1_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_ss1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss1_hs_in>;
+};
+
+&usb_1_ss1_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
+};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
index 6a0a54532e5f..6152bcd0bc1f 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "x1e80100.dtsi"
+#include "x1e80100-pmics.dtsi"
/ {
model = "Qualcomm Technologies, Inc. X1E80100 CRD";
@@ -48,6 +49,113 @@
stdout-path = "serial0:115200n8";
};
+ pmic-glink {
+ compatible = "qcom,x1e80100-pmic-glink",
+ "qcom,sm8550-pmic-glink",
+ "qcom,pmic-glink";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>,
+ <&tlmm 123 GPIO_ACTIVE_HIGH>,
+ <&tlmm 125 GPIO_ACTIVE_HIGH>;
+
+ /* Left-side rear port */
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss0_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ /* Left-side front port */
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss1_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ /* Right-side port */
+ connector@2 {
+ compatible = "usb-c-connector";
+ reg = <2>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss2_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss2_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_qmpphy_out>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ size = <0x0 0x8000000>;
+ reusable;
+ linux,cma-default;
+ };
+ };
+
sound {
compatible = "qcom,x1e80100-sndcard";
model = "X1E80100-CRD";
@@ -92,7 +200,7 @@
};
codec {
- sound-dai = <&wcd938x 1>, <&swr2 0>, <&lpass_txmacro 0>;
+ sound-dai = <&wcd938x 1>, <&swr2 1>, <&lpass_txmacro 0>;
};
platform {
@@ -163,6 +271,20 @@
regulator-always-on;
regulator-boot-on;
};
+
+ vreg_nvme: regulator-nvme {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_NVME_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nvme_reg_en>;
+ };
};
&apps_rsc {
@@ -598,8 +720,6 @@
compatible = "qcom,x1e80100-dp";
/delete-property/ #sound-dai-cells;
- data-lanes = <0 1 2 3>;
-
status = "okay";
aux-bus {
@@ -619,6 +739,9 @@
port@1 {
reg = <1>;
mdss_dp3_out: endpoint {
+ data-lanes = <0 1 2 3>;
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
remote-endpoint = <&edp_panel_in>;
};
};
@@ -644,11 +767,19 @@
};
&pcie6a {
+ perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
+
+ vddpe-3v3-supply = <&vreg_nvme>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie6a_default>;
+
status = "okay";
};
&pcie6a_phy {
- vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-phy-supply = <&vreg_l1d_0p8>;
vdda-pll-supply = <&vreg_l2j_1p2>;
status = "okay";
@@ -680,16 +811,32 @@
status = "okay";
};
+&smb2360_0_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&smb2360_2_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l8b_3p0>;
+};
+
&swr0 {
status = "okay";
+ pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>;
+ pinctrl-names = "default";
+
/* WSA8845, Left Woofer */
left_woofer: speaker@0,0 {
compatible = "sdw20217020400";
reg = <0 0>;
- pinctrl-0 = <&spkr_01_sd_n_active>;
- pinctrl-names = "default";
- powerdown-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
#sound-dai-cells = <0>;
sound-name-prefix = "WooferLeft";
vdd-1p8-supply = <&vreg_l15b_1p8>;
@@ -700,8 +847,7 @@
left_tweeter: speaker@0,1 {
compatible = "sdw20217020400";
reg = <0 1>;
- /* pinctrl in left_woofer node because of sharing the GPIO*/
- powerdown-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
#sound-dai-cells = <0>;
sound-name-prefix = "TwitterLeft";
vdd-1p8-supply = <&vreg_l15b_1p8>;
@@ -727,20 +873,21 @@
wcd_tx: codec@0,3 {
compatible = "sdw20217010d00";
reg = <0 3>;
- qcom,tx-port-mapping = <1 1 2 3>;
+ qcom,tx-port-mapping = <2 2 3 4>;
};
};
&swr3 {
status = "okay";
+ pinctrl-0 = <&wsa2_swr_active>, <&spkr_23_sd_n_active>;
+ pinctrl-names = "default";
+
/* WSA8845, Right Woofer */
right_woofer: speaker@0,0 {
compatible = "sdw20217020400";
reg = <0 0>;
- pinctrl-0 = <&spkr_23_sd_n_active>;
- pinctrl-names = "default";
- powerdown-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
#sound-dai-cells = <0>;
sound-name-prefix = "WooferRight";
vdd-1p8-supply = <&vreg_l15b_1p8>;
@@ -751,8 +898,7 @@
right_tweeter: speaker@0,1 {
compatible = "sdw20217020400";
reg = <0 1>;
- /* pinctrl in right_woofer node because of sharing the GPIO*/
- powerdown-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
#sound-dai-cells = <0>;
sound-name-prefix = "TwitterRight";
vdd-1p8-supply = <&vreg_l15b_1p8>;
@@ -778,6 +924,36 @@
bias-disable;
};
+ nvme_reg_en: nvme-reg-en-state {
+ pins = "gpio18";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ pcie6a_default: pcie2a-default-state {
+ clkreq-n-pins {
+ pins = "gpio153";
+ function = "pcie6a_clk";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio152";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ wake-n-pins {
+ pins = "gpio154";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
tpad_default: tpad-default-state {
pins = "gpio3";
function = "gpio";
@@ -814,13 +990,18 @@
};
&usb_1_ss0_hsphy {
- vdd-supply = <&vreg_l2e_0p8>;
- vdda12-supply = <&vreg_l3e_1p2>;
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_0_eusb2_repeater>;
status = "okay";
};
&usb_1_ss0_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l1j_0p8>;
+
status = "okay";
};
@@ -830,17 +1011,29 @@
&usb_1_ss0_dwc3 {
dr_mode = "host";
- usb-role-switch;
+};
+
+&usb_1_ss0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss0_hs_in>;
+};
+
+&usb_1_ss0_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
};
&usb_1_ss1_hsphy {
- vdd-supply = <&vreg_l2e_0p8>;
- vdda12-supply = <&vreg_l3e_1p2>;
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_1_eusb2_repeater>;
status = "okay";
};
&usb_1_ss1_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
status = "okay";
};
@@ -850,17 +1043,29 @@
&usb_1_ss1_dwc3 {
dr_mode = "host";
- usb-role-switch;
+};
+
+&usb_1_ss1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss1_hs_in>;
+};
+
+&usb_1_ss1_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
};
&usb_1_ss2_hsphy {
- vdd-supply = <&vreg_l2e_0p8>;
- vdda12-supply = <&vreg_l3e_1p2>;
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_2_eusb2_repeater>;
status = "okay";
};
&usb_1_ss2_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
status = "okay";
};
@@ -870,5 +1075,12 @@
&usb_1_ss2_dwc3 {
dr_mode = "host";
- usb-role-switch;
+};
+
+&usb_1_ss2_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss2_hs_in>;
+};
+
+&usb_1_ss2_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss2_ss_in>;
};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts
new file mode 100644
index 000000000000..fbff558f5b07
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts
@@ -0,0 +1,929 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "x1e80100.dtsi"
+#include "x1e80100-pmics.dtsi"
+
+/ {
+ model = "Lenovo Yoga Slim 7x";
+ compatible = "lenovo,yoga-slim7x", "qcom,x1e80100";
+
+ pmic-glink {
+ compatible = "qcom,x1e80100-pmic-glink",
+ "qcom,sm8550-pmic-glink",
+ "qcom,pmic-glink";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>,
+ <&tlmm 123 GPIO_ACTIVE_HIGH>,
+ <&tlmm 125 GPIO_ACTIVE_HIGH>;
+
+ /* Left-side rear port */
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss0_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ /* Left-side front port */
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss1_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ /* Right-side port */
+ connector@2 {
+ compatible = "usb-c-connector";
+ reg = <2>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss2_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss2_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_qmpphy_out>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ size = <0x0 0x8000000>;
+ reusable;
+ linux,cma-default;
+ };
+ };
+
+ sound {
+ compatible = "qcom,x1e80100-sndcard";
+ model = "X1E80100-LENOVO-Yoga-Slim7x";
+ audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT",
+ "TweeterLeft IN", "WSA WSA_SPK2 OUT",
+ "WooferRight IN", "WSA2 WSA_SPK2 OUT",
+ "TweeterRight IN", "WSA2 WSA_SPK2 OUT";
+
+ wsa-dai-link {
+ link-name = "WSA Playback";
+
+ cpu {
+ sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>;
+ };
+
+ codec {
+ sound-dai = <&left_woofer>, <&left_tweeter>,
+ <&swr0 0>, <&lpass_wsamacro 0>,
+ <&right_woofer>, <&right_tweeter>,
+ <&swr3 0>, <&lpass_wsa2macro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ va-dai-link {
+ link-name = "VA Capture";
+
+ cpu {
+ sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>;
+ };
+
+ codec {
+ sound-dai = <&lpass_vamacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vreg_edp_3p3: regulator-edp-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_EDP_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&edp_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vreg_nvme: regulator-nvme {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_NVME_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&nvme_reg_en>;
+ pinctrl-names = "default";
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
+ vdd-l1-l4-l10-supply = <&vreg_s4c_1p8>;
+ vdd-l2-l13-l14-supply = <&vreg_bob1>;
+ vdd-l5-l16-supply = <&vreg_bob1>;
+ vdd-l6-l7-supply = <&vreg_bob2>;
+ vdd-l8-l9-supply = <&vreg_bob1>;
+ vdd-l12-supply = <&vreg_s5j_1p2>;
+ vdd-l15-supply = <&vreg_s4c_1p8>;
+ vdd-l17-supply = <&vreg_bob2>;
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1b_1p8: ldo1 {
+ regulator-name = "vreg_l1b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b_3p0: ldo8 {
+ regulator-name = "vreg_l8b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b_1p2: ldo12 {
+ regulator-name = "vreg_l12b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p0: ldo14 {
+ regulator-name = "vreg_l14b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b_1p8: ldo15 {
+ regulator-name = "vreg_l15b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-l1-supply = <&vreg_s5j_1p2>;
+ vdd-l2-supply = <&vreg_s1f_0p7>;
+ vdd-l3-supply = <&vreg_s1f_0p7>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ vreg_s4c_1p8: smps4 {
+ regulator-name = "vreg_s4c_1p8";
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1c_1p2: ldo1 {
+ regulator-name = "vreg_l1c_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c_0p8: ldo2 {
+ regulator-name = "vreg_l2c_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_0p8: ldo3 {
+ regulator-name = "vreg_l3c_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ vdd-l1-supply = <&vreg_s1f_0p7>;
+ vdd-l2-supply = <&vreg_s1f_0p7>;
+ vdd-l3-supply = <&vreg_s4c_1p8>;
+ vdd-s1-supply = <&vph_pwr>;
+
+ vreg_l1d_0p8: ldo1 {
+ regulator-name = "vreg_l1d_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2d_0p9: ldo2 {
+ regulator-name = "vreg_l2d_0p9";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3d_1p8: ldo3 {
+ regulator-name = "vreg_l3d_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vdd-l2-supply = <&vreg_s1f_0p7>;
+ vdd-l3-supply = <&vreg_s5j_1p2>;
+
+ vreg_l2e_0p8: ldo2 {
+ regulator-name = "vreg_l2e_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vdd-l1-supply = <&vreg_s5j_1p2>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-l3-supply = <&vreg_s5j_1p2>;
+ vdd-s1-supply = <&vph_pwr>;
+
+ vreg_s1f_0p7: smps1 {
+ regulator-name = "vreg_s1f_0p7";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1f_1p0: ldo1 {
+ regulator-name = "vreg_l1f_1p0";
+ regulator-min-microvolt = <1024000>;
+ regulator-max-microvolt = <1024000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2f_1p0: ldo2 {
+ regulator-name = "vreg_l2f_1p0";
+ regulator-min-microvolt = <1024000>;
+ regulator-max-microvolt = <1024000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3f_1p0: ldo3 {
+ regulator-name = "vreg_l3f_1p0";
+ regulator-min-microvolt = <1024000>;
+ regulator-max-microvolt = <1024000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-6 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "i";
+
+ vdd-l1-supply = <&vreg_s4c_1p8>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-l3-supply = <&vreg_s1f_0p7>;
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+
+ vreg_s1i_0p9: smps1 {
+ regulator-name = "vreg_s1i_0p9";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s2i_1p0: smps2 {
+ regulator-name = "vreg_s2i_1p0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1i_1p8: ldo1 {
+ regulator-name = "vreg_l1i_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2i_1p2: ldo2 {
+ regulator-name = "vreg_l2i_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3i_0p8: ldo3 {
+ regulator-name = "vreg_l3i_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-7 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "j";
+
+ vdd-l1-supply = <&vreg_s1f_0p7>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-l3-supply = <&vreg_s1f_0p7>;
+ vdd-s5-supply = <&vph_pwr>;
+
+ vreg_s5j_1p2: smps5 {
+ regulator-name = "vreg_s5j_1p2";
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1j_0p8: ldo1 {
+ regulator-name = "vreg_l1j_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2j_1p2: ldo2 {
+ regulator-name = "vreg_l2j_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3j_0p8: ldo3 {
+ regulator-name = "vreg_l3j_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ firmware-name = "qcom/x1e80100/LENOVO/83ED/qcdxkmsuc8380.mbn";
+ };
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ touchpad@2c {
+ compatible = "hid-over-i2c";
+ reg = <0x2c>;
+
+ hid-descr-addr = <0x20>;
+ interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&tpad_default>;
+ pinctrl-names = "default";
+
+ wakeup-source;
+ };
+
+ keyboard@3a {
+ compatible = "hid-over-i2c";
+ reg = <0x3a>;
+
+ hid-descr-addr = <0x1>;
+ interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&kybd_default>;
+ pinctrl-names = "default";
+
+ wakeup-source;
+ };
+};
+
+&i2c8 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ touchscreen@14 {
+ compatible = "hid-over-i2c";
+ reg = <0x14>;
+
+ hid-descr-addr = <0x1>;
+ interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&ts0_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&lpass_tlmm {
+ spkr_01_sd_n_active: spkr-01-sd-n-active-state {
+ pins = "gpio12";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+
+ spkr_23_sd_n_active: spkr-23-sd-n-active-state {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+};
+
+&lpass_vamacro {
+ pinctrl-0 = <&dmic01_default>, <&dmic23_default>;
+ pinctrl-names = "default";
+
+ vdd-micb-supply = <&vreg_l1b_1p8>;
+ qcom,dmic-sample-rate = <4800000>;
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dp3 {
+ compatible = "qcom,x1e80100-dp";
+ /delete-property/ #sound-dai-cells;
+
+ status = "okay";
+
+ aux-bus {
+ panel {
+ compatible = "edp-panel";
+ power-supply = <&vreg_edp_3p3>;
+
+ port {
+ edp_panel_in: endpoint {
+ remote-endpoint = <&mdss_dp3_out>;
+ };
+ };
+ };
+ };
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ mdss_dp3_out: endpoint {
+ data-lanes = <0 1 2 3>;
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
+ remote-endpoint = <&edp_panel_in>;
+ };
+ };
+ };
+};
+
+&mdss_dp3_phy {
+ vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-pll-supply = <&vreg_l2j_1p2>;
+
+ status = "okay";
+};
+
+&pcie4 {
+ status = "okay";
+};
+
+&pcie4_phy {
+ vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&pcie6a {
+ perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
+
+ vddpe-3v3-supply = <&vreg_nvme>;
+
+ pinctrl-0 = <&pcie6a_default>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcie6a_phy {
+ vdda-phy-supply = <&vreg_l1d_0p8>;
+ vdda-pll-supply = <&vreg_l2j_1p2>;
+
+ status = "okay";
+};
+
+&qupv3_0 {
+ status = "okay";
+};
+
+&qupv3_1 {
+ status = "okay";
+};
+
+&qupv3_2 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/x1e80100/LENOVO/83ED/qcadsp8380.mbn",
+ "qcom/x1e80100/LENOVO/83ED/adsp_dtbs.elf";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/x1e80100/LENOVO/83ED/qccdsp8380.mbn",
+ "qcom/x1e80100/LENOVO/83ED/cdsp_dtbs.elf";
+
+ status = "okay";
+};
+
+&smb2360_0_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&smb2360_2_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l8b_3p0>;
+};
+
+&swr0 {
+ status = "okay";
+
+ pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>;
+ pinctrl-names = "default";
+
+ /* WSA8845, Left Woofer */
+ left_woofer: speaker@0,0 {
+ compatible = "sdw20217020400";
+ reg = <0 0>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "WooferLeft";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ qcom,port-mapping = <1 2 3 7 10 13>;
+ };
+
+ /* WSA8845, Left Tweeter */
+ left_tweeter: speaker@0,1 {
+ compatible = "sdw20217020400";
+ reg = <0 1>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TweeterLeft";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ qcom,port-mapping = <4 5 6 7 11 13>;
+ };
+};
+
+
+&swr3 {
+ status = "okay";
+
+ pinctrl-0 = <&wsa2_swr_active>, <&spkr_23_sd_n_active>;
+ pinctrl-names = "default";
+
+ /* WSA8845, Right Woofer */
+ right_woofer: speaker@0,0 {
+ compatible = "sdw20217020400";
+ reg = <0 0>;
+ reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "WooferRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ qcom,port-mapping = <1 2 3 7 10 13>;
+ };
+
+ /* WSA8845, Right Tweeter */
+ right_tweeter: speaker@0,1 {
+ compatible = "sdw20217020400";
+ reg = <0 1>;
+ reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TweeterRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ qcom,port-mapping = <4 5 6 7 11 13>;
+ };
+};
+
+&tlmm {
+ gpio-reserved-ranges = <34 2>, /* Unused */
+ <44 4>, /* SPI (TPM) */
+ <238 1>; /* UFS Reset */
+
+ edp_reg_en: edp-reg-en-state {
+ pins = "gpio70";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ kybd_default: kybd-default-state {
+ pins = "gpio67";
+ function = "gpio";
+ bias-disable;
+ };
+
+ nvme_reg_en: nvme-reg-en-state {
+ pins = "gpio18";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ pcie6a_default: pcie2a-default-state {
+ clkreq-n-pins {
+ pins = "gpio153";
+ function = "pcie6a_clk";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio152";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ wake-n-pins {
+ pins = "gpio154";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ tpad_default: tpad-default-state {
+ pins = "gpio3";
+ function = "gpio";
+ bias-disable;
+ };
+
+ ts0_default: ts0-default-state {
+ int-n-pins {
+ pins = "gpio51";
+ function = "gpio";
+ bias-disable;
+ };
+
+ reset-n-pins {
+ pins = "gpio48";
+ function = "gpio";
+ output-high;
+ drive-strength = <16>;
+ };
+ };
+
+};
+
+&usb_1_ss0_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_0_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss0_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l1j_0p8>;
+
+ orientation-switch;
+
+ status = "okay";
+};
+
+&usb_1_ss0 {
+ status = "okay";
+};
+
+&usb_1_ss0_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_ss0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss0_hs_in>;
+};
+
+&usb_1_ss0_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
+};
+
+&usb_1_ss1_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_1_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss1_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
+ orientation-switch;
+
+ status = "okay";
+};
+
+&usb_1_ss1 {
+ status = "okay";
+};
+
+&usb_1_ss1_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_ss1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss1_hs_in>;
+};
+
+&usb_1_ss1_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
+};
+
+&usb_1_ss2_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_2_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss2_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
+ status = "okay";
+};
+
+&usb_1_ss2 {
+ status = "okay";
+};
+
+&usb_1_ss2_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_ss2_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss2_hs_in>;
+};
+
+&usb_1_ss2_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss2_ss_in>;
+};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi b/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi
new file mode 100644
index 000000000000..e34e70922cd3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi
@@ -0,0 +1,533 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+ thermal-zones {
+ pm8550-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pm8550_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pm8550ve-2-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pm8550ve_2_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pmc8380-3-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pmc8380_3_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pmc8380-4-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pmc8380_4_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pmc8380-5-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pmc8380_5_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pmc8380-6-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pmc8380_6_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pm8550ve-8-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pm8550ve_8_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pm8550ve-9-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pm8550ve_9_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+
+ pm8010-thermal {
+ polling-delay-passive = <100>;
+
+ thermal-sensors = <&pm8010_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+ };
+};
+
+&spmi_bus0 {
+ /* PMK8380 */
+ pmk8550: pmic@0 {
+ compatible = "qcom,pm8550", "qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmk8550_pon: pon@1300 {
+ compatible = "qcom,pmk8350-pon";
+ reg = <0x1300>, <0x800>;
+ reg-names = "hlos", "pbs";
+
+ pon_pwrkey: pwrkey {
+ compatible = "qcom,pmk8350-pwrkey";
+ interrupts = <0x0 0x13 0x7 IRQ_TYPE_EDGE_BOTH>;
+ linux,code = <KEY_POWER>;
+ };
+
+ pon_resin: resin {
+ compatible = "qcom,pmk8350-resin";
+ interrupts = <0x0 0x13 0x6 IRQ_TYPE_EDGE_BOTH>;
+ status = "disabled";
+ };
+ };
+
+ pmk8550_rtc: rtc@6100 {
+ compatible = "qcom,pmk8350-rtc";
+ reg = <0x6100>, <0x6200>;
+ reg-names = "rtc", "alarm";
+ interrupts = <0x0 0x62 0x1 IRQ_TYPE_EDGE_RISING>;
+ /* Not yet sure what blocks access */
+ status = "reserved";
+ };
+
+ pmk8550_sdam_2: nvram@7100 {
+ compatible = "qcom,spmi-sdam";
+ reg = <0x7100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x7100 0x100>;
+
+ reboot_reason: reboot-reason@48 {
+ reg = <0x48 0x1>;
+ bits = <1 7>;
+ };
+ };
+
+ pmk8550_gpios: gpio@8800 {
+ compatible = "qcom,pmk8550-gpio", "qcom,spmi-gpio";
+ reg = <0xb800>;
+ gpio-controller;
+ gpio-ranges = <&pmk8550_gpios 0 0 6>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ /* PMC8380C */
+ pm8550: pmic@1 {
+ compatible = "qcom,pm8550", "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8550_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pm8550_gpios: gpio@8800 {
+ compatible = "qcom,pm8550-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pm8550_gpios 0 0 12>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pm8550_flash: led-controller@ee00 {
+ compatible = "qcom,pm8550-flash-led", "qcom,spmi-flash-led";
+ reg = <0xee00>;
+ status = "disabled";
+ };
+
+ pm8550_pwm: pwm {
+ compatible = "qcom,pm8550-pwm", "qcom,pm8350c-pwm";
+ #pwm-cells = <2>;
+
+ status = "disabled";
+ };
+ };
+
+ /* PMC8380VE */
+ pm8550ve_2: pmic@2 {
+ compatible = "qcom,pm8550", "qcom,spmi-pmic";
+ reg = <0x2 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8550ve_2_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pm8550ve_2_gpios: gpio@8800 {
+ compatible = "qcom,pm8550ve-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pm8550ve_2_gpios 0 0 8>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ /* PMC8380 is actually not a PM8550 series rebrand */
+ pmc8380_3: pmic@3 {
+ compatible = "qcom,pmc8380", "qcom,spmi-pmic";
+ reg = <0x3 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmc8380_3_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x3 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pmc8380_3_gpios: gpio@8800 {
+ compatible = "qcom,pmc8380-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pmc8380_3_gpios 0 0 10>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ pmc8380_4: pmic@4 {
+ compatible = "qcom,pmc8380", "qcom,spmi-pmic";
+ reg = <0x4 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmc8380_4_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x4 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pmc8380_4_gpios: gpio@8800 {
+ compatible = "qcom,pmc8380-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pmc8380_4_gpios 0 0 10>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ pmc8380_5: pmic@5 {
+ compatible = "qcom,pmc8380", "qcom,spmi-pmic";
+ reg = <0x5 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmc8380_5_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x5 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pmc8380_5_gpios: gpio@8800 {
+ compatible = "qcom,pmc8380-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pmc8380_5_gpios 0 0 10>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ pmc8380_6: pmic@6 {
+ compatible = "qcom,pmc8380", "qcom,spmi-pmic";
+ reg = <0x6 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmc8380_6_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x6 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pmc8380_6_gpios: gpio@8800 {
+ compatible = "qcom,pmc8380-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pmc8380_6_gpios 0 0 10>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ /* PMC8380VE */
+ pm8550ve_8: pmic@8 {
+ compatible = "qcom,pm8550", "qcom,spmi-pmic";
+ reg = <0x8 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8550ve_8_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x8 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pm8550ve_8_gpios: gpio@8800 {
+ compatible = "qcom,pm8550ve-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pm8550ve_8_gpios 0 0 8>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ /* PMC8380VE */
+ pm8550ve_9: pmic@9 {
+ compatible = "qcom,pm8550", "qcom,spmi-pmic";
+ reg = <0x9 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8550ve_9_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0x9 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pm8550ve_9_gpios: gpio@8800 {
+ compatible = "qcom,pm8550ve-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pm8550ve_9_gpios 0 0 8>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ pm8010: pmic@c {
+ compatible = "qcom,pm8010", "qcom,spmi-pmic";
+ reg = <0xc SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8010_temp_alarm: temp-alarm@2400 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0x2400>;
+ interrupts = <0xc 0x24 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+ };
+};
+
+&spmi_bus1 {
+ smb2360_0: pmic@7 {
+ compatible = "qcom,smb2360", "qcom,spmi-pmic";
+ reg = <0x7 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ smb2360_0_eusb2_repeater: phy@fd00 {
+ compatible = "qcom,smb2360-eusb2-repeater";
+ reg = <0xfd00>;
+ #phy-cells = <0>;
+ };
+ };
+
+ smb2360_1: pmic@a {
+ compatible = "qcom,smb2360", "qcom,spmi-pmic";
+ reg = <0xa SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ smb2360_1_eusb2_repeater: phy@fd00 {
+ compatible = "qcom,smb2360-eusb2-repeater";
+ reg = <0xfd00>;
+ #phy-cells = <0>;
+ };
+ };
+
+ smb2360_2: pmic@b {
+ compatible = "qcom,smb2360", "qcom,spmi-pmic";
+ reg = <0xb SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ smb2360_2_eusb2_repeater: phy@fd00 {
+ compatible = "qcom,smb2360-eusb2-repeater";
+ reg = <0xfd00>;
+ #phy-cells = <0>;
+ };
+ };
+
+ smb2360_3: pmic@c {
+ compatible = "qcom,smb2360", "qcom,spmi-pmic";
+ reg = <0xc SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ smb2360_3_eusb2_repeater: phy@fd00 {
+ compatible = "qcom,smb2360-eusb2-repeater";
+ reg = <0xfd00>;
+ #phy-cells = <0>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
index e76d29053d79..72a4f4138616 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "x1e80100.dtsi"
+#include "x1e80100-pmics.dtsi"
/ {
model = "Qualcomm Technologies, Inc. X1E80100 QCP";
@@ -18,10 +19,200 @@
serial0 = &uart21;
};
+ wcd938x: audio-codec {
+ compatible = "qcom,wcd9385-codec";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wcd_default>;
+
+ qcom,micbias1-microvolt = <1800000>;
+ qcom,micbias2-microvolt = <1800000>;
+ qcom,micbias3-microvolt = <1800000>;
+ qcom,micbias4-microvolt = <1800000>;
+ qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>;
+ qcom,mbhc-headset-vthreshold-microvolt = <1700000>;
+ qcom,mbhc-headphone-vthreshold-microvolt = <50000>;
+ qcom,rx-device = <&wcd_rx>;
+ qcom,tx-device = <&wcd_tx>;
+
+ reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>;
+
+ vdd-buck-supply = <&vreg_l15b_1p8>;
+ vdd-rxtx-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l15b_1p8>;
+ vdd-mic-bias-supply = <&vreg_bob1>;
+
+ #sound-dai-cells = <1>;
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
+ pmic-glink {
+ compatible = "qcom,x1e80100-pmic-glink",
+ "qcom,sm8550-pmic-glink",
+ "qcom,pmic-glink";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>,
+ <&tlmm 123 GPIO_ACTIVE_HIGH>,
+ <&tlmm 125 GPIO_ACTIVE_HIGH>;
+
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss0_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss1_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ connector@2 {
+ compatible = "usb-c-connector";
+ reg = <2>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss2_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss2_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_qmpphy_out>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ size = <0x0 0x8000000>;
+ reusable;
+ linux,cma-default;
+ };
+ };
+
+ sound {
+ compatible = "qcom,x1e80100-sndcard";
+ model = "X1E80100-QCP";
+ audio-routing = "SpkrLeft IN", "WSA WSA_SPK1 OUT",
+ "SpkrRight IN", "WSA WSA_SPK2 OUT",
+ "IN1_HPHL", "HPHL_OUT",
+ "IN2_HPHR", "HPHR_OUT",
+ "AMIC2", "MIC BIAS2",
+ "TX SWR_INPUT1", "ADC2_OUTPUT";
+
+ wcd-playback-dai-link {
+ link-name = "WCD Playback";
+
+ cpu {
+ sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>;
+ };
+
+ codec {
+ sound-dai = <&wcd938x 0>, <&swr1 0>, <&lpass_rxmacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ wcd-capture-dai-link {
+ link-name = "WCD Capture";
+
+ cpu {
+ sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+ };
+
+ codec {
+ sound-dai = <&wcd938x 1>, <&swr2 1>, <&lpass_txmacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ wsa-dai-link {
+ link-name = "WSA Playback";
+
+ cpu {
+ sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>;
+ };
+
+ codec {
+ sound-dai = <&left_spkr>, <&right_spkr>,
+ <&swr0 0>, <&lpass_wsamacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+ };
+
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
@@ -49,6 +240,20 @@
regulator-always-on;
regulator-boot-on;
};
+
+ vreg_nvme: regulator-nvme {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_NVME_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nvme_reg_en>;
+ };
};
&apps_rsc {
@@ -401,6 +606,16 @@
};
};
+&lpass_tlmm {
+ spkr_01_sd_n_active: spkr-01-sd-n-active-state {
+ pins = "gpio12";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+};
+
&mdss {
status = "okay";
};
@@ -409,8 +624,6 @@
compatible = "qcom,x1e80100-dp";
/delete-property/ #sound-dai-cells;
- data-lanes = <0 1 2 3>;
-
status = "okay";
aux-bus {
@@ -430,6 +643,9 @@
port@1 {
reg = <1>;
mdss_dp3_out: endpoint {
+ data-lanes = <0 1 2 3>;
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
remote-endpoint = <&edp_panel_in>;
};
};
@@ -455,11 +671,19 @@
};
&pcie6a {
+ perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
+
+ vddpe-3v3-supply = <&vreg_nvme>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie6a_default>;
+
status = "okay";
};
&pcie6a_phy {
- vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-phy-supply = <&vreg_l1d_0p8>;
vdda-pll-supply = <&vreg_l2j_1p2>;
status = "okay";
@@ -491,6 +715,76 @@
status = "okay";
};
+&smb2360_3 {
+ status = "okay";
+};
+
+&smb2360_0_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&smb2360_2_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l8b_3p0>;
+};
+
+&swr0 {
+ pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ /* WSA8845, Left Speaker */
+ left_spkr: speaker@0,0 {
+ compatible = "sdw20217020400";
+ reg = <0 0>;
+ #sound-dai-cells = <0>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ sound-name-prefix = "SpkrLeft";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ };
+
+ /* WSA8845, Right Speaker */
+ right_spkr: speaker@0,1 {
+ compatible = "sdw20217020400";
+ reg = <0 1>;
+ #sound-dai-cells = <0>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ sound-name-prefix = "SpkrRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ };
+};
+
+&swr1 {
+ status = "okay";
+
+ /* WCD9385 RX */
+ wcd_rx: codec@0,4 {
+ compatible = "sdw20217010d00";
+ reg = <0 4>;
+ qcom,rx-port-mapping = <1 2 3 4 5>;
+ };
+};
+
+&swr2 {
+ status = "okay";
+
+ /* WCD9385 TX */
+ wcd_tx: codec@0,3 {
+ compatible = "sdw20217010d00";
+ reg = <0 3>;
+ qcom,tx-port-mapping = <2 2 3 4>;
+ };
+};
+
&tlmm {
gpio-reserved-ranges = <33 3>, /* Unused */
<44 4>, /* SPI (TPM) */
@@ -502,6 +796,44 @@
drive-strength = <16>;
bias-disable;
};
+
+ nvme_reg_en: nvme-reg-en-state {
+ pins = "gpio18";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ pcie6a_default: pcie2a-default-state {
+ clkreq-n-pins {
+ pins = "gpio153";
+ function = "pcie6a_clk";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio152";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ wake-n-pins {
+ pins = "gpio154";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ wcd_default: wcd-reset-n-active-state {
+ pins = "gpio191";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
};
&uart21 {
@@ -510,13 +842,18 @@
};
&usb_1_ss0_hsphy {
- vdd-supply = <&vreg_l2e_0p8>;
- vdda12-supply = <&vreg_l3e_1p2>;
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_0_eusb2_repeater>;
status = "okay";
};
&usb_1_ss0_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l1j_0p8>;
+
status = "okay";
};
@@ -526,17 +863,29 @@
&usb_1_ss0_dwc3 {
dr_mode = "host";
- usb-role-switch;
+};
+
+&usb_1_ss0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss0_hs_in>;
+};
+
+&usb_1_ss0_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
};
&usb_1_ss1_hsphy {
- vdd-supply = <&vreg_l2e_0p8>;
- vdda12-supply = <&vreg_l3e_1p2>;
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_1_eusb2_repeater>;
status = "okay";
};
&usb_1_ss1_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
status = "okay";
};
@@ -546,17 +895,29 @@
&usb_1_ss1_dwc3 {
dr_mode = "host";
- usb-role-switch;
+};
+
+&usb_1_ss1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss1_hs_in>;
+};
+
+&usb_1_ss1_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
};
&usb_1_ss2_hsphy {
- vdd-supply = <&vreg_l2e_0p8>;
- vdda12-supply = <&vreg_l3e_1p2>;
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_2_eusb2_repeater>;
status = "okay";
};
&usb_1_ss2_qmpphy {
+ vdda-phy-supply = <&vreg_l3e_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
status = "okay";
};
@@ -566,5 +927,12 @@
&usb_1_ss2_dwc3 {
dr_mode = "host";
- usb-role-switch;
+};
+
+&usb_1_ss2_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss2_hs_in>;
+};
+
+&usb_1_ss2_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss2_ss_in>;
};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index 6b40082bac68..7bca5fcd7d52 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,x1e80100-dispcc.h>
#include <dt-bindings/clock/qcom,x1e80100-gcc.h>
+#include <dt-bindings/clock/qcom,x1e80100-gpucc.h>
#include <dt-bindings/clock/qcom,x1e80100-tcsr.h>
#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/interconnect/qcom,icc.h>
@@ -2505,6 +2506,66 @@
};
};
+ tsens0: thermal-sensor@c271000 {
+ compatible = "qcom,x1e80100-tsens", "qcom,tsens-v2";
+ reg = <0 0x0c271000 0 0x1000>,
+ <0 0x0c222000 0 0x1000>;
+
+ interrupts-extended = <&pdc 26 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow",
+ "critical";
+
+ #qcom,sensors = <16>;
+
+ #thermal-sensor-cells = <1>;
+ };
+
+ tsens1: thermal-sensor@c272000 {
+ compatible = "qcom,x1e80100-tsens", "qcom,tsens-v2";
+ reg = <0 0x0c272000 0 0x1000>,
+ <0 0x0c223000 0 0x1000>;
+
+ interrupts-extended = <&pdc 27 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow",
+ "critical";
+
+ #qcom,sensors = <16>;
+
+ #thermal-sensor-cells = <1>;
+ };
+
+ tsens2: thermal-sensor@c273000 {
+ compatible = "qcom,x1e80100-tsens", "qcom,tsens-v2";
+ reg = <0 0x0c273000 0 0x1000>,
+ <0 0x0c224000 0 0x1000>;
+
+ interrupts-extended = <&pdc 28 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow",
+ "critical";
+
+ #qcom,sensors = <16>;
+
+ #thermal-sensor-cells = <1>;
+ };
+
+ tsens3: thermal-sensor@c274000 {
+ compatible = "qcom,x1e80100-tsens", "qcom,tsens-v2";
+ reg = <0 0x0c274000 0 0x1000>,
+ <0 0x0c225000 0 0x1000>;
+
+ interrupts-extended = <&pdc 29 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 770 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow",
+ "critical";
+
+ #qcom,sensors = <16>;
+
+ #thermal-sensor-cells = <1>;
+ };
+
usb_1_ss0_hsphy: phy@fd3000 {
compatible = "qcom,x1e80100-snps-eusb2-phy",
"qcom,sm8550-snps-eusb2-phy";
@@ -2543,6 +2604,34 @@
#phy-cells = <1>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_ss0_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_ss0_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_dwc3_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_1_ss0_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp0_out>;
+ };
+ };
+ };
};
usb_1_ss1_hsphy: phy@fd9000 {
@@ -2583,6 +2672,34 @@
#phy-cells = <1>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_ss1_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_ss1_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_dwc3_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_1_ss1_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp1_out>;
+ };
+ };
+ };
};
usb_1_ss2_hsphy: phy@fde000 {
@@ -2623,6 +2740,34 @@
#phy-cells = <1>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_ss2_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_ss2_qmpphy_usb_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_dwc3_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_1_ss2_qmpphy_dp_in: endpoint {
+ remote-endpoint = <&mdss_dp2_out>;
+ };
+ };
+ };
};
cnoc_main: interconnect@1500000 {
@@ -2737,15 +2882,17 @@
device_type = "pci";
compatible = "qcom,pcie-x1e80100";
reg = <0 0x01bf8000 0 0x3000>,
- <0 0x70000000 0 0xf1d>,
- <0 0x70000f20 0 0xa8>,
+ <0 0x70000000 0 0xf20>,
+ <0 0x70000f40 0 0xa8>,
<0 0x70001000 0 0x1000>,
- <0 0x70100000 0 0x100000>;
+ <0 0x70100000 0 0x100000>,
+ <0 0x01bfb000 0 0x1000>;
reg-names = "parf",
"dbi",
"elbi",
"atu",
- "config";
+ "config",
+ "mhi";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x01000000 0 0x00000000 0 0x70200000 0 0x100000>,
@@ -2985,6 +3132,200 @@
#reset-cells = <1>;
};
+ gpu: gpu@3d00000 {
+ compatible = "qcom,adreno-43050c01", "qcom,adreno";
+ reg = <0x0 0x03d00000 0x0 0x40000>,
+ <0x0 0x03d9e000 0x0 0x1000>,
+ <0x0 0x03d61000 0x0 0x800>;
+
+ reg-names = "kgsl_3d0_reg_memory",
+ "cx_mem",
+ "cx_dbgc";
+
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&adreno_smmu 0 0x0>,
+ <&adreno_smmu 1 0x0>;
+
+ operating-points-v2 = <&gpu_opp_table>;
+
+ qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
+
+ interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
+ interconnect-names = "gfx-mem";
+
+ zap-shader {
+ memory-region = <&gpu_microcode_mem>;
+ firmware-name = "qcom/gen70500_zap.mbn";
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+ opp-peak-kBps = <16500000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+ opp-peak-kBps = <14398438>;
+ };
+
+ opp-925000000 {
+ opp-hz = /bits/ 64 <925000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+ opp-peak-kBps = <14398438>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+ opp-peak-kBps = <12449219>;
+ };
+
+ opp-744000000 {
+ opp-hz = /bits/ 64 <744000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+ opp-peak-kBps = <10687500>;
+ };
+
+ opp-687000000 {
+ opp-hz = /bits/ 64 <687000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+ opp-peak-kBps = <8171875>;
+ };
+
+ opp-550000000 {
+ opp-hz = /bits/ 64 <550000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ opp-peak-kBps = <6074219>;
+ };
+
+ opp-390000000 {
+ opp-hz = /bits/ 64 <390000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ opp-peak-kBps = <3000000>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+ opp-peak-kBps = <2136719>;
+ };
+ };
+ };
+
+ gmu: gmu@3d6a000 {
+ compatible = "qcom,adreno-gmu-x185.1", "qcom,adreno-gmu";
+ reg = <0x0 0x03d6a000 0x0 0x35000>,
+ <0x0 0x03d50000 0x0 0x10000>,
+ <0x0 0x0b280000 0x0 0x10000>;
+ reg-names = "gmu", "rscc", "gmu_pdc";
+
+ interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hfi", "gmu";
+
+ 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>,
+ <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+ <&gpucc GPU_CC_DEMET_CLK>;
+ clock-names = "ahb",
+ "gmu",
+ "cxo",
+ "axi",
+ "memnoc",
+ "hub",
+ "demet";
+
+ power-domains = <&gpucc GPU_CX_GDSC>,
+ <&gpucc GPU_GX_GDSC>;
+ power-domain-names = "cx",
+ "gx";
+
+ iommus = <&adreno_smmu 5 0x0>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ operating-points-v2 = <&gmu_opp_table>;
+
+ gmu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-550000000 {
+ opp-hz = /bits/ 64 <550000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ };
+
+ opp-220000000 {
+ opp-hz = /bits/ 64 <220000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ };
+ };
+ };
+
+ gpucc: clock-controller@3d90000 {
+ compatible = "qcom,x1e80100-gpucc";
+ reg = <0 0x03d90000 0 0xa000>;
+ clocks = <&bi_tcxo_div2>,
+ <&gcc GCC_GPU_GPLL0_CPH_CLK_SRC>,
+ <&gcc GCC_GPU_GPLL0_DIV_CPH_CLK_SRC>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ adreno_smmu: iommu@3da0000 {
+ compatible = "qcom,x1e80100-smmu-500", "qcom,adreno-smmu",
+ "qcom,smmu-500", "arm,mmu-500";
+ reg = <0x0 0x03da0000 0x0 0x40000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <1>;
+ interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 688 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 660 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 662 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 667 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 670 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 700 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+ <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+ <&gpucc GPU_CC_AHB_CLK>;
+ clock-names = "hlos",
+ "bus",
+ "iface",
+ "ahb";
+ power-domains = <&gpucc GPU_CX_GDSC>;
+ dma-coherent;
+ };
+
gem_noc: interconnect@26400000 {
compatible = "qcom,x1e80100-gem-noc";
reg = <0 0x26400000 0 0x311200>;
@@ -3088,7 +3429,7 @@
qcom,ports-hstart = /bits/ 8 <0xff 0x03 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
qcom,ports-hstop = /bits/ 8 <0xff 0x06 0x0f 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
qcom,ports-word-length = /bits/ 8 <0x01 0x07 0x04 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
- qcom,ports-block-pack-mode = /bits/ 8 <0xff 0x00 0x01 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0x01 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
qcom,ports-lane-control = /bits/ 8 <0x01 0x00 0x00 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
@@ -3445,8 +3786,23 @@
dma-coherent;
- port {
- usb_1_ss2_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_ss2_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_ss2_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_ss2_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -3514,8 +3870,15 @@
phy-names = "usb2-phy";
maximum-speed = "high-speed";
- port {
- usb_2_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_2_dwc3_hs: endpoint {
+ };
};
};
};
@@ -3590,8 +3953,23 @@
dma-coherent;
- port {
- usb_1_ss0_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_ss0_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_ss0_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -3673,8 +4051,23 @@
dma-coherent;
- port {
- usb_1_ss1_role_switch: endpoint {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_1_ss1_dwc3_hs: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_1_ss1_dwc3_ss: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_usb_ss_in>;
+ };
};
};
};
@@ -3860,6 +4253,7 @@
reg = <1>;
mdss_dp0_out: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_dp_in>;
};
};
};
@@ -3942,6 +4336,7 @@
reg = <1>;
mdss_dp1_out: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_dp_in>;
};
};
};
@@ -4021,6 +4416,10 @@
port@1 {
reg = <1>;
+
+ mdss_dp2_out: endpoint {
+ remote-endpoint = <&usb_1_ss2_qmpphy_dp_in>;
+ };
};
};
@@ -4095,8 +4494,6 @@
mdss_dp3_in: endpoint {
remote-endpoint = <&mdss_intf5_out>;
-
- link-frequencies = /bits/ 64 <8100000000>;
};
};
@@ -4221,6 +4618,48 @@
#clock-cells = <0>;
};
+ spmi: arbiter@c400000 {
+ compatible = "qcom,x1e80100-spmi-pmic-arb";
+ reg = <0 0x0c400000 0 0x3000>,
+ <0 0x0c500000 0 0x400000>,
+ <0 0x0c440000 0 0x80000>;
+ reg-names = "core", "chnls", "obsrvr";
+
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ spmi_bus0: spmi@c42d000 {
+ reg = <0 0x0c42d000 0 0x4000>,
+ <0 0x0c4c0000 0 0x10000>;
+ reg-names = "cnfg", "intr";
+
+ interrupt-names = "periph_irq";
+ interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+ };
+
+ spmi_bus1: spmi@c432000 {
+ reg = <0 0x0c432000 0 0x4000>,
+ <0 0x0c4d0000 0 0x10000>;
+ reg-names = "cnfg", "intr";
+
+ interrupt-names = "periph_irq";
+ interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+ };
+ };
tlmm: pinctrl@f100000 {
compatible = "qcom,x1e80100-tlmm";
@@ -5115,6 +5554,129 @@
};
};
+ pmu@24091000 {
+ compatible = "qcom,x1e80100-llcc-bwmon", "qcom,sc7280-llcc-bwmon";
+ reg = <0 0x24091000 0 0x1000>;
+
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+
+ interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+ operating-points-v2 = <&llcc_bwmon_opp_table>;
+
+ llcc_bwmon_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-0 {
+ opp-peak-kBps = <800000>;
+ };
+
+ opp-1 {
+ opp-peak-kBps = <2188000>;
+ };
+
+ opp-2 {
+ opp-peak-kBps = <3072000>;
+ };
+
+ opp-3 {
+ opp-peak-kBps = <6220800>;
+ };
+
+ opp-4 {
+ opp-peak-kBps = <6835200>;
+ };
+
+ opp-5 {
+ opp-peak-kBps = <8371200>;
+ };
+
+ opp-6 {
+ opp-peak-kBps = <10944000>;
+ };
+
+ opp-7 {
+ opp-peak-kBps = <12748800>;
+ };
+
+ opp-8 {
+ opp-peak-kBps = <14745600>;
+ };
+
+ opp-9 {
+ opp-peak-kBps = <16896000>;
+ };
+ };
+ };
+
+ /* cluster0 */
+ pmu@240b3400 {
+ compatible = "qcom,x1e80100-cpu-bwmon", "qcom,sdm845-bwmon";
+ reg = <0 0x240b3400 0 0x600>;
+
+ interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+ operating-points-v2 = <&cpu_bwmon_opp_table>;
+
+ cpu_bwmon_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-0 {
+ opp-peak-kBps = <4800000>;
+ };
+
+ opp-1 {
+ opp-peak-kBps = <7464000>;
+ };
+
+ opp-2 {
+ opp-peak-kBps = <9600000>;
+ };
+
+ opp-3 {
+ opp-peak-kBps = <12896000>;
+ };
+
+ opp-4 {
+ opp-peak-kBps = <14928000>;
+ };
+
+ opp-5 {
+ opp-peak-kBps = <17064000>;
+ };
+ };
+ };
+
+ /* cluster2 */
+ pmu@240b5400 {
+ compatible = "qcom,x1e80100-cpu-bwmon", "qcom,sdm845-bwmon";
+ reg = <0 0x240b5400 0 0x600>;
+
+ interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+ operating-points-v2 = <&cpu_bwmon_opp_table>;
+ };
+
+ /* cluster1 */
+ pmu@240b6400 {
+ compatible = "qcom,x1e80100-cpu-bwmon", "qcom,sdm845-bwmon";
+ reg = <0 0x240b6400 0 0x600>;
+
+ interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+ operating-points-v2 = <&cpu_bwmon_opp_table>;
+ };
+
system-cache-controller@25000000 {
compatible = "qcom,x1e80100-llcc";
reg = <0 0x25000000 0 0x200000>,
@@ -5184,6 +5746,55 @@
label = "lpass";
qcom,remote-pid = <2>;
+ fastrpc {
+ compatible = "qcom,fastrpc";
+ qcom,glink-channels = "fastrpcglink-apps-dsp";
+ label = "adsp";
+ qcom,non-secure-domain;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compute-cb@3 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <3>;
+ iommus = <&apps_smmu 0x1003 0x80>,
+ <&apps_smmu 0x1063 0x0>;
+ dma-coherent;
+ };
+
+ compute-cb@4 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <4>;
+ iommus = <&apps_smmu 0x1004 0x80>,
+ <&apps_smmu 0x1064 0x0>;
+ dma-coherent;
+ };
+
+ compute-cb@5 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <5>;
+ iommus = <&apps_smmu 0x1005 0x80>,
+ <&apps_smmu 0x1065 0x0>;
+ dma-coherent;
+ };
+
+ compute-cb@6 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <6>;
+ iommus = <&apps_smmu 0x1006 0x80>,
+ <&apps_smmu 0x1066 0x0>;
+ dma-coherent;
+ };
+
+ compute-cb@7 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <7>;
+ iommus = <&apps_smmu 0x1007 0x80>,
+ <&apps_smmu 0x1067 0x0>;
+ dma-coherent;
+ };
+ };
+
gpr {
compatible = "qcom,gpr";
qcom,glink-channels = "adsp_apps";
@@ -5273,6 +5884,101 @@
label = "cdsp";
qcom,remote-pid = <5>;
+
+ fastrpc {
+ compatible = "qcom,fastrpc";
+ qcom,glink-channels = "fastrpcglink-apps-dsp";
+ label = "cdsp";
+ qcom,non-secure-domain;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compute-cb@1 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <1>;
+ iommus = <&apps_smmu 0x0c01 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@2 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <2>;
+ iommus = <&apps_smmu 0x0c02 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@3 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <3>;
+ iommus = <&apps_smmu 0x0c03 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@4 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <4>;
+ iommus = <&apps_smmu 0x0c04 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@5 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <5>;
+ iommus = <&apps_smmu 0x0c05 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@6 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <6>;
+ iommus = <&apps_smmu 0x0c06 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@7 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <7>;
+ iommus = <&apps_smmu 0x0c07 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@8 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <8>;
+ iommus = <&apps_smmu 0x0c08 0x20>;
+ dma-coherent;
+ };
+
+ /* note: compute-cb@9 is secure */
+
+ compute-cb@10 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <10>;
+ iommus = <&apps_smmu 0x0c0c 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@11 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <11>;
+ iommus = <&apps_smmu 0x0c0d 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@12 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <12>;
+ iommus = <&apps_smmu 0x0c0e 0x20>;
+ dma-coherent;
+ };
+
+ compute-cb@13 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <13>;
+ iommus = <&apps_smmu 0x0c0f 0x20>;
+ dma-coherent;
+ };
+ };
};
};
};
@@ -5285,4 +5991,1158 @@
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
+
+ thermal-zones {
+ aoss0-thermal {
+ thermal-sensors = <&tsens0 0>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ aoss0-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-0-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 1>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-0-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 2>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-1-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 3>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-1-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 4>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-2-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 5>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-2-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 6>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-3-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 7>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-3-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 8>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss0-top-thermal {
+ thermal-sensors = <&tsens0 9>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpuss2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss0-btm-thermal {
+ thermal-sensors = <&tsens0 10>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpuss2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ mem-thermal {
+ thermal-sensors = <&tsens0 11>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ mem-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ video-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens0 12>;
+
+ trips {
+ trip-point0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ aoss1-thermal {
+ thermal-sensors = <&tsens1 0>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ aoss0-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-0-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 1>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-0-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 2>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-1-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 3>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-1-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 4>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-2-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 5>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-2-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 6>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-3-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 7>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu1-3-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens1 8>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss1-top-thermal {
+ thermal-sensors = <&tsens1 9>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpuss2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss1-btm-thermal {
+ thermal-sensors = <&tsens1 10>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpuss2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ aoss2-thermal {
+ thermal-sensors = <&tsens2 0>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ aoss0-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-0-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 1>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-0-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 2>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-1-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 3>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-1-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 4>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-2-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 5>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-2-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 6>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-3-top-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 7>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu2-3-btm-thermal {
+ polling-delay-passive = <250>;
+
+ thermal-sensors = <&tsens2 8>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss2-top-thermal {
+ thermal-sensors = <&tsens2 9>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpuss2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss2-btm-thermal {
+ thermal-sensors = <&tsens2 10>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpuss2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ aoss3-thermal {
+ thermal-sensors = <&tsens3 0>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ aoss0-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ nsp0-thermal {
+ thermal-sensors = <&tsens3 1>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ nsp0-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ nsp1-thermal {
+ thermal-sensors = <&tsens3 2>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ nsp1-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ nsp2-thermal {
+ thermal-sensors = <&tsens3 3>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ nsp2-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ nsp3-thermal {
+ thermal-sensors = <&tsens3 4>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ nsp3-critical {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-0-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 5>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-1-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 6>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-2-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 7>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-3-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 8>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-4-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 9>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-5-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 10>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-6-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 11>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss-7-thermal {
+ polling-delay-passive = <10>;
+
+ thermal-sensors = <&tsens3 12>;
+
+ trips {
+ trip-point0 {
+ temperature = <85000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+
+ trip-point1 {
+ temperature = <90000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ trip-point2 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ camera0-thermal {
+ thermal-sensors = <&tsens3 13>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ camera0-critical {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ camera1-thermal {
+ thermal-sensors = <&tsens3 14>;
+
+ trips {
+ trip-point0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ camera0-critical {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/realtek/rtd129x.dtsi b/arch/arm64/boot/dts/realtek/rtd129x.dtsi
index 39aefe66a794..ba50e292bdbb 100644
--- a/arch/arm64/boot/dts/realtek/rtd129x.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd129x.dtsi
@@ -48,7 +48,7 @@
clock-output-names = "osc27M";
};
- soc {
+ soc@0 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/realtek/rtd139x.dtsi b/arch/arm64/boot/dts/realtek/rtd139x.dtsi
index a3c10ceeb586..e8af39193e75 100644
--- a/arch/arm64/boot/dts/realtek/rtd139x.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd139x.dtsi
@@ -47,7 +47,7 @@
clock-output-names = "osc27M";
};
- soc {
+ soc@0 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/realtek/rtd16xx.dtsi b/arch/arm64/boot/dts/realtek/rtd16xx.dtsi
index 34802cc62983..3a7f6e35b7f7 100644
--- a/arch/arm64/boot/dts/realtek/rtd16xx.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd16xx.dtsi
@@ -109,7 +109,7 @@
};
arm_pmu: pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>,
<&cpu3>, <&cpu4>, <&cpu5>;
@@ -127,7 +127,7 @@
#clock-cells = <0>;
};
- soc {
+ soc@0 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 5f3e0e61d78d..fbd214a1a638 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -62,6 +62,9 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb
+dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function-expansion.dtbo
+r8a77970-eagle-function-expansion-dtbs := r8a77970-eagle.dtb r8a77970-eagle-function-expansion.dtbo
+dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function-expansion.dtb
dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk.dtb
dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb
diff --git a/arch/arm64/boot/dts/renesas/condor-common.dtsi b/arch/arm64/boot/dts/renesas/condor-common.dtsi
index 7c34d14dcd7e..8b7c0c34eadc 100644
--- a/arch/arm64/boot/dts/renesas/condor-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/condor-common.dtsi
@@ -227,6 +227,12 @@
};
};
};
+
+ eeprom@50 {
+ compatible = "rohm,br24t01", "atmel,24c01";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
};
&i2c1 {
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
index a8a44fe5e83b..1dbf9d56c68d 100644
--- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
@@ -2853,6 +2853,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
index 4fff511e994c..10f22c52e79e 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
@@ -2704,6 +2704,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index 1ef43d78c3a5..3e2af50ce7c6 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -1990,6 +1990,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
index be55ae83944c..1eeb4c7b4c4b 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
@@ -2985,6 +2985,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
index bea4edd17d53..96f3b5fe7e92 100644
--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -3473,6 +3473,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
index 7846fea8e40d..1122c470b72f 100644
--- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
@@ -3068,6 +3068,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
index 58f9286a5ab5..bf1130af7de3 100644
--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -2889,6 +2889,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
index 692940662d38..f02d1547b881 100644
--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -2877,6 +2877,7 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
/* External USB clocks - can be overridden by the board */
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso
new file mode 100644
index 000000000000..3aa243c5f04c
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Eagle V3M Function expansion board.
+ *
+ * Copyright (C) 2024 Niklas Söderlund <niklas.soderlund@ragnatech.se>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ /* CN4 */
+ /* Eagle: SW18 set to OFF */
+ cvbs-in-cn4 {
+ compatible = "composite-video-connector";
+ label = "CVBS IN CN4";
+
+ port {
+ cvbs_con: endpoint {
+ remote-endpoint = <&adv7482_ain7>;
+ };
+ };
+ };
+
+ /* CN2 */
+ /* Eagle: SW35 set 5, 6 and 8 to OFF */
+ hdmi-in-cn2 {
+ compatible = "hdmi-connector";
+ label = "HDMI IN CN2";
+ type = "a";
+
+ port {
+ hdmi_in_con2: endpoint {
+ remote-endpoint = <&adv7612_in>;
+ };
+ };
+ };
+
+ /* CN3 */
+ /* Eagle: SW18 set to OFF */
+ hdmi-in-cn3 {
+ compatible = "hdmi-connector";
+ label = "HDMI IN CN3";
+ type = "a";
+
+ port {
+ hdmi_in_con: endpoint {
+ remote-endpoint = <&adv7482_hdmi>;
+ };
+ };
+ };
+};
+
+/* Disconnect MAX9286 GMSL I2C. */
+&i2c3 {
+ status = "disabled";
+};
+
+/* Connect expansion board I2C. */
+&i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@27 {
+ compatible = "onnn,pca9654";
+ reg = <0x27>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ vin0_adv7612_en {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "VIN0_ADV7612_ENn";
+ };
+ };
+
+ hdmi-decoder@4c {
+ compatible = "adi,adv7612";
+ reg = <0x4c>, <0x50>, <0x52>, <0x54>, <0x56>, <0x58>;
+ reg-names = "main", "afe", "rep", "edid", "hdmi", "cp";
+ interrupt-parent = <&gpio3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ default-input = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ adv7612_in: endpoint {
+ remote-endpoint = <&hdmi_in_con2>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ adv7612_out: endpoint {
+ remote-endpoint = <&vin0_in>;
+ };
+ };
+ };
+ };
+
+ video-receiver@70 {
+ compatible = "adi,adv7482";
+ reg = <0x70 0x71 0x72 0x73 0x74 0x75
+ 0x60 0x61 0x62 0x63 0x64 0x65>;
+ reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
+ "infoframe", "cbus", "cec", "sdp", "txa", "txb" ;
+ interrupt-parent = <&gpio3>;
+ interrupts = <03 IRQ_TYPE_LEVEL_LOW>, <04 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "intrq1", "intrq2";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@7 {
+ reg = <7>;
+
+ adv7482_ain7: endpoint {
+ remote-endpoint = <&cvbs_con>;
+ };
+ };
+
+ port@8 {
+ reg = <8>;
+
+ adv7482_hdmi: endpoint {
+ remote-endpoint = <&hdmi_in_con>;
+ };
+ };
+
+ port@a {
+ reg = <10>;
+
+ adv7482_txa: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+ };
+ };
+
+};
+
+&csi40 {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ csi40_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&adv7482_txa>;
+ };
+ };
+ };
+};
+
+&pfc {
+ vin0_pins_parallel: vin0 {
+ groups = "vin0_data12", "vin0_sync", "vin0_clk", "vin0_clkenb";
+ function = "vin0";
+ };
+};
+
+&vin0 {
+ status = "okay";
+
+ pinctrl-0 = <&vin0_pins_parallel>;
+ pinctrl-names = "default";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ vin0_in: endpoint {
+ pclk-sample = <0>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ remote-endpoint = <&adv7612_out>;
+ };
+ };
+ };
+};
+
+&vin1 {
+ status = "okay";
+};
+
+&vin2 {
+ status = "okay";
+};
+
+&vin3 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
index d2d3cecc76d5..64fb95b1c89a 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
@@ -1223,5 +1223,6 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
index 68d1f1d53b3a..1d326552e2fa 100644
--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
@@ -14,11 +14,3 @@
model = "Renesas Condor board based on r8a77980";
compatible = "renesas,condor", "renesas,r8a77980";
};
-
-&i2c0 {
- eeprom@50 {
- compatible = "rohm,br24t01", "atmel,24c01";
- reg = <0x50>;
- pagesize = <8>;
- };
-};
diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
index c0ba110c74d6..0c2b157036e7 100644
--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
@@ -1630,5 +1630,6 @@
IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index 37063e3f4e1b..233af3081e84 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -2157,5 +2157,6 @@
<&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
<&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 89990dd8ebf7..5f0828a4675b 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -1476,5 +1476,6 @@
<&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)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
index cfa70b441e32..d76347001cc1 100644
--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -2919,6 +2919,9 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
index 477f3114d2fd..4ed8d4c37906 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
@@ -15,6 +15,12 @@
compatible = "renesas,spider-cpu", "renesas,r8a779f0";
aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
serial0 = &hscif0;
serial1 = &scif0;
};
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
index 72cf30341fc4..9629adb47d99 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -1324,7 +1324,10 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
ufs30_clk: ufs30-clk {
diff --git a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
index abfda5c6ca16..fa910b85859e 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
@@ -14,9 +14,15 @@
compatible = "renesas,s4sk", "renesas,r8a779f4", "renesas,r8a779f0";
aliases {
- serial0 = &hscif0;
- serial1 = &hscif1;
- eth0 = &rswitch;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ serial0 = &hscif0;
+ serial1 = &hscif1;
+ ethernet0 = &rswitch;
};
chosen {
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
index e6f53377ecd9..e6cf304c77ee 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
@@ -155,11 +155,7 @@
pinctrl-0 = <&sound_clk_pins>, <&sound_pins>;
pinctrl-names = "default";
- /* Single DAI */
- #sound-dai-cells = <0>;
-
/* audio_clkout */
- #clock-cells = <0>;
clock-frequency = <5644800>; /* 44.1kHz groups [(C) clock] */
// clock-frequency = <6144000>; /* 48 kHz groups [(C) clock] */
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
index 9bc542bc6169..53d1d4d8197a 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -815,8 +815,6 @@
phy-mode = "rgmii";
rx-internal-delay-ps = <0>;
tx-internal-delay-ps = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
status = "disabled";
};
@@ -862,8 +860,6 @@
phy-mode = "rgmii";
rx-internal-delay-ps = <0>;
tx-internal-delay-ps = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
status = "disabled";
};
@@ -909,8 +905,6 @@
phy-mode = "rgmii";
rx-internal-delay-ps = <0>;
tx-internal-delay-ps = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
status = "disabled";
};
@@ -1724,18 +1718,6 @@
};
rcar_sound: sound@ec5a0000 {
- /*
- * #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
- *
- * clkout : #clock-cells = <0>; <&rcar_sound>;
- * audio_clkout0/1/2/3 : #clock-cells = <1>; <&rcar_sound N>;
- */
compatible = "renesas,rcar_sound-r8a779g0", "renesas,rcar_sound-gen4";
reg = <0 0xec5a0000 0 0x020>,
<0 0xec540000 0 0x1000>,
@@ -1745,6 +1727,11 @@
clocks = <&cpg CPG_MOD 2926>, <&cpg CPG_MOD 2927>, <&audio_clkin>;
clock-names = "ssiu.0", "ssi.0", "clkin";
+ /* #clock-cells is fixed */
+ #clock-cells = <0>;
+ /* #sound-dai-cells is fixed */
+ #sound-dai-cells = <0>;
+
power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
resets = <&cpg 2926>, <&cpg 2927>;
reset-names = "ssiu.0", "ssi.0";
@@ -2359,6 +2346,9 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
index bc8616a56c03..2b9a19bb1c5d 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -17,12 +17,17 @@
compatible = "renesas,gray-hawk-single", "renesas,r8a779h0";
aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
serial0 = &hscif0;
+ serial1 = &hscif2;
ethernet0 = &avb0;
};
chosen {
- bootargs = "ignore_loglevel";
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
stdout-path = "serial0:921600n8";
};
@@ -90,6 +95,14 @@
status = "okay";
};
+&hscif2 {
+ pinctrl-0 = <&hscif2_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ status = "okay";
+};
+
&i2c0 {
pinctrl-0 = <&i2c0_pins>;
pinctrl-names = "default";
@@ -144,7 +157,7 @@
};
&pfc {
- pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-0 = <&scif_clk_pins>, <&scif_clk2_pins>;
pinctrl-names = "default";
avb0_pins: avb0 {
@@ -170,6 +183,11 @@
function = "hscif0";
};
+ hscif2_pins: hscif2 {
+ groups = "hscif2_data", "hscif2_ctrl";
+ function = "hscif2";
+ };
+
i2c0_pins: i2c0 {
groups = "i2c0";
function = "i2c0";
@@ -190,6 +208,11 @@
groups = "scif_clk";
function = "scif_clk";
};
+
+ scif_clk2_pins: scif-clk2 {
+ groups = "scif_clk2";
+ function = "scif_clk2";
+ };
};
&rpc {
@@ -228,3 +251,7 @@
&scif_clk {
clock-frequency = <24000000>;
};
+
+&scif_clk2 {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 11885729181b..a03ab2b6a859 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -14,9 +14,15 @@
#address-cells = <2>;
#size-cells = <2>;
+ /* External Audio clock - to be overridden by boards that provide it */
+ audio_clkin: audio_clkin {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
cluster0_opp: opp-table-0 {
compatible = "operating-points-v2";
- opp-shared;
opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
@@ -144,13 +150,19 @@
method = "smc";
};
- /* External SCIF clock - to be overridden by boards that provide it */
+ /* External SCIF clocks - to be overridden by boards that provide them */
scif_clk: scif-clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <0>;
};
+ scif_clk2: scif-clk2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
soc: soc {
compatible = "simple-bus";
interrupt-parent = <&gic>;
@@ -297,6 +309,76 @@
resets = <&cpg 917>;
};
+ cmt0: timer@e60f0000 {
+ compatible = "renesas,r8a779h0-cmt0",
+ "renesas,rcar-gen4-cmt0";
+ reg = <0 0xe60f0000 0 0x1004>;
+ interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 910>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 910>;
+ status = "disabled";
+ };
+
+ cmt1: timer@e6130000 {
+ compatible = "renesas,r8a779h0-cmt1",
+ "renesas,rcar-gen4-cmt1";
+ reg = <0 0xe6130000 0 0x1004>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 911>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 911>;
+ status = "disabled";
+ };
+
+ cmt2: timer@e6140000 {
+ compatible = "renesas,r8a779h0-cmt1",
+ "renesas,rcar-gen4-cmt1";
+ reg = <0 0xe6140000 0 0x1004>;
+ interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 912>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 912>;
+ status = "disabled";
+ };
+
+ cmt3: timer@e6148000 {
+ compatible = "renesas,r8a779h0-cmt1",
+ "renesas,rcar-gen4-cmt1";
+ reg = <0 0xe6148000 0 0x1004>;
+ interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 913>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 913>;
+ status = "disabled";
+ };
+
cpg: clock-controller@e6150000 {
compatible = "renesas,r8a779h0-cpg-mssr";
reg = <0 0xe6150000 0 0x4000>;
@@ -318,6 +400,106 @@
#power-domain-cells = <1>;
};
+ tsc: thermal@e6198000 {
+ compatible = "renesas,r8a779h0-thermal";
+ reg = <0 0xe6198000 0 0x200>,
+ <0 0xe61a0000 0 0x200>;
+ clocks = <&cpg CPG_MOD 919>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 919>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ intc_ex: interrupt-controller@e61c0000 {
+ compatible = "renesas,intc-ex-r8a779h0", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 611>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 611>;
+ };
+
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 291 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
+ clocks = <&cpg CPG_MOD 713>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 713>;
+ status = "disabled";
+ };
+
+ tmu1: timer@e6fc0000 {
+ compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+ reg = <0 0xe6fc0000 0 0x30>;
+ interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 714>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 714>;
+ status = "disabled";
+ };
+
+ tmu2: timer@e6fd0000 {
+ compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+ reg = <0 0xe6fd0000 0 0x30>;
+ interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 715>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 715>;
+ status = "disabled";
+ };
+
+ tmu3: timer@e6fe0000 {
+ compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+ reg = <0 0xe6fe0000 0 0x30>;
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 716>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+ };
+
+ tmu4: timer@ffc00000 {
+ compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+ reg = <0 0xffc00000 0 0x30>;
+ interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+ clocks = <&cpg CPG_MOD 717>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 717>;
+ status = "disabled";
+ };
+
i2c0: i2c@e6500000 {
compatible = "renesas,i2c-r8a779h0",
"renesas,rcar-gen4-i2c";
@@ -403,6 +585,57 @@
status = "disabled";
};
+ hscif1: serial@e6550000 {
+ compatible = "renesas,hscif-r8a779h0",
+ "renesas,rcar-gen4-hscif", "renesas,hscif";
+ reg = <0 0xe6550000 0 0x60>;
+ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 515>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 515>;
+ dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+ <&dmac2 0x33>, <&dmac2 0x32>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ hscif2: serial@e6560000 {
+ compatible = "renesas,hscif-r8a779h0",
+ "renesas,rcar-gen4-hscif", "renesas,hscif";
+ reg = <0 0xe6560000 0 0x60>;
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 516>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk2>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 516>;
+ dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+ <&dmac2 0x35>, <&dmac2 0x34>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ hscif3: serial@e66a0000 {
+ compatible = "renesas,hscif-r8a779h0",
+ "renesas,rcar-gen4-hscif", "renesas,hscif";
+ reg = <0 0xe66a0000 0 0x60>;
+ interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 517>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 517>;
+ dmas = <&dmac1 0x37>, <&dmac1 0x36>,
+ <&dmac2 0x37>, <&dmac2 0x36>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
avb0: ethernet@e6800000 {
compatible = "renesas,etheravb-r8a779h0",
"renesas,etheravb-rcar-gen4";
@@ -446,6 +679,7 @@
phy-mode = "rgmii";
rx-internal-delay-ps = <0>;
tx-internal-delay-ps = <0>;
+ iommus = <&ipmmu_hc 0>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -547,6 +781,618 @@
status = "disabled";
};
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a779h0",
+ "renesas,rcar-gen4-scif", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 702>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 702>;
+ dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+ <&dmac2 0x51>, <&dmac2 0x50>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a779h0",
+ "renesas,rcar-gen4-scif", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 703>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 703>;
+ dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+ <&dmac2 0x53>, <&dmac2 0x52>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ scif3: serial@e6c50000 {
+ compatible = "renesas,scif-r8a779h0",
+ "renesas,rcar-gen4-scif", "renesas,scif";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 704>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 704>;
+ dmas = <&dmac1 0x57>, <&dmac1 0x56>,
+ <&dmac2 0x57>, <&dmac2 0x56>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ scif4: serial@e6c40000 {
+ compatible = "renesas,scif-r8a779h0",
+ "renesas,rcar-gen4-scif", "renesas,scif";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 705>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk2>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 705>;
+ dmas = <&dmac1 0x59>, <&dmac1 0x58>,
+ <&dmac2 0x59>, <&dmac2 0x58>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a779h0",
+ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6e90000 0 0x0064>;
+ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 618>;
+ dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+ <&dmac2 0x41>, <&dmac2 0x40>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 618>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof1: spi@e6ea0000 {
+ compatible = "renesas,msiof-r8a779h0",
+ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6ea0000 0 0x0064>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 619>;
+ dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+ <&dmac2 0x43>, <&dmac2 0x42>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 619>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof2: spi@e6c00000 {
+ compatible = "renesas,msiof-r8a779h0",
+ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c00000 0 0x0064>;
+ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 620>;
+ dmas = <&dmac1 0x45>, <&dmac1 0x44>,
+ <&dmac2 0x45>, <&dmac2 0x44>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 620>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof3: spi@e6c10000 {
+ compatible = "renesas,msiof-r8a779h0",
+ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c10000 0 0x0064>;
+ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 621>;
+ dmas = <&dmac1 0x47>, <&dmac1 0x46>,
+ <&dmac2 0x47>, <&dmac2 0x46>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 621>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof4: spi@e6c20000 {
+ compatible = "renesas,msiof-r8a779h0",
+ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c20000 0 0x0064>;
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 622>;
+ dmas = <&dmac1 0x49>, <&dmac1 0x48>,
+ <&dmac2 0x49>, <&dmac2 0x48>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 622>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof5: spi@e6c28000 {
+ compatible = "renesas,msiof-r8a779h0",
+ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c28000 0 0x0064>;
+ interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 623>;
+ dmas = <&dmac1 0x4b>, <&dmac1 0x4a>,
+ <&dmac2 0x4b>, <&dmac2 0x4a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 623>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ vin00: video@e6ef0000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef0000 0 0x1000>;
+ interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 730>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 730>;
+ renesas,id = <0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin00isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin00>;
+ };
+ };
+ };
+ };
+
+ vin01: video@e6ef1000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef1000 0 0x1000>;
+ interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 731>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 731>;
+ renesas,id = <1>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin01isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin01>;
+ };
+ };
+ };
+ };
+
+ vin02: video@e6ef2000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef2000 0 0x1000>;
+ interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 800>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 800>;
+ renesas,id = <2>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin02isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin02>;
+ };
+ };
+ };
+ };
+
+ vin03: video@e6ef3000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef3000 0 0x1000>;
+ interrupts = <GIC_SPI 532 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 801>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 801>;
+ renesas,id = <3>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin03isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin03>;
+ };
+ };
+ };
+ };
+
+ vin04: video@e6ef4000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef4000 0 0x1000>;
+ interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 802>;
+ renesas,id = <4>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin04isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin04>;
+ };
+ };
+ };
+ };
+
+ vin05: video@e6ef5000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef5000 0 0x1000>;
+ interrupts = <GIC_SPI 534 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 803>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 803>;
+ renesas,id = <5>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin05isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin05>;
+ };
+ };
+ };
+ };
+
+ vin06: video@e6ef6000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef6000 0 0x1000>;
+ interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 804>;
+ renesas,id = <6>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin06isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin06>;
+ };
+ };
+ };
+ };
+
+ vin07: video@e6ef7000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef7000 0 0x1000>;
+ interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 805>;
+ renesas,id = <7>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin07isp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&isp0vin07>;
+ };
+ };
+ };
+ };
+
+ vin08: video@e6ef8000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef8000 0 0x1000>;
+ interrupts = <GIC_SPI 537 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 806>;
+ renesas,id = <8>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin08isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin08>;
+ };
+ };
+ };
+ };
+
+ vin09: video@e6ef9000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6ef9000 0 0x1000>;
+ interrupts = <GIC_SPI 538 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 807>;
+ renesas,id = <9>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin09isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin09>;
+ };
+ };
+ };
+ };
+
+ vin10: video@e6efa000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6efa000 0 0x1000>;
+ interrupts = <GIC_SPI 539 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 808>;
+ renesas,id = <10>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin10isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin10>;
+ };
+ };
+ };
+ };
+
+ vin11: video@e6efb000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6efb000 0 0x1000>;
+ interrupts = <GIC_SPI 540 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 809>;
+ renesas,id = <11>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin11isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin11>;
+ };
+ };
+ };
+ };
+
+ vin12: video@e6efc000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6efc000 0 0x1000>;
+ interrupts = <GIC_SPI 541 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 810>;
+ renesas,id = <12>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin12isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin12>;
+ };
+ };
+ };
+ };
+
+ vin13: video@e6efd000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6efd000 0 0x1000>;
+ interrupts = <GIC_SPI 542 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 811>;
+ renesas,id = <13>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin13isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin13>;
+ };
+ };
+ };
+ };
+
+ vin14: video@e6efe000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6efe000 0 0x1000>;
+ interrupts = <GIC_SPI 543 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 812>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 812>;
+ renesas,id = <14>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin14isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin14>;
+ };
+ };
+ };
+ };
+
+ vin15: video@e6eff000 {
+ compatible = "renesas,vin-r8a779h0";
+ reg = <0 0xe6eff000 0 0x1000>;
+ interrupts = <GIC_SPI 544 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 813>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 813>;
+ renesas,id = <15>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <2>;
+
+ vin15isp1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&isp1vin15>;
+ };
+ };
+ };
+ };
+
dmac1: dma-controller@e7350000 {
compatible = "renesas,dmac-r8a779h0",
"renesas,rcar-gen4-dmac";
@@ -580,6 +1426,14 @@
resets = <&cpg 709>;
#dma-cells = <1>;
dma-channels = <16>;
+ iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+ <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+ <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+ <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
+ <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
+ <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
+ <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
+ <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
};
dmac2: dma-controller@e7351000 {
@@ -605,6 +1459,71 @@
resets = <&cpg 710>;
#dma-cells = <1>;
dma-channels = <8>;
+ iommus = <&ipmmu_ds0 16>, <&ipmmu_ds0 17>,
+ <&ipmmu_ds0 18>, <&ipmmu_ds0 19>,
+ <&ipmmu_ds0 20>, <&ipmmu_ds0 21>,
+ <&ipmmu_ds0 22>, <&ipmmu_ds0 23>;
+ };
+
+ rcar_sound: sound@ec400000 {
+ compatible = "renesas,rcar_sound-r8a779h0", "renesas,rcar_sound-gen4";
+ reg = <0 0xec400000 0 0x40000>,
+ <0 0xec540000 0 0x1000>,
+ <0 0xec541000 0 0x050>,
+ <0 0xec5a0000 0 0x020>;
+ reg-names = "sdmc", "ssiu", "ssi", "adg";
+ clocks = <&cpg CPG_MOD 2926>, <&cpg CPG_MOD 2927>, <&audio_clkin>;
+ clock-names = "ssiu.0", "ssi.0", "clkin";
+ /* #clock-cells is fixed */
+ #clock-cells = <0>;
+ /* #sound-dai-cells is fixed */
+ #sound-dai-cells = <0>;
+
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 2926>, <&cpg 2927>;
+ reset-names = "ssiu.0", "ssi.0";
+ status = "disabled";
+
+ rcar_sound,ssiu {
+ ssiu00: ssiu-0 {
+ dmas = <&dmac1 0x6e>, <&dmac1 0x6f>;
+ dma-names = "tx", "rx";
+ };
+ ssiu01: ssiu-1 {
+ dmas = <&dmac1 0x6c>, <&dmac1 0x6d>;
+ dma-names = "tx", "rx";
+ };
+ ssiu02: ssiu-2 {
+ dmas = <&dmac1 0x6a>, <&dmac1 0x6b>;
+ dma-names = "tx", "rx";
+ };
+ ssiu03: ssiu-3 {
+ dmas = <&dmac1 0x68>, <&dmac1 0x69>;
+ dma-names = "tx", "rx";
+ };
+ ssiu04: ssiu-4 {
+ dmas = <&dmac1 0x66>, <&dmac1 0x67>;
+ dma-names = "tx", "rx";
+ };
+ ssiu05: ssiu-5 {
+ dmas = <&dmac1 0x64>, <&dmac1 0x65>;
+ dma-names = "tx", "rx";
+ };
+ ssiu06: ssiu-6 {
+ dmas = <&dmac1 0x62>, <&dmac1 0x63>;
+ dma-names = "tx", "rx";
+ };
+ ssiu07: ssiu-7 {
+ dmas = <&dmac1 0x60>, <&dmac1 0x61>;
+ dma-names = "tx", "rx";
+ };
+ };
+
+ rcar_sound,ssi {
+ ssi0: ssi-0 {
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
};
mmc0: mmc@ee140000 {
@@ -618,6 +1537,7 @@
power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
resets = <&cpg 706>;
max-frequency = <200000000>;
+ iommus = <&ipmmu_ds0 32>;
status = "disabled";
};
@@ -637,6 +1557,106 @@
status = "disabled";
};
+ ipmmu_rt0: iommu@ee480000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xee480000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_rt1: iommu@ee4c0000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xee4c0000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_ds0: iommu@eed00000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeed00000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_hc: iommu@eed40000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeed40000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_ir: iommu@eed80000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeed80000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vc: iommu@eedc0000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeedc0000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_3dg: iommu@eee00000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeee00000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vi0: iommu@eee80000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeee80000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vi1: iommu@eeec0000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeeec0000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vip0: iommu@eef00000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeef00000 0 0x20000>;
+ renesas,ipmmu-main = <&ipmmu_mm>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_mm: iommu@eefc0000 {
+ compatible = "renesas,ipmmu-r8a779h0",
+ "renesas,rcar-gen4-ipmmu-vmsa";
+ reg = <0 0xeefc0000 0 0x20000>;
+ interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
gic: interrupt-controller@f1000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
@@ -647,12 +1667,260 @@
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};
+ csi40: csi2@fe500000 {
+ compatible = "renesas,r8a779h0-csi2";
+ reg = <0 0xfe500000 0 0x40000>;
+ interrupts = <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 331>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 331>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ csi40isp0: endpoint {
+ remote-endpoint = <&isp0csi40>;
+ };
+ };
+ };
+ };
+
+ csi41: csi2@fe540000 {
+ compatible = "renesas,r8a779h0-csi2";
+ reg = <0 0xfe540000 0 0x40000>;
+ interrupts = <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 400>;
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 400>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ csi41isp1: endpoint {
+ remote-endpoint = <&isp1csi41>;
+ };
+ };
+ };
+ };
+
+ isp0: isp@fed00000 {
+ compatible = "renesas,r8a779h0-isp";
+ reg = <0 0xfed00000 0 0x10000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&cpg CPG_MOD 612>;
+ power-domains = <&sysc R8A779H0_PD_A3ISP0>;
+ resets = <&cpg 612>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0>;
+
+ isp0csi40: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&csi40isp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ isp0vin00: endpoint {
+ remote-endpoint = <&vin00isp0>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ isp0vin01: endpoint {
+ remote-endpoint = <&vin01isp0>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ isp0vin02: endpoint {
+ remote-endpoint = <&vin02isp0>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ isp0vin03: endpoint {
+ remote-endpoint = <&vin03isp0>;
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+ isp0vin04: endpoint {
+ remote-endpoint = <&vin04isp0>;
+ };
+ };
+
+ port@6 {
+ reg = <6>;
+ isp0vin05: endpoint {
+ remote-endpoint = <&vin05isp0>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ isp0vin06: endpoint {
+ remote-endpoint = <&vin06isp0>;
+ };
+ };
+
+ port@8 {
+ reg = <8>;
+ isp0vin07: endpoint {
+ remote-endpoint = <&vin07isp0>;
+ };
+ };
+ };
+ };
+
+ isp1: isp@fed20000 {
+ compatible = "renesas,r8a779h0-isp";
+ reg = <0 0xfed20000 0 0x10000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&cpg CPG_MOD 613>;
+ power-domains = <&sysc R8A779H0_PD_A3ISP0>;
+ resets = <&cpg 613>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0>;
+
+ isp1csi41: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&csi41isp1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ isp1vin08: endpoint {
+ remote-endpoint = <&vin08isp1>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ isp1vin09: endpoint {
+ remote-endpoint = <&vin09isp1>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ isp1vin10: endpoint {
+ remote-endpoint = <&vin10isp1>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ isp1vin11: endpoint {
+ remote-endpoint = <&vin11isp1>;
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+ isp1vin12: endpoint {
+ remote-endpoint = <&vin12isp1>;
+ };
+ };
+
+ port@6 {
+ reg = <6>;
+ isp1vin13: endpoint {
+ remote-endpoint = <&vin13isp1>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ isp1vin14: endpoint {
+ remote-endpoint = <&vin14isp1>;
+ };
+ };
+
+ port@8 {
+ reg = <8>;
+ isp1vin15: endpoint {
+ remote-endpoint = <&vin15isp1>;
+ };
+ };
+ };
+ };
+
prr: chipid@fff00044 {
compatible = "renesas,prr";
reg = <0 0xfff00044 0 4>;
};
};
+ thermal-zones {
+ sensor_thermal_cr52: sensor1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsc 0>;
+
+ trips {
+ sensor1_crit: sensor1-crit {
+ temperature = <120000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ sensor_thermal_ca76: sensor2-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsc 1>;
+
+ trips {
+ sensor2_crit: sensor2-crit {
+ temperature = <120000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
@@ -660,5 +1928,7 @@
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
index 8721f4c9fa0f..2eccab9c8962 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
@@ -598,6 +598,7 @@
gpio-ranges = <&pinctrl 0 0 152>;
#interrupt-cells = <2>;
interrupt-controller;
+ interrupt-parent = <&irqc>;
clocks = <&cpg CPG_MOD R9A07G043_GPIO_HCLK>;
power-domains = <&cpg>;
resets = <&cpg R9A07G043_GPIO_RSTN>,
@@ -645,7 +646,7 @@
sdhi0: mmc@11c00000 {
compatible = "renesas,sdhi-r9a07g043",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x11c00000 0 0x10000>;
interrupts = <SOC_PERIPHERAL_IRQ(104) IRQ_TYPE_LEVEL_HIGH>,
<SOC_PERIPHERAL_IRQ(105) IRQ_TYPE_LEVEL_HIGH>;
@@ -661,7 +662,7 @@
sdhi1: mmc@11c10000 {
compatible = "renesas,sdhi-r9a07g043",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x11c10000 0 0x10000>;
interrupts = <SOC_PERIPHERAL_IRQ(106) IRQ_TYPE_LEVEL_HIGH>,
<SOC_PERIPHERAL_IRQ(107) IRQ_TYPE_LEVEL_HIGH>;
@@ -812,7 +813,7 @@
hsusb: usb@11c60000 {
compatible = "renesas,usbhs-r9a07g043",
- "renesas,rza2-usbhs";
+ "renesas,rzg2l-usbhs";
reg = <0 0x11c60000 0 0x10000>;
interrupts = <SOC_PERIPHERAL_IRQ(100) IRQ_TYPE_EDGE_RISING>,
<SOC_PERIPHERAL_IRQ(101) IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
index 964b0a475eee..18ef297db933 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
@@ -50,14 +50,13 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
-&pinctrl {
- interrupt-parent = <&irqc>;
-};
-
&soc {
interrupt-parent = <&gic>;
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
index 9f00b75d2bd0..d3838e5820fc 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
@@ -1050,7 +1050,7 @@
sdhi0: mmc@11c00000 {
compatible = "renesas,sdhi-r9a07g044",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x11c00000 0 0x10000>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
@@ -1066,7 +1066,7 @@
sdhi1: mmc@11c10000 {
compatible = "renesas,sdhi-r9a07g044",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x11c10000 0 0x10000>;
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
@@ -1217,7 +1217,7 @@
hsusb: usb@11c60000 {
compatible = "renesas,usbhs-r9a07g044",
- "renesas,rza2-usbhs";
+ "renesas,rzg2l-usbhs";
reg = <0 0x11c60000 0 0x10000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
@@ -1334,6 +1334,9 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
index 53d8905f367a..1de2e5f0917d 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
@@ -1058,7 +1058,7 @@
sdhi0: mmc@11c00000 {
compatible = "renesas,sdhi-r9a07g054",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x11c00000 0 0x10000>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
@@ -1074,7 +1074,7 @@
sdhi1: mmc@11c10000 {
compatible = "renesas,sdhi-r9a07g054",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x11c10000 0 0x10000>;
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
@@ -1225,7 +1225,7 @@
hsusb: usb@11c60000 {
compatible = "renesas,usbhs-r9a07g054",
- "renesas,rza2-usbhs";
+ "renesas,rzg2l-usbhs";
reg = <0 0x11c60000 0 0x10000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
@@ -1342,6 +1342,9 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
index f5f3f4f4c8d6..0d5c47a65e46 100644
--- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -182,7 +182,7 @@
};
sdhi0: mmc@11c00000 {
- compatible = "renesas,sdhi-r9a08g045", "renesas,rcar-gen3-sdhi";
+ compatible = "renesas,sdhi-r9a08g045", "renesas,rzg2l-sdhi";
reg = <0x0 0x11c00000 0 0x10000>;
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
@@ -197,7 +197,7 @@
};
sdhi1: mmc@11c10000 {
- compatible = "renesas,sdhi-r9a08g045", "renesas,rcar-gen3-sdhi";
+ compatible = "renesas,sdhi-r9a08g045", "renesas,rzg2l-sdhi";
reg = <0x0 0x11c10000 0 0x10000>;
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
@@ -212,7 +212,7 @@
};
sdhi2: mmc@11c20000 {
- compatible = "renesas,sdhi-r9a08g045", "renesas,rcar-gen3-sdhi";
+ compatible = "renesas,sdhi-r9a08g045", "renesas,rzg2l-sdhi";
reg = <0x0 0x11c20000 0 0x10000>;
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
@@ -294,6 +294,9 @@
interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+ "hyp-virt";
};
};
diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
index 50ed66d42a24..9a4cbef704c1 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
@@ -71,7 +71,7 @@
sdhi0: mmc@85000000 {
compatible = "renesas,sdhi-r9a09g011",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x85000000 0 0x2000>;
interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
@@ -87,7 +87,7 @@
sdhi1: mmc@85010000 {
compatible = "renesas,sdhi-r9a09g011",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x85010000 0 0x2000>;
interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
@@ -103,7 +103,7 @@
emmc: mmc@85020000 {
compatible = "renesas,sdhi-r9a09g011",
- "renesas,rcar-gen3-sdhi";
+ "renesas,rzg2l-sdhi";
reg = <0x0 0x85020000 0 0x2000>;
interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
@@ -372,5 +372,6 @@
<&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)>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys";
};
};
diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
index b7a3e6caa386..b34855956ae0 100644
--- a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
@@ -54,14 +54,6 @@
};
};
- usb0_vbus_otg: regulator-usb0-vbus-otg {
- compatible = "regulator-fixed";
-
- regulator-name = "USB0_VBUS_OTG";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- };
-
vccq_sdhi1: regulator-vccq-sdhi1 {
compatible = "regulator-gpio";
regulator-name = "SDHI1 VccQ";
@@ -139,6 +131,9 @@
&phyrst {
status = "okay";
+ usb0_vbus_otg: regulator-vbus {
+ regulator-name = "vbus";
+ };
};
&scif0 {
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
index de590996e10a..433860987f73 100644
--- a/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
@@ -5,6 +5,7 @@
* Copyright (C) 2022 Renesas Electronics Corp.
*/
+#include <dt-bindings/gpio/gpio.h>
#include "rzg2ul-smarc-pinfunction.dtsi"
#include "rz-smarc-common.dtsi"
@@ -23,6 +24,63 @@
&i2c0 {
clock-frequency = <400000>;
+ da9062: pmic@58 {
+ compatible = "dlg,da9062";
+ reg = <0x58>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio {
+ compatible = "dlg,da9062-gpio";
+ };
+
+ onkey {
+ compatible = "dlg,da9062-onkey";
+ };
+
+ pmic-good-hog {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "PMIC_PGOOD";
+ };
+
+ rtc {
+ compatible = "dlg,da9062-rtc";
+ };
+
+ sd0-pwr-sel-hog {
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "SD0_PWR_SEL";
+ };
+
+ sd1-pwr-sel-hog {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "SD1_PWR_SEL";
+ };
+
+ sw-et0-en-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "SW_ET0_EN#";
+ };
+
+ thermal {
+ compatible = "dlg,da9062-thermal";
+ status = "disabled";
+ };
+
+ watchdog {
+ compatible = "dlg,da9062-watchdog";
+ status = "disabled";
+ };
+ };
+
versa3: clock-generator@68 {
compatible = "renesas,5p35023";
reg = <0x68>;
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
index acac4666ae59..8a3d302f1535 100644
--- a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
@@ -25,7 +25,7 @@
* SW_OFF - SD2 is connected to SoC
* SW_ON - SCIF1, SSI0, IRQ0, IRQ1 connected to SoC
*/
-#define SW_CONFIG2 SW_ON
+#define SW_CONFIG2 SW_OFF
#define SW_CONFIG3 SW_ON
/ {
@@ -36,8 +36,8 @@
#if SW_CONFIG3 == SW_OFF
mmc2 = &sdhi2;
#else
- eth0 = &eth0;
- eth1 = &eth1;
+ ethernet0 = &eth0;
+ ethernet1 = &eth1;
#endif
};
diff --git a/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
index 8ac17370ff36..80496fb3d476 100644
--- a/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
@@ -13,6 +13,12 @@
/ {
aliases {
ethernet0 = &avb0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
serial0 = &hscif0;
};
@@ -142,18 +148,23 @@
&avb0 {
pinctrl-0 = <&avb0_pins>;
pinctrl-names = "default";
- phy-handle = <&phy0>;
+ phy-handle = <&avb0_phy>;
tx-internal-delay-ps = <2000>;
status = "okay";
- phy0: ethernet-phy@0 {
- compatible = "ethernet-phy-id0022.1622",
- "ethernet-phy-ieee802.3-c22";
- rxc-skew-ps = <1500>;
- reg = <0>;
- interrupt-parent = <&gpio7>;
- interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
- reset-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>;
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ avb0_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-id0022.1622",
+ "ethernet-phy-ieee802.3-c22";
+ rxc-skew-ps = <1500>;
+ reg = <0>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi
index a218fda337cf..595ec4ff4cdd 100644
--- a/arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi
+++ b/arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi
@@ -6,6 +6,57 @@
* Copyright (C) 2022 Glider bv
*/
+/ {
+ aliases {
+ ethernet1 = &avb1;
+ ethernet2 = &avb2;
+ };
+};
+
+&avb1 {
+ pinctrl-0 = <&avb1_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&avb1_phy>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reset-gpios = <&gpio6 1 GPIO_ACTIVE_LOW>;
+ reset-post-delay-us = <4000>;
+
+ avb1_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+};
+
+&avb2 {
+ pinctrl-0 = <&avb2_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&avb2_phy>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reset-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
+ reset-post-delay-us = <4000>;
+
+ avb2_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+};
+
&i2c0 {
eeprom@53 {
compatible = "rohm,br24g01", "atmel,24c01";
@@ -14,3 +65,55 @@
pagesize = <8>;
};
};
+
+&pfc {
+ avb1_pins: avb1 {
+ mux {
+ groups = "avb1_link", "avb1_mdio", "avb1_rgmii",
+ "avb1_txcrefclk";
+ function = "avb1";
+ };
+
+ mdio {
+ groups = "avb1_mdio";
+ drive-strength = <24>;
+ bias-disable;
+ };
+
+ rgmii {
+ groups = "avb1_rgmii";
+ drive-strength = <24>;
+ bias-disable;
+ };
+
+ link {
+ groups = "avb1_link";
+ bias-disable;
+ };
+ };
+
+ avb2_pins: avb2 {
+ mux {
+ groups = "avb2_link", "avb2_mdio", "avb2_rgmii",
+ "avb2_txcrefclk";
+ function = "avb2";
+ };
+
+ mdio {
+ groups = "avb2_mdio";
+ drive-strength = <24>;
+ bias-disable;
+ };
+
+ rgmii {
+ groups = "avb2_rgmii";
+ drive-strength = <24>;
+ bias-disable;
+ };
+
+ link {
+ groups = "avb2_link";
+ bias-disable;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index f906a868b71a..fda1b980eb4b 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -7,9 +7,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-ringneck-haikou.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-s0.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351m.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351v.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-gameforce-chi.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2-v11.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go3.dtb
@@ -26,6 +28,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-pc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-lba3368.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-lion-haikou.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb
@@ -78,6 +81,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353ps.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353v.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353vs.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg503.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-orangepi-3b-v1.1.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-orangepi-3b-v2.1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinetab2-v0.1.dtb
@@ -89,7 +94,10 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-powkiddy-x55.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-zero-3e.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-zero-3w.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rock-3c.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-model-a.dtb
@@ -100,6 +108,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r68s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-lubancat-2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-mecsbc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5c.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-odroid-m1.dtb
@@ -107,16 +116,25 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-qnap-ts433.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtbo
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-ok3588-c.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5-itx.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b-pcie-ep.dtbo
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b-pcie-srns.dtbo
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-tiger-haikou.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
index b47fe02c33fb..62d18ca769a1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
@@ -5,6 +5,8 @@
*/
/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
#include "rk3308.dtsi"
/ {
@@ -15,6 +17,7 @@
ethernet0 = &gmac;
mmc0 = &emmc;
mmc1 = &sdmmc;
+ mmc2 = &sdio;
};
chosen {
@@ -24,17 +27,21 @@
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
- pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>;
+ pinctrl-0 = <&green_led>, <&heartbeat_led>;
green-led {
+ color = <LED_COLOR_ID_GREEN>;
default-state = "on";
+ function = LED_FUNCTION_POWER;
gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
label = "rockpis:green:power";
linux,default-trigger = "default-on";
};
blue-led {
+ color = <LED_COLOR_ID_BLUE>;
default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
label = "rockpis:blue:user";
linux,default-trigger = "heartbeat";
@@ -126,21 +133,37 @@
};
&emmc {
- bus-width = <4>;
cap-mmc-highspeed;
- mmc-hs200-1_8v;
+ cap-sd-highspeed;
+ no-sdio;
non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
vmmc-supply = <&vcc_io>;
status = "okay";
};
&gmac {
clock_in_out = "output";
+ phy-handle = <&rtl8201f>;
phy-supply = <&vcc_io>;
- snps,reset-gpio = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
- snps,reset-active-low;
- snps,reset-delays-us = <0 50000 50000>;
status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rtl8201f: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ };
+ };
};
&gpio0 {
@@ -209,16 +232,46 @@
status = "okay";
};
+&io_domains {
+ vccio0-supply = <&vcc_io>;
+ vccio1-supply = <&vcc_io>;
+ vccio2-supply = <&vcc_io>;
+ vccio3-supply = <&vcc_io>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_io>;
+ status = "okay";
+};
+
&pinctrl {
pinctrl-names = "default";
pinctrl-0 = <&rtc_32k>;
+ bluetooth {
+ bt_reg_on: bt-reg-on {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host: bt-wake-host {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ host_wake_bt: host-wake-bt {
+ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gmac {
+ mac_rst: mac-rst {
+ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
leds {
- green_led_gio: green-led-gpio {
+ green_led: green-led {
rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
- heartbeat_led_gpio: heartbeat-led-gpio {
+ heartbeat_led: heartbeat-led {
rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
@@ -256,15 +309,31 @@
cap-sd-highspeed;
cap-sdio-irq;
keep-power-in-suspend;
- max-frequency = <1000000>;
+ max-frequency = <100000000>;
mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
non-removable;
- sd-uhs-sdr104;
+ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc_1v8>;
status = "okay";
+
+ rtl8723ds: wifi@1 {
+ reg = <1>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_host_wake>;
+ };
};
&sdmmc {
+ cap-mmc-highspeed;
cap-sd-highspeed;
+ disable-wp;
+ vmmc-supply = <&vcc_io>;
status = "okay";
};
@@ -283,16 +352,22 @@
};
&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
status = "okay";
};
&uart4 {
+ uart-has-rtscts;
status = "okay";
bluetooth {
- compatible = "realtek,rtl8723bs-bt";
- device-wake-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+ compatible = "realtek,rtl8723ds-bt";
+ device-wake-gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_HIGH>;
+ enable-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
host-wake-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_reg_on &bt_wake_host &host_wake_bt>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts
new file mode 100644
index 000000000000..bd6419a5c20a
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "rk3308.dtsi"
+
+/ {
+ model = "Radxa ROCK S0";
+ compatible = "radxa,rock-s0", "rockchip,rk3308";
+
+ aliases {
+ ethernet0 = &gmac;
+ mmc0 = &emmc;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
+ };
+
+ chosen {
+ stdout-path = "serial0:1500000n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_led>;
+
+ led-green {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ vdd_log: regulator-1v04-vdd-log {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_log";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1040000>;
+ regulator-max-microvolt = <1040000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_ddr: regulator-1v5-vcc-ddr {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_1v8: regulator-1v8-vcc {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_io: regulator-3v3-vcc-io {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_io";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: regulator-5v0-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vdd_core: regulator-vdd-core {
+ compatible = "pwm-regulator";
+ pwms = <&pwm0 0 5000 1>;
+ pwm-supply = <&vcc5v0_sys>;
+ regulator-name = "vdd_core";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <827000>;
+ regulator-max-microvolt = <1340000>;
+ regulator-settling-time-up-us = <250>;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on>;
+ reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_core>;
+};
+
+&emmc {
+ cap-mmc-highspeed;
+ no-sd;
+ no-sdio;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_pwren>;
+ vmmc-supply = <&vcc_io>;
+ status = "okay";
+};
+
+&gmac {
+ clock_in_out = "output";
+ phy-handle = <&rtl8201f>;
+ phy-supply = <&vcc_io>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rtl8201f: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&io_domains {
+ vccio0-supply = <&vcc_io>;
+ vccio1-supply = <&vcc_io>;
+ vccio2-supply = <&vcc_io>;
+ vccio3-supply = <&vcc_io>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_io>;
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_32k>;
+
+ bluetooth {
+ bt_reg_on: bt-reg-on {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host: bt-wake-host {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ host_wake_bt: host-wake-bt {
+ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gmac {
+ mac_rst: mac-rst {
+ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ pwr_led: pwr-led {
+ rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_reg_on: wifi-reg-on {
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_wake_host: wifi-wake-host {
+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin_pull_down>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ max-frequency = <50000000>;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
+ non-removable;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+
+ brcmf: wifi@1 {
+ compatible = "brcm,bcm43430a1-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_wake_host>;
+ };
+};
+
+&sdmmc {
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ vmmc-supply = <&vcc_io>;
+ status = "okay";
+};
+
+&u2phy {
+ status = "okay";
+};
+
+&u2phy_host {
+ status = "okay";
+};
+
+&u2phy_otg {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+ status = "okay";
+};
+
+&uart4 {
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm43430a1-bt";
+ clocks = <&cru SCLK_RTC32K>;
+ clock-names = "lpo";
+ interrupt-parent = <&gpio4>;
+ interrupts = <RK_PB4 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wakeup";
+ device-wakeup-gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_reg_on &bt_wake_host &host_wake_bt>;
+ vbat-supply = <&vcc_io>;
+ vddio-supply = <&vcc_1v8>;
+ };
+};
+
+&usb_host_ehci {
+ status = "okay";
+};
+
+&usb_host_ohci {
+ status = "okay";
+};
+
+&usb20_otg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
index cfc0a87b5195..31c25de2d689 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
@@ -173,6 +173,11 @@
compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd";
reg = <0x0 0xff000000 0x0 0x08000>;
+ io_domains: io-domains {
+ compatible = "rockchip,rk3308-io-voltage-domain";
+ status = "disabled";
+ };
+
reboot-mode {
compatible = "syscon-reboot-mode";
offset = <0x500>;
@@ -556,6 +561,30 @@
status = "disabled";
};
+ otp: efuse@ff210000 {
+ compatible = "rockchip,rk3308-otp";
+ reg = <0x0 0xff210000 0x0 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
+ <&cru PCLK_OTP_PHY>;
+ clock-names = "otp", "apb_pclk", "phy";
+ resets = <&cru SRST_OTP_PHY>;
+ reset-names = "phy";
+
+ cpu_id: id@7 {
+ reg = <0x07 0x10>;
+ };
+
+ cpu_leakage: cpu-leakage@17 {
+ reg = <0x17 0x1>;
+ };
+
+ logic_leakage: logic-leakage@18 {
+ reg = <0x18 0x1>;
+ };
+ };
+
dmac0: dma-controller@ff2c0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xff2c0000 0x0 0x4000>;
@@ -578,6 +607,48 @@
#dma-cells = <1>;
};
+ /*
+ * - can be clock producer or consumer
+ * - up to 8 capture channels and 2 playback channels
+ * - connected internally to audio codec
+ */
+ i2s_8ch_2: i2s@ff320000 {
+ compatible = "rockchip,rk3308-i2s-tdm";
+ reg = <0x0 0xff320000 0x0 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ clocks = <&cru SCLK_I2S2_8CH_TX>,
+ <&cru SCLK_I2S2_8CH_RX>,
+ <&cru HCLK_I2S2_8CH>;
+ dmas = <&dmac1 5>, <&dmac1 4>;
+ dma-names = "rx", "tx";
+ resets = <&cru SRST_I2S2_8CH_TX_M>, <&cru SRST_I2S2_8CH_RX_M>;
+ reset-names = "tx-m", "rx-m";
+ rockchip,grf = <&grf>;
+ status = "disabled";
+ };
+
+ /*
+ * - can be clock consumer only
+ * - up to 4 capture channels, no playback
+ * - connected internally to audio codec
+ */
+ i2s_8ch_3: i2s@ff330000 {
+ compatible = "rockchip,rk3308-i2s-tdm";
+ reg = <0x0 0xff330000 0x0 0x1000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ clocks = <&cru SCLK_I2S3_8CH_TX>,
+ <&cru SCLK_I2S3_8CH_RX>,
+ <&cru HCLK_I2S3_8CH>;
+ dmas = <&dmac1 7>;
+ dma-names = "rx";
+ resets = <&cru SRST_I2S3_8CH_TX_M>, <&cru SRST_I2S3_8CH_RX_M>;
+ reset-names = "tx-m", "rx-m";
+ rockchip,grf = <&grf>;
+ status = "disabled";
+ };
+
i2s_2ch_0: i2s@ff350000 {
compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
reg = <0x0 0xff350000 0x0 0x1000>;
@@ -761,6 +832,20 @@
assigned-clock-rates = <32768>;
};
+ codec: codec@ff560000 {
+ compatible = "rockchip,rk3308-codec";
+ reg = <0x0 0xff560000 0x0 0x10000>;
+ rockchip,grf = <&grf>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ clocks = <&cru SCLK_I2S2_8CH_TX_OUT>,
+ <&cru SCLK_I2S2_8CH_RX_OUT>,
+ <&cru PCLK_ACODEC>;
+ reset-names = "codec";
+ resets = <&cru SRST_ACODEC_P>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@ff580000 {
compatible = "arm,gic-400";
reg = <0x0 0xff581000 0x0 0x1000>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts b/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
new file mode 100644
index 000000000000..579261b3a474
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
@@ -0,0 +1,809 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Chris Morgan <macromorgan@hotmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3326.dtsi"
+
+/ {
+ model = "GameForce Chi";
+ compatible = "gameforce,chi", "rockchip,rk3326";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &sdio;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ adc_joystick: adc-joystick {
+ compatible = "adc-joystick";
+ io-channels = <&saradc 0>,
+ <&saradc 1>;
+ poll-interval = <100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ axis@0 {
+ reg = <0>;
+ abs-flat = <10>;
+ abs-fuzz = <10>;
+ abs-range = <850 175>;
+ linux,code = <ABS_Y>;
+ };
+
+ axis@1 {
+ reg = <1>;
+ abs-flat = <10>;
+ abs-fuzz = <10>;
+ abs-range = <800 190>;
+ linux,code = <ABS_X>;
+ };
+ };
+
+ adc_keys: adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 2>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <60>;
+
+ button-1 {
+ label = "HAPPY1";
+ linux,code = <BTN_TRIGGER_HAPPY1>;
+ press-threshold-microvolt = <15000>;
+ };
+
+ button-2 {
+ label = "HAPPY2";
+ linux,code = <BTN_TRIGGER_HAPPY2>;
+ press-threshold-microvolt = <300000>;
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ power-supply = <&vcc_bl>;
+ pwms = <&pwm1 0 25000 0>;
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ charge-full-design-microamp-hours = <3000000>;
+ charge-term-current-microamp = <300000>;
+ constant-charge-current-max-microamp = <1500000>;
+ constant-charge-voltage-max-microvolt = <4200000>;
+ factory-internal-resistance-micro-ohms = <180000>;
+ ocv-capacity-celsius = <20>;
+ ocv-capacity-table-0 = <4106000 100>, <4071000 95>, <4018000 90>, <3975000 85>,
+ <3946000 80>, <3908000 75>, <3877000 70>, <3853000 65>,
+ <3834000 60>, <3816000 55>, <3802000 50>, <3788000 45>,
+ <3774000 40>, <3760000 35>, <3748000 30>, <3735000 25>,
+ <3718000 20>, <3697000 15>, <3685000 10>, <3625000 5>,
+ <3400000 0>;
+ voltage-max-design-microvolt = <4250000>;
+ voltage-min-design-microvolt = <3400000>;
+ };
+
+ gpio_leds: gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ red_led: led-0 {
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+ };
+
+ green_led: led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+ };
+
+ blue_led: led-2 {
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
+ };
+
+ white_led: led-3 {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ };
+
+ chg_led: led-4 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_CHARGING;
+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>;
+ };
+
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&btn_pins_ctrl>;
+ pinctrl-names = "default";
+
+ button-a {
+ gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>;
+ label = "EAST";
+ linux,code = <BTN_EAST>;
+ };
+
+ button-b {
+ gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;
+ label = "SOUTH";
+ linux,code = <BTN_SOUTH>;
+ };
+
+ button-down {
+ gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-DOWN";
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ button-home {
+ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>;
+ label = "HOME";
+ linux,code = <BTN_MODE>;
+ };
+
+ button-l1 {
+ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "TL";
+ linux,code = <BTN_TL>;
+ };
+
+ button-l2 {
+ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;
+ label = "TL2";
+ linux,code = <BTN_TL2>;
+ };
+
+ button-left {
+ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-r1 {
+ gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR>;
+ };
+
+ button-r2 {
+ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR2>;
+ };
+
+ button-right {
+ gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-select {
+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;
+ label = "SELECT";
+ linux,code = <BTN_SELECT>;
+ };
+
+ button-start {
+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "START";
+ linux,code = <BTN_START>;
+ };
+
+ button-up {
+ gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "DPAD-UP";
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ button-x {
+ gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "NORTH";
+ linux,code = <BTN_NORTH>;
+ };
+
+ button-y {
+ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+ label = "WEST";
+ linux,code = <BTN_WEST>;
+ };
+ };
+
+ multi-led {
+ compatible = "leds-group-multicolor";
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+ leds = <&red_led>, <&green_led>, <&blue_led>;
+ };
+
+ spk_amp: audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&spk_amp_enable_h>;
+ pinctrl-names = "default";
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-0 = <&hp_det>;
+ pinctrl-names = "default";
+ simple-audio-card,name = "rk817_ext";
+ simple-audio-card,aux-devs = <&spk_amp>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Headphone", "Headphones",
+ "Speaker", "Internal Speakers";
+ simple-audio-card,routing =
+ "MICL", "Mic Jack",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "Internal Speakers", "Speaker Amp OUTL",
+ "Internal Speakers", "Speaker Amp OUTR",
+ "Speaker Amp INL", "HPOL",
+ "Speaker Amp INR", "HPOR";
+ simple-audio-card,pin-switches = "Internal Speakers";
+
+ simple-audio-card,codec {
+ sound-dai = <&rk817>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_2ch>;
+ };
+ };
+
+ vibrator_left: pwm-vibrator-l {
+ compatible = "pwm-vibrator";
+ pwm-names = "enable";
+ pwms = <&pwm4 0 25000 0>;
+ };
+
+ vibrator_right: pwm-vibrator-r {
+ compatible = "pwm-vibrator";
+ pwm-names = "enable";
+ pwms = <&pwm5 0 25000 0>;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&wifi_enable_h>;
+ pinctrl-names = "default";
+ post-power-on-delay-ms = <200>;
+ reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
+ };
+
+ vccsys: vccsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v8_sys";
+ regulator-always-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+ status = "okay";
+};
+
+&dsi {
+ status = "okay";
+
+ internal_display: panel@0 {
+ reg = <0>;
+ compatible = "gameforce,chi-panel";
+ backlight = <&backlight>;
+ iovcc-supply = <&vcc_lcd>;
+ vcc-supply = <&vcc_lcd>;
+ reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+
+ ports {
+ mipi_out: port@1 {
+ reg = <1>;
+
+ mipi_out_panel: endpoint {
+ remote-endpoint = <&mipi_in_panel>;
+ };
+ };
+ };
+};
+
+&dsi_dphy {
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_logic>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ i2c-scl-falling-time-ns = <16>;
+ i2c-scl-rising-time-ns = <280>;
+ status = "okay";
+
+ rk817: pmic@20 {
+ compatible = "rockchip,rk817";
+ reg = <0x20>;
+ #clock-cells = <1>;
+ clock-names = "mclk";
+ clock-output-names = "rk808-clkout1", "xin32k";
+ clocks = <&cru SCLK_I2S1_OUT>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PC1 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>;
+ pinctrl-names = "default";
+ #sound-dai-cells = <0>;
+ system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vccsys>;
+ vcc2-supply = <&vccsys>;
+ vcc3-supply = <&vccsys>;
+ vcc4-supply = <&vccsys>;
+ vcc5-supply = <&vccsys>;
+ vcc6-supply = <&vccsys>;
+ vcc7-supply = <&vcc_3v0>;
+ vcc8-supply = <&vccsys>;
+ vcc9-supply = <&dcdc_boost>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1150000>;
+ regulator-min-microvolt = <950000>;
+ regulator-name = "vdd_logic";
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <950000>;
+ };
+ };
+
+ vdd_arm: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microvolt = <950000>;
+ regulator-name = "vdd_arm";
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <950000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_ddr";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_3v0: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc_3v0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+
+ vcc_1v8: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "vcc_1v8";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_1v0: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1000000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-name = "vdd_1v0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_3v0_pmu: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc_3v0_pmu";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "vccio_sd";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_sd: LDO_REG6 {
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_sd";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_bl: LDO_REG7 {
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_bl";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_lcd: LDO_REG8 {
+ regulator-max-microvolt = <2800000>;
+ regulator-min-microvolt = <2800000>;
+ regulator-name = "vcc_lcd";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <2800000>;
+ };
+ };
+
+ vcc_wifi: LDO_REG9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_wifi";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ dcdc_boost: BOOST {
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "dcdc_boost";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ otg_switch: OTG_SWITCH {
+ regulator-name = "otg_switch";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+
+ rk817_charger: charger {
+ monitored-battery = <&battery>;
+ rockchip,resistor-sense-micro-ohms = <10000>;
+ rockchip,sleep-enter-current-microamp = <300000>;
+ rockchip,sleep-filter-current-microamp = <100000>;
+ };
+ };
+};
+
+&i2s1_2ch {
+ status = "okay";
+};
+
+&io_domains {
+ vccio1-supply = <&vcc_3v0_pmu>;
+ vccio2-supply = <&vccio_sd>;
+ vccio3-supply = <&vcc_3v0>;
+ vccio4-supply = <&vcc_3v0>;
+ vccio5-supply = <&vcc_3v0>;
+ vccio6-supply = <&vcc_3v0>;
+ status = "okay";
+};
+
+&pinctrl {
+ bluetooth-pins {
+ bt_reset: bt-reset {
+ rockchip,pins =
+ <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ bt_wake_dev: bt-wake-dev {
+ rockchip,pins =
+ <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host: bt-wake-host {
+ rockchip,pins =
+ <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ headphone {
+ hp_det: hp-det {
+ rockchip,pins =
+ <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ gpio-btns {
+ btn_pins_ctrl: btn-pins-ctrl {
+ rockchip,pins =
+ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>,
+ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
+ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>,
+ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ gpio-leds {
+ led_pins: led-pins {
+ rockchip,pins =
+ <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins =
+ <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ soc_slppin_gpio: soc_slppin_gpio {
+ rockchip,pins =
+ <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+
+ soc_slppin_rst: soc_slppin_rst {
+ rockchip,pins =
+ <0 RK_PA4 2 &pcfg_pull_none>;
+ };
+
+ soc_slppin_slp: soc_slppin_slp {
+ rockchip,pins =
+ <0 RK_PA4 1 &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins =
+ <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ speaker {
+ spk_amp_enable_h: spk-amp-enable-h {
+ rockchip,pins =
+ <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc_1v8>;
+ pmuio2-supply = <&vcc_3v0_pmu>;
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&pwm5 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdio {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ disable-wp;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
+ non-removable;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&sdmmc {
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ no-sdio;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sfc {
+ #address-cells = <1>;
+ pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
+ pinctrl-names = "default";
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <108000000>;
+ spi-rx-bus-width = <2>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy {
+ status = "okay";
+
+ u2phy_otg: otg-port {
+ status = "okay";
+ };
+};
+
+&usb20_otg {
+ status = "okay";
+};
+
+/*
+ * The right ADC joystick exists connected to an unknown ADC
+ * controller which can be communicated with via uart0. This ADC device
+ * is an 8-pin SOIC with no markings located right next to the left ADC
+ * joystick ribbon cable. The pinout for this ADC controller appears to
+ * be pin 1 - VCC (2.8v), pin 2 - 1.8v (clk maybe?), pin 3 - GPIO 10,
+ * pin 4 - unknown, pin 5 - unknown, pin 6 - analog in, pin 7 - analog in,
+ * pin 8 - ground. There is currently a userspace UART driver for this
+ * device but it only works with the BSP joystick driver.
+ */
+&uart0 {
+ status = "okay";
+};
+
+/*
+ * Bluetooth was not working on BSP and is not currently working on
+ * mainline due to missing firmware. Bluetooth requires removal of DMA
+ * or else it will not probe.
+ */
+&uart1 {
+ /delete-property/ dma-names;
+ /delete-property/ dmas;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth: bluetooth {
+ compatible = "realtek,rtl8723ds-bt";
+ device-wake-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
+ enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&bt_reset>, <&bt_wake_dev>, <&bt_wake_host>;
+ pinctrl-names = "default";
+ };
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m1_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index f09d60bbe6c4..a608a219543e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -241,8 +241,8 @@
rk805: pmic@18 {
compatible = "rockchip,rk805";
reg = <0x18>;
- interrupt-parent = <&gpio2>;
- interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
#clock-cells = <1>;
clock-output-names = "xin32k", "rk805-clkout2";
gpio-controller;
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
index 229fe9da9c2d..90fef766f3ae 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
@@ -154,6 +154,8 @@
};
&hdmi {
+ avdd-0v9-supply = <&vdd_10>;
+ avdd-1v8-supply = <&vcc_18>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index b6f045069ee2..b01efd6d042c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -46,8 +46,14 @@
cpu-idle-states = <&CPU_SLEEP>;
dynamic-power-coefficient = <120>;
enable-method = "psci";
- next-level-cache = <&l2>;
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu1: cpu@1 {
@@ -59,8 +65,14 @@
cpu-idle-states = <&CPU_SLEEP>;
dynamic-power-coefficient = <120>;
enable-method = "psci";
- next-level-cache = <&l2>;
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu2: cpu@2 {
@@ -72,8 +84,14 @@
cpu-idle-states = <&CPU_SLEEP>;
dynamic-power-coefficient = <120>;
enable-method = "psci";
- next-level-cache = <&l2>;
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
cpu3: cpu@3 {
@@ -85,8 +103,14 @@
cpu-idle-states = <&CPU_SLEEP>;
dynamic-power-coefficient = <120>;
enable-method = "psci";
- next-level-cache = <&l2>;
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ 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_cache>;
};
idle-states {
@@ -102,10 +126,13 @@
};
};
- l2: l2-cache0 {
+ l2_cache: l2-cache {
compatible = "cache";
cache-level = <2>;
cache-unified;
+ cache-size = <0x40000>;
+ cache-line-size = <64>;
+ cache-sets = <256>;
};
};
@@ -823,8 +850,8 @@
<0>, <24000000>,
<24000000>, <24000000>,
<15000000>, <15000000>,
- <100000000>, <100000000>,
- <100000000>, <100000000>,
+ <300000000>, <100000000>,
+ <400000000>, <100000000>,
<50000000>, <100000000>,
<100000000>, <100000000>,
<50000000>, <50000000>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
index b48b98c13705..e5c0dbf794ae 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
@@ -17,7 +17,7 @@
stdout-path = "serial2:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x40000000>;
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-lba3368.dts b/arch/arm64/boot/dts/rockchip/rk3368-lba3368.dts
new file mode 100644
index 000000000000..e0cc4da7f392
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-lba3368.dts
@@ -0,0 +1,659 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/clock/rockchip,rk808.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/sound/rt5640.h>
+#include "rk3368.dtsi"
+
+/ {
+ model = "Neardi LBA3368";
+ compatible = "neardi,lba3368", "rockchip,rk3368";
+
+ aliases {
+ ethernet0 = &gmac;
+ mmc0 = &emmc;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio0;
+ rtc0 = &hym8563;
+ rtc1 = &rk808;
+ };
+
+ chosen {
+ stdout-path = "serial1:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ adc-key {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ poll-interval = <100>;
+ keyup-threshold-microvolt = <1800000>;
+
+ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <0>;
+ };
+ };
+
+ analog-sound {
+ compatible = "audio-graph-card";
+ dais = <&i2s_8ch_p0>;
+ hp-det-gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ label = "alc5640";
+ routing = "Mic Jack", "MICBIAS1",
+ "IN1P", "Mic Jack",
+ "Headphone Jack", "HPOL",
+ "Headphone Jack", "HPOR",
+ "Speakers", "SPORP",
+ "Speakers", "SPORN",
+ "Speakers", "SPOLP",
+ "Speakers", "SPOLN";
+ widgets = "Microphone", "Mic Jack",
+ "Headphone", "Headphone Jack",
+ "Speaker", "Speakers";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_det>;
+ };
+
+ dc_12v: dc-12v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_12v";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ext_gmac: gmac-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ clock-output-names = "ext_gmac";
+ #clock-cells = <0>;
+ };
+
+ hub_avdd: hub-avdd-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "hub_avdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_io>;
+ regulator-always-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power-led {
+ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_led>;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk808 RK808_CLKOUT1>;
+ clock-names = "ext_clock";
+ reset-gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on>;
+ };
+
+ vcc_host: vcc-host-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ vcc_lan: vcc-lan-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_lan";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_io>;
+ regulator-always-on;
+ };
+
+ vcc_otg: vcc-otg-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ vcc_sys: vcc-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd10_usb: vdd10-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd10_usb";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ vin-supply = <&vdd_10>;
+ regulator-always-on;
+ };
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&emmc {
+ bus-width = <8>;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc_18>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ cap-mmc-highspeed;
+ non-removable;
+ no-sd;
+ no-sdio;
+ mmc-hs200-1_8v;
+ status = "okay";
+};
+
+&gmac {
+ clock_in_out = "input";
+ phy-handle = <&phy>;
+ phy-mode = "rmii";
+ phy-supply = <&vcc_lan>;
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rmii_pins>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ max-speed = <100>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <1000000>;
+ reset-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&phy_rst>;
+ };
+ };
+};
+
+&io_domains {
+ audio-supply = <&vcca1v8_codec>;
+ dvp-supply = <&vcc_18>;
+ flash0-supply = <&vcc_18>;
+ gpio1830-supply = <&vcc_io>;
+ gpio30-supply = <&vcc_io>;
+ sdcard-supply = <&vccio_sd>;
+ wifi-supply = <&vdd1v8_wl>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupts-extended = <&gpio0 RK_PA5 IRQ_TYPE_LEVEL_LOW>;
+ clock-output-names = "rk808-clkout1", "xin32k_wifi_bt";
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc_sys>;
+ vcc8-supply = <&vcc_io>;
+ vcc9-supply = <&vcc_sys>;
+ vcc10-supply = <&vcc_sys>;
+ vcc11-supply = <&vcc_sys>;
+ vcc12-supply = <&vcc_io>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int &pmic_sleep>;
+ system-power-controller;
+ wakeup-source;
+ #clock-cells = <1>;
+
+ regulators {
+ vdd_cpu: DCDC_REG1 {
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log: DCDC_REG2 {
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-ramp-delay = <6001>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-suspend-microvolt = <1000000>;
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_io: DCDC_REG4 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-suspend-microvolt = <3300000>;
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcca1v8_codec: LDO_REG1 {
+ regulator-name = "vcca1v8_codec";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca3v0_codec: LDO_REG2 {
+ regulator-name = "vcca3v0_codec";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_10: LDO_REG3 {
+ regulator-name = "vdd_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-suspend-microvolt = <1000000>;
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdd1v8_wl: LDO_REG4 {
+ regulator-name = "vdd1v8_wl";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd10_lcd: LDO_REG6 {
+ regulator-name = "vdd10_lcd";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_18: LDO_REG7 {
+ regulator-name = "vcc_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-suspend-microvolt = <1800000>;
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc18_lcd: LDO_REG8 {
+ regulator-name = "vcc18_lcd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_tp: SWITCH_REG1 {
+ regulator-name = "vcc_tp";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_sd: SWITCH_REG2 {
+ regulator-name = "vcc_sd";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ codec@1c {
+ compatible = "realtek,rt5640";
+ reg = <0x1c>;
+ clocks = <&cru SCLK_I2S_8CH_OUT>;
+ clock-names = "mclk";
+ realtek,dmic1-data-pin = <RT5640_DMIC1_DATA_PIN_IN1P>;
+ realtek,dmic2-data-pin = <RT5640_DMIC2_DATA_PIN_IN1N>;
+ realtek,in1-differential;
+ #sound-dai-cells = <0>;
+
+ port {
+ rt5640_p0_0: endpoint {
+ remote-endpoint = <&i2s_8ch_p0_0>;
+ };
+ };
+ };
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ clock-output-names = "xin32k";
+ #clock-cells = <0>;
+ };
+};
+
+&i2s_8ch {
+ status = "okay";
+
+ i2s_8ch_p0: port {
+ i2s_8ch_p0_0: endpoint {
+ dai-format = "i2s";
+ mclk-fs = <256>;
+ remote-endpoint = <&rt5640_p0_0>;
+ };
+ };
+};
+
+&pinctrl {
+ bluetooth {
+ bt_host_wake: bt-host-wake {
+ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_reg_on: bt-reg-on {
+ rockchip,pins = <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ bt_wake: bt-wake {
+ rockchip,pins = <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ power_led: power-led {
+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ phy {
+ phy_rst: phy-rst {
+ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ pmic_sleep: pmic-sleep {
+ rockchip,pins = <0 RK_PA0 2 &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_reg_on: wifi-reg-on {
+ rockchip,pins = <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ hp_det: hp-det {
+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_host_wake: wifi-host-wake {
+ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmu-supply = <&vcc_io>;
+ vop-supply = <&vcc_io>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdio0 {
+ bus-width = <4>;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vdd1v8_wl>;
+ assigned-clocks = <&cru SCLK_SDIO0>;
+ assigned-clock-parents = <&cru PLL_CPLL>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ no-sd;
+ no-mmc;
+ non-removable;
+ sd-uhs-sdr104;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ wifi@1 {
+ compatible = "brcm,bcm43455-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+ interrupts-extended = <&gpio3 RK_PA6 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_host_wake>;
+ };
+};
+
+&sdmmc {
+ bus-width = <4>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4 &sdmmc_cd>;
+ cap-sd-highspeed;
+ disable-wp;
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <0>;
+ rockchip,hw-tshut-polarity = <1>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm4345c5";
+ interrupts-extended = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
+ interrupt-names = "host-wakeup";
+ clocks = <&rk808 RK808_CLKOUT1>;
+ clock-names = "lpo";
+ device-wakeup-gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
+ max-speed = <15000000>;
+ vbat-supply = <&vcc_io>;
+ vddio-supply = <&vdd1v8_wl>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_host_wake &bt_wake &bt_reg_on>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ hub@1 {
+ compatible = "usb5e3,610";
+ reg = <1>;
+ vdd-supply = <&hub_avdd>;
+ };
+};
+
+&usb_otg {
+ vbus-supply = <&vcc_otg>;
+ vusb_a-supply = <&vcc_io>;
+ vusb_d-supply = <&vdd10_usb>;
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
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 dcee2e28916f..23ae2d9de382 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
@@ -21,7 +21,7 @@
stdout-path = "serial2:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>;
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
index b16b7ca02379..7f14206d53c3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
@@ -21,7 +21,7 @@
stdout-path = "serial2:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x40000000>;
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
index 62af0cb94839..73618df7a889 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -141,7 +141,7 @@
};
arm-pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
@@ -793,6 +793,7 @@
dma-names = "tx";
pinctrl-names = "default";
pinctrl-0 = <&spdif_tx>;
+ #sound-dai-cells = <0>;
status = "disabled";
};
@@ -804,6 +805,7 @@
clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>;
dmas = <&dmac_bus 6>, <&dmac_bus 7>;
dma-names = "tx", "rx";
+ #sound-dai-cells = <0>;
status = "disabled";
};
@@ -817,6 +819,7 @@
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&i2s_8ch_bus>;
+ #sound-dai-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 789fd0dcc88b..3cd63d1e8f15 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -450,7 +450,7 @@ ap_i2c_audio: &i2c8 {
dlg,btn-cfg = <50>;
dlg,mic-det-thr = <500>;
dlg,jack-ins-deb = <20>;
- dlg,jack-det-rate = "32ms_64ms";
+ dlg,jack-det-rate = "32_64";
dlg,jack-rem-deb = <1>;
dlg,a-d-btn-thr = <0xa>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
index 61f3fec5a8b1..ef754ea30a94 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -12,11 +12,12 @@
/dts-v1/;
#include <dt-bindings/input/gpio-keys.h>
#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
#include "rk3399.dtsi"
#include "rk3399-opp.dtsi"
/ {
- model = "Pine64 PinePhonePro";
+ model = "Pine64 PinePhone Pro";
compatible = "pine64,pinephone-pro", "rockchip,rk3399";
chassis-type = "handset";
@@ -69,6 +70,34 @@
};
};
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&red_led_pin &green_led_pin &blue_led_pin>;
+
+ led_red: led-0 {
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_green: led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_blue: led-2 {
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ multi-led {
+ compatible = "leds-group-multicolor";
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_INDICATOR;
+ leds = <&led_red>, <&led_green>, <&led_blue>;
+ };
+
vcc_sys: vcc-sys-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_sys";
@@ -152,6 +181,12 @@
gpio = <&gpio3 RK_PA1 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
};
+
+ vibrator {
+ compatible = "gpio-vibrator";
+ enable-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
+ vcc-supply = <&vcc3v3_sys>;
+ };
};
&cpu_alert0 {
@@ -407,6 +442,21 @@
};
};
+&i2c4 {
+ i2c-scl-rising-time-ns = <600>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+
+ /* Accelerometer/gyroscope */
+ mpu6500@68 {
+ compatible = "invensense,mpu6500";
+ reg = <0x68>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <RK_PC6 IRQ_TYPE_LEVEL_LOW>;
+ vddio-supply = <&vcc_1v8>;
+ };
+};
+
&cluster0_opp {
opp04 {
status = "disabled";
@@ -481,6 +531,20 @@
};
};
+ leds {
+ red_led_pin: red-led-pin {
+ rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ green_led_pin: green-led-pin {
+ rockchip,pins = <4 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ blue_led_pin: blue-led-pin {
+ rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -565,6 +629,16 @@
status = "okay";
};
+&spi1 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
&tsadc {
rockchip,hw-tshut-mode = <1>;
rockchip,hw-tshut-polarity = <1>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
index 7baf9d1b22fd..972aea843afd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
@@ -151,6 +151,7 @@
};
&emmc_phy {
+ rockchip,enable-strobe-pulldown;
status = "okay";
};
@@ -549,7 +550,8 @@
&sdhci {
max-frequency = <150000000>;
bus-width = <8>;
- mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
non-removable;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 281a12180703..b9d6284bb804 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -194,6 +194,7 @@
};
&emmc_phy {
+ rockchip,enable-strobe-pulldown;
status = "okay";
};
@@ -648,7 +649,8 @@
&sdhci {
max-frequency = <150000000>;
bus-width = <8>;
- mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
non-removable;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro.dtsi
deleted file mode 100644
index bb5ebf6608b9..000000000000
--- a/arch/arm64/boot/dts/rockchip/rk3399pro.dtsi
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-// Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd.
-
-#include "rk3399.dtsi"
-
-/ {
- compatible = "rockchip,rk3399pro";
-};
-
-/* Default to enabled since AP talk to NPU part over pcie */
-&pcie_phy {
- status = "okay";
-};
-
-/* Default to enabled since AP talk to NPU part over pcie */
-&pcie0 {
- ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
- num-lanes = <4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pcie_clkreqn_cpm>;
- status = "okay";
-};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
index 8aa93c646bec..a73cf30801ec 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
@@ -8,7 +8,7 @@
#include "rk3566-anbernic-rg353x.dtsi"
/ {
- model = "RG353P";
+ model = "Anbernic RG353P";
compatible = "anbernic,rg353p", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353ps.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353ps.dts
index b211973e36c2..ca5284e4807d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353ps.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353ps.dts
@@ -8,7 +8,7 @@
#include "rk3566-anbernic-rg353x.dtsi"
/ {
- model = "RG353PS";
+ model = "Anbernic RG353PS";
compatible = "anbernic,rg353ps", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts
index f49ce29ba597..e9954a33e8cd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts
@@ -8,7 +8,7 @@
#include "rk3566-anbernic-rg353x.dtsi"
/ {
- model = "RG353V";
+ model = "Anbernic RG353V";
compatible = "anbernic,rg353v", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353vs.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353vs.dts
index a7dc462fe21f..90da43855d1c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353vs.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353vs.dts
@@ -8,7 +8,7 @@
#include "rk3566-anbernic-rg353x.dtsi"
/ {
- model = "RG353VS";
+ model = "Anbernic RG353VS";
compatible = "anbernic,rg353vs", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
index 94e6dd61a2db..74cf313e0635 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
@@ -8,7 +8,7 @@
#include "rk3566-anbernic-rgxx3.dtsi"
/ {
- model = "RG503";
+ model = "Anbernic RG503";
compatible = "anbernic,rg503", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
index 18b8c2e7befa..233eade30f21 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
@@ -10,6 +10,8 @@
#include "rk3566.dtsi"
/ {
+ chassis-type = "handset";
+
chosen: chosen {
stdout-path = "serial2:1500000n8";
};
@@ -623,9 +625,12 @@
cap-sdio-irq;
keep-power-in-suspend;
mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
non-removable;
pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
pinctrl-names = "default";
+ sd-uhs-sdr50;
vmmc-supply = <&vcc_wifi>;
vqmmc-supply = <&vcca1v8_pmu>;
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v1.1.dts b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v1.1.dts
new file mode 100644
index 000000000000..074e93bd4b85
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v1.1.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-orangepi-3b.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 3B v1.1";
+ compatible = "xunlong,orangepi-3b-v1.1", "xunlong,orangepi-3b", "rockchip,rk3566";
+};
+
+&pmu_io_domains {
+ vccio5-supply = <&vcc_3v3>;
+};
+
+&gmac1 {
+ phy-handle = <&rgmii_phy1>;
+ status = "okay";
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v2.1.dts b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v2.1.dts
new file mode 100644
index 000000000000..d894bff41e61
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v2.1.dts
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-orangepi-3b.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 3B v2.1";
+ compatible = "xunlong,orangepi-3b-v2.1", "xunlong,orangepi-3b", "rockchip,rk3566";
+
+ vccio_phy1: regulator-1v8-vccio-phy {
+ compatible = "regulator-fixed";
+ regulator-name = "vccio_phy1";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ };
+};
+
+&pmu_io_domains {
+ vccio5-supply = <&vccio_phy1>;
+};
+
+&gmac1 {
+ phy-handle = <&rgmii_phy1>;
+ status = "okay";
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&sdmmc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ brcmf: wifi@1 {
+ compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD6 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_wake_host_h>;
+ };
+};
+
+&uart1 {
+ bluetooth {
+ compatible = "brcm,bcm4345c5";
+ clocks = <&rk809 1>;
+ clock-names = "lpo";
+ interrupt-parent = <&gpio2>;
+ interrupts = <RK_PC0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wakeup";
+ device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_reg_on_h &bt_wake_host_h &host_wake_bt_h>;
+ vbat-supply = <&vcc_3v3>;
+ vddio-supply = <&vcc_1v8>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
new file mode 100644
index 000000000000..d539570f531e
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
@@ -0,0 +1,678 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 3B";
+ compatible = "xunlong,orangepi-3b", "rockchip,rk3566";
+
+ aliases {
+ ethernet0 = &gmac1;
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ hdmi-con {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&work_led>;
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ vcc3v3_pcie30: regulator-3v3-vcc-pcie30 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie20_pwren>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ vcc3v3_sys: regulator-3v3-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: regulator-5v0-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_host_pwren_h>;
+ regulator-name = "vcc5v0_usb_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_usb_otg: regulator-5v0-vcc-usb-otg {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_otg_pwren_h>;
+ regulator-name = "vcc5v0_usb_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk809 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on_h>;
+ post-power-on-delay-ms = <200>;
+ power-off-delay-us = <5000000>;
+ reset-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_LOW>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Analog RK809";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&rk809>;
+ };
+ };
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&combphy2 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&gmac1 {
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
+ clock_in_out = "input";
+ phy-mode = "rgmii-id";
+ phy-supply = <&vcc_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m0_miim
+ &gmac1m0_tx_bus2
+ &gmac1m0_rx_bus2
+ &gmac1m0_rgmii_clk
+ &gmac1m0_rgmii_bus
+ &gmac1m0_clkinout>;
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vdda0v9_image>;
+ avdd-1v8-supply = <&vcca1v8_image>;
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+ #clock-cells = <1>;
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ clock-names = "mclk";
+ clock-output-names = "rk809-clkout1", "rk809-clkout2";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+ #sound-dai-cells = <0>;
+ system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc3v3_sys>;
+ vcc2-supply = <&vcc3v3_sys>;
+ vcc3-supply = <&vcc3v3_sys>;
+ vcc4-supply = <&vcc3v3_sys>;
+ vcc5-supply = <&vcc3v3_sys>;
+ vcc6-supply = <&vcc3v3_sys>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-name = "vdd_gpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdd_npu: DCDC_REG4 {
+ regulator-name = "vdd_npu";
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG5 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_image: LDO_REG1 {
+ regulator-name = "vdda0v9_image";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda0v9_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca_1v8: LDO_REG7 {
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG8 {
+ regulator-name = "vcca1v8_pmu";
+ 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>;
+ };
+ };
+
+ vcca1v8_image: LDO_REG9 {
+ regulator-name = "vcca1v8_image";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3: SWITCH_REG1 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: SWITCH_REG2 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ vdd_cpu: regulator@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <830000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc3v3_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&i2s1_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_sclktx
+ &i2s1m0_lrcktx
+ &i2s1m0_sdi0
+ &i2s1m0_sdo0>;
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&pcie2x1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie20_pins>;
+ reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ bluetooth {
+ bt_reg_on_h: bt-reg-on-h {
+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host_h: bt-wake-host-h {
+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ host_wake_bt_h: host-wake-bt-h {
+ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ work_led: work-led {
+ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie {
+ pcie20_pins: pcie20-pins {
+ rockchip,pins =
+ <1 RK_PB0 4 &pcfg_pull_none>,
+ <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>,
+ <1 RK_PB1 4 &pcfg_pull_none>;
+ };
+
+ pcie20_pwren: pcie20-pwren {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ usb_host_pwren_h: usb-host-pwren-h {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usb_otg_pwren_h: usb-otg-pwren-h {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_reg_on_h: wifi-reg-on-h {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_wake_host_h: wifi-wake-host-h {
+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio6-supply = <&vcc_3v3>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ mmc-hs200-1_8v;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sfc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ phy-supply = <&vcc5v0_usb_otg>;
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
+
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
index d899087bf0b5..ae2536c65a83 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
@@ -674,6 +674,7 @@
};
&uart1 {
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart1m0_ctsn>, <&uart1m0_rtsn>, <&uart1m0_xfer>;
pinctrl-names = "default";
uart-has-rtscts;
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
index 1f567a14ac84..952b1b285f3b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
@@ -8,7 +8,7 @@
#include "rk3566-powkiddy-rk2023.dtsi"
/ {
- model = "RGB30";
+ model = "Powkiddy RGB30";
compatible = "powkiddy,rgb30", "rockchip,rk3566";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
index bc9933d9e262..72890f747ee3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
@@ -8,7 +8,7 @@
#include "rk3566-powkiddy-rk2023.dtsi"
/ {
- model = "RK2023";
+ model = "Powkiddy RK2023";
compatible = "powkiddy,rk2023", "rockchip,rk3566";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
index 3ab751a01cb2..bd332714a023 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
@@ -10,6 +10,8 @@
#include "rk3566.dtsi"
/ {
+ chassis-type = "handset";
+
aliases {
mmc1 = &sdmmc0;
mmc2 = &sdmmc1;
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts
index 4786b19fd017..5a648db41f35 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts
@@ -11,6 +11,7 @@
/ {
model = "Powkiddy x55";
+ chassis-type = "handset";
compatible = "powkiddy,x55", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 59843a7a199c..37a1303d9a34 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -8,7 +8,7 @@
#include "rk3566.dtsi"
/ {
- model = "Pine64 RK3566 Quartz64-A Board";
+ model = "Pine64 Quartz64 Model A";
compatible = "pine64,quartz64-a", "rockchip,rk3566";
aliases {
@@ -738,6 +738,7 @@
};
&uart1 {
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
index 2d92713be2a0..13e599a85eb8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
@@ -8,7 +8,7 @@
#include "rk3566.dtsi"
/ {
- model = "Pine64 RK3566 Quartz64-B Board";
+ model = "Pine64 Quartz64 Model B";
compatible = "pine64,quartz64-b", "rockchip,rk3566";
aliases {
@@ -289,7 +289,7 @@
regulator-name = "vdd_gpu";
regulator-always-on;
regulator-boot-on;
- regulator-min-microvolt = <900000>;
+ regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
@@ -652,6 +652,7 @@
};
&uart1 {
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
new file mode 100644
index 000000000000..9cc7aa3298d0
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ hdmi-con {
+ compatible = "hdmi-connector";
+ type = "d";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led2>;
+
+ led-green {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ vcc_1v8: regulator-1v8-vcc {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_1v8_p>;
+ };
+
+ vcca_1v8: regulator-1v8-vcca {
+ compatible = "regulator-fixed";
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_1v8_p>;
+ };
+
+ vcca1v8_image: regulator-1v8-vcca-image {
+ compatible = "regulator-fixed";
+ regulator-name = "vcca1v8_image";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_1v8_p>;
+ };
+
+ vcc_3v3: regulator-3v3-vcc {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ vcc_sys: regulator-5v0-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&gpio0 {
+ gpio-line-names =
+ /* GPIO0_A0 - A7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO0_B0 - B7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO0_C0 - C7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO0_D0 - D7 */
+ "pin-10 [GPIO0_D0]", "pin-08 [GPIO0_D1]", "",
+ "", "", "", "", "";
+};
+
+&gpio1 {
+ gpio-line-names =
+ /* GPIO1_A0 - A7 */
+ "pin-03 [GPIO1_A0]", "pin-05 [GPIO1_A1]", "",
+ "", "pin-37 [GPIO1_A4]", "",
+ "", "",
+ /* GPIO1_B0 - B7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO1_C0 - C7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO1_D0 - D7 */
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+ gpio-line-names =
+ /* GPIO2_A0 - A7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO2_B0 - B7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO2_C0 - C7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO2_D0 - D7 */
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio3 {
+ gpio-line-names =
+ /* GPIO3_A0 - A7 */
+ "", "pin-11 [GPIO3_A1]", "pin-13 [GPIO3_A2]",
+ "pin-12 [GPIO3_A3]", "pin-35 [GPIO3_A4]", "pin-40 [GPIO3_A5]",
+ "pin-38 [GPIO3_A6]", "pin-36 [GPIO3_A7]",
+ /* GPIO3_B0 - B7 */
+ "pin-15 [GPIO3_B0]", "pin-16 [GPIO3_B1]", "pin-18 [GPIO3_B2]",
+ "pin-29 [GPIO3_B3]", "pin-31 [GPIO3_B4]", "",
+ "", "",
+ /* GPIO3_C0 - C7 */
+ "", "pin-22 [GPIO3_C1]", "pin-32 [GPIO3_C2]",
+ "pin-33 [GPIO3_C3]", "pin-07 [GPIO3_C4]", "",
+ "", "",
+ /* GPIO3_D0 - D7 */
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names =
+ /* GPIO4_A0 - A7 */
+ "", "", "", "", "", "", "", "",
+ /* GPIO4_B0 - B7 */
+ "", "", "pin-27 [GPIO4_B2]",
+ "pin-28 [GPIO4_B3]", "", "", "", "",
+ /* GPIO4_C0 - C7 */
+ "", "", "pin-23 [GPIO4_C2]",
+ "pin-19 [GPIO4_C3]", "", "pin-21 [GPIO4_C5]",
+ "pin-24 [GPIO4_C6]", "",
+ /* GPIO4_D0 - D7 */
+ "", "", "", "", "", "", "", "";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_npu>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vdda_0v9>;
+ avdd-1v8-supply = <&vcca1v8_image>;
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk817: pmic@20 {
+ compatible = "rockchip,rk817";
+ reg = <0x20>;
+ #clock-cells = <1>;
+ clock-output-names = "rk817-clkout1", "rk817-clkout2";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc5-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc_sys>;
+ vcc8-supply = <&vcc_sys>;
+ vcc9-supply = <&vcc5v_midu>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vdd_gpu_npu: DCDC_REG2 {
+ regulator-name = "vdd_gpu_npu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc3v3_sys: DCDC_REG4 {
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG1 {
+ regulator-name = "vcca1v8_pmu";
+ 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>;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda0v9_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_1v8_p: LDO_REG7 {
+ regulator-name = "vcc_1v8_p";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8_dvp: LDO_REG8 {
+ regulator-name = "vcc1v8_dvp";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc2v8_dvp: LDO_REG9 {
+ regulator-name = "vcc2v8_dvp";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc5v_midu: BOOST {
+ regulator-name = "vcc5v_midu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vbus: OTG_SWITCH {
+ regulator-name = "vbus";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ vdd_cpu: regulator@40 {
+ compatible = "rockchip,rk8600";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&pinctrl {
+ leds {
+ user_led2: user-led2 {
+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcca1v8_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_3v3>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8>;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ vmmc-supply = <&vcc3v3_sys>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
new file mode 100644
index 000000000000..4a830eb09f0b
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-radxa-zero-3.dtsi"
+
+/ {
+ model = "Radxa ZERO 3E";
+ compatible = "radxa,zero-3e", "rockchip,rk3566";
+
+ aliases {
+ ethernet0 = &gmac1;
+ mmc0 = &sdmmc0;
+ };
+};
+
+&gmac1 {
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
+ clock_in_out = "input";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&vcc_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m1_miim
+ &gmac1m1_tx_bus2
+ &gmac1m1_rx_bus2
+ &gmac1m1_rgmii_clk
+ &gmac1m1_rgmii_bus
+ &gmac1m1_clkinout>;
+ status = "okay";
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1_rstn>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ gmac1 {
+ gmac1_rstn: gmac1-rstn {
+ rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
new file mode 100644
index 000000000000..f92475c59deb
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-radxa-zero-3.dtsi"
+
+/ {
+ model = "Radxa ZERO 3W";
+ compatible = "radxa,zero-3w", "rockchip,rk3566";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on_h>;
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <5000000>;
+ reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ bluetooth {
+ bt_reg_on_h: bt-reg-on-h {
+ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host_h: bt-wake-host-h {
+ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ host_wake_bt_h: host-wake-bt-h {
+ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_reg_on_h: wifi-reg-on-h {
+ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_wake_host_h: wifi-wake-host-h {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ mmc-hs200-1_8v;
+ no-sd;
+ no-sdio;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
+ uart-has-rtscts;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
index 63eea27293fe..67e7801bd489 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
@@ -269,7 +269,7 @@
vcc9-supply = <&vcc3v3_sys>;
codec {
- mic-in-differential;
+ rockchip,mic-in-differential;
};
regulators {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
new file mode 100644
index 000000000000..f2cc086e5001
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -0,0 +1,726 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+ model = "Radxa ROCK 3C";
+ compatible = "radxa,rock-3c", "rockchip,rk3566";
+
+ aliases {
+ ethernet0 = &gmac1;
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ gmac1_clkin: external-gmac1-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "gmac1_clkin";
+ #clock-cells = <0>;
+ };
+
+ hdmi-con {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_BLUE>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led2>;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk809 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on_h>;
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <5000000>;
+ reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
+ };
+
+ vcc5v_dcin: vcc5v-dcin-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v_dcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc3v3_pcie: vcc3v3-pcie-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pwr_en>;
+ regulator-name = "vcc3v3_pcie";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ vcc3v3_sys: vcc3v3-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v_dcin>;
+ };
+
+ vcc5v0_usb30_host: vcc5v0-usb30-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb30_host_en>;
+ regulator-name = "vcc5v0_usb30_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb_otg_en>;
+ regulator-name = "vcc5v0_usb_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_cam: vcc-cam-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_cam_en>;
+ regulator-name = "vcc_cam";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_mipi: vcc-mipi-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_mipi_en>;
+ regulator-name = "vcc_mipi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&combphy2 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&gmac1 {
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
+ clock_in_out = "input";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&vcc_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m1_miim
+ &gmac1m1_tx_bus2
+ &gmac1m1_rx_bus2
+ &gmac1m1_rgmii_clk
+ &gmac1m1_rgmii_bus
+ &gmac1m1_clkinout>;
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vdda0v9_image>;
+ avdd-1v8-supply = <&vcca1v8_image>;
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+ system-power-controller;
+ vcc1-supply = <&vcc3v3_sys>;
+ vcc2-supply = <&vcc3v3_sys>;
+ vcc3-supply = <&vcc3v3_sys>;
+ vcc4-supply = <&vcc3v3_sys>;
+ vcc5-supply = <&vcc3v3_sys>;
+ vcc6-supply = <&vcc3v3_sys>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+ wakeup-source;
+ #clock-cells = <1>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-name = "vdd_gpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdd_npu: DCDC_REG4 {
+ regulator-name = "vdd_npu";
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG5 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_image: LDO_REG1 {
+ regulator-name = "vdda0v9_image";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda0v9_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca_1v8: LDO_REG7 {
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG8 {
+ regulator-name = "vcca1v8_pmu";
+ 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>;
+ };
+ };
+
+ vcca1v8_image: LDO_REG9 {
+ regulator-name = "vcca1v8_image";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3: SWITCH_REG1 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: SWITCH_REG2 {
+ regulator-name = "vcc3v3_sd";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "belling,bl24c16a", "atmel,24c16";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&i2s1_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_reset_h>;
+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie>;
+ status = "okay";
+};
+
+&pinctrl {
+ bluetooth {
+ bt_reg_on_h: bt-reg-on-h {
+ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host_h: bt-wake-host-h {
+ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_host_wake_h: bt-host-wake-h {
+ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ cam {
+ vcc_cam_en: vcc_cam_en {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ display {
+ vcc_mipi_en: vcc_mipi_en {
+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ user_led2: user-led2 {
+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie {
+ pcie_pwr_en: pcie-pwr-en {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie_reset_h: pcie-reset-h {
+ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ vcc5v0_usb30_host_en: vcc5v0-usb30-host-en {
+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
+ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_host_wake_h: wifi-host-wake-h {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_reg_on_h: wifi-reg-on-h {
+ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcca1v8_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcca1v8_pmu>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_3v3>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ mmc-hs200-1_8v;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ sd-uhs-sdr50;
+ vmmc-supply = <&vcc3v3_sys>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_sys>;
+ vqmmc-supply = <&vcca1v8_pmu>;
+ status = "okay";
+};
+
+&sfc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_ctsn &uart1m0_rtsn &uart1m0_xfer>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ phy-supply = <&vcc5v0_usb30_host>;
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ phy-supply = <&vcc5v0_usb_otg>;
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ phy-supply = <&vcc5v0_usb30_host>;
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ phy-supply = <&vcc5v0_usb30_host>;
+ status = "okay";
+};
+
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts
index fdbf1c783242..fdbb4a6a19d8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts
@@ -10,7 +10,7 @@
#include "rk3566-soquartz.dtsi"
/ {
- model = "PINE64 RK3566 SOQuartz on Blade carrier board";
+ model = "Pine64 SOQuartz on Blade carrier board";
compatible = "pine64,soquartz-blade", "pine64,soquartz", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts
index 6ed3fa4aee34..2b6f0df477b6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts
@@ -5,7 +5,7 @@
#include "rk3566-soquartz.dtsi"
/ {
- model = "Pine64 RK3566 SoQuartz with CM4-IO Carrier Board";
+ model = "Pine64 SOQuartz on CM4-IO carrier board";
compatible = "pine64,soquartz-cm4io", "pine64,soquartz", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts
index f2095dfa4eaf..9a6a63277c3d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts
@@ -5,7 +5,7 @@
#include "rk3566-soquartz.dtsi"
/ {
- model = "PINE64 RK3566 SOQuartz on Model A carrier board";
+ model = "Pine64 SOQuartz on Model A carrier board";
compatible = "pine64,soquartz-model-a", "pine64,soquartz", "rockchip,rk3566";
aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi
index bfb7b952f4c5..e42c474ef4ad 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi
@@ -8,7 +8,7 @@
#include "rk3566.dtsi"
/ {
- model = "Pine64 RK3566 SoQuartz SOM";
+ model = "Pine64 SOQuartz system on module";
compatible = "pine64,soquartz", "rockchip,rk3566";
aliases {
@@ -614,6 +614,7 @@
};
&uart1 {
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
uart-has-rtscts;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 19f8fc369b13..8c3ab07d3807 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -475,7 +475,7 @@
};
codec {
- mic-in-differential;
+ rockchip,mic-in-differential;
};
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts
index 58ab7e9971db..b5e67990dd0f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts
@@ -11,6 +11,10 @@
};
};
+&pmu_io_domains {
+ vccio3-supply = <&vccio_sd>;
+};
+
&sdmmc0 {
bus-width = <4>;
cap-mmc-highspeed;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi
index 89e84e3a9262..25c49bdbadbc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi
@@ -39,9 +39,9 @@
};
};
- dc_12v: dc-12v-regulator {
+ vcc12v_dcin: vcc12v-dcin-regulator {
compatible = "regulator-fixed";
- regulator-name = "dc_12v";
+ regulator-name = "vcc12v_dcin";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <12000000>;
@@ -65,7 +65,7 @@
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- vin-supply = <&dc_12v>;
+ vin-supply = <&vcc12v_dcin>;
};
vcc5v0_sys: vcc5v0-sys-regulator {
@@ -75,16 +75,7 @@
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- vin-supply = <&dc_12v>;
- };
-
- vcc5v0_usb_host: vcc5v0-usb-host-regulator {
- compatible = "regulator-fixed";
- regulator-name = "vcc5v0_usb_host";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_dcin>;
};
vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
@@ -94,8 +85,9 @@
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_usb_otg_en>;
regulator-name = "vcc5v0_usb_otg";
- regulator-always-on;
- regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
};
};
@@ -123,6 +115,10 @@
cpu-supply = <&vdd_cpu>;
};
+&display_subsystem {
+ status = "disabled";
+};
+
&gpu {
mali-supply = <&vdd_gpu>;
status = "okay";
@@ -405,8 +401,8 @@
&pmu_io_domains {
pmuio1-supply = <&vcc3v3_pmu>;
pmuio2-supply = <&vcc3v3_pmu>;
- vccio1-supply = <&vccio_acodec>;
- vccio3-supply = <&vccio_sd>;
+ vccio1-supply = <&vcc_3v3>;
+ vccio2-supply = <&vcc_1v8>;
vccio4-supply = <&vcc_1v8>;
vccio5-supply = <&vcc_3v3>;
vccio6-supply = <&vcc_1v8>;
@@ -429,28 +425,12 @@
status = "okay";
};
-&usb_host0_ehci {
- status = "okay";
-};
-
-&usb_host0_ohci {
- status = "okay";
-};
-
&usb_host0_xhci {
dr_mode = "host";
extcon = <&usb2phy0>;
status = "okay";
};
-&usb_host1_ehci {
- status = "okay";
-};
-
-&usb_host1_ohci {
- status = "okay";
-};
-
&usb_host1_xhci {
status = "okay";
};
@@ -460,7 +440,7 @@
};
&usb2phy0_host {
- phy-supply = <&vcc5v0_usb_host>;
+ phy-supply = <&vcc5v0_sys>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts
index e1fe5e442689..ce2a5e1ccefc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts
@@ -39,7 +39,7 @@
&gmac0_rx_bus2
&gmac0_rgmii_clk
&gmac0_rgmii_bus>;
- snps,reset-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
+ snps,reset-gpio = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 15ms, 50ms for rtl8211f */
snps,reset-delays-us = <0 15000 50000>;
@@ -61,7 +61,7 @@
&gmac1m1_rx_bus2
&gmac1m1_rgmii_clk
&gmac1m1_rgmii_bus>;
- snps,reset-gpio = <&gpio0 RK_PB1 GPIO_ACTIVE_LOW>;
+ snps,reset-gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 15ms, 50ms for rtl8211f */
snps,reset-delays-us = <0 15000 50000>;
@@ -71,18 +71,18 @@
};
&mdio0 {
- rgmii_phy0: ethernet-phy@0 {
+ rgmii_phy0: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
- reg = <0>;
+ reg = <0x1>;
pinctrl-0 = <&eth_phy0_reset_pin>;
pinctrl-names = "default";
};
};
&mdio1 {
- rgmii_phy1: ethernet-phy@0 {
+ rgmii_phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
- reg = <0>;
+ reg = <0x1>;
pinctrl-0 = <&eth_phy1_reset_pin>;
pinctrl-names = "default";
};
@@ -102,6 +102,10 @@
};
};
+&pmu_io_domains {
+ vccio3-supply = <&vcc_3v3>;
+};
+
&sdhci {
bus-width = <8>;
max-frequency = <200000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
new file mode 100644
index 000000000000..c2dfffc638d1
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3568.dtsi"
+
+/ {
+ model = "Protonic MECSBC";
+ compatible = "prt,mecsbc", "rockchip,rk3568";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ tas2562-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Speaker";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&tas2562>;
+ };
+ };
+
+ vdd_gpu: regulator-vdd-gpu {
+ compatible = "pwm-regulator";
+ pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <915000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-settling-time-up-us = <250>;
+ pwm-dutycycle-range = <0 100>; /* dutycycle inverted 0% => 0.915V */
+ };
+
+ p3v3: regulator-p3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "p3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ p1v8: regulator-p1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "p1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc_sd: regulator-sd {
+ compatible = "regulator-gpio";
+ enable-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ regulator-name = "sdcard-gpio-supply";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ states = <1800000 0x1>, <3300000 0x0>;
+ };
+
+ vdd_npu: regulator-vdd-npu {
+ compatible = "pwm-regulator";
+ pwms = <&pwm2 0 5000 PWM_POLARITY_INVERTED>;
+ regulator-name = "vdd_npu";
+ regulator-min-microvolt = <915000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-settling-time-up-us = <250>;
+ pwm-dutycycle-range = <0 100>; /* dutycycle inverted 0% => 0.915V */
+ };
+};
+
+&combphy0 {
+ status = "okay";
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&combphy2 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&gmac1 {
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-id";
+ clock_in_out = "output";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m1_miim
+ &gmac1m1_tx_bus2
+ &gmac1m1_rx_bus2
+ &gmac1m1_rgmii_clk
+ &gmac1m1_clkinout
+ &gmac1m1_rgmii_bus>;
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&gpu_opp_table {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <915000>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <915000>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <915000>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <920000>;
+ };
+
+ opp-700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <950000>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1000000>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ vdd_cpu: regulator@60 {
+ compatible = "fcs,fan53555";
+ reg = <0x60>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <2300>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2m0_xfer>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3m0_xfer>;
+ status = "okay";
+
+ tas2562: amplifier@4c {
+ compatible = "ti,tas2562";
+ reg = <0x4c>;
+ #sound-dai-cells = <0>;
+ shutdown-gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>;
+ interrupt-parent = <&gpio1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tas2562>;
+ interrupts = <RK_PD1 IRQ_TYPE_LEVEL_LOW>;
+ ti,imon-slot-no = <0>;
+ };
+};
+
+&i2c5 {
+ status = "okay";
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp1075";
+ reg = <0x48>;
+ };
+
+ rtc@51 {
+ compatible = "nxp,pcf85363";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "rtcic_32kout";
+ };
+};
+
+&i2s1_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_phy1_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie20m1_pins>;
+ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x2m1_pins>;
+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&p3v3>;
+ status = "okay";
+};
+
+&pinctrl {
+ ethernet {
+ eth_phy1_rst: eth-phy1-rst {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ tas2562 {
+ pinctrl_tas2562: tas2562 {
+ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&p3v3>;
+ pmuio2-supply = <&p3v3>;
+ vccio1-supply = <&p1v8>;
+ vccio2-supply = <&p1v8>;
+ vccio3-supply = <&vcc_sd>;
+ vccio4-supply = <&p1v8>;
+ vccio5-supply = <&p3v3>;
+ vccio6-supply = <&p1v8>;
+ vccio7-supply = <&p3v3>;
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1m0_pins>;
+};
+
+&pwm2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2m0_pins>;
+};
+
+&saradc {
+ vref-supply = <&p1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ vmmc-supply = <&p3v3>;
+ vqmmc-supply = <&p1v8>;
+ mmc-hs200-1_8v;
+ non-removable;
+ no-sd;
+ no-sdio;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&p3v3>;
+ vqmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ dr_mode = "host";
+ extcon = <&usb2phy0>;
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
index a5e974ea659e..59f1403b4fa5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
@@ -8,7 +8,7 @@
#include "rk3568.dtsi"
/ {
- model = "Radxa ROCK3 Model A";
+ model = "Radxa ROCK 3A";
compatible = "radxa,rock3a", "rockchip,rk3568";
aliases {
@@ -531,10 +531,6 @@
};
};
};
-
- codec {
- mic-in-differential;
- };
};
};
@@ -757,6 +753,20 @@
status = "okay";
};
+&sfc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
&tsadc {
rockchip,hw-tshut-mode = <1>;
rockchip,hw-tshut-polarity = <0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
new file mode 100644
index 000000000000..3d0c1ccfaa79
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
@@ -0,0 +1,781 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3568.dtsi"
+
+/ {
+ model = "Radxa ROCK 3B";
+ compatible = "radxa,rock-3b", "rockchip,rk3568";
+
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ hdmi-con {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_ir>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led>;
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ /* pi6c pcie clock generator */
+ vcc3v3_pi6c_03: regulator-3v3-vcc-pi6c-03 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pwren_h>;
+ regulator-name = "vcc3v3_pi6c_03";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <10000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_sys: regulator-3v3-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_sys2: regulator-3v3-vcc-sys2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys2";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: regulator-5v0-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_host_pwren_h>;
+ regulator-name = "vcc5v0_usb_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_usb_otg: regulator-5v0-vcc-usb-otg {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_otg_pwren_h>;
+ regulator-name = "vcc5v0_usb_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk809 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on_h>;
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <5000000>;
+ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Analog RK809";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&rk809>;
+ };
+ };
+};
+
+&combphy0 {
+ status = "okay";
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&combphy2 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&gmac0 {
+ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+ clock_in_out = "input";
+ phy-handle = <&rgmii_phy0>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&vcc_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus
+ &gmac0_clkinout>;
+ status = "okay";
+};
+
+&gmac1 {
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
+ clock_in_out = "input";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&vcc_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m1_miim
+ &gmac1m1_tx_bus2
+ &gmac1m1_rx_bus2
+ &gmac1m1_rgmii_clk
+ &gmac1m1_rgmii_bus
+ &gmac1m1_clkinout>;
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vdda0v9_image>;
+ avdd-1v8-supply = <&vcca1v8_image>;
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+ #clock-cells = <1>;
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ clock-names = "mclk";
+ clock-output-names = "rk809-clkout1", "rk809-clkout2";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+ #sound-dai-cells = <0>;
+ system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc3v3_sys>;
+ vcc2-supply = <&vcc3v3_sys>;
+ vcc3-supply = <&vcc3v3_sys>;
+ vcc4-supply = <&vcc3v3_sys>;
+ vcc5-supply = <&vcc3v3_sys>;
+ vcc6-supply = <&vcc3v3_sys>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-name = "vdd_gpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdd_npu: DCDC_REG4 {
+ regulator-name = "vdd_npu";
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG5 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_image: LDO_REG1 {
+ regulator-name = "vdda0v9_image";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda0v9_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca_1v8: LDO_REG7 {
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG8 {
+ regulator-name = "vcca1v8_pmu";
+ 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>;
+ };
+ };
+
+ vcca1v8_image: LDO_REG9 {
+ regulator-name = "vcca1v8_image";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3: SWITCH_REG1 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: SWITCH_REG2 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c5 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+ clock-output-names = "rtcic_32kout";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtcic_int_l>;
+ wakeup-source;
+ };
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&i2s1_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_sclktx
+ &i2s1m0_lrcktx
+ &i2s1m0_sdi0
+ &i2s1m0_sdo0>;
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&mdio0 {
+ rgmii_phy0: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie20m1_pins>;
+ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_sys2>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x2m1_pins>;
+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pinctrl {
+ bluetooth {
+ bt_reg_on_h: bt-reg-on-h {
+ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host_h: bt-wake-host-h {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ host_wake_bt_h: host-wake-bt-h {
+ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ ir-receiver {
+ pwm3_ir: pwm3-ir {
+ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ led: led {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie {
+ pcie_pwren_h: pcie-pwren-h {
+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie20 {
+ pcie20m1_pins: pcie20m1-pins {
+ rockchip,pins =
+ <2 RK_PD0 4 &pcfg_pull_none>,
+ <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>,
+ <2 RK_PD1 4 &pcfg_pull_none>;
+ };
+ };
+
+ pcie30x2 {
+ pcie30x2m1_pins: pcie30x2m1-pins {
+ rockchip,pins =
+ <2 RK_PD4 4 &pcfg_pull_none>,
+ <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>,
+ <2 RK_PD5 4 &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ rtc {
+ rtcic_int_l: rtcic-int-l {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ usb_host_pwren_h: usb-host-pwren-h {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usb_otg_pwren_h: usb-otg-pwren-h {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_reg_on_h: wifi-reg-on-h {
+ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_wake_host_h: wifi-wake-host-h {
+ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_1v8>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ mmc-hs200-1_8v;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdmmc2 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_sys2>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "disabled";
+};
+
+&sfc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn &uart8m0_rtsn>;
+ uart-has-rtscts;
+ status = "disabled";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ extcon = <&usb2phy0>;
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ phy-supply = <&vcc5v0_usb_otg>;
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
+
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso
new file mode 100644
index 000000000000..ebcaeafc3800
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Device tree overlay for the WolfVision PF5 IO Expander board.
+ *
+ * Copyright (C) 2024 WolfVision GmbH.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/rk3568-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+&{/} {
+ gmac0_clkin: external-gmac0-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ clock-output-names = "gmac0_clkin";
+ #clock-cells = <0>;
+ };
+
+ usb_host_vbus: usb-host-vbus-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_host_vbus_en>;
+ regulator-name = "usb_host_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v_in>;
+ };
+
+ vcc1v8_eth: vcc1v8-eth-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc1v8_eth_en>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "1v8_eth";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ vcc3v3_eth: vcc3v3-eth-regulator {
+ compatible = "regulator-fixed";
+ enable-active-low;
+ gpio = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_eth_enn>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "3v3_eth";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+};
+
+&gmac0 {
+ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>,
+ <&cru SCLK_GMAC0>;
+ assigned-clock-parents = <&cru SCLK_GMAC0_RMII_SPEED>,
+ <&gmac0_clkin>;
+ clock_in_out = "input";
+ phy-handle = <&dp83826>;
+ phy-mode = "rmii";
+ phy-supply = <&vcc3v3_eth>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_clkinout
+ &gmac0_rx_er
+ &gmac0_rx_bus2
+ &gmac0_tx_bus2>;
+ status = "okay";
+};
+
+&mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dp83826: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD3 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_wake_intn &eth_phy_rstn>;
+ reset-assert-us = <1000>;
+ reset-deassert-us = <2000>;
+ reset-gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+};
+
+&pinctrl {
+ ethernet {
+ eth_wake_intn: eth-wake-intn-pinctrl {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ eth_phy_rstn: eth-phy-rstn-pinctrl {
+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc1v8_eth_en: vcc1v8-eth-en-pinctrl {
+ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc3v3_eth_enn: vcc3v3-eth-enn-pinctrl {
+ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ usb_host_vbus_en: usb-host-vbus-en-pinctrl {
+ rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&usb_host1_xhci {
+ maximum-speed = "high-speed";
+ phys = <&usb2phy0_host>;
+ phy-names = "usb2-phy";
+ status = "okay";
+};
+
+&usb2phy0_host {
+ phy-supply = <&usb_host_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
new file mode 100644
index 000000000000..170b14f92f51
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Device tree for the WolfVision PF5 mainboard.
+ *
+ * Copyright (C) 2024 WolfVision GmbH.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/regulator/ti,tps62864.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3568.dtsi"
+
+/ {
+ model = "WolfVision PF5";
+ compatible = "wolfvision,rk3568-pf5", "rockchip,rk3568";
+
+ aliases {
+ ethernet0 = &gmac0;
+ mmc0 = &sdhci;
+ rtc0 = &pcf85623;
+ rtc1 = &rk809;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ hdmi_tx: hdmi-tx-connector {
+ compatible = "hdmi-connector";
+ hdmi-pwr-supply = <&hdmi_tx_5v>;
+ type = "a";
+
+ port {
+ hdmi_tx_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
+ hdmi_tx_5v: hdmi-tx-5v-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_tx_5v_en>;
+ regulator-name = "hdmi_tx_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v_in>;
+ };
+
+ pdm_codec: pdm-codec {
+ compatible = "dmic-codec";
+ num-channels = <1>;
+ #sound-dai-cells = <0>;
+ };
+
+ pdm_sound: pdm-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "microphone";
+
+ simple-audio-card,cpu {
+ sound-dai = <&pdm>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&pdm_codec>;
+ };
+ };
+
+ vcc12v_cam: vcc12v-cam-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc12v_cam_en>;
+ regulator-name = "12v_cam";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ vin-supply = <&vcc12v_in>;
+ };
+
+ vcc12v_in: vcc12v-in-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "12v_in";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc3v8_cam: vcc3v8-cam-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v8_cam_en>;
+ regulator-name = "3v8_cam";
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ vin-supply = <&vcc5v_in>;
+ };
+
+ vcc3v3_sys: vcc3v3-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v_in>;
+ };
+
+ vcc5v_in: vcc5v-in-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "5v_in";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_in>;
+ };
+};
+
+&combphy0 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vcc0v9_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vcc0v9_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vcc0v9_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vcc0v9_cpu>;
+};
+
+&gpu {
+ mali-supply = <&vcc0v9_gpu>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vcc0v9a_image>;
+ avdd-1v8-supply = <&vcc1v8a_image>;
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_tx_in>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ vcc1-supply = <&vcc5v_in>;
+ vcc2-supply = <&vcc5v_in>;
+ vcc3-supply = <&vcc5v_in>;
+ vcc4-supply = <&vcc5v_in>;
+ vcc5-supply = <&vcc3v3_sys>;
+ vcc6-supply = <&vcc5v_in>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+ wakeup-source;
+
+ regulators {
+ vcc0v9_logic: DCDC_REG1 {
+ regulator-name = "0v9_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc0v9_gpu: DCDC_REG2 {
+ regulator-name = "0v9_gpu";
+ regulator-always-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v1_ddr4: DCDC_REG3 {
+ regulator-name = "1v1_ddr4";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc0v9_npu: DCDC_REG4 {
+ regulator-name = "0v9_npu";
+ regulator-always-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8: DCDC_REG5 {
+ regulator-name = "1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc0v9a_image: LDO_REG1 {
+ regulator-name = "0v9a_image";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc0v9a: LDO_REG2 {
+ regulator-name = "0v9a";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc0v9a_pmu: LDO_REG3 {
+ regulator-name = "0v9a_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vcc3v3_acodec: LDO_REG4 {
+ regulator-name = "3v3_acodec";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: LDO_REG5 {
+ regulator-name = "3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc1v8a: LDO_REG7 {
+ regulator-name = "1v8a";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8a_pmu: LDO_REG8 {
+ regulator-name = "1v8a_pmu";
+ 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>;
+ };
+ };
+
+ vcc1v8a_image: LDO_REG9 {
+ regulator-name = "1v8a_image";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sw: SWITCH_REG1 {
+ regulator-name = "3v3_sw";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ regulator@42 {
+ compatible = "ti,tps62869";
+ reg = <0x42>;
+
+ regulators {
+ vcc0v9_cpu: SW {
+ regulator-name = "0v9_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <TPS62864_MODE_FPWM>;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1150000>;
+ vin-supply = <&vcc5v_in>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ pcf85623: rtc@51 {
+ compatible = "nxp,pcf85263";
+ reg = <0x51>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&clk32k_in>;
+ quartz-load-femtofarads = <12500>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3m0_xfer>;
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4m1_xfer>;
+};
+
+&pdm {
+ pinctrl-0 = <&pdmm0_clk
+ &pdmm0_sdi0>;
+ status = "okay";
+};
+
+&pinctrl {
+ cam {
+ vcc12v_cam_en: vcc12v-cam-en-pinctrl {
+ rockchip,pins = <2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc3v8_cam_en: vcc3v8-cam-en-pinctrl {
+ rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hdmitx {
+ hdmi_tx_5v_en: hdmi-tx-5v-en-pinctrl {
+ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l-pinctrl {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vcc3v3_acodec>;
+ vccio2-supply = <&vcc1v8>;
+ vccio3-supply = <&vcc3v3_sd>;
+ vccio4-supply = <&vcc1v8>;
+ vccio5-supply = <&vcc1v8>;
+ vccio6-supply = <&vcc3v3_sw>;
+ vccio7-supply = <&vcc3v3_sw>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc1v8a>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ vmmc-supply = <&vcc3v3_sw>;
+ vqmmc-supply = <&vcc1v8>;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ dr_mode = "peripheral";
+ /* The following quirks are required since the bInterval is 1 and we
+ * handle steady ISOC streaming. See Usecase 3 in commit 729dcffd1ed3
+ * ("usb: dwc3: gadget: Add support for disabling U1 and U2 entries").
+ */
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ /*
+ * Without this quirk the available fifosize seems to be miscalculated
+ * in cases where many endpoints are used. In one particular situation
+ * 8 IN EPs and 3 OUT EPs where selected and lead to stalled transfers
+ * without the resize quirk.
+ */
+ tx-fifo-resize;
+
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP2>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 92f96ec01385..4690be841a1c 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -57,6 +57,13 @@
#cooling-cells = <2>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l3_cache>;
};
cpu1: cpu@100 {
@@ -66,6 +73,13 @@
#cooling-cells = <2>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l3_cache>;
};
cpu2: cpu@200 {
@@ -75,6 +89,13 @@
#cooling-cells = <2>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l3_cache>;
};
cpu3: cpu@300 {
@@ -84,9 +105,29 @@
#cooling-cells = <2>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l3_cache>;
};
};
+ /*
+ * There are no private per-core L2 caches, but only the
+ * L3 cache that appears to the CPU cores as L2 caches
+ */
+ l3_cache: l3-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ };
+
cpu0_opp_table: opp-table-0 {
compatible = "operating-points-v2";
opp-shared;
@@ -154,32 +195,32 @@
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
- opp-microvolt = <825000>;
+ opp-microvolt = <850000 850000 1000000>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
- opp-microvolt = <825000>;
+ opp-microvolt = <850000 850000 1000000>;
};
opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
- opp-microvolt = <825000>;
+ opp-microvolt = <850000 850000 1000000>;
};
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <825000>;
+ opp-microvolt = <900000 900000 1000000>;
};
opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <950000 950000 1000000>;
};
opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
- opp-microvolt = <1000000>;
+ opp-microvolt = <1000000 1000000 1000000>;
};
};
@@ -749,6 +790,7 @@
clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
clock-names = "aclk", "iface";
#iommu-cells = <0>;
+ power-domains = <&power RK3568_PD_VO>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
new file mode 100644
index 000000000000..c667704ba985
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
@@ -0,0 +1,725 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "ArmSoM Sige7";
+ compatible = "armsom,sige7", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ analog-sound {
+ compatible = "audio-graph-card";
+ dais = <&i2s0_8ch_p0>;
+ label = "rk3588-es8316";
+ hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_detect>;
+ routing = "MIC2", "Mic Jack",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR";
+ widgets = "Microphone", "Mic Jack",
+ "Headphone", "Headphones";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_rgb_g>;
+
+ led_green: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led_red: led-1 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ };
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 95 145 195 255>;
+ fan-supply = <&vcc5v0_sys>;
+ pwms = <&pwm1 0 50000 0>;
+ #cooling-cells = <2>;
+ };
+
+ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ wakeup-source;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ es8316: audio-codec@11 {
+ compatible = "everest,es8316";
+ reg = <0x11>;
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+
+ port {
+ es8316_p0_0: endpoint {
+ remote-endpoint = <&i2s0_8ch_p0_0>;
+ };
+ };
+ };
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+
+ i2s0_8ch_p0: port {
+ i2s0_8ch_p0_0: endpoint {
+ dai-format = "i2s";
+ mclk-fs = <256>;
+ remote-endpoint = <&es8316_p0_0>;
+ };
+ };
+};
+
+/* phy1 - right ethernet port */
+&pcie2x1l0 {
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+/* phy2 - WiFi */
+&pcie2x1l1 {
+ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+/* phy0 - left ethernet port */
+&pcie2x1l2 {
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ led_rgb_g: led-rgb-g {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ led_rgb_r: led-rgb-r {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ mmc-hs200-1_8v;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <200000000>;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ system-power-controller;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&usbdp_phy1 {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
index 30db12c4fc82..30db12c4fc82 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
new file mode 100644
index 000000000000..b6e4df180f0b
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -0,0 +1,2799 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/clock/rockchip,rk3588-cru.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/power/rk3588-power.h>
+#include <dt-bindings/reset/rockchip,rk3588-cru.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/ata/ahci.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ compatible = "rockchip,rk3588";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ i2c7 = &i2c7;
+ i2c8 = &i2c8;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ serial6 = &uart6;
+ serial7 = &uart7;
+ serial8 = &uart8;
+ serial9 = &uart9;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ spi3 = &spi3;
+ spi4 = &spi4;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu_l0>;
+ };
+ core1 {
+ cpu = <&cpu_l1>;
+ };
+ core2 {
+ cpu = <&cpu_l2>;
+ };
+ core3 {
+ cpu = <&cpu_l3>;
+ };
+ };
+ cluster1 {
+ core0 {
+ cpu = <&cpu_b0>;
+ };
+ core1 {
+ cpu = <&cpu_b1>;
+ };
+ };
+ cluster2 {
+ core0 {
+ cpu = <&cpu_b2>;
+ };
+ core1 {
+ cpu = <&cpu_b3>;
+ };
+ };
+ };
+
+ cpu_l0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <530>;
+ clocks = <&scmi_clk SCMI_CLK_CPUL>;
+ assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
+ assigned-clock-rates = <816000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l0>;
+ dynamic-power-coefficient = <228>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_l1: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x100>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <530>;
+ clocks = <&scmi_clk SCMI_CLK_CPUL>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l1>;
+ dynamic-power-coefficient = <228>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_l2: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x200>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <530>;
+ clocks = <&scmi_clk SCMI_CLK_CPUL>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l2>;
+ dynamic-power-coefficient = <228>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_l3: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x300>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <530>;
+ clocks = <&scmi_clk SCMI_CLK_CPUL>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <32768>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_cache_l3>;
+ dynamic-power-coefficient = <228>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_b0: cpu@400 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a76";
+ reg = <0x400>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+ assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+ assigned-clock-rates = <816000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <65536>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <65536>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_cache_b0>;
+ dynamic-power-coefficient = <416>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_b1: cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a76";
+ reg = <0x500>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <65536>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <65536>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_cache_b1>;
+ dynamic-power-coefficient = <416>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_b2: cpu@600 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a76";
+ reg = <0x600>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+ assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+ assigned-clock-rates = <816000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <65536>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <65536>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_cache_b2>;
+ dynamic-power-coefficient = <416>;
+ #cooling-cells = <2>;
+ };
+
+ cpu_b3: cpu@700 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a76";
+ reg = <0x700>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ i-cache-size = <65536>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <65536>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_cache_b3>;
+ dynamic-power-coefficient = <416>;
+ #cooling-cells = <2>;
+ };
+
+ idle-states {
+ entry-method = "psci";
+ CPU_SLEEP: cpu-sleep {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ arm,psci-suspend-param = <0x0010000>;
+ entry-latency-us = <100>;
+ exit-latency-us = <120>;
+ min-residency-us = <1000>;
+ };
+ };
+
+ l2_cache_l0: l2-cache-l0 {
+ compatible = "cache";
+ cache-size = <131072>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l1: l2-cache-l1 {
+ compatible = "cache";
+ cache-size = <131072>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l2: l2-cache-l2 {
+ compatible = "cache";
+ cache-size = <131072>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_l3: l2-cache-l3 {
+ compatible = "cache";
+ cache-size = <131072>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_b0: l2-cache-b0 {
+ compatible = "cache";
+ cache-size = <524288>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_b1: l2-cache-b1 {
+ compatible = "cache";
+ cache-size = <524288>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_b2: l2-cache-b2 {
+ compatible = "cache";
+ cache-size = <524288>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l2_cache_b3: l2-cache-b3 {
+ compatible = "cache";
+ cache-size = <524288>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3_cache>;
+ };
+
+ l3_cache: l3-cache {
+ compatible = "cache";
+ cache-size = <3145728>;
+ cache-line-size = <64>;
+ cache-sets = <4096>;
+ cache-level = <3>;
+ cache-unified;
+ };
+ };
+
+ display_subsystem: display-subsystem {
+ compatible = "rockchip,display-subsystem";
+ ports = <&vop_out>;
+ };
+
+ firmware {
+ optee: optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+
+ scmi: scmi {
+ compatible = "arm,scmi-smc";
+ arm,smc-id = <0x82000010>;
+ shmem = <&scmi_shmem>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_clk: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
+ scmi_reset: protocol@16 {
+ reg = <0x16>;
+ #reset-cells = <1>;
+ };
+ };
+ };
+
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
+ };
+
+ pmu-a76 {
+ compatible = "arm,cortex-a76-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ spll: clock-0 {
+ compatible = "fixed-clock";
+ clock-frequency = <702000000>;
+ clock-output-names = "spll";
+ #clock-cells = <0>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
+ };
+
+ xin24m: clock-1 {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ xin32k: clock-2 {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ #clock-cells = <0>;
+ };
+
+ pmu_sram: sram@10f000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x0010f000 0x0 0x100>;
+ ranges = <0 0x0 0x0010f000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scmi_shmem: sram@0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0x100>;
+ };
+ };
+
+ gpu: gpu@fb000000 {
+ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+ reg = <0x0 0xfb000000 0x0 0x200000>;
+ #cooling-cells = <2>;
+ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+ assigned-clock-rates = <200000000>;
+ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
+ <&cru CLK_GPU_STACKS>;
+ clock-names = "core", "coregroup", "stacks";
+ dynamic-power-coefficient = <2982>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "job", "mmu", "gpu";
+ power-domains = <&power RK3588_PD_GPU>;
+ status = "disabled";
+ };
+
+ usb_host0_xhci: usb@fc000000 {
+ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+ reg = <0x0 0xfc000000 0x0 0x400000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
+ <&cru ACLK_USB3OTG0>;
+ clock-names = "ref_clk", "suspend_clk", "bus_clk";
+ dr_mode = "otg";
+ phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ phy_type = "utmi_wide";
+ power-domains = <&power RK3588_PD_USB>;
+ resets = <&cru SRST_A_USB3OTG0>;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ status = "disabled";
+ };
+
+ usb_host0_ehci: usb@fc800000 {
+ compatible = "rockchip,rk3588-ehci", "generic-ehci";
+ reg = <0x0 0xfc800000 0x0 0x40000>;
+ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
+ phys = <&u2phy2_host>;
+ phy-names = "usb";
+ power-domains = <&power RK3588_PD_USB>;
+ status = "disabled";
+ };
+
+ usb_host0_ohci: usb@fc840000 {
+ compatible = "rockchip,rk3588-ohci", "generic-ohci";
+ reg = <0x0 0xfc840000 0x0 0x40000>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
+ phys = <&u2phy2_host>;
+ phy-names = "usb";
+ power-domains = <&power RK3588_PD_USB>;
+ status = "disabled";
+ };
+
+ usb_host1_ehci: usb@fc880000 {
+ compatible = "rockchip,rk3588-ehci", "generic-ehci";
+ reg = <0x0 0xfc880000 0x0 0x40000>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
+ phys = <&u2phy3_host>;
+ phy-names = "usb";
+ power-domains = <&power RK3588_PD_USB>;
+ status = "disabled";
+ };
+
+ usb_host1_ohci: usb@fc8c0000 {
+ compatible = "rockchip,rk3588-ohci", "generic-ohci";
+ reg = <0x0 0xfc8c0000 0x0 0x40000>;
+ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
+ phys = <&u2phy3_host>;
+ phy-names = "usb";
+ power-domains = <&power RK3588_PD_USB>;
+ status = "disabled";
+ };
+
+ usb_host2_xhci: usb@fcd00000 {
+ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+ reg = <0x0 0xfcd00000 0x0 0x400000>;
+ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
+ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
+ <&cru CLK_PIPEPHY2_PIPE_U3_G>;
+ clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
+ dr_mode = "host";
+ phys = <&combphy2_psu PHY_TYPE_USB3>;
+ phy-names = "usb3-phy";
+ phy_type = "utmi_wide";
+ resets = <&cru SRST_A_USB3OTG2>;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ snps,dis_rxdet_inp3_quirk;
+ status = "disabled";
+ };
+
+ mmu600_pcie: iommu@fc900000 {
+ compatible = "arm,smmu-v3";
+ reg = <0x0 0xfc900000 0x0 0x200000>;
+ interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ mmu600_php: iommu@fcb00000 {
+ compatible = "arm,smmu-v3";
+ reg = <0x0 0xfcb00000 0x0 0x200000>;
+ interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
+ };
+
+ sys_grf: syscon@fd58c000 {
+ compatible = "rockchip,rk3588-sys-grf", "syscon";
+ reg = <0x0 0xfd58c000 0x0 0x1000>;
+ };
+
+ vop_grf: syscon@fd5a4000 {
+ compatible = "rockchip,rk3588-vop-grf", "syscon";
+ reg = <0x0 0xfd5a4000 0x0 0x2000>;
+ };
+
+ vo0_grf: syscon@fd5a6000 {
+ compatible = "rockchip,rk3588-vo-grf", "syscon";
+ reg = <0x0 0xfd5a6000 0x0 0x2000>;
+ clocks = <&cru PCLK_VO0GRF>;
+ };
+
+ vo1_grf: syscon@fd5a8000 {
+ compatible = "rockchip,rk3588-vo-grf", "syscon";
+ reg = <0x0 0xfd5a8000 0x0 0x100>;
+ clocks = <&cru PCLK_VO1GRF>;
+ };
+
+ usb_grf: syscon@fd5ac000 {
+ compatible = "rockchip,rk3588-usb-grf", "syscon";
+ reg = <0x0 0xfd5ac000 0x0 0x4000>;
+ };
+
+ php_grf: syscon@fd5b0000 {
+ compatible = "rockchip,rk3588-php-grf", "syscon";
+ reg = <0x0 0xfd5b0000 0x0 0x1000>;
+ };
+
+ pipe_phy0_grf: syscon@fd5bc000 {
+ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfd5bc000 0x0 0x100>;
+ };
+
+ pipe_phy2_grf: syscon@fd5c4000 {
+ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfd5c4000 0x0 0x100>;
+ };
+
+ usbdpphy0_grf: syscon@fd5c8000 {
+ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+ reg = <0x0 0xfd5c8000 0x0 0x4000>;
+ };
+
+ usb2phy0_grf: syscon@fd5d0000 {
+ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd5d0000 0x0 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ u2phy0: usb2phy@0 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x0 0x10>;
+ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy0";
+ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
+ resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
+ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy0_otg: otg-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+ };
+
+ usb2phy2_grf: syscon@fd5d8000 {
+ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd5d8000 0x0 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ u2phy2: usb2phy@8000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x8000 0x10>;
+ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy2";
+ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+ resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
+ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy2_host: host-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+ };
+
+ usb2phy3_grf: syscon@fd5dc000 {
+ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd5dc000 0x0 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ u2phy3: usb2phy@c000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0xc000 0x10>;
+ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy3";
+ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
+ resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
+ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy3_host: host-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+ };
+
+ hdptxphy0_grf: syscon@fd5e0000 {
+ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+ reg = <0x0 0xfd5e0000 0x0 0x100>;
+ };
+
+ ioc: syscon@fd5f0000 {
+ compatible = "rockchip,rk3588-ioc", "syscon";
+ reg = <0x0 0xfd5f0000 0x0 0x10000>;
+ };
+
+ system_sram1: sram@fd600000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0xfd600000 0x0 0x100000>;
+ ranges = <0x0 0x0 0xfd600000 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ cru: clock-controller@fd7c0000 {
+ compatible = "rockchip,rk3588-cru";
+ reg = <0x0 0xfd7c0000 0x0 0x5c000>;
+ assigned-clocks =
+ <&cru PLL_PPLL>, <&cru PLL_AUPLL>,
+ <&cru PLL_NPLL>, <&cru PLL_GPLL>,
+ <&cru ACLK_CENTER_ROOT>,
+ <&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
+ <&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
+ <&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
+ <&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
+ <&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
+ <&cru CLK_GPU>;
+ assigned-clock-rates =
+ <1100000000>, <786432000>,
+ <850000000>, <1188000000>,
+ <702000000>,
+ <400000000>, <500000000>,
+ <800000000>, <100000000>,
+ <400000000>, <100000000>,
+ <200000000>, <500000000>,
+ <375000000>, <150000000>,
+ <200000000>;
+ rockchip,grf = <&php_grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ i2c0: i2c@fd880000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfd880000 0x0 0x1000>;
+ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
+ clock-names = "i2c", "pclk";
+ pinctrl-0 = <&i2c0m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ uart0: serial@fd890000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfd890000 0x0 0x100>;
+ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart0m1_xfer>;
+ pinctrl-names = "default";
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@fd8b0000 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfd8b0000 0x0 0x10>;
+ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm0m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@fd8b0010 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfd8b0010 0x0 0x10>;
+ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm1m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@fd8b0020 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfd8b0020 0x0 0x10>;
+ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm2m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@fd8b0030 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfd8b0030 0x0 0x10>;
+ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm3m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pmu: power-management@fd8d8000 {
+ compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
+ reg = <0x0 0xfd8d8000 0x0 0x400>;
+
+ power: power-controller {
+ compatible = "rockchip,rk3588-power-controller";
+ #address-cells = <1>;
+ #power-domain-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ /* These power domains are grouped by VD_NPU */
+ power-domain@RK3588_PD_NPU {
+ reg = <RK3588_PD_NPU>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-domain@RK3588_PD_NPUTOP {
+ reg = <RK3588_PD_NPUTOP>;
+ clocks = <&cru HCLK_NPU_ROOT>,
+ <&cru PCLK_NPU_ROOT>,
+ <&cru CLK_NPU_DSU0>,
+ <&cru HCLK_NPU_CM0_ROOT>;
+ pm_qos = <&qos_npu0_mwr>,
+ <&qos_npu0_mro>,
+ <&qos_mcu_npu>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-domain@RK3588_PD_NPU1 {
+ reg = <RK3588_PD_NPU1>;
+ clocks = <&cru HCLK_NPU_ROOT>,
+ <&cru PCLK_NPU_ROOT>,
+ <&cru CLK_NPU_DSU0>;
+ pm_qos = <&qos_npu1>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_NPU2 {
+ reg = <RK3588_PD_NPU2>;
+ clocks = <&cru HCLK_NPU_ROOT>,
+ <&cru PCLK_NPU_ROOT>,
+ <&cru CLK_NPU_DSU0>;
+ pm_qos = <&qos_npu2>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ /* These power domains are grouped by VD_GPU */
+ power-domain@RK3588_PD_GPU {
+ reg = <RK3588_PD_GPU>;
+ clocks = <&cru CLK_GPU>,
+ <&cru CLK_GPU_COREGROUP>,
+ <&cru CLK_GPU_STACKS>;
+ pm_qos = <&qos_gpu_m0>,
+ <&qos_gpu_m1>,
+ <&qos_gpu_m2>,
+ <&qos_gpu_m3>;
+ #power-domain-cells = <0>;
+ };
+ /* These power domains are grouped by VD_VCODEC */
+ power-domain@RK3588_PD_VCODEC {
+ reg = <RK3588_PD_VCODEC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ power-domain@RK3588_PD_RKVDEC0 {
+ reg = <RK3588_PD_RKVDEC0>;
+ clocks = <&cru HCLK_RKVDEC0>,
+ <&cru HCLK_VDPU_ROOT>,
+ <&cru ACLK_VDPU_ROOT>,
+ <&cru ACLK_RKVDEC0>,
+ <&cru ACLK_RKVDEC_CCU>;
+ pm_qos = <&qos_rkvdec0>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_RKVDEC1 {
+ reg = <RK3588_PD_RKVDEC1>;
+ clocks = <&cru HCLK_RKVDEC1>,
+ <&cru HCLK_VDPU_ROOT>,
+ <&cru ACLK_VDPU_ROOT>,
+ <&cru ACLK_RKVDEC1>;
+ pm_qos = <&qos_rkvdec1>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_VENC0 {
+ reg = <RK3588_PD_VENC0>;
+ clocks = <&cru HCLK_RKVENC0>,
+ <&cru ACLK_RKVENC0>;
+ pm_qos = <&qos_rkvenc0_m0ro>,
+ <&qos_rkvenc0_m1ro>,
+ <&qos_rkvenc0_m2wo>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ power-domain@RK3588_PD_VENC1 {
+ reg = <RK3588_PD_VENC1>;
+ clocks = <&cru HCLK_RKVENC1>,
+ <&cru HCLK_RKVENC0>,
+ <&cru ACLK_RKVENC0>,
+ <&cru ACLK_RKVENC1>;
+ pm_qos = <&qos_rkvenc1_m0ro>,
+ <&qos_rkvenc1_m1ro>,
+ <&qos_rkvenc1_m2wo>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ /* These power domains are grouped by VD_LOGIC */
+ power-domain@RK3588_PD_VDPU {
+ reg = <RK3588_PD_VDPU>;
+ clocks = <&cru HCLK_VDPU_ROOT>,
+ <&cru ACLK_VDPU_LOW_ROOT>,
+ <&cru ACLK_VDPU_ROOT>,
+ <&cru ACLK_JPEG_DECODER_ROOT>,
+ <&cru ACLK_IEP2P0>,
+ <&cru HCLK_IEP2P0>,
+ <&cru ACLK_JPEG_ENCODER0>,
+ <&cru HCLK_JPEG_ENCODER0>,
+ <&cru ACLK_JPEG_ENCODER1>,
+ <&cru HCLK_JPEG_ENCODER1>,
+ <&cru ACLK_JPEG_ENCODER2>,
+ <&cru HCLK_JPEG_ENCODER2>,
+ <&cru ACLK_JPEG_ENCODER3>,
+ <&cru HCLK_JPEG_ENCODER3>,
+ <&cru ACLK_JPEG_DECODER>,
+ <&cru HCLK_JPEG_DECODER>,
+ <&cru ACLK_RGA2>,
+ <&cru HCLK_RGA2>;
+ pm_qos = <&qos_iep>,
+ <&qos_jpeg_dec>,
+ <&qos_jpeg_enc0>,
+ <&qos_jpeg_enc1>,
+ <&qos_jpeg_enc2>,
+ <&qos_jpeg_enc3>,
+ <&qos_rga2_mro>,
+ <&qos_rga2_mwo>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+
+ power-domain@RK3588_PD_AV1 {
+ reg = <RK3588_PD_AV1>;
+ clocks = <&cru PCLK_AV1>,
+ <&cru ACLK_AV1>,
+ <&cru HCLK_VDPU_ROOT>;
+ pm_qos = <&qos_av1>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_RKVDEC0 {
+ reg = <RK3588_PD_RKVDEC0>;
+ clocks = <&cru HCLK_RKVDEC0>,
+ <&cru HCLK_VDPU_ROOT>,
+ <&cru ACLK_VDPU_ROOT>,
+ <&cru ACLK_RKVDEC0>;
+ pm_qos = <&qos_rkvdec0>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_RKVDEC1 {
+ reg = <RK3588_PD_RKVDEC1>;
+ clocks = <&cru HCLK_RKVDEC1>,
+ <&cru HCLK_VDPU_ROOT>,
+ <&cru ACLK_VDPU_ROOT>;
+ pm_qos = <&qos_rkvdec1>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_RGA30 {
+ reg = <RK3588_PD_RGA30>;
+ clocks = <&cru ACLK_RGA3_0>,
+ <&cru HCLK_RGA3_0>;
+ pm_qos = <&qos_rga3_0>;
+ #power-domain-cells = <0>;
+ };
+ };
+ power-domain@RK3588_PD_VOP {
+ reg = <RK3588_PD_VOP>;
+ clocks = <&cru PCLK_VOP_ROOT>,
+ <&cru HCLK_VOP_ROOT>,
+ <&cru ACLK_VOP>;
+ pm_qos = <&qos_vop_m0>,
+ <&qos_vop_m1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ power-domain@RK3588_PD_VO0 {
+ reg = <RK3588_PD_VO0>;
+ clocks = <&cru PCLK_VO0_ROOT>,
+ <&cru PCLK_VO0_S_ROOT>,
+ <&cru HCLK_VO0_S_ROOT>,
+ <&cru ACLK_VO0_ROOT>,
+ <&cru HCLK_HDCP0>,
+ <&cru ACLK_HDCP0>,
+ <&cru HCLK_VOP_ROOT>;
+ pm_qos = <&qos_hdcp0>;
+ #power-domain-cells = <0>;
+ };
+ };
+ power-domain@RK3588_PD_VO1 {
+ reg = <RK3588_PD_VO1>;
+ clocks = <&cru PCLK_VO1_ROOT>,
+ <&cru PCLK_VO1_S_ROOT>,
+ <&cru HCLK_VO1_S_ROOT>,
+ <&cru HCLK_HDCP1>,
+ <&cru ACLK_HDCP1>,
+ <&cru ACLK_HDMIRX_ROOT>,
+ <&cru HCLK_VO1USB_TOP_ROOT>;
+ pm_qos = <&qos_hdcp1>,
+ <&qos_hdmirx>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_VI {
+ reg = <RK3588_PD_VI>;
+ clocks = <&cru HCLK_VI_ROOT>,
+ <&cru PCLK_VI_ROOT>,
+ <&cru HCLK_ISP0>,
+ <&cru ACLK_ISP0>,
+ <&cru HCLK_VICAP>,
+ <&cru ACLK_VICAP>;
+ pm_qos = <&qos_isp0_mro>,
+ <&qos_isp0_mwo>,
+ <&qos_vicap_m0>,
+ <&qos_vicap_m1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ power-domain@RK3588_PD_ISP1 {
+ reg = <RK3588_PD_ISP1>;
+ clocks = <&cru HCLK_ISP1>,
+ <&cru ACLK_ISP1>,
+ <&cru HCLK_VI_ROOT>,
+ <&cru PCLK_VI_ROOT>;
+ pm_qos = <&qos_isp1_mwo>,
+ <&qos_isp1_mro>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_FEC {
+ reg = <RK3588_PD_FEC>;
+ clocks = <&cru HCLK_FISHEYE0>,
+ <&cru ACLK_FISHEYE0>,
+ <&cru HCLK_FISHEYE1>,
+ <&cru ACLK_FISHEYE1>,
+ <&cru PCLK_VI_ROOT>;
+ pm_qos = <&qos_fisheye0>,
+ <&qos_fisheye1>;
+ #power-domain-cells = <0>;
+ };
+ };
+ power-domain@RK3588_PD_RGA31 {
+ reg = <RK3588_PD_RGA31>;
+ clocks = <&cru HCLK_RGA3_1>,
+ <&cru ACLK_RGA3_1>;
+ pm_qos = <&qos_rga3_1>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_USB {
+ reg = <RK3588_PD_USB>;
+ clocks = <&cru PCLK_PHP_ROOT>,
+ <&cru ACLK_USB_ROOT>,
+ <&cru ACLK_USB>,
+ <&cru HCLK_USB_ROOT>,
+ <&cru HCLK_HOST0>,
+ <&cru HCLK_HOST_ARB0>,
+ <&cru HCLK_HOST1>,
+ <&cru HCLK_HOST_ARB1>;
+ pm_qos = <&qos_usb3_0>,
+ <&qos_usb3_1>,
+ <&qos_usb2host_0>,
+ <&qos_usb2host_1>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_GMAC {
+ reg = <RK3588_PD_GMAC>;
+ clocks = <&cru PCLK_PHP_ROOT>,
+ <&cru ACLK_PCIE_ROOT>,
+ <&cru ACLK_PHP_ROOT>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_PCIE {
+ reg = <RK3588_PD_PCIE>;
+ clocks = <&cru PCLK_PHP_ROOT>,
+ <&cru ACLK_PCIE_ROOT>,
+ <&cru ACLK_PHP_ROOT>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_SDIO {
+ reg = <RK3588_PD_SDIO>;
+ clocks = <&cru HCLK_SDIO>,
+ <&cru HCLK_NVM_ROOT>;
+ pm_qos = <&qos_sdio>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_AUDIO {
+ reg = <RK3588_PD_AUDIO>;
+ clocks = <&cru HCLK_AUDIO_ROOT>,
+ <&cru PCLK_AUDIO_ROOT>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3588_PD_SDMMC {
+ reg = <RK3588_PD_SDMMC>;
+ pm_qos = <&qos_sdmmc>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ av1d: video-codec@fdc70000 {
+ compatible = "rockchip,rk3588-av1-vpu";
+ reg = <0x0 0xfdc70000 0x0 0x800>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "vdpu";
+ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+ assigned-clock-rates = <400000000>, <400000000>;
+ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+ clock-names = "aclk", "hclk";
+ power-domains = <&power RK3588_PD_AV1>;
+ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+ };
+
+ vop: vop@fdd90000 {
+ compatible = "rockchip,rk3588-vop";
+ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
+ reg-names = "vop", "gamma-lut";
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru ACLK_VOP>,
+ <&cru HCLK_VOP>,
+ <&cru DCLK_VOP0>,
+ <&cru DCLK_VOP1>,
+ <&cru DCLK_VOP2>,
+ <&cru DCLK_VOP3>,
+ <&cru PCLK_VOP_ROOT>;
+ clock-names = "aclk",
+ "hclk",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2",
+ "dclk_vp3",
+ "pclk_vop";
+ iommus = <&vop_mmu>;
+ power-domains = <&power RK3588_PD_VOP>;
+ rockchip,grf = <&sys_grf>;
+ rockchip,vop-grf = <&vop_grf>;
+ rockchip,vo1-grf = <&vo1_grf>;
+ rockchip,pmu = <&pmu>;
+ status = "disabled";
+
+ vop_out: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vp0: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ vp1: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ vp2: port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ vp3: port@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+ };
+
+ vop_mmu: iommu@fdd97e00 {
+ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
+ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+ clock-names = "aclk", "iface";
+ #iommu-cells = <0>;
+ power-domains = <&power RK3588_PD_VOP>;
+ status = "disabled";
+ };
+
+ i2s4_8ch: i2s@fddc0000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddc0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S4_8CH_TX>, <&cru MCLK_I2S4_8CH_TX>, <&cru HCLK_I2S4_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S4_8CH_TX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 0>;
+ dma-names = "tx";
+ power-domains = <&power RK3588_PD_VO0>;
+ resets = <&cru SRST_M_I2S4_8CH_TX>;
+ reset-names = "tx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s5_8ch: i2s@fddf0000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddf0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S5_8CH_TX>, <&cru MCLK_I2S5_8CH_TX>, <&cru HCLK_I2S5_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S5_8CH_TX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 2>;
+ dma-names = "tx";
+ power-domains = <&power RK3588_PD_VO1>;
+ resets = <&cru SRST_M_I2S5_8CH_TX>;
+ reset-names = "tx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s9_8ch: i2s@fddfc000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddfc000 0x0 0x1000>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S9_8CH_RX>, <&cru MCLK_I2S9_8CH_RX>, <&cru HCLK_I2S9_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S9_8CH_RX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 23>;
+ dma-names = "rx";
+ power-domains = <&power RK3588_PD_VO1>;
+ resets = <&cru SRST_M_I2S9_8CH_RX>;
+ reset-names = "rx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ qos_gpu_m0: qos@fdf35000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf35000 0x0 0x20>;
+ };
+
+ qos_gpu_m1: qos@fdf35200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf35200 0x0 0x20>;
+ };
+
+ qos_gpu_m2: qos@fdf35400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf35400 0x0 0x20>;
+ };
+
+ qos_gpu_m3: qos@fdf35600 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf35600 0x0 0x20>;
+ };
+
+ qos_rga3_1: qos@fdf36000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf36000 0x0 0x20>;
+ };
+
+ qos_sdio: qos@fdf39000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf39000 0x0 0x20>;
+ };
+
+ qos_sdmmc: qos@fdf3d800 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf3d800 0x0 0x20>;
+ };
+
+ qos_usb3_1: qos@fdf3e000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf3e000 0x0 0x20>;
+ };
+
+ qos_usb3_0: qos@fdf3e200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf3e200 0x0 0x20>;
+ };
+
+ qos_usb2host_0: qos@fdf3e400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf3e400 0x0 0x20>;
+ };
+
+ qos_usb2host_1: qos@fdf3e600 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf3e600 0x0 0x20>;
+ };
+
+ qos_fisheye0: qos@fdf40000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf40000 0x0 0x20>;
+ };
+
+ qos_fisheye1: qos@fdf40200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf40200 0x0 0x20>;
+ };
+
+ qos_isp0_mro: qos@fdf40400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf40400 0x0 0x20>;
+ };
+
+ qos_isp0_mwo: qos@fdf40500 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf40500 0x0 0x20>;
+ };
+
+ qos_vicap_m0: qos@fdf40600 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf40600 0x0 0x20>;
+ };
+
+ qos_vicap_m1: qos@fdf40800 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf40800 0x0 0x20>;
+ };
+
+ qos_isp1_mwo: qos@fdf41000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf41000 0x0 0x20>;
+ };
+
+ qos_isp1_mro: qos@fdf41100 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf41100 0x0 0x20>;
+ };
+
+ qos_rkvenc0_m0ro: qos@fdf60000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf60000 0x0 0x20>;
+ };
+
+ qos_rkvenc0_m1ro: qos@fdf60200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf60200 0x0 0x20>;
+ };
+
+ qos_rkvenc0_m2wo: qos@fdf60400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf60400 0x0 0x20>;
+ };
+
+ qos_rkvenc1_m0ro: qos@fdf61000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf61000 0x0 0x20>;
+ };
+
+ qos_rkvenc1_m1ro: qos@fdf61200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf61200 0x0 0x20>;
+ };
+
+ qos_rkvenc1_m2wo: qos@fdf61400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf61400 0x0 0x20>;
+ };
+
+ qos_rkvdec0: qos@fdf62000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf62000 0x0 0x20>;
+ };
+
+ qos_rkvdec1: qos@fdf63000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf63000 0x0 0x20>;
+ };
+
+ qos_av1: qos@fdf64000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf64000 0x0 0x20>;
+ };
+
+ qos_iep: qos@fdf66000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66000 0x0 0x20>;
+ };
+
+ qos_jpeg_dec: qos@fdf66200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66200 0x0 0x20>;
+ };
+
+ qos_jpeg_enc0: qos@fdf66400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66400 0x0 0x20>;
+ };
+
+ qos_jpeg_enc1: qos@fdf66600 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66600 0x0 0x20>;
+ };
+
+ qos_jpeg_enc2: qos@fdf66800 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66800 0x0 0x20>;
+ };
+
+ qos_jpeg_enc3: qos@fdf66a00 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66a00 0x0 0x20>;
+ };
+
+ qos_rga2_mro: qos@fdf66c00 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66c00 0x0 0x20>;
+ };
+
+ qos_rga2_mwo: qos@fdf66e00 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf66e00 0x0 0x20>;
+ };
+
+ qos_rga3_0: qos@fdf67000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf67000 0x0 0x20>;
+ };
+
+ qos_vdpu: qos@fdf67200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf67200 0x0 0x20>;
+ };
+
+ qos_npu1: qos@fdf70000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf70000 0x0 0x20>;
+ };
+
+ qos_npu2: qos@fdf71000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf71000 0x0 0x20>;
+ };
+
+ qos_npu0_mwr: qos@fdf72000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf72000 0x0 0x20>;
+ };
+
+ qos_npu0_mro: qos@fdf72200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf72200 0x0 0x20>;
+ };
+
+ qos_mcu_npu: qos@fdf72400 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf72400 0x0 0x20>;
+ };
+
+ qos_hdcp0: qos@fdf80000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf80000 0x0 0x20>;
+ };
+
+ qos_hdcp1: qos@fdf81000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf81000 0x0 0x20>;
+ };
+
+ qos_hdmirx: qos@fdf81200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf81200 0x0 0x20>;
+ };
+
+ qos_vop_m0: qos@fdf82000 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf82000 0x0 0x20>;
+ };
+
+ qos_vop_m1: qos@fdf82200 {
+ compatible = "rockchip,rk3588-qos", "syscon";
+ reg = <0x0 0xfdf82200 0x0 0x20>;
+ };
+
+ dfi: dfi@fe060000 {
+ reg = <0x00 0xfe060000 0x00 0x10000>;
+ compatible = "rockchip,rk3588-dfi";
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+ rockchip,pmu = <&pmu1grf>;
+ };
+
+ pcie2x1l1: pcie@fe180000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ bus-range = <0x30 0x3f>;
+ clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
+ <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
+ <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ device_type = "pci";
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>,
+ <0 0 0 2 &pcie2x1l1_intc 1>,
+ <0 0 0 3 &pcie2x1l1_intc 2>,
+ <0 0 0 4 &pcie2x1l1_intc 3>;
+ linux,pci-domain = <3>;
+ max-link-speed = <2>;
+ msi-map = <0x3000 &its0 0x3000 0x1000>;
+ num-lanes = <1>;
+ phys = <&combphy2_psu PHY_TYPE_PCIE>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>,
+ <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>,
+ <0x03000000 0x0 0x40000000 0x9 0xc0000000 0x0 0x40000000>;
+ reg = <0xa 0x40c00000 0x0 0x00400000>,
+ <0x0 0xfe180000 0x0 0x00010000>,
+ <0x0 0xf3000000 0x0 0x00100000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
+ reset-names = "pwr", "pipe";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ status = "disabled";
+
+ pcie2x1l1_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING 0>;
+ };
+ };
+
+ pcie2x1l2: pcie@fe190000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ bus-range = <0x40 0x4f>;
+ clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
+ <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
+ <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ device_type = "pci";
+ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
+ <0 0 0 2 &pcie2x1l2_intc 1>,
+ <0 0 0 3 &pcie2x1l2_intc 2>,
+ <0 0 0 4 &pcie2x1l2_intc 3>;
+ linux,pci-domain = <4>;
+ max-link-speed = <2>;
+ msi-map = <0x4000 &its0 0x4000 0x1000>;
+ num-lanes = <1>;
+ phys = <&combphy0_ps PHY_TYPE_PCIE>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
+ <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
+ <0x03000000 0x0 0x40000000 0xa 0x00000000 0x0 0x40000000>;
+ reg = <0xa 0x41000000 0x0 0x00400000>,
+ <0x0 0xfe190000 0x0 0x00010000>,
+ <0x0 0xf4000000 0x0 0x00100000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
+ reset-names = "pwr", "pipe";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ status = "disabled";
+
+ pcie2x1l2_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
+ };
+ };
+
+ gmac1: ethernet@fe1c0000 {
+ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+ reg = <0x0 0xfe1c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+ <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
+ <&cru CLK_GMAC1_PTP_REF>;
+ clock-names = "stmmaceth", "clk_mac_ref",
+ "pclk_mac", "aclk_mac",
+ "ptp_ref";
+ power-domains = <&power RK3588_PD_GMAC>;
+ resets = <&cru SRST_A_GMAC1>;
+ reset-names = "stmmaceth";
+ rockchip,grf = <&sys_grf>;
+ rockchip,php-grf = <&php_grf>;
+ snps,axi-config = <&gmac1_stmmac_axi_setup>;
+ snps,mixed-burst;
+ snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
+ snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
+ snps,tso;
+ status = "disabled";
+
+ mdio1: mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ };
+
+ gmac1_stmmac_axi_setup: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,wr_osr_lmt = <4>;
+ snps,rd_osr_lmt = <8>;
+ };
+
+ gmac1_mtl_rx_setup: rx-queues-config {
+ snps,rx-queues-to-use = <2>;
+ queue0 {};
+ queue1 {};
+ };
+
+ gmac1_mtl_tx_setup: tx-queues-config {
+ snps,tx-queues-to-use = <2>;
+ queue0 {};
+ queue1 {};
+ };
+ };
+
+ sata0: sata@fe210000 {
+ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+ reg = <0 0xfe210000 0 0x1000>;
+ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
+ <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
+ <&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
+ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+ ports-implemented = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ sata-port@0 {
+ reg = <0>;
+ hba-port-cap = <HBA_PORT_FBSCP>;
+ phys = <&combphy0_ps PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ snps,rx-ts-max = <32>;
+ snps,tx-ts-max = <32>;
+ };
+ };
+
+ sata2: sata@fe230000 {
+ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+ reg = <0 0xfe230000 0 0x1000>;
+ interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>,
+ <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>,
+ <&cru CLK_PIPEPHY2_PIPE_ASIC_G>;
+ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+ ports-implemented = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ sata-port@0 {
+ reg = <0>;
+ hba-port-cap = <HBA_PORT_FBSCP>;
+ phys = <&combphy2_psu PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ snps,rx-ts-max = <32>;
+ snps,tx-ts-max = <32>;
+ };
+ };
+
+ sfc: spi@fe2b0000 {
+ compatible = "rockchip,sfc";
+ reg = <0x0 0xfe2b0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sdmmc: mmc@fe2c0000 {
+ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xfe2c0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+ power-domains = <&power RK3588_PD_SDMMC>;
+ status = "disabled";
+ };
+
+ sdio: mmc@fe2d0000 {
+ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x00 0xfe2d0000 0x00 0x4000>;
+ interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>,
+ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdiom1_pins>;
+ power-domains = <&power RK3588_PD_SDIO>;
+ status = "disabled";
+ };
+
+ sdhci: mmc@fe2e0000 {
+ compatible = "rockchip,rk3588-dwcmshc";
+ reg = <0x0 0xfe2e0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
+ assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
+ assigned-clock-rates = <200000000>, <24000000>, <200000000>;
+ clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
+ <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
+ <&cru TMCLK_EMMC>;
+ clock-names = "core", "bus", "axi", "block", "timer";
+ max-frequency = <200000000>;
+ pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>,
+ <&emmc_cmd>, <&emmc_data_strobe>;
+ pinctrl-names = "default";
+ resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
+ <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
+ <&cru SRST_T_EMMC>;
+ reset-names = "core", "bus", "axi", "block", "timer";
+ status = "disabled";
+ };
+
+ i2s0_8ch: i2s@fe470000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfe470000 0x0 0x1000>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>, <&cru PLL_AUPLL>;
+ dmas = <&dmac0 0>, <&dmac0 1>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3588_PD_AUDIO>;
+ resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
+ reset-names = "tx-m", "rx-m";
+ rockchip,trcm-sync-tx-only;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdi1
+ &i2s0_sdi2
+ &i2s0_sdi3
+ &i2s0_sdo0
+ &i2s0_sdo1
+ &i2s0_sdo2
+ &i2s0_sdo3>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s1_8ch: i2s@fe480000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfe480000 0x0 0x1000>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ dmas = <&dmac0 2>, <&dmac0 3>;
+ dma-names = "tx", "rx";
+ resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+ reset-names = "tx-m", "rx-m";
+ rockchip,trcm-sync-tx-only;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_lrck
+ &i2s1m0_sclk
+ &i2s1m0_sdi0
+ &i2s1m0_sdi1
+ &i2s1m0_sdi2
+ &i2s1m0_sdi3
+ &i2s1m0_sdo0
+ &i2s1m0_sdo1
+ &i2s1m0_sdo2
+ &i2s1m0_sdo3>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s2_2ch: i2s@fe490000 {
+ compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xfe490000 0x0 0x1000>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac1 0>, <&dmac1 1>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3588_PD_AUDIO>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2m1_lrck
+ &i2s2m1_sclk
+ &i2s2m1_sdi
+ &i2s2m1_sdo>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s3_2ch: i2s@fe4a0000 {
+ compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xfe4a0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S3_2CH>, <&cru HCLK_I2S3_2CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ assigned-clocks = <&cru CLK_I2S3_2CH_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac1 2>, <&dmac1 3>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3588_PD_AUDIO>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s3_lrck
+ &i2s3_sclk
+ &i2s3_sdi
+ &i2s3_sdo>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@fe600000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0xfe600000 0 0x10000>, /* GICD */
+ <0x0 0xfe680000 0 0x100000>; /* GICR */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-controller;
+ mbi-alias = <0x0 0xfe610000>;
+ mbi-ranges = <424 56>;
+ msi-controller;
+ ranges;
+ #address-cells = <2>;
+ #interrupt-cells = <4>;
+ #size-cells = <2>;
+
+ its0: msi-controller@fe640000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x0 0xfe640000 0x0 0x20000>;
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ its1: msi-controller@fe660000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x0 0xfe660000 0x0 0x20000>;
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ ppi-partitions {
+ ppi_partition0: interrupt-partition-0 {
+ affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
+ };
+
+ ppi_partition1: interrupt-partition-1 {
+ affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
+ };
+ };
+ };
+
+ dmac0: dma-controller@fea10000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0xfea10000 0x0 0x4000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
+ arm,pl330-periph-burst;
+ clocks = <&cru ACLK_DMAC0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ };
+
+ dmac1: dma-controller@fea30000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0xfea30000 0x0 0x4000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
+ arm,pl330-periph-burst;
+ clocks = <&cru ACLK_DMAC1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ };
+
+ i2c1: i2c@fea90000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfea90000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c1m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@feaa0000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfeaa0000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c2m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@feab0000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfeab0000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c3m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@feac0000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfeac0000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c4m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@fead0000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfead0000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c5m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ timer0: timer@feae0000 {
+ compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer";
+ reg = <0x0 0xfeae0000 0x0 0x20>;
+ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>;
+ clock-names = "pclk", "timer";
+ };
+
+ wdt: watchdog@feaf0000 {
+ compatible = "rockchip,rk3588-wdt", "snps,dw-wdt";
+ reg = <0x0 0xfeaf0000 0x0 0x100>;
+ clocks = <&cru TCLK_WDT0>, <&cru PCLK_WDT0>;
+ clock-names = "tclk", "pclk";
+ interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ spi0: spi@feb00000 {
+ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xfeb00000 0x0 0x1000>;
+ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac0 14>, <&dmac0 15>;
+ dma-names = "tx", "rx";
+ num-cs = <2>;
+ pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@feb10000 {
+ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xfeb10000 0x0 0x1000>;
+ interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac0 16>, <&dmac0 17>;
+ dma-names = "tx", "rx";
+ num-cs = <2>;
+ pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@feb20000 {
+ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xfeb20000 0x0 0x1000>;
+ interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac1 15>, <&dmac1 16>;
+ dma-names = "tx", "rx";
+ num-cs = <2>;
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi3: spi@feb30000 {
+ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xfeb30000 0x0 0x1000>;
+ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac1 17>, <&dmac1 18>;
+ dma-names = "tx", "rx";
+ num-cs = <2>;
+ pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ uart1: serial@feb40000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeb40000 0x0 0x100>;
+ interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac0 8>, <&dmac0 9>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart1m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart2: serial@feb50000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeb50000 0x0 0x100>;
+ interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac0 10>, <&dmac0 11>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart2m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart3: serial@feb60000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeb60000 0x0 0x100>;
+ interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac0 12>, <&dmac0 13>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart3m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart4: serial@feb70000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeb70000 0x0 0x100>;
+ interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac1 9>, <&dmac1 10>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart4m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart5: serial@feb80000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeb80000 0x0 0x100>;
+ interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac1 11>, <&dmac1 12>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart5m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart6: serial@feb90000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeb90000 0x0 0x100>;
+ interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac1 13>, <&dmac1 14>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart6m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart7: serial@feba0000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfeba0000 0x0 0x100>;
+ interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac2 7>, <&dmac2 8>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart7m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart8: serial@febb0000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfebb0000 0x0 0x100>;
+ interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac2 9>, <&dmac2 10>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart8m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart9: serial@febc0000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfebc0000 0x0 0x100>;
+ interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac2 11>, <&dmac2 12>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&uart9m1_xfer>;
+ pinctrl-names = "default";
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@febd0000 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebd0000 0x0 0x10>;
+ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm4m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm5: pwm@febd0010 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebd0010 0x0 0x10>;
+ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm5m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm6: pwm@febd0020 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebd0020 0x0 0x10>;
+ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm6m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm7: pwm@febd0030 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebd0030 0x0 0x10>;
+ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm7m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm8: pwm@febe0000 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebe0000 0x0 0x10>;
+ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm8m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm9: pwm@febe0010 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebe0010 0x0 0x10>;
+ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm9m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm10: pwm@febe0020 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebe0020 0x0 0x10>;
+ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm10m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm11: pwm@febe0030 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebe0030 0x0 0x10>;
+ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm11m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm12: pwm@febf0000 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebf0000 0x0 0x10>;
+ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm12m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm13: pwm@febf0010 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebf0010 0x0 0x10>;
+ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm13m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm14: pwm@febf0020 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebf0020 0x0 0x10>;
+ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm14m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm15: pwm@febf0030 {
+ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+ reg = <0x0 0xfebf0030 0x0 0x10>;
+ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+ clock-names = "pwm", "pclk";
+ pinctrl-0 = <&pwm15m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ thermal_zones: thermal-zones {
+ /* sensor near the center of the SoC */
+ package_thermal: package-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 0>;
+
+ trips {
+ package_crit: package-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ /* sensor between A76 cores 0 and 1 */
+ bigcore0_thermal: bigcore0-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 1>;
+
+ trips {
+ bigcore0_alert: bigcore0-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ bigcore0_crit: bigcore0-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&bigcore0_alert>;
+ cooling-device =
+ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ /* sensor between A76 cores 2 and 3 */
+ bigcore2_thermal: bigcore2-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 2>;
+
+ trips {
+ bigcore2_alert: bigcore2-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ bigcore2_crit: bigcore2-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&bigcore2_alert>;
+ cooling-device =
+ <&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ /* sensor between the four A55 cores */
+ little_core_thermal: littlecore-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 3>;
+
+ trips {
+ littlecore_alert: littlecore-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ littlecore_crit: littlecore-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&littlecore_alert>;
+ cooling-device =
+ <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ /* sensor near the PD_CENTER power domain */
+ center_thermal: center-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 4>;
+
+ trips {
+ center_crit: center-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpu_thermal: gpu-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 5>;
+
+ trips {
+ gpu_alert: gpu-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ gpu_crit: gpu-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert>;
+ cooling-device =
+ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ npu_thermal: npu-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 6>;
+
+ trips {
+ npu_crit: npu-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ tsadc: tsadc@fec00000 {
+ compatible = "rockchip,rk3588-tsadc";
+ reg = <0x0 0xfec00000 0x0 0x400>;
+ interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
+ clock-names = "tsadc", "apb_pclk";
+ assigned-clocks = <&cru CLK_TSADC>;
+ assigned-clock-rates = <2000000>;
+ resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>;
+ reset-names = "tsadc-apb", "tsadc";
+ rockchip,hw-tshut-temp = <120000>;
+ rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
+ rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+ pinctrl-0 = <&tsadc_gpio_func>;
+ pinctrl-1 = <&tsadc_shut>;
+ pinctrl-names = "gpio", "otpout";
+ #thermal-sensor-cells = <1>;
+ status = "disabled";
+ };
+
+ saradc: adc@fec10000 {
+ compatible = "rockchip,rk3588-saradc";
+ reg = <0x0 0xfec10000 0x0 0x10000>;
+ interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH 0>;
+ #io-channel-cells = <1>;
+ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ resets = <&cru SRST_P_SARADC>;
+ reset-names = "saradc-apb";
+ status = "disabled";
+ };
+
+ i2c6: i2c@fec80000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfec80000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c6m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@fec90000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfec90000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c7m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c8: i2c@feca0000 {
+ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+ reg = <0x0 0xfeca0000 0x0 0x1000>;
+ clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
+ clock-names = "i2c", "pclk";
+ interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-0 = <&i2c8m0_xfer>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi4: spi@fecb0000 {
+ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xfecb0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac2 13>, <&dmac2 14>;
+ dma-names = "tx", "rx";
+ num-cs = <2>;
+ pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ otp: efuse@fecc0000 {
+ compatible = "rockchip,rk3588-otp";
+ reg = <0x0 0xfecc0000 0x0 0x400>;
+ clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
+ <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
+ clock-names = "otp", "apb_pclk", "phy", "arb";
+ resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
+ <&cru SRST_OTPC_ARB>;
+ reset-names = "otp", "apb", "arb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpu_code: cpu-code@2 {
+ reg = <0x02 0x2>;
+ };
+
+ otp_id: id@7 {
+ reg = <0x07 0x10>;
+ };
+
+ cpub0_leakage: cpu-leakage@17 {
+ reg = <0x17 0x1>;
+ };
+
+ cpub1_leakage: cpu-leakage@18 {
+ reg = <0x18 0x1>;
+ };
+
+ cpul_leakage: cpu-leakage@19 {
+ reg = <0x19 0x1>;
+ };
+
+ log_leakage: log-leakage@1a {
+ reg = <0x1a 0x1>;
+ };
+
+ gpu_leakage: gpu-leakage@1b {
+ reg = <0x1b 0x1>;
+ };
+
+ otp_cpu_version: cpu-version@1c {
+ reg = <0x1c 0x1>;
+ bits = <3 3>;
+ };
+
+ npu_leakage: npu-leakage@28 {
+ reg = <0x28 0x1>;
+ };
+
+ codec_leakage: codec-leakage@29 {
+ reg = <0x29 0x1>;
+ };
+ };
+
+ dmac2: dma-controller@fed10000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0xfed10000 0x0 0x4000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
+ arm,pl330-periph-burst;
+ clocks = <&cru ACLK_DMAC2>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ };
+
+ hdptxphy_hdmi0: phy@fed60000 {
+ compatible = "rockchip,rk3588-hdptx-phy";
+ reg = <0x0 0xfed60000 0x0 0x2000>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+ clock-names = "ref", "apb";
+ #phy-cells = <0>;
+ resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+ <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+ <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+ <&cru SRST_HDPTX0_LCPLL>;
+ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+ "lcpll";
+ rockchip,grf = <&hdptxphy0_grf>;
+ status = "disabled";
+ };
+
+ usbdp_phy0: phy@fed80000 {
+ compatible = "rockchip,rk3588-usbdp-phy";
+ reg = <0x0 0xfed80000 0x0 0x10000>;
+ #phy-cells = <1>;
+ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+ <&cru CLK_USBDP_PHY0_IMMORTAL>,
+ <&cru PCLK_USBDPPHY0>,
+ <&u2phy0>;
+ clock-names = "refclk", "immortal", "pclk", "utmi";
+ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
+ <&cru SRST_USBDP_COMBO_PHY0_CMN>,
+ <&cru SRST_USBDP_COMBO_PHY0_LANE>,
+ <&cru SRST_USBDP_COMBO_PHY0_PCS>,
+ <&cru SRST_P_USBDPPHY0>;
+ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+ rockchip,u2phy-grf = <&usb2phy0_grf>;
+ rockchip,usb-grf = <&usb_grf>;
+ rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
+ rockchip,vo-grf = <&vo0_grf>;
+ status = "disabled";
+ };
+
+ combphy0_ps: phy@fee00000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee00000 0x0 0x100>;
+ clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
+ <&cru PCLK_PHP_ROOT>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
+ assigned-clock-rates = <100000000>;
+ #phy-cells = <1>;
+ resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>;
+ reset-names = "phy", "apb";
+ rockchip,pipe-grf = <&php_grf>;
+ rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+ status = "disabled";
+ };
+
+ combphy2_psu: phy@fee20000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee20000 0x0 0x100>;
+ clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
+ <&cru PCLK_PHP_ROOT>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
+ assigned-clock-rates = <100000000>;
+ #phy-cells = <1>;
+ resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>;
+ reset-names = "phy", "apb";
+ rockchip,pipe-grf = <&php_grf>;
+ rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
+ status = "disabled";
+ };
+
+ system_sram2: sram@ff001000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0xff001000 0x0 0xef000>;
+ ranges = <0x0 0x0 0xff001000 0xef000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3588-pinctrl";
+ ranges;
+ rockchip,grf = <&ioc>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ gpio0: gpio@fd8a0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xfd8a0000 0x0 0x100>;
+ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 32>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@fec20000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xfec20000 0x0 0x100>;
+ interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 32 32>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@fec30000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xfec30000 0x0 0x100>;
+ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 64 32>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@fec40000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xfec40000 0x0 0x100>;
+ interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 96 32>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@fec50000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xfec50000 0x0 0x100>;
+ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 128 32>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+ };
+};
+
+#include "rk3588-base-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
index 94ecb9b4f98f..fde8b228f2c7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
@@ -136,6 +136,11 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
&i2c0 {
pinctrl-0 = <&i2c0m2_xfer>;
status = "okay";
@@ -357,7 +362,7 @@
vcca-supply = <&vcc5v0_sys>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
index c0d4a15323e2..03fd193be253 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
@@ -162,6 +162,8 @@
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
<&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ system-power-controller;
+
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
vcc3-supply = <&vcc5v0_sys>;
@@ -182,7 +184,7 @@
#gpio-cells = <2>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
@@ -464,3 +466,7 @@
};
};
};
+
+&tsadc {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
index 963e880ccc12..7b1317898358 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
@@ -68,6 +68,10 @@
status = "okay";
};
+&combphy2_psu {
+ status = "okay";
+};
+
&i2c6 {
status = "okay";
@@ -230,3 +234,7 @@
&usb_host1_ohci {
status = "okay";
};
+
+&usb_host2_xhci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index de30c2632b8e..00f660d50127 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
#include "rk3588.dtsi"
/ {
@@ -159,6 +160,18 @@
vin-supply = <&avcc_1v8_s0>;
};
+ vbus5v0_typec: vbus5v0-typec-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PD0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec5v_pwren>;
+ regulator-name = "vbus5v0_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
vcc12v_dcin: vcc12v-dcin-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc12v_dcin";
@@ -281,9 +294,68 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ sram-supply = <&vdd_gpu_mem_s0>;
+ status = "okay";
+};
+
&i2c2 {
status = "okay";
+ usbc0: usb-typec@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbc0_int>;
+ vbus-supply = <&vbus5v0_typec>;
+ status = "okay";
+
+ usb_con: connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "dual";
+ op-sink-microwatt = <1000000>;
+ power-role = "dual";
+ sink-pdos =
+ <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+ source-pdos =
+ <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ try-power-role = "source";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usbc0_orien_sw: endpoint {
+ remote-endpoint = <&usbdp_phy0_orientation_switch>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usbc0_role_sw: endpoint {
+ remote-endpoint = <&dwc3_0_role_switch>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ dp_altmode_mux: endpoint {
+ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+ };
+ };
+ };
+ };
+ };
+
hym8563: rtc@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
@@ -410,6 +482,16 @@
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ usb-typec {
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usbc0_int: usbc0-int {
+ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
};
&pwm2 {
@@ -484,12 +566,16 @@
regulators {
vdd_gpu_s0: dcdc-reg1 {
+ /* regulator coupling requires always-on */
+ regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_gpu_s0";
regulator-enable-ramp-delay = <400>;
+ regulator-coupled-with = <&vdd_gpu_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-state-mem {
regulator-off-in-suspend;
};
@@ -534,12 +620,16 @@
};
vdd_gpu_mem_s0: dcdc-reg5 {
+ /* regulator coupling requires always-on */
+ regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <400>;
regulator-name = "vdd_gpu_mem_s0";
+ regulator-coupled-with = <&vdd_gpu_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-state-mem {
regulator-off-in-suspend;
};
@@ -788,6 +878,8 @@
vdd_cpu_big1_s0: dcdc-reg1 {
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big1_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -800,6 +892,8 @@
vdd_cpu_big0_s0: dcdc-reg2 {
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big0_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -812,6 +906,8 @@
vdd_cpu_lit_s0: dcdc-reg3 {
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_lit_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
@@ -836,6 +932,8 @@
vdd_cpu_big1_mem_s0: dcdc-reg5 {
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big1_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -849,6 +947,8 @@
vdd_cpu_big0_mem_s0: dcdc-reg6 {
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big0_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -873,6 +973,8 @@
vdd_cpu_lit_mem_s0: dcdc-reg8 {
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_lit_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
@@ -1041,6 +1143,26 @@
status = "okay";
};
+&tsadc {
+ status = "okay";
+};
+
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
@@ -1079,3 +1201,58 @@
&usb_host1_ohci {
status = "okay";
};
+
+&usbdp_phy0 {
+ mode-switch;
+ orientation-switch;
+ sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+ sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbdp_phy0_orientation_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_orien_sw>;
+ };
+
+ usbdp_phy0_dp_altmode_mux: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dp_altmode_mux>;
+ };
+ };
+};
+
+&usbdp_phy1 {
+ /*
+ * USBDP PHY1 is wired to a female USB3 Type-A connector. Additionally
+ * the differential pairs 2+3 and the aux channel are wired to a RTD2166,
+ * which converts the DP signal into VGA. This is exposed on the
+ * board via a female VGA connector.
+ */
+ rockchip,dp-lane-mux = <2 3>;
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ dr_mode = "otg";
+ usb-role-switch;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dwc3_0_role_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_role_sw>;
+ };
+ };
+};
+
+&usb_host1_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra-pinctrl.dtsi
index 244c66faa161..244c66faa161 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra-pinctrl.dtsi
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
new file mode 100644
index 000000000000..0ce0934ec6b7
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include "rk3588-base.dtsi"
+#include "rk3588-extra-pinctrl.dtsi"
+
+/ {
+ usb_host1_xhci: usb@fc400000 {
+ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+ reg = <0x0 0xfc400000 0x0 0x400000>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
+ <&cru ACLK_USB3OTG1>;
+ clock-names = "ref_clk", "suspend_clk", "bus_clk";
+ dr_mode = "otg";
+ phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ phy_type = "utmi_wide";
+ power-domains = <&power RK3588_PD_USB>;
+ resets = <&cru SRST_A_USB3OTG1>;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ status = "disabled";
+ };
+
+ pcie30_phy_grf: syscon@fd5b8000 {
+ compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
+ reg = <0x0 0xfd5b8000 0x0 0x10000>;
+ };
+
+ pipe_phy1_grf: syscon@fd5c0000 {
+ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfd5c0000 0x0 0x100>;
+ };
+
+ usbdpphy1_grf: syscon@fd5cc000 {
+ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+ reg = <0x0 0xfd5cc000 0x0 0x4000>;
+ };
+
+ usb2phy1_grf: syscon@fd5d4000 {
+ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd5d4000 0x0 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ u2phy1: usb2phy@4000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x4000 0x10>;
+ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy1";
+ interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
+ resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
+ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy1_otg: otg-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+ };
+
+ i2s8_8ch: i2s@fddc8000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddc8000 0x0 0x1000>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S8_8CH_TX>, <&cru MCLK_I2S8_8CH_TX>, <&cru HCLK_I2S8_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S8_8CH_TX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 22>;
+ dma-names = "tx";
+ power-domains = <&power RK3588_PD_VO0>;
+ resets = <&cru SRST_M_I2S8_8CH_TX>;
+ reset-names = "tx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s6_8ch: i2s@fddf4000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddf4000 0x0 0x1000>;
+ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S6_8CH_TX>, <&cru MCLK_I2S6_8CH_TX>, <&cru HCLK_I2S6_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S6_8CH_TX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 4>;
+ dma-names = "tx";
+ power-domains = <&power RK3588_PD_VO1>;
+ resets = <&cru SRST_M_I2S6_8CH_TX>;
+ reset-names = "tx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s7_8ch: i2s@fddf8000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddf8000 0x0 0x1000>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S7_8CH_RX>, <&cru MCLK_I2S7_8CH_RX>, <&cru HCLK_I2S7_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S7_8CH_RX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 21>;
+ dma-names = "rx";
+ power-domains = <&power RK3588_PD_VO1>;
+ resets = <&cru SRST_M_I2S7_8CH_RX>;
+ reset-names = "rx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s10_8ch: i2s@fde00000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfde00000 0x0 0x1000>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru MCLK_I2S10_8CH_RX>, <&cru MCLK_I2S10_8CH_RX>, <&cru HCLK_I2S10_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ assigned-clocks = <&cru CLK_I2S10_8CH_RX_SRC>;
+ assigned-clock-parents = <&cru PLL_AUPLL>;
+ dmas = <&dmac2 24>;
+ dma-names = "rx";
+ power-domains = <&power RK3588_PD_VO1>;
+ resets = <&cru SRST_M_I2S10_8CH_RX>;
+ reset-names = "rx-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ pcie3x4: pcie@fe150000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0x0f>;
+ clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+ <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+ <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ device_type = "pci";
+ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
+ <0 0 0 2 &pcie3x4_intc 1>,
+ <0 0 0 3 &pcie3x4_intc 2>,
+ <0 0 0 4 &pcie3x4_intc 3>;
+ linux,pci-domain = <0>;
+ max-link-speed = <3>;
+ msi-map = <0x0000 &its1 0x0000 0x1000>;
+ num-lanes = <4>;
+ phys = <&pcie30phy>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ ranges = <0x01000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x00100000>,
+ <0x02000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0x00e00000>,
+ <0x03000000 0x0 0x40000000 0x9 0x00000000 0x0 0x40000000>;
+ reg = <0xa 0x40000000 0x0 0x00400000>,
+ <0x0 0xfe150000 0x0 0x00010000>,
+ <0x0 0xf0000000 0x0 0x00100000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
+ reset-names = "pwr", "pipe";
+ status = "disabled";
+
+ pcie3x4_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING 0>;
+ };
+ };
+
+ pcie3x4_ep: pcie-ep@fe150000 {
+ compatible = "rockchip,rk3588-pcie-ep";
+ reg = <0xa 0x40000000 0x0 0x00100000>,
+ <0xa 0x40100000 0x0 0x00100000>,
+ <0x0 0xfe150000 0x0 0x00010000>,
+ <0x9 0x00000000 0x0 0x40000000>,
+ <0xa 0x40300000 0x0 0x00100000>;
+ reg-names = "dbi", "dbi2", "apb", "addr_space", "atu";
+ clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+ <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+ <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err",
+ "dma0", "dma1", "dma2", "dma3";
+ max-link-speed = <3>;
+ num-lanes = <4>;
+ phys = <&pcie30phy>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
+ reset-names = "pwr", "pipe";
+ status = "disabled";
+ };
+
+ pcie3x2: pcie@fe160000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x10 0x1f>;
+ clocks = <&cru ACLK_PCIE_2L_MSTR>, <&cru ACLK_PCIE_2L_SLV>,
+ <&cru ACLK_PCIE_2L_DBI>, <&cru PCLK_PCIE_2L>,
+ <&cru CLK_PCIE_AUX1>, <&cru CLK_PCIE2L_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ device_type = "pci";
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+ <0 0 0 2 &pcie3x2_intc 1>,
+ <0 0 0 3 &pcie3x2_intc 2>,
+ <0 0 0 4 &pcie3x2_intc 3>;
+ linux,pci-domain = <1>;
+ max-link-speed = <3>;
+ msi-map = <0x1000 &its1 0x1000 0x1000>;
+ num-lanes = <2>;
+ phys = <&pcie30phy>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ ranges = <0x01000000 0x0 0xf1100000 0x0 0xf1100000 0x0 0x00100000>,
+ <0x02000000 0x0 0xf1200000 0x0 0xf1200000 0x0 0x00e00000>,
+ <0x03000000 0x0 0x40000000 0x9 0x40000000 0x0 0x40000000>;
+ reg = <0xa 0x40400000 0x0 0x00400000>,
+ <0x0 0xfe160000 0x0 0x00010000>,
+ <0x0 0xf1000000 0x0 0x00100000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
+ reset-names = "pwr", "pipe";
+ status = "disabled";
+
+ pcie3x2_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 255 IRQ_TYPE_EDGE_RISING 0>;
+ };
+ };
+
+ pcie2x1l0: pcie@fe170000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ bus-range = <0x20 0x2f>;
+ clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>,
+ <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>,
+ <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ device_type = "pci";
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>,
+ <0 0 0 2 &pcie2x1l0_intc 1>,
+ <0 0 0 3 &pcie2x1l0_intc 2>,
+ <0 0 0 4 &pcie2x1l0_intc 3>;
+ linux,pci-domain = <2>;
+ max-link-speed = <2>;
+ msi-map = <0x2000 &its0 0x2000 0x1000>;
+ num-lanes = <1>;
+ phys = <&combphy1_ps PHY_TYPE_PCIE>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>,
+ <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>,
+ <0x03000000 0x0 0x40000000 0x9 0x80000000 0x0 0x40000000>;
+ reg = <0xa 0x40800000 0x0 0x00400000>,
+ <0x0 0xfe170000 0x0 0x00010000>,
+ <0x0 0xf2000000 0x0 0x00100000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>;
+ reset-names = "pwr", "pipe";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ status = "disabled";
+
+ pcie2x1l0_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_EDGE_RISING 0>;
+ };
+ };
+
+ gmac0: ethernet@fe1b0000 {
+ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+ reg = <0x0 0xfe1b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+ <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
+ <&cru CLK_GMAC0_PTP_REF>;
+ clock-names = "stmmaceth", "clk_mac_ref",
+ "pclk_mac", "aclk_mac",
+ "ptp_ref";
+ power-domains = <&power RK3588_PD_GMAC>;
+ resets = <&cru SRST_A_GMAC0>;
+ reset-names = "stmmaceth";
+ rockchip,grf = <&sys_grf>;
+ rockchip,php-grf = <&php_grf>;
+ snps,axi-config = <&gmac0_stmmac_axi_setup>;
+ snps,mixed-burst;
+ snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
+ snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
+ snps,tso;
+ status = "disabled";
+
+ mdio0: mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ };
+
+ gmac0_stmmac_axi_setup: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,wr_osr_lmt = <4>;
+ snps,rd_osr_lmt = <8>;
+ };
+
+ gmac0_mtl_rx_setup: rx-queues-config {
+ snps,rx-queues-to-use = <2>;
+ queue0 {};
+ queue1 {};
+ };
+
+ gmac0_mtl_tx_setup: tx-queues-config {
+ snps,tx-queues-to-use = <2>;
+ queue0 {};
+ queue1 {};
+ };
+ };
+
+ sata1: sata@fe220000 {
+ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+ reg = <0 0xfe220000 0 0x1000>;
+ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
+ <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>,
+ <&cru CLK_PIPEPHY1_PIPE_ASIC_G>;
+ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+ ports-implemented = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ sata-port@0 {
+ reg = <0>;
+ hba-port-cap = <HBA_PORT_FBSCP>;
+ phys = <&combphy1_ps PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ snps,rx-ts-max = <32>;
+ snps,tx-ts-max = <32>;
+ };
+ };
+
+ usbdp_phy1: phy@fed90000 {
+ compatible = "rockchip,rk3588-usbdp-phy";
+ reg = <0x0 0xfed90000 0x0 0x10000>;
+ #phy-cells = <1>;
+ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+ <&cru CLK_USBDP_PHY1_IMMORTAL>,
+ <&cru PCLK_USBDPPHY1>,
+ <&u2phy1>;
+ clock-names = "refclk", "immortal", "pclk", "utmi";
+ resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
+ <&cru SRST_USBDP_COMBO_PHY1_CMN>,
+ <&cru SRST_USBDP_COMBO_PHY1_LANE>,
+ <&cru SRST_USBDP_COMBO_PHY1_PCS>,
+ <&cru SRST_P_USBDPPHY1>;
+ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+ rockchip,u2phy-grf = <&usb2phy1_grf>;
+ rockchip,usb-grf = <&usb_grf>;
+ rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
+ rockchip,vo-grf = <&vo0_grf>;
+ status = "disabled";
+ };
+
+ combphy1_ps: phy@fee10000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee10000 0x0 0x100>;
+ clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>,
+ <&cru PCLK_PHP_ROOT>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&cru CLK_REF_PIPE_PHY1>;
+ assigned-clock-rates = <100000000>;
+ #phy-cells = <1>;
+ resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>;
+ reset-names = "phy", "apb";
+ rockchip,pipe-grf = <&php_grf>;
+ rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
+ status = "disabled";
+ };
+
+ pcie30phy: phy@fee80000 {
+ compatible = "rockchip,rk3588-pcie3-phy";
+ reg = <0x0 0xfee80000 0x0 0x20000>;
+ #phy-cells = <0>;
+ clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>;
+ clock-names = "pclk";
+ resets = <&cru SRST_PCIE30_PHY>;
+ reset-names = "phy";
+ rockchip,pipe-grf = <&php_grf>;
+ rockchip,phy-grf = <&pcie30_phy_grf>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi
new file mode 100644
index 000000000000..47e64d547ea9
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "rk3588.dtsi"
+
+/ {
+ compatible = "forlinx,fet3588-c", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_rgb_b>;
+
+ io-led {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie20_avdd0v85";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ vin-supply = <&vdd_0v85_s0>;
+ };
+
+ pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie20_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&avcc_1v8_s0>;
+ };
+
+ pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd0v75";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ vin-supply = <&avdd_0v75_s0>;
+ };
+
+ pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&avcc_1v8_s0>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc4v0_sys: vcc4v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc4v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ mem-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ mem-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+ mem-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+ mem-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1m2_xfer>;
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&pinctrl {
+ leds {
+ led_rgb_b: led-rgb-b {
+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdhci {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ no-sdio;
+ no-sd;
+ non-removable;
+ status = "okay";
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ num-cs = <1>;
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ system-power-controller;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
new file mode 100644
index 000000000000..83103e4c7216
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
@@ -0,0 +1,778 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Thomas McKahan
+ * Copyright (c) 2024 Sebastian Kropatsch
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588-friendlyelec-cm3588.dtsi"
+
+/ {
+ model = "FriendlyElec CM3588 NAS";
+ compatible = "friendlyarm,cm3588-nas", "friendlyarm,cm3588", "rockchip,rk3588";
+
+ adc_key_recovery: adc-key-recovery {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <17000>;
+ };
+ };
+
+ analog-sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&headphone_detect>;
+
+ simple-audio-card,format = "i2s";
+ simple-audio-card,hp-det-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,name = "realtek,rt5616-codec";
+
+ simple-audio-card,routing =
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "MIC1", "Microphone Jack",
+ "Microphone Jack", "micbias1";
+ simple-audio-card,widgets =
+ "Headphone", "Headphones",
+ "Microphone", "Microphone Jack";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&rt5616>;
+ };
+ };
+
+ buzzer: pwm-beeper {
+ compatible = "pwm-beeper";
+ amp-supply = <&vcc_5v0_sys>;
+ beeper-hz = <500>;
+ pwms = <&pwm8 0 500000 0>;
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ #cooling-cells = <2>;
+ cooling-levels = <0 50 80 120 160 220>;
+ fan-supply = <&vcc_5v0_sys>;
+ pwms = <&pwm1 0 50000 0>;
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key1_pin>;
+
+ button-user {
+ debounce-interval = <50>;
+ gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_LOW>;
+ label = "User Button";
+ linux,code = <BTN_1>;
+ wakeup-source;
+ };
+ };
+
+ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
+ };
+
+ vcc_12v_dcin: regulator-vcc-12v-dcin {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_12v_dcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc_3v3_m2_a: regulator-vcc-3v3-m2-a {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_m2_a";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_12v_dcin>;
+ };
+
+ vcc_3v3_m2_b: regulator-vcc-3v3-m2-b {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_m2_b";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_12v_dcin>;
+ };
+
+ vcc_3v3_m2_c: regulator-vcc-3v3-m2-c {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_m2_c";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_12v_dcin>;
+ };
+
+ vcc_3v3_m2_d: regulator-vcc-3v3-m2-d {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_m2_d";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_12v_dcin>;
+ };
+
+ /* vcc_5v0_sys powers the peripherals */
+ vcc_5v0_sys: regulator-vcc-5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_12v_dcin>;
+ };
+
+ /* SY6280AAC power switch (U14 in schematics) */
+ vcc_5v0_host_20: regulator-vcc-5v0-host-20 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_5v0_host20_en>;
+ regulator-name = "vcc_5v0_host_20";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v0_sys>;
+ };
+
+ /* SY6280AAC power switch (U8 in schematics) */
+ vcc_5v0_host_30_p1: regulator-vcc-5v0-host-30-p1 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_5v0_host30p1_en>;
+ regulator-name = "vcc_5v0_host_30_p1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v0_sys>;
+ };
+
+ /* SY6280AAC power switch (U9 in schematics) */
+ vcc_5v0_host_30_p2: regulator-vcc-5v0-host-30-p2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_5v0_host30p2_en>;
+ regulator-name = "vcc_5v0_host_30_p2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v0_sys>;
+ };
+
+ /* SY6280AAC power switch (U10 in schematics) */
+ vbus_5v0_typec: regulator-vbus-5v0-typec {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec_5v_pwr_en>;
+ regulator-name = "vbus_5v0_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v0_sys>;
+ };
+};
+
+/* vcc_4v0_sys powers the RK806 and RK860's */
+&vcc_4v0_sys {
+ vin-supply = <&vcc_12v_dcin>;
+};
+
+/* Combo PHY 1 is configured to act as as PCIe 2.0 PHY */
+/* Used by PCIe controller 2 (pcie2x1l0) */
+&combphy1_ps {
+ status = "okay";
+};
+
+/* Combo PHY 2 is configured to act as USB3 PHY */
+/* Used by USB 3.0 OTG 2 controller (USB 3.0 Type-A port 2) */
+/* CM3588 USB Controller Config Table: USB30 HOST2 */
+&combphy2_psu {
+ status = "okay";
+};
+
+/* GPIO names are in the format "Human-readable-name [SIGNAL_LABEL]" */
+/* Signal labels match the official CM3588 NAS SDK schematic revision 2309 */
+&gpio0 {
+ gpio-line-names =
+ /* GPIO0 A0-A7 */
+ "", "", "", "",
+ "MicroSD detect [SDMMC_DET_L]", "", "", "",
+ /* GPIO0 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO0 C0-C7 */
+ "", "", "", "",
+ "Pin 10 [UART0_RX_M0]", "Pin 08 [UART0_TX_M0/PWM4_M0]", "Pin 32 [PWM5_M1]", "",
+ /* GPIO0 D0-D7 */
+ "", "", "", "USB3 Type-C [CC_INT_L]",
+ "IR receiver [PWM3_IR_M0]", "User Button", "", "";
+};
+
+&gpio1 {
+ gpio-line-names =
+ /* GPIO1 A0-A7 */
+ "Pin 27 [UART6_RX_M1]", "Pin 28 [UART6_TX_M1]", "", "",
+ "USB2 Type-A [USB2_PWREN]", "", "", "Pin 15",
+ /* GPIO1 B0-B7 */
+ "Pin 26", "Pin 21 [SPI0_MISO_M2]", "Pin 19 [SPI0_MOSI_M2/UART4_RX_M2]", "Pin 23 [SPI0_CLK_M2/UART4_TX_M2]",
+ "Pin 24 [SPI0_CS0_M2/UART7_RX_M2]", "Pin 22 [SPI0_CS1_M0/UART7_TX_M2]", "", "CSI-Pin 14 [MIPI_CAM2_CLKOUT]",
+ /* GPIO1 C0-C7 */
+ "", "", "", "",
+ "Headphone detect [HP_DET_L]", "", "", "",
+ /* GPIO1 D0-D7 */
+ "", "", "USB3 Type-C [TYPEC5V_PWREN_H]", "5V Fan [PWM1_M1]",
+ "", "HDMI-in detect [HDMIIRX_DET_L]", "Pin 05 [I2C8_SCL_M2]", "Pin 03 [I2C8_SDA_M2]";
+};
+
+&gpio2 {
+ gpio-line-names =
+ /* GPIO2 A0-A7 */
+ "", "", "", "",
+ "", "", "SPI NOR Flash [FSPI_D0_M1]", "SPI NOR Flash [FSPI_D1_M1]",
+ /* GPIO2 B0-B7 */
+ "SPI NOR Flash [FSPI_D2_M1]", "SPI NOR Flash [FSPI_D3_M1]", "", "SPI NOR Flash [FSPI_CLK_M1]",
+ "SPI NOR Flash [FSPI_CSN0_M1]", "", "", "",
+ /* GPIO2 C0-C7 */
+ "", "CSI-Pin 11 [MIPI_CAM2_RESET_L]", "CSI-Pin 12 [MIPI_CAM2_PDN_L]", "",
+ "", "", "", "",
+ /* GPIO2 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio3 {
+ gpio-line-names =
+ /* GPIO3 A0-A7 */
+ "Pin 35 [SPI4_MISO_M1/PWM10_M0]", "Pin 38 [SPI4_MOSI_M1]", "Pin 40 [SPI4_CLK_M1/UART8_TX_M1]", "Pin 36 [SPI4_CS0_M1/UART8_RX_M1]",
+ "Pin 37 [SPI4_CS1_M1]", "USB3-A #2 [USB3_2_PWREN]", "DSI-Pin 12 [LCD_RST]", "Buzzer [PWM8_M0]",
+ /* GPIO3 B0-B7 */
+ "Pin 33 [PWM9_M0]", "DSI-Pin 10 [PWM2_M1/LCD_BL]", "Pin 07", "Pin 16",
+ "Pin 18", "Pin 29 [UART3_TX_M1/PWM12_M0]", "Pin 31 [UART3_RX_M1/PWM13_M0]", "Pin 12",
+ /* GPIO3 C0-C7 */
+ "DSI-Pin 08 [TP_INT_L]", "DSI-Pin 14 [TP_RST_L]", "Pin 11 [PWM14_M0]", "Pin 13 [PWM15_IR_M0]",
+ "", "", "", "DSI-Pin 06 [I2C5_SCL_M0_TP]",
+ /* GPIO3 D0-D7 */
+ "DSI-Pin 05 [I2C5_SDA_M0_TP]", "", "", "",
+ "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names =
+ /* GPIO4 A0-A7 */
+ "", "", "M.2 M-Key Slot4 [M2_D_PERST_L]", "",
+ "", "", "", "",
+ /* GPIO4 B0-B7 */
+ "USB3-A #1 [USB3_TYPEC1_PWREN]", "", "", "M.2 M-Key Slot3 [M2_C_PERST_L]",
+ "M.2 M-Key Slot2 [M2_B_PERST_L]", "M.2 M-Key Slot1 [M2_A_CLKREQ_L]", "M.2 M-Key Slot1 [M2_A_PERST_L]", "",
+ /* GPIO4 C0-C7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO4 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+/* Connected to MIPI-DSI0 */
+&i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5m0_xfer>;
+ status = "disabled";
+};
+
+&i2c6 {
+ fusb302: typec-portc@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbc0_int>;
+ vbus-supply = <&vbus_5v0_typec>;
+
+ usb_con: connector {
+ compatible = "usb-c-connector";
+ data-role = "dual";
+ label = "USB-C";
+ power-role = "source";
+ source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
+ try-power-role = "source";
+ vbus-supply = <&vbus_5v0_typec>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usbc0_orien_sw: endpoint {
+ remote-endpoint = <&usbdp_phy0_orientation_switch>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usbc0_role_sw: endpoint {
+ remote-endpoint = <&dwc3_0_role_switch>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ dp_altmode_mux: endpoint {
+ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+ };
+ };
+ };
+ };
+ };
+};
+
+/* Connected to MIPI-CSI1 */
+/* &i2c7 */
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+&i2c8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8m2_xfer>;
+ status = "okay";
+};
+
+&pcie2x1l0 {
+ /* 2. M.2 socket, CON14: pcie30phy port0 lane1, @fe170000 */
+ max-link-speed = <3>;
+ num-lanes = <1>;
+ phys = <&pcie30phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_rst>;
+ reset-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_m2_b>;
+ status = "okay";
+};
+
+&pcie2x1l1 {
+ /* 4. M.2 socket, CON16: pcie30phy port1 lane1, @fe180000 */
+ max-link-speed = <3>;
+ num-lanes = <1>;
+ phys = <&pcie30phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_rst>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_m2_d>;
+ status = "okay";
+};
+
+&pcie30phy {
+ /*
+ * Data lane mapping <1 3 2 4> = x1x1 x1x1 (bifurcation of both ports)
+ * port 0 lane 0 - always mapped to controller 0 (4L)
+ * port 0 lane 1 - map to controller 2 (1L0)
+ * port 1 lane 0 - map to controller 1 (2L)
+ * port 1 lane 1 - map to controller 3 (1L1)
+ */
+ data-lanes = <1 3 2 4>;
+ status = "okay";
+};
+
+&pcie3x4 {
+ /* 1. M.2 socket, CON13: pcie30phy port0 lane0, @fe150000 */
+ max-link-speed = <3>;
+ num-lanes = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3x4_rst>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_m2_a>;
+ status = "okay";
+};
+
+&pcie3x2 {
+ /* 3. M.2 socket, CON15: pcie30phy port1 lane0, @fe160000 */
+ max-link-speed = <3>;
+ num-lanes = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3x2_rst>;
+ reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_m2_c>;
+ status = "okay";
+};
+
+&pinctrl {
+ audio {
+ headphone_detect: headphone-detect {
+ rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gpio-key {
+ key1_pin: key1-pin {
+ rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pcie {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_1_rst: pcie2-1-rst {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3x2_rst: pcie3x2-rst {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3x4_rst: pcie3x4-rst {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc_5v0_host20_en: vcc-5v0-host20-en {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc_5v0_host30p1_en: vcc-5v0-host30p1-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc_5v0_host30p2_en: vcc-5v0-host30p2-en {
+ rockchip,pins = <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb-typec {
+ usbc0_int: usbc0-int {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ typec_5v_pwr_en: typec-5v-pwr-en {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+/* Connected to 5V Fan */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1m1_pins>;
+ status = "okay";
+};
+
+/* Connected to MIPI-DSI0 */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2m1_pins>;
+};
+
+/* Connected to IR Receiver */
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3m0_pins>;
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with UART0 */
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm4m1_pins>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+&pwm5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm5m1_pins>;
+ status = "okay";
+};
+
+/* Connected to Buzzer */
+&pwm8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm8m0_pins>;
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+&pwm9 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm9m0_pins>;
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with SPI4 */
+&pwm10 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm10m0_pins>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with UART3 */
+&pwm12 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm12m0_pins>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with UART3 */
+&pwm13 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm13m0_pins>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+&pwm14 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm14m0_pins>;
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Optimized for infrared applications */
+&pwm15 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm15m0_pins>;
+ status = "disabled";
+};
+
+/* microSD card */
+&sdmmc {
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with UART4, UART7 and PWM10 */
+&spi0 {
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0m2_cs0 &spi0m2_pins>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with UART8 */
+&spi4 {
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi4m1_cs0 &spi4m1_pins>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with PWM4 */
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0m0_xfer>;
+ status = "disabled";
+};
+
+/* Debug UART */
+&uart2 {
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with PWM12 and PWM13 */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3m1_xfer>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with SPI0 */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4m2_xfer>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+&uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart6m1_xfer>;
+ status = "okay";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with SPI0 */
+&uart7 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart7m2_xfer>;
+ status = "disabled";
+};
+
+/* GPIO Connector, connected to 40-pin GPIO header */
+/* Shared with SPI4 */
+&uart8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart8m1_xfer>;
+ status = "disabled";
+};
+
+/* USB2 PHY for USB Type-C port */
+/* CM3588 USB Controller Config Table: USB20 OTG0 */
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ phy-supply = <&vbus_5v0_typec>;
+ status = "okay";
+};
+
+/* USB2 PHY for USB 3.0 Type-A port 1 */
+/* CM3588 USB Controller Config Table: USB20 OTG1 */
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ phy-supply = <&vcc_5v0_host_30_p1>;
+ status = "okay";
+};
+
+/* USB2 PHY for USB 2.0 Type-A */
+/* CM3588 USB Controller Config Table: USB20 HOST0 */
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc_5v0_host_20>;
+ status = "okay";
+};
+
+/* USB2 PHY for USB 3.0 Type-A port 2 */
+/* CM3588 USB Controller Config Table: USB20 HOST1 */
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc_5v0_host_30_p2>;
+ status = "okay";
+};
+
+/* USB 2.0 Type-A */
+/* PHY: <&u2phy2_host> */
+&usb_host0_ehci {
+ status = "okay";
+};
+
+/* USB 2.0 Type-A */
+/* PHY: <&u2phy2_host> */
+&usb_host0_ohci {
+ status = "okay";
+};
+
+/* USB Type-C */
+/* PHYs: <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3> */
+&usb_host0_xhci {
+ usb-role-switch;
+ status = "okay";
+
+ port {
+ dwc3_0_role_switch: endpoint {
+ remote-endpoint = <&usbc0_role_sw>;
+ };
+ };
+};
+
+/* Lower USB 3.0 Type-A (port 2) */
+/* PHY: <&u2phy3_host> */
+&usb_host1_ehci {
+ status = "okay";
+};
+
+/* Lower USB 3.0 Type-A (port 2) */
+/* PHY: <&u2phy3_host> */
+&usb_host1_ohci {
+ status = "okay";
+};
+
+/* Upper USB 3.0 Type-A (port 1) */
+/* PHYs: <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3> */
+&usb_host1_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* Lower USB 3.0 Type-A (port 2) */
+/* PHYs: <&combphy2_psu PHY_TYPE_USB3> */
+&usb_host2_xhci {
+ status = "okay";
+};
+
+/* USB3 PHY for USB Type-C port */
+/* CM3588 USB Controller Config Table: USB30 OTG0 */
+&usbdp_phy0 {
+ mode-switch;
+ orientation-switch;
+ sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+ sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbdp_phy0_orientation_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_orien_sw>;
+ };
+
+ usbdp_phy0_dp_altmode_mux: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dp_altmode_mux>;
+ };
+ };
+};
+
+/* USB3 PHY for USB 3.0 Type-A port 1 */
+/* CM3588 USB Controller Config Table: USB30 OTG1 */
+&usbdp_phy1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi
new file mode 100644
index 000000000000..e3a9598b99fc
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi
@@ -0,0 +1,653 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Thomas McKahan
+ * Copyright (c) 2024 Sebastian Kropatsch
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "FriendlyElec CM3588";
+ compatible = "friendlyarm,cm3588", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_sys: led-0 {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_sys_pin>;
+ };
+
+ led_usr: led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_usr_pin>;
+ };
+ };
+
+ /* vcc_4v0_sys powers the RK806 and RK860's */
+ vcc_4v0_sys: regulator-vcc-4v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_4v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ };
+
+ vcc_3v3_pcie20: regulator-vcc-3v3-pcie20 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_pcie20";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc_3v3_sd_s0: regulator-vcc-3v3-sd-s0 {
+ compatible = "regulator-fixed";
+ gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_s0_pwr>;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_sd_s0";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-1v1-nldo-s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc_4v0_sys>;
+ };
+};
+
+/* Combo PHY 0 is configured to act as as PCIe 2.0 PHY */
+/* Used by PCIe controller 4 (pcie2x1l2) */
+&combphy0_ps {
+ status = "okay";
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ sram-supply = <&vdd_gpu_mem_s0>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ clock-frequency = <200000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6m0_xfer>;
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ wakeup-source;
+ };
+};
+
+&i2c7 {
+ clock-frequency = <200000>;
+ status = "okay";
+
+ rt5616: audio-codec@1b {
+ compatible = "realtek,rt5616";
+ reg = <0x1b>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+};
+
+&i2s5_8ch {
+ status = "okay";
+};
+
+&i2s6_8ch {
+ status = "okay";
+};
+
+&i2s7_8ch {
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ /* r8125 ethernet, @fe190000 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+ reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_pcie20>;
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-leds {
+ led_sys_pin: led-sys-pin {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ led_usr_pin: led-usr-pin {
+ rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: rtc-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pcie {
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sd_s0_pwr: sd-s0-pwr {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+/* eMMC */
+&sdhci {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ no-sd;
+ no-sdio;
+ non-removable;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ status = "okay";
+};
+
+/* microSD card */
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ status = "okay";
+
+ rk806_single: pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ spi-max-frequency = <1000000>;
+ system-power-controller;
+
+ vcc1-supply = <&vcc_4v0_sys>;
+ vcc2-supply = <&vcc_4v0_sys>;
+ vcc3-supply = <&vcc_4v0_sys>;
+ vcc4-supply = <&vcc_4v0_sys>;
+ vcc5-supply = <&vcc_4v0_sys>;
+ vcc6-supply = <&vcc_4v0_sys>;
+ vcc7-supply = <&vcc_4v0_sys>;
+ vcc8-supply = <&vcc_4v0_sys>;
+ vcc9-supply = <&vcc_4v0_sys>;
+ vcc10-supply = <&vcc_4v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc_4v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc_4v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+/* Debug UART */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2m0_xfer>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
index 39d65002add1..31d2f8994f85 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
@@ -72,6 +72,27 @@
};
};
+ /*
+ * 100MHz reference clock for PCIe peripherals from PI6C557-05BLE
+ * clock generator.
+ * The clock output is gated via the OE pin on the clock generator.
+ * This is modeled as a fixed-clock plus a gpio-gate-clock.
+ */
+ pcie_refclk_gen: pcie-refclk-gen-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ pcie_refclk: pcie-refclk-clock {
+ compatible = "gpio-gate-clock";
+ clocks = <&pcie_refclk_gen>;
+ #clock-cells = <0>;
+ enable-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>; /* PCIE30X4_CLKREQN_M0 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x4_clkreqn_m0>;
+ };
+
pps {
compatible = "pps-gpio";
gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
@@ -245,6 +266,11 @@
};
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
&i2c0 {
pinctrl-0 = <&i2c0m2_xfer>;
status = "okay";
@@ -353,6 +379,30 @@
status = "okay";
};
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ /*
+ * The board has a gpio-controlled "pcie_refclk" generator,
+ * so add it to the list of clocks.
+ */
+ clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+ <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+ <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>,
+ <&pcie_refclk>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe",
+ "ref";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x4_waken_m0 &pcie30x4_perstn_m0>;
+ reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_HIGH>; /* PCIE30X4_PERSTN_M0 */
+ vpcie3v3-supply = <&vcc3v3_mdot2>;
+ status = "okay";
+};
+
&pinctrl {
emmc {
emmc_reset: emmc-reset {
@@ -371,6 +421,20 @@
rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ pcie30x4 {
+ pcie30x4_clkreqn_m0: pcie30x4-clkreqn-m0 {
+ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30x4_perstn_m0: pcie30x4-perstn-m0 {
+ rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30x4_waken_m0: pcie30x4-waken-m0 {
+ rockchip,pins = <0 RK_PC7 12 &pcfg_pull_none>;
+ };
+ };
};
&saradc {
@@ -452,7 +516,7 @@
vcca-supply = <&vcc5v0_sys>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
new file mode 100644
index 000000000000..c2a08bdf09e8
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include "rk3588-fet3588-c.dtsi"
+
+/ {
+ model = "Forlinx OK3588-C Board";
+ compatible = "forlinx,ok3588-c", "forlinx,fet3588-c", "rockchip,rk3588";
+
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ mmc1 = &sdmmc;
+ };
+
+ adc-keys-0 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-maskrom {
+ label = "Maskrom";
+ linux,code = <KEY_SETUP>;
+ press-threshold-microvolt = <400>;
+ };
+ };
+
+ adc-keys-1 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-volume-up {
+ label = "V+/Recovery";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <17000>;
+ };
+
+ button-volume-down {
+ label = "V-";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <417000>;
+ };
+
+ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <890000>;
+ };
+
+ button-escape {
+ label = "ESC";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1235000>;
+ };
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 95 145 195 255>;
+ fan-supply = <&vcc12v_dcin>;
+ pwms = <&pwm2 0 50000 0>;
+ #cooling-cells = <2>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_detect>;
+ simple-audio-card,name = "RK3588 OK3588-C Audio";
+ simple-audio-card,bitclock-master = <&masterdai>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&masterdai>;
+ simple-audio-card,hp-det-gpio = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,pin-switches = "Headphones", "Speaker";
+ simple-audio-card,widgets =
+ "Headphones", "Headphones",
+ "Speaker", "Speaker",
+ "Microphone", "Internal Microphone",
+ "Microphone", "Headset Microphone";
+ simple-audio-card,routing =
+ "Headphones", "LHP",
+ "Headphones", "RHP",
+ "Speaker", "LSPK",
+ "Speaker", "RSPK",
+ "LMICP", "Headset Microphone",
+ "RMICP", "Internal Microphone";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ };
+
+ masterdai: simple-audio-card,codec {
+ sound-dai = <&nau8822>;
+ };
+ };
+
+ vcc12v_dcin: vcc12v-dcin-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc12v_dcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc1v8_sys: vcc1v8-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc1v8_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie30: vcc3v3_pcie30-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie30";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_sys: vcc3v3-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+};
+
+&gmac0 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy0>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus>;
+ tx_delay = <0x44>;
+ rx_delay = <0x00>;
+ status = "okay";
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ tx_delay = <0x44>;
+ rx_delay = <0x00>;
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+
+ tca6424a: gpio@23 {
+ compatible = "ti,tca6424";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tca6424a_int>;
+ vcc-supply = <&vcc3v3_sys>;
+ };
+};
+
+&i2c5 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5m2_xfer>;
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ nau8822: audio-codec@1a {
+ compatible = "nuvoton,nau8822";
+ reg = <0x1a>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+};
+
+&mdio0 {
+ rgmii_phy0: ethernet-phy@1 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8211f_0_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@2 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8211f_1_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1l0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_rst>;
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_rst>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ pcie2 {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_rst: pcie3-rst {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ rtl8211f {
+ rtl8211f_0_rst: rtl8211f-0-rst {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ rtl8211f_1_rst: rtl8211f-1-rst {
+ rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ tca6424a {
+ tca6424a_int: tca6424a-int {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
new file mode 100644
index 000000000000..0f1a77697351
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/ {
+ cluster0_opp_table: opp-table-cluster0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt = <675000 675000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <712500 712500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <762500 762500 950000>;
+ clock-latency-ns = <40000>;
+ opp-suspend;
+ };
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <850000 850000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <950000 950000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ cluster1_opp_table: opp-table-cluster1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <675000 675000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <725000 725000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <762500 762500 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <850000 850000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <925000 925000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-microvolt = <987500 987500 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2400000000 {
+ opp-hz = /bits/ 64 <2400000000>;
+ opp-microvolt = <1000000 1000000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ cluster2_opp_table: opp-table-cluster2 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <675000 675000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <725000 725000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <762500 762500 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <850000 850000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <925000 925000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-microvolt = <987500 987500 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2400000000 {
+ opp-hz = /bits/ 64 <2400000000>;
+ opp-microvolt = <1000000 1000000 1000000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <675000 675000 850000>;
+ };
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <675000 675000 850000>;
+ };
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <675000 675000 850000>;
+ };
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <675000 675000 850000>;
+ };
+ opp-700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <700000 700000 850000>;
+ };
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+ opp-900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = <800000 800000 850000>;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <850000 850000 850000>;
+ };
+ };
+};
+
+&cpu_b0 {
+ operating-points-v2 = <&cluster1_opp_table>;
+};
+
+&cpu_b1 {
+ operating-points-v2 = <&cluster1_opp_table>;
+};
+
+&cpu_b2 {
+ operating-points-v2 = <&cluster2_opp_table>;
+};
+
+&cpu_b3 {
+ operating-points-v2 = <&cluster2_opp_table>;
+};
+
+&cpu_l0 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&cpu_l1 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&cpu_l2 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&cpu_l3 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&gpu {
+ operating-points-v2 = <&gpu_opp_table>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
index 1a604429fb26..e74871491ef5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -444,6 +444,7 @@
&sdmmc {
bus-width = <4>;
cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
disable-wp;
max-frequency = <150000000>;
no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
index 22bbfbe729c1..e4a20cda65ed 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
@@ -13,7 +13,7 @@
#include "rk3588.dtsi"
/ {
- model = "PINE64 QuartzPro64";
+ model = "Pine64 QuartzPro64";
compatible = "pine64,quartzpro64", "rockchip,rk3588";
aliases {
@@ -285,6 +285,12 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ sram-supply = <&vdd_gpu_mem_s0>;
+ status = "okay";
+};
+
&i2c2 {
status = "okay";
@@ -429,6 +435,7 @@
&sdmmc {
bus-width = <4>;
cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
disable-wp;
max-frequency = <150000000>;
no-sdio;
@@ -492,11 +499,15 @@
regulators {
vdd_gpu_s0: dcdc-reg1 {
regulator-name = "vdd_gpu_s0";
+ /* regulator coupling requires always-on */
+ regulator-always-on;
regulator-boot-on;
regulator-enable-ramp-delay = <400>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
+ regulator-coupled-with = <&vdd_gpu_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-state-mem {
regulator-off-in-suspend;
@@ -546,11 +557,15 @@
vdd_gpu_mem_s0: dcdc-reg5 {
regulator-name = "vdd_gpu_mem_s0";
+ /* regulator coupling requires always-on */
+ regulator-always-on;
regulator-boot-on;
regulator-enable-ramp-delay = <400>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
+ regulator-coupled-with = <&vdd_gpu_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-state-mem {
regulator-off-in-suspend;
@@ -818,6 +833,8 @@
regulator-name = "vdd_cpu_big1_s0";
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big1_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -831,6 +848,8 @@
regulator-name = "vdd_cpu_big0_s0";
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big0_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -844,6 +863,8 @@
regulator-name = "vdd_cpu_lit_s0";
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_lit_mem_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
@@ -870,6 +891,8 @@
regulator-name = "vdd_cpu_big1_mem_s0";
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big1_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -884,6 +907,8 @@
regulator-name = "vdd_cpu_big0_mem_s0";
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_big0_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <12500>;
@@ -910,6 +935,8 @@
regulator-name = "vdd_cpu_lit_mem_s0";
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&vdd_cpu_lit_s0>;
+ regulator-coupled-max-spread = <10000>;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
new file mode 100644
index 000000000000..d0b922b8d67e
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -0,0 +1,1177 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Radxa Limited
+ * Copyright (c) 2024 Heiko Stuebner <heiko@sntech.de>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "dt-bindings/usb/pd.h"
+#include "rk3588.dtsi"
+
+/ {
+ model = "Radxa ROCK 5 ITX";
+ compatible = "radxa,rock-5-itx", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc_keys: adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-maskrom {
+ label = "Mask Rom";
+ linux,code = <KEY_SETUP>;
+ press-threshold-microvolt = <1750>;
+ };
+ };
+
+ analog-sound {
+ compatible = "audio-graph-card";
+ label = "rk3588-es8316";
+ dais = <&i2s0_8ch_p0>;
+ hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_detect>;
+ routing = "MIC2", "Mic Jack",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR";
+ widgets = "Microphone", "Mic Jack",
+ "Headphone", "Headphones";
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ power-led1 {
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ hdd-led2 {
+ gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "disk-activity";
+ };
+ };
+
+ fan0: pwm-fan {
+ compatible = "pwm-fan";
+ #cooling-cells = <2>;
+ cooling-levels = <0 64 128 192 255>;
+ fan-supply = <&vcc12v_dcin>;
+ pwms = <&pwm14 0 10000 0>;
+ };
+
+ /* M.2 E-KEY */
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&hym8563>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
+ };
+
+ typec_vin: regulator-typec-vin {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vbus5v0_typec_en>;
+ regulator-name = "typec_vin";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc12v_dcin: regulator-vcc12v-dcin {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc12v_dcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc33_io64: regulator-vcc33-io64 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc33_io64";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc3v3_ekey: regulator-vcc3v3-ekey {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ekey_en>;
+ regulator-name = "vcc3v3_ekey";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_lan: vcc3v3_lan_phy2: regulator-vcc3v3-lan {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_lan";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_mkey: regulator-vcc3v3-mkey {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x4_pwren_h>;
+ regulator-name = "vcc3v3_mkey";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_sys: regulator-vcc3v3-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc5v0_sys: regulator-vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc5v0_usb20: vcc5v0_usb12: vcc5v0_usb34: regulator-vcc5v0-usb {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_host_pwren_h>;
+ regulator-name = "vcc5v0_usb";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1m2_xfer>;
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+/* CAM0 connector */
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3m0_xfer>;
+};
+
+/* M.2 E-key */
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4m1_xfer>;
+};
+
+/* RTC and LCD0 connector */
+&i2c6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6m0_xfer>;
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "wifi_32kout";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ };
+};
+
+/* Audio codec and CAM1 connector */
+&i2c7 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7m0_xfer>;
+ status = "okay";
+
+ es8316: audio-codec@11 {
+ compatible = "everest,es8316";
+ reg = <0x11>;
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+
+ port {
+ es8316_p0_0: endpoint {
+ remote-endpoint = <&i2s0_8ch_p0_0>;
+ };
+ };
+ };
+};
+
+/* FUSB302 and LCD1 connector */
+&i2c8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8m4_xfer>;
+ status = "okay";
+
+ usbc0: usb-typec@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbc0_int>;
+ vbus-supply = <&typec_vin>;
+
+ usb_con: connector {
+ compatible = "usb-c-connector";
+ data-role = "dual";
+ label = "USB-C";
+ power-role = "source";
+ source-pdos =
+ <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usbc0_orien_sw: endpoint {
+ remote-endpoint = <&usbdp_phy0_orientation_switch>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usbc0_role_sw: endpoint {
+ remote-endpoint = <&dwc3_0_role_switch>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ dp_altmode_mux: endpoint {
+ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&i2c8m4_xfer {
+ rockchip,pins =
+ /* i2c8_scl_m4 */
+ <3 RK_PC2 9 &pcfg_pull_up_drv_level_6>,
+ /* i2c8_sda_m4 */
+ <3 RK_PC3 9 &pcfg_pull_up_drv_level_6>;
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+
+ i2s0_8ch_p0: port {
+ i2s0_8ch_p0_0: endpoint {
+ dai-format = "i2s";
+ mclk-fs = <256>;
+ remote-endpoint = <&es8316_p0_0>;
+ };
+ };
+};
+
+&package_thermal {
+ polling-delay = <1000>;
+
+ trips {
+ package_fan0: package-fan0 {
+ hysteresis = <2000>;
+ temperature = <50000>;
+ type = "active";
+ };
+
+ package_fan1: package-fan1 {
+ hysteresis = <2000>;
+ temperature = <65000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ cooling-device = <&fan0 THERMAL_NO_LIMIT 1>;
+ trip = <&package_fan0>;
+ };
+ map1 {
+ cooling-device = <&fan0 2 THERMAL_NO_LIMIT>;
+ trip = <&package_fan1>;
+ };
+ };
+};
+
+/* M.2 E-key */
+&pcie2x1l0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x1_0_perstn_m1_l>;
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_ekey>;
+ status = "okay";
+};
+
+/* RTL8125B_1 */
+&pcie2x1l1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x1_1_perstn>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_lan>;
+ status = "okay";
+};
+
+/* RTL8125B_2 */
+&pcie2x1l2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie20x1_2_perstn>;
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_lan_phy2>;
+ status = "okay";
+};
+
+&pcie30phy {
+ data-lanes = <1 1 2 2>;
+ /* separate clock lines from the clock generator to phy and devices */
+ rockchip,rx-common-refclk-mode = <0 0 0 0>;
+ status = "okay";
+};
+
+/* ASMedia ASM1164 Sata controller */
+&pcie3x2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x2_perstn_m1_l>;
+ reset-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc33_io64>;
+ status = "okay";
+};
+
+/* M.2 M.key */
+&pcie3x4 {
+ num-lanes = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x4_perstn_m1_l>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_mkey>;
+ status = "okay";
+};
+
+&pinctrl {
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ led_pins: led-pins {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>,
+ <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie {
+ pcie20x1_2_perstn: pcie20x1-2-perstn {
+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30x1_0_perstn_m1_l: pcie30x1-0-perstn-m1-l {
+ rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30x1_1_perstn: pcie30x1-1-perstn {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30x2_perstn_m1_l: pcie30x2-perstn-m1-l {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30x4_perstn_m1_l: pcie30x4-perstn-m1-l {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ ekey_en: ekey-en {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ pcie30x4_pwren_h: pcie30x4-pwren-h {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ usb {
+ usb_host_pwren_h: usb-host-pwren-h {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc5v0_otg_en: vcc5v0-otg-en {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ gl3523_reset: rl3523-reset {
+ rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb-typec {
+ usbc0_int: usbc0-int {
+ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ vbus5v0_typec_en: vbus5v0-typec-en {
+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hdmirx {
+ hdmirx_det: hdmirx-det {
+ rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wireless-wlan {
+ wifi_host_wake_irq: wifi-host-wake-irq {
+ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ bt {
+ bt_enable_h: bt-enable-h {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_host_wake_l: bt-host-wake-l {
+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_l: bt-wake-l {
+ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ dp {
+ dp1_hpd: dp1-hpd {
+ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm14 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm14m1_pins>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ mmc-hs200-1_8v;
+ no-sdio;
+ no-sd;
+ non-removable;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <200000000>;
+ no-sdio;
+ no-mmc;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+/* M.2 E-KEY */
+&sdio {
+ broken-cd;
+ bus-width = <4>;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ max-frequency = <150000000>;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-sd;
+ no-mmc;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdiom0_pins>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_ekey>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim2_pins>;
+ status = "okay";
+
+ spi_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <50000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+ system-power-controller;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <837500>;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+/* Connected to M.2 E-key */
+&uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
+ status = "okay";
+};
+
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ /* connected to USB3 hub, which is powered by vcc5v0_usb12 */
+ phy-supply = <&vcc5v0_usb12>;
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ /* connected to USB2 hub, which is powered by vcc5v0_usb20 */
+ phy-supply = <&vcc5v0_usb20>;
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_usb20>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ usb-role-switch;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dwc3_0_role_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_role_sw>;
+ };
+ };
+};
+
+&usb_host1_xhci {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ /* 2.0 hub on port 1 */
+ hub_2_0: hub@1 {
+ compatible = "usb5e3,610";
+ reg = <1>;
+ peer-hub = <&hub_3_0>;
+ vdd-supply = <&vcc_3v3_s3>;
+ };
+
+ /* 3.0 hub on port 4 */
+ hub_3_0: hub@2 {
+ compatible = "usb5e3,620";
+ reg = <2>;
+ peer-hub = <&hub_2_0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gl3523_reset>;
+ reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&vcc_3v3_s3>;
+ };
+};
+
+&usbdp_phy0 {
+ mode-switch;
+ orientation-switch;
+ sbu1-dc-gpios = <&gpio4 RK_PB7 GPIO_ACTIVE_HIGH>;
+ sbu2-dc-gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ usbdp_phy0_orientation_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_orien_sw>;
+ };
+
+ usbdp_phy0_dp_altmode_mux: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dp_altmode_mux>;
+ };
+ };
+};
+
+&usbdp_phy1 {
+ rockchip,dp-lane-mux = <2 3>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-ep.dtso b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-ep.dtso
new file mode 100644
index 000000000000..672d748fcc67
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-ep.dtso
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * DT-overlay to run the PCIe3_4L Dual Mode controller in Endpoint mode
+ * in the SRNS (Separate Reference Clock No Spread) configuration.
+ *
+ * NOTE: If using a setup with two ROCK 5B:s, with one board running in
+ * RC mode and the other board running in EP mode, see also the device
+ * tree overlay: rk3588-rock-5b-pcie-srns.dtso.
+ */
+
+/dts-v1/;
+/plugin/;
+
+&pcie30phy {
+ rockchip,rx-common-refclk-mode = <0 0 0 0>;
+};
+
+&pcie3x4 {
+ status = "disabled";
+};
+
+&pcie3x4_ep {
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-srns.dtso b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-srns.dtso
new file mode 100644
index 000000000000..1a0f1af65c43
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-pcie-srns.dtso
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * DT-overlay to run the PCIe3_4L Dual Mode controller in Root Complex
+ * mode in the SRNS (Separate Reference Clock No Spread) configuration.
+ *
+ * This device tree overlay is only needed (on the RC side) when running
+ * a setup with two ROCK 5B:s, with one board running in RC mode and the
+ * other board running in EP mode.
+ */
+
+/dts-v1/;
+/plugin/;
+
+&pcie30phy {
+ rockchip,rx-common-refclk-mode = <0 0 0 0>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index 1fe8b2a0ed75..966bbc582d89 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -7,7 +7,7 @@
#include "rk3588.dtsi"
/ {
- model = "Radxa ROCK 5 Model B";
+ model = "Radxa ROCK 5B";
compatible = "radxa,rock-5b", "rockchip,rk3588";
aliases {
@@ -52,7 +52,7 @@
fan: pwm-fan {
compatible = "pwm-fan";
- cooling-levels = <0 95 145 195 255>;
+ cooling-levels = <0 120 150 180 210 240 255>;
fan-supply = <&vcc5v0_sys>;
pwms = <&pwm1 0 50000 0>;
#cooling-cells = <2>;
@@ -65,6 +65,13 @@
shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
};
+ rfkill-bt {
+ compatible = "rfkill-gpio";
+ label = "rfkill-m2-bt";
+ radio-type = "bluetooth";
+ shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
+ };
+
vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
compatible = "regulator-fixed";
enable-active-high;
@@ -180,6 +187,11 @@
cpu-supply = <&vdd_cpu_lit_s0>;
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0m2_xfer>;
@@ -274,6 +286,36 @@
};
};
+&package_thermal {
+ polling-delay = <1000>;
+
+ trips {
+ package_fan0: package-fan0 {
+ temperature = <55000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+
+ package_fan1: package-fan1 {
+ temperature = <65000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map1 {
+ trip = <&package_fan0>;
+ cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+ };
+
+ map2 {
+ trip = <&package_fan1>;
+ cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
&pcie2x1l0 {
pinctrl-names = "default";
pinctrl-0 = <&pcie2_0_rst>;
@@ -378,6 +420,7 @@
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
disable-wp;
sd-uhs-sdr104;
vmmc-supply = <&vcc_3v3_s3>;
@@ -406,6 +449,20 @@
status = "okay";
};
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim2_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
&uart6 {
pinctrl-names = "default";
pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
@@ -737,11 +794,23 @@
};
};
+&tsadc {
+ status = "okay";
+};
+
&uart2 {
pinctrl-0 = <&uart2m0_xfer>;
status = "okay";
};
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
@@ -761,6 +830,10 @@
status = "okay";
};
+&usbdp_phy1 {
+ status = "okay";
+};
+
&usb_host0_ehci {
status = "okay";
};
@@ -777,6 +850,11 @@
status = "okay";
};
+&usb_host1_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
&usb_host2_xhci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
index d672198c6b64..e4b7a0a4444b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
@@ -113,6 +113,16 @@
vin-supply = <&dc_12v>;
};
+ vcc5v0_otg: vcc5v0-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-name = "vcc5v0_otg";
+ regulator-always-on;
+ };
+
vcc5v0_usb: vcc5v0-usb-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_usb";
@@ -137,6 +147,10 @@
status = "okay";
};
+&extcon_usb3 {
+ status = "okay";
+};
+
&gmac0 {
status = "okay";
};
@@ -199,6 +213,13 @@
<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
+
+ usb2 {
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins =
+ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&sdmmc {
@@ -214,6 +235,23 @@
status = "okay";
};
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ phy-supply = <&vcc5v0_otg>;
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
@@ -231,25 +269,38 @@
};
&uart2 {
- pinctrl-0 = <&uart2m2_xfer>;
status = "okay";
};
&uart5 {
rts-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+};
+
+&usbdp_phy0 {
status = "okay";
};
-/* host0 on Q7_USB_P2, lower usb3 port */
+&usbdp_phy1 {
+ status = "okay";
+};
+
+/* host0 on Q7_USB_P2, upper usb3 port */
&usb_host0_ehci {
status = "okay";
};
-/* host0 on Q7_USB_P2, lower usb3 port */
+/* host0 on Q7_USB_P2, upper usb3 port */
&usb_host0_ohci {
status = "okay";
};
+/* host0_xhci on Q7_USB_P1, usb3-otg port */
+&usb_host0_xhci {
+ dr_mode = "otg";
+ extcon = <&extcon_usb3>;
+ status = "okay";
+};
+
/* host1 on Q7_USB_P3, usb2 port */
&usb_host1_ehci {
status = "okay";
@@ -260,7 +311,13 @@
status = "okay";
};
-/* host2 on Q7_USB_P2, lower usb3 port */
+/* host1_xhci on Q7_USB_P0, lower usb3 port */
+&usb_host1_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* host2 on Q7_USB_P2, upper usb3 port */
&usb_host2_xhci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
index 1eb2543a5fde..615094bb8ba3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
@@ -23,6 +23,14 @@
reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>;
};
+ extcon_usb3: extcon-usb3 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb3_id>;
+ status = "disabled";
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -46,7 +54,7 @@
pcie_refclk_gen: pcie-refclk-gen-clock {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <1000000000>;
+ clock-frequency = <100000000>;
};
pcie_refclk: pcie-refclk-clock {
@@ -139,6 +147,11 @@
snps,reset-delays-us = <0 10000 100000>;
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
&i2c1 {
pinctrl-0 = <&i2c1m0_xfer>;
};
@@ -322,6 +335,18 @@
rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ usb3 {
+ usb3_id: usb3-id {
+ rockchip,pins =
+ <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm0 {
+ pinctrl-0 = <&pwm0m1_pins>;
+ pinctrl-names = "default";
};
&saradc {
@@ -396,7 +421,7 @@
vcca-supply = <&vcc5v0_sys>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
@@ -683,6 +708,11 @@
status = "okay";
};
+/* Routed to UART0 on the Q7 connector */
+&uart2 {
+ pinctrl-0 = <&uart2m2_xfer>;
+};
+
/* Mule-ATtiny UPDI */
&uart4 {
pinctrl-0 = <&uart4m2_xfer>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
index 9090c5c99f2a..d0021524e7f9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
@@ -648,6 +648,10 @@
};
};
+&tsadc {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
index dc08da518a76..dbaa94ca69f4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
@@ -198,8 +198,7 @@
&mdio1 {
rgmii_phy: ethernet-phy@1 {
/* RTL8211F */
- compatible = "ethernet-phy-id001c.c916",
- "ethernet-phy-ieee802.3-c22";
+ compatible = "ethernet-phy-id001c.c916";
reg = <0x1>;
pinctrl-names = "default";
pinctrl-0 = <&rtl8211f_rst>;
@@ -318,7 +317,7 @@
#gpio-cells = <2>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
@@ -601,6 +600,10 @@
};
};
+&tsadc {
+ status = "okay";
+};
+
&uart2 {
pinctrl-0 = <&uart2m0_xfer>;
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
index 5519c1430cb7..7462cc1e1007 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
@@ -1,341 +1,8 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ *
*/
-#include "rk3588s.dtsi"
-#include "rk3588-pinctrl.dtsi"
-
-/ {
- pcie30_phy_grf: syscon@fd5b8000 {
- compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
- reg = <0x0 0xfd5b8000 0x0 0x10000>;
- };
-
- pipe_phy1_grf: syscon@fd5c0000 {
- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
- reg = <0x0 0xfd5c0000 0x0 0x100>;
- };
-
- i2s8_8ch: i2s@fddc8000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfddc8000 0x0 0x1000>;
- interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S8_8CH_TX>, <&cru MCLK_I2S8_8CH_TX>, <&cru HCLK_I2S8_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S8_8CH_TX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 22>;
- dma-names = "tx";
- power-domains = <&power RK3588_PD_VO0>;
- resets = <&cru SRST_M_I2S8_8CH_TX>;
- reset-names = "tx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s6_8ch: i2s@fddf4000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfddf4000 0x0 0x1000>;
- interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S6_8CH_TX>, <&cru MCLK_I2S6_8CH_TX>, <&cru HCLK_I2S6_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S6_8CH_TX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 4>;
- dma-names = "tx";
- power-domains = <&power RK3588_PD_VO1>;
- resets = <&cru SRST_M_I2S6_8CH_TX>;
- reset-names = "tx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s7_8ch: i2s@fddf8000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfddf8000 0x0 0x1000>;
- interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S7_8CH_RX>, <&cru MCLK_I2S7_8CH_RX>, <&cru HCLK_I2S7_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S7_8CH_RX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 21>;
- dma-names = "rx";
- power-domains = <&power RK3588_PD_VO1>;
- resets = <&cru SRST_M_I2S7_8CH_RX>;
- reset-names = "rx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s10_8ch: i2s@fde00000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfde00000 0x0 0x1000>;
- interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S10_8CH_RX>, <&cru MCLK_I2S10_8CH_RX>, <&cru HCLK_I2S10_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S10_8CH_RX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 24>;
- dma-names = "rx";
- power-domains = <&power RK3588_PD_VO1>;
- resets = <&cru SRST_M_I2S10_8CH_RX>;
- reset-names = "rx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- pcie3x4: pcie@fe150000 {
- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
- #address-cells = <3>;
- #size-cells = <2>;
- bus-range = <0x00 0x0f>;
- clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
- <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
- <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
- clock-names = "aclk_mst", "aclk_slv",
- "aclk_dbi", "pclk",
- "aux", "pipe";
- device_type = "pci";
- interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
- <0 0 0 2 &pcie3x4_intc 1>,
- <0 0 0 3 &pcie3x4_intc 2>,
- <0 0 0 4 &pcie3x4_intc 3>;
- linux,pci-domain = <0>;
- max-link-speed = <3>;
- msi-map = <0x0000 &its1 0x0000 0x1000>;
- num-lanes = <4>;
- phys = <&pcie30phy>;
- phy-names = "pcie-phy";
- power-domains = <&power RK3588_PD_PCIE>;
- ranges = <0x01000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x00100000>,
- <0x02000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0x00e00000>,
- <0x03000000 0x0 0x40000000 0x9 0x00000000 0x0 0x40000000>;
- reg = <0xa 0x40000000 0x0 0x00400000>,
- <0x0 0xfe150000 0x0 0x00010000>,
- <0x0 0xf0000000 0x0 0x00100000>;
- reg-names = "dbi", "apb", "config";
- resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
- reset-names = "pwr", "pipe";
- status = "disabled";
-
- pcie3x4_intc: legacy-interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING 0>;
- };
- };
-
- pcie3x2: pcie@fe160000 {
- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
- #address-cells = <3>;
- #size-cells = <2>;
- bus-range = <0x10 0x1f>;
- clocks = <&cru ACLK_PCIE_2L_MSTR>, <&cru ACLK_PCIE_2L_SLV>,
- <&cru ACLK_PCIE_2L_DBI>, <&cru PCLK_PCIE_2L>,
- <&cru CLK_PCIE_AUX1>, <&cru CLK_PCIE2L_PIPE>;
- clock-names = "aclk_mst", "aclk_slv",
- "aclk_dbi", "pclk",
- "aux", "pipe";
- device_type = "pci";
- interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
- <0 0 0 2 &pcie3x2_intc 1>,
- <0 0 0 3 &pcie3x2_intc 2>,
- <0 0 0 4 &pcie3x2_intc 3>;
- linux,pci-domain = <1>;
- max-link-speed = <3>;
- msi-map = <0x1000 &its1 0x1000 0x1000>;
- num-lanes = <2>;
- phys = <&pcie30phy>;
- phy-names = "pcie-phy";
- power-domains = <&power RK3588_PD_PCIE>;
- ranges = <0x01000000 0x0 0xf1100000 0x0 0xf1100000 0x0 0x00100000>,
- <0x02000000 0x0 0xf1200000 0x0 0xf1200000 0x0 0x00e00000>,
- <0x03000000 0x0 0x40000000 0x9 0x40000000 0x0 0x40000000>;
- reg = <0xa 0x40400000 0x0 0x00400000>,
- <0x0 0xfe160000 0x0 0x00010000>,
- <0x0 0xf1000000 0x0 0x00100000>;
- reg-names = "dbi", "apb", "config";
- resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
- reset-names = "pwr", "pipe";
- status = "disabled";
-
- pcie3x2_intc: legacy-interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 255 IRQ_TYPE_EDGE_RISING 0>;
- };
- };
-
- pcie2x1l0: pcie@fe170000 {
- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
- bus-range = <0x20 0x2f>;
- clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>,
- <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>,
- <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>;
- clock-names = "aclk_mst", "aclk_slv",
- "aclk_dbi", "pclk",
- "aux", "pipe";
- device_type = "pci";
- interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>,
- <0 0 0 2 &pcie2x1l0_intc 1>,
- <0 0 0 3 &pcie2x1l0_intc 2>,
- <0 0 0 4 &pcie2x1l0_intc 3>;
- linux,pci-domain = <2>;
- max-link-speed = <2>;
- msi-map = <0x2000 &its0 0x2000 0x1000>;
- num-lanes = <1>;
- phys = <&combphy1_ps PHY_TYPE_PCIE>;
- phy-names = "pcie-phy";
- power-domains = <&power RK3588_PD_PCIE>;
- ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>,
- <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>,
- <0x03000000 0x0 0x40000000 0x9 0x80000000 0x0 0x40000000>;
- reg = <0xa 0x40800000 0x0 0x00400000>,
- <0x0 0xfe170000 0x0 0x00010000>,
- <0x0 0xf2000000 0x0 0x00100000>;
- reg-names = "dbi", "apb", "config";
- resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>;
- reset-names = "pwr", "pipe";
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie2x1l0_intc: legacy-interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 240 IRQ_TYPE_EDGE_RISING 0>;
- };
- };
-
- gmac0: ethernet@fe1b0000 {
- compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
- reg = <0x0 0xfe1b0000 0x0 0x10000>;
- interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "macirq", "eth_wake_irq";
- clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
- <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
- <&cru CLK_GMAC0_PTP_REF>;
- clock-names = "stmmaceth", "clk_mac_ref",
- "pclk_mac", "aclk_mac",
- "ptp_ref";
- power-domains = <&power RK3588_PD_GMAC>;
- resets = <&cru SRST_A_GMAC0>;
- reset-names = "stmmaceth";
- rockchip,grf = <&sys_grf>;
- rockchip,php-grf = <&php_grf>;
- snps,axi-config = <&gmac0_stmmac_axi_setup>;
- snps,mixed-burst;
- snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
- snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
- snps,tso;
- status = "disabled";
-
- mdio0: mdio {
- compatible = "snps,dwmac-mdio";
- #address-cells = <0x1>;
- #size-cells = <0x0>;
- };
-
- gmac0_stmmac_axi_setup: stmmac-axi-config {
- snps,blen = <0 0 0 0 16 8 4>;
- snps,wr_osr_lmt = <4>;
- snps,rd_osr_lmt = <8>;
- };
-
- gmac0_mtl_rx_setup: rx-queues-config {
- snps,rx-queues-to-use = <2>;
- queue0 {};
- queue1 {};
- };
-
- gmac0_mtl_tx_setup: tx-queues-config {
- snps,tx-queues-to-use = <2>;
- queue0 {};
- queue1 {};
- };
- };
-
- sata1: sata@fe220000 {
- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
- reg = <0 0xfe220000 0 0x1000>;
- interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
- <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>,
- <&cru CLK_PIPEPHY1_PIPE_ASIC_G>;
- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
- ports-implemented = <0x1>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- sata-port@0 {
- reg = <0>;
- hba-port-cap = <HBA_PORT_FBSCP>;
- phys = <&combphy1_ps PHY_TYPE_SATA>;
- phy-names = "sata-phy";
- snps,rx-ts-max = <32>;
- snps,tx-ts-max = <32>;
- };
- };
-
- combphy1_ps: phy@fee10000 {
- compatible = "rockchip,rk3588-naneng-combphy";
- reg = <0x0 0xfee10000 0x0 0x100>;
- clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>,
- <&cru PCLK_PHP_ROOT>;
- clock-names = "ref", "apb", "pipe";
- assigned-clocks = <&cru CLK_REF_PIPE_PHY1>;
- assigned-clock-rates = <100000000>;
- #phy-cells = <1>;
- resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>;
- reset-names = "phy", "apb";
- rockchip,pipe-grf = <&php_grf>;
- rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
- status = "disabled";
- };
-
- pcie30phy: phy@fee80000 {
- compatible = "rockchip,rk3588-pcie3-phy";
- reg = <0x0 0xfee80000 0x0 0x20000>;
- #phy-cells = <0>;
- clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>;
- clock-names = "pclk";
- resets = <&cru SRST_PCIE30_PHY>;
- reset-names = "phy";
- rockchip,pipe-grf = <&php_grf>;
- rockchip,phy-grf = <&pcie30_phy_grf>;
- status = "disabled";
- };
-};
+#include "rk3588-extra.dtsi"
+#include "rk3588-opp.dtsi"
diff --git a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
index 38b9dbf38a21..bce72bac4503 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
@@ -4,4 +4,145 @@
*
*/
-#include "rk3588.dtsi"
+#include "rk3588-extra.dtsi"
+
+/ {
+ cluster0_opp_table: opp-table-cluster0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <750000 750000 950000>;
+ clock-latency-ns = <40000>;
+ opp-suspend;
+ };
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <887500 887500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <937500 937500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ cluster1_opp_table: opp-table-cluster1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <750000 750000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <787500 787500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <875000 875000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <950000 950000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ cluster2_opp_table: opp-table-cluster2 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <750000 750000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <787500 787500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <875000 875000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <950000 950000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+ opp-700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+ opp-850000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <787500 787500 850000>;
+ };
+ };
+};
+
+&cpu_b0 {
+ operating-points-v2 = <&cluster1_opp_table>;
+};
+
+&cpu_b1 {
+ operating-points-v2 = <&cluster1_opp_table>;
+};
+
+&cpu_b2 {
+ operating-points-v2 = <&cluster2_opp_table>;
+};
+
+&cpu_b3 {
+ operating-points-v2 = <&cluster2_opp_table>;
+};
+
+&cpu_l0 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&cpu_l1 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&cpu_l2 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&cpu_l3 {
+ operating-points-v2 = <&cluster0_opp_table>;
+};
+
+&gpu {
+ operating-points-v2 = <&gpu_opp_table>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
index e037bf9db75a..074c316a9a69 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
@@ -203,6 +203,11 @@
cpu-supply = <&vdd_cpu_big1_s0>;
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
&i2c0 {
pinctrl-0 = <&i2c0m2_xfer>;
status = "okay";
@@ -283,9 +288,9 @@
pinctrl-0 = <&i2c7m0_xfer>;
status = "okay";
- es8316: audio-codec@11 {
+ es8316: audio-codec@10 {
compatible = "everest,es8316";
- reg = <0x11>;
+ reg = <0x10>;
assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
assigned-clock-rates = <12288000>;
clocks = <&cru I2S0_8CH_MCLKOUT>;
@@ -479,7 +484,7 @@
vcca-supply = <&vcc5v0_sys>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index ce8119cbb824..d8c50fdcca3b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -316,7 +316,7 @@
pinctrl-names = "default";
vbus-supply = <&vbus5v0_typec>;
- connector {
+ usb_con: connector {
compatible = "usb-c-connector";
data-role = "dual";
label = "USB-C";
@@ -325,6 +325,32 @@
source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
sink-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
op-sink-microwatt = <1000000>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usbc0_orien_sw: endpoint {
+ remote-endpoint = <&usbdp_phy0_orientation_switch>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ usbc0_role_sw: endpoint {
+ remote-endpoint = <&dwc3_0_role_switch>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ dp_altmode_mux: endpoint {
+ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+ };
+ };
+ };
};
};
@@ -528,7 +554,7 @@
vcca-supply = <&vcc5v0_sys>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
@@ -788,6 +814,14 @@
status = "okay";
};
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
@@ -839,6 +873,17 @@
status = "okay";
};
+&usb_host0_xhci {
+ usb-role-switch;
+ status = "okay";
+
+ port {
+ dwc3_0_role_switch: endpoint {
+ remote-endpoint = <&usbc0_role_sw>;
+ };
+ };
+};
+
&usb_host1_ehci {
status = "okay";
};
@@ -850,3 +895,27 @@
&usb_host2_xhci {
status = "okay";
};
+
+&usbdp_phy0 {
+ orientation-switch;
+ mode-switch;
+ sbu1-dc-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>;
+ sbu2-dc-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
+ rockchip,dp-lane-mux = <2 3>;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbdp_phy0_orientation_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_orien_sw>;
+ };
+
+ usbdp_phy0_dp_altmode_mux: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dp_altmode_mux>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index f53e993c785e..dbddfc3bb464 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -3,7 +3,9 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/leds/common.h>
#include "rk3588s.dtsi"
/ {
@@ -12,11 +14,298 @@
aliases {
mmc0 = &sdhci;
+ mmc1 = &sdmmc;
};
chosen {
stdout-path = "serial2:1500000n8";
};
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-function {
+ label = "Function";
+ linux,code = <KEY_FN>;
+ press-threshold-microvolt = <17000>;
+ };
+ };
+
+ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_receiver_pin>;
+ };
+
+ leds {
+ compatible = "pwm-leds";
+
+ red_led: led-0 {
+ label = "red_led";
+ color = <LED_COLOR_ID_RED>;
+ default-state = "off";
+ function = LED_FUNCTION_INDICATOR;
+ linux,default-trigger = "none";
+ max-brightness = <255>;
+ pwms = <&pwm11 0 25000 0>;
+ };
+
+ green_led: led-1 {
+ label = "green_led";
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_POWER;
+ linux,default-trigger = "default-on";
+ max-brightness = <255>;
+ pwms = <&pwm14 0 25000 0>;
+ };
+
+ blue_led: led-2 {
+ label = "blue_led";
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "off";
+ function = LED_FUNCTION_INDICATOR;
+ linux,default-trigger = "none";
+ max-brightness = <255>;
+ pwms = <&pwm15 0 25000 0>;
+ };
+ };
+
+ vcc3v3_pcie_wl: vcc3v3-pcie-wl-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie_wl";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vdd_3v3_sd: vdd-3v3-sd-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v3_sd";
+ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ enable-active-high;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vdd_sd_en>;
+ };
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ wakeup-source;
+ };
+};
+
+&pinctrl {
+ vdd_sd {
+ vdd_sd_en: vdd-sd-en {
+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pcie2 {
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_2_vcc3v3_en: pcie2-2-vcc-en {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ ir-receiver {
+ ir_receiver_pin: ir-receiver-pin {
+ rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wireless-bluetooth {
+ bt_reset_pin: bt-reset-pin {
+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_pin: bt-wake-pin {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ bt_wake_host_irq: bt-wake-host-irq {
+ rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
+
+&pcie2x1l2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie_wl>;
+ status = "okay";
+};
+
+&pwm11 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm11m1_pins>;
+ status = "okay";
+};
+
+&pwm14 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm14m1_pins>;
+ status = "okay";
+};
+
+&pwm15 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm15m1_pins>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
};
&sdhci {
@@ -29,7 +318,403 @@
status = "okay";
};
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vdd_3v3_sd>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim2_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <100000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+ system-power-controller;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_log_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_vdenc_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdd_ddr_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
&uart2 {
pinctrl-0 = <&uart2m0_xfer>;
status = "okay";
};
+
+&uart9 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart9m2_xfer &uart9m2_ctsn>;
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host2_xhci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
index 25de4362af38..feea6b20a6bf 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
@@ -6,6 +6,7 @@
#include <dt-bindings/leds/common.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
#include "rk3588s.dtsi"
/ {
@@ -146,6 +147,11 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0m2_xfer>;
@@ -212,6 +218,56 @@
pinctrl-0 = <&i2c6m3_xfer>;
status = "okay";
+ usbc0: usb-typec@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbc0_int>;
+ vbus-supply = <&vbus_typec>;
+ status = "okay";
+
+ usb_con: connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "dual";
+ op-sink-microwatt = <1000000>;
+ power-role = "dual";
+ sink-pdos =
+ <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+ source-pdos =
+ <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ try-power-role = "source";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usbc0_hs: endpoint {
+ remote-endpoint = <&usb_host0_xhci_drd_sw>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ usbc0_ss: endpoint {
+ remote-endpoint = <&usbdp_phy0_typec_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ usbc0_sbu: endpoint {
+ remote-endpoint = <&usbdp_phy0_typec_sbu>;
+ };
+ };
+ };
+ };
+ };
+
hym8563: rtc@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
@@ -336,7 +392,7 @@
#gpio-cells = <2>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
@@ -625,6 +681,14 @@
status = "okay";
};
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
@@ -646,6 +710,29 @@
status = "okay";
};
+&usbdp_phy0 {
+ mode-switch;
+ orientation-switch;
+ sbu1-dc-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbdp_phy0_typec_ss: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc0_ss>;
+ };
+
+ usbdp_phy0_typec_sbu: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&usbc0_sbu>;
+ };
+ };
+};
+
&usb_host0_ehci {
status = "okay";
};
@@ -654,6 +741,18 @@
status = "okay";
};
+&usb_host0_xhci {
+ dr_mode = "otg";
+ usb-role-switch;
+ status = "okay";
+
+ port {
+ usb_host0_xhci_drd_sw: endpoint {
+ remote-endpoint = <&usbc0_hs>;
+ };
+ };
+};
+
&usb_host1_ehci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 00afb90d4eb1..03ed48246d36 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -8,7 +8,7 @@
#include "rk3588s.dtsi"
/ {
- model = "Radxa ROCK 5 Model A";
+ model = "Radxa ROCK 5A";
compatible = "radxa,rock-5a", "rockchip,rk3588s";
aliases {
@@ -366,6 +366,7 @@
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
disable-wp;
max-frequency = <150000000>;
no-sdio;
@@ -376,6 +377,19 @@
status = "okay";
};
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim0_pins>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
&spi2 {
status = "okay";
assigned-clocks = <&cru CLK_SPI2>;
@@ -393,6 +407,7 @@
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
<&rk806_dvs2_null>, <&rk806_dvs3_null>;
spi-max-frequency = <1000000>;
+ system-power-controller;
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
@@ -414,7 +429,7 @@
#gpio-cells = <2>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
@@ -697,6 +712,18 @@
};
};
+&tsadc {
+ status = "okay";
+};
+
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_otg {
+ status = "okay";
+};
+
&u2phy2 {
status = "okay";
};
@@ -720,6 +747,11 @@
status = "okay";
};
+&usbdp_phy0 {
+ status = "okay";
+ rockchip,dp-lane-mux = <2 3>;
+};
+
&usb_host0_ehci {
status = "okay";
pinctrl-names = "default";
@@ -730,6 +762,11 @@
status = "okay";
};
+&usb_host0_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
&usb_host1_ehci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 87b83c87bd55..c7fecf8fe7ec 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -1,2505 +1,8 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ *
*/
-#include <dt-bindings/clock/rockchip,rk3588-cru.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/power/rk3588-power.h>
-#include <dt-bindings/reset/rockchip,rk3588-cru.h>
-#include <dt-bindings/phy/phy.h>
-#include <dt-bindings/ata/ahci.h>
-
-/ {
- compatible = "rockchip,rk3588";
-
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
-
- aliases {
- gpio0 = &gpio0;
- gpio1 = &gpio1;
- gpio2 = &gpio2;
- gpio3 = &gpio3;
- gpio4 = &gpio4;
- i2c0 = &i2c0;
- i2c1 = &i2c1;
- i2c2 = &i2c2;
- i2c3 = &i2c3;
- i2c4 = &i2c4;
- i2c5 = &i2c5;
- i2c6 = &i2c6;
- i2c7 = &i2c7;
- i2c8 = &i2c8;
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- serial4 = &uart4;
- serial5 = &uart5;
- serial6 = &uart6;
- serial7 = &uart7;
- serial8 = &uart8;
- serial9 = &uart9;
- spi0 = &spi0;
- spi1 = &spi1;
- spi2 = &spi2;
- spi3 = &spi3;
- spi4 = &spi4;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu-map {
- cluster0 {
- core0 {
- cpu = <&cpu_l0>;
- };
- core1 {
- cpu = <&cpu_l1>;
- };
- core2 {
- cpu = <&cpu_l2>;
- };
- core3 {
- cpu = <&cpu_l3>;
- };
- };
- cluster1 {
- core0 {
- cpu = <&cpu_b0>;
- };
- core1 {
- cpu = <&cpu_b1>;
- };
- };
- cluster2 {
- core0 {
- cpu = <&cpu_b2>;
- };
- core1 {
- cpu = <&cpu_b3>;
- };
- };
- };
-
- cpu_l0: cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a55";
- reg = <0x0>;
- enable-method = "psci";
- capacity-dmips-mhz = <530>;
- clocks = <&scmi_clk SCMI_CLK_CPUL>;
- assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
- assigned-clock-rates = <816000000>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <32768>;
- i-cache-line-size = <64>;
- i-cache-sets = <128>;
- d-cache-size = <32768>;
- d-cache-line-size = <64>;
- d-cache-sets = <128>;
- next-level-cache = <&l2_cache_l0>;
- dynamic-power-coefficient = <228>;
- #cooling-cells = <2>;
- };
-
- cpu_l1: cpu@100 {
- device_type = "cpu";
- compatible = "arm,cortex-a55";
- reg = <0x100>;
- enable-method = "psci";
- capacity-dmips-mhz = <530>;
- clocks = <&scmi_clk SCMI_CLK_CPUL>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <32768>;
- i-cache-line-size = <64>;
- i-cache-sets = <128>;
- d-cache-size = <32768>;
- d-cache-line-size = <64>;
- d-cache-sets = <128>;
- next-level-cache = <&l2_cache_l1>;
- dynamic-power-coefficient = <228>;
- #cooling-cells = <2>;
- };
-
- cpu_l2: cpu@200 {
- device_type = "cpu";
- compatible = "arm,cortex-a55";
- reg = <0x200>;
- enable-method = "psci";
- capacity-dmips-mhz = <530>;
- clocks = <&scmi_clk SCMI_CLK_CPUL>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <32768>;
- i-cache-line-size = <64>;
- i-cache-sets = <128>;
- d-cache-size = <32768>;
- d-cache-line-size = <64>;
- d-cache-sets = <128>;
- next-level-cache = <&l2_cache_l2>;
- dynamic-power-coefficient = <228>;
- #cooling-cells = <2>;
- };
-
- cpu_l3: cpu@300 {
- device_type = "cpu";
- compatible = "arm,cortex-a55";
- reg = <0x300>;
- enable-method = "psci";
- capacity-dmips-mhz = <530>;
- clocks = <&scmi_clk SCMI_CLK_CPUL>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <32768>;
- i-cache-line-size = <64>;
- i-cache-sets = <128>;
- d-cache-size = <32768>;
- d-cache-line-size = <64>;
- d-cache-sets = <128>;
- next-level-cache = <&l2_cache_l3>;
- dynamic-power-coefficient = <228>;
- #cooling-cells = <2>;
- };
-
- cpu_b0: cpu@400 {
- device_type = "cpu";
- compatible = "arm,cortex-a76";
- reg = <0x400>;
- enable-method = "psci";
- capacity-dmips-mhz = <1024>;
- clocks = <&scmi_clk SCMI_CLK_CPUB01>;
- assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
- assigned-clock-rates = <816000000>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <65536>;
- i-cache-line-size = <64>;
- i-cache-sets = <256>;
- d-cache-size = <65536>;
- d-cache-line-size = <64>;
- d-cache-sets = <256>;
- next-level-cache = <&l2_cache_b0>;
- dynamic-power-coefficient = <416>;
- #cooling-cells = <2>;
- };
-
- cpu_b1: cpu@500 {
- device_type = "cpu";
- compatible = "arm,cortex-a76";
- reg = <0x500>;
- enable-method = "psci";
- capacity-dmips-mhz = <1024>;
- clocks = <&scmi_clk SCMI_CLK_CPUB01>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <65536>;
- i-cache-line-size = <64>;
- i-cache-sets = <256>;
- d-cache-size = <65536>;
- d-cache-line-size = <64>;
- d-cache-sets = <256>;
- next-level-cache = <&l2_cache_b1>;
- dynamic-power-coefficient = <416>;
- #cooling-cells = <2>;
- };
-
- cpu_b2: cpu@600 {
- device_type = "cpu";
- compatible = "arm,cortex-a76";
- reg = <0x600>;
- enable-method = "psci";
- capacity-dmips-mhz = <1024>;
- clocks = <&scmi_clk SCMI_CLK_CPUB23>;
- assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
- assigned-clock-rates = <816000000>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <65536>;
- i-cache-line-size = <64>;
- i-cache-sets = <256>;
- d-cache-size = <65536>;
- d-cache-line-size = <64>;
- d-cache-sets = <256>;
- next-level-cache = <&l2_cache_b2>;
- dynamic-power-coefficient = <416>;
- #cooling-cells = <2>;
- };
-
- cpu_b3: cpu@700 {
- device_type = "cpu";
- compatible = "arm,cortex-a76";
- reg = <0x700>;
- enable-method = "psci";
- capacity-dmips-mhz = <1024>;
- clocks = <&scmi_clk SCMI_CLK_CPUB23>;
- cpu-idle-states = <&CPU_SLEEP>;
- i-cache-size = <65536>;
- i-cache-line-size = <64>;
- i-cache-sets = <256>;
- d-cache-size = <65536>;
- d-cache-line-size = <64>;
- d-cache-sets = <256>;
- next-level-cache = <&l2_cache_b3>;
- dynamic-power-coefficient = <416>;
- #cooling-cells = <2>;
- };
-
- idle-states {
- entry-method = "psci";
- CPU_SLEEP: cpu-sleep {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x0010000>;
- entry-latency-us = <100>;
- exit-latency-us = <120>;
- min-residency-us = <1000>;
- };
- };
-
- l2_cache_l0: l2-cache-l0 {
- compatible = "cache";
- cache-size = <131072>;
- cache-line-size = <64>;
- cache-sets = <512>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_l1: l2-cache-l1 {
- compatible = "cache";
- cache-size = <131072>;
- cache-line-size = <64>;
- cache-sets = <512>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_l2: l2-cache-l2 {
- compatible = "cache";
- cache-size = <131072>;
- cache-line-size = <64>;
- cache-sets = <512>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_l3: l2-cache-l3 {
- compatible = "cache";
- cache-size = <131072>;
- cache-line-size = <64>;
- cache-sets = <512>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_b0: l2-cache-b0 {
- compatible = "cache";
- cache-size = <524288>;
- cache-line-size = <64>;
- cache-sets = <1024>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_b1: l2-cache-b1 {
- compatible = "cache";
- cache-size = <524288>;
- cache-line-size = <64>;
- cache-sets = <1024>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_b2: l2-cache-b2 {
- compatible = "cache";
- cache-size = <524288>;
- cache-line-size = <64>;
- cache-sets = <1024>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l2_cache_b3: l2-cache-b3 {
- compatible = "cache";
- cache-size = <524288>;
- cache-line-size = <64>;
- cache-sets = <1024>;
- cache-level = <2>;
- cache-unified;
- next-level-cache = <&l3_cache>;
- };
-
- l3_cache: l3-cache {
- compatible = "cache";
- cache-size = <3145728>;
- cache-line-size = <64>;
- cache-sets = <4096>;
- cache-level = <3>;
- cache-unified;
- };
- };
-
- firmware {
- optee: optee {
- compatible = "linaro,optee-tz";
- method = "smc";
- };
-
- scmi: scmi {
- compatible = "arm,scmi-smc";
- arm,smc-id = <0x82000010>;
- shmem = <&scmi_shmem>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- scmi_clk: protocol@14 {
- reg = <0x14>;
- #clock-cells = <1>;
- };
-
- scmi_reset: protocol@16 {
- reg = <0x16>;
- #reset-cells = <1>;
- };
- };
- };
-
- pmu-a55 {
- compatible = "arm,cortex-a55-pmu";
- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
- };
-
- pmu-a76 {
- compatible = "arm,cortex-a76-pmu";
- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
- };
-
- psci {
- compatible = "arm,psci-1.0";
- method = "smc";
- };
-
- spll: clock-0 {
- compatible = "fixed-clock";
- clock-frequency = <702000000>;
- clock-output-names = "spll";
- #clock-cells = <0>;
- };
-
- display_subsystem: display-subsystem {
- compatible = "rockchip,display-subsystem";
- ports = <&vop_out>;
- };
-
- timer {
- compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
- };
-
- xin24m: clock-1 {
- compatible = "fixed-clock";
- clock-frequency = <24000000>;
- clock-output-names = "xin24m";
- #clock-cells = <0>;
- };
-
- xin32k: clock-2 {
- compatible = "fixed-clock";
- clock-frequency = <32768>;
- clock-output-names = "xin32k";
- #clock-cells = <0>;
- };
-
- pmu_sram: sram@10f000 {
- compatible = "mmio-sram";
- reg = <0x0 0x0010f000 0x0 0x100>;
- ranges = <0 0x0 0x0010f000 0x100>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- scmi_shmem: sram@0 {
- compatible = "arm,scmi-shmem";
- reg = <0x0 0x100>;
- };
- };
-
- usb_host0_ehci: usb@fc800000 {
- compatible = "rockchip,rk3588-ehci", "generic-ehci";
- reg = <0x0 0xfc800000 0x0 0x40000>;
- interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
- phys = <&u2phy2_host>;
- phy-names = "usb";
- power-domains = <&power RK3588_PD_USB>;
- status = "disabled";
- };
-
- usb_host0_ohci: usb@fc840000 {
- compatible = "rockchip,rk3588-ohci", "generic-ohci";
- reg = <0x0 0xfc840000 0x0 0x40000>;
- interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
- phys = <&u2phy2_host>;
- phy-names = "usb";
- power-domains = <&power RK3588_PD_USB>;
- status = "disabled";
- };
-
- usb_host1_ehci: usb@fc880000 {
- compatible = "rockchip,rk3588-ehci", "generic-ehci";
- reg = <0x0 0xfc880000 0x0 0x40000>;
- interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
- phys = <&u2phy3_host>;
- phy-names = "usb";
- power-domains = <&power RK3588_PD_USB>;
- status = "disabled";
- };
-
- usb_host1_ohci: usb@fc8c0000 {
- compatible = "rockchip,rk3588-ohci", "generic-ohci";
- reg = <0x0 0xfc8c0000 0x0 0x40000>;
- interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
- phys = <&u2phy3_host>;
- phy-names = "usb";
- power-domains = <&power RK3588_PD_USB>;
- status = "disabled";
- };
-
- usb_host2_xhci: usb@fcd00000 {
- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
- reg = <0x0 0xfcd00000 0x0 0x400000>;
- interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
- <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
- <&cru CLK_PIPEPHY2_PIPE_U3_G>;
- clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
- dr_mode = "host";
- phys = <&combphy2_psu PHY_TYPE_USB3>;
- phy-names = "usb3-phy";
- phy_type = "utmi_wide";
- resets = <&cru SRST_A_USB3OTG2>;
- snps,dis_enblslpm_quirk;
- snps,dis-u2-freeclk-exists-quirk;
- snps,dis-del-phy-power-chg-quirk;
- snps,dis-tx-ipgap-linecheck-quirk;
- snps,dis_rxdet_inp3_quirk;
- status = "disabled";
- };
-
- pmu1grf: syscon@fd58a000 {
- compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
- reg = <0x0 0xfd58a000 0x0 0x10000>;
- };
-
- sys_grf: syscon@fd58c000 {
- compatible = "rockchip,rk3588-sys-grf", "syscon";
- reg = <0x0 0xfd58c000 0x0 0x1000>;
- };
-
- vop_grf: syscon@fd5a4000 {
- compatible = "rockchip,rk3588-vop-grf", "syscon";
- reg = <0x0 0xfd5a4000 0x0 0x2000>;
- };
-
- vo1_grf: syscon@fd5a8000 {
- compatible = "rockchip,rk3588-vo-grf", "syscon";
- reg = <0x0 0xfd5a8000 0x0 0x100>;
- clocks = <&cru PCLK_VO1GRF>;
- };
-
- php_grf: syscon@fd5b0000 {
- compatible = "rockchip,rk3588-php-grf", "syscon";
- reg = <0x0 0xfd5b0000 0x0 0x1000>;
- };
-
- pipe_phy0_grf: syscon@fd5bc000 {
- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
- reg = <0x0 0xfd5bc000 0x0 0x100>;
- };
-
- pipe_phy2_grf: syscon@fd5c4000 {
- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
- reg = <0x0 0xfd5c4000 0x0 0x100>;
- };
-
- usb2phy2_grf: syscon@fd5d8000 {
- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
- reg = <0x0 0xfd5d8000 0x0 0x4000>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- u2phy2: usb2-phy@8000 {
- compatible = "rockchip,rk3588-usb2phy";
- reg = <0x8000 0x10>;
- interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
- resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
- reset-names = "phy", "apb";
- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
- clock-names = "phyclk";
- clock-output-names = "usb480m_phy2";
- #clock-cells = <0>;
- status = "disabled";
-
- u2phy2_host: host-port {
- #phy-cells = <0>;
- status = "disabled";
- };
- };
- };
-
- usb2phy3_grf: syscon@fd5dc000 {
- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
- reg = <0x0 0xfd5dc000 0x0 0x4000>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- u2phy3: usb2-phy@c000 {
- compatible = "rockchip,rk3588-usb2phy";
- reg = <0xc000 0x10>;
- interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
- resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
- reset-names = "phy", "apb";
- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
- clock-names = "phyclk";
- clock-output-names = "usb480m_phy3";
- #clock-cells = <0>;
- status = "disabled";
-
- u2phy3_host: host-port {
- #phy-cells = <0>;
- status = "disabled";
- };
- };
- };
-
- hdptxphy0_grf: syscon@fd5e0000 {
- compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
- reg = <0x0 0xfd5e0000 0x0 0x100>;
- };
-
- ioc: syscon@fd5f0000 {
- compatible = "rockchip,rk3588-ioc", "syscon";
- reg = <0x0 0xfd5f0000 0x0 0x10000>;
- };
-
- system_sram1: sram@fd600000 {
- compatible = "mmio-sram";
- reg = <0x0 0xfd600000 0x0 0x100000>;
- ranges = <0x0 0x0 0xfd600000 0x100000>;
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
- cru: clock-controller@fd7c0000 {
- compatible = "rockchip,rk3588-cru";
- reg = <0x0 0xfd7c0000 0x0 0x5c000>;
- assigned-clocks =
- <&cru PLL_PPLL>, <&cru PLL_AUPLL>,
- <&cru PLL_NPLL>, <&cru PLL_GPLL>,
- <&cru ACLK_CENTER_ROOT>,
- <&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
- <&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
- <&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
- <&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
- <&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
- <&cru CLK_GPU>;
- assigned-clock-rates =
- <1100000000>, <786432000>,
- <850000000>, <1188000000>,
- <702000000>,
- <400000000>, <500000000>,
- <800000000>, <100000000>,
- <400000000>, <100000000>,
- <200000000>, <500000000>,
- <375000000>, <150000000>,
- <200000000>;
- rockchip,grf = <&php_grf>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-
- i2c0: i2c@fd880000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfd880000 0x0 0x1000>;
- interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
- clock-names = "i2c", "pclk";
- pinctrl-0 = <&i2c0m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- vop: vop@fdd90000 {
- compatible = "rockchip,rk3588-vop";
- reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
- reg-names = "vop", "gamma-lut";
- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru ACLK_VOP>,
- <&cru HCLK_VOP>,
- <&cru DCLK_VOP0>,
- <&cru DCLK_VOP1>,
- <&cru DCLK_VOP2>,
- <&cru DCLK_VOP3>,
- <&cru PCLK_VOP_ROOT>;
- clock-names = "aclk",
- "hclk",
- "dclk_vp0",
- "dclk_vp1",
- "dclk_vp2",
- "dclk_vp3",
- "pclk_vop";
- iommus = <&vop_mmu>;
- power-domains = <&power RK3588_PD_VOP>;
- rockchip,grf = <&sys_grf>;
- rockchip,vop-grf = <&vop_grf>;
- rockchip,vo1-grf = <&vo1_grf>;
- rockchip,pmu = <&pmu>;
- status = "disabled";
-
- vop_out: ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- vp0: port@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- };
-
- vp1: port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- };
-
- vp2: port@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- };
-
- vp3: port@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- };
- };
- };
-
- vop_mmu: iommu@fdd97e00 {
- compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
- reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
- clock-names = "aclk", "iface";
- #iommu-cells = <0>;
- power-domains = <&power RK3588_PD_VOP>;
- status = "disabled";
- };
-
- uart0: serial@fd890000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfd890000 0x0 0x100>;
- interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac0 6>, <&dmac0 7>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart0m1_xfer>;
- pinctrl-names = "default";
- reg-shift = <2>;
- reg-io-width = <4>;
- status = "disabled";
- };
-
- pwm0: pwm@fd8b0000 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfd8b0000 0x0 0x10>;
- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm0m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm1: pwm@fd8b0010 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfd8b0010 0x0 0x10>;
- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm1m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm2: pwm@fd8b0020 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfd8b0020 0x0 0x10>;
- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm2m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm3: pwm@fd8b0030 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfd8b0030 0x0 0x10>;
- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm3m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pmu: power-management@fd8d8000 {
- compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
- reg = <0x0 0xfd8d8000 0x0 0x400>;
-
- power: power-controller {
- compatible = "rockchip,rk3588-power-controller";
- #address-cells = <1>;
- #power-domain-cells = <1>;
- #size-cells = <0>;
- status = "okay";
-
- /* These power domains are grouped by VD_NPU */
- power-domain@RK3588_PD_NPU {
- reg = <RK3588_PD_NPU>;
- #power-domain-cells = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- power-domain@RK3588_PD_NPUTOP {
- reg = <RK3588_PD_NPUTOP>;
- clocks = <&cru HCLK_NPU_ROOT>,
- <&cru PCLK_NPU_ROOT>,
- <&cru CLK_NPU_DSU0>,
- <&cru HCLK_NPU_CM0_ROOT>;
- pm_qos = <&qos_npu0_mwr>,
- <&qos_npu0_mro>,
- <&qos_mcu_npu>;
- #power-domain-cells = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- power-domain@RK3588_PD_NPU1 {
- reg = <RK3588_PD_NPU1>;
- clocks = <&cru HCLK_NPU_ROOT>,
- <&cru PCLK_NPU_ROOT>,
- <&cru CLK_NPU_DSU0>;
- pm_qos = <&qos_npu1>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_NPU2 {
- reg = <RK3588_PD_NPU2>;
- clocks = <&cru HCLK_NPU_ROOT>,
- <&cru PCLK_NPU_ROOT>,
- <&cru CLK_NPU_DSU0>;
- pm_qos = <&qos_npu2>;
- #power-domain-cells = <0>;
- };
- };
- };
- /* These power domains are grouped by VD_GPU */
- power-domain@RK3588_PD_GPU {
- reg = <RK3588_PD_GPU>;
- clocks = <&cru CLK_GPU>,
- <&cru CLK_GPU_COREGROUP>,
- <&cru CLK_GPU_STACKS>;
- pm_qos = <&qos_gpu_m0>,
- <&qos_gpu_m1>,
- <&qos_gpu_m2>,
- <&qos_gpu_m3>;
- #power-domain-cells = <0>;
- };
- /* These power domains are grouped by VD_VCODEC */
- power-domain@RK3588_PD_VCODEC {
- reg = <RK3588_PD_VCODEC>;
- #address-cells = <1>;
- #size-cells = <0>;
- #power-domain-cells = <0>;
-
- power-domain@RK3588_PD_RKVDEC0 {
- reg = <RK3588_PD_RKVDEC0>;
- clocks = <&cru HCLK_RKVDEC0>,
- <&cru HCLK_VDPU_ROOT>,
- <&cru ACLK_VDPU_ROOT>,
- <&cru ACLK_RKVDEC0>,
- <&cru ACLK_RKVDEC_CCU>;
- pm_qos = <&qos_rkvdec0>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_RKVDEC1 {
- reg = <RK3588_PD_RKVDEC1>;
- clocks = <&cru HCLK_RKVDEC1>,
- <&cru HCLK_VDPU_ROOT>,
- <&cru ACLK_VDPU_ROOT>,
- <&cru ACLK_RKVDEC1>;
- pm_qos = <&qos_rkvdec1>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_VENC0 {
- reg = <RK3588_PD_VENC0>;
- clocks = <&cru HCLK_RKVENC0>,
- <&cru ACLK_RKVENC0>;
- pm_qos = <&qos_rkvenc0_m0ro>,
- <&qos_rkvenc0_m1ro>,
- <&qos_rkvenc0_m2wo>;
- #address-cells = <1>;
- #size-cells = <0>;
- #power-domain-cells = <0>;
-
- power-domain@RK3588_PD_VENC1 {
- reg = <RK3588_PD_VENC1>;
- clocks = <&cru HCLK_RKVENC1>,
- <&cru HCLK_RKVENC0>,
- <&cru ACLK_RKVENC0>,
- <&cru ACLK_RKVENC1>;
- pm_qos = <&qos_rkvenc1_m0ro>,
- <&qos_rkvenc1_m1ro>,
- <&qos_rkvenc1_m2wo>;
- #power-domain-cells = <0>;
- };
- };
- };
- /* These power domains are grouped by VD_LOGIC */
- power-domain@RK3588_PD_VDPU {
- reg = <RK3588_PD_VDPU>;
- clocks = <&cru HCLK_VDPU_ROOT>,
- <&cru ACLK_VDPU_LOW_ROOT>,
- <&cru ACLK_VDPU_ROOT>,
- <&cru ACLK_JPEG_DECODER_ROOT>,
- <&cru ACLK_IEP2P0>,
- <&cru HCLK_IEP2P0>,
- <&cru ACLK_JPEG_ENCODER0>,
- <&cru HCLK_JPEG_ENCODER0>,
- <&cru ACLK_JPEG_ENCODER1>,
- <&cru HCLK_JPEG_ENCODER1>,
- <&cru ACLK_JPEG_ENCODER2>,
- <&cru HCLK_JPEG_ENCODER2>,
- <&cru ACLK_JPEG_ENCODER3>,
- <&cru HCLK_JPEG_ENCODER3>,
- <&cru ACLK_JPEG_DECODER>,
- <&cru HCLK_JPEG_DECODER>,
- <&cru ACLK_RGA2>,
- <&cru HCLK_RGA2>;
- pm_qos = <&qos_iep>,
- <&qos_jpeg_dec>,
- <&qos_jpeg_enc0>,
- <&qos_jpeg_enc1>,
- <&qos_jpeg_enc2>,
- <&qos_jpeg_enc3>,
- <&qos_rga2_mro>,
- <&qos_rga2_mwo>;
- #address-cells = <1>;
- #size-cells = <0>;
- #power-domain-cells = <0>;
-
-
- power-domain@RK3588_PD_AV1 {
- reg = <RK3588_PD_AV1>;
- clocks = <&cru PCLK_AV1>,
- <&cru ACLK_AV1>,
- <&cru HCLK_VDPU_ROOT>;
- pm_qos = <&qos_av1>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_RKVDEC0 {
- reg = <RK3588_PD_RKVDEC0>;
- clocks = <&cru HCLK_RKVDEC0>,
- <&cru HCLK_VDPU_ROOT>,
- <&cru ACLK_VDPU_ROOT>,
- <&cru ACLK_RKVDEC0>;
- pm_qos = <&qos_rkvdec0>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_RKVDEC1 {
- reg = <RK3588_PD_RKVDEC1>;
- clocks = <&cru HCLK_RKVDEC1>,
- <&cru HCLK_VDPU_ROOT>,
- <&cru ACLK_VDPU_ROOT>;
- pm_qos = <&qos_rkvdec1>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_RGA30 {
- reg = <RK3588_PD_RGA30>;
- clocks = <&cru ACLK_RGA3_0>,
- <&cru HCLK_RGA3_0>;
- pm_qos = <&qos_rga3_0>;
- #power-domain-cells = <0>;
- };
- };
- power-domain@RK3588_PD_VOP {
- reg = <RK3588_PD_VOP>;
- clocks = <&cru PCLK_VOP_ROOT>,
- <&cru HCLK_VOP_ROOT>,
- <&cru ACLK_VOP>;
- pm_qos = <&qos_vop_m0>,
- <&qos_vop_m1>;
- #address-cells = <1>;
- #size-cells = <0>;
- #power-domain-cells = <0>;
-
- power-domain@RK3588_PD_VO0 {
- reg = <RK3588_PD_VO0>;
- clocks = <&cru PCLK_VO0_ROOT>,
- <&cru PCLK_VO0_S_ROOT>,
- <&cru HCLK_VO0_S_ROOT>,
- <&cru ACLK_VO0_ROOT>,
- <&cru HCLK_HDCP0>,
- <&cru ACLK_HDCP0>,
- <&cru HCLK_VOP_ROOT>;
- pm_qos = <&qos_hdcp0>;
- #power-domain-cells = <0>;
- };
- };
- power-domain@RK3588_PD_VO1 {
- reg = <RK3588_PD_VO1>;
- clocks = <&cru PCLK_VO1_ROOT>,
- <&cru PCLK_VO1_S_ROOT>,
- <&cru HCLK_VO1_S_ROOT>,
- <&cru HCLK_HDCP1>,
- <&cru ACLK_HDCP1>,
- <&cru ACLK_HDMIRX_ROOT>,
- <&cru HCLK_VO1USB_TOP_ROOT>;
- pm_qos = <&qos_hdcp1>,
- <&qos_hdmirx>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_VI {
- reg = <RK3588_PD_VI>;
- clocks = <&cru HCLK_VI_ROOT>,
- <&cru PCLK_VI_ROOT>,
- <&cru HCLK_ISP0>,
- <&cru ACLK_ISP0>,
- <&cru HCLK_VICAP>,
- <&cru ACLK_VICAP>;
- pm_qos = <&qos_isp0_mro>,
- <&qos_isp0_mwo>,
- <&qos_vicap_m0>,
- <&qos_vicap_m1>;
- #address-cells = <1>;
- #size-cells = <0>;
- #power-domain-cells = <0>;
-
- power-domain@RK3588_PD_ISP1 {
- reg = <RK3588_PD_ISP1>;
- clocks = <&cru HCLK_ISP1>,
- <&cru ACLK_ISP1>,
- <&cru HCLK_VI_ROOT>,
- <&cru PCLK_VI_ROOT>;
- pm_qos = <&qos_isp1_mwo>,
- <&qos_isp1_mro>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_FEC {
- reg = <RK3588_PD_FEC>;
- clocks = <&cru HCLK_FISHEYE0>,
- <&cru ACLK_FISHEYE0>,
- <&cru HCLK_FISHEYE1>,
- <&cru ACLK_FISHEYE1>,
- <&cru PCLK_VI_ROOT>;
- pm_qos = <&qos_fisheye0>,
- <&qos_fisheye1>;
- #power-domain-cells = <0>;
- };
- };
- power-domain@RK3588_PD_RGA31 {
- reg = <RK3588_PD_RGA31>;
- clocks = <&cru HCLK_RGA3_1>,
- <&cru ACLK_RGA3_1>;
- pm_qos = <&qos_rga3_1>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_USB {
- reg = <RK3588_PD_USB>;
- clocks = <&cru PCLK_PHP_ROOT>,
- <&cru ACLK_USB_ROOT>,
- <&cru ACLK_USB>,
- <&cru HCLK_USB_ROOT>,
- <&cru HCLK_HOST0>,
- <&cru HCLK_HOST_ARB0>,
- <&cru HCLK_HOST1>,
- <&cru HCLK_HOST_ARB1>;
- pm_qos = <&qos_usb3_0>,
- <&qos_usb3_1>,
- <&qos_usb2host_0>,
- <&qos_usb2host_1>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_GMAC {
- reg = <RK3588_PD_GMAC>;
- clocks = <&cru PCLK_PHP_ROOT>,
- <&cru ACLK_PCIE_ROOT>,
- <&cru ACLK_PHP_ROOT>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_PCIE {
- reg = <RK3588_PD_PCIE>;
- clocks = <&cru PCLK_PHP_ROOT>,
- <&cru ACLK_PCIE_ROOT>,
- <&cru ACLK_PHP_ROOT>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_SDIO {
- reg = <RK3588_PD_SDIO>;
- clocks = <&cru HCLK_SDIO>,
- <&cru HCLK_NVM_ROOT>;
- pm_qos = <&qos_sdio>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_AUDIO {
- reg = <RK3588_PD_AUDIO>;
- clocks = <&cru HCLK_AUDIO_ROOT>,
- <&cru PCLK_AUDIO_ROOT>;
- #power-domain-cells = <0>;
- };
- power-domain@RK3588_PD_SDMMC {
- reg = <RK3588_PD_SDMMC>;
- pm_qos = <&qos_sdmmc>;
- #power-domain-cells = <0>;
- };
- };
- };
-
- i2s4_8ch: i2s@fddc0000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfddc0000 0x0 0x1000>;
- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S4_8CH_TX>, <&cru MCLK_I2S4_8CH_TX>, <&cru HCLK_I2S4_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S4_8CH_TX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 0>;
- dma-names = "tx";
- power-domains = <&power RK3588_PD_VO0>;
- resets = <&cru SRST_M_I2S4_8CH_TX>;
- reset-names = "tx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s5_8ch: i2s@fddf0000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfddf0000 0x0 0x1000>;
- interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S5_8CH_TX>, <&cru MCLK_I2S5_8CH_TX>, <&cru HCLK_I2S5_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S5_8CH_TX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 2>;
- dma-names = "tx";
- power-domains = <&power RK3588_PD_VO1>;
- resets = <&cru SRST_M_I2S5_8CH_TX>;
- reset-names = "tx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s9_8ch: i2s@fddfc000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfddfc000 0x0 0x1000>;
- interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S9_8CH_RX>, <&cru MCLK_I2S9_8CH_RX>, <&cru HCLK_I2S9_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S9_8CH_RX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac2 23>;
- dma-names = "rx";
- power-domains = <&power RK3588_PD_VO1>;
- resets = <&cru SRST_M_I2S9_8CH_RX>;
- reset-names = "rx-m";
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- qos_gpu_m0: qos@fdf35000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf35000 0x0 0x20>;
- };
-
- qos_gpu_m1: qos@fdf35200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf35200 0x0 0x20>;
- };
-
- qos_gpu_m2: qos@fdf35400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf35400 0x0 0x20>;
- };
-
- qos_gpu_m3: qos@fdf35600 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf35600 0x0 0x20>;
- };
-
- qos_rga3_1: qos@fdf36000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf36000 0x0 0x20>;
- };
-
- qos_sdio: qos@fdf39000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf39000 0x0 0x20>;
- };
-
- qos_sdmmc: qos@fdf3d800 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf3d800 0x0 0x20>;
- };
-
- qos_usb3_1: qos@fdf3e000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf3e000 0x0 0x20>;
- };
-
- qos_usb3_0: qos@fdf3e200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf3e200 0x0 0x20>;
- };
-
- qos_usb2host_0: qos@fdf3e400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf3e400 0x0 0x20>;
- };
-
- qos_usb2host_1: qos@fdf3e600 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf3e600 0x0 0x20>;
- };
-
- qos_fisheye0: qos@fdf40000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf40000 0x0 0x20>;
- };
-
- qos_fisheye1: qos@fdf40200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf40200 0x0 0x20>;
- };
-
- qos_isp0_mro: qos@fdf40400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf40400 0x0 0x20>;
- };
-
- qos_isp0_mwo: qos@fdf40500 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf40500 0x0 0x20>;
- };
-
- qos_vicap_m0: qos@fdf40600 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf40600 0x0 0x20>;
- };
-
- qos_vicap_m1: qos@fdf40800 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf40800 0x0 0x20>;
- };
-
- qos_isp1_mwo: qos@fdf41000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf41000 0x0 0x20>;
- };
-
- qos_isp1_mro: qos@fdf41100 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf41100 0x0 0x20>;
- };
-
- qos_rkvenc0_m0ro: qos@fdf60000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf60000 0x0 0x20>;
- };
-
- qos_rkvenc0_m1ro: qos@fdf60200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf60200 0x0 0x20>;
- };
-
- qos_rkvenc0_m2wo: qos@fdf60400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf60400 0x0 0x20>;
- };
-
- qos_rkvenc1_m0ro: qos@fdf61000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf61000 0x0 0x20>;
- };
-
- qos_rkvenc1_m1ro: qos@fdf61200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf61200 0x0 0x20>;
- };
-
- qos_rkvenc1_m2wo: qos@fdf61400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf61400 0x0 0x20>;
- };
-
- qos_rkvdec0: qos@fdf62000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf62000 0x0 0x20>;
- };
-
- qos_rkvdec1: qos@fdf63000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf63000 0x0 0x20>;
- };
-
- qos_av1: qos@fdf64000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf64000 0x0 0x20>;
- };
-
- qos_iep: qos@fdf66000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66000 0x0 0x20>;
- };
-
- qos_jpeg_dec: qos@fdf66200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66200 0x0 0x20>;
- };
-
- qos_jpeg_enc0: qos@fdf66400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66400 0x0 0x20>;
- };
-
- qos_jpeg_enc1: qos@fdf66600 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66600 0x0 0x20>;
- };
-
- qos_jpeg_enc2: qos@fdf66800 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66800 0x0 0x20>;
- };
-
- qos_jpeg_enc3: qos@fdf66a00 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66a00 0x0 0x20>;
- };
-
- qos_rga2_mro: qos@fdf66c00 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66c00 0x0 0x20>;
- };
-
- qos_rga2_mwo: qos@fdf66e00 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf66e00 0x0 0x20>;
- };
-
- qos_rga3_0: qos@fdf67000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf67000 0x0 0x20>;
- };
-
- qos_vdpu: qos@fdf67200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf67200 0x0 0x20>;
- };
-
- qos_npu1: qos@fdf70000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf70000 0x0 0x20>;
- };
-
- qos_npu2: qos@fdf71000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf71000 0x0 0x20>;
- };
-
- qos_npu0_mwr: qos@fdf72000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf72000 0x0 0x20>;
- };
-
- qos_npu0_mro: qos@fdf72200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf72200 0x0 0x20>;
- };
-
- qos_mcu_npu: qos@fdf72400 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf72400 0x0 0x20>;
- };
-
- qos_hdcp0: qos@fdf80000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf80000 0x0 0x20>;
- };
-
- qos_hdcp1: qos@fdf81000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf81000 0x0 0x20>;
- };
-
- qos_hdmirx: qos@fdf81200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf81200 0x0 0x20>;
- };
-
- qos_vop_m0: qos@fdf82000 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf82000 0x0 0x20>;
- };
-
- qos_vop_m1: qos@fdf82200 {
- compatible = "rockchip,rk3588-qos", "syscon";
- reg = <0x0 0xfdf82200 0x0 0x20>;
- };
-
- pcie2x1l1: pcie@fe180000 {
- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
- bus-range = <0x30 0x3f>;
- clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
- <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
- <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
- clock-names = "aclk_mst", "aclk_slv",
- "aclk_dbi", "pclk",
- "aux", "pipe";
- device_type = "pci";
- interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>,
- <0 0 0 2 &pcie2x1l1_intc 1>,
- <0 0 0 3 &pcie2x1l1_intc 2>,
- <0 0 0 4 &pcie2x1l1_intc 3>;
- linux,pci-domain = <3>;
- max-link-speed = <2>;
- msi-map = <0x3000 &its0 0x3000 0x1000>;
- num-lanes = <1>;
- phys = <&combphy2_psu PHY_TYPE_PCIE>;
- phy-names = "pcie-phy";
- power-domains = <&power RK3588_PD_PCIE>;
- ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>,
- <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>,
- <0x03000000 0x0 0x40000000 0x9 0xc0000000 0x0 0x40000000>;
- reg = <0xa 0x40c00000 0x0 0x00400000>,
- <0x0 0xfe180000 0x0 0x00010000>,
- <0x0 0xf3000000 0x0 0x00100000>;
- reg-names = "dbi", "apb", "config";
- resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
- reset-names = "pwr", "pipe";
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie2x1l1_intc: legacy-interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING 0>;
- };
- };
-
- pcie2x1l2: pcie@fe190000 {
- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
- bus-range = <0x40 0x4f>;
- clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
- <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
- <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
- clock-names = "aclk_mst", "aclk_slv",
- "aclk_dbi", "pclk",
- "aux", "pipe";
- device_type = "pci";
- interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
- <0 0 0 2 &pcie2x1l2_intc 1>,
- <0 0 0 3 &pcie2x1l2_intc 2>,
- <0 0 0 4 &pcie2x1l2_intc 3>;
- linux,pci-domain = <4>;
- max-link-speed = <2>;
- msi-map = <0x4000 &its0 0x4000 0x1000>;
- num-lanes = <1>;
- phys = <&combphy0_ps PHY_TYPE_PCIE>;
- phy-names = "pcie-phy";
- power-domains = <&power RK3588_PD_PCIE>;
- ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
- <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
- <0x03000000 0x0 0x40000000 0xa 0x00000000 0x0 0x40000000>;
- reg = <0xa 0x41000000 0x0 0x00400000>,
- <0x0 0xfe190000 0x0 0x00010000>,
- <0x0 0xf4000000 0x0 0x00100000>;
- reg-names = "dbi", "apb", "config";
- resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
- reset-names = "pwr", "pipe";
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie2x1l2_intc: legacy-interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
- };
- };
-
- dfi: dfi@fe060000 {
- reg = <0x00 0xfe060000 0x00 0x10000>;
- compatible = "rockchip,rk3588-dfi";
- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
- rockchip,pmu = <&pmu1grf>;
- };
-
- gmac1: ethernet@fe1c0000 {
- compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
- reg = <0x0 0xfe1c0000 0x0 0x10000>;
- interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "macirq", "eth_wake_irq";
- clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
- <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
- <&cru CLK_GMAC1_PTP_REF>;
- clock-names = "stmmaceth", "clk_mac_ref",
- "pclk_mac", "aclk_mac",
- "ptp_ref";
- power-domains = <&power RK3588_PD_GMAC>;
- resets = <&cru SRST_A_GMAC1>;
- reset-names = "stmmaceth";
- rockchip,grf = <&sys_grf>;
- rockchip,php-grf = <&php_grf>;
- snps,axi-config = <&gmac1_stmmac_axi_setup>;
- snps,mixed-burst;
- snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
- snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
- snps,tso;
- status = "disabled";
-
- mdio1: mdio {
- compatible = "snps,dwmac-mdio";
- #address-cells = <0x1>;
- #size-cells = <0x0>;
- };
-
- gmac1_stmmac_axi_setup: stmmac-axi-config {
- snps,blen = <0 0 0 0 16 8 4>;
- snps,wr_osr_lmt = <4>;
- snps,rd_osr_lmt = <8>;
- };
-
- gmac1_mtl_rx_setup: rx-queues-config {
- snps,rx-queues-to-use = <2>;
- queue0 {};
- queue1 {};
- };
-
- gmac1_mtl_tx_setup: tx-queues-config {
- snps,tx-queues-to-use = <2>;
- queue0 {};
- queue1 {};
- };
- };
-
- sata0: sata@fe210000 {
- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
- reg = <0 0xfe210000 0 0x1000>;
- interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
- <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
- <&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
- ports-implemented = <0x1>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- sata-port@0 {
- reg = <0>;
- hba-port-cap = <HBA_PORT_FBSCP>;
- phys = <&combphy0_ps PHY_TYPE_SATA>;
- phy-names = "sata-phy";
- snps,rx-ts-max = <32>;
- snps,tx-ts-max = <32>;
- };
- };
-
- sata2: sata@fe230000 {
- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
- reg = <0 0xfe230000 0 0x1000>;
- interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>,
- <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>,
- <&cru CLK_PIPEPHY2_PIPE_ASIC_G>;
- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
- ports-implemented = <0x1>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- sata-port@0 {
- reg = <0>;
- hba-port-cap = <HBA_PORT_FBSCP>;
- phys = <&combphy2_psu PHY_TYPE_SATA>;
- phy-names = "sata-phy";
- snps,rx-ts-max = <32>;
- snps,tx-ts-max = <32>;
- };
- };
-
- sfc: spi@fe2b0000 {
- compatible = "rockchip,sfc";
- reg = <0x0 0xfe2b0000 0x0 0x4000>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
- clock-names = "clk_sfc", "hclk_sfc";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- sdmmc: mmc@fe2c0000 {
- compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
- reg = <0x0 0xfe2c0000 0x0 0x4000>;
- interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
- <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
- clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
- fifo-depth = <0x100>;
- max-frequency = <200000000>;
- pinctrl-names = "default";
- pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
- power-domains = <&power RK3588_PD_SDMMC>;
- status = "disabled";
- };
-
- sdio: mmc@fe2d0000 {
- compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
- reg = <0x00 0xfe2d0000 0x00 0x4000>;
- interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>,
- <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
- clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
- fifo-depth = <0x100>;
- max-frequency = <200000000>;
- pinctrl-names = "default";
- pinctrl-0 = <&sdiom1_pins>;
- power-domains = <&power RK3588_PD_SDIO>;
- status = "disabled";
- };
-
- sdhci: mmc@fe2e0000 {
- compatible = "rockchip,rk3588-dwcmshc";
- reg = <0x0 0xfe2e0000 0x0 0x10000>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
- assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
- assigned-clock-rates = <200000000>, <24000000>, <200000000>;
- clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
- <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
- <&cru TMCLK_EMMC>;
- clock-names = "core", "bus", "axi", "block", "timer";
- max-frequency = <200000000>;
- pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>,
- <&emmc_cmd>, <&emmc_data_strobe>;
- pinctrl-names = "default";
- resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
- <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
- <&cru SRST_T_EMMC>;
- reset-names = "core", "bus", "axi", "block", "timer";
- status = "disabled";
- };
-
- i2s0_8ch: i2s@fe470000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfe470000 0x0 0x1000>;
- interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>, <&cru PLL_AUPLL>;
- dmas = <&dmac0 0>, <&dmac0 1>;
- dma-names = "tx", "rx";
- power-domains = <&power RK3588_PD_AUDIO>;
- resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
- reset-names = "tx-m", "rx-m";
- rockchip,trcm-sync-tx-only;
- pinctrl-names = "default";
- pinctrl-0 = <&i2s0_lrck
- &i2s0_sclk
- &i2s0_sdi0
- &i2s0_sdi1
- &i2s0_sdi2
- &i2s0_sdi3
- &i2s0_sdo0
- &i2s0_sdo1
- &i2s0_sdo2
- &i2s0_sdo3>;
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s1_8ch: i2s@fe480000 {
- compatible = "rockchip,rk3588-i2s-tdm";
- reg = <0x0 0xfe480000 0x0 0x1000>;
- interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>;
- clock-names = "mclk_tx", "mclk_rx", "hclk";
- dmas = <&dmac0 2>, <&dmac0 3>;
- dma-names = "tx", "rx";
- resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
- reset-names = "tx-m", "rx-m";
- rockchip,trcm-sync-tx-only;
- pinctrl-names = "default";
- pinctrl-0 = <&i2s1m0_lrck
- &i2s1m0_sclk
- &i2s1m0_sdi0
- &i2s1m0_sdi1
- &i2s1m0_sdi2
- &i2s1m0_sdi3
- &i2s1m0_sdo0
- &i2s1m0_sdo1
- &i2s1m0_sdo2
- &i2s1m0_sdo3>;
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s2_2ch: i2s@fe490000 {
- compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
- reg = <0x0 0xfe490000 0x0 0x1000>;
- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
- clock-names = "i2s_clk", "i2s_hclk";
- assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac1 0>, <&dmac1 1>;
- dma-names = "tx", "rx";
- power-domains = <&power RK3588_PD_AUDIO>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2s2m1_lrck
- &i2s2m1_sclk
- &i2s2m1_sdi
- &i2s2m1_sdo>;
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- i2s3_2ch: i2s@fe4a0000 {
- compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
- reg = <0x0 0xfe4a0000 0x0 0x1000>;
- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru MCLK_I2S3_2CH>, <&cru HCLK_I2S3_2CH>;
- clock-names = "i2s_clk", "i2s_hclk";
- assigned-clocks = <&cru CLK_I2S3_2CH_SRC>;
- assigned-clock-parents = <&cru PLL_AUPLL>;
- dmas = <&dmac1 2>, <&dmac1 3>;
- dma-names = "tx", "rx";
- power-domains = <&power RK3588_PD_AUDIO>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2s3_lrck
- &i2s3_sclk
- &i2s3_sdi
- &i2s3_sdo>;
- #sound-dai-cells = <0>;
- status = "disabled";
- };
-
- gic: interrupt-controller@fe600000 {
- compatible = "arm,gic-v3";
- reg = <0x0 0xfe600000 0 0x10000>, /* GICD */
- <0x0 0xfe680000 0 0x100000>; /* GICR */
- interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-controller;
- mbi-alias = <0x0 0xfe610000>;
- mbi-ranges = <424 56>;
- msi-controller;
- ranges;
- #address-cells = <2>;
- #interrupt-cells = <4>;
- #size-cells = <2>;
-
- its0: msi-controller@fe640000 {
- compatible = "arm,gic-v3-its";
- reg = <0x0 0xfe640000 0x0 0x20000>;
- msi-controller;
- #msi-cells = <1>;
- };
-
- its1: msi-controller@fe660000 {
- compatible = "arm,gic-v3-its";
- reg = <0x0 0xfe660000 0x0 0x20000>;
- msi-controller;
- #msi-cells = <1>;
- };
-
- ppi-partitions {
- ppi_partition0: interrupt-partition-0 {
- affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
- };
-
- ppi_partition1: interrupt-partition-1 {
- affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
- };
- };
- };
-
- dmac0: dma-controller@fea10000 {
- compatible = "arm,pl330", "arm,primecell";
- reg = <0x0 0xfea10000 0x0 0x4000>;
- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
- arm,pl330-periph-burst;
- clocks = <&cru ACLK_DMAC0>;
- clock-names = "apb_pclk";
- #dma-cells = <1>;
- };
-
- dmac1: dma-controller@fea30000 {
- compatible = "arm,pl330", "arm,primecell";
- reg = <0x0 0xfea30000 0x0 0x4000>;
- interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
- arm,pl330-periph-burst;
- clocks = <&cru ACLK_DMAC1>;
- clock-names = "apb_pclk";
- #dma-cells = <1>;
- };
-
- i2c1: i2c@fea90000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfea90000 0x0 0x1000>;
- clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c1m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c2: i2c@feaa0000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfeaa0000 0x0 0x1000>;
- clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c2m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c3: i2c@feab0000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfeab0000 0x0 0x1000>;
- clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c3m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c4: i2c@feac0000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfeac0000 0x0 0x1000>;
- clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c4m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c5: i2c@fead0000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfead0000 0x0 0x1000>;
- clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c5m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- timer0: timer@feae0000 {
- compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer";
- reg = <0x0 0xfeae0000 0x0 0x20>;
- interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>;
- clock-names = "pclk", "timer";
- };
-
- wdt: watchdog@feaf0000 {
- compatible = "rockchip,rk3588-wdt", "snps,dw-wdt";
- reg = <0x0 0xfeaf0000 0x0 0x100>;
- clocks = <&cru TCLK_WDT0>, <&cru PCLK_WDT0>;
- clock-names = "tclk", "pclk";
- interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH 0>;
- };
-
- spi0: spi@feb00000 {
- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
- reg = <0x0 0xfeb00000 0x0 0x1000>;
- interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
- clock-names = "spiclk", "apb_pclk";
- dmas = <&dmac0 14>, <&dmac0 15>;
- dma-names = "tx", "rx";
- num-cs = <2>;
- pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi1: spi@feb10000 {
- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
- reg = <0x0 0xfeb10000 0x0 0x1000>;
- interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
- clock-names = "spiclk", "apb_pclk";
- dmas = <&dmac0 16>, <&dmac0 17>;
- dma-names = "tx", "rx";
- num-cs = <2>;
- pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi2: spi@feb20000 {
- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
- reg = <0x0 0xfeb20000 0x0 0x1000>;
- interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
- clock-names = "spiclk", "apb_pclk";
- dmas = <&dmac1 15>, <&dmac1 16>;
- dma-names = "tx", "rx";
- num-cs = <2>;
- pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi3: spi@feb30000 {
- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
- reg = <0x0 0xfeb30000 0x0 0x1000>;
- interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
- clock-names = "spiclk", "apb_pclk";
- dmas = <&dmac1 17>, <&dmac1 18>;
- dma-names = "tx", "rx";
- num-cs = <2>;
- pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- uart1: serial@feb40000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeb40000 0x0 0x100>;
- interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac0 8>, <&dmac0 9>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart1m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart2: serial@feb50000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeb50000 0x0 0x100>;
- interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac0 10>, <&dmac0 11>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart2m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart3: serial@feb60000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeb60000 0x0 0x100>;
- interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac0 12>, <&dmac0 13>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart3m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart4: serial@feb70000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeb70000 0x0 0x100>;
- interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac1 9>, <&dmac1 10>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart4m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart5: serial@feb80000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeb80000 0x0 0x100>;
- interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac1 11>, <&dmac1 12>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart5m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart6: serial@feb90000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeb90000 0x0 0x100>;
- interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac1 13>, <&dmac1 14>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart6m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart7: serial@feba0000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfeba0000 0x0 0x100>;
- interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac2 7>, <&dmac2 8>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart7m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart8: serial@febb0000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfebb0000 0x0 0x100>;
- interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac2 9>, <&dmac2 10>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart8m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- uart9: serial@febc0000 {
- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
- reg = <0x0 0xfebc0000 0x0 0x100>;
- interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
- clock-names = "baudclk", "apb_pclk";
- dmas = <&dmac2 11>, <&dmac2 12>;
- dma-names = "tx", "rx";
- pinctrl-0 = <&uart9m1_xfer>;
- pinctrl-names = "default";
- reg-io-width = <4>;
- reg-shift = <2>;
- status = "disabled";
- };
-
- pwm4: pwm@febd0000 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebd0000 0x0 0x10>;
- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm4m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm5: pwm@febd0010 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebd0010 0x0 0x10>;
- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm5m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm6: pwm@febd0020 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebd0020 0x0 0x10>;
- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm6m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm7: pwm@febd0030 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebd0030 0x0 0x10>;
- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm7m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm8: pwm@febe0000 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebe0000 0x0 0x10>;
- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm8m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm9: pwm@febe0010 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebe0010 0x0 0x10>;
- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm9m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm10: pwm@febe0020 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebe0020 0x0 0x10>;
- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm10m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm11: pwm@febe0030 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebe0030 0x0 0x10>;
- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm11m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm12: pwm@febf0000 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebf0000 0x0 0x10>;
- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm12m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm13: pwm@febf0010 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebf0010 0x0 0x10>;
- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm13m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm14: pwm@febf0020 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebf0020 0x0 0x10>;
- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm14m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pwm15: pwm@febf0030 {
- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
- reg = <0x0 0xfebf0030 0x0 0x10>;
- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
- clock-names = "pwm", "pclk";
- pinctrl-0 = <&pwm15m0_pins>;
- pinctrl-names = "default";
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- tsadc: tsadc@fec00000 {
- compatible = "rockchip,rk3588-tsadc";
- reg = <0x0 0xfec00000 0x0 0x400>;
- interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
- clock-names = "tsadc", "apb_pclk";
- assigned-clocks = <&cru CLK_TSADC>;
- assigned-clock-rates = <2000000>;
- resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>;
- reset-names = "tsadc-apb", "tsadc";
- rockchip,hw-tshut-temp = <120000>;
- rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
- rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
- pinctrl-0 = <&tsadc_gpio_func>;
- pinctrl-1 = <&tsadc_shut>;
- pinctrl-names = "gpio", "otpout";
- #thermal-sensor-cells = <1>;
- status = "disabled";
- };
-
- saradc: adc@fec10000 {
- compatible = "rockchip,rk3588-saradc";
- reg = <0x0 0xfec10000 0x0 0x10000>;
- interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH 0>;
- #io-channel-cells = <1>;
- clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
- clock-names = "saradc", "apb_pclk";
- resets = <&cru SRST_P_SARADC>;
- reset-names = "saradc-apb";
- status = "disabled";
- };
-
- i2c6: i2c@fec80000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfec80000 0x0 0x1000>;
- clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c6m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c7: i2c@fec90000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfec90000 0x0 0x1000>;
- clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c7m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c8: i2c@feca0000 {
- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
- reg = <0x0 0xfeca0000 0x0 0x1000>;
- clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
- clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
- pinctrl-0 = <&i2c8m0_xfer>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi4: spi@fecb0000 {
- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
- reg = <0x0 0xfecb0000 0x0 0x1000>;
- interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
- clock-names = "spiclk", "apb_pclk";
- dmas = <&dmac2 13>, <&dmac2 14>;
- dma-names = "tx", "rx";
- num-cs = <2>;
- pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- otp: efuse@fecc0000 {
- compatible = "rockchip,rk3588-otp";
- reg = <0x0 0xfecc0000 0x0 0x400>;
- clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
- <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
- clock-names = "otp", "apb_pclk", "phy", "arb";
- resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
- <&cru SRST_OTPC_ARB>;
- reset-names = "otp", "apb", "arb";
- #address-cells = <1>;
- #size-cells = <1>;
-
- cpu_code: cpu-code@2 {
- reg = <0x02 0x2>;
- };
-
- otp_id: id@7 {
- reg = <0x07 0x10>;
- };
-
- cpub0_leakage: cpu-leakage@17 {
- reg = <0x17 0x1>;
- };
-
- cpub1_leakage: cpu-leakage@18 {
- reg = <0x18 0x1>;
- };
-
- cpul_leakage: cpu-leakage@19 {
- reg = <0x19 0x1>;
- };
-
- log_leakage: log-leakage@1a {
- reg = <0x1a 0x1>;
- };
-
- gpu_leakage: gpu-leakage@1b {
- reg = <0x1b 0x1>;
- };
-
- otp_cpu_version: cpu-version@1c {
- reg = <0x1c 0x1>;
- bits = <3 3>;
- };
-
- npu_leakage: npu-leakage@28 {
- reg = <0x28 0x1>;
- };
-
- codec_leakage: codec-leakage@29 {
- reg = <0x29 0x1>;
- };
- };
-
- dmac2: dma-controller@fed10000 {
- compatible = "arm,pl330", "arm,primecell";
- reg = <0x0 0xfed10000 0x0 0x4000>;
- interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
- <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
- arm,pl330-periph-burst;
- clocks = <&cru ACLK_DMAC2>;
- clock-names = "apb_pclk";
- #dma-cells = <1>;
- };
-
- hdptxphy_hdmi0: phy@fed60000 {
- compatible = "rockchip,rk3588-hdptx-phy";
- reg = <0x0 0xfed60000 0x0 0x2000>;
- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
- clock-names = "ref", "apb";
- #phy-cells = <0>;
- resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
- <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
- <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
- <&cru SRST_HDPTX0_LCPLL>;
- reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
- "lcpll";
- rockchip,grf = <&hdptxphy0_grf>;
- status = "disabled";
- };
-
- combphy0_ps: phy@fee00000 {
- compatible = "rockchip,rk3588-naneng-combphy";
- reg = <0x0 0xfee00000 0x0 0x100>;
- clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
- <&cru PCLK_PHP_ROOT>;
- clock-names = "ref", "apb", "pipe";
- assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
- assigned-clock-rates = <100000000>;
- #phy-cells = <1>;
- resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>;
- reset-names = "phy", "apb";
- rockchip,pipe-grf = <&php_grf>;
- rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
- status = "disabled";
- };
-
- combphy2_psu: phy@fee20000 {
- compatible = "rockchip,rk3588-naneng-combphy";
- reg = <0x0 0xfee20000 0x0 0x100>;
- clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
- <&cru PCLK_PHP_ROOT>;
- clock-names = "ref", "apb", "pipe";
- assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
- assigned-clock-rates = <100000000>;
- #phy-cells = <1>;
- resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>;
- reset-names = "phy", "apb";
- rockchip,pipe-grf = <&php_grf>;
- rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
- status = "disabled";
- };
-
- system_sram2: sram@ff001000 {
- compatible = "mmio-sram";
- reg = <0x0 0xff001000 0x0 0xef000>;
- ranges = <0x0 0x0 0xff001000 0xef000>;
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
- pinctrl: pinctrl {
- compatible = "rockchip,rk3588-pinctrl";
- ranges;
- rockchip,grf = <&ioc>;
- #address-cells = <2>;
- #size-cells = <2>;
-
- gpio0: gpio@fd8a0000 {
- compatible = "rockchip,gpio-bank";
- reg = <0x0 0xfd8a0000 0x0 0x100>;
- interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 0 32>;
- interrupt-controller;
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- };
-
- gpio1: gpio@fec20000 {
- compatible = "rockchip,gpio-bank";
- reg = <0x0 0xfec20000 0x0 0x100>;
- interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 32 32>;
- interrupt-controller;
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- };
-
- gpio2: gpio@fec30000 {
- compatible = "rockchip,gpio-bank";
- reg = <0x0 0xfec30000 0x0 0x100>;
- interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 64 32>;
- interrupt-controller;
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- };
-
- gpio3: gpio@fec40000 {
- compatible = "rockchip,gpio-bank";
- reg = <0x0 0xfec40000 0x0 0x100>;
- interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 96 32>;
- interrupt-controller;
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- };
-
- gpio4: gpio@fec50000 {
- compatible = "rockchip,gpio-bank";
- reg = <0x0 0xfec50000 0x0 0x100>;
- interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 128 32>;
- interrupt-controller;
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- };
- };
-
- av1d: video-codec@fdc70000 {
- compatible = "rockchip,rk3588-av1-vpu";
- reg = <0x0 0xfdc70000 0x0 0x800>;
- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
- interrupt-names = "vdpu";
- assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
- assigned-clock-rates = <400000000>, <400000000>;
- clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
- clock-names = "aclk", "hclk";
- power-domains = <&power RK3588_PD_AV1>;
- resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
- };
-};
-
-#include "rk3588s-pinctrl.dtsi"
+#include "rk3588-base.dtsi"
+#include "rk3588-opp.dtsi"
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
index da44a15a8adf..a251c4343548 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
@@ -111,7 +111,7 @@
&i2c0 {
status = "okay";
- tas5707a@1d {
+ audio-codec@1d {
compatible = "ti,tas5711";
reg = <0x1d>;
reset-gpios = <&gpio UNIPHIER_GPIO_PORT(23, 4) GPIO_ACTIVE_LOW>;
@@ -124,7 +124,7 @@
PVDD_C-supply = <&amp_vcc_reg>;
PVDD_D-supply = <&amp_vcc_reg>;
- port@0 {
+ port {
tas_speaker: endpoint {
dai-format = "i2s";
remote-endpoint = <&i2s_hpcmout1>;
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
index a01579cb3b79..79f6db2455c1 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
@@ -111,7 +111,7 @@
&i2c0 {
status = "okay";
- tas5707@1b {
+ audio-codec@1b {
compatible = "ti,tas5711";
reg = <0x1b>;
reset-gpios = <&gpio UNIPHIER_GPIO_PORT(0, 0) GPIO_ACTIVE_LOW>;
@@ -124,7 +124,7 @@
PVDD_C-supply = <&amp_vcc_reg>;
PVDD_D-supply = <&amp_vcc_reg>;
- port@0 {
+ port {
tas_speaker: endpoint {
dai-format = "i2s";
remote-endpoint = <&i2s_hpcmout1>;
diff --git a/arch/arm64/boot/dts/sprd/sc9860.dtsi b/arch/arm64/boot/dts/sprd/sc9860.dtsi
index e27eb3ed1d47..31952d361a8a 100644
--- a/arch/arm64/boot/dts/sprd/sc9860.dtsi
+++ b/arch/arm64/boot/dts/sprd/sc9860.dtsi
@@ -113,7 +113,7 @@
};
};
- idle-states{
+ idle-states {
entry-method = "psci";
CORE_PD: core_pd {
@@ -135,18 +135,6 @@
};
};
- gic: interrupt-controller@12001000 {
- compatible = "arm,gic-400";
- reg = <0 0x12001000 0 0x1000>,
- <0 0x12002000 0 0x2000>,
- <0 0x12004000 0 0x2000>,
- <0 0x12006000 0 0x2000>;
- #interrupt-cells = <3>;
- interrupt-controller;
- interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8)
- | IRQ_TYPE_LEVEL_HIGH)>;
- };
-
psci {
compatible = "arm,psci-0.2";
method = "smc";
@@ -165,7 +153,7 @@
};
pmu {
- compatible = "arm,cortex-a53-pmu", "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
@@ -185,6 +173,18 @@
};
soc {
+ gic: interrupt-controller@12001000 {
+ compatible = "arm,gic-400";
+ reg = <0 0x12001000 0 0x1000>,
+ <0 0x12002000 0 0x2000>,
+ <0 0x12004000 0 0x2000>,
+ <0 0x12006000 0 0x2000>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8)
+ | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
pmu_gate: pmu-gate {
compatible = "sprd,sc9860-pmu-gate";
sprd,syscon = <&pmu_regs>; /* 0x402b0000 */
@@ -207,7 +207,7 @@
#clock-cells = <1>;
};
- aon_prediv: aon-prediv {
+ aon_prediv: aon-prediv@402d0000 {
compatible = "sprd,sc9860-aon-prediv";
reg = <0 0x402d0000 0 0x400>;
clocks = <&ext_26m>, <&pll 0>,
@@ -684,33 +684,5 @@
};
};
};
-
- gpio-keys {
- compatible = "gpio-keys";
-
- key-volumedown {
- label = "Volume Down Key";
- linux,code = <KEY_VOLUMEDOWN>;
- gpios = <&eic_debounce 2 GPIO_ACTIVE_LOW>;
- debounce-interval = <2>;
- wakeup-source;
- };
-
- key-volumeup {
- label = "Volume Up Key";
- linux,code = <KEY_VOLUMEUP>;
- gpios = <&pmic_eic 10 GPIO_ACTIVE_HIGH>;
- debounce-interval = <2>;
- wakeup-source;
- };
-
- key-power {
- label = "Power Key";
- linux,code = <KEY_POWER>;
- gpios = <&pmic_eic 1 GPIO_ACTIVE_HIGH>;
- debounce-interval = <2>;
- wakeup-source;
- };
- };
};
};
diff --git a/arch/arm64/boot/dts/sprd/sc9863a.dtsi b/arch/arm64/boot/dts/sprd/sc9863a.dtsi
index 22d81ace740a..53e5b77d70b5 100644
--- a/arch/arm64/boot/dts/sprd/sc9863a.dtsi
+++ b/arch/arm64/boot/dts/sprd/sc9863a.dtsi
@@ -134,7 +134,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/sprd/sharkl3.dtsi b/arch/arm64/boot/dts/sprd/sharkl3.dtsi
index 206a4afdab1c..9b4ee0bdd69f 100644
--- a/arch/arm64/boot/dts/sprd/sharkl3.dtsi
+++ b/arch/arm64/boot/dts/sprd/sharkl3.dtsi
@@ -24,7 +24,7 @@
#size-cells = <1>;
ranges = <0 0 0x20e00000 0x4000>;
- apahb_gate: apahb-gate {
+ apahb_gate: apahb-gate@0 {
compatible = "sprd,sc9863a-apahb-gate";
reg = <0x0 0x1020>;
#clock-cells = <1>;
@@ -39,7 +39,7 @@
#size-cells = <1>;
ranges = <0 0 0x402b0000 0x4000>;
- pmu_gate: pmu-gate {
+ pmu_gate: pmu-gate@0 {
compatible = "sprd,sc9863a-pmu-gate";
reg = <0 0x1200>;
clocks = <&ext_26m>;
@@ -56,7 +56,7 @@
#size-cells = <1>;
ranges = <0 0 0x402e0000 0x4000>;
- aonapb_gate: aonapb-gate {
+ aonapb_gate: aonapb-gate@0 {
compatible = "sprd,sc9863a-aonapb-gate";
reg = <0 0x1100>;
#clock-cells = <1>;
@@ -71,7 +71,7 @@
#size-cells = <1>;
ranges = <0 0 0x40353000 0x3000>;
- pll: pll {
+ pll: pll@0 {
compatible = "sprd,sc9863a-pll";
reg = <0 0x100>;
clocks = <&ext_26m>;
@@ -88,7 +88,7 @@
#size-cells = <1>;
ranges = <0 0 0x40359000 0x3000>;
- mpll: mpll {
+ mpll: mpll@0 {
compatible = "sprd,sc9863a-mpll";
reg = <0 0x100>;
#clock-cells = <1>;
@@ -103,7 +103,7 @@
#size-cells = <1>;
ranges = <0 0 0x4035c000 0x3000>;
- rpll: rpll {
+ rpll: rpll@0 {
compatible = "sprd,sc9863a-rpll";
reg = <0 0x100>;
clocks = <&ext_26m>;
@@ -120,7 +120,7 @@
#size-cells = <1>;
ranges = <0 0 0x40363000 0x3000>;
- dpll: dpll {
+ dpll: dpll@0 {
compatible = "sprd,sc9863a-dpll";
reg = <0 0x100>;
#clock-cells = <1>;
@@ -135,7 +135,7 @@
#size-cells = <1>;
ranges = <0 0 0x60800000 0x3000>;
- mm_gate: mm-gate {
+ mm_gate: mm-gate@0 {
compatible = "sprd,sc9863a-mm-gate";
reg = <0 0x1100>;
#clock-cells = <1>;
@@ -150,7 +150,7 @@
#size-cells = <1>;
ranges = <0 0 0x71300000 0x4000>;
- apapb_gate: apapb-gate {
+ apapb_gate: apapb-gate@0 {
compatible = "sprd,sc9863a-apapb-gate";
reg = <0 0x1000>;
clocks = <&ext_26m>;
diff --git a/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts b/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
index 6b95fd94cee3..1ce3cbbd9668 100644
--- a/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
+++ b/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
@@ -24,7 +24,7 @@
spi0 = &adi_bus;
};
- memory{
+ memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0 0x60000000>,
<0x1 0x80000000 0 0x60000000>;
@@ -34,6 +34,34 @@
stdout-path = "serial1:115200n8";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-volumedown {
+ label = "Volume Down Key";
+ linux,code = <KEY_VOLUMEDOWN>;
+ gpios = <&eic_debounce 2 GPIO_ACTIVE_LOW>;
+ debounce-interval = <2>;
+ wakeup-source;
+ };
+
+ key-volumeup {
+ label = "Volume Up Key";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pmic_eic 10 GPIO_ACTIVE_HIGH>;
+ debounce-interval = <2>;
+ wakeup-source;
+ };
+
+ key-power {
+ label = "Power Key";
+ linux,code = <KEY_POWER>;
+ gpios = <&pmic_eic 1 GPIO_ACTIVE_HIGH>;
+ debounce-interval = <2>;
+ wakeup-source;
+ };
+ };
+
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
diff --git a/arch/arm64/boot/dts/sprd/ums512.dtsi b/arch/arm64/boot/dts/sprd/ums512.dtsi
index dbdb79f8e959..4c080df48724 100644
--- a/arch/arm64/boot/dts/sprd/ums512.dtsi
+++ b/arch/arm64/boot/dts/sprd/ums512.dtsi
@@ -136,16 +136,22 @@
<GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>; /* Hipervisor PPI */
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>;
+ };
+
+ pmu-a75 {
+ compatible = "arm,cortex-a75-pmu";
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&CPU6>, <&CPU7>;
};
soc: soc {
diff --git a/arch/arm64/boot/dts/sprd/ums9620.dtsi b/arch/arm64/boot/dts/sprd/ums9620.dtsi
index 2191f0a4811b..2458071320c9 100644
--- a/arch/arm64/boot/dts/sprd/ums9620.dtsi
+++ b/arch/arm64/boot/dts/sprd/ums9620.dtsi
@@ -144,16 +144,22 @@
<GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>; /* Hipervisor PPI */
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>;
+ };
+
+ pmu-a76 {
+ compatible = "arm,cortex-a76-pmu";
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
};
soc: soc {
diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi b/arch/arm64/boot/dts/sprd/whale2.dtsi
index fece49704b5c..7068bfd2f4c3 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -64,7 +64,7 @@
reg = <0 0x70b00000 0 0x40000>;
};
- ap-apb {
+ ap-apb@70000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
index 66791a974f8f..8fdd5f020425 100644
--- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
@@ -6,6 +6,82 @@
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
&pinctrl {
+ eth2_rgmii_pins_a: eth2-rgmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('C', 7, AF10)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('C', 8, AF10)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 9, AF10)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('C', 10, AF10)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('C', 4, AF10)>; /* ETH_RGMII_TX_CTL */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <3>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 8, AF10)>, /* ETH_RGMII_CLK125 */
+ <STM32_PINMUX('F', 7, AF10)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('C', 6, AF10)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <3>;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('C', 5, AF10)>; /* ETH_MDIO */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins4 {
+ pinmux = <STM32_PINMUX('G', 0, AF10)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 12, AF10)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('F', 9, AF10)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('C', 11, AF10)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('C', 3, AF10)>; /* ETH_RGMII_RX_CTL */
+ bias-disable;
+ };
+ pins5 {
+ pinmux = <STM32_PINMUX('F', 6, AF10)>; /* ETH_RGMII_RX_CLK */
+ bias-disable;
+ };
+ };
+
+ eth2_rgmii_sleep_pins_a: eth2-rgmii-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 7, ANALOG)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('C', 8, ANALOG)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 9, ANALOG)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('C', 10, ANALOG)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('F', 8, ANALOG)>, /* ETH_RGMII_CLK125 */
+ <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('C', 6, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 0, ANALOG)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 12, ANALOG)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('F', 9, ANALOG)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('C', 11, ANALOG)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('C', 3, ANALOG)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('F', 6, ANALOG)>; /* ETH_RGMII_RX_CLK */
+ };
+ };
+
+ i2c2_pins_a: i2c2-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 5, AF9)>, /* I2C2_SCL */
+ <STM32_PINMUX('B', 4, AF9)>; /* I2C2_SDA */
+ bias-disable;
+ drive-open-drain;
+ slew-rate = <0>;
+ };
+ };
+
+ i2c2_sleep_pins_a: i2c2-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 5, ANALOG)>, /* I2C2_SCL */
+ <STM32_PINMUX('B', 4, ANALOG)>; /* I2C2_SDA */
+ };
+ };
+
sdmmc1_b4_pins_a: sdmmc1-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
@@ -60,6 +136,28 @@
};
};
+ spi3_pins_a: spi3-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 7, AF1)>, /* SPI3_SCK */
+ <STM32_PINMUX('B', 8, AF1)>; /* SPI3_MOSI */
+ drive-push-pull;
+ bias-disable;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 10, AF1)>; /* SPI3_MISO */
+ bias-disable;
+ };
+ };
+
+ spi3_sleep_pins_a: spi3-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 7, ANALOG)>, /* SPI3_SCK */
+ <STM32_PINMUX('B', 8, ANALOG)>, /* SPI3_MOSI */
+ <STM32_PINMUX('B', 10, ANALOG)>; /* SPI3_MISO */
+ };
+ };
+
usart2_pins_a: usart2-0 {
pins1 {
pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */
@@ -89,4 +187,88 @@
<STM32_PINMUX('A', 8, ANALOG)>; /* USART2_RX */
};
};
+
+ usart6_pins_a: usart6-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 13, AF3)>, /* USART6_TX */
+ <STM32_PINMUX('G', 5, AF3)>; /* USART6_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 14, AF3)>, /* USART6_RX */
+ <STM32_PINMUX('F', 15, AF3)>; /* USART6_CTS_NSS */
+ bias-pull-up;
+ };
+ };
+
+ usart6_idle_pins_a: usart6-idle-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 13, ANALOG)>, /* USART6_TX */
+ <STM32_PINMUX('F', 15, ANALOG)>; /* USART6_CTS_NSS */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('G', 5, AF3)>; /* USART6_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('F', 14, AF3)>; /* USART6_RX */
+ bias-pull-up;
+ };
+ };
+
+ usart6_sleep_pins_a: usart6-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 13, ANALOG)>, /* USART6_TX */
+ <STM32_PINMUX('G', 5, ANALOG)>, /* USART6_RTS */
+ <STM32_PINMUX('F', 15, ANALOG)>, /* USART6_CTS_NSS */
+ <STM32_PINMUX('F', 14, ANALOG)>; /* USART6_RX */
+ };
+ };
+};
+
+&pinctrl_z {
+ i2c8_pins_a: i2c8-0 {
+ pins {
+ pinmux = <STM32_PINMUX('Z', 4, AF8)>, /* I2C8_SCL */
+ <STM32_PINMUX('Z', 3, AF8)>; /* I2C8_SDA */
+ bias-disable;
+ drive-open-drain;
+ slew-rate = <0>;
+ };
+ };
+
+ i2c8_sleep_pins_a: i2c8-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C8_SCL */
+ <STM32_PINMUX('Z', 3, ANALOG)>; /* I2C8_SDA */
+ };
+ };
+};
+
+&pinctrl_z {
+ spi8_pins_a: spi8-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('Z', 2, AF3)>, /* SPI8_SCK */
+ <STM32_PINMUX('Z', 0, AF3)>; /* SPI8_MOSI */
+ drive-push-pull;
+ bias-disable;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('Z', 1, AF3)>; /* SPI8_MISO */
+ bias-disable;
+ };
+ };
+
+ spi8_sleep_pins_a: spi8-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('Z', 2, ANALOG)>, /* SPI8_SCK */
+ <STM32_PINMUX('Z', 0, ANALOG)>, /* SPI8_MOSI */
+ <STM32_PINMUX('Z', 1, ANALOG)>; /* SPI8_MISO */
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 5dd4f3580a60..1167cf63d7e8 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -3,7 +3,10 @@
* Copyright (C) STMicroelectronics 2023 - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
+#include <dt-bindings/clock/st,stm32mp25-rcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/st,stm32mp25-rcc.h>
+#include <dt-bindings/regulator/st,stm32mp25-regulator.h>
/ {
#address-cells = <2>;
@@ -18,6 +21,8 @@
device_type = "cpu";
reg = <0>;
enable-method = "psci";
+ power-domains = <&CPU_PD0>;
+ power-domain-names = "psci";
};
};
@@ -35,41 +40,25 @@
};
clocks {
- ck_flexgen_08: ck-flexgen-08 {
+ clk_dsi_txbyte: txbyteclk {
#clock-cells = <0>;
compatible = "fixed-clock";
- clock-frequency = <100000000>;
+ clock-frequency = <0>;
};
- ck_flexgen_51: ck-flexgen-51 {
+ clk_rcbsec: clk-rcbsec {
#clock-cells = <0>;
compatible = "fixed-clock";
- clock-frequency = <200000000>;
- };
-
- ck_icn_ls_mcu: ck-icn-ls-mcu {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <200000000>;
- };
-
- ck_icn_p_vdec: ck-icn-p-vdec {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <200000000>;
- };
-
- ck_icn_p_venc: ck-icn-p-venc {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <200000000>;
+ clock-frequency = <64000000>;
};
};
firmware {
- optee {
+ optee: optee {
compatible = "linaro,optee-tz";
method = "smc";
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
};
scmi {
@@ -87,6 +76,40 @@
reg = <0x16>;
#reset-cells = <1>;
};
+
+ scmi_voltd: protocol@17 {
+ reg = <0x17>;
+
+ scmi_regu: regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_vddio1: regulator@0 {
+ reg = <VOLTD_SCMI_VDDIO1>;
+ regulator-name = "vddio1";
+ };
+ scmi_vddio2: regulator@1 {
+ reg = <VOLTD_SCMI_VDDIO2>;
+ regulator-name = "vddio2";
+ };
+ scmi_vddio3: regulator@2 {
+ reg = <VOLTD_SCMI_VDDIO3>;
+ regulator-name = "vddio3";
+ };
+ scmi_vddio4: regulator@3 {
+ reg = <VOLTD_SCMI_VDDIO4>;
+ regulator-name = "vddio4";
+ };
+ scmi_vdd33ucpd: regulator@5 {
+ reg = <VOLTD_SCMI_UCPD>;
+ regulator-name = "vdd33ucpd";
+ };
+ scmi_vdda18adc: regulator@7 {
+ reg = <VOLTD_SCMI_ADC>;
+ regulator-name = "vdda18adc";
+ };
+ };
+ };
};
};
@@ -104,15 +127,29 @@
psci {
compatible = "arm,psci-1.0";
method = "smc";
+
+ CPU_PD0: power-domain-cpu0 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ };
+
+ CLUSTER_PD: power-domain-cluster {
+ #power-domain-cells = <0>;
+ power-domains = <&RET_PD>;
+ };
+
+ RET_PD: power-domain-retention {
+ #power-domain-cells = <0>;
+ };
};
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&intc>;
- 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)>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
always-on;
};
@@ -123,18 +160,361 @@
interrupt-parent = <&intc>;
ranges = <0x0 0x0 0x0 0x80000000>;
- rifsc: rifsc-bus@42080000 {
- compatible = "simple-bus";
+ hpdma: dma-controller@40400000 {
+ compatible = "st,stm32mp25-dma3";
+ reg = <0x40400000 0x1000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk CK_SCMI_HPDMA1>;
+ #dma-cells = <3>;
+ };
+
+ hpdma2: dma-controller@40410000 {
+ compatible = "st,stm32mp25-dma3";
+ reg = <0x40410000 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <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>,
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk CK_SCMI_HPDMA2>;
+ #dma-cells = <3>;
+ };
+
+ hpdma3: dma-controller@40420000 {
+ compatible = "st,stm32mp25-dma3";
+ reg = <0x40420000 0x1000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <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 73 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk CK_SCMI_HPDMA3>;
+ #dma-cells = <3>;
+ };
+
+ rifsc: bus@42080000 {
+ compatible = "st,stm32mp25-rifsc", "simple-bus";
reg = <0x42080000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+ #access-controller-cells = <1>;
ranges;
+ spi2: spi@400b0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x400b0000 0x400>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI2>;
+ resets = <&rcc SPI2_R>;
+ access-controllers = <&rifsc 23>;
+ status = "disabled";
+ };
+
+ spi3: spi@400c0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x400c0000 0x400>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI3>;
+ resets = <&rcc SPI3_R>;
+ access-controllers = <&rifsc 24>;
+ status = "disabled";
+ };
+
usart2: serial@400e0000 {
compatible = "st,stm32h7-uart";
reg = <0x400e0000 0x400>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ck_flexgen_08>;
+ clocks = <&rcc CK_KER_USART2>;
+ access-controllers = <&rifsc 32>;
+ status = "disabled";
+ };
+
+ usart3: serial@400f0000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x400f0000 0x400>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_USART3>;
+ access-controllers = <&rifsc 33>;
+ status = "disabled";
+ };
+
+ uart4: serial@40100000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40100000 0x400>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_UART4>;
+ access-controllers = <&rifsc 34>;
+ status = "disabled";
+ };
+
+ uart5: serial@40110000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40110000 0x400>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_UART5>;
+ access-controllers = <&rifsc 35>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@40120000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40120000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C1>;
+ resets = <&rcc I2C1_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 41>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@40130000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40130000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C2>;
+ resets = <&rcc I2C2_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 42>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@40140000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40140000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C3>;
+ resets = <&rcc I2C3_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 43>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@40150000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40150000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C4>;
+ resets = <&rcc I2C4_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 44>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@40160000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40160000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C5>;
+ resets = <&rcc I2C5_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 45>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@40170000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40170000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C6>;
+ resets = <&rcc I2C6_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 46>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@40180000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x40180000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C7>;
+ resets = <&rcc I2C7_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 47>;
+ status = "disabled";
+ };
+
+ usart6: serial@40220000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40220000 0x400>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_USART6>;
+ access-controllers = <&rifsc 36>;
+ status = "disabled";
+ };
+
+ spi1: spi@40230000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x40230000 0x400>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI1>;
+ resets = <&rcc SPI1_R>;
+ access-controllers = <&rifsc 22>;
+ status = "disabled";
+ };
+
+ spi4: spi@40240000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x40240000 0x400>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI4>;
+ resets = <&rcc SPI4_R>;
+ access-controllers = <&rifsc 25>;
+ status = "disabled";
+ };
+
+ spi5: spi@40280000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x40280000 0x400>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI5>;
+ resets = <&rcc SPI5_R>;
+ access-controllers = <&rifsc 26>;
+ status = "disabled";
+ };
+
+ uart9: serial@402c0000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x402c0000 0x400>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_UART9>;
+ access-controllers = <&rifsc 39>;
+ status = "disabled";
+ };
+
+ usart1: serial@40330000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40330000 0x400>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_USART1>;
+ access-controllers = <&rifsc 31>;
+ status = "disabled";
+ };
+
+ spi6: spi@40350000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x40350000 0x400>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI6>;
+ resets = <&rcc SPI6_R>;
+ access-controllers = <&rifsc 27>;
+ status = "disabled";
+ };
+
+ spi7: spi@40360000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x40360000 0x400>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI7>;
+ resets = <&rcc SPI7_R>;
+ access-controllers = <&rifsc 28>;
+ status = "disabled";
+ };
+
+ uart7: serial@40370000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40370000 0x400>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_UART7>;
+ access-controllers = <&rifsc 37>;
+ status = "disabled";
+ };
+
+ uart8: serial@40380000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40380000 0x400>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_UART8>;
+ access-controllers = <&rifsc 38>;
+ status = "disabled";
+ };
+
+ spi8: spi@46020000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp25-spi";
+ reg = <0x46020000 0x400>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_SPI8>;
+ resets = <&rcc SPI8_R>;
+ access-controllers = <&rifsc 29>;
+ status = "disabled";
+ };
+
+ i2c8: i2c@46040000 {
+ compatible = "st,stm32mp25-i2c";
+ reg = <0x46040000 0x400>;
+ interrupt-names = "event";
+ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_KER_I2C8>;
+ resets = <&rcc I2C8_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ access-controllers = <&rifsc 48>;
status = "disabled";
};
@@ -143,12 +523,63 @@
arm,primecell-periphid = <0x00353180>;
reg = <0x48220000 0x400>, <0x44230400 0x8>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ck_flexgen_51>;
+ clocks = <&rcc CK_KER_SDMMC1 >;
clock-names = "apb_pclk";
+ resets = <&rcc SDMMC1_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
max-frequency = <120000000>;
+ access-controllers = <&rifsc 76>;
+ status = "disabled";
+ };
+
+ ethernet1: ethernet@482c0000 {
+ compatible = "st,stm32mp25-dwmac", "snps,dwmac-5.20";
+ reg = <0x482c0000 0x4000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ptp_ref",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc CK_ETH1_MAC>,
+ <&rcc CK_ETH1_TX>,
+ <&rcc CK_ETH1_RX>,
+ <&rcc CK_KER_ETH1PTP>,
+ <&rcc CK_ETH1_STP>,
+ <&rcc CK_KER_ETH1>;
+ snps,axi-config = <&stmmac_axi_config_1>;
+ snps,mixed-burst;
+ snps,mtl-rx-config = <&mtl_rx_setup_1>;
+ snps,mtl-tx-config = <&mtl_tx_setup_1>;
+ snps,pbl = <2>;
+ snps,tso;
+ st,syscon = <&syscfg 0x3000>;
+ access-controllers = <&rifsc 60>;
status = "disabled";
+
+ mtl_rx_setup_1: rx-queues-config {
+ snps,rx-queues-to-use = <2>;
+ queue0 {};
+ queue1 {};
+ };
+
+ mtl_tx_setup_1: tx-queues-config {
+ snps,tx-queues-to-use = <4>;
+ queue0 {};
+ queue1 {};
+ queue2 {};
+ queue3 {};
+ };
+
+ stmmac_axi_config_1: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
};
};
@@ -168,6 +599,187 @@
};
};
+ rcc: clock-controller@44200000 {
+ compatible = "st,stm32mp25-rcc";
+ reg = <0x44200000 0x10000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ clocks = <&scmi_clk CK_SCMI_HSE>,
+ <&scmi_clk CK_SCMI_HSI>,
+ <&scmi_clk CK_SCMI_MSI>,
+ <&scmi_clk CK_SCMI_LSE>,
+ <&scmi_clk CK_SCMI_LSI>,
+ <&scmi_clk CK_SCMI_HSE_DIV2>,
+ <&scmi_clk CK_SCMI_ICN_HS_MCU>,
+ <&scmi_clk CK_SCMI_ICN_LS_MCU>,
+ <&scmi_clk CK_SCMI_ICN_SDMMC>,
+ <&scmi_clk CK_SCMI_ICN_DDR>,
+ <&scmi_clk CK_SCMI_ICN_DISPLAY>,
+ <&scmi_clk CK_SCMI_ICN_HSL>,
+ <&scmi_clk CK_SCMI_ICN_NIC>,
+ <&scmi_clk CK_SCMI_ICN_VID>,
+ <&scmi_clk CK_SCMI_FLEXGEN_07>,
+ <&scmi_clk CK_SCMI_FLEXGEN_08>,
+ <&scmi_clk CK_SCMI_FLEXGEN_09>,
+ <&scmi_clk CK_SCMI_FLEXGEN_10>,
+ <&scmi_clk CK_SCMI_FLEXGEN_11>,
+ <&scmi_clk CK_SCMI_FLEXGEN_12>,
+ <&scmi_clk CK_SCMI_FLEXGEN_13>,
+ <&scmi_clk CK_SCMI_FLEXGEN_14>,
+ <&scmi_clk CK_SCMI_FLEXGEN_15>,
+ <&scmi_clk CK_SCMI_FLEXGEN_16>,
+ <&scmi_clk CK_SCMI_FLEXGEN_17>,
+ <&scmi_clk CK_SCMI_FLEXGEN_18>,
+ <&scmi_clk CK_SCMI_FLEXGEN_19>,
+ <&scmi_clk CK_SCMI_FLEXGEN_20>,
+ <&scmi_clk CK_SCMI_FLEXGEN_21>,
+ <&scmi_clk CK_SCMI_FLEXGEN_22>,
+ <&scmi_clk CK_SCMI_FLEXGEN_23>,
+ <&scmi_clk CK_SCMI_FLEXGEN_24>,
+ <&scmi_clk CK_SCMI_FLEXGEN_25>,
+ <&scmi_clk CK_SCMI_FLEXGEN_26>,
+ <&scmi_clk CK_SCMI_FLEXGEN_27>,
+ <&scmi_clk CK_SCMI_FLEXGEN_28>,
+ <&scmi_clk CK_SCMI_FLEXGEN_29>,
+ <&scmi_clk CK_SCMI_FLEXGEN_30>,
+ <&scmi_clk CK_SCMI_FLEXGEN_31>,
+ <&scmi_clk CK_SCMI_FLEXGEN_32>,
+ <&scmi_clk CK_SCMI_FLEXGEN_33>,
+ <&scmi_clk CK_SCMI_FLEXGEN_34>,
+ <&scmi_clk CK_SCMI_FLEXGEN_35>,
+ <&scmi_clk CK_SCMI_FLEXGEN_36>,
+ <&scmi_clk CK_SCMI_FLEXGEN_37>,
+ <&scmi_clk CK_SCMI_FLEXGEN_38>,
+ <&scmi_clk CK_SCMI_FLEXGEN_39>,
+ <&scmi_clk CK_SCMI_FLEXGEN_40>,
+ <&scmi_clk CK_SCMI_FLEXGEN_41>,
+ <&scmi_clk CK_SCMI_FLEXGEN_42>,
+ <&scmi_clk CK_SCMI_FLEXGEN_43>,
+ <&scmi_clk CK_SCMI_FLEXGEN_44>,
+ <&scmi_clk CK_SCMI_FLEXGEN_45>,
+ <&scmi_clk CK_SCMI_FLEXGEN_46>,
+ <&scmi_clk CK_SCMI_FLEXGEN_47>,
+ <&scmi_clk CK_SCMI_FLEXGEN_48>,
+ <&scmi_clk CK_SCMI_FLEXGEN_49>,
+ <&scmi_clk CK_SCMI_FLEXGEN_50>,
+ <&scmi_clk CK_SCMI_FLEXGEN_51>,
+ <&scmi_clk CK_SCMI_FLEXGEN_52>,
+ <&scmi_clk CK_SCMI_FLEXGEN_53>,
+ <&scmi_clk CK_SCMI_FLEXGEN_54>,
+ <&scmi_clk CK_SCMI_FLEXGEN_55>,
+ <&scmi_clk CK_SCMI_FLEXGEN_56>,
+ <&scmi_clk CK_SCMI_FLEXGEN_57>,
+ <&scmi_clk CK_SCMI_FLEXGEN_58>,
+ <&scmi_clk CK_SCMI_FLEXGEN_59>,
+ <&scmi_clk CK_SCMI_FLEXGEN_60>,
+ <&scmi_clk CK_SCMI_FLEXGEN_61>,
+ <&scmi_clk CK_SCMI_FLEXGEN_62>,
+ <&scmi_clk CK_SCMI_FLEXGEN_63>,
+ <&scmi_clk CK_SCMI_ICN_APB1>,
+ <&scmi_clk CK_SCMI_ICN_APB2>,
+ <&scmi_clk CK_SCMI_ICN_APB3>,
+ <&scmi_clk CK_SCMI_ICN_APB4>,
+ <&scmi_clk CK_SCMI_ICN_APBDBG>,
+ <&scmi_clk CK_SCMI_TIMG1>,
+ <&scmi_clk CK_SCMI_TIMG2>,
+ <&scmi_clk CK_SCMI_PLL3>,
+ <&clk_dsi_txbyte>;
+ access-controllers = <&rifsc 156>;
+ };
+
+ exti1: interrupt-controller@44220000 {
+ compatible = "st,stm32mp1-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x44220000 0x400>;
+ interrupts-extended =
+ <&intc GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_0 */
+ <&intc GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_10 */
+ <&intc GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+ <0>, /* EXTI_20 */
+ <&intc GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_30 */
+ <&intc GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_40 */
+ <&intc GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_50 */
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+ <0>, /* EXTI_60 */
+ <&intc GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_70 */
+ <0>,
+ <&intc GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
+ <0>, /* EXTI_80 */
+ <0>,
+ <0>,
+ <&intc GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
syscfg: syscon@44230000 {
compatible = "st,stm32mp25-syscfg", "syscon";
reg = <0x44230000 0x10000>;
@@ -178,6 +790,8 @@
#size-cells = <1>;
compatible = "st,stm32mp257-pinctrl";
ranges = <0 0x44240000 0xa0400>;
+ interrupt-parent = <&exti1>;
+ st,syscfg = <&exti1 0x60 0xff>;
pins-are-numbered;
gpioa: gpio@44240000 {
@@ -186,7 +800,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x0 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOA>;
st,bank-name = "GPIOA";
status = "disabled";
};
@@ -197,7 +811,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x10000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOB>;
st,bank-name = "GPIOB";
status = "disabled";
};
@@ -208,7 +822,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x20000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOC>;
st,bank-name = "GPIOC";
status = "disabled";
};
@@ -219,7 +833,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x30000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOD>;
st,bank-name = "GPIOD";
status = "disabled";
};
@@ -230,7 +844,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x40000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOE>;
st,bank-name = "GPIOE";
status = "disabled";
};
@@ -241,7 +855,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x50000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOF>;
st,bank-name = "GPIOF";
status = "disabled";
};
@@ -252,7 +866,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x60000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOG>;
st,bank-name = "GPIOG";
status = "disabled";
};
@@ -263,7 +877,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x70000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOH>;
st,bank-name = "GPIOH";
status = "disabled";
};
@@ -274,7 +888,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x80000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOI>;
st,bank-name = "GPIOI";
status = "disabled";
};
@@ -285,7 +899,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x90000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOJ>;
st,bank-name = "GPIOJ";
status = "disabled";
};
@@ -296,7 +910,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0xa0000 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOK>;
st,bank-name = "GPIOK";
status = "disabled";
};
@@ -307,6 +921,8 @@
#size-cells = <1>;
compatible = "st,stm32mp257-z-pinctrl";
ranges = <0 0x46200000 0x400>;
+ interrupt-parent = <&exti1>;
+ st,syscfg = <&exti1 0x60 0xff>;
pins-are-numbered;
gpioz: gpio@46200000 {
@@ -315,12 +931,91 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0 0x400>;
- clocks = <&ck_icn_ls_mcu>;
+ clocks = <&scmi_clk CK_SCMI_GPIOZ>;
st,bank-name = "GPIOZ";
st,bank-ioport = <11>;
status = "disabled";
};
};
+
+ exti2: interrupt-controller@46230000 {
+ compatible = "st,stm32mp1-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x46230000 0x400>;
+ interrupts-extended =
+ <&intc GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_0 */
+ <&intc GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_10 */
+ <&intc GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>, /* EXTI_20 */
+ <&intc GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_30 */
+ <&intc GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_40 */
+ <0>,
+ <0>,
+ <&intc GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, /* EXTI_50 */
+ <&intc GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>, /* EXTI_60 */
+ <&intc GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <&intc GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <0>,
+ <0>,
+ <&intc GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>; /* EXTI_70 */
+ };
};
};
diff --git a/arch/arm64/boot/dts/st/stm32mp253.dtsi b/arch/arm64/boot/dts/st/stm32mp253.dtsi
index af48e82efe8a..eeceb086252b 100644
--- a/arch/arm64/boot/dts/st/stm32mp253.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp253.dtsi
@@ -12,6 +12,8 @@
device_type = "cpu";
reg = <1>;
enable-method = "psci";
+ power-domains = <&CPU_PD1>;
+ power-domain-names = "psci";
};
};
@@ -20,4 +22,73 @@
<GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&cpu0>, <&cpu1>;
};
+
+ psci {
+ CPU_PD1: power-domain-cpu1 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ };
+ };
+
+ timer {
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
+
+&optee {
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+};
+
+&rifsc {
+ ethernet2: ethernet@482d0000 {
+ compatible = "st,stm32mp25-dwmac", "snps,dwmac-5.20";
+ reg = <0x482d0000 0x4000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ptp_ref",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc CK_ETH2_MAC>,
+ <&rcc CK_ETH2_TX>,
+ <&rcc CK_ETH2_RX>,
+ <&rcc CK_KER_ETH2PTP>,
+ <&rcc CK_ETH2_STP>,
+ <&rcc CK_KER_ETH2>;
+ snps,axi-config = <&stmmac_axi_config_2>;
+ snps,mixed-burst;
+ snps,mtl-rx-config = <&mtl_rx_setup_2>;
+ snps,mtl-tx-config = <&mtl_tx_setup_2>;
+ snps,pbl = <2>;
+ snps,tso;
+ st,syscon = <&syscfg 0x3400>;
+ access-controllers = <&rifsc 61>;
+ status = "disabled";
+
+ mtl_rx_setup_2: rx-queues-config {
+ snps,rx-queues-to-use = <2>;
+ queue0 {};
+ queue1 {};
+ };
+
+ mtl_tx_setup_2: tx-queues-config {
+ snps,tx-queues-to-use = <4>;
+ queue0 {};
+ queue1 {};
+ queue2 {};
+ queue3 {};
+ };
+
+ stmmac_axi_config_2: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/st/stm32mp255.dtsi b/arch/arm64/boot/dts/st/stm32mp255.dtsi
index 17f197c5b22b..f689b47c5010 100644
--- a/arch/arm64/boot/dts/st/stm32mp255.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp255.dtsi
@@ -5,22 +5,21 @@
*/
#include "stm32mp253.dtsi"
-/ {
- soc@0 {
- rifsc: rifsc-bus@42080000 {
- vdec: vdec@480d0000 {
- compatible = "st,stm32mp25-vdec";
- reg = <0x480d0000 0x3c8>;
- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ck_icn_p_vdec>;
- };
+&rifsc {
+ vdec: vdec@480d0000 {
+ compatible = "st,stm32mp25-vdec";
+ reg = <0x480d0000 0x3c8>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_BUS_VDEC>;
+ access-controllers = <&rifsc 89>;
- venc: venc@480e0000 {
- compatible = "st,stm32mp25-venc";
- reg = <0x480e0000 0x800>;
- interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ck_icn_ls_mcu>;
- };
- };
};
-};
+
+ venc: venc@480e0000 {
+ compatible = "st,stm32mp25-venc";
+ reg = <0x480e0000 0x800>;
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc CK_BUS_VENC>;
+ access-controllers = <&rifsc 90>;
+ };
+}; \ No newline at end of file
diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index b2d3afb15758..214191a8322b 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/st,stm32mp25-regulator.h>
#include "stm32mp257.dtsi"
#include "stm32mp25xf.dtsi"
#include "stm32mp25-pinctrl.dtsi"
@@ -17,7 +18,9 @@
compatible = "st,stm32mp257f-ev1", "st,stm32mp257";
aliases {
+ ethernet0 = &ethernet2;
serial0 = &usart2;
+ serial1 = &usart6;
};
chosen {
@@ -40,14 +43,6 @@
no-map;
};
};
-
- vdd_sdcard: vdd-sdcard {
- compatible = "regulator-fixed";
- regulator-name = "vdd_sdcard";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
};
&arm_wdt {
@@ -55,6 +50,80 @@
status = "okay";
};
+&ethernet2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&eth2_rgmii_pins_a>;
+ pinctrl-1 = <&eth2_rgmii_sleep_pins_a>;
+ max-speed = <1000>;
+ phy-handle = <&phy0_eth2>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ phy0_eth2: ethernet-phy@1 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <1>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <300>;
+ reset-gpios = <&gpiog 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c2_pins_a>;
+ pinctrl-1 = <&i2c2_sleep_pins_a>;
+ i2c-scl-rising-time-ns = <100>;
+ i2c-scl-falling-time-ns = <13>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&i2c8 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c8_pins_a>;
+ pinctrl-1 = <&i2c8_sleep_pins_a>;
+ i2c-scl-rising-time-ns = <57>;
+ i2c-scl-falling-time-ns = <7>;
+ clock-frequency = <400000>;
+ status = "disabled";
+};
+
+&scmi_regu {
+ scmi_vddio1: regulator@0 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ scmi_vddcore: regulator@11 {
+ reg = <VOLTD_SCMI_STPMIC2_BUCK2>;
+ regulator-name = "vddcore";
+ };
+ scmi_v1v8: regulator@14 {
+ reg = <VOLTD_SCMI_STPMIC2_BUCK5>;
+ regulator-name = "v1v8";
+ };
+ scmi_v3v3: regulator@16 {
+ reg = <VOLTD_SCMI_STPMIC2_BUCK7>;
+ regulator-name = "v3v3";
+ };
+ scmi_vdd_emmc: regulator@18 {
+ reg = <VOLTD_SCMI_STPMIC2_LDO2>;
+ regulator-name = "vdd_emmc";
+ };
+ scmi_vdd3v3_usb: regulator@20 {
+ reg = <VOLTD_SCMI_STPMIC2_LDO4>;
+ regulator-name = "vdd3v3_usb";
+ };
+ scmi_vdd_sdcard: regulator@23 {
+ reg = <VOLTD_SCMI_STPMIC2_LDO7>;
+ regulator-name = "vdd_sdcard";
+ };
+};
+
&sdmmc1 {
pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdmmc1_b4_pins_a>;
@@ -64,10 +133,25 @@
disable-wp;
st,neg-edge;
bus-width = <4>;
- vmmc-supply = <&vdd_sdcard>;
+ vmmc-supply = <&scmi_vdd_sdcard>;
+ vqmmc-supply = <&scmi_vddio1>;
status = "okay";
};
+&spi3 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&spi3_pins_a>;
+ pinctrl-1 = <&spi3_sleep_pins_a>;
+ status = "disabled";
+};
+
+&spi8 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&spi8_pins_a>;
+ pinctrl-1 = <&spi8_sleep_pins_a>;
+ status = "disabled";
+};
+
&usart2 {
pinctrl-names = "default", "idle", "sleep";
pinctrl-0 = <&usart2_pins_a>;
@@ -75,3 +159,12 @@
pinctrl-2 = <&usart2_sleep_pins_a>;
status = "okay";
};
+
+&usart6 {
+ pinctrl-names = "default", "idle", "sleep";
+ pinctrl-0 = <&usart6_pins_a>;
+ pinctrl-1 = <&usart6_idle_pins_a>;
+ pinctrl-2 = <&usart6_sleep_pins_a>;
+ uart-has-rtscts;
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/synaptics/berlin4ct.dtsi b/arch/arm64/boot/dts/synaptics/berlin4ct.dtsi
index 53d616c3cfed..71e4bfcc9e81 100644
--- a/arch/arm64/boot/dts/synaptics/berlin4ct.dtsi
+++ b/arch/arm64/boot/dts/synaptics/berlin4ct.dtsi
@@ -88,7 +88,7 @@
};
pmu {
- compatible = "arm,cortex-a53-pmu", "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 047a83cee603..690b4ed9c29b 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -304,7 +304,7 @@
};
arm-pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a72-pmu";
interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 9a722c2473fb..e20b27ddf901 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -22,11 +22,14 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am625-phyboard-lyra-1-4-ghz-opp.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am62x-phyboard-lyra-gpio-fan.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk-nand.dtbo
# Boards with AM62Ax SoC
dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-phyboard-lyra-rdk.dtb
# Boards with AM62Px SoC
dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
@@ -44,15 +47,26 @@ k3-am642-hummingboard-t-usb3-dtbs := \
k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-usb3.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac-mii.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
+k3-am642-evm-nand-dtbs := k3-am642-evm.dtb k3-am642-evm-nand.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-nand.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-gpio-fan.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-pcie-usb2.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+# Common overlays for the phyCORE-AM6* family of boards
+dtb-$(CONFIG_ARCH_K3) += k3-am6xx-phycore-disable-eth-phy.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am6xx-phycore-disable-rtc.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am6xx-phycore-disable-spi-nor.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am6xx-phycore-qspi-nor.dtbo
+
# Boards with AM65x SoC
k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb \
k3-am654-base-board-rocktech-rk101-panel.dtbo \
@@ -80,6 +94,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j7200-evm.dtb
# Boards with J721e SoC
k3-j721e-evm-dtbs := k3-j721e-common-proc-board.dtb k3-j721e-evm-quad-port-eth-exp.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board-infotainment.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
@@ -100,14 +115,27 @@ dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
# Boards with J784s4 SoC
dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-pcie0-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-quad-port-eth-exp1.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-usxgmii-exp1-exp2.dtbo
# Build time test only, enabled by CONFIG_OF_ALL_DTBS
k3-am625-beagleplay-csi2-ov5640-dtbs := k3-am625-beagleplay.dtb \
k3-am625-beagleplay-csi2-ov5640.dtbo
k3-am625-beagleplay-csi2-tevi-ov5640-dtbs := k3-am625-beagleplay.dtb \
k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
+k3-am625-phyboard-lyra-1-4-ghz-opp.dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+ k3-am625-phyboard-lyra-1-4-ghz-opp.dtbo
+k3-am625-phyboard-lyra-disable-eth-phy-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+ k3-am6xx-phycore-disable-eth-phy.dtbo
+k3-am625-phyboard-lyra-disable-rtc-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+ k3-am6xx-phycore-disable-rtc.dtbo
+k3-am625-phyboard-lyra-disable-spi-nor-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+ k3-am6xx-phycore-disable-spi-nor.dtbo
k3-am625-phyboard-lyra-gpio-fan-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
k3-am62x-phyboard-lyra-gpio-fan.dtbo
+k3-am625-phyboard-lyra-qspi-nor-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+ k3-am6xx-phycore-qspi-nor.dtbo
k3-am625-sk-csi2-imx219-dtbs := k3-am625-sk.dtb \
k3-am62x-sk-csi2-imx219.dtbo
k3-am625-sk-csi2-ov5640-dtbs := k3-am625-sk.dtb \
@@ -131,6 +159,20 @@ k3-am62p5-sk-csi2-tevi-ov5640-dtbs := k3-am62p5-sk.dtb \
k3-am62x-sk-csi2-tevi-ov5640.dtbo
k3-am642-evm-icssg1-dualemac-dtbs := \
k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
+k3-am642-evm-icssg1-dualemac-mii-dtbs := \
+ k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac-mii.dtbo
+k3-am642-phyboard-electra-disable-eth-phy-dtbs := \
+ k3-am642-phyboard-electra-rdk.dtb k3-am6xx-phycore-disable-eth-phy.dtbo
+k3-am642-phyboard-electra-disable-rtc-dtbs := \
+ k3-am642-phyboard-electra-rdk.dtb k3-am6xx-phycore-disable-rtc.dtbo
+k3-am642-phyboard-electra-disable-spi-nor-dtbs := \
+ k3-am642-phyboard-electra-rdk.dtb k3-am6xx-phycore-disable-spi-nor.dtbo
+k3-am642-phyboard-electra-qspi-nor-dtbs := \
+ k3-am642-phyboard-electra-rdk.dtb k3-am6xx-phycore-qspi-nor.dtbo
+k3-am642-phyboard-electra-gpio-fan-dtbs := \
+ k3-am642-phyboard-electra-rdk.dtb k3-am642-phyboard-electra-gpio-fan.dtbo
+k3-am642-phyboard-electra-pcie-usb2-dtbs := \
+ k3-am642-phyboard-electra-rdk.dtb k3-am642-phyboard-electra-pcie-usb2.dtbo
k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
@@ -139,12 +181,20 @@ k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-j721e-common-proc-board-infotainment-dtbs := k3-j721e-common-proc-board.dtb \
+ k3-j721e-common-proc-board-infotainment.dtbo
k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
k3-j721e-evm-pcie0-ep.dtbo
k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
k3-j721s2-evm-pcie1-ep.dtbo
+k3-j784s4-evm-pcie0-pcie1-ep-dtbs := k3-j784s4-evm.dtb \
+ k3-j784s4-evm-pcie0-pcie1-ep.dtbo
+k3-j784s4-evm-quad-port-eth-exp1-dtbs := k3-j784s4-evm.dtb \
+ k3-j784s4-evm-quad-port-eth-exp1.dtbo
+k3-j784s4-evm-usxgmii-exp1-exp2-dtbs := k3-j784s4-evm.dtb \
+ k3-j784s4-evm-usxgmii-exp1-exp2.dtbo
dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-am625-beagleplay-csi2-tevi-ov5640.dtb \
k3-am625-sk-csi2-imx219.dtb \
@@ -159,21 +209,29 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-am62p5-sk-csi2-ov5640.dtb \
k3-am62p5-sk-csi2-tevi-ov5640.dtb \
k3-am642-evm-icssg1-dualemac.dtb \
+ k3-am642-evm-icssg1-dualemac-mii.dtb \
k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
- k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
- k3-am69-sk-csi2-dual-imx219-dtbs \
+ k3-am68-sk-base-board-csi2-dual-imx219.dtb \
+ k3-am69-sk-csi2-dual-imx219.dtb \
+ k3-j721e-common-proc-board-infotainment.dtb \
k3-j721e-evm-pcie0-ep.dtb \
- k3-j721e-sk-csi2-dual-imx219-dtbs \
- k3-j721s2-evm-pcie1-ep.dtb
+ k3-j721e-sk-csi2-dual-imx219.dtb \
+ k3-j721s2-evm-pcie1-ep.dtb \
+ k3-j784s4-evm-pcie0-pcie1-ep.dtb \
+ k3-j784s4-evm-quad-port-eth-exp1.dtb \
+ k3-j784s4-evm-usxgmii-exp1-exp2.dtb
# Enable support for device-tree overlays
DTC_FLAGS_k3-am625-beagleplay += -@
+DTC_FLAGS_k3-am625-phyboard-lyra-rdk += -@
+DTC_FLAGS_k3-am62a7-phyboard-lyra-rdk += -@
DTC_FLAGS_k3-am625-sk += -@
DTC_FLAGS_k3-am62-lp-sk += -@
DTC_FLAGS_k3-am62a7-sk += -@
DTC_FLAGS_k3-am62p5-sk += -@
DTC_FLAGS_k3-am642-evm += -@
+DTC_FLAGS_k3-am642-phyboard-electra-rdk += -@
DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
DTC_FLAGS_k3-am68-sk-base-board += -@
@@ -181,3 +239,4 @@ DTC_FLAGS_k3-am69-sk += -@
DTC_FLAGS_k3-j721e-common-proc-board += -@
DTC_FLAGS_k3-j721e-sk += -@
DTC_FLAGS_k3-j721s2-common-proc-board += -@
+DTC_FLAGS_k3-j784s4-evm += -@
diff --git a/arch/arm64/boot/dts/ti/k3-am62-lp-sk-nand.dtso b/arch/arm64/boot/dts/ti/k3-am62-lp-sk-nand.dtso
new file mode 100644
index 000000000000..173ac60723b6
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk-nand.dtso
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&mcasp1 {
+ status = "disabled";
+};
+
+&main_pmx0 {
+ gpmc0_pins_default: gpmc0-pins-default {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x003c, PIN_INPUT, 0) /* (K19) GPMC0_AD0 */
+ AM62X_IOPAD(0x0040, PIN_INPUT, 0) /* (L19) GPMC0_AD1 */
+ AM62X_IOPAD(0x0044, PIN_INPUT, 0) /* (L20) GPMC0_AD2 */
+ AM62X_IOPAD(0x0048, PIN_INPUT, 0) /* (L21) GPMC0_AD3 */
+ AM62X_IOPAD(0x004c, PIN_INPUT, 0) /* (M21) GPMC0_AD4 */
+ AM62X_IOPAD(0x0050, PIN_INPUT, 0) /* (L17) GPMC0_AD5 */
+ AM62X_IOPAD(0x0054, PIN_INPUT, 0) /* (L18) GPMC0_AD6 */
+ AM62X_IOPAD(0x0058, PIN_INPUT, 0) /* (M20) GPMC0_AD7 */
+ AM62X_IOPAD(0x0098, PIN_INPUT, 0) /* (P21) GPMC0_WAIT0 */
+ AM62X_IOPAD(0x00a8, PIN_OUTPUT, 0) /* (J18) GPMC0_CSn0 */
+ AM62X_IOPAD(0x0084, PIN_OUTPUT, 0) /* (K20) GPMC0_ADVn_ALE */
+ AM62X_IOPAD(0x0088, PIN_OUTPUT, 0) /* (K21) GPMC0_OEn_REn */
+ AM62X_IOPAD(0x008c, PIN_OUTPUT, 0) /* (J17) GPMC0_WEn */
+ AM62X_IOPAD(0x0090, PIN_OUTPUT, 0) /* (K17) GPMC0_BE0n_CLE */
+ AM62X_IOPAD(0x00a0, PIN_OUTPUT, 0) /* (J20) GPMC0_WPn */
+ >;
+ };
+};
+
+&elm0 {
+ status = "okay";
+};
+
+&gpmc0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmc0_pins_default>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ nand@0,0 {
+ compatible = "ti,am64-nand";
+ reg = <0 0 64>; /* device IO registers */
+ interrupt-parent = <&gpmc0>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+ rb-gpios = <&gpmc0 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+ ti,nand-xfer-type = "prefetch-polled";
+ ti,nand-ecc-opt = "bch8"; /* BCH8: Bootrom limitation */
+ ti,elm-id = <&elm0>;
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <40>;
+ gpmc,cs-wr-off-ns = <40>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <25>;
+ gpmc,adv-wr-off-ns = <25>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <20>;
+ gpmc,oe-on-ns = <3>;
+ gpmc,oe-off-ns = <30>;
+ gpmc,access-ns = <30>;
+ gpmc,rd-cycle-ns = <40>;
+ gpmc,wr-cycle-ns = <40>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "NAND.tiboot3";
+ reg = <0x00000000 0x00200000>; /* 2M */
+ };
+ partition@200000 {
+ label = "NAND.tispl";
+ reg = <0x00200000 0x00200000>; /* 2M */
+ };
+ partition@400000 {
+ label = "NAND.tiboot3.backup"; /* 2M */
+ reg = <0x00400000 0x00200000>; /* BootROM looks at 4M */
+ };
+ partition@600000 {
+ label = "NAND.u-boot";
+ reg = <0x00600000 0x00400000>; /* 4M */
+ };
+ partition@a00000 {
+ label = "NAND.u-boot-env";
+ reg = <0x00a00000 0x00040000>; /* 256K */
+ };
+ partition@a40000 {
+ label = "NAND.u-boot-env.backup";
+ reg = <0x00a40000 0x00040000>; /* 256K */
+ };
+ partition@a80000 {
+ label = "NAND.file-system";
+ reg = <0x00a80000 0x3f580000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
index c4149059a4c5..8e9fc00a6b3c 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
@@ -166,7 +166,6 @@
interrupt-parent = <&gic500>;
interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
- ti,power-button;
regulators {
buck1_reg: buck1 {
@@ -229,3 +228,7 @@
&tlv320aic3106 {
DVDD-supply = <&buck2_reg>;
};
+
+&gpmc0 {
+ ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index e9cffca073ef..328929c740dc 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -141,8 +141,8 @@
compatible = "ti,am64-dmss-pktdma";
reg = <0x00 0x485c0000 0x00 0x100>,
<0x00 0x4a800000 0x00 0x20000>,
- <0x00 0x4aa00000 0x00 0x40000>,
- <0x00 0x4b800000 0x00 0x400000>,
+ <0x00 0x4aa00000 0x00 0x20000>,
+ <0x00 0x4b800000 0x00 0x200000>,
<0x00 0x485e0000 0x00 0x10000>,
<0x00 0x484a0000 0x00 0x2000>,
<0x00 0x484c0000 0x00 0x2000>,
@@ -207,10 +207,6 @@
crypto: crypto@40900000 {
compatible = "ti,am62-sa3ul";
reg = <0x00 0x40900000 0x00 0x1200>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x00 0x40900000 0x00 0x40900000 0x00 0x30000>;
-
dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>,
<&main_pktdma 0x7507 0>;
dma-names = "tx", "rx1", "rx2";
@@ -619,10 +615,11 @@
usbss0: dwc3-usb@f900000 {
compatible = "ti,am62-usb";
- reg = <0x00 0x0f900000 0x00 0x800>;
+ reg = <0x00 0x0f900000 0x00 0x800>,
+ <0x00 0x0f908000 0x00 0x400>;
clocks = <&k3_clks 161 3>;
clock-names = "ref";
- ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+ ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
#address-cells = <2>;
#size-cells = <2>;
power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -644,10 +641,11 @@
usbss1: dwc3-usb@f910000 {
compatible = "ti,am62-usb";
- reg = <0x00 0x0f910000 0x00 0x800>;
+ reg = <0x00 0x0f910000 0x00 0x800>,
+ <0x00 0x0f918000 0x00 0x400>;
clocks = <&k3_clks 162 3>;
clock-names = "ref";
- ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+ ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
#address-cells = <2>;
#size-cells = <2>;
power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
@@ -737,7 +735,7 @@
label = "port1";
phys = <&phy_gmii_sel 1>;
mac-address = [00 00 00 00 00 00];
- ti,syscon-efuse = <&wkup_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
};
cpsw_port2: port@2 {
@@ -1055,4 +1053,33 @@
status = "disabled";
};
+ gpmc0: memory-controller@3b000000 {
+ compatible = "ti,am64-gpmc";
+ power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 80 0>;
+ clock-names = "fck";
+ reg = <0x00 0x03b000000 0x00 0x400>,
+ <0x00 0x050000000 0x00 0x8000000>;
+ reg-names = "cfg", "data";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ gpmc,num-cs = <3>;
+ gpmc,num-waitpins = <2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ status = "disabled";
+ };
+
+ elm0: ecc@25010000 {
+ compatible = "ti,am64-elm";
+ reg = <0x00 0x25010000 0x00 0x2000>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 54 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 54 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
index 6c4cec8728e4..e8f4d136e5df 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
@@ -22,6 +22,7 @@
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&codec_dai>;
simple-audio-card,name = "verdin-wm8904";
+ simple-audio-card,mclk-fs = <256>;
simple-audio-card,routing =
"Headphone Jack", "HPOUTL",
"Headphone Jack", "HPOUTR",
@@ -35,7 +36,6 @@
"Line", "Line In Jack";
codec_dai: simple-audio-card,codec {
- clocks = <&audio_refclk1>;
sound-dai = <&wm8904_1a>;
};
@@ -43,6 +43,15 @@
sound-dai = <&mcasp0>;
};
};
+
+ reg_usb_hub: regulator-usb-hub {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ regulator-name = "HUB_PWR_EN";
+ };
};
/* Verdin ETHs */
@@ -160,7 +169,8 @@
pinctrl-0 = <&pinctrl_gpio_1>,
<&pinctrl_gpio_2>,
<&pinctrl_gpio_3>,
- <&pinctrl_gpio_4>;
+ <&pinctrl_gpio_4>,
+ <&pinctrl_pcie_1_reset>;
};
/* Verdin I2C_3_HDMI */
@@ -183,6 +193,11 @@
status = "okay";
};
+/* Do not force CTRL_SLEEP_MOCI# always enabled */
+&reg_force_sleep_moci {
+ status = "disabled";
+};
+
/* Verdin SD_1 */
&sdhci1 {
status = "okay";
@@ -203,7 +218,15 @@
};
&usb1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
status = "okay";
+
+ usb-hub@1 {
+ compatible = "usb424,2744";
+ reg = <1>;
+ vdd-supply = <&reg_usb_hub>;
+ };
};
/* Verdin CTRL_WAKE1_MICO# */
@@ -211,6 +234,11 @@
status = "okay";
};
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+ status = "okay";
+};
+
/* Verdin UART_2 */
&wkup_uart0 {
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
index be62648e7818..5c1284b802ad 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
@@ -14,6 +14,7 @@
simple-audio-card,bitclock-master = <&codec_dai>;
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&codec_dai>;
+ simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "verdin-nau8822";
simple-audio-card,routing =
"Headphones", "LHP",
@@ -34,7 +35,6 @@
"Line", "Line In";
codec_dai: simple-audio-card,codec {
- clocks = <&audio_refclk1>;
sound-dai = <&nau8822_1a>;
};
@@ -107,6 +107,8 @@
reg = <0x1a>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2s1_mclk>;
+ clock-names = "mclk";
+ clocks = <&audio_refclk1>;
#sound-dai-cells = <0>;
};
@@ -181,7 +183,8 @@
pinctrl-0 = <&pinctrl_gpio_1>,
<&pinctrl_gpio_2>,
<&pinctrl_gpio_3>,
- <&pinctrl_gpio_4>;
+ <&pinctrl_gpio_4>,
+ <&pinctrl_pcie_1_reset>;
};
/* Verdin I2C_3_HDMI */
@@ -232,6 +235,11 @@
status = "okay";
};
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+ status = "okay";
+};
+
/* Verdin UART_2 */
&wkup_uart0 {
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
index 77b1beb638ad..754216d8ac14 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
@@ -81,10 +81,10 @@
&main_gpio0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ctrl_sleep_moci>,
- <&pinctrl_gpio_1>,
- <&pinctrl_gpio_2>,
- <&pinctrl_gpio_3>,
- <&pinctrl_gpio_4>;
+ <&pinctrl_gpio_5>,
+ <&pinctrl_gpio_6>,
+ <&pinctrl_gpio_7>,
+ <&pinctrl_gpio_8>;
};
/* Verdin I2C_1 */
@@ -149,6 +149,15 @@
status = "okay";
};
+&mcu_gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_1>,
+ <&pinctrl_gpio_2>,
+ <&pinctrl_gpio_3>,
+ <&pinctrl_gpio_4>,
+ <&pinctrl_pcie_1_reset>;
+};
+
/* Verdin I2C_3_HDMI */
&mcu_i2c0 {
status = "okay";
@@ -192,6 +201,11 @@
status = "okay";
};
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+ status = "okay";
+};
+
/* Verdin UART_2 */
&wkup_uart0 {
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-yavia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-yavia.dtsi
index 997dfafd27eb..7372d392ec8a 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-yavia.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-yavia.dtsi
@@ -159,7 +159,8 @@
pinctrl-0 = <&pinctrl_gpio_1>,
<&pinctrl_gpio_2>,
<&pinctrl_gpio_3>,
- <&pinctrl_gpio_4>;
+ <&pinctrl_gpio_4>,
+ <&pinctrl_pcie_1_reset>;
};
/* Verdin I2C_3_HDMI */
@@ -205,6 +206,11 @@
status = "okay";
};
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+ status = "okay";
+};
+
/* Verdin UART_2 */
&wkup_uart0 {
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index e8d8857ad51f..359f53f3e019 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -76,7 +76,7 @@
memory@80000000 {
device_type = "memory";
- reg = <0x00000000 0x80000000 0x00000000 0x40000000>; /* 1G RAM */
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>; /* 2G RAM */
};
opp-table {
@@ -138,6 +138,22 @@
vin-supply = <&reg_1v8>;
};
+ /*
+ * By default we enable CTRL_SLEEP_MOCI#, this is required to have
+ * peripherals on the carrier board powered.
+ * If more granularity or power saving is required this can be disabled
+ * in the carrier board device tree files.
+ */
+ reg_force_sleep_moci: regulator-force-sleep-moci {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpio = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "CTRL_SLEEP_MOCI#";
+ };
+
/* Verdin SD_1 Power Supply */
reg_sdhc1_vmmc: regulator-sdhci1 {
compatible = "regulator-fixed";
@@ -457,6 +473,13 @@
>;
};
+ /* Verdin SD_1_CD# as GPIO */
+ pinctrl_sd1_cd_gpio: main-gpio1-48-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 7) /* (D17) MMC1_SDCD.GPIO1_48 */ /* SODIMM 84 */
+ >;
+ };
+
/* Verdin DSI_1_INT# (pulled-up as active-low) */
pinctrl_dsi1_int: main-gpio1-49-default-pins {
pinctrl-single,pins = <
@@ -571,7 +594,6 @@
AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ /* SODIMM 82 */
AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */ /* SODIMM 70 */
AM62X_IOPAD(0x224, PIN_INPUT, 0) /* (D22) MMC1_DAT3 */ /* SODIMM 72 */
- AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 0) /* (D17) MMC1_SDCD */ /* SODIMM 84 */
>;
};
@@ -979,14 +1001,6 @@
"",
"",
"";
-
- verdin_ctrl_sleep_moci: ctrl-sleep-moci-hog {
- gpio-hog;
- /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
- gpios = <31 GPIO_ACTIVE_HIGH>;
- line-name = "CTRL_SLEEP_MOCI#";
- output-high;
- };
};
&main_gpio1 {
@@ -1350,8 +1364,6 @@
0 0 0 0
>;
tdm-slots = <2>;
- rx-num-evt = <32>;
- tx-num-evt = <32>;
#sound-dai-cells = <0>;
status = "disabled";
};
@@ -1368,8 +1380,6 @@
0 0 0 0
>;
tdm-slots = <2>;
- rx-num-evt = <32>;
- tx-num-evt = <32>;
#sound-dai-cells = <0>;
status = "disabled";
};
@@ -1407,6 +1417,15 @@
"",
"",
"";
+
+ verdin_pcie_1_reset_hog: pcie-1-reset-hog {
+ gpio-hog;
+ /* Verdin PCIE_1_RESET# (SODIMM 244) */
+ gpios = <0 GPIO_ACTIVE_LOW>;
+ line-name = "PCIE_1_RESET#";
+ output-low;
+ status = "disabled";
+ };
};
/* Verdin CAN_2 */
@@ -1441,10 +1460,12 @@
/* Verdin SD_1 */
&sdhci1 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sdhci1>;
+ pinctrl-0 = <&pinctrl_sdhci1>, <&pinctrl_sd1_cd_gpio>;
+ cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
disable-wp;
vmmc-supply = <&reg_sdhc1_vmmc>;
vqmmc-supply = <&reg_sdhc1_vqmmc>;
+ ti,fails-without-test-cd;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index 23ce1bfda8d6..e0afafd532a5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -21,6 +21,21 @@
compatible = "ti,am654-chipid";
reg = <0x14 0x4>;
};
+
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
+
+ usb0_phy_ctrl: syscon@4008 {
+ compatible = "ti,am62-usb-phy-ctrl", "syscon";
+ reg = <0x4008 0x4>;
+ };
+
+ usb1_phy_ctrl: syscon@4018 {
+ compatible = "ti,am62-usb-phy-ctrl", "syscon";
+ reg = <0x4018 0x4>;
+ };
};
target-module@2b300050 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi
index f0781f2bea29..bfb55ca11323 100644
--- a/arch/arm64/boot/dts/ti/k3-am62.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi
@@ -68,11 +68,13 @@
<0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
<0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
<0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core window */
+ <0x00 0x3b000000 0x00 0x3b000000 0x00 0x00000400>, /* GPMC0_CFG */
<0x00 0x40900000 0x00 0x40900000 0x00 0x00030000>, /* SA3UL */
<0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */
<0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */
<0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */
<0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>, /* DMSS */
+ <0x00 0x50000000 0x00 0x50000000 0x00 0x08000000>, /* GPMC0 DATA */
<0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
<0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */
<0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index a34e0df2ab86..70de288d728e 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -82,6 +82,17 @@
};
};
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_en_pins_default>;
+ /* Internal power on time(Figure 8-3) * 2 */
+ post-power-on-delay-ms = <10>;
+ /* Re-enable time(Figure 8-2) + 20uS */
+ power-off-delay-us = <80>;
+ reset-gpios = <&main_gpio0 38 GPIO_ACTIVE_LOW>;
+ };
+
vsys_5v0: regulator-1 {
bootph-all;
compatible = "regulator-fixed";
@@ -104,20 +115,6 @@
regulator-boot-on;
};
- wlan_en: regulator-3 {
- /* OUTPUT of SN74AVC2T244DQMR */
- compatible = "regulator-fixed";
- regulator-name = "wlan_en";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- enable-active-high;
- regulator-always-on;
- vin-supply = <&vdd_3v3>;
- gpio = <&main_gpio0 38 GPIO_ACTIVE_HIGH>;
- pinctrl-names = "default";
- pinctrl-0 = <&wifi_en_pins_default>;
- };
-
vdd_3v3_sd: regulator-4 {
/* output of TPS22918DBVR-U21 */
bootph-all;
@@ -292,6 +289,8 @@
pinctrl-single,pins = <
AM62X_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AD24) MDIO0_MDC */
AM62X_IOPAD(0x015c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */
+ AM62X_IOPAD(0x003c, PIN_INPUT, 7) /* (M25) GPMC0_AD0.GPIO0_15 */
+ AM62X_IOPAD(0x018c, PIN_INPUT, 7) /* (AC21) RGMII2_RD2.GPIO1_5 */
>;
};
@@ -383,7 +382,6 @@
AM62X_IOPAD(0x016c, PIN_INPUT, 1) /* (Y18) RGMII2_TD0.RMII2_TXD0 */
AM62X_IOPAD(0x0170, PIN_INPUT, 1) /* (AA18) RGMII2_TD1.RMII2_TXD1 */
AM62X_IOPAD(0x0164, PIN_INPUT, 1) /* (AA19) RGMII2_TX_CTL.RMII2_TX_EN */
- AM62X_IOPAD(0x018c, PIN_OUTPUT, 7) /* (AC21) RGMII2_RD2.GPIO1_5 */
AM62X_IOPAD(0x0190, PIN_INPUT, 7) /* (AE22) RGMII2_RD3.GPIO1_6 */
AM62X_IOPAD(0x01f0, PIN_OUTPUT, 5) /* (A18) EXT_REFCLK1.CLKOUT0 */
>;
@@ -597,6 +595,9 @@
cpsw3g_phy0: ethernet-phy@0 {
reg = <0>;
+ reset-gpios = <&main_gpio0 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <50000>;
};
cpsw3g_phy1: ethernet-phy@1 {
@@ -615,7 +616,7 @@
"USR0", "USR1", "USR2", "USR3", "", "", "USR4", /* 3-9 */
"EEPROM_WP", /* 10 */
"CSI2_CAMERA_GPIO1", "CSI2_CAMERA_GPIO2", /* 11-12 */
- "CC1352P7_BOOT", "CC1352P7_RSTN", "", "", "", /* 13-17 */
+ "CC1352P7_BOOT", "CC1352P7_RSTN", "GBE_RSTN", "", "", /* 13-17 */
"USR_BUTTON", "", "", "", "", "", "", "", "", /* 18-26 */
"", "", "", "", "", "", "", "", "", "HDMI_INT", /* 27-36 */
"", "VDD_WLAN_EN", "", "", "WL_IRQ", "GBE_INTN",/* 37-42 */
@@ -839,13 +840,13 @@
};
&sdhci2 {
- vmmc-supply = <&wlan_en>;
pinctrl-names = "default";
pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
non-removable;
ti,fails-without-test-cd;
cap-power-off-card;
keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
assigned-clocks = <&k3_clks 157 158>;
assigned-clock-parents = <&k3_clks 157 160>;
#address-cells = <1>;
@@ -923,6 +924,4 @@
0 0 0 0
0 0 0 0
>;
- tx-num-evt = <32>;
- rx-num-evt = <32>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso
new file mode 100644
index 000000000000..6ec6d57ec49c
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&vdd_core {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+};
+
+&a53_opp_table {
+ opp-1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ opp-supported-hw = <0x01 0x0004>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
index a83a90497857..4fa5efdffcd7 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
@@ -7,354 +7,12 @@
* https://www.phytec.com/product/phyboard-am62x
*/
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/net/ti-dp83867.h>
#include "k3-am625.dtsi"
#include "k3-am62-phycore-som.dtsi"
+#include "k3-am62x-phyboard-lyra.dtsi"
/ {
compatible = "phytec,am625-phyboard-lyra-rdk",
"phytec,am62-phycore-som", "ti,am625";
model = "PHYTEC phyBOARD-Lyra AM625";
-
- aliases {
- serial2 = &main_uart0;
- serial3 = &main_uart1;
- mmc1 = &sdhci1;
- usb0 = &usb0;
- usb1 = &usb1;
- ethernet1 = &cpsw_port2;
- };
-
- can_tc1: can-phy0 {
- compatible = "ti,tcan1042";
- #phy-cells = <0>;
- max-bitrate = <5000000>;
- standby-gpios = <&gpio_exp 1 GPIO_ACTIVE_HIGH>;
- };
-
- hdmi0: connector-hdmi {
- compatible = "hdmi-connector";
- label = "hdmi";
- type = "a";
-
- port {
- hdmi_connector_in: endpoint {
- remote-endpoint = <&sii9022_out>;
- };
- };
- };
-
- keys {
- compatible = "gpio-keys";
- autorepeat;
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_keys_pins_default>;
-
- key-home {
- label = "home";
- linux,code = <KEY_HOME>;
- gpios = <&main_gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- key-menu {
- label = "menu";
- linux,code = <KEY_MENU>;
- gpios = <&gpio_exp 4 GPIO_ACTIVE_HIGH>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&leds_pins_default>, <&user_leds_pins_default>;
-
- led-1 {
- gpios = <&main_gpio0 32 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "mmc0";
- };
-
- led-2 {
- gpios = <&gpio_exp 2 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "mmc1";
- };
- };
-
- vcc_3v3_mmc: regulator-vcc-3v3-mmc {
- compatible = "regulator-fixed";
- regulator-name = "VCC_3V3_MMC";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- regulator-boot-on;
- };
-};
-
-&main_pmx0 {
- gpio_keys_pins_default: gpio-keys-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x1d4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
- >;
- };
-
- gpio_exp_int_pins_default: gpio-exp-int-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x244, PIN_INPUT, 7) /* (C17) MMC1_SDWP.GPIO1_49 */
- >;
- };
-
- hdmi_int_pins_default: hdmi-int-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x040, PIN_INPUT, 7) /* (N23) GPMC0_AD1.GPIO0_16 */
- >;
- };
-
- main_dss0_pins_default: main-dss0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0b8, PIN_OUTPUT, 0) /* (U22) VOUT0_DATA0 */
- AM62X_IOPAD(0x0bc, PIN_OUTPUT, 0) /* (V24) VOUT0_DATA1 */
- AM62X_IOPAD(0x0e0, PIN_OUTPUT, 0) /* (V20) VOUT0_DATA10 */
- AM62X_IOPAD(0x0e4, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA11 */
- AM62X_IOPAD(0x0e8, PIN_OUTPUT, 0) /* (AB25) VOUT0_DATA12 */
- AM62X_IOPAD(0x0ec, PIN_OUTPUT, 0) /* (AA24) VOUT0_DATA13 */
- AM62X_IOPAD(0x0f0, PIN_OUTPUT, 0) /* (Y22) VOUT0_DATA14 */
- AM62X_IOPAD(0x0f4, PIN_OUTPUT, 0) /* (AA21) VOUT0_DATA15 */
- AM62X_IOPAD(0x0c0, PIN_OUTPUT, 0) /* (W25) VOUT0_DATA2 */
- AM62X_IOPAD(0x0c4, PIN_OUTPUT, 0) /* (W24) VOUT0_DATA3 */
- AM62X_IOPAD(0x0c8, PIN_OUTPUT, 0) /* (Y25) VOUT0_DATA4 */
- AM62X_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (Y24) VOUT0_DATA5 */
- AM62X_IOPAD(0x0d0, PIN_OUTPUT, 0) /* (Y23) VOUT0_DATA6 */
- AM62X_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (AA25) VOUT0_DATA7 */
- AM62X_IOPAD(0x0d8, PIN_OUTPUT, 0) /* (V21) VOUT0_DATA8 */
- AM62X_IOPAD(0x0dc, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA9 */
- AM62X_IOPAD(0x0fc, PIN_OUTPUT, 0) /* (Y20) VOUT0_DE */
- AM62X_IOPAD(0x0f8, PIN_OUTPUT, 0) /* (AB24) VOUT0_HSYNC */
- AM62X_IOPAD(0x104, PIN_OUTPUT, 0) /* (AC24) VOUT0_PCLK */
- AM62X_IOPAD(0x100, PIN_OUTPUT, 0) /* (AC25) VOUT0_VSYNC */
- >;
- };
-
- main_i2c1_pins_default: main-i2c1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x1e8, PIN_INPUT_PULLUP, 0) /* (B17) I2C1_SCL */
- AM62X_IOPAD(0x1ec, PIN_INPUT_PULLUP, 0) /* (A17) I2C1_SDA */
- >;
- };
-
- main_mcan0_pins_default: main-mcan0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x1dc, PIN_INPUT, 0) /* (E15) MCAN0_RX */
- AM62X_IOPAD(0x1d8, PIN_OUTPUT, 0) /* (C15) MCAN0_TX */
- >;
- };
-
- main_mmc1_pins_default: main-mmc1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x23c, PIN_INPUT_PULLUP, 0) /* (A21) MMC1_CMD */
- AM62X_IOPAD(0x234, PIN_INPUT_PULLDOWN, 0) /* (B22) MMC1_CLK */
- AM62X_IOPAD(0x230, PIN_INPUT_PULLUP, 0) /* (A22) MMC1_DAT0 */
- AM62X_IOPAD(0x22c, PIN_INPUT_PULLUP, 0) /* (B21) MMC1_DAT1 */
- AM62X_IOPAD(0x228, PIN_INPUT_PULLUP, 0) /* (C21) MMC1_DAT2 */
- AM62X_IOPAD(0x224, PIN_INPUT_PULLUP, 0) /* (D22) MMC1_DAT3 */
- AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 0) /* (D17) MMC1_SDCD */
- >;
- };
-
- main_rgmii2_pins_default: main-rgmii2-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x184, PIN_INPUT, 0) /* (AE23) RGMII2_RD0 */
- AM62X_IOPAD(0x188, PIN_INPUT, 0) /* (AB20) RGMII2_RD1 */
- AM62X_IOPAD(0x18c, PIN_INPUT, 0) /* (AC21) RGMII2_RD2 */
- AM62X_IOPAD(0x190, PIN_INPUT, 0) /* (AE22) RGMII2_RD3 */
- AM62X_IOPAD(0x180, PIN_INPUT, 0) /* (AD23) RGMII2_RXC */
- AM62X_IOPAD(0x17c, PIN_INPUT, 0) /* (AD22) RGMII2_RX_CTL */
- AM62X_IOPAD(0x16c, PIN_OUTPUT, 0) /* (Y18) RGMII2_TD0 */
- AM62X_IOPAD(0x170, PIN_OUTPUT, 0) /* (AA18) RGMII2_TD1 */
- AM62X_IOPAD(0x174, PIN_OUTPUT, 0) /* (AD21) RGMII2_TD2 */
- AM62X_IOPAD(0x178, PIN_OUTPUT, 0) /* (AC20) RGMII2_TD3 */
- AM62X_IOPAD(0x168, PIN_OUTPUT, 0) /* (AE21) RGMII2_TXC */
- AM62X_IOPAD(0x164, PIN_OUTPUT, 0) /* (AA19) RGMII2_TX_CTL */
- >;
- };
-
- main_uart0_pins_default: main-uart0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14) UART0_RXD */
- AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */
- >;
- };
-
- main_uart1_pins_default: main-uart1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x194, PIN_INPUT, 2) /* (B19) MCASP0_AXR3.UART1_CTSn */
- AM62X_IOPAD(0x198, PIN_OUTPUT, 2) /* (A19) MCASP0_AXR2.UART1_RTSn */
- AM62X_IOPAD(0x1ac, PIN_INPUT, 2) /* (E19) MCASP0_AFSR.UART1_RXD */
- AM62X_IOPAD(0x1b0, PIN_OUTPUT, 2) /* (A20) MCASP0_ACLKR.UART1_TXD */
- >;
- };
-
- main_usb1_pins_default: main-usb1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x258, PIN_OUTPUT, 0) /* (F18) USB1_DRVVBUS */
- >;
- };
-
- user_leds_pins_default: user-leds-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x084, PIN_OUTPUT, 7) /* (L23) GPMC0_ADVn_ALE.GPIO0_32 */
- >;
- };
-};
-
-&cpsw3g {
- pinctrl-names = "default";
- pinctrl-0 = <&main_rgmii1_pins_default>, <&main_rgmii2_pins_default>;
-};
-
-&cpsw_port2 {
- phy-mode = "rgmii-rxid";
- phy-handle = <&cpsw3g_phy3>;
-};
-
-&cpsw3g_mdio {
- cpsw3g_phy3: ethernet-phy@3 {
- compatible = "ethernet-phy-id2000.a231", "ethernet-phy-ieee802.3-c22";
- reg = <3>;
- ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
- ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
- ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
- };
-};
-
-&dss {
- pinctrl-names = "default";
- pinctrl-0 = <&main_dss0_pins_default>;
- status = "okay";
-};
-
-&dss_ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* VP2: DPI/HDMI Output */
- port@1 {
- reg = <1>;
-
- dpi1_out: endpoint {
- remote-endpoint = <&sii9022_in>;
- };
- };
-};
-
-&main_i2c1 {
- pinctrl-names = "default";
- pinctrl-0 = <&main_i2c1_pins_default>;
- clock-frequency = <100000>;
- status = "okay";
-
- gpio_exp: gpio-expander@21 {
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_exp_int_pins_default>;
- compatible = "nxp,pcf8574";
- reg = <0x21>;
- interrupt-parent = <&main_gpio1>;
- interrupts = <49 0>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- gpio-line-names = "", "GPIO1_CAN0_nEN",
- "GPIO2_LED2", "GPIO3_LVDS_GPIO",
- "GPIO4_BUT2", "GPIO5_LVDS_BKLT_EN",
- "GPIO6_ETH1_USER_RESET", "GPIO7_AUDIO_USER_RESET";
- };
-
- sii9022: bridge-hdmi@39 {
- compatible = "sil,sii9022";
- reg = <0x39>;
-
- interrupt-parent = <&main_gpio0>;
- interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
- pinctrl-names = "default";
- pinctrl-0 = <&hdmi_int_pins_default>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- sii9022_in: endpoint {
- remote-endpoint = <&dpi1_out>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- sii9022_out: endpoint {
- remote-endpoint = <&hdmi_connector_in>;
- };
- };
- };
- };
-
- eeprom@51 {
- compatible = "atmel,24c02";
- pagesize = <16>;
- reg = <0x51>;
- };
-};
-
-&main_mcan0 {
- pinctrl-names = "default";
- pinctrl-0 = <&main_mcan0_pins_default>;
- phys = <&can_tc1>;
- status = "okay";
-};
-
-&main_uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&main_uart0_pins_default>;
- status = "okay";
-};
-
-&main_uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&main_uart1_pins_default>;
- /* Main UART1 may be used by TIFS firmware */
- status = "okay";
-};
-
-&sdhci1 {
- vmmc-supply = <&vcc_3v3_mmc>;
- vqmmc-supply = <&vddshv5_sdio>;
- pinctrl-names = "default";
- pinctrl-0 = <&main_mmc1_pins_default>;
- disable-wp;
- no-1-8-v;
- status = "okay";
-};
-
-&usbss0 {
- ti,vbus-divider;
- status = "okay";
-};
-
-&usbss1 {
- ti,vbus-divider;
- status = "okay";
-};
-
-&usb0 {
- dr_mode = "peripheral";
-};
-
-&usb1 {
- dr_mode = "host";
- pinctrl-names = "default";
- pinctrl-0 = <&main_usb1_pins_default>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index aa1e057082f0..916fcf3cc57d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -59,6 +59,24 @@
reg = <0x4130 0x4>;
#clock-cells = <1>;
};
+
+ audio_refclk0: clock-controller@82e0 {
+ compatible = "ti,am62-audio-refclk";
+ reg = <0x82e0 0x4>;
+ clocks = <&k3_clks 157 0>;
+ assigned-clocks = <&k3_clks 157 0>;
+ assigned-clock-parents = <&k3_clks 157 8>;
+ #clock-cells = <0>;
+ };
+
+ audio_refclk1: clock-controller@82e4 {
+ compatible = "ti,am62-audio-refclk";
+ reg = <0x82e4 0x4>;
+ clocks = <&k3_clks 157 10>;
+ assigned-clocks = <&k3_clks 157 10>;
+ assigned-clock-parents = <&k3_clks 157 18>;
+ #clock-cells = <0>;
+ };
};
dmss: bus@48000000 {
@@ -120,8 +138,8 @@
compatible = "ti,am64-dmss-pktdma";
reg = <0x00 0x485c0000 0x00 0x100>,
<0x00 0x4a800000 0x00 0x20000>,
- <0x00 0x4aa00000 0x00 0x40000>,
- <0x00 0x4b800000 0x00 0x400000>,
+ <0x00 0x4aa00000 0x00 0x20000>,
+ <0x00 0x4b800000 0x00 0x200000>,
<0x00 0x485e0000 0x00 0x10000>,
<0x00 0x484a0000 0x00 0x2000>,
<0x00 0x484c0000 0x00 0x2000>,
@@ -216,6 +234,14 @@
};
};
+ crypto: crypto@40900000 {
+ compatible = "ti,am62-sa3ul";
+ reg = <0x00 0x40900000 0x00 0x1200>;
+ dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>,
+ <&main_pktdma 0x7507 0>;
+ dma-names = "tx", "rx1", "rx2";
+ };
+
secure_proxy_sa3: mailbox@43600000 {
compatible = "ti,am654-secure-proxy";
#mbox-cells = <1>;
@@ -573,7 +599,6 @@
ti,itap-del-sel-sd-hs = <0x0>;
ti,itap-del-sel-sdr12 = <0x0>;
ti,itap-del-sel-sdr25 = <0x0>;
- no-1-8-v;
status = "disabled";
};
@@ -597,16 +622,16 @@
ti,itap-del-sel-sd-hs = <0x0>;
ti,itap-del-sel-sdr12 = <0x0>;
ti,itap-del-sel-sdr25 = <0x0>;
- no-1-8-v;
status = "disabled";
};
usbss0: dwc3-usb@f900000 {
compatible = "ti,am62-usb";
- reg = <0x00 0x0f900000 0x00 0x800>;
+ reg = <0x00 0x0f900000 0x00 0x800>,
+ <0x00 0x0f908000 0x00 0x400>;
clocks = <&k3_clks 161 3>;
clock-names = "ref";
- ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+ ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
#address-cells = <2>;
#size-cells = <2>;
power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -621,15 +646,18 @@
interrupt-names = "host", "peripheral";
maximum-speed = "high-speed";
dr_mode = "otg";
+ snps,usb2-gadget-lpm-disable;
+ snps,usb2-lpm-disable;
};
};
usbss1: dwc3-usb@f910000 {
compatible = "ti,am62-usb";
- reg = <0x00 0x0f910000 0x00 0x800>;
+ reg = <0x00 0x0f910000 0x00 0x800>,
+ <0x00 0x0f918000 0x00 0x400>;
clocks = <&k3_clks 162 3>;
clock-names = "ref";
- ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+ ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
#address-cells = <2>;
#size-cells = <2>;
power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
@@ -644,6 +672,8 @@
interrupt-names = "host", "peripheral";
maximum-speed = "high-speed";
dr_mode = "otg";
+ snps,usb2-gadget-lpm-disable;
+ snps,usb2-lpm-disable;
};
};
@@ -709,7 +739,7 @@
label = "port1";
phys = <&phy_gmii_sel 1>;
mac-address = [00 00 00 00 00 00];
- ti,syscon-efuse = <&wkup_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
};
cpsw_port2: port@2 {
@@ -1051,4 +1081,11 @@
#size-cells = <0>;
};
};
+
+ vpu: video-codec@30210000 {
+ compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+ reg = <0x00 0x30210000 0x00 0x10000>;
+ clocks = <&k3_clks 204 2>;
+ power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi
new file mode 100644
index 000000000000..a5aceaa39670
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023 - 2024 PHYTEC America LLC
+ * Author: Garrett Giordano <ggiordano@phytec.com>
+ *
+ * Product homepage:
+ * https://www.phytec.com/product/phycore-am62a
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+ model = "PHYTEC phyCORE-AM62Ax";
+ compatible = "phytec,am62a-phycore-som", "ti,am62a7";
+
+ aliases {
+ ethernet0 = &cpsw_port1;
+ gpio0 = &main_gpio0;
+ gpio1 = &main_gpio1;
+ i2c0 = &main_i2c0;
+ mmc0 = &sdhci0;
+ rtc0 = &i2c_som_rtc;
+ spi0 = &ospi0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins_default>;
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&main_gpio0 13 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ function = LED_FUNCTION_HEARTBEAT;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* 2G RAM */
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* global cma region */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x00 0x24000000>;
+ alloc-ranges = <0x00 0xc0000000 0x00 0x24000000>;
+ linux,cma-default;
+ };
+
+ secure_tfa_ddr: tfa@9e780000 {
+ reg = <0x00 0x9e780000 0x00 0x80000>;
+ alignment = <0x1000>;
+ no-map;
+ };
+
+ secure_ddr: optee@9e800000 {
+ reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+ alignment = <0x1000>;
+ no-map;
+ };
+
+ wkup_r5fss0_core0_memory_region: r5f-dma-memory@9c900000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0x9c900000 0x00 0x01e00000>;
+ no-map;
+ };
+ };
+
+ vcc_5v0_som: regulator-vcc-5v0-som {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_5V0_SOM";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&main_pmx0 {
+ leds_pins_default: leds-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x034, PIN_OUTPUT, 7) /* (K20) OSPI0_CSN2.GPIO0_13 */
+ >;
+ };
+
+ main_i2c0_pins_default: main-i2c0-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x1e0, PIN_INPUT_PULLUP, 0) /* (D17) I2C0_SCL */
+ AM62AX_IOPAD(0x1e4, PIN_INPUT_PULLUP, 0) /* (E16) I2C0_SDA */
+ >;
+ };
+
+ main_mdio1_pins_default: main-mdio1-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x160, PIN_OUTPUT, 0) /* (V12) MDIO0_MDC */
+ AM62AX_IOPAD(0x15c, PIN_INPUT, 0) /* (V13) MDIO0_MDIO */
+ >;
+ };
+
+ main_mmc0_pins_default: main-mmc0-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x220, PIN_INPUT_PULLUP, 0) /* (Y6) MMC0_CMD */
+ AM62AX_IOPAD(0x218, PIN_INPUT_PULLDOWN, 0) /* (AB7) MMC0_CLK */
+ AM62AX_IOPAD(0x214, PIN_INPUT_PULLUP, 0) /* (AA6) MMC0_DAT0 */
+ AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AB6) MMC0_DAT1 */
+ AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (Y7) MMC0_DAT2 */
+ AM62AX_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (AA7) MMC0_DAT3 */
+ AM62AX_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (Y8) MMC0_DAT4 */
+ AM62AX_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (W7) MMC0_DAT5 */
+ AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (W9) MMC0_DAT6 */
+ AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AB8) MMC0_DAT7 */
+ >;
+ };
+
+ main_rgmii1_pins_default: main-rgmii1-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x14c, PIN_INPUT, 0) /* (AB16) RGMII1_RD0 */
+ AM62AX_IOPAD(0x150, PIN_INPUT, 0) /* (V15) RGMII1_RD1 */
+ AM62AX_IOPAD(0x154, PIN_INPUT, 0) /* (W15) RGMII1_RD2 */
+ AM62AX_IOPAD(0x158, PIN_INPUT, 0) /* (V14) RGMII1_RD3 */
+ AM62AX_IOPAD(0x148, PIN_INPUT, 0) /* (AA16) RGMII1_RXC */
+ AM62AX_IOPAD(0x144, PIN_INPUT, 0) /* (AA15) RGMII1_RX_CTL */
+ AM62AX_IOPAD(0x134, PIN_OUTPUT, 0) /* (Y17) RGMII1_TD0 */
+ AM62AX_IOPAD(0x138, PIN_OUTPUT, 0) /* (V16) RGMII1_TD1 */
+ AM62AX_IOPAD(0x13c, PIN_OUTPUT, 0) /* (Y16) RGMII1_TD2 */
+ AM62AX_IOPAD(0x140, PIN_OUTPUT, 0) /* (AA17) RGMII1_TD3 */
+ AM62AX_IOPAD(0x130, PIN_OUTPUT, 0) /* (AB17) RGMII1_TXC */
+ AM62AX_IOPAD(0x12c, PIN_OUTPUT, 0) /* (W16) RGMII1_TX_CTL */
+ >;
+ };
+
+ ospi0_pins_default: ospi0-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x000, PIN_OUTPUT, 0) /* (L22) OSPI0_CLK */
+ AM62AX_IOPAD(0x02c, PIN_OUTPUT, 0) /* (H21) OSPI0_CSn0 */
+ AM62AX_IOPAD(0x038, PIN_OUTPUT, 0) /* (G20) OSPI0_CSn3 */
+ AM62AX_IOPAD(0x00c, PIN_INPUT, 0) /* (J21) OSPI0_D0 */
+ AM62AX_IOPAD(0x010, PIN_INPUT, 0) /* (J18) OSPI0_D1 */
+ AM62AX_IOPAD(0x014, PIN_INPUT, 0) /* (J19) OSPI0_D2 */
+ AM62AX_IOPAD(0x018, PIN_INPUT, 0) /* (H18) OSPI0_D3 */
+ AM62AX_IOPAD(0x01c, PIN_INPUT, 0) /* (K21) OSPI0_D4 */
+ AM62AX_IOPAD(0x020, PIN_INPUT, 0) /* (H19) OSPI0_D5 */
+ AM62AX_IOPAD(0x024, PIN_INPUT, 0) /* (J20) OSPI0_D6 */
+ AM62AX_IOPAD(0x028, PIN_INPUT, 0) /* (J22) OSPI0_D7 */
+ AM62AX_IOPAD(0x008, PIN_INPUT, 0) /* (L21) OSPI0_DQS */
+ >;
+ };
+
+ pmic_irq_pins_default: pmic-irq-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x1f4, PIN_INPUT, 0) /* (D16) EXTINTn */
+ >;
+ };
+};
+
+&cpsw3g {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_rgmii1_pins_default>;
+};
+
+&cpsw_port1 {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&cpsw3g_phy1>;
+};
+
+&cpsw3g_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mdio1_pins_default>;
+
+ cpsw3g_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-id2000.a231", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+};
+
+&fss {
+ status = "okay";
+};
+
+&main_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c0_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ pmic@30 {
+ compatible = "ti,tps65219";
+ reg = <0x30>;
+ buck1-supply = <&vcc_5v0_som>;
+ buck2-supply = <&vcc_5v0_som>;
+ buck3-supply = <&vcc_5v0_som>;
+ ldo1-supply = <&vdd_3v3>;
+ ldo2-supply = <&vdd_1v8>;
+ ldo3-supply = <&vcc_5v0_som>;
+ ldo4-supply = <&vcc_5v0_som>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_irq_pins_default>;
+ interrupt-parent = <&gic500>;
+ interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ti,power-button;
+ system-power-controller;
+
+ regulators {
+ vdd_3v3: buck1 {
+ regulator-name = "VDD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_1v8: buck2 {
+ regulator-name = "VDD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_lpddr4: buck3 {
+ regulator-name = "VDD_LPDDR4";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddshv5_sdio: ldo1 {
+ regulator-name = "VDDSHV5_SDIO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-allow-bypass;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddr_core: ldo2 {
+ regulator-name = "VDDR_CORE";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdda_1v8: ldo3 {
+ regulator-name = "VDDA_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_2v5: ldo4 {
+ regulator-name = "VDD_2V5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c32";
+ pagesize = <32>;
+ reg = <0x50>;
+ };
+
+ i2c_som_rtc: rtc@52 {
+ compatible = "microcrystal,rv3028";
+ reg = <0x52>;
+ };
+};
+
+&main_gpio0 {
+ status = "okay";
+};
+
+&main_gpio1 {
+ status = "okay";
+};
+
+&main_gpio_intr {
+ status = "okay";
+};
+
+&ospi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ospi0_pins_default>;
+ status = "okay";
+
+ serial_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <25000000>;
+ cdns,tshsl-ns = <60>;
+ cdns,tsd2d-ns = <60>;
+ cdns,tchsh-ns = <60>;
+ cdns,tslch-ns = <60>;
+ cdns,read-delay = <0>;
+ };
+};
+
+&sdhci0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc0_pins_default>;
+ disable-wp;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
index f7bec484705a..f5ac101a04df 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
@@ -6,9 +6,8 @@
*/
&cbass_wakeup {
- wkup_conf: syscon@43000000 {
- compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
- reg = <0x00 0x43000000 0x00 0x20000>;
+ wkup_conf: bus@43000000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x00 0x00 0x43000000 0x20000>;
@@ -17,6 +16,21 @@
compatible = "ti,am654-chipid";
reg = <0x14 0x4>;
};
+
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
+
+ usb0_phy_ctrl: syscon@4008 {
+ compatible = "ti,am62-usb-phy-ctrl", "syscon";
+ reg = <0x4008 0x4>;
+ };
+
+ usb1_phy_ctrl: syscon@4018 {
+ compatible = "ti,am62-usb-phy-ctrl", "syscon";
+ reg = <0x4018 0x4>;
+ };
};
wkup_uart0: serial@2b300000 {
@@ -49,7 +63,6 @@
clock-names = "vbus", "osc32k";
power-domains = <&k3_pds 117 TI_SCI_PD_EXCLUSIVE>;
wakeup-source;
- status = "disabled";
};
wkup_rti0: watchdog@2b000000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts
new file mode 100644
index 000000000000..3b93409b23e7
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023 - 2024 PHYTEC America LLC
+ * Author: Garrett Giordano <ggiordano@phytec.com>
+ *
+ * Product homepage:
+ * https://www.phytec.com/product/phyboard-am62a
+ */
+
+#include "k3-am62a7.dtsi"
+#include "k3-am62a-phycore-som.dtsi"
+#include "k3-am62x-phyboard-lyra.dtsi"
+
+/ {
+ compatible = "phytec,am62a7-phyboard-lyra-rdk",
+ "phytec,am62a-phycore-som", "ti,am62a7";
+ model = "PHYTEC phyBOARD-Lyra AM62A7";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index f241637a5642..67faf46d7a35 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -40,6 +40,15 @@
#size-cells = <2>;
ranges;
+ /* global cma region */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x00 0x24000000>;
+ alloc-ranges = <0x00 0xc0000000 0x00 0x24000000>;
+ linux,cma-default;
+ };
+
secure_tfa_ddr: tfa@9e780000 {
reg = <0x00 0x9e780000 0x00 0x80000>;
alignment = <0x1000>;
@@ -113,6 +122,20 @@
regulator-boot-on;
};
+ vddshv_sdio: regulator-5 {
+ compatible = "regulator-gpio";
+ regulator-name = "vddshv_sdio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vddshv_sdio_pins_default>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ vin-supply = <&ldo1>;
+ gpios = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+ states = <1800000 0x0>,
+ <3300000 0x1>;
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -342,6 +365,12 @@
AM62AX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C15) UART0_RTSn.GPIO1_23 */
>;
};
+
+ vddshv_sdio_pins_default: vddshv-sdio-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
+ >;
+ };
};
&mcu_pmx0 {
@@ -580,6 +609,7 @@
/* SD/MMC */
status = "okay";
vmmc-supply = <&vdd_mmc1>;
+ vqmmc-supply = <&vddshv_sdio>;
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
disable-wp;
@@ -680,8 +710,6 @@
0 0 0 0
0 0 0 0
>;
- tx-num-evt = <32>;
- rx-num-evt = <32>;
};
&dss {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
new file mode 100644
index 000000000000..9701fc69aed9
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
@@ -0,0 +1,1062 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree file for the MAIN domain peripherals shared by AM62P and J722S
+ *
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+&cbass_main {
+ oc_sram: sram@70000000 {
+ compatible = "mmio-sram";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ 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 0x01880000 0x00 0xc0000>, /* GICR */
+ <0x01 0x00000000 0x00 0x2000>, /* GICC */
+ <0x01 0x00010000 0x00 0x1000>, /* GICH */
+ <0x01 0x00020000 0x00 0x2000>; /* GICV */
+ /*
+ * 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_conf: bus@100000 {
+ compatible = "simple-bus";
+ reg = <0x00 0x00100000 0x00 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00 0x00 0x00100000 0x20000>;
+
+ phy_gmii_sel: phy@4044 {
+ compatible = "ti,am654-phy-gmii-sel";
+ reg = <0x4044 0x8>;
+ #phy-cells = <1>;
+ };
+
+ epwm_tbclk: clock-controller@4130 {
+ compatible = "ti,am62-epwm-tbclk";
+ reg = <0x4130 0x4>;
+ #clock-cells = <1>;
+ };
+ };
+
+ dmss: bus@48000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges;
+ ranges = <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>;
+ bootph-all;
+
+ ti,sci-dev-id = <25>;
+
+ secure_proxy_main: mailbox@4d000000 {
+ compatible = "ti,am654-secure-proxy";
+ #mbox-cells = <1>;
+ reg-names = "target_data", "rt", "scfg";
+ reg = <0x00 0x4d000000 0x00 0x80000>,
+ <0x00 0x4a600000 0x00 0x80000>,
+ <0x00 0x4a400000 0x00 0x80000>;
+ interrupt-names = "rx_012";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ bootph-all;
+ };
+
+ inta_main_dmss: interrupt-controller@48000000 {
+ compatible = "ti,sci-inta";
+ reg = <0x00 0x48000000 0x00 0x100000>;
+ #interrupt-cells = <0>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ msi-controller;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <28>;
+ ti,unmapped-event-sources = <&main_bcdma>, <&main_pktdma>;
+ };
+
+ main_bcdma: dma-controller@485c0100 {
+ compatible = "ti,am64-dmss-bcdma";
+ reg = <0x00 0x485c0100 0x00 0x100>,
+ <0x00 0x4c000000 0x00 0x20000>,
+ <0x00 0x4a820000 0x00 0x20000>,
+ <0x00 0x4aa40000 0x00 0x20000>,
+ <0x00 0x4bc00000 0x00 0x100000>,
+ <0x00 0x48600000 0x00 0x8000>,
+ <0x00 0x484a4000 0x00 0x2000>,
+ <0x00 0x484c2000 0x00 0x2000>,
+ <0x00 0x48420000 0x00 0x2000>;
+ reg-names = "gcfg", "bchanrt", "rchanrt", "tchanrt", "ringrt",
+ "ring", "tchan", "rchan", "bchan";
+ msi-parent = <&inta_main_dmss>;
+ #dma-cells = <3>;
+
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <26>;
+ ti,sci-rm-range-bchan = <0x20>; /* BLOCK_COPY_CHAN */
+ ti,sci-rm-range-rchan = <0x21>; /* SPLIT_TR_RX_CHAN */
+ ti,sci-rm-range-tchan = <0x22>; /* SPLIT_TR_TX_CHAN */
+ bootph-all;
+ };
+
+ main_pktdma: dma-controller@485c0000 {
+ compatible = "ti,am64-dmss-pktdma";
+ reg = <0x00 0x485c0000 0x00 0x100>,
+ <0x00 0x4a800000 0x00 0x20000>,
+ <0x00 0x4aa00000 0x00 0x20000>,
+ <0x00 0x4b800000 0x00 0x200000>,
+ <0x00 0x485e0000 0x00 0x10000>,
+ <0x00 0x484a0000 0x00 0x2000>,
+ <0x00 0x484c0000 0x00 0x2000>,
+ <0x00 0x48430000 0x00 0x1000>;
+ reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt",
+ "ring", "tchan", "rchan", "rflow";
+ msi-parent = <&inta_main_dmss>;
+ #dma-cells = <2>;
+ bootph-all;
+
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <30>;
+ ti,sci-rm-range-tchan = <0x23>, /* UNMAPPED_TX_CHAN */
+ <0x24>, /* CPSW_TX_CHAN */
+ <0x25>, /* SAUL_TX_0_CHAN */
+ <0x26>; /* SAUL_TX_1_CHAN */
+ ti,sci-rm-range-tflow = <0x10>, /* RING_UNMAPPED_TX_CHAN */
+ <0x11>, /* RING_CPSW_TX_CHAN */
+ <0x12>, /* RING_SAUL_TX_0_CHAN */
+ <0x13>; /* RING_SAUL_TX_1_CHAN */
+ ti,sci-rm-range-rchan = <0x29>, /* UNMAPPED_RX_CHAN */
+ <0x2b>, /* CPSW_RX_CHAN */
+ <0x2d>, /* SAUL_RX_0_CHAN */
+ <0x2f>, /* SAUL_RX_1_CHAN */
+ <0x31>, /* SAUL_RX_2_CHAN */
+ <0x33>; /* SAUL_RX_3_CHAN */
+ ti,sci-rm-range-rflow = <0x2a>, /* FLOW_UNMAPPED_RX_CHAN */
+ <0x2c>, /* FLOW_CPSW_RX_CHAN */
+ <0x2e>, /* FLOW_SAUL_RX_0/1_CHAN */
+ <0x32>; /* FLOW_SAUL_RX_2/3_CHAN */
+ };
+ };
+
+ dmss_csi: bus@4e000000 {
+ compatible = "simple-bus";
+ ranges = <0x00 0x4e000000 0x00 0x4e000000 0x00 0x408000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges;
+ ti,sci-dev-id = <198>;
+
+ inta_main_dmss_csi: interrupt-controller@4e400000 {
+ compatible = "ti,sci-inta";
+ reg = <0x00 0x4e400000 0x00 0x8000>;
+ #interrupt-cells = <0>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ msi-controller;
+ power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <200>;
+ ti,interrupt-ranges = <0 237 8>;
+ ti,unmapped-event-sources = <&main_bcdma_csi>;
+ };
+
+ main_bcdma_csi: dma-controller@4e230000 {
+ compatible = "ti,am62a-dmss-bcdma-csirx";
+ reg = <0x00 0x4e230000 0x00 0x100>,
+ <0x00 0x4e180000 0x00 0x8000>,
+ <0x00 0x4e100000 0x00 0x10000>;
+ reg-names = "gcfg", "rchanrt", "ringrt";
+ #dma-cells = <3>;
+ msi-parent = <&inta_main_dmss_csi>;
+ power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <199>;
+ ti,sci-rm-range-rchan = <0x21>;
+ };
+ };
+
+ dmsc: system-controller@44043000 {
+ compatible = "ti,k2g-sci";
+ ti,host-id = <12>;
+ mbox-names = "rx", "tx";
+ mboxes = <&secure_proxy_main 12>,
+ <&secure_proxy_main 13>;
+ reg-names = "debug_messages";
+ reg = <0x00 0x44043000 0x00 0xfe0>;
+ bootph-all;
+
+ k3_pds: power-controller {
+ compatible = "ti,sci-pm-domain";
+ #power-domain-cells = <2>;
+ bootph-all;
+ };
+
+ k3_clks: clock-controller {
+ compatible = "ti,k2g-sci-clk";
+ #clock-cells = <2>;
+ bootph-all;
+ };
+
+ k3_reset: reset-controller {
+ compatible = "ti,sci-reset";
+ #reset-cells = <2>;
+ bootph-all;
+ };
+ };
+
+ crypto: crypto@40900000 {
+ compatible = "ti,am62-sa3ul";
+ reg = <0x00 0x40900000 0x00 0x1200>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>,
+ <&main_pktdma 0x7507 0>;
+ dma-names = "tx", "rx1", "rx2";
+ };
+
+ secure_proxy_sa3: mailbox@43600000 {
+ compatible = "ti,am654-secure-proxy";
+ #mbox-cells = <1>;
+ reg-names = "target_data", "rt", "scfg";
+ reg = <0x00 0x43600000 0x00 0x10000>,
+ <0x00 0x44880000 0x00 0x20000>,
+ <0x00 0x44860000 0x00 0x20000>;
+ /*
+ * Marked Disabled:
+ * Node is incomplete as it is meant for bootloaders and
+ * firmware on non-MPU processors
+ */
+ status = "disabled";
+ bootph-all;
+ };
+
+ main_pmx0: pinctrl@f4000 {
+ compatible = "pinctrl-single";
+ reg = <0x00 0xf4000 0x00 0x2ac>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+ bootph-all;
+ };
+
+ main_esm: esm@420000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x420000 0x00 0x1000>;
+ ti,esm-pins = <160>, <161>, <162>, <163>, <177>, <178>;
+ bootph-pre-ram;
+ };
+
+ main_timer0: timer@2400000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2400000 0x00 0x400>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 36 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 36 2>;
+ assigned-clock-parents = <&k3_clks 36 3>;
+ power-domains = <&k3_pds 36 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ bootph-all;
+ };
+
+ main_timer1: timer@2410000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2410000 0x00 0x400>;
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 37 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 37 2>;
+ assigned-clock-parents = <&k3_clks 37 3>;
+ power-domains = <&k3_pds 37 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer2: timer@2420000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2420000 0x00 0x400>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 38 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 38 2>;
+ assigned-clock-parents = <&k3_clks 38 3>;
+ power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer3: timer@2430000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2430000 0x00 0x400>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 39 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 39 2>;
+ assigned-clock-parents = <&k3_clks 39 3>;
+ power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer4: timer@2440000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2440000 0x00 0x400>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 40 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 40 2>;
+ assigned-clock-parents = <&k3_clks 40 3>;
+ power-domains = <&k3_pds 40 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer5: timer@2450000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2450000 0x00 0x400>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 41 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 41 2>;
+ assigned-clock-parents = <&k3_clks 41 3>;
+ power-domains = <&k3_pds 41 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer6: timer@2460000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2460000 0x00 0x400>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 42 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 42 2>;
+ assigned-clock-parents = <&k3_clks 42 3>;
+ power-domains = <&k3_pds 42 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer7: timer@2470000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2470000 0x00 0x400>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 43 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 43 2>;
+ assigned-clock-parents = <&k3_clks 43 3>;
+ power-domains = <&k3_pds 43 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_uart0: serial@2800000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02800000 0x00 0x100>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 146 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart1: serial@2810000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02810000 0x00 0x100>;
+ interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 152 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart2: serial@2820000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02820000 0x00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 153 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart3: serial@2830000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02830000 0x00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 154 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart4: serial@2840000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02840000 0x00 0x100>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 155 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 155 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart5: serial@2850000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02850000 0x00 0x100>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 156 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart6: serial@2860000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02860000 0x00 0x100>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 158 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 158 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_i2c0: i2c@20000000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20000000 0x00 0x100>;
+ interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 102 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_i2c1: i2c@20010000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20010000 0x00 0x100>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 103 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_i2c2: i2c@20020000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20020000 0x00 0x100>;
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 104 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_i2c3: i2c@20030000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20030000 0x00 0x100>;
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 105 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_spi0: spi@20100000 {
+ compatible = "ti,am654-mcspi", "ti,omap4-mcspi";
+ reg = <0x00 0x20100000 0x00 0x400>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 141 0>;
+ status = "disabled";
+ };
+
+ main_spi1: spi@20110000 {
+ compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+ reg = <0x00 0x20110000 0x00 0x400>;
+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 142 0>;
+ status = "disabled";
+ };
+
+ main_spi2: spi@20120000 {
+ compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+ reg = <0x00 0x20120000 0x00 0x400>;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 143 0>;
+ status = "disabled";
+ };
+
+ main_gpio_intr: interrupt-controller@a00000 {
+ compatible = "ti,sci-intr";
+ reg = <0x00 0x00a00000 0x00 0x800>;
+ ti,intr-trigger-type = <1>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ #interrupt-cells = <1>;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <3>;
+ ti,interrupt-ranges = <0 32 16>;
+ };
+
+ main_gpio0: gpio@600000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x00 0x00600000 0x00 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&main_gpio_intr>;
+ interrupts = <190>, <191>, <192>,
+ <193>, <194>, <195>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 77 0>;
+ clock-names = "gpio";
+ };
+
+ main_gpio1: gpio@601000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x00 0x00601000 0x00 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&main_gpio_intr>;
+ interrupts = <180>, <181>, <182>,
+ <183>, <184>, <185>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 78 0>;
+ clock-names = "gpio";
+ };
+
+ sdhci0: mmc@fa10000 {
+ compatible = "ti,am64-sdhci-8bit";
+ reg = <0x00 0x0fa10000 0x00 0x1000>, <0x00 0x0fa18000 0x00 0x400>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 57 1>, <&k3_clks 57 2>;
+ clock-names = "clk_ahb", "clk_xin";
+ assigned-clocks = <&k3_clks 57 2>;
+ assigned-clock-parents = <&k3_clks 57 4>;
+ bus-width = <8>;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ ti,clkbuf-sel = <0x7>;
+ ti,strobe-sel = <0x77>;
+ ti,trm-icp = <0x8>;
+ ti,otap-del-sel-legacy = <0x1>;
+ ti,otap-del-sel-mmc-hs = <0x1>;
+ ti,otap-del-sel-ddr52 = <0x6>;
+ ti,otap-del-sel-hs200 = <0x8>;
+ ti,otap-del-sel-hs400 = <0x5>;
+ ti,itap-del-sel-legacy = <0x10>;
+ ti,itap-del-sel-mmc-hs = <0xa>;
+ ti,itap-del-sel-ddr52 = <0x3>;
+ status = "disabled";
+ };
+
+ sdhci1: mmc@fa00000 {
+ compatible = "ti,am62-sdhci";
+ reg = <0x00 0x0fa00000 0x00 0x1000>, <0x00 0x0fa08000 0x00 0x400>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
+ clock-names = "clk_ahb", "clk_xin";
+ bus-width = <4>;
+ ti,clkbuf-sel = <0x7>;
+ 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-ddr50 = <0x9>;
+ ti,otap-del-sel-sdr104 = <0x6>;
+ ti,itap-del-sel-legacy = <0x0>;
+ ti,itap-del-sel-sd-hs = <0x0>;
+ ti,itap-del-sel-sdr12 = <0x0>;
+ ti,itap-del-sel-sdr25 = <0x0>;
+ status = "disabled";
+ };
+
+ sdhci2: mmc@fa20000 {
+ compatible = "ti,am62-sdhci";
+ reg = <0x00 0x0fa20000 0x00 0x1000>, <0x00 0x0fa28000 0x00 0x400>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
+ clock-names = "clk_ahb", "clk_xin";
+ bus-width = <4>;
+ ti,clkbuf-sel = <0x7>;
+ 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-ddr50 = <0x9>;
+ ti,otap-del-sel-sdr104 = <0x6>;
+ ti,itap-del-sel-legacy = <0x0>;
+ ti,itap-del-sel-sd-hs = <0x0>;
+ ti,itap-del-sel-sdr12 = <0x0>;
+ ti,itap-del-sel-sdr25 = <0x0>;
+ status = "disabled";
+ };
+
+ usbss0: usb@f900000 {
+ compatible = "ti,am62-usb";
+ reg = <0x00 0x0f900000 0x00 0x800>,
+ <0x00 0x0f908000 0x00 0x400>;
+ clocks = <&k3_clks 161 3>;
+ clock-names = "ref";
+ ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+ ranges;
+ status = "disabled";
+
+ usb0: usb@31000000 {
+ compatible = "snps,dwc3";
+ reg = <0x00 0x31000000 0x00 0x50000>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+ <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+ interrupt-names = "host", "peripheral";
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ snps,usb2-gadget-lpm-disable;
+ snps,usb2-lpm-disable;
+ };
+ };
+
+ fss: bus@fc00000 {
+ compatible = "simple-bus";
+ reg = <0x00 0x0fc00000 0x00 0x70000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ospi0: spi@fc40000 {
+ compatible = "ti,am654-ospi", "cdns,qspi-nor";
+ reg = <0x00 0x0fc40000 0x00 0x100>,
+ <0x05 0x00000000 0x01 0x00000000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x0>;
+ clocks = <&k3_clks 75 7>;
+ assigned-clocks = <&k3_clks 75 7>;
+ assigned-clock-parents = <&k3_clks 75 8>;
+ assigned-clock-rates = <166666666>;
+ power-domains = <&k3_pds 75 TI_SCI_PD_EXCLUSIVE>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ cpsw3g: ethernet@8000000 {
+ compatible = "ti,am642-cpsw-nuss";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ reg = <0x00 0x08000000 0x00 0x200000>;
+ reg-names = "cpsw_nuss";
+ ranges = <0x00 0x00 0x00 0x08000000 0x00 0x200000>;
+ clocks = <&k3_clks 13 0>;
+ assigned-clocks = <&k3_clks 13 3>;
+ assigned-clock-parents = <&k3_clks 13 11>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 13 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ dmas = <&main_pktdma 0xc600 15>,
+ <&main_pktdma 0xc601 15>,
+ <&main_pktdma 0xc602 15>,
+ <&main_pktdma 0xc603 15>,
+ <&main_pktdma 0xc604 15>,
+ <&main_pktdma 0xc605 15>,
+ <&main_pktdma 0xc606 15>,
+ <&main_pktdma 0xc607 15>,
+ <&main_pktdma 0x4600 15>;
+ 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";
+ phys = <&phy_gmii_sel 1>;
+ mac-address = [00 00 00 00 00 00];
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
+ status = "disabled";
+ };
+
+ cpsw_port2: port@2 {
+ reg = <2>;
+ ti,mac-only;
+ label = "port2";
+ phys = <&phy_gmii_sel 2>;
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+ };
+
+ cpsw3g_mdio: mdio@f00 {
+ compatible = "ti,cpsw-mdio","ti,davinci_mdio";
+ reg = <0x00 0xf00 0x00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&k3_clks 13 0>;
+ clock-names = "fck";
+ bus_freq = <1000000>;
+ status = "disabled";
+ };
+
+ cpts@3d000 {
+ compatible = "ti,j721e-cpts";
+ reg = <0x00 0x3d000 0x00 0x400>;
+ clocks = <&k3_clks 13 3>;
+ clock-names = "cpts";
+ interrupts-extended = <&gic500 GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cpts";
+ ti,cpts-ext-ts-inputs = <4>;
+ ti,cpts-periodic-outputs = <2>;
+ };
+ };
+
+ hwspinlock: spinlock@2a000000 {
+ compatible = "ti,am64-hwspinlock";
+ reg = <0x00 0x2a000000 0x00 0x1000>;
+ #hwlock-cells = <1>;
+ };
+
+ mailbox0_cluster0: mailbox@29000000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29000000 0x00 0x200>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ mailbox0_cluster1: mailbox@29010000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29010000 0x00 0x200>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ mailbox0_cluster2: mailbox@29020000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29020000 0x00 0x200>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ mailbox0_cluster3: mailbox@29030000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29030000 0x00 0x200>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ ecap0: pwm@23100000 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23100000 0x00 0x100>;
+ power-domains = <&k3_pds 51 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 51 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ ecap1: pwm@23110000 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23110000 0x00 0x100>;
+ power-domains = <&k3_pds 52 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 52 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ ecap2: pwm@23120000 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23120000 0x00 0x100>;
+ power-domains = <&k3_pds 53 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 53 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_mcan0: can@20701000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x20701000 0x00 0x200>,
+ <0x00 0x20708000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 98 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 98 6>, <&k3_clks 98 1>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan1: can@20711000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x20711000 0x00 0x200>,
+ <0x00 0x20718000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 99 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 99 6>, <&k3_clks 99 1>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_rti0: watchdog@e000000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e000000 0x00 0x100>;
+ clocks = <&k3_clks 125 0>;
+ power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 125 0>;
+ assigned-clock-parents = <&k3_clks 125 2>;
+ };
+
+ main_rti1: watchdog@e010000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e010000 0x00 0x100>;
+ clocks = <&k3_clks 126 0>;
+ power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 126 0>;
+ assigned-clock-parents = <&k3_clks 126 2>;
+ };
+
+ main_rti2: watchdog@e020000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e020000 0x00 0x100>;
+ clocks = <&k3_clks 127 0>;
+ power-domains = <&k3_pds 127 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 127 0>;
+ assigned-clock-parents = <&k3_clks 127 2>;
+ };
+
+ main_rti3: watchdog@e030000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e030000 0x00 0x100>;
+ clocks = <&k3_clks 128 0>;
+ power-domains = <&k3_pds 128 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 128 0>;
+ assigned-clock-parents = <&k3_clks 128 2>;
+ };
+
+ main_rti15: watchdog@e0f0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e0f0000 0x00 0x100>;
+ clocks = <&k3_clks 130 0>;
+ power-domains = <&k3_pds 130 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 130 0>;
+ assigned-clock-parents = <&k3_clks 130 2>;
+ };
+
+ epwm0: pwm@23000000 {
+ compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23000000 0x00 0x100>;
+ power-domains = <&k3_pds 86 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&epwm_tbclk 0>, <&k3_clks 86 0>;
+ clock-names = "tbclk", "fck";
+ status = "disabled";
+ };
+
+ epwm1: pwm@23010000 {
+ compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23010000 0x00 0x100>;
+ power-domains = <&k3_pds 87 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&epwm_tbclk 1>, <&k3_clks 87 0>;
+ clock-names = "tbclk", "fck";
+ status = "disabled";
+ };
+
+ epwm2: pwm@23020000 {
+ compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23020000 0x00 0x100>;
+ power-domains = <&k3_pds 88 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&epwm_tbclk 2>, <&k3_clks 88 0>;
+ clock-names = "tbclk", "fck";
+ status = "disabled";
+ };
+
+ mcasp0: audio-controller@2b00000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b00000 0x00 0x2000>,
+ <0x00 0x02b08000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc500 0>, <&main_bcdma 0 0x4500 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 190 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 190 0>;
+ assigned-clock-parents = <&k3_clks 190 2>;
+ power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp1: audio-controller@2b10000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b10000 0x00 0x2000>,
+ <0x00 0x02b18000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc501 0>, <&main_bcdma 0 0x4501 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 191 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 191 0>;
+ assigned-clock-parents = <&k3_clks 191 2>;
+ power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp2: audio-controller@2b20000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b20000 0x00 0x2000>,
+ <0x00 0x02b28000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc502 0>, <&main_bcdma 0 0x4502 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 192 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 192 0>;
+ assigned-clock-parents = <&k3_clks 192 2>;
+ power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ ti_csi2rx0: ticsi2rx@30102000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x00 0x30102000 0x00 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_bcdma_csi 0 0x5000 0>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx0: csi-bridge@30101000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x00 0x30101000 0x00 0x1000>;
+ clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
+ <&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
+ clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+ "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+ phys = <&dphy0>;
+ phy-names = "dphy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+
+ csi0_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ csi0_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ csi0_port3: port@3 {
+ reg = <3>;
+ status = "disabled";
+ };
+
+ csi0_port4: port@4 {
+ reg = <4>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ dphy0: phy@30110000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x00 0x30110000 0x00 0x1100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ vpu: video-codec@30210000 {
+ compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+ reg = <0x00 0x30210000 0x00 0x10000>;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 204 2>;
+ power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
index b973b550eb9d..e65db6ce02bf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Device Tree file for the AM62P MCU domain peripherals
+ * Device Tree file for the MCU domain peripherals shared by AM62P and J722S
+ *
* Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
@@ -11,7 +12,15 @@
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0xffffffff>;
+ pinctrl-single,gpio-range =
+ <&mcu_pmx_range 0 21 PIN_GPIO_RANGE_IOPAD>,
+ <&mcu_pmx_range 23 1 PIN_GPIO_RANGE_IOPAD>,
+ <&mcu_pmx_range 32 2 PIN_GPIO_RANGE_IOPAD>;
bootph-all;
+
+ mcu_pmx_range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
};
mcu_esm: esm@4100000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-thermal.dtsi
index c7486fb2a5b4..c7486fb2a5b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-thermal.dtsi
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi
index a84756c336d0..315d0092e736 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Device Tree file for the AM62P wakeup domain peripherals
+ * Device Tree file for the WAKEUP domain peripherals shared by AM62P and J722S
+ *
* Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
@@ -18,6 +19,21 @@
reg = <0x14 0x4>;
bootph-all;
};
+
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
+
+ usb0_phy_ctrl: syscon@4008 {
+ compatible = "ti,am62-usb-phy-ctrl", "syscon";
+ reg = <0x4008 0x4>;
+ };
+
+ usb1_phy_ctrl: syscon@4018 {
+ compatible = "ti,am62-usb-phy-ctrl", "syscon";
+ reg = <0x4018 0x4>;
+ };
};
wkup_uart0: serial@2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 7337a9e13535..57383bd2eaeb 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -1,1038 +1,68 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Device Tree file for the AM62P main domain peripherals
+ * Device Tree file for the AM62P MAIN domain peripherals
+ *
* Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_main {
- oc_sram: sram@70000000 {
- compatible = "mmio-sram";
- reg = <0x00 0x70000000 0x00 0x10000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x00 0x00 0x70000000 0x10000>;
- };
-
- gic500: interrupt-controller@1800000 {
- compatible = "arm,gic-v3";
+ usbss1: usb@f910000 {
+ compatible = "ti,am62-usb";
+ reg = <0x00 0x0f910000 0x00 0x800>,
+ <0x00 0x0f918000 0x00 0x400>;
+ clocks = <&k3_clks 162 3>;
+ clock-names = "ref";
+ ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
#address-cells = <2>;
#size-cells = <2>;
+ power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
ranges;
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */
- <0x00 0x01880000 0x00 0xc0000>, /* GICR */
- <0x01 0x00000000 0x00 0x2000>, /* GICC */
- <0x01 0x00010000 0x00 0x1000>, /* GICH */
- <0x01 0x00020000 0x00 0x2000>; /* GICV */
- /*
- * 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_conf: bus@100000 {
- compatible = "simple-bus";
- reg = <0x00 0x00100000 0x00 0x20000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x00 0x00 0x00100000 0x20000>;
-
- phy_gmii_sel: phy@4044 {
- compatible = "ti,am654-phy-gmii-sel";
- reg = <0x4044 0x8>;
- #phy-cells = <1>;
- };
-
- epwm_tbclk: clock-controller@4130 {
- compatible = "ti,am62-epwm-tbclk";
- reg = <0x4130 0x4>;
- #clock-cells = <1>;
- };
- };
-
- dmss: bus@48000000 {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <2>;
- dma-ranges;
- ranges = <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>;
- bootph-all;
-
- ti,sci-dev-id = <25>;
-
- secure_proxy_main: mailbox@4d000000 {
- compatible = "ti,am654-secure-proxy";
- #mbox-cells = <1>;
- reg-names = "target_data", "rt", "scfg";
- reg = <0x00 0x4d000000 0x00 0x80000>,
- <0x00 0x4a600000 0x00 0x80000>,
- <0x00 0x4a400000 0x00 0x80000>;
- interrupt-names = "rx_012";
- interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
- bootph-all;
- };
-
- inta_main_dmss: interrupt-controller@48000000 {
- compatible = "ti,sci-inta";
- reg = <0x00 0x48000000 0x00 0x100000>;
- #interrupt-cells = <0>;
- interrupt-controller;
- interrupt-parent = <&gic500>;
- msi-controller;
- ti,sci = <&dmsc>;
- ti,sci-dev-id = <28>;
- ti,interrupt-ranges = <5 69 35>;
- ti,unmapped-event-sources = <&main_bcdma>, <&main_pktdma>;
- };
-
- main_bcdma: dma-controller@485c0100 {
- compatible = "ti,am64-dmss-bcdma";
- reg = <0x00 0x485c0100 0x00 0x100>,
- <0x00 0x4c000000 0x00 0x20000>,
- <0x00 0x4a820000 0x00 0x20000>,
- <0x00 0x4aa40000 0x00 0x20000>,
- <0x00 0x4bc00000 0x00 0x100000>,
- <0x00 0x48600000 0x00 0x8000>,
- <0x00 0x484a4000 0x00 0x2000>,
- <0x00 0x484c2000 0x00 0x2000>,
- <0x00 0x48420000 0x00 0x2000>;
- reg-names = "gcfg", "bchanrt", "rchanrt", "tchanrt", "ringrt",
- "ring", "tchan", "rchan", "bchan";
- msi-parent = <&inta_main_dmss>;
- #dma-cells = <3>;
-
- ti,sci = <&dmsc>;
- ti,sci-dev-id = <26>;
- ti,sci-rm-range-bchan = <0x20>; /* BLOCK_COPY_CHAN */
- ti,sci-rm-range-rchan = <0x21>; /* SPLIT_TR_RX_CHAN */
- ti,sci-rm-range-tchan = <0x22>; /* SPLIT_TR_TX_CHAN */
- bootph-all;
- };
-
- main_pktdma: dma-controller@485c0000 {
- compatible = "ti,am64-dmss-pktdma";
- reg = <0x00 0x485c0000 0x00 0x100>,
- <0x00 0x4a800000 0x00 0x20000>,
- <0x00 0x4aa00000 0x00 0x40000>,
- <0x00 0x4b800000 0x00 0x400000>,
- <0x00 0x485e0000 0x00 0x10000>,
- <0x00 0x484a0000 0x00 0x2000>,
- <0x00 0x484c0000 0x00 0x2000>,
- <0x00 0x48430000 0x00 0x1000>;
- reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt",
- "ring", "tchan", "rchan", "rflow";
- msi-parent = <&inta_main_dmss>;
- #dma-cells = <2>;
- bootph-all;
-
- ti,sci = <&dmsc>;
- ti,sci-dev-id = <30>;
- ti,sci-rm-range-tchan = <0x23>, /* UNMAPPED_TX_CHAN */
- <0x24>, /* CPSW_TX_CHAN */
- <0x25>, /* SAUL_TX_0_CHAN */
- <0x26>; /* SAUL_TX_1_CHAN */
- ti,sci-rm-range-tflow = <0x10>, /* RING_UNMAPPED_TX_CHAN */
- <0x11>, /* RING_CPSW_TX_CHAN */
- <0x12>, /* RING_SAUL_TX_0_CHAN */
- <0x13>; /* RING_SAUL_TX_1_CHAN */
- ti,sci-rm-range-rchan = <0x29>, /* UNMAPPED_RX_CHAN */
- <0x2b>, /* CPSW_RX_CHAN */
- <0x2d>, /* SAUL_RX_0_CHAN */
- <0x2f>, /* SAUL_RX_1_CHAN */
- <0x31>, /* SAUL_RX_2_CHAN */
- <0x33>; /* SAUL_RX_3_CHAN */
- ti,sci-rm-range-rflow = <0x2a>, /* FLOW_UNMAPPED_RX_CHAN */
- <0x2c>, /* FLOW_CPSW_RX_CHAN */
- <0x2e>, /* FLOW_SAUL_RX_0/1_CHAN */
- <0x32>; /* FLOW_SAUL_RX_2/3_CHAN */
- };
- };
-
- dmss_csi: bus@4e000000 {
- compatible = "simple-bus";
- ranges = <0x00 0x4e000000 0x00 0x4e000000 0x00 0x408000>;
- #address-cells = <2>;
- #size-cells = <2>;
- dma-ranges;
- ti,sci-dev-id = <198>;
-
- inta_main_dmss_csi: interrupt-controller@4e400000 {
- compatible = "ti,sci-inta";
- reg = <0x00 0x4e400000 0x00 0x8000>;
- #interrupt-cells = <0>;
- interrupt-controller;
- interrupt-parent = <&gic500>;
- msi-controller;
- power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
- ti,sci = <&dmsc>;
- ti,sci-dev-id = <200>;
- ti,interrupt-ranges = <0 237 8>;
- ti,unmapped-event-sources = <&main_bcdma_csi>;
- };
-
- main_bcdma_csi: dma-controller@4e230000 {
- compatible = "ti,am62a-dmss-bcdma-csirx";
- reg = <0x00 0x4e230000 0x00 0x100>,
- <0x00 0x4e180000 0x00 0x8000>,
- <0x00 0x4e100000 0x00 0x10000>;
- reg-names = "gcfg", "rchanrt", "ringrt";
- #dma-cells = <3>;
- msi-parent = <&inta_main_dmss_csi>;
- power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
- ti,sci = <&dmsc>;
- ti,sci-dev-id = <199>;
- ti,sci-rm-range-rchan = <0x21>;
- };
- };
-
- dmsc: system-controller@44043000 {
- compatible = "ti,k2g-sci";
- ti,host-id = <12>;
- mbox-names = "rx", "tx";
- mboxes = <&secure_proxy_main 12>,
- <&secure_proxy_main 13>;
- reg-names = "debug_messages";
- reg = <0x00 0x44043000 0x00 0xfe0>;
- bootph-all;
-
- k3_pds: power-controller {
- compatible = "ti,sci-pm-domain";
- #power-domain-cells = <2>;
- bootph-all;
- };
-
- k3_clks: clock-controller {
- compatible = "ti,k2g-sci-clk";
- #clock-cells = <2>;
- bootph-all;
- };
-
- k3_reset: reset-controller {
- compatible = "ti,sci-reset";
- #reset-cells = <2>;
- bootph-all;
- };
- };
-
- crypto: crypto@40900000 {
- compatible = "ti,am62-sa3ul";
- reg = <0x00 0x40900000 0x00 0x1200>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x00 0x40900000 0x00 0x40900000 0x00 0x30000>;
-
- dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>,
- <&main_pktdma 0x7507 0>;
- dma-names = "tx", "rx1", "rx2";
- };
-
- secure_proxy_sa3: mailbox@43600000 {
- compatible = "ti,am654-secure-proxy";
- #mbox-cells = <1>;
- reg-names = "target_data", "rt", "scfg";
- reg = <0x00 0x43600000 0x00 0x10000>,
- <0x00 0x44880000 0x00 0x20000>,
- <0x00 0x44860000 0x00 0x20000>;
- /*
- * Marked Disabled:
- * Node is incomplete as it is meant for bootloaders and
- * firmware on non-MPU processors
- */
- status = "disabled";
- bootph-all;
- };
-
- main_pmx0: pinctrl@f4000 {
- compatible = "pinctrl-single";
- reg = <0x00 0xf4000 0x00 0x2ac>;
- #pinctrl-cells = <1>;
- pinctrl-single,register-width = <32>;
- pinctrl-single,function-mask = <0xffffffff>;
- bootph-all;
- };
-
- main_esm: esm@420000 {
- compatible = "ti,j721e-esm";
- reg = <0x00 0x420000 0x00 0x1000>;
- ti,esm-pins = <160>, <161>, <162>, <163>, <177>, <178>;
- bootph-pre-ram;
- };
-
- main_timer0: timer@2400000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2400000 0x00 0x400>;
- interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 36 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 36 2>;
- assigned-clock-parents = <&k3_clks 36 3>;
- power-domains = <&k3_pds 36 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- bootph-all;
- };
-
- main_timer1: timer@2410000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2410000 0x00 0x400>;
- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 37 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 37 2>;
- assigned-clock-parents = <&k3_clks 37 3>;
- power-domains = <&k3_pds 37 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_timer2: timer@2420000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2420000 0x00 0x400>;
- interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 38 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 38 2>;
- assigned-clock-parents = <&k3_clks 38 3>;
- power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_timer3: timer@2430000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2430000 0x00 0x400>;
- interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 39 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 39 2>;
- assigned-clock-parents = <&k3_clks 39 3>;
- power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_timer4: timer@2440000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2440000 0x00 0x400>;
- interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 40 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 40 2>;
- assigned-clock-parents = <&k3_clks 40 3>;
- power-domains = <&k3_pds 40 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_timer5: timer@2450000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2450000 0x00 0x400>;
- interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 41 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 41 2>;
- assigned-clock-parents = <&k3_clks 41 3>;
- power-domains = <&k3_pds 41 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_timer6: timer@2460000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2460000 0x00 0x400>;
- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 42 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 42 2>;
- assigned-clock-parents = <&k3_clks 42 3>;
- power-domains = <&k3_pds 42 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_timer7: timer@2470000 {
- compatible = "ti,am654-timer";
- reg = <0x00 0x2470000 0x00 0x400>;
- interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 43 2>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 43 2>;
- assigned-clock-parents = <&k3_clks 43 3>;
- power-domains = <&k3_pds 43 TI_SCI_PD_EXCLUSIVE>;
- ti,timer-pwm;
- };
-
- main_uart0: serial@2800000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02800000 0x00 0x100>;
- interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 146 0>;
- clock-names = "fclk";
- status = "disabled";
- };
-
- main_uart1: serial@2810000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02810000 0x00 0x100>;
- interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 152 0>;
- clock-names = "fclk";
- status = "disabled";
- };
-
- main_uart2: serial@2820000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02820000 0x00 0x100>;
- interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 153 0>;
- clock-names = "fclk";
status = "disabled";
- };
- main_uart3: serial@2830000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02830000 0x00 0x100>;
- interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 154 0>;
- clock-names = "fclk";
- status = "disabled";
- };
-
- main_uart4: serial@2840000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02840000 0x00 0x100>;
- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 155 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 155 0>;
- clock-names = "fclk";
- status = "disabled";
- };
-
- main_uart5: serial@2850000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02850000 0x00 0x100>;
- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 156 0>;
- clock-names = "fclk";
- status = "disabled";
- };
-
- main_uart6: serial@2860000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x02860000 0x00 0x100>;
- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 158 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 158 0>;
- clock-names = "fclk";
- status = "disabled";
- };
-
- main_i2c0: i2c@20000000 {
- compatible = "ti,am64-i2c", "ti,omap4-i2c";
- reg = <0x00 0x20000000 0x00 0x100>;
- interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 102 2>;
- clock-names = "fck";
- status = "disabled";
- };
-
- main_i2c1: i2c@20010000 {
- compatible = "ti,am64-i2c", "ti,omap4-i2c";
- reg = <0x00 0x20010000 0x00 0x100>;
- interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 103 2>;
- clock-names = "fck";
- status = "disabled";
- };
-
- main_i2c2: i2c@20020000 {
- compatible = "ti,am64-i2c", "ti,omap4-i2c";
- reg = <0x00 0x20020000 0x00 0x100>;
- interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 104 2>;
- clock-names = "fck";
- status = "disabled";
- };
-
- main_i2c3: i2c@20030000 {
- compatible = "ti,am64-i2c", "ti,omap4-i2c";
- reg = <0x00 0x20030000 0x00 0x100>;
- interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 105 2>;
- clock-names = "fck";
- status = "disabled";
- };
-
- main_spi0: spi@20100000 {
- compatible = "ti,am654-mcspi", "ti,omap4-mcspi";
- reg = <0x00 0x20100000 0x00 0x400>;
- interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 141 0>;
- status = "disabled";
- };
-
- main_spi1: spi@20110000 {
- compatible = "ti,am654-mcspi","ti,omap4-mcspi";
- reg = <0x00 0x20110000 0x00 0x400>;
- interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 142 0>;
- status = "disabled";
- };
-
- main_spi2: spi@20120000 {
- compatible = "ti,am654-mcspi","ti,omap4-mcspi";
- reg = <0x00 0x20120000 0x00 0x400>;
- interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 143 0>;
- status = "disabled";
- };
-
- main_gpio_intr: interrupt-controller@a00000 {
- compatible = "ti,sci-intr";
- reg = <0x00 0x00a00000 0x00 0x800>;
- ti,intr-trigger-type = <1>;
- interrupt-controller;
- interrupt-parent = <&gic500>;
- #interrupt-cells = <1>;
- ti,sci = <&dmsc>;
- ti,sci-dev-id = <3>;
- ti,interrupt-ranges = <0 32 16>;
- };
-
- main_gpio0: gpio@600000 {
- compatible = "ti,am64-gpio", "ti,keystone-gpio";
- reg = <0x00 0x00600000 0x00 0x100>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-parent = <&main_gpio_intr>;
- interrupts = <190>, <191>, <192>,
- <193>, <194>, <195>;
- interrupt-controller;
- #interrupt-cells = <2>;
- ti,ngpio = <92>;
- ti,davinci-gpio-unbanked = <0>;
- power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 77 0>;
- clock-names = "gpio";
- };
-
- main_gpio1: gpio@601000 {
- compatible = "ti,am64-gpio", "ti,keystone-gpio";
- reg = <0x00 0x00601000 0x00 0x100>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-parent = <&main_gpio_intr>;
- interrupts = <180>, <181>, <182>,
- <183>, <184>, <185>;
- interrupt-controller;
- #interrupt-cells = <2>;
- ti,ngpio = <52>;
- ti,davinci-gpio-unbanked = <0>;
- power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 78 0>;
- clock-names = "gpio";
- };
-
- sdhci0: mmc@fa10000 {
- compatible = "ti,am64-sdhci-8bit";
- reg = <0x00 0x0fa10000 0x00 0x1000>, <0x00 0x0fa18000 0x00 0x400>;
- interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 57 1>, <&k3_clks 57 2>;
- clock-names = "clk_ahb", "clk_xin";
- assigned-clocks = <&k3_clks 57 2>;
- assigned-clock-parents = <&k3_clks 57 4>;
- bus-width = <8>;
- mmc-ddr-1_8v;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- ti,clkbuf-sel = <0x7>;
- ti,strobe-sel = <0x77>;
- ti,trm-icp = <0x8>;
- ti,otap-del-sel-legacy = <0x1>;
- ti,otap-del-sel-mmc-hs = <0x1>;
- ti,otap-del-sel-ddr52 = <0x6>;
- ti,otap-del-sel-hs200 = <0x8>;
- ti,otap-del-sel-hs400 = <0x5>;
- ti,itap-del-sel-legacy = <0x10>;
- ti,itap-del-sel-mmc-hs = <0xa>;
- ti,itap-del-sel-ddr52 = <0x3>;
- status = "disabled";
- };
-
- sdhci1: mmc@fa00000 {
- compatible = "ti,am62-sdhci";
- reg = <0x00 0x0fa00000 0x00 0x1000>, <0x00 0x0fa08000 0x00 0x400>;
- interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
- clock-names = "clk_ahb", "clk_xin";
- bus-width = <4>;
- ti,clkbuf-sel = <0x7>;
- 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-ddr50 = <0x9>;
- ti,otap-del-sel-sdr104 = <0x6>;
- ti,itap-del-sel-legacy = <0x0>;
- ti,itap-del-sel-sd-hs = <0x0>;
- ti,itap-del-sel-sdr12 = <0x0>;
- ti,itap-del-sel-sdr25 = <0x0>;
- status = "disabled";
- };
-
- sdhci2: mmc@fa20000 {
- compatible = "ti,am62-sdhci";
- reg = <0x00 0x0fa20000 0x00 0x1000>, <0x00 0x0fa28000 0x00 0x400>;
- interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
- power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
- clock-names = "clk_ahb", "clk_xin";
- bus-width = <4>;
- ti,clkbuf-sel = <0x7>;
- 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-ddr50 = <0x9>;
- ti,otap-del-sel-sdr104 = <0x6>;
- ti,itap-del-sel-legacy = <0x0>;
- ti,itap-del-sel-sd-hs = <0x0>;
- ti,itap-del-sel-sdr12 = <0x0>;
- ti,itap-del-sel-sdr25 = <0x0>;
- status = "disabled";
- };
-
- fss: bus@fc00000 {
- compatible = "simple-bus";
- reg = <0x00 0x0fc00000 0x00 0x70000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- ospi0: spi@fc40000 {
- compatible = "ti,am654-ospi", "cdns,qspi-nor";
- reg = <0x00 0x0fc40000 0x00 0x100>,
- <0x05 0x00000000 0x01 0x00000000>;
- interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
- cdns,fifo-depth = <256>;
- cdns,fifo-width = <4>;
- cdns,trigger-address = <0x0>;
- clocks = <&k3_clks 75 7>;
- assigned-clocks = <&k3_clks 75 7>;
- assigned-clock-parents = <&k3_clks 75 8>;
- assigned-clock-rates = <166666666>;
- power-domains = <&k3_pds 75 TI_SCI_PD_EXCLUSIVE>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+ usb1: usb@31100000 {
+ compatible = "snps,dwc3";
+ reg = <0x00 0x31100000 0x00 0x50000>;
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+ <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+ interrupt-names = "host", "peripheral";
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ snps,usb2-gadget-lpm-disable;
+ snps,usb2-lpm-disable;
};
};
+};
- cpsw3g: ethernet@8000000 {
- compatible = "ti,am642-cpsw-nuss";
- #address-cells = <2>;
- #size-cells = <2>;
- reg = <0x00 0x08000000 0x00 0x200000>;
- reg-names = "cpsw_nuss";
- ranges = <0x00 0x00 0x00 0x08000000 0x00 0x200000>;
- clocks = <&k3_clks 13 0>;
- assigned-clocks = <&k3_clks 13 3>;
- assigned-clock-parents = <&k3_clks 13 11>;
- clock-names = "fck";
- power-domains = <&k3_pds 13 TI_SCI_PD_EXCLUSIVE>;
-
- dmas = <&main_pktdma 0xc600 15>,
- <&main_pktdma 0xc601 15>,
- <&main_pktdma 0xc602 15>,
- <&main_pktdma 0xc603 15>,
- <&main_pktdma 0xc604 15>,
- <&main_pktdma 0xc605 15>,
- <&main_pktdma 0xc606 15>,
- <&main_pktdma 0xc607 15>,
- <&main_pktdma 0x4600 15>;
- 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";
- phys = <&phy_gmii_sel 1>;
- mac-address = [00 00 00 00 00 00];
- };
-
- cpsw_port2: port@2 {
- reg = <2>;
- ti,mac-only;
- label = "port2";
- phys = <&phy_gmii_sel 2>;
- mac-address = [00 00 00 00 00 00];
- };
- };
-
- cpsw3g_mdio: mdio@f00 {
- compatible = "ti,cpsw-mdio","ti,davinci_mdio";
- reg = <0x00 0xf00 0x00 0x100>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&k3_clks 13 0>;
- clock-names = "fck";
- bus_freq = <1000000>;
- status = "disabled";
- };
-
- cpts@3d000 {
- compatible = "ti,j721e-cpts";
- reg = <0x00 0x3d000 0x00 0x400>;
- clocks = <&k3_clks 13 3>;
- clock-names = "cpts";
- interrupts-extended = <&gic500 GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "cpts";
- ti,cpts-ext-ts-inputs = <4>;
- ti,cpts-periodic-outputs = <2>;
- };
- };
-
- hwspinlock: spinlock@2a000000 {
- compatible = "ti,am64-hwspinlock";
- reg = <0x00 0x2a000000 0x00 0x1000>;
- #hwlock-cells = <1>;
- };
-
- mailbox0_cluster0: mailbox@29000000 {
- compatible = "ti,am64-mailbox";
- reg = <0x00 0x29000000 0x00 0x200>;
- interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
- #mbox-cells = <1>;
- ti,mbox-num-users = <4>;
- ti,mbox-num-fifos = <16>;
- };
-
- mailbox0_cluster1: mailbox@29010000 {
- compatible = "ti,am64-mailbox";
- reg = <0x00 0x29010000 0x00 0x200>;
- interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
- #mbox-cells = <1>;
- ti,mbox-num-users = <4>;
- ti,mbox-num-fifos = <16>;
- };
-
- mailbox0_cluster2: mailbox@29020000 {
- compatible = "ti,am64-mailbox";
- reg = <0x00 0x29020000 0x00 0x200>;
- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
- #mbox-cells = <1>;
- ti,mbox-num-users = <4>;
- ti,mbox-num-fifos = <16>;
- };
-
- mailbox0_cluster3: mailbox@29030000 {
- compatible = "ti,am64-mailbox";
- reg = <0x00 0x29030000 0x00 0x200>;
- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
- #mbox-cells = <1>;
- ti,mbox-num-users = <4>;
- ti,mbox-num-fifos = <16>;
- };
-
- ecap0: pwm@23100000 {
- compatible = "ti,am3352-ecap";
- #pwm-cells = <3>;
- reg = <0x00 0x23100000 0x00 0x100>;
- power-domains = <&k3_pds 51 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 51 0>;
- clock-names = "fck";
- status = "disabled";
- };
-
- ecap1: pwm@23110000 {
- compatible = "ti,am3352-ecap";
- #pwm-cells = <3>;
- reg = <0x00 0x23110000 0x00 0x100>;
- power-domains = <&k3_pds 52 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 52 0>;
- clock-names = "fck";
- status = "disabled";
- };
-
- ecap2: pwm@23120000 {
- compatible = "ti,am3352-ecap";
- #pwm-cells = <3>;
- reg = <0x00 0x23120000 0x00 0x100>;
- power-domains = <&k3_pds 53 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 53 0>;
- clock-names = "fck";
- status = "disabled";
- };
-
- main_mcan0: can@20701000 {
- compatible = "bosch,m_can";
- reg = <0x00 0x20701000 0x00 0x200>,
- <0x00 0x20708000 0x00 0x8000>;
- reg-names = "m_can", "message_ram";
- power-domains = <&k3_pds 98 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 98 6>, <&k3_clks 98 1>;
- clock-names = "hclk", "cclk";
- interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "int0", "int1";
- bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
- status = "disabled";
- };
-
- main_mcan1: can@20711000 {
- compatible = "bosch,m_can";
- reg = <0x00 0x20711000 0x00 0x200>,
- <0x00 0x20718000 0x00 0x8000>;
- reg-names = "m_can", "message_ram";
- power-domains = <&k3_pds 99 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 99 6>, <&k3_clks 99 1>;
- clock-names = "hclk", "cclk";
- interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "int0", "int1";
- bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
- status = "disabled";
- };
-
- main_rti0: watchdog@e000000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0x0e000000 0x00 0x100>;
- clocks = <&k3_clks 125 0>;
- power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 125 0>;
- assigned-clock-parents = <&k3_clks 125 2>;
- };
-
- main_rti1: watchdog@e010000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0x0e010000 0x00 0x100>;
- clocks = <&k3_clks 126 0>;
- power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 126 0>;
- assigned-clock-parents = <&k3_clks 126 2>;
- };
-
- main_rti2: watchdog@e020000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0x0e020000 0x00 0x100>;
- clocks = <&k3_clks 127 0>;
- power-domains = <&k3_pds 127 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 127 0>;
- assigned-clock-parents = <&k3_clks 127 2>;
- };
-
- main_rti3: watchdog@e030000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0x0e030000 0x00 0x100>;
- clocks = <&k3_clks 128 0>;
- power-domains = <&k3_pds 128 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 128 0>;
- assigned-clock-parents = <&k3_clks 128 2>;
- };
-
- main_rti15: watchdog@e0f0000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0x0e0f0000 0x00 0x100>;
- clocks = <&k3_clks 130 0>;
- power-domains = <&k3_pds 130 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 130 0>;
- assigned-clock-parents = <&k3_clks 130 2>;
- };
-
- epwm0: pwm@23000000 {
- compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
- #pwm-cells = <3>;
- reg = <0x00 0x23000000 0x00 0x100>;
- power-domains = <&k3_pds 86 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&epwm_tbclk 0>, <&k3_clks 86 0>;
- clock-names = "tbclk", "fck";
- status = "disabled";
- };
-
- epwm1: pwm@23010000 {
- compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
- #pwm-cells = <3>;
- reg = <0x00 0x23010000 0x00 0x100>;
- power-domains = <&k3_pds 87 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&epwm_tbclk 1>, <&k3_clks 87 0>;
- clock-names = "tbclk", "fck";
- status = "disabled";
- };
-
- epwm2: pwm@23020000 {
- compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
- #pwm-cells = <3>;
- reg = <0x00 0x23020000 0x00 0x100>;
- power-domains = <&k3_pds 88 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&epwm_tbclk 2>, <&k3_clks 88 0>;
- clock-names = "tbclk", "fck";
- status = "disabled";
- };
-
- mcasp0: audio-controller@2b00000 {
- compatible = "ti,am33xx-mcasp-audio";
- reg = <0x00 0x02b00000 0x00 0x2000>,
- <0x00 0x02b08000 0x00 0x400>;
- reg-names = "mpu", "dat";
- interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx", "rx";
-
- dmas = <&main_bcdma 0 0xc500 0>, <&main_bcdma 0 0x4500 0>;
- dma-names = "tx", "rx";
-
- clocks = <&k3_clks 190 0>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 190 0>;
- assigned-clock-parents = <&k3_clks 190 2>;
- power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
- status = "disabled";
- };
-
- mcasp1: audio-controller@2b10000 {
- compatible = "ti,am33xx-mcasp-audio";
- reg = <0x00 0x02b10000 0x00 0x2000>,
- <0x00 0x02b18000 0x00 0x400>;
- reg-names = "mpu", "dat";
- interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx", "rx";
-
- dmas = <&main_bcdma 0 0xc501 0>, <&main_bcdma 0 0x4501 0>;
- dma-names = "tx", "rx";
-
- clocks = <&k3_clks 191 0>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 191 0>;
- assigned-clock-parents = <&k3_clks 191 2>;
- power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
- status = "disabled";
- };
-
- mcasp2: audio-controller@2b20000 {
- compatible = "ti,am33xx-mcasp-audio";
- reg = <0x00 0x02b20000 0x00 0x2000>,
- <0x00 0x02b28000 0x00 0x400>;
- reg-names = "mpu", "dat";
- interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx", "rx";
-
- dmas = <&main_bcdma 0 0xc502 0>, <&main_bcdma 0 0x4502 0>;
- dma-names = "tx", "rx";
-
- clocks = <&k3_clks 192 0>;
- clock-names = "fck";
- assigned-clocks = <&k3_clks 192 0>;
- assigned-clock-parents = <&k3_clks 192 2>;
- power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
- status = "disabled";
- };
-
- ti_csi2rx0: ticsi2rx@30102000 {
- compatible = "ti,j721e-csi2rx-shim";
- reg = <0x00 0x30102000 0x00 0x1000>;
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
- dmas = <&main_bcdma_csi 0 0x5000 0>;
- dma-names = "rx0";
- power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
- status = "disabled";
-
- cdns_csi2rx0: csi-bridge@30101000 {
- compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
- reg = <0x00 0x30101000 0x00 0x1000>;
- clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
- <&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
- clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
- "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
- phys = <&dphy0>;
- phy-names = "dphy";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- csi0_port0: port@0 {
- reg = <0>;
- status = "disabled";
- };
-
- csi0_port1: port@1 {
- reg = <1>;
- status = "disabled";
- };
+&oc_sram {
+ reg = <0x00 0x70000000 0x00 0x10000>;
+ ranges = <0x00 0x00 0x70000000 0x10000>;
+};
- csi0_port2: port@2 {
- reg = <2>;
- status = "disabled";
- };
+&inta_main_dmss {
+ ti,interrupt-ranges = <5 69 35>;
+};
- csi0_port3: port@3 {
- reg = <3>;
- status = "disabled";
- };
+&main_pmx0 {
+ pinctrl-single,gpio-range =
+ <&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 33 92 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 137 5 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 143 3 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 149 2 PIN_GPIO_RANGE_IOPAD>;
- csi0_port4: port@4 {
- reg = <4>;
- status = "disabled";
- };
- };
- };
+ main_pmx0_range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
};
+};
- dphy0: phy@30110000 {
- compatible = "cdns,dphy-rx";
- reg = <0x00 0x30110000 0x00 0x1100>;
- #phy-cells = <0>;
- power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
- status = "disabled";
- };
+&main_gpio0 {
+ gpio-ranges = <&main_pmx0 0 0 32>, <&main_pmx0 32 33 38>,
+ <&main_pmx0 70 72 22>;
+ ti,ngpio = <92>;
+};
- vpu: video-codec@30210000 {
- compatible = "ti,j721s2-wave521c", "cnm,wave521c";
- reg = <0x00 0x30210000 0x00 0x10000>;
- interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&k3_clks 204 2>;
- power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
- };
+&main_gpio1 {
+ gpio-ranges = <&main_pmx0 0 94 32>, <&main_pmx0 42 137 5>,
+ <&main_pmx0 47 143 3>, <&main_pmx0 50 149 2>;
+ ti,ngpio = <52>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index 94babc412575..75a15c368c11 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -116,10 +116,13 @@
};
};
- #include "k3-am62p-thermal.dtsi"
+ #include "k3-am62p-j722s-common-thermal.dtsi"
};
/* Now include peripherals for each bus segment */
+#include "k3-am62p-j722s-common-main.dtsi"
+#include "k3-am62p-j722s-common-mcu.dtsi"
+#include "k3-am62p-j722s-common-wakeup.dtsi"
+
+/* Include AM62P specific peripherals */
#include "k3-am62p-main.dtsi"
-#include "k3-am62p-mcu.dtsi"
-#include "k3-am62p-wakeup.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index e86f34e835c1..ff65955551a3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -27,6 +27,8 @@
spi0 = &ospi0;
ethernet0 = &cpsw_port1;
ethernet1 = &cpsw_port2;
+ usb0 = &usb0;
+ usb1 = &usb1;
};
chosen {
@@ -205,7 +207,7 @@
pinctrl-single,pins = <
AM62PX_IOPAD(0x0090, PIN_INPUT, 2) /* (U24) GPMC0_BE0n_CLE.MCASP1_ACLKX */
AM62PX_IOPAD(0x0098, PIN_INPUT, 2) /* (AA24) GPMC0_WAIT0.MCASP1_AFSX */
- AM62PX_IOPAD(0x008c, PIN_INPUT, 2) /* (T25) GPMC0_WEn.MCASP1_AXR0 */
+ AM62PX_IOPAD(0x008c, PIN_OUTPUT, 2) /* (T25) GPMC0_WEn.MCASP1_AXR0 */
AM62PX_IOPAD(0x0084, PIN_INPUT, 2) /* (R25) GPMC0_ADVn_ALE.MCASP1_AXR2 */
>;
};
@@ -297,6 +299,12 @@
bootph-all;
};
+ main_usb1_pins_default: main-usb1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+ >;
+ };
+
main_wlirq_pins_default: main-wlirq-default-pins {
pinctrl-single,pins = <
AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
@@ -340,6 +348,31 @@
};
};
+&main_i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c0_pins_default>;
+ clock-frequency = <400000>;
+
+ typec_pd0: usb-power-controller@3f {
+ compatible = "ti,tps6598x";
+ reg = <0x3f>;
+
+ connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ self-powered;
+ data-role = "dual";
+ power-role = "sink";
+ port {
+ usb_con_hs: endpoint {
+ remote-endpoint = <&usb0_hs_ep>;
+ };
+ };
+ };
+ };
+};
+
&main_i2c1 {
status = "okay";
pinctrl-names = "default";
@@ -431,16 +464,19 @@
pinctrl-names = "default";
pinctrl-0 = <&main_rgmii1_pins_default>,
<&main_rgmii2_pins_default>;
+ status = "okay";
};
&cpsw_port1 {
phy-mode = "rgmii-rxid";
phy-handle = <&cpsw3g_phy0>;
+ status = "okay";
};
&cpsw_port2 {
phy-mode = "rgmii-rxid";
phy-handle = <&cpsw3g_phy1>;
+ status = "okay";
};
&cpsw3g_mdio {
@@ -463,6 +499,32 @@
};
};
+&usbss0 {
+ status = "okay";
+ ti,vbus-divider;
+};
+
+&usbss1 {
+ status = "okay";
+ ti,vbus-divider;
+};
+
+&usb0 {
+ usb-role-switch;
+
+ port {
+ usb0_hs_ep: endpoint {
+ remote-endpoint = <&usb_con_hs>;
+ };
+ };
+};
+
+&usb1 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_usb1_pins_default>;
+};
+
&mcasp1 {
status = "okay";
#sound-dai-cells = <0>;
@@ -479,8 +541,6 @@
0 0 0 0
0 0 0 0
>;
- tx-num-evt = <32>;
- rx-num-evt = <32>;
};
&fss {
@@ -493,7 +553,7 @@
pinctrl-0 = <&ospi0_pins_default>;
bootph-all;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi
new file mode 100644
index 000000000000..e4633af87eb9
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi
@@ -0,0 +1,475 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2022-2024 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.egorov@phytec.de>
+ *
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+ aliases {
+ serial2 = &main_uart0;
+ serial3 = &main_uart1;
+ mmc1 = &sdhci1;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ ethernet1 = &cpsw_port2;
+ };
+
+ can_tc1: can-phy0 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <8000000>;
+ standby-gpios = <&gpio_exp 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ hdmi0: connector-hdmi {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&sii9022_out>;
+ };
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+ autorepeat;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pins_default>;
+
+ key-home {
+ label = "home";
+ linux,code = <KEY_HOME>;
+ gpios = <&main_gpio1 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ key-menu {
+ label = "menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&gpio_exp 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "phyBOARD-Lyra";
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Headphone", "Headphone Jack",
+ "Speaker", "External Speaker";
+ simple-audio-card,routing =
+ "MIC3R", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "External Speaker", "SPOP",
+ "External Speaker", "SPOM";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound_master>;
+ simple-audio-card,frame-master = <&sound_master>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp2>;
+ };
+
+ sound_master: simple-audio-card,codec {
+ sound-dai = <&audio_codec>;
+ clocks = <&audio_refclk1>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins_default>, <&user_leds_pins_default>;
+
+ led-1 {
+ gpios = <&main_gpio0 32 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ };
+
+ led-2 {
+ gpios = <&gpio_exp 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc1";
+ };
+ };
+
+ vcc_1v8: regulator-vcc-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_3v3_mmc: regulator-vcc-3v3-mmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3_MMC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_3v3_sw: regulator-vcc-3v3-sw {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3_SW";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&main_pmx0 {
+ audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x0a0, PIN_OUTPUT, 1) /* (K25) GPMC0_WPn.AUDIO_EXT_REFCLK1 */
+ >;
+ };
+
+ gpio_keys_pins_default: gpio-keys-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1d4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
+ >;
+ };
+
+ gpio_exp_int_pins_default: gpio-exp-int-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x244, PIN_INPUT, 7) /* (C17) MMC1_SDWP.GPIO1_49 */
+ >;
+ };
+
+ hdmi_int_pins_default: hdmi-int-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x040, PIN_INPUT, 7) /* (N23) GPMC0_AD1.GPIO0_16 */
+ >;
+ };
+
+ main_dss0_pins_default: main-dss0-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x0b8, PIN_OUTPUT, 0) /* (U22) VOUT0_DATA0 */
+ AM62X_IOPAD(0x0bc, PIN_OUTPUT, 0) /* (V24) VOUT0_DATA1 */
+ AM62X_IOPAD(0x0e0, PIN_OUTPUT, 0) /* (V20) VOUT0_DATA10 */
+ AM62X_IOPAD(0x0e4, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA11 */
+ AM62X_IOPAD(0x0e8, PIN_OUTPUT, 0) /* (AB25) VOUT0_DATA12 */
+ AM62X_IOPAD(0x0ec, PIN_OUTPUT, 0) /* (AA24) VOUT0_DATA13 */
+ AM62X_IOPAD(0x0f0, PIN_OUTPUT, 0) /* (Y22) VOUT0_DATA14 */
+ AM62X_IOPAD(0x0f4, PIN_OUTPUT, 0) /* (AA21) VOUT0_DATA15 */
+ AM62X_IOPAD(0x0c0, PIN_OUTPUT, 0) /* (W25) VOUT0_DATA2 */
+ AM62X_IOPAD(0x0c4, PIN_OUTPUT, 0) /* (W24) VOUT0_DATA3 */
+ AM62X_IOPAD(0x0c8, PIN_OUTPUT, 0) /* (Y25) VOUT0_DATA4 */
+ AM62X_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (Y24) VOUT0_DATA5 */
+ AM62X_IOPAD(0x0d0, PIN_OUTPUT, 0) /* (Y23) VOUT0_DATA6 */
+ AM62X_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (AA25) VOUT0_DATA7 */
+ AM62X_IOPAD(0x0d8, PIN_OUTPUT, 0) /* (V21) VOUT0_DATA8 */
+ AM62X_IOPAD(0x0dc, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA9 */
+ AM62X_IOPAD(0x0fc, PIN_OUTPUT, 0) /* (Y20) VOUT0_DE */
+ AM62X_IOPAD(0x0f8, PIN_OUTPUT, 0) /* (AB24) VOUT0_HSYNC */
+ AM62X_IOPAD(0x104, PIN_OUTPUT, 0) /* (AC24) VOUT0_PCLK */
+ AM62X_IOPAD(0x100, PIN_OUTPUT, 0) /* (AC25) VOUT0_VSYNC */
+ >;
+ };
+
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1e8, PIN_INPUT_PULLUP, 0) /* (B17) I2C1_SCL */
+ AM62X_IOPAD(0x1ec, PIN_INPUT_PULLUP, 0) /* (A17) I2C1_SDA */
+ >;
+ };
+
+ main_mcan0_pins_default: main-mcan0-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1dc, PIN_INPUT, 0) /* (E15) MCAN0_RX */
+ AM62X_IOPAD(0x1d8, PIN_OUTPUT, 0) /* (C15) MCAN0_TX */
+ >;
+ };
+
+ main_mcasp2_pins_default: main-mcasp2-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x070, PIN_INPUT, 3) /* (T24) GPMC0_AD13.MCASP2_ACLKX */
+ AM62X_IOPAD(0x06c, PIN_INPUT, 3) /* (T22) GPMC0_AD12.MCASP2_AFSX */
+ AM62X_IOPAD(0x064, PIN_OUTPUT, 3) /* (T25) GPMC0_AD10.MCASP2_AXR2 */
+ AM62X_IOPAD(0x068, PIN_INPUT, 3) /* (R21) GPMC0_AD11.MCASP2_AXR3 */
+ >;
+ };
+
+ main_mmc1_pins_default: main-mmc1-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x23c, PIN_INPUT_PULLUP, 0) /* (A21) MMC1_CMD */
+ AM62X_IOPAD(0x234, PIN_INPUT_PULLDOWN, 0) /* (B22) MMC1_CLK */
+ AM62X_IOPAD(0x230, PIN_INPUT_PULLUP, 0) /* (A22) MMC1_DAT0 */
+ AM62X_IOPAD(0x22c, PIN_INPUT_PULLUP, 0) /* (B21) MMC1_DAT1 */
+ AM62X_IOPAD(0x228, PIN_INPUT_PULLUP, 0) /* (C21) MMC1_DAT2 */
+ AM62X_IOPAD(0x224, PIN_INPUT_PULLUP, 0) /* (D22) MMC1_DAT3 */
+ AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 0) /* (D17) MMC1_SDCD */
+ >;
+ };
+
+ main_rgmii2_pins_default: main-rgmii2-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x184, PIN_INPUT, 0) /* (AE23) RGMII2_RD0 */
+ AM62X_IOPAD(0x188, PIN_INPUT, 0) /* (AB20) RGMII2_RD1 */
+ AM62X_IOPAD(0x18c, PIN_INPUT, 0) /* (AC21) RGMII2_RD2 */
+ AM62X_IOPAD(0x190, PIN_INPUT, 0) /* (AE22) RGMII2_RD3 */
+ AM62X_IOPAD(0x180, PIN_INPUT, 0) /* (AD23) RGMII2_RXC */
+ AM62X_IOPAD(0x17c, PIN_INPUT, 0) /* (AD22) RGMII2_RX_CTL */
+ AM62X_IOPAD(0x16c, PIN_OUTPUT, 0) /* (Y18) RGMII2_TD0 */
+ AM62X_IOPAD(0x170, PIN_OUTPUT, 0) /* (AA18) RGMII2_TD1 */
+ AM62X_IOPAD(0x174, PIN_OUTPUT, 0) /* (AD21) RGMII2_TD2 */
+ AM62X_IOPAD(0x178, PIN_OUTPUT, 0) /* (AC20) RGMII2_TD3 */
+ AM62X_IOPAD(0x168, PIN_OUTPUT, 0) /* (AE21) RGMII2_TXC */
+ AM62X_IOPAD(0x164, PIN_OUTPUT, 0) /* (AA19) RGMII2_TX_CTL */
+ >;
+ };
+
+ main_uart0_pins_default: main-uart0-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14) UART0_RXD */
+ AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */
+ >;
+ };
+
+ main_uart1_pins_default: main-uart1-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x194, PIN_INPUT, 2) /* (B19) MCASP0_AXR3.UART1_CTSn */
+ AM62X_IOPAD(0x198, PIN_OUTPUT, 2) /* (A19) MCASP0_AXR2.UART1_RTSn */
+ AM62X_IOPAD(0x1ac, PIN_INPUT, 2) /* (E19) MCASP0_AFSR.UART1_RXD */
+ AM62X_IOPAD(0x1b0, PIN_OUTPUT, 2) /* (A20) MCASP0_ACLKR.UART1_TXD */
+ >;
+ };
+
+ main_usb1_pins_default: main-usb1-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x258, PIN_OUTPUT, 0) /* (F18) USB1_DRVVBUS */
+ >;
+ };
+
+ user_leds_pins_default: user-leds-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x084, PIN_OUTPUT, 7) /* (L23) GPMC0_ADVn_ALE.GPIO0_32 */
+ >;
+ };
+};
+
+&cpsw3g {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_rgmii1_pins_default>, <&main_rgmii2_pins_default>;
+};
+
+&cpsw_port2 {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&cpsw3g_phy3>;
+};
+
+&cpsw3g_mdio {
+ cpsw3g_phy3: ethernet-phy@3 {
+ compatible = "ethernet-phy-id2000.a231", "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_dss0_pins_default>;
+ status = "okay";
+};
+
+&dss_ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* VP2: DPI/HDMI Output */
+ port@1 {
+ reg = <1>;
+
+ dpi1_out: endpoint {
+ remote-endpoint = <&sii9022_in>;
+ };
+ };
+};
+
+&main_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ audio_codec: audio-codec@18 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3007";
+ reg = <0x18>;
+ ai3x-micbias-vg = <2>;
+
+ AVDD-supply = <&vcc_3v3_sw>;
+ IOVDD-supply = <&vcc_3v3_sw>;
+ DRVDD-supply = <&vcc_3v3_sw>;
+ DVDD-supply = <&vcc_1v8>;
+ };
+
+ gpio_exp: gpio-expander@21 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_exp_int_pins_default>;
+ compatible = "nxp,pcf8574";
+ reg = <0x21>;
+ interrupt-parent = <&main_gpio1>;
+ interrupts = <49 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-line-names = "", "GPIO1_CAN0_nEN",
+ "GPIO2_LED2", "GPIO3_LVDS_GPIO",
+ "GPIO4_BUT2", "GPIO5_LVDS_BKLT_EN",
+ "GPIO6_ETH1_USER_RESET", "GPIO7_AUDIO_USER_RESET";
+ };
+
+ usb-pd@22 {
+ compatible = "ti,tps6598x";
+ reg = <0x22>;
+
+ connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ self-powered;
+ data-role = "dual";
+ power-role = "sink";
+ port {
+ usb_con_hs: endpoint {
+ remote-endpoint = <&typec_hs>;
+ };
+ };
+ };
+ };
+
+ sii9022: bridge-hdmi@39 {
+ compatible = "sil,sii9022";
+ reg = <0x39>;
+
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_int_pins_default>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ sii9022_in: endpoint {
+ remote-endpoint = <&dpi1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ sii9022_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c02";
+ pagesize = <16>;
+ reg = <0x51>;
+ };
+};
+
+&main_mcan0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan0_pins_default>;
+ phys = <&can_tc1>;
+ status = "okay";
+};
+
+&main_uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart0_pins_default>;
+ status = "okay";
+};
+
+&main_uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart1_pins_default>;
+ /* Main UART1 may be used by TIFS firmware */
+ status = "okay";
+};
+
+&mcasp2 {
+ #sound-dai-cells = <0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp2_pins_default>;
+
+ /* MCASP_IIS_MODE */
+ op-mode = <0>;
+ tdm-slots = <2>;
+
+ /* 0: INACTIVE, 1: TX, 2: RX */
+ serial-dir = <
+ 0 0 1 2
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+ status = "okay";
+};
+
+&sdhci1 {
+ vmmc-supply = <&vcc_3v3_mmc>;
+ vqmmc-supply = <&vddshv5_sdio>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc1_pins_default>;
+ disable-wp;
+ no-1-8-v;
+ status = "okay";
+};
+
+&usbss0 {
+ ti,vbus-divider;
+ status = "okay";
+};
+
+&usbss1 {
+ ti,vbus-divider;
+ status = "okay";
+};
+
+&usb0 {
+ usb-role-switch;
+
+ port {
+ typec_hs: endpoint {
+ remote-endpoint = <&usb_con_hs>;
+ };
+ };
+};
+
+&usb1 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_usb1_pins_default>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 3c45782ab2b7..44ff67b6bf1e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -48,6 +48,14 @@
pmsg-size = <0x8000>;
};
+ /* global cma region */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x00 0x8000000>;
+ linux,cma-default;
+ };
+
secure_tfa_ddr: tfa@9e780000 {
reg = <0x00 0x9e780000 0x00 0x80000>;
alignment = <0x1000>;
@@ -128,6 +136,10 @@
};
};
+&phy_gmii_sel {
+ bootph-all;
+};
+
&main_pmx0 {
/* First pad number is ALW package and second is AMC package */
main_uart0_pins_default: main-uart0-default-pins {
@@ -156,6 +168,7 @@
};
main_i2c1_pins_default: main-i2c1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x1e8, PIN_INPUT_PULLUP, 0) /* (B17/A17) I2C1_SCL */
AM62X_IOPAD(0x1ec, PIN_INPUT_PULLUP, 0) /* (A17/A16) I2C1_SDA */
@@ -335,15 +348,9 @@
self-powered;
data-role = "dual";
power-role = "sink";
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- usb_con_hs: endpoint {
- remote-endpoint = <&usb0_hs_ep>;
- };
+ port {
+ usb_con_hs: endpoint {
+ remote-endpoint = <&usb0_hs_ep>;
};
};
};
@@ -470,12 +477,9 @@
&usb0 {
bootph-all;
- #address-cells = <1>;
- #size-cells = <0>;
usb-role-switch;
- port@0 {
- reg = <0>;
+ port {
usb0_hs_ep: endpoint {
remote-endpoint = <&usb_con_hs>;
};
@@ -504,8 +508,6 @@
0 0 0 0
0 0 0 0
>;
- tx-num-evt = <32>;
- rx-num-evt = <32>;
};
&dss {
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 6f9aa5e02138..f8370dd03350 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1283,6 +1283,9 @@
<0x22400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-pru0_0-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <16 2 2>;
+ interrupt-names = "vring";
};
rtu0_0: rtu@4000 {
@@ -1292,6 +1295,9 @@
<0x23400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-rtu0_0-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <20 4 4>;
+ interrupt-names = "vring";
};
tx_pru0_0: txpru@a000 {
@@ -1310,6 +1316,9 @@
<0x24400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-pru0_1-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <18 3 3>;
+ interrupt-names = "vring";
};
rtu0_1: rtu@6000 {
@@ -1319,6 +1328,9 @@
<0x23c00 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-rtu0_1-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <22 5 5>;
+ interrupt-names = "vring";
};
tx_pru0_1: txpru@c000 {
@@ -1436,6 +1448,9 @@
<0x22400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-pru1_0-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <16 2 2>;
+ interrupt-names = "vring";
};
rtu1_0: rtu@4000 {
@@ -1445,6 +1460,9 @@
<0x23400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-rtu1_0-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <20 4 4>;
+ interrupt-names = "vring";
};
tx_pru1_0: txpru@a000 {
@@ -1463,6 +1481,9 @@
<0x24400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-pru1_1-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <18 3 3>;
+ interrupt-names = "vring";
};
rtu1_1: rtu@6000 {
@@ -1472,6 +1493,9 @@
<0x23c00 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am64x-rtu1_1-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <22 5 5>;
+ interrupt-names = "vring";
};
tx_pru1_1: txpru@c000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
index 125e507966fb..ea7c58fb67e2 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
@@ -265,6 +265,50 @@
interrupts = <70 IRQ_TYPE_EDGE_FALLING>;
wakeup-source;
};
+
+ pmic@61 {
+ compatible = "ti,lp8733";
+ reg = <0x61>;
+
+ buck0-in-supply = <&vcc_5v0_som>;
+ buck1-in-supply = <&vcc_5v0_som>;
+ ldo0-in-supply = <&vdd_3v3>;
+ ldo1-in-supply = <&vdd_3v3>;
+
+ regulators {
+ vdd_core: buck0 {
+ regulator-name = "VDD_CORE";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_3v3: buck1 {
+ regulator-name = "VDD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v8_ldo0: ldo0 {
+ regulator-name = "VDD_1V8_LDO0";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdda_1v8: ldo1 {
+ regulator-name = "VDDA_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
};
&main_r5fss0_core0 {
@@ -296,7 +340,7 @@
pinctrl-names = "default";
pinctrl-0 = <&ospi0_pins_default>;
- flash@0 {
+ serial_flash: flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
diff --git a/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-sdcard.dtso b/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-sdcard.dtso
index 79ed19c6c0e9..c4525024ba5d 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-sdcard.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-sdcard.dtso
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (c) 2022-2023 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
+ * Copyright (c) 2022-2024 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-wlan.dtso b/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-wlan.dtso
index 32596a84b7ba..82f8a21b6cbf 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-wlan.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am64-tqma64xxl-mbax4xxl-wlan.dtso
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (c) 2022-2023 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
+ * Copyright (c) 2022-2024 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac-mii.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac-mii.dtso
new file mode 100644
index 000000000000..423d6027278d
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac-mii.dtso
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for enabling both ICSSG1 port on AM642 EVM in MII mode
+ *
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ aliases {
+ ethernet1 = "/icssg1-eth/ethernet-ports/port@1";
+ };
+
+ mdio-mux-2 {
+ compatible = "mdio-mux-multiplexer";
+ mux-controls = <&mdio_mux>;
+ mdio-parent-bus = <&icssg1_mdio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio@0 {
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ icssg1_phy2: ethernet-phy@3 {
+ reg = <3>;
+ };
+ };
+ };
+};
+
+&main_pmx0 {
+ icssg1_mii1_pins_default: icssg1-mii1-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x00f8, PIN_INPUT, 1) /* (V9) PRG1_PRU0_GPO16.PR1_MII_MT0_CLK */
+ AM64X_IOPAD(0x00f4, PIN_OUTPUT, 0) /* (Y9) PRG1_PRU0_GPO15.PR1_MII0_TXEN */
+ AM64X_IOPAD(0x00f0, PIN_OUTPUT, 0) /* (AA9) PRG1_PRU0_GPO14.PR1_MII0_TXD3 */
+ AM64X_IOPAD(0x00ec, PIN_OUTPUT, 0) /* (W9) PRG1_PRU0_GPO13.PR1_MII0_TXD2 */
+ AM64X_IOPAD(0x00e8, PIN_OUTPUT, 0) /* (U9) PRG1_PRU0_GPO12.PR1_MII0_TXD1 */
+ AM64X_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (AA8) PRG1_PRU0_GPO11.PR1_MII0_TXD0 */
+ AM64X_IOPAD(0x00c8, PIN_INPUT, 1) /* (Y8) PRG1_PRU0_GPO4.PR1_MII0_RXDV */
+ AM64X_IOPAD(0x00d0, PIN_INPUT, 1) /* (AA7) PRG1_PRU0_GPO6.PR1_MII_MR0_CLK */
+ AM64X_IOPAD(0x00c4, PIN_INPUT, 1) /* (V8) PRG1_PRU0_GPO3.PR1_MII0_RXD3 */
+ AM64X_IOPAD(0x00c0, PIN_INPUT, 1) /* (W8) PRG1_PRU0_GPO2.PR1_MII0_RXD2 */
+ AM64X_IOPAD(0x00cc, PIN_INPUT, 1) /* (V13) PRG1_PRU0_GPO5.PR1_MII0_RXER */
+ AM64X_IOPAD(0x00bc, PIN_INPUT, 1) /* (U8) PRG1_PRU0_GPO1.PR1_MII0_RXD1 */
+ AM64X_IOPAD(0x00b8, PIN_INPUT, 1) /* (Y7) PRG1_PRU0_GPO0.PR1_MII0_RXD0 */
+ AM64X_IOPAD(0x00d8, PIN_INPUT, 1) /* (W13) PRG1_PRU0_GPO8.PR1_MII0_RXLINK */
+ >;
+ };
+
+ icssg1_mii2_pins_default: icssg1-mii2-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0148, PIN_INPUT, 1) /* (Y10) PRG1_PRU1_GPO16.PR1_MII_MT1_CLK */
+ AM64X_IOPAD(0x0144, PIN_OUTPUT, 0) /* (Y11) PRG1_PRU1_GPO15.PR1_MII1_TXEN */
+ AM64X_IOPAD(0x0140, PIN_OUTPUT, 0) /* (AA11) PRG1_PRU1_GPO14.PR1_MII1_TXD3 */
+ AM64X_IOPAD(0x013c, PIN_OUTPUT, 0) /* (U10) PRG1_PRU1_GPO13.PR1_MII1_TXD2 */
+ AM64X_IOPAD(0x0138, PIN_OUTPUT, 0) /* (V10) PRG1_PRU1_GPO12.PR1_MII1_TXD1 */
+ AM64X_IOPAD(0x0134, PIN_OUTPUT, 0) /* (AA10) PRG1_PRU1_GPO11.PR1_MII1_TXD0 */
+ AM64X_IOPAD(0x0118, PIN_INPUT, 1) /* (W12) PRG1_PRU1_GPO4.PR1_MII1_RXDV */
+ AM64X_IOPAD(0x0120, PIN_INPUT, 1) /* (U11) PRG1_PRU1_GPO6.PR1_MII_MR1_CLK */
+ AM64X_IOPAD(0x0114, PIN_INPUT, 1) /* (Y12) PRG1_PRU1_GPO3.PR1_MII1_RXD3 */
+ AM64X_IOPAD(0x0110, PIN_INPUT, 1) /* (AA12) PRG1_PRU1_GPO2.PR1_MII1_RXD2 */
+ AM64X_IOPAD(0x011c, PIN_INPUT, 1) /* (AA13) PRG1_PRU1_GPO5.PR1_MII1_RXER */
+ AM64X_IOPAD(0x010c, PIN_INPUT, 1) /* (V11) PRG1_PRU1_GPO1.PR1_MII1_RXD1 */
+ AM64X_IOPAD(0x0108, PIN_INPUT, 1) /* (W11) PRG1_PRU1_GPO0.PR1_MII1_RXD0 */
+ AM64X_IOPAD(0x0128, PIN_INPUT, 1) /* (U12) PRG1_PRU1_GPO8.PR1_MII1_RXLINK */
+ >;
+ };
+};
+
+&cpsw3g {
+ pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw_port2 {
+ status = "disabled";
+};
+
+&mdio_mux_1 {
+ status = "disabled";
+};
+
+&icssg1_eth {
+ pinctrl-0 = <&icssg1_mii1_pins_default &icssg1_mii2_pins_default>;
+};
+
+&icssg1_emac0 {
+ phy-mode = "mii";
+};
+
+&icssg1_emac1 {
+ status = "okay";
+ phy-handle = <&icssg1_phy2>;
+ phy-mode = "mii";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-nand.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-nand.dtso
new file mode 100644
index 000000000000..f08c0e272b53
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-nand.dtso
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for HSE NAND expansion card on AM642 EVM
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+ gpmc0_pins_default: gpmc0-pins-default {
+ bootph-all;
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0094, PIN_INPUT, 7) /* (T19) GPMC0_BE1n.GPIO0_36 */
+ AM64X_IOPAD(0x003c, PIN_INPUT, 0) /* (T20) GPMC0_AD0 */
+ AM64X_IOPAD(0x0040, PIN_INPUT, 0) /* (U21) GPMC0_AD1 */
+ AM64X_IOPAD(0x0064, PIN_INPUT, 0) /* (R16) GPMC0_AD10 */
+ AM64X_IOPAD(0x0068, PIN_INPUT, 0) /* (W20) GPMC0_AD11 */
+ AM64X_IOPAD(0x006c, PIN_INPUT, 0) /* (W21) GPMC0_AD12 */
+ AM64X_IOPAD(0x0070, PIN_INPUT, 0) /* (V18) GPMC0_AD13 */
+ AM64X_IOPAD(0x0074, PIN_INPUT, 0) /* (Y21) GPMC0_AD14 */
+ AM64X_IOPAD(0x0078, PIN_INPUT, 0) /* (Y20) GPMC0_AD15 */
+ AM64X_IOPAD(0x0044, PIN_INPUT, 0) /* (T18) GPMC0_AD2 */
+ AM64X_IOPAD(0x0048, PIN_INPUT, 0) /* (U20) GPMC0_AD3 */
+ AM64X_IOPAD(0x004c, PIN_INPUT, 0) /* (U18) GPMC0_AD4 */
+ AM64X_IOPAD(0x0050, PIN_INPUT, 0) /* (U19) GPMC0_AD5 */
+ AM64X_IOPAD(0x0054, PIN_INPUT, 0) /* (V20) GPMC0_AD6 */
+ AM64X_IOPAD(0x0058, PIN_INPUT, 0) /* (V21) GPMC0_AD7 */
+ AM64X_IOPAD(0x005c, PIN_INPUT, 0) /* (V19) GPMC0_AD8 */
+ AM64X_IOPAD(0x0060, PIN_INPUT, 0) /* (T17) GPMC0_AD9 */
+ AM64X_IOPAD(0x0098, PIN_INPUT_PULLUP, 0) /* (W19) GPMC0_WAIT0 */
+ AM64X_IOPAD(0x009c, PIN_INPUT_PULLUP, 0) /* (Y18) GPMC0_WAIT1 */
+ AM64X_IOPAD(0x00a8, PIN_OUTPUT_PULLUP, 0) /* (R19) GPMC0_CSn0 */
+ AM64X_IOPAD(0x00ac, PIN_OUTPUT_PULLUP, 0) /* (R20) GPMC0_CSn1 */
+ AM64X_IOPAD(0x00b0, PIN_OUTPUT_PULLUP, 0) /* (P19) GPMC0_CSn2 */
+ AM64X_IOPAD(0x00b4, PIN_OUTPUT_PULLUP, 0) /* (R21) GPMC0_CSn3 */
+ AM64X_IOPAD(0x007c, PIN_OUTPUT, 0) /* (R17) GPMC0_CLK */
+ AM64X_IOPAD(0x0084, PIN_OUTPUT, 0) /* (P16) GPMC0_ADVn_ALE */
+ AM64X_IOPAD(0x0088, PIN_OUTPUT, 0) /* (R18) GPMC0_OEn_REn */
+ AM64X_IOPAD(0x008c, PIN_OUTPUT, 0) /* (T21) GPMC0_WEn */
+ AM64X_IOPAD(0x0090, PIN_OUTPUT, 0) /* (P17) GPMC0_BE0n_CLE */
+ AM64X_IOPAD(0x00a0, PIN_OUTPUT_PULLUP, 0) /* (N16) GPMC0_WPn */
+ AM64X_IOPAD(0x00a4, PIN_OUTPUT, 0) /* (N17) GPMC0_DIR */
+ >;
+ };
+};
+
+&main_gpio0 {
+ gpio0-36 {
+ bootph-all;
+ gpio-hog;
+ gpios = <36 0>;
+ input;
+ line-name = "GPMC0_MUX_DIR";
+ };
+};
+
+&elm0 {
+ bootph-all;
+ status = "okay";
+};
+
+&gpmc0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmc0_pins_default>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ nand@0,0 {
+ compatible = "ti,am64-nand";
+ reg = <0 0 64>; /* device IO registers */
+ interrupt-parent = <&gpmc0>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+ rb-gpios = <&gpmc0 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+ ti,nand-xfer-type = "prefetch-polled";
+ ti,nand-ecc-opt = "bch8"; /* BCH8: Bootrom limitation */
+ ti,elm-id = <&elm0>;
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <40>;
+ gpmc,cs-wr-off-ns = <40>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <25>;
+ gpmc,adv-wr-off-ns = <25>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <20>;
+ gpmc,oe-on-ns = <3>;
+ gpmc,oe-off-ns = <30>;
+ gpmc,access-ns = <30>;
+ gpmc,rd-cycle-ns = <40>;
+ gpmc,wr-cycle-ns = <40>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ bootph-all;
+ label = "NAND.tiboot3";
+ reg = <0x00000000 0x00200000>; /* 2M */
+ };
+ partition@200000 {
+ bootph-all;
+ label = "NAND.tispl";
+ reg = <0x00200000 0x00200000>; /* 2M */
+ };
+ partition@400000 {
+ bootph-all;
+ label = "NAND.tiboot3.backup"; /* 2M */
+ reg = <0x00400000 0x00200000>; /* BootROM looks at 4M */
+ };
+ partition@600000 {
+ bootph-all;
+ label = "NAND.u-boot";
+ reg = <0x00600000 0x00400000>; /* 4M */
+ };
+ partition@a00000 {
+ bootph-all;
+ label = "NAND.u-boot-env";
+ reg = <0x00a00000 0x00040000>; /* 256K */
+ };
+ partition@a40000 {
+ bootph-all;
+ label = "NAND.u-boot-env.backup";
+ reg = <0x00a40000 0x00040000>; /* 256K */
+ };
+ partition@a80000 {
+ bootph-all;
+ label = "NAND.file-system";
+ reg = <0x00a80000 0x3f580000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 53fe1d065ddb..6bb1ad2e56ec 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -466,6 +466,12 @@
AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
>;
};
+
+ icssg1_iep0_pins_default: icssg1-iep0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0104, PIN_OUTPUT, 2) /* (W7) PRG1_PRU0_GPO19.PRG1_IEP0_EDC_SYNC_OUT0 */
+ >;
+ };
};
&main_uart0 {
@@ -473,7 +479,6 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
- current-speed = <115200>;
};
/* main_uart1 is reserved for firmware usage */
@@ -818,3 +823,12 @@
rx-internal-delay-ps = <2000>;
};
};
+
+&gpmc0 {
+ ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
+};
+
+&icssg1_iep0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg1_iep0_pins_default>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
index 234d76e4e944..5b5e9eeec5ac 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -282,7 +282,6 @@
pinctrl-names = "default";
pinctrl-0 = <&main_uart3_default_pins>;
uart-has-rtscts;
- rs485-rts-active-low;
linux,rs485-enabled-at-boot-time;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso
new file mode 100644
index 000000000000..5057658061b4
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ fan: gpio-fan {
+ compatible = "gpio-fan";
+ gpio-fan,speed-map = <0 0 8600 1>;
+ gpios = <&main_gpio0 28 GPIO_ACTIVE_LOW>;
+ #cooling-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_fan_pins_default>;
+ };
+};
+
+&main_pmx0 {
+ gpio_fan_pins_default: gpio-fan-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x070, PIN_OUTPUT, 7) /* (V18) GPMC0_AD13.GPIO0_28 */
+ >;
+ };
+};
+
+&thermal_zones {
+ main0_thermal: main0-thermal {
+ trips {
+ main0_thermal_trip0: main0-thermal-trip {
+ temperature = <65000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&main0_thermal_trip0>;
+ cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-pcie-usb2.dtso b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-pcie-usb2.dtso
new file mode 100644
index 000000000000..7a5ce4bc02f3
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-pcie-usb2.dtso
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT overlay for PCIe support (limits USB to 2.0/high-speed)
+ *
+ * Copyright (C) 2021 PHYTEC America, LLC - https://www.phytec.com
+ * Author: Matt McKee <mmckee@phytec.com>
+ *
+ * Copyright (C) 2024 PHYTEC America, LLC - https://www.phytec.com
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
+
+#include "k3-pinctrl.h"
+#include "k3-serdes.h"
+
+&{/} {
+ pcie_refclk0: pcie-refclk0 {
+ compatible = "gpio-gate-clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_usb_sel_pins_default>;
+ clocks = <&serdes_refclk>;
+ #clock-cells = <0>;
+ enable-gpios = <&main_gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&main_pmx0 {
+ pcie_usb_sel_pins_default: pcie-usb-sel-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x017c, PIN_OUTPUT, 7) /* (T1) PRG0_PRU0_GPO7.GPIO1_7 */
+ >;
+ };
+
+ pcie_pins_default: pcie-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0098, PIN_OUTPUT, 7) /* (W19) GPMC0_WAIT0.GPIO0_37 */
+ >;
+ };
+};
+
+&pcie0_rc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pins_default>;
+ reset-gpios = <&main_gpio0 37 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_pcie_usb_link>;
+ phy-names = "pcie-phy";
+ num-lanes = <1>;
+ status = "okay";
+};
+
+&serdes0_pcie_usb_link {
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+};
+
+&serdes_ln_ctrl {
+ idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes0 {
+ assigned-clock-parents = <&pcie_refclk0>, <&pcie_refclk0>, <&pcie_refclk0>;
+};
+
+&serdes_refclk {
+ clock-frequency = <100000000>;
+};
+
+/*
+ * Assign pcie_refclk0 to serdes_wiz0 as ext_ref_clk.
+ * This makes sure that the clock generator gets enabled at the right time.
+ */
+&serdes_wiz0 {
+ clocks = <&k3_clks 162 0>, <&k3_clks 162 1>, <&pcie_refclk0>;
+};
+
+&usbss0 {
+ ti,usb2-only;
+};
+
+&usb0 {
+ maximum-speed = "high-speed";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
index 8237b8c815b8..30729b49dd69 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
@@ -42,7 +42,7 @@
pinctrl-names = "default";
pinctrl-0 = <&can_tc1_pins_default>;
#phy-cells = <0>;
- max-bitrate = <5000000>;
+ max-bitrate = <8000000>;
standby-gpios = <&main_gpio0 32 GPIO_ACTIVE_HIGH>;
};
@@ -51,7 +51,7 @@
pinctrl-names = "default";
pinctrl-0 = <&can_tc2_pins_default>;
#phy-cells = <0>;
- max-bitrate = <5000000>;
+ max-bitrate = <8000000>;
standby-gpios = <&main_gpio0 35 GPIO_ACTIVE_HIGH>;
};
@@ -190,18 +190,6 @@
>;
};
- pcie_usb_sel_pins_default: pcie-usb-sel-default-pins {
- pinctrl-single,pins = <
- AM64X_IOPAD(0x017c, PIN_OUTPUT, 7) /* (T1) PRG0_PRU0_GPO7.GPIO1_7 */
- >;
- };
-
- pcie0_pins_default: pcie0-default-pins {
- pinctrl-single,pins = <
- AM64X_IOPAD(0x0098, PIN_OUTPUT, 7) /* (W19) GPMC0_WAIT0.GPIO0_37 */
- >;
- };
-
user_leds_pins_default: user-leds-default-pins {
pinctrl-single,pins = <
AM64X_IOPAD(0x003c, PIN_OUTPUT, 7) /* (T20) GPMC0_AD0.GPIO0_15 */
@@ -275,7 +263,6 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
- current-speed = <115200>;
};
&main_uart1 {
@@ -283,7 +270,6 @@
pinctrl-names = "default";
pinctrl-0 = <&main_uart1_pins_default>;
uart-has-rtscts;
- current-speed = <115200>;
};
&sdhci1 {
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 67cd41bf806e..44ecbcf1c844 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -381,7 +381,6 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
- current-speed = <115200>;
};
&main_uart1 {
@@ -431,6 +430,18 @@
#gpio-cells = <2>;
gpio-line-names = "LED1","LED2","LED3","LED4","LED5","LED6","LED7","LED8";
};
+
+ /* SoC power supply temperature */
+ tmp100@48 {
+ compatible = "ti,tmp100";
+ reg = <0x48>;
+ };
+
+ /* DDR power supply temperature */
+ tmp100@49 {
+ compatible = "ti,tmp100";
+ reg = <0x49>;
+ };
};
/* mcu_gpio0 and mcu_gpio_intr are reserved for mcu firmware usage */
diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
index 1f4dc5ad1696..c40ad67cee01 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
- * Copyright (c) 2022-2023 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
+ * Copyright (c) 2022-2024 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
index 6c785eff7d2f..828d815d6bdf 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
- * Copyright (c) 2022-2023 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
+ * Copyright (c) 2022-2024 TQ-Systems GmbH <linux@ew.tq-group.com>, D-82229 Seefeld, Germany.
*/
#include "k3-am642.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
index c50a585dd638..0a29ed172215 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
@@ -43,9 +43,45 @@
};
&icssg0_eth {
- status = "disabled";
+ compatible = "ti,am654-sr1-icssg-prueth";
+
+ ti,prus = <&pru0_0>, <&rtu0_0>, <&pru0_1>, <&rtu0_1>;
+ firmware-name = "ti-pruss/am65x-pru0-prueth-fw.elf",
+ "ti-pruss/am65x-rtu0-prueth-fw.elf",
+ "ti-pruss/am65x-pru1-prueth-fw.elf",
+ "ti-pruss/am65x-rtu1-prueth-fw.elf";
+
+ ti,pruss-gp-mux-sel = <2>, /* MII mode */
+ <2>,
+ <2>, /* MII mode */
+ <2>;
+
+ dmas = <&main_udmap 0xc100>, /* egress slice 0 */
+ <&main_udmap 0xc101>, /* egress slice 0 */
+ <&main_udmap 0xc102>, /* egress slice 0 */
+ <&main_udmap 0xc103>, /* egress slice 0 */
+ <&main_udmap 0xc104>, /* egress slice 1 */
+ <&main_udmap 0xc105>, /* egress slice 1 */
+ <&main_udmap 0xc106>, /* egress slice 1 */
+ <&main_udmap 0xc107>, /* egress slice 1 */
+ <&main_udmap 0x4100>, /* ingress slice 0 */
+ <&main_udmap 0x4101>, /* ingress slice 1 */
+ <&main_udmap 0x4102>, /* mgmnt rsp slice 0 */
+ <&main_udmap 0x4103>; /* mgmnt rsp slice 1 */
+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+ "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+ "rx0", "rx1",
+ "rxmgm0", "rxmgm1";
};
-&icssg0_mdio {
- status = "disabled";
+&icssg0_iep0 {
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <7 7 7>;
+ interrupt-names = "iep_cap_cmp";
+};
+
+&icssg0_iep1 {
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <56 8 8>;
+ interrupt-names = "iep_cap_cmp";
};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index ff857117d719..1af3dedde1f6 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -66,7 +66,7 @@
assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>;
ti,serdes-clk = <&serdes0_clk>;
#clock-cells = <1>;
- mux-controls = <&serdes_mux 0>;
+ mux-controls = <&serdes0_mux 0>;
};
serdes1: serdes@910000 {
@@ -81,7 +81,7 @@
assigned-clock-parents = <&k3_clks 154 9>, <&k3_clks 154 5>;
ti,serdes-clk = <&serdes1_clk>;
#clock-cells = <1>;
- mux-controls = <&serdes_mux 1>;
+ mux-controls = <&serdes1_mux 0>;
};
main_uart0: serial@2800000 {
@@ -89,7 +89,6 @@
reg = <0x00 0x02800000 0x00 0x100>;
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <48000000>;
- current-speed = <115200>;
power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
};
@@ -436,18 +435,13 @@
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
+ ti,clkbuf-sel = <0x7>;
+ ti,trm-icp = <0x8>;
ti,otap-del-sel-legacy = <0x0>;
ti,otap-del-sel-mmc-hs = <0x0>;
- ti,otap-del-sel-sd-hs = <0x0>;
- ti,otap-del-sel-sdr12 = <0x0>;
- ti,otap-del-sel-sdr25 = <0x0>;
- ti,otap-del-sel-sdr50 = <0x8>;
- ti,otap-del-sel-sdr104 = <0x7>;
- ti,otap-del-sel-ddr50 = <0x5>;
ti,otap-del-sel-ddr52 = <0x5>;
ti,otap-del-sel-hs200 = <0x5>;
- ti,otap-del-sel-hs400 = <0x0>;
- ti,trm-icp = <0x8>;
+ ti,itap-del-sel-ddr52 = <0x0>;
dma-coherent;
status = "disabled";
};
@@ -459,18 +453,19 @@
clocks = <&k3_clks 48 0>, <&k3_clks 48 1>;
clock-names = "clk_ahb", "clk_xin";
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ ti,clkbuf-sel = <0x7>;
+ ti,trm-icp = <0x8>;
ti,otap-del-sel-legacy = <0x0>;
- ti,otap-del-sel-mmc-hs = <0x0>;
ti,otap-del-sel-sd-hs = <0x0>;
- ti,otap-del-sel-sdr12 = <0x0>;
- ti,otap-del-sel-sdr25 = <0x0>;
+ ti,otap-del-sel-sdr12 = <0xf>;
+ ti,otap-del-sel-sdr25 = <0xf>;
ti,otap-del-sel-sdr50 = <0x8>;
ti,otap-del-sel-sdr104 = <0x7>;
ti,otap-del-sel-ddr50 = <0x4>;
- ti,otap-del-sel-ddr52 = <0x4>;
- ti,otap-del-sel-hs200 = <0x7>;
- ti,clkbuf-sel = <0x7>;
- ti,trm-icp = <0x8>;
+ ti,itap-del-sel-legacy = <0xa>;
+ ti,itap-del-sel-sd-hs = <0x1>;
+ ti,itap-del-sel-sdr12 = <0xa>;
+ ti,itap-del-sel-sdr25 = <0x1>;
dma-coherent;
status = "disabled";
};
@@ -483,20 +478,25 @@
ranges = <0x0 0x0 0x00100000 0x1c000>;
serdes0_clk: clock@4080 {
- compatible = "syscon";
- reg = <0x00004080 0x4>;
+ compatible = "ti,am654-serdes-ctrl", "syscon";
+ reg = <0x4080 0x4>;
+
+ serdes0_mux: mux-controller {
+ compatible = "mmio-mux";
+ #mux-control-cells = <1>;
+ mux-reg-masks = <0x0 0x3>; /* lane select */
+ };
};
serdes1_clk: clock@4090 {
- compatible = "syscon";
- reg = <0x00004090 0x4>;
- };
+ compatible = "ti,am654-serdes-ctrl", "syscon";
+ reg = <0x4090 0x4>;
- serdes_mux: mux-controller {
- compatible = "mmio-mux";
- #mux-control-cells = <1>;
- mux-reg-masks = <0x4080 0x3>, /* SERDES0 lane select */
- <0x4090 0x3>; /* SERDES1 lane select */
+ serdes1_mux: mux-controller {
+ compatible = "mmio-mux";
+ #mux-control-cells = <1>;
+ mux-reg-masks = <0x0 0x3>; /* lane select */
+ };
};
dss_oldi_io_ctrl: dss-oldi-io-ctrl@41e0 {
@@ -1185,6 +1185,9 @@
<0x22400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru0_0-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <16 2 2>;
+ interrupt-names = "vring";
};
rtu0_0: rtu@4000 {
@@ -1194,6 +1197,9 @@
<0x23400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu0_0-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <20 4 4>;
+ interrupt-names = "vring";
};
tx_pru0_0: txpru@a000 {
@@ -1212,6 +1218,9 @@
<0x24400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru0_1-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <18 3 3>;
+ interrupt-names = "vring";
};
rtu0_1: rtu@6000 {
@@ -1221,6 +1230,9 @@
<0x23c00 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu0_1-fw";
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <22 5 5>;
+ interrupt-names = "vring";
};
tx_pru0_1: txpru@c000 {
@@ -1339,6 +1351,9 @@
<0x22400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru1_0-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <16 2 2>;
+ interrupt-names = "vring";
};
rtu1_0: rtu@4000 {
@@ -1348,6 +1363,9 @@
<0x23400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu1_0-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <20 4 4>;
+ interrupt-names = "vring";
};
tx_pru1_0: txpru@a000 {
@@ -1366,6 +1384,9 @@
<0x24400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru1_1-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <18 3 3>;
+ interrupt-names = "vring";
};
rtu1_1: rtu@6000 {
@@ -1375,6 +1396,9 @@
<0x23c00 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu1_1-fw";
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <22 5 5>;
+ interrupt-names = "vring";
};
tx_pru1_1: txpru@c000 {
@@ -1493,6 +1517,9 @@
<0x22400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru2_0-fw";
+ interrupt-parent = <&icssg2_intc>;
+ interrupts = <16 2 2>;
+ interrupt-names = "vring";
};
rtu2_0: rtu@4000 {
@@ -1502,6 +1529,9 @@
<0x23400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu2_0-fw";
+ interrupt-parent = <&icssg2_intc>;
+ interrupts = <20 4 4>;
+ interrupt-names = "vring";
};
tx_pru2_0: txpru@a000 {
@@ -1520,6 +1550,9 @@
<0x24400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru2_1-fw";
+ interrupt-parent = <&icssg2_intc>;
+ interrupts = <18 3 3>;
+ interrupt-names = "vring";
};
rtu2_1: rtu@6000 {
@@ -1529,6 +1562,9 @@
<0x23c00 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu2_1-fw";
+ interrupt-parent = <&icssg2_intc>;
+ interrupts = <22 5 5>;
+ interrupt-names = "vring";
};
tx_pru2_1: txpru@c000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
index 6ff3ccc39fb4..43c6118d2bf0 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
@@ -6,13 +6,17 @@
*/
&cbass_mcu {
- mcu_conf: scm-conf@40f00000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x0 0x40f00000 0x0 0x20000>;
+ mcu_conf: bus@40f00000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x40f00000 0x20000>;
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
+
phy_gmii_sel: phy@4040 {
compatible = "ti,am654-phy-gmii-sel";
reg = <0x4040 0x4>;
@@ -43,7 +47,6 @@
reg = <0x00 0x40a00000 0x00 0x100>;
interrupts = <GIC_SPI 565 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <96000000>;
- current-speed = <115200>;
power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
};
@@ -286,7 +289,11 @@
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
- ranges;
+ ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+ <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+ <0x0 0x47050000 0x0 0x47050000 0x0 0x100>, /* OSPI1 Control */
+ <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>, /* OSPI0 Memory */
+ <0x7 0x00000000 0x7 0x00000000 0x1 0x0000000>; /* OSPI1 Memory */
ospi0: spi@47040000 {
compatible = "ti,am654-ospi", "cdns,qspi-nor";
@@ -355,7 +362,7 @@
reg = <1>;
ti,mac-only;
label = "port1";
- ti,syscon-efuse = <&mcu_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
phys = <&phy_gmii_sel 1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
index 37527890ddea..eee072e44a42 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
@@ -59,7 +59,6 @@
reg = <0x42300000 0x100>;
interrupts = <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <48000000>;
- current-speed = <115200>;
power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
};
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 aba0c52b1213..aa7139cc8a92 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -33,6 +33,7 @@
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 4G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
<0x00000008 0x80000000 0x00000000 0x80000000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
index d743f023cdd9..90dbe31c5b81 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
@@ -414,6 +414,82 @@
pinctrl-0 = <&wkup_uart0_pins_default>;
};
+&wkup_i2c0 {
+ bootph-all;
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wkup_i2c0_pins_default>;
+ status = "okay";
+
+ lp8733: pmic@60 {
+ compatible = "ti,lp8733";
+ reg = <0x60>;
+ buck0-in-supply = <&vsys_3v3>;
+ buck1-in-supply = <&vsys_3v3>;
+ ldo0-in-supply = <&vsys_3v3>;
+ ldo1-in-supply = <&vsys_3v3>;
+
+ lp8733_regulators: regulators {
+ lp8733_buck0_reg: buck0 {
+ /* FB_B0 -> LP8733-BUCK1 - VDD_MCU_0V85 */
+ regulator-name = "lp8733-buck0";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ lp8733_buck1_reg: buck1 {
+ /* FB_B1 -> LP8733-BUCK2 - VDD_DDR_1V1 */
+ regulator-name = "lp8733-buck1";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ lp8733_ldo0_reg: ldo0 {
+ /* LDO0 -> LP8733-LDO1 - VDA_DLL_0V8 */
+ regulator-name = "lp8733-ldo0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ lp8733_ldo1_reg: ldo1 {
+ /* LDO1 -> LP8733-LDO2 - VDA_LN_1V8 */
+ regulator-name = "lp8733-ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ tps62873a: regulator@40 {
+ compatible = "ti,tps62873";
+ reg = <0x40>;
+ bootph-pre-ram;
+ regulator-name = "VDD_CPU_AVS";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ tps62873b: regulator@43 {
+ compatible = "ti,tps62873";
+ reg = <0x43>;
+ regulator-name = "VDD_CORE_0V8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
&mcu_uart0 {
status = "okay";
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
index 0f4a5da0ebc4..5c66e0ec6e82 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
@@ -11,9 +11,10 @@
/ {
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 16 GB RAM */
- reg = <0x00 0x80000000 0x00 0x80000000>,
- <0x08 0x80000000 0x03 0x80000000>;
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000003 0x80000000>;
};
reserved_memory: reserved-memory {
@@ -130,6 +131,25 @@
};
};
+&wkup_pmx0 {
+ mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins {
+ bootph-all;
+ pinctrl-single,pins = <
+ J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (D19) MCU_OSPI0_CLK */
+ J721S2_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F15) MCU_OSPI0_CSn0 */
+ J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (C19) MCU_OSPI0_D0 */
+ J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F16) MCU_OSPI0_D1 */
+ J721S2_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (G15) MCU_OSPI0_D2 */
+ J721S2_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (F18) MCU_OSPI0_D3 */
+ J721S2_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (E19) MCU_OSPI0_D4 */
+ J721S2_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (G19) MCU_OSPI0_D5 */
+ J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
+ J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
+ J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
+ >;
+ };
+};
+
&wkup_pmx2 {
wkup_i2c0_pins_default: wkup-i2c0-default-pins {
pinctrl-single,pins = <
@@ -152,6 +172,68 @@
};
};
+&ospi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <25000000>;
+ cdns,tshsl-ns = <60>;
+ cdns,tsd2d-ns = <60>;
+ cdns,tchsh-ns = <60>;
+ cdns,tslch-ns = <60>;
+ cdns,read-delay = <4>;
+
+ partitions {
+ bootph-all;
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "ospi.tiboot3";
+ reg = <0x0 0x80000>;
+ };
+
+ partition@80000 {
+ label = "ospi.tispl";
+ reg = <0x80000 0x200000>;
+ };
+
+ partition@280000 {
+ label = "ospi.u-boot";
+ reg = <0x280000 0x400000>;
+ };
+
+ partition@680000 {
+ label = "ospi.env";
+ reg = <0x680000 0x40000>;
+ };
+
+ partition@740000 {
+ label = "ospi.env.backup";
+ reg = <0x740000 0x40000>;
+ };
+
+ partition@800000 {
+ label = "ospi.rootfs";
+ reg = <0x800000 0x37c0000>;
+ };
+
+ partition@3fc0000 {
+ bootph-pre-ram;
+ label = "ospi.phypattern";
+ reg = <0x3fc0000 0x40000>;
+ };
+ };
+ };
+};
+
&mailbox0_cluster0 {
status = "okay";
interrupts = <436>;
diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 50de2a448a3a..3f655852244e 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -35,8 +35,8 @@
device_type = "memory";
bootph-all;
/* 32G RAM */
- reg = <0x00 0x80000000 0x00 0x80000000>,
- <0x08 0x80000000 0x07 0x80000000>;
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000007 0x80000000>;
};
reserved_memory: reserved-memory {
@@ -517,18 +517,18 @@
wkup_uart0_pins_default: wkup-uart0-default-pins {
bootph-all;
pinctrl-single,pins = <
- J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
- J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
- J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
- J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
+ J784S4_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_UART0_CTSn */
+ J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (L36) WKUP_UART0_RTSn */
+ J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
+ J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */
>;
};
wkup_i2c0_pins_default: wkup-i2c0-default-pins {
bootph-all;
pinctrl-single,pins = <
- J721S2_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
- J721S2_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
+ J784S4_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
+ J784S4_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
>;
};
@@ -814,6 +814,27 @@
};
};
};
+
+ tps62873a: regulator@40 {
+ compatible = "ti,tps62873";
+ reg = <0x40>;
+ bootph-pre-ram;
+ regulator-name = "VDD_CPU_AVS";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ tps62873b: regulator@43 {
+ compatible = "ti,tps62873";
+ reg = <0x43>;
+ regulator-name = "VDD_CORE_0V8";
+ regulator-min-microvolt = <760000>;
+ regulator-max-microvolt = <840000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
};
&wkup_gpio0 {
@@ -1203,3 +1224,65 @@
};
};
};
+
+&serdes_ln_ctrl {
+ idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
+ <J784S4_SERDES0_LANE2_PCIE3_LANE0>, <J784S4_SERDES0_LANE3_USB>,
+ <J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
+ <J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>;
+};
+
+&serdes_wiz0 {
+ status = "okay";
+};
+
+&serdes0 {
+ status = "okay";
+
+ serdes0_pcie_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <3>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>, <&serdes_wiz0 3>;
+ };
+};
+
+&serdes_wiz1 {
+ status = "okay";
+};
+
+&serdes1 {
+ status = "okay";
+
+ serdes1_pcie_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <4>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ resets = <&serdes_wiz1 1>, <&serdes_wiz1 2>, <&serdes_wiz1 3>, <&serdes_wiz1 4>;
+ };
+};
+
+&pcie0_rc {
+ status = "okay";
+ reset-gpios = <&exp1 4 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes1_pcie_link>;
+ phy-names = "pcie-phy";
+};
+
+&pcie1_rc {
+ status = "okay";
+ reset-gpios = <&exp1 5 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_pcie_link>;
+ phy-names = "pcie-phy";
+ num-lanes = <2>;
+};
+
+&pcie3_rc {
+ status = "okay";
+ reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_pcie_link>;
+ phy-names = "pcie-phy";
+ num-lanes = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-eth-phy.dtso b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-eth-phy.dtso
new file mode 100644
index 000000000000..356c82bbe143
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-eth-phy.dtso
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023 PHYTEC America, LLC
+ * Author: Garrett Giordano <ggiordano@phytec.com>
+ *
+ * Copyright (C) 2024 PHYTEC America, LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&cpsw3g_phy1 {
+ status = "disabled";
+};
+
+&cpsw_port1 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-rtc.dtso b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-rtc.dtso
new file mode 100644
index 000000000000..8b24191f5948
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-rtc.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023 PHYTEC America, LLC
+ * Author: Garrett Giordano <ggiordano@phytec.com>
+ *
+ * Copyright (C) 2024 PHYTEC America, LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&i2c_som_rtc {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-spi-nor.dtso b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-spi-nor.dtso
new file mode 100644
index 000000000000..cc0cf269b6e4
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-disable-spi-nor.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023 PHYTEC America, LLC
+ * Author: Garrett Giordano <ggiordano@phytec.com>
+ *
+ * Copyright (C) 2024 PHYTEC America, LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&serial_flash {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6xx-phycore-qspi-nor.dtso b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-qspi-nor.dtso
new file mode 100644
index 000000000000..969dfebcd637
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6xx-phycore-qspi-nor.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-pinctrl.h"
+
+&serial_flash {
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index 657f9cc9f4ea..9386bf3ef9f6 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -440,7 +440,6 @@
reg = <0x00 0x02800000 0x00 0x100>;
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";
@@ -452,7 +451,6 @@
reg = <0x00 0x02810000 0x00 0x100>;
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";
@@ -464,7 +462,6 @@
reg = <0x00 0x02820000 0x00 0x100>;
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";
@@ -476,7 +473,6 @@
reg = <0x00 0x02830000 0x00 0x100>;
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";
@@ -488,7 +484,6 @@
reg = <0x00 0x02840000 0x00 0x100>;
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";
@@ -500,7 +495,6 @@
reg = <0x00 0x02850000 0x00 0x100>;
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";
@@ -512,7 +506,6 @@
reg = <0x00 0x02860000 0x00 0x100>;
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";
@@ -524,7 +517,6 @@
reg = <0x00 0x02870000 0x00 0x100>;
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";
@@ -536,7 +528,6 @@
reg = <0x00 0x02880000 0x00 0x100>;
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";
@@ -548,7 +539,6 @@
reg = <0x00 0x02890000 0x00 0x100>;
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";
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
index 7cf21c99956e..5097d192c2b2 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -164,12 +164,16 @@
ti,timer-pwm;
};
- mcu_conf: syscon@40f00000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x00 0x40f00000 0x00 0x20000>;
+ mcu_conf: bus@40f00000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0x00 0x00 0x40f00000 0x20000>;
+ ranges = <0x0 0x0 0x40f00000 0x20000>;
+
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
phy_gmii_sel: phy@4040 {
compatible = "ti,am654-phy-gmii-sel";
@@ -259,7 +263,6 @@
reg = <0x00 0x42300000 0x00 0x100>;
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";
@@ -271,7 +274,6 @@
reg = <0x00 0x40a00000 0x00 0x100>;
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";
@@ -422,7 +424,7 @@
reg = <1>;
ti,mac-only;
label = "port1";
- ti,syscon-efuse = <&mcu_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
phys = <&phy_gmii_sel 1>;
};
};
@@ -520,10 +522,12 @@
fss: bus@47000000 {
compatible = "simple-bus";
- reg = <0x00 0x47000000 0x00 0x100>;
#address-cells = <2>;
#size-cells = <2>;
- ranges;
+ ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+ <0x0 0x47034000 0x0 0x47040000 0x0 0x100>, /* HBMC Control */
+ <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+ <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>; /* HBMC/OSPI0 Memory */
hbmc_mux: mux-controller@47000004 {
compatible = "reg-mux";
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
index 7e6a584ac6f0..21fe194a5766 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
@@ -12,9 +12,10 @@
/ {
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 4G RAM */
- reg = <0x00 0x80000000 0x00 0x80000000>,
- <0x08 0x80000000 0x00 0x80000000>;
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000000 0x80000000>;
};
reserved_memory: reserved-memory {
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board-infotainment.dtso b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board-infotainment.dtso
new file mode 100644
index 000000000000..65a7e54f0884
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board-infotainment.dtso
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Infotainment Expansion Board for j721e-evm
+ * User Guide: <https://www.ti.com/lit/ug/spruit0a/spruit0a.pdf>
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "a";
+ ddc-i2c-bus = <&main_i2c1>;
+ digital;
+ /* P12 - HDMI_HPD */
+ hpd-gpios = <&exp6 10 GPIO_ACTIVE_HIGH>;
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+
+ dvi-bridge {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,tfp410";
+ /* P10 - HDMI_PDn */
+ powerdown-gpios = <&exp6 8 GPIO_ACTIVE_LOW>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint {
+ remote-endpoint = <&dpi_out0>;
+ pclk-sample = <1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint {
+ remote-endpoint =
+ <&hdmi_connector_in>;
+ };
+ };
+ };
+};
+
+&main_pmx0 {
+ main_i2c1_exp6_pins_default: main-i2c1-exp6-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x264, PIN_INPUT, 7) /* (T29) MMC2_DAT2.GPIO1_24 */
+ >;
+ };
+
+ dss_vout0_pins_default: dss-vout0-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x58, PIN_OUTPUT, 10) /* (AE22) PRG1_PRU1_GPO0.VOUT0_DATA0 */
+ J721E_IOPAD(0x5c, PIN_OUTPUT, 10) /* (AG23) PRG1_PRU1_GPO1.VOUT0_DATA1 */
+ J721E_IOPAD(0x60, PIN_OUTPUT, 10) /* (AF23) PRG1_PRU1_GPO2.VOUT0_DATA2 */
+ J721E_IOPAD(0x64, PIN_OUTPUT, 10) /* (AD23) PRG1_PRU1_GPO3.VOUT0_DATA3 */
+ J721E_IOPAD(0x68, PIN_OUTPUT, 10) /* (AH24) PRG1_PRU1_GPO4.VOUT0_DATA4 */
+ J721E_IOPAD(0x6c, PIN_OUTPUT, 10) /* (AG21) PRG1_PRU1_GPO5.VOUT0_DATA5 */
+ J721E_IOPAD(0x70, PIN_OUTPUT, 10) /* (AE23) PRG1_PRU1_GPO6.VOUT0_DATA6 */
+ J721E_IOPAD(0x74, PIN_OUTPUT, 10) /* (AC21) PRG1_PRU1_GPO7.VOUT0_DATA7 */
+ J721E_IOPAD(0x78, PIN_OUTPUT, 10) /* (Y23) PRG1_PRU1_GPO8.VOUT0_DATA8 */
+ J721E_IOPAD(0x7c, PIN_OUTPUT, 10) /* (AF21) PRG1_PRU1_GPO9.VOUT0_DATA9 */
+ J721E_IOPAD(0x80, PIN_OUTPUT, 10) /* (AB23) PRG1_PRU1_GPO10.VOUT0_DATA10 */
+ J721E_IOPAD(0x84, PIN_OUTPUT, 10) /* (AJ25) PRG1_PRU1_GPO11.VOUT0_DATA11 */
+ J721E_IOPAD(0x88, PIN_OUTPUT, 10) /* (AH25) PRG1_PRU1_GPO12.VOUT0_DATA12 */
+ J721E_IOPAD(0x8c, PIN_OUTPUT, 10) /* (AG25) PRG1_PRU1_GPO13.VOUT0_DATA13 */
+ J721E_IOPAD(0x90, PIN_OUTPUT, 10) /* (AH26) PRG1_PRU1_GPO14.VOUT0_DATA14 */
+ J721E_IOPAD(0x94, PIN_OUTPUT, 10) /* (AJ27) PRG1_PRU1_GPO15.VOUT0_DATA15 */
+ J721E_IOPAD(0x30, PIN_OUTPUT, 10) /* (AF24) PRG1_PRU0_GPO11.VOUT0_DATA16 */
+ J721E_IOPAD(0x34, PIN_OUTPUT, 10) /* (AJ24) PRG1_PRU0_GPO12.VOUT0_DATA17 */
+ J721E_IOPAD(0x38, PIN_OUTPUT, 10) /* (AG24) PRG1_PRU0_GPO13.VOUT0_DATA18 */
+ J721E_IOPAD(0x3c, PIN_OUTPUT, 10) /* (AD24) PRG1_PRU0_GPO14.VOUT0_DATA19 */
+ J721E_IOPAD(0x40, PIN_OUTPUT, 10) /* (AC24) PRG1_PRU0_GPO15.VOUT0_DATA20 */
+ J721E_IOPAD(0x44, PIN_OUTPUT, 10) /* (AE24) PRG1_PRU0_GPO16.VOUT0_DATA21 */
+ J721E_IOPAD(0x24, PIN_OUTPUT, 10) /* (AJ20) PRG1_PRU0_GPO8.VOUT0_DATA22 */
+ J721E_IOPAD(0x28, PIN_OUTPUT, 10) /* (AG20) PRG1_PRU0_GPO9.VOUT0_DATA23 */
+ J721E_IOPAD(0x9c, PIN_OUTPUT, 10) /* (AC22) PRG1_PRU1_GPO17.VOUT0_DE */
+ J721E_IOPAD(0x98, PIN_OUTPUT, 10) /* (AJ26) PRG1_PRU1_GPO16.VOUT0_HSYNC */
+ J721E_IOPAD(0xa4, PIN_OUTPUT, 10) /* (AH22) PRG1_PRU1_GPO19.VOUT0_PCLK */
+ J721E_IOPAD(0xa0, PIN_OUTPUT, 10) /* (AJ22) PRG1_PRU1_GPO18.VOUT0_VSYNC */
+ >;
+ };
+};
+
+&exp1 {
+ p14-hog {
+ /* P14 - VINOUT_MUX_SEL0 */
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "VINOUT_MUX_SEL0";
+ };
+
+ p15-hog {
+ /* P15 - VINOUT_MUX_SEL1 */
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "VINOUT_MUX_SEL1";
+ };
+};
+
+&main_i2c1 {
+ /* i2c1 is used for DVI DDC, so we need to use 100kHz */
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ exp6: gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_exp6_pins_default>;
+ interrupt-parent = <&main_gpio1>;
+ interrupts = <24 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ p11-hog {
+ /* P11 - HDMI_DDC_OE */
+ gpio-hog;
+ gpios = <9 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "HDMI_DDC_OE";
+ };
+ };
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_vout0_pins_default>;
+};
+
+&dss_ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dpi_out0: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index c7eafbc862f9..0da785be80ff 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -1337,7 +1337,6 @@
reg = <0x00 0x02800000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1349,7 +1348,6 @@
reg = <0x00 0x02810000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1361,7 +1359,6 @@
reg = <0x00 0x02820000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1373,7 +1370,6 @@
reg = <0x00 0x02830000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1385,7 +1381,6 @@
reg = <0x00 0x02840000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1397,7 +1392,6 @@
reg = <0x00 0x02850000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1409,7 +1403,6 @@
reg = <0x00 0x02860000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1421,7 +1414,6 @@
reg = <0x00 0x02870000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1433,7 +1425,6 @@
reg = <0x00 0x02880000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -1445,7 +1436,6 @@
reg = <0x00 0x02890000 0x00 0x100>;
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 0>;
clock-names = "fclk";
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 4618b697fbc4..6b6ef6a30614 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
@@ -34,13 +34,17 @@
};
};
- mcu_conf: syscon@40f00000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x0 0x40f00000 0x0 0x20000>;
+ mcu_conf: bus@40f00000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x40f00000 0x20000>;
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
+
phy_gmii_sel: phy@4040 {
compatible = "ti,am654-phy-gmii-sel";
reg = <0x4040 0x4>;
@@ -243,7 +247,6 @@
reg = <0x00 0x42300000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -255,7 +258,6 @@
reg = <0x00 0x40a00000 0x00 0x100>;
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 0>;
clock-names = "fclk";
@@ -346,10 +348,14 @@
fss: bus@47000000 {
compatible = "simple-bus";
- reg = <0x0 0x47000000 0x0 0x100>;
#address-cells = <2>;
#size-cells = <2>;
- ranges;
+ ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+ <0x0 0x47034000 0x0 0x47034000 0x0 0x100>, /* HBMC Control */
+ <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+ <0x0 0x47050000 0x0 0x47050000 0x0 0x100>, /* OSPI1 Control */
+ <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>, /* HBMC/OSPI0 Memory */
+ <0x7 0x00000000 0x7 0x00000000 0x1 0x0000000>; /* OSPI1 Memory */
hbmc_mux: mux-controller@47000004 {
compatible = "reg-mux";
@@ -544,7 +550,7 @@
reg = <1>;
ti,mac-only;
label = "port1";
- ti,syscon-efuse = <&mcu_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
phys = <&phy_gmii_sel 1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 0c4575ad8d7c..89fbfb21e5d3 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -31,6 +31,7 @@
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 4G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
<0x00000008 0x80000000 0x00000000 0x80000000>;
@@ -210,6 +211,42 @@
<3300000 0x1>;
};
+ transceiver1: can-phy1 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_gpio_pins_default>;
+ standby-gpios = <&wkup_gpio0 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver2: can-phy2 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan0_gpio_pins_default>;
+ standby-gpios = <&main_gpio0 65 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver3: can-phy3 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan5_gpio_pins_default>;
+ standby-gpios = <&main_gpio0 66 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver4: can-phy4 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan9_gpio_pins_default>;
+ standby-gpios = <&main_gpio0 67 GPIO_ACTIVE_HIGH>;
+ };
+
dp_pwr_3v3: fixedregulator-dp-prw {
compatible = "regulator-fixed";
regulator-name = "dp-pwr";
@@ -367,6 +404,45 @@
>;
};
+ main_mcan0_pins_default: main-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x208, PIN_INPUT, 0) /* (W5) MCAN0_RX */
+ J721E_IOPAD(0x20c, PIN_OUTPUT, 0) /* (W6) MCAN0_TX */
+ >;
+ };
+
+ main_mcan0_gpio_pins_default: main-mcan0-gpio-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x108, PIN_INPUT, 7) /* (AD27) PRG0_PRU1_GPO2.GPIO0_65 */
+ >;
+ };
+
+ main_mcan5_pins_default: main-mcan5-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x050, PIN_INPUT, 6) /* (AE21) PRG1_PRU0_GPO18.MCAN5_RX */
+ J721E_IOPAD(0x04c, PIN_OUTPUT, 6) /* (AJ21) PRG1_PRU0_GPO17.MCAN5_TX */
+ >;
+ };
+
+ main_mcan5_gpio_pins_default: main-mcan5-gpio-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x10c, PIN_INPUT, 7) /* (AC25) PRG0_PRU1_GPO3.GPIO0_66 */
+ >;
+ };
+
+ main_mcan9_pins_default: main-mcan9-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x0d0, PIN_INPUT, 6) /* (AC27) PRG0_PRU0_GPO8.MCAN9_RX */
+ J721E_IOPAD(0x0cc, PIN_OUTPUT, 6) /* (AC28) PRG0_PRU0_GPO7.MCAN9_TX */
+ >;
+ };
+
+ main_mcan9_gpio_pins_default: main-mcan9-gpio-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x110, PIN_INPUT, 7) /* (AD29) PRG0_PRU1_GPO4.GPIO0_67 */
+ >;
+ };
+
dp0_pins_default: dp0-default-pins {
pinctrl-single,pins = <
J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */
@@ -555,6 +631,19 @@
>;
};
+ mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x0ac, PIN_INPUT, 0) /* (C29) MCU_MCAN0_RX */
+ J721E_WKUP_IOPAD(0x0a8, PIN_OUTPUT, 0) /* (D29) MCU_MCAN0_TX */
+ >;
+ };
+
+ mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x0bc, PIN_INPUT, 7) /* (F27) WKUP_GPIO0_3 */
+ >;
+ };
+
/* Reset for M.2 M Key slot on PCIe1 */
mkey_reset_pins_default: mkey-reset-pns-default-pins {
pinctrl-single,pins = <
@@ -1108,6 +1197,34 @@
num-lanes = <2>;
};
+&mcu_mcan0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_pins_default>;
+ phys = <&transceiver1>;
+ status = "okay";
+};
+
+&main_mcan0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan0_pins_default>;
+ phys = <&transceiver2>;
+ status = "okay";
+};
+
+&main_mcan5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan5_pins_default>;
+ phys = <&transceiver3>;
+ status = "okay";
+};
+
+&main_mcan9 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan9_pins_default>;
+ phys = <&transceiver4>;
+ status = "okay";
+};
+
&ufs_wrapper {
status = "disabled";
};
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 1fae6495db07..5ba947771b84 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
@@ -12,6 +12,7 @@
/ {
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 4G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
<0x00000008 0x80000000 0x00000000 0x80000000>;
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index b70c8615e3c1..9ed6949b40e9 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -459,7 +459,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02800000 0x00 0x200>;
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 146 3>;
clock-names = "fclk";
power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
@@ -470,7 +469,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02810000 0x00 0x200>;
interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 350 3>;
clock-names = "fclk";
power-domains = <&k3_pds 350 TI_SCI_PD_EXCLUSIVE>;
@@ -481,7 +479,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02820000 0x00 0x200>;
interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 351 3>;
clock-names = "fclk";
power-domains = <&k3_pds 351 TI_SCI_PD_EXCLUSIVE>;
@@ -492,7 +489,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02830000 0x00 0x200>;
interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 352 3>;
clock-names = "fclk";
power-domains = <&k3_pds 352 TI_SCI_PD_EXCLUSIVE>;
@@ -503,7 +499,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02840000 0x00 0x200>;
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 353 3>;
clock-names = "fclk";
power-domains = <&k3_pds 353 TI_SCI_PD_EXCLUSIVE>;
@@ -514,7 +509,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02850000 0x00 0x200>;
interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 354 3>;
clock-names = "fclk";
power-domains = <&k3_pds 354 TI_SCI_PD_EXCLUSIVE>;
@@ -525,7 +519,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02860000 0x00 0x200>;
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 355 3>;
clock-names = "fclk";
power-domains = <&k3_pds 355 TI_SCI_PD_EXCLUSIVE>;
@@ -536,7 +529,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02870000 0x00 0x200>;
interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 356 3>;
clock-names = "fclk";
power-domains = <&k3_pds 356 TI_SCI_PD_EXCLUSIVE>;
@@ -547,7 +539,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02880000 0x00 0x200>;
interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 357 3>;
clock-names = "fclk";
power-domains = <&k3_pds 357 TI_SCI_PD_EXCLUSIVE>;
@@ -558,7 +549,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02890000 0x00 0x200>;
interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 358 3>;
clock-names = "fclk";
power-domains = <&k3_pds 358 TI_SCI_PD_EXCLUSIVE>;
@@ -778,8 +768,6 @@
ti,clkbuf-sel = <0x7>;
ti,trm-icp = <0x8>;
dma-coherent;
- /* Masking support for SDR104 capability */
- sdhci-caps-mask = <0x00000003 0x00000000>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
index eaf7f709440e..8feb42c89e47 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
@@ -139,13 +139,17 @@
ti,interrupt-ranges = <16 960 16>;
};
- mcu_conf: syscon@40f00000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x0 0x40f00000 0x0 0x20000>;
+ mcu_conf: bus@40f00000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x40f00000 0x20000>;
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
+
phy_gmii_sel: phy@4040 {
compatible = "ti,am654-phy-gmii-sel";
reg = <0x4040 0x4>;
@@ -298,7 +302,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x42300000 0x00 0x200>;
interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 359 3>;
clock-names = "fclk";
power-domains = <&k3_pds 359 TI_SCI_PD_EXCLUSIVE>;
@@ -309,7 +312,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x40a00000 0x00 0x200>;
interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 149 3>;
clock-names = "fclk";
power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
@@ -546,7 +548,7 @@
reg = <1>;
ti,mac-only;
label = "port1";
- ti,syscon-efuse = <&mcu_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
phys = <&phy_gmii_sel 1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
index 623c8421525d..82aacc01e8fe 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
@@ -13,9 +13,10 @@
/ {
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 16 GB RAM */
- reg = <0x00 0x80000000 0x00 0x80000000>,
- <0x08 0x80000000 0x03 0x80000000>;
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000003 0x80000000>;
};
/* Reserving memory regions still pending */
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
index be4502fe1c9d..568e6a04619d 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
@@ -117,6 +117,7 @@
#size-cells = <2>;
ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
<0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
+ <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
<0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
<0x00 0x0d800000 0x00 0x0d800000 0x00 0x00800000>, /* PCIe Core*/
<0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
index cee3a8661d5e..dd3b5f7039d7 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -9,7 +9,9 @@
/dts-v1/;
#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
#include "k3-j722s.dtsi"
+#include "k3-serdes.h"
/ {
compatible = "ti,j722s-evm", "ti,j722s";
@@ -105,6 +107,15 @@
<3300000 0x1>;
};
+ vsys_io_3v3: regulator-vsys-io-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_io_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
vsys_io_1v8: regulator-vsys-io-1v8 {
compatible = "regulator-fixed";
regulator-name = "vsys_io_1v8";
@@ -122,6 +133,35 @@
regulator-always-on;
regulator-boot-on;
};
+
+ codec_audio: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "J722S-EVM";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Line", "Line In",
+ "Microphone", "Microphone Jack";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In",
+ "MIC3R", "Microphone Jack",
+ "Microphone Jack", "Mic Bias";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound_master>;
+ simple-audio-card,frame-master = <&sound_master>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp1>;
+ };
+
+ sound_master: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ clocks = <&audio_refclk1>;
+ };
+ };
};
&main_pmx0 {
@@ -202,6 +242,27 @@
J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */
>;
};
+
+ main_usb1_pins_default: main-usb1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0258, PIN_INPUT, 0) /* (B27) USB1_DRVVBUS */
+ >;
+ };
+
+ main_mcasp1_pins_default: main-mcasp1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0090, PIN_INPUT, 2) /* (P27) GPMC0_BE0n_CLE.MCASP1_ACLKX */
+ J722S_IOPAD(0x0098, PIN_INPUT, 2) /* (V21) GPMC0_WAIT0.MCASP1_AFSX */
+ J722S_IOPAD(0x008c, PIN_OUTPUT, 2) /* (N23) GPMC0_WEn.MCASP1_AXR0 */
+ J722S_IOPAD(0x0084, PIN_INPUT, 2) /* (N21) GPMC0_ADVn_ALE.MCASP1_AXR2 */
+ >;
+ };
+
+ audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x00a0, PIN_OUTPUT, 1) /* (N24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */
+ >;
+ };
};
&cpsw3g {
@@ -226,10 +287,7 @@
&cpsw_port1 {
phy-mode = "rgmii-rxid";
phy-handle = <&cpsw3g_phy0>;
-};
-
-&cpsw_port2 {
- status = "disabled";
+ status = "okay";
};
&main_gpio1 {
@@ -280,6 +338,12 @@
bootph-all;
};
+&k3_clks {
+ /* Configure AUDIO_EXT_REFCLK1 pin as output */
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+};
+
&main_i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&main_i2c0_pins_default>;
@@ -304,6 +368,48 @@
"PCIe0_1L_RC_RSTz", "PCIe0_1L_PRSNT#",
"ENET1_EXP_SPARE2", "ENET1_EXP_PWRDN",
"PD_I2ENET1_I2CMUX_SELC_IRQ", "ENET1_EXP_RESETZ";
+
+ p05-hog {
+ /* P05 - USB2.0_MUX_SEL */
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+
+ p01_hog: p01-hog {
+ /* P01 - TRC_MUX_SEL */
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "TRC_MUX_SEL";
+ };
+
+ p02_hog: p02-hog {
+ /* P02 - MCASP1_FET_SEL */
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "MCASP1_FET_SEL";
+ };
+
+ p13_hog: p13-hog {
+ /* P13 - GPIO_AUD_RSTn */
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "GPIO_AUD_RSTn";
+ };
+ };
+
+ tlv320aic3106: audio-codec@1b {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ ai3x-micbias-vg = <1>; /* 2.0V */
+ AVDD-supply = <&vsys_io_3v3>;
+ IOVDD-supply = <&vsys_io_3v3>;
+ DRVDD-supply = <&vsys_io_3v3>;
+ DVDD-supply = <&vsys_io_1v8>;
};
};
@@ -369,6 +475,13 @@
};
+&sdhci0 {
+ disable-wp;
+ bootph-all;
+ ti,driver-strength-ohm = <50>;
+ status = "okay";
+};
+
&sdhci1 {
/* SD/MMC */
vmmc-supply = <&vdd_mmc1>;
@@ -377,7 +490,79 @@
pinctrl-0 = <&main_mmc1_pins_default>;
ti,driver-strength-ohm = <50>;
disable-wp;
- no-1-8-v;
status = "okay";
bootph-all;
};
+
+&serdes_ln_ctrl {
+ idle-states = <J722S_SERDES0_LANE0_USB>,
+ <J722S_SERDES1_LANE0_PCIE0_LANE0>;
+};
+
+&serdes0 {
+ status = "okay";
+ serdes0_usb_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <1>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_USB3>;
+ resets = <&serdes_wiz0 1>;
+ };
+};
+
+&serdes1 {
+ status = "okay";
+ serdes1_pcie_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <1>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ resets = <&serdes_wiz1 1>;
+ };
+};
+
+&pcie0_rc {
+ reset-gpios = <&exp1 18 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes1_pcie_link>;
+ phy-names = "pcie-phy";
+ status = "okay";
+};
+
+&usbss0 {
+ ti,vbus-divider;
+ status = "okay";
+};
+
+&usb0 {
+ dr_mode = "otg";
+ usb-role-switch;
+};
+
+&usbss1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_usb1_pins_default>;
+ ti,vbus-divider;
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "host";
+ maximum-speed = "super-speed";
+ phys = <&serdes0_usb_link>;
+ phy-names = "cdns3,usb3-phy";
+};
+
+&mcasp1 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp1_pins_default>;
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 0 2 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
new file mode 100644
index 000000000000..c797980528ec
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree file for the J722S MAIN domain peripherals
+ *
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <dt-bindings/phy/phy-cadence.h>
+#include <dt-bindings/phy/phy-ti.h>
+
+/ {
+ serdes_refclk: clk-0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+};
+
+&cbass_main {
+ serdes_wiz0: phy@f000000 {
+ compatible = "ti,am64-wiz-10g";
+ ranges = <0x0f000000 0x0 0x0f000000 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&k3_pds 279 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 279 0>, <&k3_clks 279 1>, <&serdes_refclk>;
+ clock-names = "fck", "core_ref_clk", "ext_ref_clk";
+ num-lanes = <1>;
+ #reset-cells = <1>;
+ #clock-cells = <1>;
+
+ assigned-clocks = <&k3_clks 279 1>;
+ assigned-clock-parents = <&k3_clks 279 5>;
+
+ serdes0: serdes@f000000 {
+ compatible = "ti,j721e-serdes-10g";
+ reg = <0x0f000000 0x00010000>;
+ reg-names = "torrent_phy";
+ resets = <&serdes_wiz0 0>;
+ reset-names = "torrent_reset";
+ clocks = <&serdes_wiz0 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz0 TI_WIZ_PHY_EN_REFCLK>;
+ clock-names = "refclk", "phy_en_refclk";
+ assigned-clocks = <&serdes_wiz0 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz0 TI_WIZ_PLL1_REFCLK>,
+ <&serdes_wiz0 TI_WIZ_REFCLK_DIG>;
+ assigned-clock-parents = <&k3_clks 279 1>,
+ <&k3_clks 279 1>,
+ <&k3_clks 279 1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+
+ status = "disabled"; /* Needs lane config */
+ };
+ };
+
+ serdes_wiz1: phy@f010000 {
+ compatible = "ti,am64-wiz-10g";
+ ranges = <0x0f010000 0x0 0x0f010000 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&k3_pds 280 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 280 0>, <&k3_clks 280 1>, <&serdes_refclk>;
+ clock-names = "fck", "core_ref_clk", "ext_ref_clk";
+ num-lanes = <1>;
+ #reset-cells = <1>;
+ #clock-cells = <1>;
+
+ assigned-clocks = <&k3_clks 280 1>;
+ assigned-clock-parents = <&k3_clks 280 5>;
+
+ serdes1: serdes@f010000 {
+ compatible = "ti,j721e-serdes-10g";
+ reg = <0x0f010000 0x00010000>;
+ reg-names = "torrent_phy";
+ resets = <&serdes_wiz1 0>;
+ reset-names = "torrent_reset";
+ clocks = <&serdes_wiz1 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz1 TI_WIZ_PHY_EN_REFCLK>;
+ clock-names = "refclk", "phy_en_refclk";
+ assigned-clocks = <&serdes_wiz1 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz1 TI_WIZ_PLL1_REFCLK>,
+ <&serdes_wiz1 TI_WIZ_REFCLK_DIG>;
+ assigned-clock-parents = <&k3_clks 280 1>,
+ <&k3_clks 280 1>,
+ <&k3_clks 280 1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+
+ status = "disabled"; /* Needs lane config */
+ };
+ };
+
+ pcie0_rc: pcie@f102000 {
+ compatible = "ti,j722s-pcie-host", "ti,j721e-pcie-host";
+ reg = <0x00 0x0f102000 0x00 0x1000>,
+ <0x00 0x0f100000 0x00 0x400>,
+ <0x00 0x0d000000 0x00 0x00800000>,
+ <0x00 0x68000000 0x00 0x00001000>;
+ reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
+ ranges = <0x01000000 0x00 0x68001000 0x00 0x68001000 0x00 0x0010000>,
+ <0x02000000 0x00 0x68011000 0x00 0x68011000 0x00 0x7fef000>;
+ dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+ interrupt-names = "link_state";
+ interrupts = <GIC_SPI 99 IRQ_TYPE_EDGE_RISING>;
+ device_type = "pci";
+ max-link-speed = <3>;
+ num-lanes = <1>;
+ power-domains = <&k3_pds 259 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 259 0>, <&serdes1 CDNS_TORRENT_REFCLK_DRIVER>;
+ clock-names = "fck", "pcie_refclk";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x104c>;
+ device-id = <0xb010>;
+ cdns,no-bar-match-nbits = <64>;
+ ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
+ msi-map = <0x0 &gic_its 0x0 0x10000>;
+ status = "disabled";
+ };
+
+ usbss1: usb@f920000 {
+ compatible = "ti,j721e-usb";
+ reg = <0x00 0x0f920000 0x00 0x100>;
+ power-domains = <&k3_pds 278 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 278 3>, <&k3_clks 278 1>;
+ clock-names = "ref", "lpm";
+ assigned-clocks = <&k3_clks 278 3>; /* USB2_REFCLK */
+ assigned-clock-parents = <&k3_clks 278 4>; /* HF0SC0 */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ status = "disabled";
+
+ usb1: usb@31200000{
+ compatible = "cdns,usb3";
+ reg = <0x00 0x31200000 0x00 0x10000>,
+ <0x00 0x31210000 0x00 0x10000>,
+ <0x00 0x31220000 0x00 0x10000>;
+ reg-names = "otg",
+ "xhci",
+ "dev";
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>, /* irq.6 */
+ <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>; /* otgirq */
+ interrupt-names = "host",
+ "peripheral",
+ "otg";
+ maximum-speed = "super-speed";
+ dr_mode = "otg";
+ };
+ };
+};
+
+&main_conf {
+ serdes_ln_ctrl: mux-controller@4080 {
+ compatible = "reg-mux";
+ reg = <0x4080 0x14>;
+ #mux-control-cells = <1>;
+ mux-reg-masks = <0x00 0x3>, /* SERDES0 lane0 select */
+ <0x10 0x3>; /* SERDES1 lane0 select */
+ };
+
+ audio_refclk1: clock@82e4 {
+ compatible = "ti,am62-audio-refclk";
+ reg = <0x82e4 0x4>;
+ clocks = <&k3_clks 157 18>;
+ assigned-clocks = <&k3_clks 157 18>;
+ assigned-clock-parents = <&k3_clks 157 33>;
+ #clock-cells = <0>;
+ };
+};
+
+&wkup_conf {
+ pcie0_ctrl: pcie0-ctrl@4070 {
+ compatible = "ti,j784s4-pcie-ctrl", "syscon";
+ reg = <0x4070 0x4>;
+ };
+};
+
+&oc_sram {
+ reg = <0x00 0x70000000 0x00 0x40000>;
+ ranges = <0x00 0x00 0x70000000 0x40000>;
+};
+
+&inta_main_dmss {
+ ti,interrupt-ranges = <7 71 21>;
+};
+
+&main_pmx0 {
+ pinctrl-single,gpio-range =
+ <&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 33 55 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 101 25 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 137 5 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 143 3 PIN_GPIO_RANGE_IOPAD>,
+ <&main_pmx0_range 149 2 PIN_GPIO_RANGE_IOPAD>;
+
+ main_pmx0_range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
+};
+
+&main_gpio0 {
+ gpio-ranges = <&main_pmx0 0 0 32>, <&main_pmx0 32 33 38>,
+ <&main_pmx0 70 72 17>;
+ ti,ngpio = <87>;
+};
+
+&main_gpio1 {
+ gpio-ranges = <&main_pmx0 7 101 25>, <&main_pmx0 42 137 5>,
+ <&main_pmx0 47 143 3>, <&main_pmx0 50 149 2>;
+ ti,ngpio = <73>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j722s.dtsi b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
index c75744edb143..14c6c6a332ef 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
@@ -10,11 +10,133 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/soc/ti,sci_pm_domain.h>
-#include "k3-am62p5.dtsi"
+#include "k3-pinctrl.h"
/ {
model = "Texas Instruments K3 J722S SoC";
compatible = "ti,j722s";
+ interrupt-parent = <&gic500>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0: cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+
+ core2 {
+ cpu = <&cpu2>;
+ };
+
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a53";
+ reg = <0x000>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ 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>;
+ clocks = <&k3_clks 135 0>;
+ };
+
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a53";
+ reg = <0x001>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ 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>;
+ clocks = <&k3_clks 136 0>;
+ };
+
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a53";
+ reg = <0x002>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ 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>;
+ clocks = <&k3_clks 137 0>;
+ };
+
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a53";
+ reg = <0x003>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ 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>;
+ clocks = <&k3_clks 138 0>;
+ };
+ };
+
+ l2_0: l2-cache0 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+
+ psci: psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+ };
+
+ a53_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,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
cbass_main: bus@f0000 {
compatible = "simple-bus";
@@ -74,16 +196,39 @@
<0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
<0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>,
<0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>;
- };
-};
-/* Main domain overrides */
+ cbass_mcu: bus@4000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x04000000 0x00 0x04000000 0x00 0x01ff1400>, /* Peripheral window */
+ <0x00 0x79000000 0x00 0x79000000 0x00 0x00008000>, /* MCU R5 ATCM */
+ <0x00 0x79020000 0x00 0x79020000 0x00 0x00008000>, /* MCU R5 BTCM */
+ <0x00 0x79100000 0x00 0x79100000 0x00 0x00040000>, /* MCU IRAM0 */
+ <0x00 0x79140000 0x00 0x79140000 0x00 0x00040000>; /* MCU IRAM1 */
+ bootph-all;
+ };
-&inta_main_dmss {
- ti,interrupt-ranges = <7 71 21>;
-};
+ cbass_wakeup: bus@b00000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>, /* VTM */
+ <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>, /* Peripheral Window */
+ <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>, /* WKUP CTRL MMR */
+ <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM*/
+ <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM*/
+ bootph-all;
+ };
+ };
-&oc_sram {
- reg = <0x00 0x70000000 0x00 0x40000>;
- ranges = <0x00 0x00 0x70000000 0x40000>;
+ #include "k3-am62p-j722s-common-thermal.dtsi"
};
+
+/* Include peripherals shared with AM62P */
+#include "k3-am62p-j722s-common-main.dtsi"
+#include "k3-am62p-j722s-common-mcu.dtsi"
+#include "k3-am62p-j722s-common-wakeup.dtsi"
+
+/* Include J722S specific peripherals */
+#include "k3-j722s-main.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso
new file mode 100644
index 000000000000..685305092bd8
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE0 and PCIE1 instances in Endpoint Configuration
+ * on J784S4 EVM.
+ *
+ * J784S4 EVM Product Link: https://www.ti.com/tool/J784S4XEVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie0_rc {
+ status = "disabled";
+};
+
+&pcie1_rc {
+ status = "disabled";
+};
+
+&cbass_main {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&gic500>;
+
+ pcie0_ep: pcie-ep@2900000 {
+ compatible = "ti,j784s4-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 0x0>;
+ max-link-speed = <3>;
+ num-lanes = <4>;
+ power-domains = <&k3_pds 332 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 332 0>;
+ clock-names = "fck";
+ max-functions = /bits/ 8 <6>;
+ max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+ dma-coherent;
+ phys = <&serdes1_pcie0_link>;
+ phy-names = "pcie-phy";
+ };
+
+ pcie1_ep: pcie-ep@2910000 {
+ compatible = "ti,j784s4-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 0x0>;
+ max-link-speed = <3>;
+ num-lanes = <2>;
+ power-domains = <&k3_pds 333 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 333 0>;
+ clock-names = "fck";
+ max-functions = /bits/ 8 <6>;
+ max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+ dma-coherent;
+ phys = <&serdes0_pcie1_link>;
+ phy-names = "pcie-phy";
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso
new file mode 100644
index 000000000000..dcd2c7c39ec3
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/**
+ * DT Overlay for CPSW9G in QSGMII mode using J7 Quad Port ETH EXP Add-On Ethernet Card with
+ * J784S4 EVM. The Add-On Ethernet Card has to be connected to ENET Expansion 1 slot on the
+ * board.
+ *
+ * Product Datasheet: https://www.ti.com/lit/ug/spruj74/spruj74.pdf
+ *
+ * Link to QSGMII Daughtercard: https://www.ti.com/tool/J721EXENETXPANEVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy-cadence.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-pinctrl.h"
+#include "k3-serdes.h"
+
+&{/} {
+ aliases {
+ ethernet1 = "/bus@100000/ethernet@c000000/ethernet-ports/port@5";
+ ethernet2 = "/bus@100000/ethernet@c000000/ethernet-ports/port@6";
+ ethernet3 = "/bus@100000/ethernet@c000000/ethernet-ports/port@7";
+ ethernet4 = "/bus@100000/ethernet@c000000/ethernet-ports/port@8";
+ ethernet5 = "/bus@100000/ethernet@c200000/ethernet-ports/port@1";
+ };
+};
+
+&main_cpsw0 {
+ status = "okay";
+};
+
+&main_cpsw0_port5 {
+ phy-handle = <&cpsw9g_phy1>;
+ phy-mode = "qsgmii";
+ mac-address = [00 00 00 00 00 00];
+ phys = <&cpsw0_phy_gmii_sel 5>, <&serdes2_qsgmii_link>;
+ phy-names = "mac", "serdes";
+ status = "okay";
+};
+
+&main_cpsw0_port6 {
+ phy-handle = <&cpsw9g_phy2>;
+ phy-mode = "qsgmii";
+ mac-address = [00 00 00 00 00 00];
+ phys = <&cpsw0_phy_gmii_sel 6>, <&serdes2_qsgmii_link>;
+ phy-names = "mac", "serdes";
+ status = "okay";
+};
+
+&main_cpsw0_port7 {
+ phy-handle = <&cpsw9g_phy0>;
+ phy-mode = "qsgmii";
+ mac-address = [00 00 00 00 00 00];
+ phys = <&cpsw0_phy_gmii_sel 7>, <&serdes2_qsgmii_link>;
+ phy-names = "mac", "serdes";
+ status = "okay";
+};
+
+&main_cpsw0_port8 {
+ phy-handle = <&cpsw9g_phy3>;
+ phy-mode = "qsgmii";
+ mac-address = [00 00 00 00 00 00];
+ phys = <&cpsw0_phy_gmii_sel 8>, <&serdes2_qsgmii_link>;
+ phy-names = "mac", "serdes";
+ status = "okay";
+};
+
+&main_cpsw0_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_default_pins>;
+ bus_freq = <1000000>;
+ reset-gpios = <&exp2 17 GPIO_ACTIVE_LOW>;
+ reset-post-delay-us = <120000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ cpsw9g_phy0: ethernet-phy@16 {
+ reg = <16>;
+ };
+ cpsw9g_phy1: ethernet-phy@17 {
+ reg = <17>;
+ };
+ cpsw9g_phy2: ethernet-phy@18 {
+ reg = <18>;
+ };
+ cpsw9g_phy3: ethernet-phy@19 {
+ reg = <19>;
+ };
+};
+
+&exp2 {
+ /* Power-up ENET1 EXPANDER PHY. */
+ qsgmii-line-hog {
+ gpio-hog;
+ gpios = <16 GPIO_ACTIVE_HIGH>;
+ output-low;
+ };
+
+ /* Toggle MUX2 for MDIO lines */
+ mux-sel-hog {
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>, <14 GPIO_ACTIVE_HIGH>, <15 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+};
+
+&main_pmx0 {
+ mdio0_default_pins: mdio0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x05c, PIN_INPUT, 4) /* (AC36) MCASP2_AXR0.MDIO1_MDIO */
+ J784S4_IOPAD(0x058, PIN_INPUT, 4) /* (AE37) MCASP2_AFSX.MDIO1_MDC */
+ >;
+ };
+};
+
+&serdes_ln_ctrl {
+ idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
+ <J784S4_SERDES0_LANE2_IP3_UNUSED>, <J784S4_SERDES0_LANE3_USB>,
+ <J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
+ <J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
+ <J784S4_SERDES2_LANE0_QSGMII_LANE5>, <J784S4_SERDES2_LANE1_QSGMII_LANE6>,
+ <J784S4_SERDES2_LANE2_QSGMII_LANE7>, <J784S4_SERDES2_LANE3_QSGMII_LANE8>;
+};
+
+&serdes_wiz2 {
+ status = "okay";
+};
+
+&serdes2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ serdes2_qsgmii_link: phy@0 {
+ reg = <2>;
+ cdns,num-lanes = <1>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_QSGMII>;
+ resets = <&serdes_wiz2 3>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm-usxgmii-exp1-exp2.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-usxgmii-exp1-exp2.dtso
new file mode 100644
index 000000000000..d5f8c8531923
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-usxgmii-exp1-exp2.dtso
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/**
+ * DT Overlay for CPSW9G in dual port fixed-link USXGMII mode using ENET-1
+ * and ENET-2 Expansion slots of J784S4 EVM.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy-cadence.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&{/} {
+ aliases {
+ ethernet1 = "/bus@100000/ethernet@c000000/ethernet-ports/port@1";
+ ethernet2 = "/bus@100000/ethernet@c000000/ethernet-ports/port@2";
+ ethernet3 = "/bus@100000/ethernet@c200000/ethernet-ports/port@1";
+ };
+};
+
+&main_cpsw0 {
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&main_cpsw0_port1 {
+ phy-mode = "usxgmii";
+ mac-address = [00 00 00 00 00 00];
+ phys = <&cpsw0_phy_gmii_sel 1>, <&serdes2_usxgmii_link>;
+ phy-names = "mac", "serdes";
+ status = "okay";
+ fixed-link {
+ speed = <5000>;
+ full-duplex;
+ };
+};
+
+&main_cpsw0_port2 {
+ phy-mode = "usxgmii";
+ mac-address = [00 00 00 00 00 00];
+ phys = <&cpsw0_phy_gmii_sel 2>, <&serdes2_usxgmii_link>;
+ phy-names = "mac", "serdes";
+ status = "okay";
+ fixed-link {
+ speed = <5000>;
+ full-duplex;
+ };
+};
+
+&serdes_wiz2 {
+ assigned-clock-parents = <&k3_clks 406 9>; /* Use 156.25 MHz clock for USXGMII */
+ status = "okay";
+};
+
+&serdes2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ serdes2_usxgmii_link: phy@2 {
+ reg = <2>;
+ cdns,num-lanes = <2>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_USXGMII>;
+ resets = <&serdes_wiz2 3>, <&serdes_wiz2 4>;
+ };
+};
+
+&serdes_ln_ctrl {
+ idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
+ <J784S4_SERDES0_LANE2_IP3_UNUSED>, <J784S4_SERDES0_LANE3_USB>,
+ <J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
+ <J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
+ <J784S4_SERDES2_LANE0_IP2_UNUSED>, <J784S4_SERDES2_LANE1_IP2_UNUSED>,
+ <J784S4_SERDES2_LANE2_QSGMII_LANE1>, <J784S4_SERDES2_LANE3_QSGMII_LANE2>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 81fd7afac8c5..9338d987180d 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -27,14 +27,16 @@
mmc1 = &main_sdhci1;
i2c0 = &wkup_i2c0;
i2c3 = &main_i2c0;
+ ethernet0 = &mcu_cpsw_port1;
+ ethernet1 = &main_cpsw1_port1;
};
memory@80000000 {
device_type = "memory";
bootph-all;
/* 32G RAM */
- reg = <0x00 0x80000000 0x00 0x80000000>,
- <0x08 0x80000000 0x07 0x80000000>;
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000007 0x80000000>;
};
reserved_memory: reserved-memory {
@@ -272,6 +274,59 @@
};
};
};
+
+ transceiver0: can-phy0 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_gpio_pins_default>;
+ standby-gpios = <&wkup_gpio0 69 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver1: can-phy1 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan1_gpio_pins_default>;
+ standby-gpios = <&wkup_gpio0 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver2: can-phy2 {
+ /* standby pin has been grounded by default */
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ };
+
+ transceiver3: can-phy3 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ standby-gpios = <&exp2 7 GPIO_ACTIVE_HIGH>;
+ mux-states = <&mux1 1>;
+ };
+
+ mux1: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&exp2 14 GPIO_ACTIVE_HIGH>;
+ idle-state = <1>;
+ };
+
+ codec_audio: sound {
+ compatible = "ti,j7200-cpb-audio";
+ model = "j784s4-cpb";
+
+ ti,cpb-mcasp = <&mcasp0>;
+ ti,cpb-codec = <&pcm3168a_1>;
+
+ clocks = <&k3_clks 265 0>, <&k3_clks 265 1>,
+ <&k3_clks 157 34>, <&k3_clks 157 63>;
+ clock-names = "cpb-mcasp-auxclk", "cpb-mcasp-auxclk-48000",
+ "cpb-codec-scki", "cpb-codec-scki-48000";
+ };
};
&wkup_gpio0 {
@@ -280,6 +335,30 @@
&main_pmx0 {
bootph-all;
+ main_cpsw2g_default_pins: main-cpsw2g-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x0b8, PIN_INPUT, 6) /* (AC34) MCASP1_ACLKX.RGMII1_RD0 */
+ J784S4_IOPAD(0x0a0, PIN_INPUT, 6) /* (AD34) MCASP0_AXR12.RGMII1_RD1 */
+ J784S4_IOPAD(0x0a4, PIN_INPUT, 6) /* (AJ36) MCASP0_AXR13.RGMII1_RD2 */
+ J784S4_IOPAD(0x0a8, PIN_INPUT, 6) /* (AF34) MCASP0_AXR14.RGMII1_RD3 */
+ J784S4_IOPAD(0x0b0, PIN_INPUT, 6) /* (AL33) MCASP1_AXR3.RGMII1_RXC */
+ J784S4_IOPAD(0x0ac, PIN_INPUT, 6) /* (AE34) MCASP0_AXR15.RGMII1_RX_CTL */
+ J784S4_IOPAD(0x08c, PIN_INPUT, 6) /* (AE35) MCASP0_AXR7.RGMII1_TD0 */
+ J784S4_IOPAD(0x090, PIN_INPUT, 6) /* (AC35) MCASP0_AXR8.RGMII1_TD1 */
+ J784S4_IOPAD(0x094, PIN_INPUT, 6) /* (AG35) MCASP0_AXR9.RGMII1_TD2 */
+ J784S4_IOPAD(0x098, PIN_INPUT, 6) /* (AH36) MCASP0_AXR10.RGMII1_TD3 */
+ J784S4_IOPAD(0x0b4, PIN_INPUT, 6) /* (AL34) MCASP1_AXR4.RGMII1_TXC */
+ J784S4_IOPAD(0x09c, PIN_INPUT, 6) /* (AF35) MCASP0_AXR11.RGMII1_TX_CTL */
+ >;
+ };
+
+ main_cpsw2g_mdio_default_pins: main-cpsw2g-mdio-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x0c0, PIN_INPUT, 6) /* (AD38) MCASP1_AXR0.MDIO0_MDC */
+ J784S4_IOPAD(0x0bc, PIN_INPUT, 6) /* (AD33) MCASP1_AFSX.MDIO0_MDIO */
+ >;
+ };
+
main_uart8_pins_default: main-uart8-default-pins {
bootph-all;
pinctrl-single,pins = <
@@ -336,6 +415,49 @@
J784S4_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AH33) MCAN13_RX.I2C4_SDA */
>;
};
+
+ main_mcan4_pins_default: main-mcan4-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x088, PIN_INPUT, 0) /* (AF36) MCAN4_RX */
+ J784S4_IOPAD(0x084, PIN_OUTPUT, 0) /* (AG38) MCAN4_TX */
+ >;
+ };
+
+ main_mcan16_pins_default: main-mcan16-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x028, PIN_INPUT, 0) /* (AE33) MCAN16_RX */
+ J784S4_IOPAD(0x024, PIN_OUTPUT, 0) /* (AH34) MCAN16_TX */
+ >;
+ };
+
+ main_usbss0_pins_default: main-usbss0-default-pins {
+ bootph-all;
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
+ >;
+ };
+
+ main_i2c3_pins_default: main-i2c3-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x064, PIN_INPUT, 13) /* (AF38) MCAN0_TX.I2C3_SCL */
+ J784S4_IOPAD(0x060, PIN_INPUT, 13) /* (AE36) MCASP2_AXR1.I2C3_SDA */
+ >;
+ };
+
+ main_mcasp0_pins_default: main-mcasp0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x038, PIN_OUTPUT_PULLDOWN, 1) /* (AK35) MCASP0_ACLKX */
+ J784S4_IOPAD(0x03c, PIN_OUTPUT_PULLDOWN, 1) /* (AK38) MCASP0_AFSX */
+ J784S4_IOPAD(0x07c, PIN_OUTPUT_PULLDOWN, 1) /* (AJ38) MCASP0_AXR3 */
+ J784S4_IOPAD(0x080, PIN_INPUT_PULLDOWN, 1) /* (AK34) MCASP0_AXR4 */
+ >;
+ };
+
+ audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x078, PIN_OUTPUT, 1) /* (AH37) MCAN2_RX.AUDIO_EXT_REFCLK1 */
+ >;
+ };
};
&wkup_pmx2 {
@@ -343,16 +465,16 @@
wkup_uart0_pins_default: wkup-uart0-default-pins {
bootph-all;
pinctrl-single,pins = <
- J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
- J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
+ J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
+ J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */
>;
};
wkup_i2c0_pins_default: wkup-i2c0-default-pins {
bootph-all;
pinctrl-single,pins = <
- J721S2_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
- J721S2_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
+ J784S4_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
+ J784S4_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
>;
};
@@ -415,6 +537,32 @@
J784S4_WKUP_IOPAD(0x108, PIN_INPUT, 0) /* (Y36) MCU_ADC1_AIN7 */
>;
};
+
+ mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */
+ J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */
+ >;
+ };
+
+ mcu_mcan1_pins_default: mcu-mcan1-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */
+ J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */
+ >;
+ };
+
+ mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x040, PIN_INPUT, 7) /* (J38) MCU_SPI0_D1.WKUP_GPIO0_69 */
+ >;
+ };
+
+ mcu_mcan1_gpio_pins_default: mcu-mcan1-gpio-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x060, PIN_INPUT, 7) /* (J35) WKUP_GPIO0_2 */
+ >;
+ };
};
&wkup_pmx1 {
@@ -579,6 +727,27 @@
};
};
};
+
+ tps62873a: regulator@40 {
+ compatible = "ti,tps62873";
+ reg = <0x40>;
+ bootph-pre-ram;
+ regulator-name = "VDD_CPU_AVS";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1330000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ tps62873b: regulator@43 {
+ compatible = "ti,tps62873";
+ reg = <0x43>;
+ regulator-name = "VDD_CORE_0V8";
+ regulator-min-microvolt = <760000>;
+ regulator-max-microvolt = <840000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
};
&mcu_uart0 {
@@ -748,6 +917,14 @@
"PCIE0_4L_RC_RSTZ", "PCIE0_4L_EP_RST_EN", "PCIE1_4L_PRSNT#",
"PCIE0_4L_PRSNT#", "CDCI1_OE1/OE4", "CDCI1_OE2/OE3",
"AUDIO_MUX_SEL", "EXP_MUX2", "EXP_MUX3", "GESI_EXP_PHY_RSTZ";
+
+ p12-hog {
+ /* P12 - AUDIO_MUX_SEL */
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "AUDIO_MUX_SEL";
+ };
};
exp2: gpio@22 {
@@ -763,6 +940,22 @@
"CANUART_MUX1_SEL1", "ENET1_EXP_PWRDN", "ENET1_EXP_RESETZ",
"ENET1_I2CMUX_SEL", "ENET1_EXP_SPARE2", "ENET2_EXP_RESETZ",
"USER_INPUT1", "USER_LED1", "USER_LED2";
+
+ p13-hog {
+ /* P13 - CANUART_MUX_SEL0 */
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "CANUART_MUX_SEL0";
+ };
+
+ p15-hog {
+ /* P15 - CANUART_MUX1_SEL1 */
+ gpio-hog;
+ gpios = <15 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "CANUART_MUX1_SEL1";
+ };
};
};
@@ -832,6 +1025,31 @@
phy-handle = <&mcu_phy0>;
};
+&main_cpsw1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_cpsw2g_default_pins>;
+ status = "okay";
+};
+
+&main_cpsw1_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_cpsw2g_mdio_default_pins>;
+ status = "okay";
+
+ main_cpsw1_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>;
+ ti,min-output-impedance;
+ };
+};
+
+&main_cpsw1_port1 {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&main_cpsw1_phy0>;
+ status = "okay";
+};
+
&mailbox0_cluster0 {
status = "okay";
interrupts = <436>;
@@ -1041,6 +1259,40 @@
<&k3_clks 218 22>;
};
+&serdes0 {
+ status = "okay";
+
+ serdes0_usb_link: phy@3 {
+ reg = <3>;
+ cdns,num-lanes = <1>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_USB3>;
+ resets = <&serdes_wiz0 4>;
+ };
+};
+
+&serdes_wiz0 {
+ status = "okay";
+};
+
+&usb_serdes_mux {
+ idle-states = <0>; /* USB0 to SERDES lane 3 */
+};
+
+&usbss0 {
+ status = "okay";
+ pinctrl-0 = <&main_usbss0_pins_default>;
+ pinctrl-names = "default";
+ ti,vbus-divider;
+};
+
+&usb0 {
+ dr_mode = "otg";
+ maximum-speed = "super-speed";
+ phys = <&serdes0_usb_link>;
+ phy-names = "cdns3,usb3-phy";
+};
+
&serdes_wiz4 {
status = "okay";
};
@@ -1105,3 +1357,130 @@
};
};
};
+
+&mcu_mcan0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_pins_default>;
+ phys = <&transceiver0>;
+};
+
+&mcu_mcan1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan1_pins_default>;
+ phys = <&transceiver1>;
+};
+
+&main_mcan16 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan16_pins_default>;
+ phys = <&transceiver2>;
+};
+
+&main_mcan4 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan4_pins_default>;
+ phys = <&transceiver3>;
+};
+
+&serdes0 {
+ status = "okay";
+
+ serdes0_pcie1_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <4>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>,
+ <&serdes_wiz0 3>, <&serdes_wiz0 4>;
+ };
+};
+
+&serdes_wiz0 {
+ status = "okay";
+};
+
+&pcie1_rc {
+ status = "okay";
+ num-lanes = <2>;
+ reset-gpios = <&exp1 2 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_pcie1_link>;
+ phy-names = "pcie-phy";
+};
+
+&serdes1 {
+ status = "okay";
+
+ serdes1_pcie0_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <2>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ resets = <&serdes_wiz1 1>, <&serdes_wiz1 2>;
+ };
+};
+
+&serdes_wiz1 {
+ status = "okay";
+};
+
+&pcie0_rc {
+ status = "okay";
+ reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes1_pcie0_link>;
+ phy-names = "pcie-phy";
+};
+
+&k3_clks {
+ /* Confiure AUDIO_EXT_REFCLK1 pin as output */
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+};
+
+&main_i2c3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c3_pins_default>;
+ clock-frequency = <400000>;
+
+ exp3: gpio@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pcm3168a_1: audio-codec@44 {
+ compatible = "ti,pcm3168a";
+ reg = <0x44>;
+ #sound-dai-cells = <1>;
+ reset-gpios = <&exp3 0 GPIO_ACTIVE_LOW>;
+ clocks = <&audio_refclk1>;
+ clock-names = "scki";
+ VDD1-supply = <&vsys_3v3>;
+ VDD2-supply = <&vsys_3v3>;
+ VCCAD1-supply = <&vsys_5v0>;
+ VCCAD2-supply = <&vsys_5v0>;
+ VCCDA1-supply = <&vsys_5v0>;
+ VCCDA2-supply = <&vsys_5v0>;
+ };
+};
+
+&mcasp0 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp0_pins_default>;
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ auxclk-fs-ratio = <256>;
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 0 1
+ 2 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index b67c37460a73..f170f80f00c1 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -48,6 +48,39 @@
#size-cells = <1>;
ranges = <0x00 0x00 0x00100000 0x1c000>;
+ cpsw1_phy_gmii_sel: phy@4034 {
+ compatible = "ti,am654-phy-gmii-sel";
+ reg = <0x4034 0x4>;
+ #phy-cells = <1>;
+ };
+
+ cpsw0_phy_gmii_sel: phy@4044 {
+ compatible = "ti,j784s4-cpsw9g-phy-gmii-sel";
+ reg = <0x4044 0x20>;
+ #phy-cells = <1>;
+ ti,qsgmii-main-ports = <7>, <7>;
+ };
+
+ pcie0_ctrl: pcie0-ctrl@4070 {
+ compatible = "ti,j784s4-pcie-ctrl", "syscon";
+ reg = <0x4070 0x4>;
+ };
+
+ pcie1_ctrl: pcie1-ctrl@4074 {
+ compatible = "ti,j784s4-pcie-ctrl", "syscon";
+ reg = <0x4074 0x4>;
+ };
+
+ pcie2_ctrl: pcie2-ctrl@4078 {
+ compatible = "ti,j784s4-pcie-ctrl", "syscon";
+ reg = <0x4078 0x4>;
+ };
+
+ pcie3_ctrl: pcie3-ctrl@407c {
+ compatible = "ti,j784s4-pcie-ctrl", "syscon";
+ reg = <0x407c 0x4>;
+ };
+
serdes_ln_ctrl: mux-controller@4080 {
compatible = "reg-mux";
reg = <0x00004080 0x30>;
@@ -75,6 +108,88 @@
<J784S4_SERDES4_LANE2_EDP_LANE2>,
<J784S4_SERDES4_LANE3_EDP_LANE3>;
};
+
+ usb_serdes_mux: mux-controller@4000 {
+ compatible = "reg-mux";
+ reg = <0x4000 0x4>;
+ #mux-control-cells = <1>;
+ mux-reg-masks = <0x0 0x8000000>; /* USB0 to SERDES0 lane 3 mux */
+ };
+
+ ehrpwm_tbclk: clock-controller@4140 {
+ compatible = "ti,am654-ehrpwm-tbclk";
+ reg = <0x4140 0x18>;
+ #clock-cells = <1>;
+ };
+
+ audio_refclk1: clock@82e4 {
+ compatible = "ti,am62-audio-refclk";
+ reg = <0x82e4 0x4>;
+ clocks = <&k3_clks 157 34>;
+ assigned-clocks = <&k3_clks 157 34>;
+ assigned-clock-parents = <&k3_clks 157 63>;
+ #clock-cells = <0>;
+ };
+ };
+
+ main_ehrpwm0: pwm@3000000 {
+ compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
+ reg = <0x00 0x3000000 0x00 0x100>;
+ clocks = <&ehrpwm_tbclk 0>, <&k3_clks 219 0>;
+ clock-names = "tbclk", "fck";
+ power-domains = <&k3_pds 219 TI_SCI_PD_EXCLUSIVE>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ main_ehrpwm1: pwm@3010000 {
+ compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
+ reg = <0x00 0x3010000 0x00 0x100>;
+ clocks = <&ehrpwm_tbclk 1>, <&k3_clks 220 0>;
+ clock-names = "tbclk", "fck";
+ power-domains = <&k3_pds 220 TI_SCI_PD_EXCLUSIVE>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ main_ehrpwm2: pwm@3020000 {
+ compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
+ reg = <0x00 0x3020000 0x00 0x100>;
+ clocks = <&ehrpwm_tbclk 2>, <&k3_clks 221 0>;
+ clock-names = "tbclk", "fck";
+ power-domains = <&k3_pds 221 TI_SCI_PD_EXCLUSIVE>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ main_ehrpwm3: pwm@3030000 {
+ compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
+ reg = <0x00 0x3030000 0x00 0x100>;
+ clocks = <&ehrpwm_tbclk 3>, <&k3_clks 222 0>;
+ clock-names = "tbclk", "fck";
+ power-domains = <&k3_pds 222 TI_SCI_PD_EXCLUSIVE>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ main_ehrpwm4: pwm@3040000 {
+ compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
+ reg = <0x00 0x3040000 0x00 0x100>;
+ clocks = <&ehrpwm_tbclk 4>, <&k3_clks 223 0>;
+ clock-names = "tbclk", "fck";
+ power-domains = <&k3_pds 223 TI_SCI_PD_EXCLUSIVE>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ main_ehrpwm5: pwm@3050000 {
+ compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
+ reg = <0x00 0x3050000 0x00 0x100>;
+ clocks = <&ehrpwm_tbclk 5>, <&k3_clks 224 0>;
+ clock-names = "tbclk", "fck";
+ power-domains = <&k3_pds 224 TI_SCI_PD_EXCLUSIVE>;
+ #pwm-cells = <3>;
+ status = "disabled";
};
gic500: interrupt-controller@1800000 {
@@ -404,7 +519,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02800000 0x00 0x200>;
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 146 0>;
clock-names = "fclk";
power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
@@ -415,7 +529,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02810000 0x00 0x200>;
interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 388 0>;
clock-names = "fclk";
power-domains = <&k3_pds 388 TI_SCI_PD_EXCLUSIVE>;
@@ -426,7 +539,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02820000 0x00 0x200>;
interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 389 0>;
clock-names = "fclk";
power-domains = <&k3_pds 389 TI_SCI_PD_EXCLUSIVE>;
@@ -437,7 +549,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02830000 0x00 0x200>;
interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 390 0>;
clock-names = "fclk";
power-domains = <&k3_pds 390 TI_SCI_PD_EXCLUSIVE>;
@@ -448,7 +559,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02840000 0x00 0x200>;
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 391 0>;
clock-names = "fclk";
power-domains = <&k3_pds 391 TI_SCI_PD_EXCLUSIVE>;
@@ -459,7 +569,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02850000 0x00 0x200>;
interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 392 0>;
clock-names = "fclk";
power-domains = <&k3_pds 392 TI_SCI_PD_EXCLUSIVE>;
@@ -470,7 +579,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02860000 0x00 0x200>;
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 393 0>;
clock-names = "fclk";
power-domains = <&k3_pds 393 TI_SCI_PD_EXCLUSIVE>;
@@ -481,7 +589,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02870000 0x00 0x200>;
interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 394 0>;
clock-names = "fclk";
power-domains = <&k3_pds 394 TI_SCI_PD_EXCLUSIVE>;
@@ -492,7 +599,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02880000 0x00 0x200>;
interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 395 0>;
clock-names = "fclk";
power-domains = <&k3_pds 395 TI_SCI_PD_EXCLUSIVE>;
@@ -503,7 +609,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x02890000 0x00 0x200>;
interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 396 0>;
clock-names = "fclk";
power-domains = <&k3_pds 396 TI_SCI_PD_EXCLUSIVE>;
@@ -578,6 +683,38 @@
status = "disabled";
};
+ usbss0: usb@4104000 {
+ bootph-all;
+ compatible = "ti,j721e-usb";
+ reg = <0x00 0x4104000 0x00 0x100>;
+ dma-coherent;
+ power-domains = <&k3_pds 398 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 398 21>, <&k3_clks 398 2>;
+ clock-names = "ref", "lpm";
+ assigned-clocks = <&k3_clks 398 21>; /* USB2_REFCLK */
+ assigned-clock-parents = <&k3_clks 398 22>; /* HFOSC0 */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ status = "disabled"; /* Needs lane config */
+
+ usb0: usb@6000000 {
+ bootph-all;
+ 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";
+ };
+ };
+
main_i2c0: i2c@2000000 {
compatible = "ti,j721e-i2c", "ti,omap4-i2c";
reg = <0x00 0x02000000 0x00 0x100>;
@@ -914,8 +1051,122 @@
ti,clkbuf-sel = <0x7>;
ti,trm-icp = <0x8>;
dma-coherent;
- sdhci-caps-mask = <0x00000003 0x00000000>;
- no-1-8-v;
+ status = "disabled";
+ };
+
+ pcie0_rc: pcie@2900000 {
+ compatible = "ti,j784s4-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 0x0>;
+ max-link-speed = <3>;
+ num-lanes = <4>;
+ power-domains = <&k3_pds 332 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 332 0>;
+ clock-names = "fck";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x104c>;
+ device-id = <0xb012>;
+ 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>;
+ status = "disabled";
+ };
+
+ pcie1_rc: pcie@2910000 {
+ compatible = "ti,j784s4-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 0x0>;
+ max-link-speed = <3>;
+ num-lanes = <4>;
+ power-domains = <&k3_pds 333 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 333 0>;
+ clock-names = "fck";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x104c>;
+ device-id = <0xb012>;
+ msi-map = <0x0 &gic_its 0x10000 0x10000>;
+ dma-coherent;
+ ranges = <0x01000000 0x0 0x18001000 0x00 0x18001000 0x0 0x0010000>,
+ <0x02000000 0x0 0x18011000 0x00 0x18011000 0x0 0x7fef000>;
+ dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+ status = "disabled";
+ };
+
+ pcie2_rc: pcie@2920000 {
+ compatible = "ti,j784s4-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 0x0>;
+ max-link-speed = <3>;
+ num-lanes = <2>;
+ power-domains = <&k3_pds 334 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 334 0>;
+ clock-names = "fck";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x104c>;
+ device-id = <0xb012>;
+ 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>;
+ status = "disabled";
+ };
+
+ pcie3_rc: pcie@2930000 {
+ compatible = "ti,j784s4-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 0x0>;
+ max-link-speed = <3>;
+ num-lanes = <2>;
+ power-domains = <&k3_pds 335 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 335 0>;
+ clock-names = "fck";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x104c>;
+ device-id = <0xb012>;
+ 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>;
status = "disabled";
};
@@ -1439,6 +1690,180 @@
};
};
+ main_cpsw0: ethernet@c000000 {
+ compatible = "ti,j784s4-cpswxg-nuss";
+ reg = <0x00 0xc000000 0x00 0x200000>;
+ reg-names = "cpsw_nuss";
+ ranges = <0x00 0x00 0x00 0xc000000 0x00 0x200000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-coherent;
+ clocks = <&k3_clks 64 0>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 64 TI_SCI_PD_EXCLUSIVE>;
+
+ dmas = <&main_udmap 0xca00>,
+ <&main_udmap 0xca01>,
+ <&main_udmap 0xca02>,
+ <&main_udmap 0xca03>,
+ <&main_udmap 0xca04>,
+ <&main_udmap 0xca05>,
+ <&main_udmap 0xca06>,
+ <&main_udmap 0xca07>,
+ <&main_udmap 0x4a00>;
+ dma-names = "tx0", "tx1", "tx2", "tx3",
+ "tx4", "tx5", "tx6", "tx7",
+ "rx";
+
+ status = "disabled";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ main_cpsw0_port1: port@1 {
+ reg = <1>;
+ label = "port1";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port2: port@2 {
+ reg = <2>;
+ label = "port2";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port3: port@3 {
+ reg = <3>;
+ label = "port3";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port4: port@4 {
+ reg = <4>;
+ label = "port4";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port5: port@5 {
+ reg = <5>;
+ label = "port5";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port6: port@6 {
+ reg = <6>;
+ label = "port6";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port7: port@7 {
+ reg = <7>;
+ label = "port7";
+ ti,mac-only;
+ status = "disabled";
+ };
+
+ main_cpsw0_port8: port@8 {
+ reg = <8>;
+ label = "port8";
+ ti,mac-only;
+ status = "disabled";
+ };
+ };
+
+ main_cpsw0_mdio: mdio@f00 {
+ compatible = "ti,cpsw-mdio","ti,davinci_mdio";
+ reg = <0x00 0xf00 0x00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&k3_clks 64 0>;
+ clock-names = "fck";
+ bus_freq = <1000000>;
+ status = "disabled";
+ };
+
+ cpts@3d000 {
+ compatible = "ti,am65-cpts";
+ reg = <0x00 0x3d000 0x00 0x400>;
+ clocks = <&k3_clks 64 3>;
+ clock-names = "cpts";
+ interrupts-extended = <&gic500 GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cpts";
+ ti,cpts-ext-ts-inputs = <4>;
+ ti,cpts-periodic-outputs = <2>;
+ };
+ };
+
+ main_cpsw1: ethernet@c200000 {
+ compatible = "ti,j721e-cpsw-nuss";
+ reg = <0x00 0xc200000 0x00 0x200000>;
+ reg-names = "cpsw_nuss";
+ ranges = <0x00 0x00 0x00 0xc200000 0x00 0x200000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-coherent;
+ clocks = <&k3_clks 62 0>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 62 TI_SCI_PD_EXCLUSIVE>;
+
+ dmas = <&main_udmap 0xc640>,
+ <&main_udmap 0xc641>,
+ <&main_udmap 0xc642>,
+ <&main_udmap 0xc643>,
+ <&main_udmap 0xc644>,
+ <&main_udmap 0xc645>,
+ <&main_udmap 0xc646>,
+ <&main_udmap 0xc647>,
+ <&main_udmap 0x4640>;
+ dma-names = "tx0", "tx1", "tx2", "tx3",
+ "tx4", "tx5", "tx6", "tx7",
+ "rx";
+
+ status = "disabled";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ main_cpsw1_port1: port@1 {
+ reg = <1>;
+ label = "port1";
+ phys = <&cpsw1_phy_gmii_sel 1>;
+ ti,mac-only;
+ status = "disabled";
+ };
+ };
+
+ main_cpsw1_mdio: mdio@f00 {
+ compatible = "ti,cpsw-mdio", "ti,davinci_mdio";
+ reg = <0x00 0xf00 0x00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&k3_clks 62 0>;
+ clock-names = "fck";
+ bus_freq = <1000000>;
+ status = "disabled";
+ };
+
+ cpts@3d000 {
+ compatible = "ti,am65-cpts";
+ reg = <0x00 0x3d000 0x00 0x400>;
+ clocks = <&k3_clks 62 3>;
+ clock-names = "cpts";
+ interrupts-extended = <&gic500 GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cpts";
+ ti,cpts-ext-ts-inputs = <4>;
+ ti,cpts-periodic-outputs = <2>;
+ };
+ };
+
main_mcan0: can@2701000 {
compatible = "bosch,m_can";
reg = <0x00 0x02701000 0x00 0x200>,
@@ -2267,4 +2692,94 @@
*/
};
};
+
+ mcasp0: mcasp@2b00000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b00000 0x00 0x2000>,
+ <0x00 0x02b08000 0x00 0x1000>;
+ reg-names = "mpu","dat";
+ interrupts = <GIC_SPI 544 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 545 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+ dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
+ dma-names = "tx", "rx";
+ clocks = <&k3_clks 265 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 265 0>;
+ assigned-clock-parents = <&k3_clks 265 1>;
+ power-domains = <&k3_pds 265 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp1: mcasp@2b10000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b10000 0x00 0x2000>,
+ <0x00 0x02b18000 0x00 0x1000>;
+ reg-names = "mpu","dat";
+ interrupts = <GIC_SPI 546 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 547 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+ dmas = <&main_udmap 0xc401>, <&main_udmap 0x4401>;
+ dma-names = "tx", "rx";
+ clocks = <&k3_clks 266 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 266 0>;
+ assigned-clock-parents = <&k3_clks 266 1>;
+ power-domains = <&k3_pds 266 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp2: mcasp@2b20000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b20000 0x00 0x2000>,
+ <0x00 0x02b28000 0x00 0x1000>;
+ reg-names = "mpu","dat";
+ interrupts = <GIC_SPI 548 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 549 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+ dmas = <&main_udmap 0xc402>, <&main_udmap 0x4402>;
+ dma-names = "tx", "rx";
+ clocks = <&k3_clks 267 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 267 0>;
+ assigned-clock-parents = <&k3_clks 267 1>;
+ power-domains = <&k3_pds 267 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp3: mcasp@2b30000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b30000 0x00 0x2000>,
+ <0x00 0x02b38000 0x00 0x1000>;
+ reg-names = "mpu","dat";
+ interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+ dmas = <&main_udmap 0xc500>, <&main_udmap 0x4500>;
+ dma-names = "tx", "rx";
+ clocks = <&k3_clks 268 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 268 0>;
+ assigned-clock-parents = <&k3_clks 268 1>;
+ power-domains = <&k3_pds 268 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp4: mcasp@2b40000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b40000 0x00 0x2000>,
+ <0x00 0x02b48000 0x00 0x1000>;
+ reg-names = "mpu","dat";
+ interrupts = <GIC_SPI 552 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 553 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+ dmas = <&main_udmap 0xc501>, <&main_udmap 0x4501>;
+ dma-names = "tx", "rx";
+ clocks = <&k3_clks 269 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 269 0>;
+ assigned-clock-parents = <&k3_clks 269 1>;
+ power-domains = <&k3_pds 269 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
index 77a8d99139ec..f3a6ed1c979d 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
@@ -145,12 +145,16 @@
status = "reserved";
};
- mcu_conf: syscon@40f00000 {
- compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
- reg = <0x00 0x40f00000 0x00 0x20000>;
+ mcu_conf: bus@40f00000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0x00 0x00 0x40f00000 0x20000>;
+ ranges = <0x0 0x0 0x40f00000 0x20000>;
+
+ cpsw_mac_syscon: ethernet-mac-syscon@200 {
+ compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+ reg = <0x200 0x8>;
+ };
phy_gmii_sel: phy@4040 {
compatible = "ti,am654-phy-gmii-sel";
@@ -304,7 +308,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x42300000 0x00 0x200>;
interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 397 0>;
clock-names = "fclk";
power-domains = <&k3_pds 397 TI_SCI_PD_EXCLUSIVE>;
@@ -315,7 +318,6 @@
compatible = "ti,j721e-uart", "ti,am654-uart";
reg = <0x00 0x40a00000 0x00 0x200>;
interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
clocks = <&k3_clks 149 0>;
clock-names = "fclk";
power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
@@ -555,7 +557,7 @@
reg = <1>;
ti,mac-only;
label = "port1";
- ti,syscon-efuse = <&mcu_conf 0x200>;
+ ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
phys = <&phy_gmii_sel 1>;
};
};
@@ -674,10 +676,13 @@
fss: bus@47000000 {
compatible = "simple-bus";
- reg = <0x00 0x47000000 0x00 0x100>;
#address-cells = <2>;
#size-cells = <2>;
- ranges;
+ ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+ <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+ <0x0 0x47050000 0x0 0x47050000 0x0 0x100>, /* OSPI1 Control */
+ <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>, /* OSPI0 Memory */
+ <0x7 0x00000000 0x7 0x00000000 0x1 0x0000000>; /* OSPI1 Memory */
ospi0: spi@47040000 {
compatible = "ti,am654-ospi", "cdns,qspi-nor";
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
index 6e2e92ffe745..73cc3c1fec08 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
@@ -234,10 +234,14 @@
#size-cells = <2>;
ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
<0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
+ <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
<0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
<0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
<0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */
- <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/
+ <0x00 0x0d000000 0x00 0x0d000000 0x00 0x00800000>, /* PCIe0 Core*/
+ <0x00 0x0d800000 0x00 0x0d800000 0x00 0x00800000>, /* PCIe1 Core*/
+ <0x00 0x0e000000 0x00 0x0e000000 0x00 0x00800000>, /* PCIe2 Core*/
+ <0x00 0x0e800000 0x00 0x0e800000 0x00 0x00800000>, /* PCIe3 Core*/
<0x00 0x10000000 0x00 0x10000000 0x00 0x08000000>, /* PCIe0 DAT0 */
<0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
<0x00 0x64800000 0x00 0x64800000 0x00 0x0070c000>, /* C71_1 */
@@ -247,7 +251,12 @@
<0x00 0x6f000000 0x00 0x6f000000 0x00 0x00310000>, /* A72 PERIPHBASE */
<0x00 0x70000000 0x00 0x70000000 0x00 0x00400000>, /* MSMC RAM */
<0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */
+ <0x40 0x00000000 0x40 0x00000000 0x01 0x00000000>, /* PCIe0 DAT1 */
<0x41 0x00000000 0x41 0x00000000 0x01 0x00000000>, /* PCIe1 DAT1 */
+ <0x42 0x00000000 0x42 0x00000000 0x01 0x00000000>, /* PCIe2 DAT1 */
+ <0x43 0x00000000 0x43 0x00000000 0x01 0x00000000>, /* PCIe3 DAT1 */
+ <0x44 0x00000000 0x44 0x00000000 0x00 0x08000000>, /* PCIe2 DAT0 */
+ <0x44 0x10000000 0x44 0x10000000 0x00 0x08000000>, /* PCIe3 DAT0 */
<0x4e 0x20000000 0x4e 0x20000000 0x00 0x00080000>, /* GPU */
/* MCUSS_WKUP Range */
diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h
index 4cd2df467d0b..22b8d73cfd32 100644
--- a/arch/arm64/boot/dts/ti/k3-pinctrl.h
+++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h
@@ -38,6 +38,9 @@
#define PIN_DEBOUNCE_CONF5 (5 << DEBOUNCE_SHIFT)
#define PIN_DEBOUNCE_CONF6 (6 << DEBOUNCE_SHIFT)
+/* Default mux configuration for gpio-ranges to use with pinctrl */
+#define PIN_GPIO_RANGE_IOPAD (PIN_INPUT | 7)
+
#define AM62AX_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
#define AM62AX_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
diff --git a/arch/arm64/boot/dts/ti/k3-serdes.h b/arch/arm64/boot/dts/ti/k3-serdes.h
index a011ad893b44..ef3606068140 100644
--- a/arch/arm64/boot/dts/ti/k3-serdes.h
+++ b/arch/arm64/boot/dts/ti/k3-serdes.h
@@ -201,4 +201,12 @@
#define J784S4_SERDES4_LANE3_USB 0x2
#define J784S4_SERDES4_LANE3_IP4_UNUSED 0x3
+/* J722S */
+
+#define J722S_SERDES0_LANE0_USB 0x0
+#define J722S_SERDES0_LANE0_QSGMII_LANE2 0x1
+
+#define J722S_SERDES1_LANE0_PCIE0_LANE0 0x0
+#define J722S_SERDES1_LANE0_QSGMII_LANE1 0x1
+
#endif /* DTS_ARM64_TI_K3_SERDES_H */
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
index dd4569e7bd95..60d1b1acf9a0 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
@@ -70,6 +70,22 @@
clocks = <&zynqmp_clk ACPU>;
};
+&cpu0_debug {
+ clocks = <&zynqmp_clk DBF_FPD>;
+};
+
+&cpu1_debug {
+ clocks = <&zynqmp_clk DBF_FPD>;
+};
+
+&cpu2_debug {
+ clocks = <&zynqmp_clk DBF_FPD>;
+};
+
+&cpu3_debug {
+ clocks = <&zynqmp_clk DBF_FPD>;
+};
+
&fpd_dma_chan1 {
clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso
index d7535a77b45e..95d16904d765 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso
@@ -22,6 +22,17 @@
/plugin/;
&{/} {
+ compatible = "xlnx,zynqmp-sk-kv260-revA",
+ "xlnx,zynqmp-sk-kv260-revY",
+ "xlnx,zynqmp-sk-kv260-revZ",
+ "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";
+ model = "ZynqMP KV260 revA";
+
+ ina260-u14 {
+ compatible = "iio-hwmon";
+ io-channels = <&u14 0>, <&u14 1>, <&u14 2>;
+ };
+
si5332_0: si5332-0 { /* u17 */
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -68,7 +79,12 @@
scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- /* u14 - 0x40 - ina260 */
+ u14: ina260@40 { /* u14 */
+ compatible = "ti,ina260";
+ #io-channel-cells = <1>;
+ label = "ina260-u14";
+ reg = <0x40>;
+ };
/* u27 - 0xe0 - STDP4320 DP/HDMI splitter */
};
@@ -321,6 +337,7 @@
slew-rate = <SLEW_RATE_SLOW>;
power-source = <IO_STANDARD_LVCMOS18>;
bias-disable;
+ output-enable;
};
conf-cd {
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso
index a7b8fffad499..a74d0ac7e07a 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso
@@ -17,6 +17,17 @@
/plugin/;
&{/} {
+ compatible = "xlnx,zynqmp-sk-kv260-rev2",
+ "xlnx,zynqmp-sk-kv260-rev1",
+ "xlnx,zynqmp-sk-kv260-revB",
+ "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";
+ model = "ZynqMP KV260 revB";
+
+ ina260-u14 {
+ compatible = "iio-hwmon";
+ io-channels = <&u14 0>, <&u14 1>, <&u14 2>;
+ };
+
si5332_0: si5332-0 { /* u17 */
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -52,6 +63,18 @@
#clock-cells = <0>;
clock-frequency = <27000000>;
};
+
+ dpcon {
+ compatible = "dp-connector";
+ label = "P11";
+ type = "full-size";
+
+ port {
+ dpcon_in: endpoint {
+ remote-endpoint = <&dpsub_dp_out>;
+ };
+ };
+ };
};
&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
@@ -63,8 +86,13 @@
scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- /* u14 - 0x40 - ina260 */
- /* u43 - 0x2d - usb5744 */
+ u14: ina260@40 { /* u14 */
+ compatible = "ti,ina260";
+ #io-channel-cells = <1>;
+ label = "ina260-u14";
+ reg = <0x40>;
+ };
+ /* u43 - 0x2d - USB hub */
/* u27 - 0xe0 - STDP4320 DP/HDMI splitter */
};
@@ -81,6 +109,14 @@
phy-names = "dp-phy0", "dp-phy1";
phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>;
assigned-clock-rates = <27000000>, <25000000>, <300000000>;
+
+ ports {
+ port@5 {
+ dpsub_dp_out: endpoint {
+ remote-endpoint = <&dpcon_in>;
+ };
+ };
+ };
};
&zynqmp_dpdma {
@@ -305,6 +341,7 @@
slew-rate = <SLEW_RATE_SLOW>;
power-source = <IO_STANDARD_LVCMOS18>;
bias-disable;
+ output-enable;
};
conf-cd {
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
index 51622896b1b1..86e6c4990560 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * dts file for Xilinx ZynqMP SM-K26 rev1/B/A
+ * dts file for Xilinx ZynqMP SM-K26 rev2/1/B/A
*
* (C) Copyright 2020 - 2021, Xilinx, Inc.
+ * (C) Copyright 2023 - 2024, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
*/
@@ -17,8 +18,9 @@
#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
/ {
- model = "ZynqMP SM-K26 Rev1/B/A";
- compatible = "xlnx,zynqmp-sm-k26-rev1", "xlnx,zynqmp-sm-k26-revB",
+ model = "ZynqMP SM-K26 Rev2/1/B/A";
+ compatible = "xlnx,zynqmp-sm-k26-rev2",
+ "xlnx,zynqmp-sm-k26-rev1", "xlnx,zynqmp-sm-k26-revB",
"xlnx,zynqmp-sm-k26-revA", "xlnx,zynqmp-sm-k26",
"xlnx,zynqmp";
@@ -101,12 +103,23 @@
<&xilinx_ams 24>, <&xilinx_ams 25>, <&xilinx_ams 26>,
<&xilinx_ams 27>, <&xilinx_ams 28>, <&xilinx_ams 29>;
};
+
+ pwm-fan {
+ compatible = "pwm-fan";
+ status = "okay";
+ pwms = <&ttc0 2 40000 0>;
+ };
};
&modepin_gpio {
label = "modepin";
};
+&ttc0 {
+ status = "okay";
+ #pwm-cells = <3>;
+};
+
&uart1 { /* MIO36/MIO37 */
status = "okay";
};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
index 85b0d1677240..b804abe89d1d 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * dts file for Xilinx ZynqMP SMK-K26 rev1/B/A
+ * dts file for Xilinx ZynqMP SMK-K26 rev2/1/B/A
*
* (C) Copyright 2020 - 2021, Xilinx, Inc.
+ * (C) Copyright 2023 - 2024, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
*/
@@ -10,8 +11,9 @@
#include "zynqmp-sm-k26-revA.dts"
/ {
- model = "ZynqMP SMK-K26 Rev1/B/A";
- compatible = "xlnx,zynqmp-smk-k26-rev1", "xlnx,zynqmp-smk-k26-revB",
+ model = "ZynqMP SMK-K26 Rev2/1/B/A";
+ compatible = "xlnx,zynqmp-smk-k26-rev2",
+ "xlnx,zynqmp-smk-k26-rev1", "xlnx,zynqmp-smk-k26-revB",
"xlnx,zynqmp-smk-k26-revA", "xlnx,zynqmp-smk-k26",
"xlnx,zynqmp";
};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
index c8f71a1aec89..495ca94b45db 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
@@ -14,6 +14,14 @@
compatible = "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
};
+&rproc_split {
+ status = "okay";
+};
+
+&rproc_lockstep {
+ status = "disabled";
+};
+
&eeprom {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 25d20d803230..b1b31dcf6291 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -169,7 +169,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
@@ -207,13 +207,71 @@
mbox-names = "tx", "rx";
};
- nvmem-firmware {
+ soc-nvmem {
compatible = "xlnx,zynqmp-nvmem-fw";
- #address-cells = <1>;
- #size-cells = <1>;
-
- soc_revision: soc-revision@0 {
- reg = <0x0 0x4>;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ soc_revision: soc-revision@0 {
+ reg = <0x0 0x4>;
+ };
+ /* efuse access */
+ efuse_dna: efuse-dna@c {
+ reg = <0xc 0xc>;
+ };
+ efuse_usr0: efuse-usr0@20 {
+ reg = <0x20 0x4>;
+ };
+ efuse_usr1: efuse-usr1@24 {
+ reg = <0x24 0x4>;
+ };
+ efuse_usr2: efuse-usr2@28 {
+ reg = <0x28 0x4>;
+ };
+ efuse_usr3: efuse-usr3@2c {
+ reg = <0x2c 0x4>;
+ };
+ efuse_usr4: efuse-usr4@30 {
+ reg = <0x30 0x4>;
+ };
+ efuse_usr5: efuse-usr5@34 {
+ reg = <0x34 0x4>;
+ };
+ efuse_usr6: efuse-usr6@38 {
+ reg = <0x38 0x4>;
+ };
+ efuse_usr7: efuse-usr7@3c {
+ reg = <0x3c 0x4>;
+ };
+ efuse_miscusr: efuse-miscusr@40 {
+ reg = <0x40 0x4>;
+ };
+ efuse_chash: efuse-chash@50 {
+ reg = <0x50 0x4>;
+ };
+ efuse_pufmisc: efuse-pufmisc@54 {
+ reg = <0x54 0x4>;
+ };
+ efuse_sec: efuse-sec@58 {
+ reg = <0x58 0x4>;
+ };
+ efuse_spkid: efuse-spkid@5c {
+ reg = <0x5c 0x4>;
+ };
+ efuse_aeskey: efuse-aeskey@60 {
+ reg = <0x60 0x20>;
+ };
+ efuse_ppk0hash: efuse-ppk0hash@a0 {
+ reg = <0xa0 0x30>;
+ };
+ efuse_ppk1hash: efuse-ppk1hash@d0 {
+ reg = <0xd0 0x30>;
+ };
+ efuse_pufuser: efuse-pufuser@100 {
+ reg = <0x100 0x7F>;
+ };
};
};
@@ -252,7 +310,7 @@
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
- fpga_full: fpga-full {
+ fpga_full: fpga-region {
compatible = "fpga-region";
fpga-mgr = <&zynqmp_pcap>;
#address-cells = <2>;
@@ -260,19 +318,76 @@
ranges;
};
- remoteproc {
+ rproc_lockstep: remoteproc@ffe00000 {
compatible = "xlnx,zynqmp-r5fss";
xlnx,cluster-mode = <1>;
+ xlnx,tcm-mode = <1>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
- r5f-0 {
+ ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+ <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+ <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+ <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+ r5f@0 {
compatible = "xlnx,zynqmp-r5f";
- power-domains = <&zynqmp_firmware PD_RPU_0>;
+ reg = <0x0 0x0 0x0 0x10000>,
+ <0x0 0x20000 0x0 0x10000>,
+ <0x0 0x10000 0x0 0x10000>,
+ <0x0 0x30000 0x0 0x10000>;
+ reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+ power-domains = <&zynqmp_firmware PD_RPU_0>,
+ <&zynqmp_firmware PD_R5_0_ATCM>,
+ <&zynqmp_firmware PD_R5_0_BTCM>,
+ <&zynqmp_firmware PD_R5_1_ATCM>,
+ <&zynqmp_firmware PD_R5_1_BTCM>;
memory-region = <&rproc_0_fw_image>;
};
- r5f-1 {
+ r5f@1 {
compatible = "xlnx,zynqmp-r5f";
- power-domains = <&zynqmp_firmware PD_RPU_1>;
+ reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+ reg-names = "atcm0", "btcm0";
+ power-domains = <&zynqmp_firmware PD_RPU_1>,
+ <&zynqmp_firmware PD_R5_1_ATCM>,
+ <&zynqmp_firmware PD_R5_1_BTCM>;
+ memory-region = <&rproc_1_fw_image>;
+ };
+ };
+
+ rproc_split: remoteproc-split@ffe00000 {
+ status = "disabled";
+ compatible = "xlnx,zynqmp-r5fss";
+ xlnx,cluster-mode = <0>;
+ xlnx,tcm-mode = <0>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+ <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+ <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+ <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+ r5f@0 {
+ compatible = "xlnx,zynqmp-r5f";
+ reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+ reg-names = "atcm0", "btcm0";
+ power-domains = <&zynqmp_firmware PD_RPU_0>,
+ <&zynqmp_firmware PD_R5_0_ATCM>,
+ <&zynqmp_firmware PD_R5_0_BTCM>;
+ memory-region = <&rproc_0_fw_image>;
+ };
+
+ r5f@1 {
+ compatible = "xlnx,zynqmp-r5f";
+ reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+ reg-names = "atcm0", "btcm0";
+ power-domains = <&zynqmp_firmware PD_RPU_1>,
+ <&zynqmp_firmware PD_R5_1_ATCM>,
+ <&zynqmp_firmware PD_R5_1_BTCM>;
memory-region = <&rproc_1_fw_image>;
};
};
@@ -330,6 +445,34 @@
};
};
+ cpu0_debug: debug@fec10000 {
+ compatible = "arm,coresight-cpu-debug", "arm,primecell";
+ reg = <0x0 0xfec10000 0x0 0x1000>;
+ clock-names = "apb_pclk";
+ cpu = <&cpu0>;
+ };
+
+ cpu1_debug: debug@fed10000 {
+ compatible = "arm,coresight-cpu-debug", "arm,primecell";
+ reg = <0x0 0xfed10000 0x0 0x1000>;
+ clock-names = "apb_pclk";
+ cpu = <&cpu1>;
+ };
+
+ cpu2_debug: debug@fee10000 {
+ compatible = "arm,coresight-cpu-debug", "arm,primecell";
+ reg = <0x0 0xfee10000 0x0 0x1000>;
+ clock-names = "apb_pclk";
+ cpu = <&cpu2>;
+ };
+
+ cpu3_debug: debug@fef10000 {
+ compatible = "arm,coresight-cpu-debug", "arm,primecell";
+ reg = <0x0 0xfef10000 0x0 0x1000>;
+ clock-names = "apb_pclk";
+ cpu = <&cpu3>;
+ };
+
/* GDMA */
fpd_dma_chan1: dma-controller@fd500000 {
status = "disabled";
@@ -684,6 +827,13 @@
power-domains = <&zynqmp_firmware PD_I2C_1>;
};
+ ocm: memory-controller@ff960000 {
+ compatible = "xlnx,zynqmp-ocmc-1.0";
+ reg = <0x0 0xff960000 0x0 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
pcie: pcie@fd0e0000 {
compatible = "xlnx,nwl-pcie-2.11";
status = "disabled";
@@ -906,6 +1056,7 @@
reg = <0x0 0xff000000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
power-domains = <&zynqmp_firmware PD_UART_0>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_UART0>;
};
uart1: serial@ff010000 {
@@ -917,6 +1068,7 @@
reg = <0x0 0xff010000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
power-domains = <&zynqmp_firmware PD_UART_1>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_UART1>;
};
usb0: usb@ff9d0000 {
@@ -939,10 +1091,11 @@
status = "disabled";
reg = <0x0 0xfe200000 0x0 0x40000>;
interrupt-parent = <&gic>;
- interrupt-names = "host", "peripheral", "otg";
+ interrupt-names = "host", "peripheral", "otg", "wakeup";
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "ref";
/* iommus = <&smmu 0x860>; */
snps,quirk-frame-length-adjustment = <0x20>;
@@ -970,10 +1123,11 @@
status = "disabled";
reg = <0x0 0xfe300000 0x0 0x40000>;
interrupt-parent = <&gic>;
- interrupt-names = "host", "peripheral", "otg";
+ interrupt-names = "host", "peripheral", "otg", "wakeup";
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "ref";
/* iommus = <&smmu 0x861>; */
snps,quirk-frame-length-adjustment = <0x20>;
@@ -1022,8 +1176,6 @@
compatible = "xlnx,zynqmp-ams-pl";
status = "disabled";
reg = <0x400 0x400>;
- #address-cells = <1>;
- #size-cells = <0>;
};
};
diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh
index 9b7a09808a3d..cc2f4ccca6c0 100755
--- a/arch/arm64/boot/install.sh
+++ b/arch/arm64/boot/install.sh
@@ -17,6 +17,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ]
then
# Compressed install
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2c30d617e180..7d32fca64996 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -34,6 +34,7 @@ CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_CRASH_DUMP=y
CONFIG_ARCH_ACTIONS=y
+CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_ALPINE=y
CONFIG_ARCH_APPLE=y
@@ -232,6 +233,8 @@ CONFIG_PCIE_HISI_STB=y
CONFIG_PCIE_ARMADA_8K=y
CONFIG_PCIE_TEGRA194_HOST=m
CONFIG_PCIE_QCOM=y
+CONFIG_PCIE_RCAR_GEN4_HOST=m
+CONFIG_PCIE_RCAR_GEN4_EP=m
CONFIG_PCIE_ROCKCHIP_DW_HOST=y
CONFIG_PCIE_VISCONTI_HOST=y
CONFIG_PCIE_LAYERSCAPE_GEN4=y
@@ -255,6 +258,7 @@ CONFIG_GOOGLE_CBMEM=m
CONFIG_GOOGLE_COREBOOT_TABLE=m
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_IMX_SCU=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
CONFIG_QCOM_QSEECOM=y
CONFIG_QCOM_QSEECOM_UEFISECAPP=y
CONFIG_GNSS=m
@@ -278,6 +282,8 @@ CONFIG_MTD_NAND_FSL_IFC=y
CONFIG_MTD_NAND_QCOM=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_UBI=m
+CONFIG_MTD_HYPERBUS=m
+CONFIG_HBMC_AM654=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
CONFIG_VIRTIO_BLK=y
@@ -374,6 +380,7 @@ CONFIG_AQUANTIA_PHY=y
CONFIG_BCM54140_PHY=m
CONFIG_MARVELL_PHY=m
CONFIG_MARVELL_10G_PHY=y
+CONFIG_MARVELL_88Q2XXX_PHY=y
CONFIG_MICREL_PHY=y
CONFIG_MICROSEMI_PHY=y
CONFIG_AT803X_PHY=y
@@ -411,7 +418,11 @@ CONFIG_WCN36XX=m
CONFIG_ATH11K=m
CONFIG_ATH11K_AHB=m
CONFIG_ATH11K_PCI=m
+CONFIG_ATH12K=m
CONFIG_BRCMFMAC=m
+CONFIG_IWLWIFI=m
+CONFIG_IWLDVM=m
+CONFIG_IWLMVM=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_PCIE=m
@@ -445,6 +456,7 @@ CONFIG_INPUT_TPS65219_PWRBUTTON=m
CONFIG_INPUT_PWM_BEEPER=m
CONFIG_INPUT_PWM_VIBRA=m
CONFIG_INPUT_RK805_PWRKEY=m
+CONFIG_INPUT_DA9063_ONKEY=m
CONFIG_INPUT_HISI_POWERKEY=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_AMBAKMI=y
@@ -562,6 +574,7 @@ CONFIG_SPI_TEGRA114=m
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
CONFIG_SPMI_MTK_PMIF=m
+CONFIG_PINCTRL_DA9062=m
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_RK805=m
CONFIG_PINCTRL_SINGLE=y
@@ -727,6 +740,7 @@ CONFIG_MFD_ALTERA_SYSMGR=y
CONFIG_MFD_BD9571MWV=y
CONFIG_MFD_AXP20X_I2C=y
CONFIG_MFD_AXP20X_RSB=y
+CONFIG_MFD_DA9062=m
CONFIG_MFD_EXYNOS_LPASS=m
CONFIG_MFD_HI6421_PMIC=y
CONFIG_MFD_HI655X_PMIC=y
@@ -740,6 +754,7 @@ CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_SL28CPLD=y
CONFIG_RZ_MTU3=y
CONFIG_MFD_TI_AM335X_TSCADC=m
+CONFIG_MFD_TI_LP873X=m
CONFIG_MFD_TPS65219=y
CONFIG_MFD_TPS6594_I2C=m
CONFIG_MFD_ROHM_BD718XX=y
@@ -755,6 +770,7 @@ CONFIG_REGULATOR_FAN53555=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_HI6421V530=y
CONFIG_REGULATOR_HI655X=y
+CONFIG_REGULATOR_LP873X=m
CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_MAX20411=m
@@ -772,6 +788,7 @@ CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_QCOM_RPMH=y
CONFIG_REGULATOR_QCOM_SMD_RPM=y
CONFIG_REGULATOR_QCOM_SPMI=y
+CONFIG_REGULATOR_QCOM_USB_VBUS=m
CONFIG_REGULATOR_RAA215300=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_S2MPS11=y
@@ -854,6 +871,7 @@ CONFIG_DRM_RCAR_DU=m
CONFIG_DRM_RCAR_DW_HDMI=m
CONFIG_DRM_RCAR_MIPI_DSI=m
CONFIG_DRM_RZG2L_MIPI_DSI=m
+CONFIG_DRM_RZG2L_DU=m
CONFIG_DRM_SUN4I=m
CONFIG_DRM_SUN6I_DSI=m
CONFIG_DRM_SUN8I_DW_HDMI=m
@@ -865,7 +883,9 @@ CONFIG_DRM_PANEL_LVDS=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_EDP=m
CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
+CONFIG_DRM_PANEL_KHADAS_TS050=m
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
CONFIG_DRM_PANEL_SITRONIX_ST7703=m
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
@@ -890,6 +910,7 @@ CONFIG_DRM_ANALOGIX_ANX7625=m
CONFIG_DRM_I2C_ADV7511=m
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_DRM_CDNS_MHDP8546=m
+CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
CONFIG_DRM_DW_HDMI_CEC=m
CONFIG_DRM_IMX_DCSS=m
@@ -907,6 +928,7 @@ CONFIG_DRM_MESON=m
CONFIG_DRM_PL111=m
CONFIG_DRM_LIMA=m
CONFIG_DRM_PANFROST=m
+CONFIG_DRM_PANTHOR=m
CONFIG_DRM_TIDSS=m
CONFIG_DRM_POWERVR=m
CONFIG_FB=y
@@ -929,7 +951,6 @@ CONFIG_SND_SOC_FSL_MICFIL=m
CONFIG_SND_SOC_FSL_EASRC=m
CONFIG_SND_IMX_SOC=m
CONFIG_SND_SOC_IMX_SGTL5000=m
-CONFIG_SND_SOC_IMX_SPDIF=m
CONFIG_SND_SOC_FSL_ASOC_CARD=m
CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_SND_SOC_MT8183=m
@@ -949,6 +970,7 @@ CONFIG_SND_SOC_SM8250=m
CONFIG_SND_SOC_SC8280XP=m
CONFIG_SND_SOC_SC7180=m
CONFIG_SND_SOC_SC7280=m
+CONFIG_SND_SOC_X1E80100=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
@@ -991,6 +1013,7 @@ CONFIG_SND_SOC_GTM601=m
CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
CONFIG_SND_SOC_PCM3168A_I2C=m
+CONFIG_SND_SOC_RK3308=m
CONFIG_SND_SOC_RK817=m
CONFIG_SND_SOC_RT5640=m
CONFIG_SND_SOC_RT5659=m
@@ -1023,6 +1046,7 @@ CONFIG_SND_AUDIO_GRAPH_CARD2=m
CONFIG_HID_MULTITOUCH=m
CONFIG_I2C_HID_ACPI=m
CONFIG_I2C_HID_OF=m
+CONFIG_I2C_HID_OF_ELAN=m
CONFIG_USB=y
CONFIG_USB_OTG=y
CONFIG_USB_XHCI_HCD=y
@@ -1049,6 +1073,7 @@ CONFIG_USB_MTU3=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SUNXI=y
CONFIG_USB_DWC3=y
+CONFIG_OMAP_USB2=m
CONFIG_USB_DWC2=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
@@ -1060,7 +1085,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_QCOM_EUD=m
CONFIG_USB_HSIC_USB3503=y
-CONFIG_USB_ONBOARD_HUB=m
+CONFIG_USB_ONBOARD_DEV=m
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MXS_PHY=m
CONFIG_USB_GADGET=y
@@ -1169,6 +1194,7 @@ CONFIG_RTC_DRV_RV8803=m
CONFIG_RTC_DRV_S5M=y
CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_PCF2127=m
+CONFIG_RTC_DRV_DA9063=m
CONFIG_RTC_DRV_EFI=y
CONFIG_RTC_DRV_CROS_EC=y
CONFIG_RTC_DRV_FSL_FTM_ALARM=m
@@ -1201,6 +1227,7 @@ CONFIG_QCOM_BAM_DMA=y
CONFIG_QCOM_GPI_DMA=m
CONFIG_QCOM_HIDMA_MGMT=y
CONFIG_QCOM_HIDMA=y
+CONFIG_DW_EDMA=m
CONFIG_RCAR_DMAC=y
CONFIG_RENESAS_USB_DMAC=m
CONFIG_RZ_DMAC=y
@@ -1217,6 +1244,7 @@ CONFIG_STAGING=y
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_MAX96712=m
CONFIG_VIDEO_MESON_VDEC=m
+CONFIG_SND_BCM2835=m
CONFIG_CHROME_PLATFORMS=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
@@ -1286,6 +1314,7 @@ CONFIG_QCM_DISPCC_2290=m
CONFIG_QCS_GCC_404=y
CONFIG_QDU_GCC_1000=y
CONFIG_SC_CAMCC_8280XP=m
+CONFIG_SC_DISPCC_7280=m
CONFIG_SC_DISPCC_8280XP=m
CONFIG_SA_GCC_8775P=y
CONFIG_SA_GPUCC_8775P=m
@@ -1293,6 +1322,7 @@ CONFIG_SC_GCC_7180=y
CONFIG_SC_GCC_7280=y
CONFIG_SC_GCC_8180X=y
CONFIG_SC_GCC_8280XP=y
+CONFIG_SC_GPUCC_7280=m
CONFIG_SC_GPUCC_8280XP=m
CONFIG_SC_LPASSCC_8280XP=m
CONFIG_SDM_CAMCC_845=m
@@ -1316,6 +1346,7 @@ CONFIG_SM_GCC_8650=y
CONFIG_SM_GPUCC_6115=m
CONFIG_SM_GPUCC_8150=y
CONFIG_SM_GPUCC_8250=y
+CONFIG_SM_GPUCC_8350=m
CONFIG_SM_GPUCC_8450=m
CONFIG_SM_GPUCC_8550=m
CONFIG_SM_GPUCC_8650=m
@@ -1408,6 +1439,7 @@ CONFIG_ARCH_R9A07G044=y
CONFIG_ARCH_R9A07G054=y
CONFIG_ARCH_R9A08G045=y
CONFIG_ARCH_R9A09G011=y
+CONFIG_ARCH_R9A09G057=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
@@ -1473,6 +1505,7 @@ CONFIG_PWM_VISCONTI=m
CONFIG_SL28CPLD_INTC=y
CONFIG_QCOM_PDC=y
CONFIG_QCOM_MPM=y
+CONFIG_RESET_GPIO=m
CONFIG_RESET_IMX7=y
CONFIG_RESET_QCOM_AOSS=y
CONFIG_RESET_QCOM_PDC=m
@@ -1517,6 +1550,7 @@ CONFIG_PHY_ROCKCHIP_PCIE=m
CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=m
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
+CONFIG_PHY_ROCKCHIP_USBDP=m
CONFIG_PHY_SAMSUNG_UFS=y
CONFIG_PHY_UNIPHIER_USB2=y
CONFIG_PHY_UNIPHIER_USB3=y
@@ -1535,6 +1569,7 @@ CONFIG_ARM_SPE_PMU=m
CONFIG_ARM_DMC620_PMU=m
CONFIG_HISI_PMU=y
CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
+CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
CONFIG_MESON_DDR_PMU=m
CONFIG_NVMEM_LAYOUT_SL28_VPD=m
CONFIG_NVMEM_IMX_OCOTP=y
@@ -1544,6 +1579,7 @@ CONFIG_NVMEM_LAYERSCAPE_SFP=m
CONFIG_NVMEM_MESON_EFUSE=m
CONFIG_NVMEM_MTK_EFUSE=y
CONFIG_NVMEM_QCOM_QFPROM=y
+CONFIG_NVMEM_QCOM_SEC_QFPROM=m
CONFIG_NVMEM_RMEM=m
CONFIG_NVMEM_ROCKCHIP_EFUSE=y
CONFIG_NVMEM_ROCKCHIP_OTP=y
@@ -1573,7 +1609,7 @@ CONFIG_INTERCONNECT_IMX8MQ=m
CONFIG_INTERCONNECT_IMX8MP=y
CONFIG_INTERCONNECT_QCOM=y
CONFIG_INTERCONNECT_QCOM_MSM8916=m
-CONFIG_INTERCONNECT_QCOM_MSM8996=m
+CONFIG_INTERCONNECT_QCOM_MSM8996=y
CONFIG_INTERCONNECT_QCOM_OSM_L3=m
CONFIG_INTERCONNECT_QCOM_QCM2290=y
CONFIG_INTERCONNECT_QCOM_QCS404=m
@@ -1585,9 +1621,10 @@ CONFIG_INTERCONNECT_QCOM_SC8180X=y
CONFIG_INTERCONNECT_QCOM_SC8280XP=y
CONFIG_INTERCONNECT_QCOM_SDM845=y
CONFIG_INTERCONNECT_QCOM_SDX75=y
-CONFIG_INTERCONNECT_QCOM_SM8150=m
+CONFIG_INTERCONNECT_QCOM_SM6115=y
+CONFIG_INTERCONNECT_QCOM_SM8150=y
CONFIG_INTERCONNECT_QCOM_SM8250=y
-CONFIG_INTERCONNECT_QCOM_SM8350=m
+CONFIG_INTERCONNECT_QCOM_SM8350=y
CONFIG_INTERCONNECT_QCOM_SM8450=y
CONFIG_INTERCONNECT_QCOM_SM8550=y
CONFIG_INTERCONNECT_QCOM_SM8650=y
@@ -1599,6 +1636,7 @@ CONFIG_HTE_TEGRA194=y
CONFIG_HTE_TEGRA194_TEST=m
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_FANOTIFY=y
@@ -1647,6 +1685,7 @@ CONFIG_CRYPTO_DEV_FSL_CAAM=m
CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCOM_RNG=m
+CONFIG_CRYPTO_DEV_TEGRA=m
CONFIG_CRYPTO_DEV_CCREE=m
CONFIG_CRYPTO_DEV_HISI_SEC2=m
CONFIG_CRYPTO_DEV_HISI_ZIP=m
diff --git a/arch/arm64/configs/hardening.config b/arch/arm64/configs/hardening.config
index b0e795208998..24179722927e 100644
--- a/arch/arm64/configs/hardening.config
+++ b/arch/arm64/configs/hardening.config
@@ -5,6 +5,7 @@ CONFIG_ARM64_SW_TTBR0_PAN=y
# Software Shadow Stack or PAC
CONFIG_SHADOW_CALL_STACK=y
+CONFIG_UNWIND_PATCH_PAC_INTO_SCS=y
# Pointer authentication (ARMv8.3 and later). If hardware actually supports
# it, one can turn off CONFIG_STACKPROTECTOR_STRONG with this enabled.
diff --git a/arch/arm64/crypto/aes-ce.S b/arch/arm64/crypto/aes-ce.S
index 1dc5bbbfeed2..b262eaa9170c 100644
--- a/arch/arm64/crypto/aes-ce.S
+++ b/arch/arm64/crypto/aes-ce.S
@@ -25,33 +25,28 @@
.endm
/* preload all round keys */
- .macro load_round_keys, rounds, rk
- cmp \rounds, #12
- blo 2222f /* 128 bits */
- beq 1111f /* 192 bits */
- ld1 {v17.4s-v18.4s}, [\rk], #32
-1111: ld1 {v19.4s-v20.4s}, [\rk], #32
-2222: ld1 {v21.4s-v24.4s}, [\rk], #64
- ld1 {v25.4s-v28.4s}, [\rk], #64
- ld1 {v29.4s-v31.4s}, [\rk]
+ .macro load_round_keys, rk, nr, tmp
+ add \tmp, \rk, \nr, sxtw #4
+ sub \tmp, \tmp, #160
+ ld1 {v17.4s-v20.4s}, [\rk]
+ ld1 {v21.4s-v24.4s}, [\tmp], #64
+ ld1 {v25.4s-v28.4s}, [\tmp], #64
+ ld1 {v29.4s-v31.4s}, [\tmp]
.endm
/* prepare for encryption with key in rk[] */
.macro enc_prepare, rounds, rk, temp
- mov \temp, \rk
- load_round_keys \rounds, \temp
+ load_round_keys \rk, \rounds, \temp
.endm
/* prepare for encryption (again) but with new key in rk[] */
.macro enc_switch_key, rounds, rk, temp
- mov \temp, \rk
- load_round_keys \rounds, \temp
+ load_round_keys \rk, \rounds, \temp
.endm
/* prepare for decryption with key in rk[] */
.macro dec_prepare, rounds, rk, temp
- mov \temp, \rk
- load_round_keys \rounds, \temp
+ load_round_keys \rk, \rounds, \temp
.endm
.macro do_enc_Nx, de, mc, k, i0, i1, i2, i3, i4
@@ -110,14 +105,13 @@
/* up to 5 interleaved blocks */
.macro do_block_Nx, enc, rounds, i0, i1, i2, i3, i4
- cmp \rounds, #12
- blo 2222f /* 128 bits */
- beq 1111f /* 192 bits */
+ tbz \rounds, #2, .L\@ /* 128 bits */
round_Nx \enc, v17, \i0, \i1, \i2, \i3, \i4
round_Nx \enc, v18, \i0, \i1, \i2, \i3, \i4
-1111: round_Nx \enc, v19, \i0, \i1, \i2, \i3, \i4
+ tbz \rounds, #1, .L\@ /* 192 bits */
+ round_Nx \enc, v19, \i0, \i1, \i2, \i3, \i4
round_Nx \enc, v20, \i0, \i1, \i2, \i3, \i4
-2222: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29
+.L\@: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29
round_Nx \enc, \key, \i0, \i1, \i2, \i3, \i4
.endr
fin_round_Nx \enc, v30, v31, \i0, \i1, \i2, \i3, \i4
diff --git a/arch/arm64/crypto/aes-neon.S b/arch/arm64/crypto/aes-neon.S
index 9de7fbc797af..3a8961b6ea51 100644
--- a/arch/arm64/crypto/aes-neon.S
+++ b/arch/arm64/crypto/aes-neon.S
@@ -99,16 +99,16 @@
ld1 {v15.4s}, [\rk]
add \rkp, \rk, #16
mov \i, \rounds
-1111: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
+.La\@: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
movi v15.16b, #0x40
tbl \in\().16b, {\in\().16b}, v13.16b /* ShiftRows */
sub_bytes \in
- subs \i, \i, #1
+ sub \i, \i, #1
ld1 {v15.4s}, [\rkp], #16
- beq 2222f
+ cbz \i, .Lb\@
mix_columns \in, \enc
- b 1111b
-2222: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
+ b .La\@
+.Lb\@: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
.endm
.macro encrypt_block, in, rounds, rk, rkp, i
@@ -206,7 +206,7 @@
ld1 {v15.4s}, [\rk]
add \rkp, \rk, #16
mov \i, \rounds
-1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
+.La\@: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
@@ -216,13 +216,13 @@
tbl \in2\().16b, {\in2\().16b}, v13.16b /* ShiftRows */
tbl \in3\().16b, {\in3\().16b}, v13.16b /* ShiftRows */
sub_bytes_4x \in0, \in1, \in2, \in3
- subs \i, \i, #1
+ sub \i, \i, #1
ld1 {v15.4s}, [\rkp], #16
- beq 2222f
+ cbz \i, .Lb\@
mix_columns_2x \in0, \in1, \enc
mix_columns_2x \in2, \in3, \enc
- b 1111b
-2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
+ b .La\@
+.Lb\@: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c
index 467ac2f768ac..46425e7b9755 100644
--- a/arch/arm64/crypto/aes-neonbs-glue.c
+++ b/arch/arm64/crypto/aes-neonbs-glue.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("Bit sliced AES using NEON instructions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("ecb(aes)");
diff --git a/arch/arm64/crypto/crct10dif-ce-glue.c b/arch/arm64/crypto/crct10dif-ce-glue.c
index 09eb1456aed4..606d25c559ed 100644
--- a/arch/arm64/crypto/crct10dif-ce-glue.c
+++ b/arch/arm64/crypto/crct10dif-ce-glue.c
@@ -98,7 +98,7 @@ static struct shash_alg crc_t10dif_alg[] = {{
.base.cra_name = "crct10dif",
.base.cra_driver_name = "crct10dif-arm64-neon",
- .base.cra_priority = 100,
+ .base.cra_priority = 150,
.base.cra_blocksize = CRC_T10DIF_BLOCK_SIZE,
.base.cra_module = THIS_MODULE,
}, {
@@ -138,6 +138,7 @@ module_cpu_feature_match(ASIMD, crc_t10dif_mod_init);
module_exit(crc_t10dif_mod_exit);
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("CRC-T10DIF using arm64 NEON and Crypto Extensions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("crct10dif");
MODULE_ALIAS_CRYPTO("crct10dif-arm64-ce");
diff --git a/arch/arm64/crypto/poly1305-glue.c b/arch/arm64/crypto/poly1305-glue.c
index 1fae18ba11ed..9c4bfd62e789 100644
--- a/arch/arm64/crypto/poly1305-glue.c
+++ b/arch/arm64/crypto/poly1305-glue.c
@@ -226,6 +226,7 @@ static void __exit neon_poly1305_mod_exit(void)
module_init(neon_poly1305_mod_init);
module_exit(neon_poly1305_mod_exit);
+MODULE_DESCRIPTION("Poly1305 transform using NEON instructions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("poly1305");
MODULE_ALIAS_CRYPTO("poly1305-neon");
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 4b6d2d52053e..7d7d97ad3cd5 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -1,4 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
+syscall-y += syscall_table_64.h
+
+# arm32 syscall table used by lib/compat_audit.c:
+syscall-y += unistd_32.h
+# same constants with prefixes, used by vdso, seccomp and sigreturn:
+syscall-y += unistd_compat_32.h
+
generic-y += early_ioremap.h
generic-y += mcs_spinlock.h
generic-y += qrwlock.h
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6792a1f83f2a..a407f9cd549e 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -119,6 +119,18 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
return acpi_cpu_get_madt_gicc(cpu)->uid;
}
+static inline int get_cpu_for_acpi_id(u32 uid)
+{
+ int cpu;
+
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+ if (acpi_cpu_get_madt_gicc(cpu) &&
+ uid == get_acpi_id_for_cpu(cpu))
+ return cpu;
+
+ return -EINVAL;
+}
+
static inline void arch_fix_phys_package_id(int num, u32 slot) { }
void __init acpi_init_cpus(void);
int apei_claim_sea(struct pt_regs *regs);
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 5f172611654b..9e96f024b2f1 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -175,21 +175,6 @@ 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 |
- GIC_PRIO_PSR_I_SET));
- BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON);
- /*
- * Need to make sure IRQON allows IRQs when SCR_EL3.FIQ is cleared
- * and non-secure PMR accesses are not subject to the shifts that
- * 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/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 934c658ee947..f5794d50f51d 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -15,7 +15,7 @@
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/jump_label.h>
-#include <linux/smp.h>
+#include <linux/percpu.h>
#include <linux/types.h>
#include <clocksource/arm_arch_timer.h>
diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
index c27404fa4418..a4697a0b6835 100644
--- a/arch/arm64/include/asm/arm_pmuv3.h
+++ b/arch/arm64/include/asm/arm_pmuv3.h
@@ -6,7 +6,7 @@
#ifndef __ASM_PMUV3_H
#define __ASM_PMUV3_H
-#include <linux/kvm_host.h>
+#include <asm/kvm_host.h>
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
diff --git a/arch/arm64/include/asm/asm-bug.h b/arch/arm64/include/asm/asm-bug.h
index c762038ba400..6e73809f6492 100644
--- a/arch/arm64/include/asm/asm-bug.h
+++ b/arch/arm64/include/asm/asm-bug.h
@@ -28,6 +28,7 @@
14470: .long 14471f - .; \
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
.short flags; \
+ .align 2; \
.popsection; \
14471:
#else
diff --git a/arch/arm64/include/asm/asm-extable.h b/arch/arm64/include/asm/asm-extable.h
index 980d1dd8e1a3..b8a5861dc7b7 100644
--- a/arch/arm64/include/asm/asm-extable.h
+++ b/arch/arm64/include/asm/asm-extable.h
@@ -112,6 +112,9 @@
#define _ASM_EXTABLE_KACCESS_ERR(insn, fixup, err) \
_ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, wzr)
+#define _ASM_EXTABLE_KACCESS(insn, fixup) \
+ _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, wzr, wzr)
+
#define _ASM_EXTABLE_LOAD_UNALIGNED_ZEROPAD(insn, fixup, data, addr) \
__DEFINE_ASM_GPR_NUMS \
__ASM_EXTABLE_RAW(#insn, #fixup, \
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ab8b396428da..bc0b0d75acef 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -50,16 +50,12 @@
msr daif, \flags
.endm
- .macro enable_dbg
- msr daifclr, #8
- .endm
-
.macro disable_step_tsk, flgs, tmp
tbz \flgs, #TIF_SINGLESTEP, 9990f
mrs \tmp, mdscr_el1
bic \tmp, \tmp, #DBG_MDSCR_SS
msr mdscr_el1, \tmp
- isb // Synchronise with enable_dbg
+ isb // Take effect before a subsequent clear of DAIF.D
9990:
.endm
@@ -480,9 +476,10 @@ alternative_endif
*/
.macro reset_pmuserenr_el0, tmpreg
mrs \tmpreg, id_aa64dfr0_el1
- sbfx \tmpreg, \tmpreg, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
- cmp \tmpreg, #1 // Skip if no PMU present
- b.lt 9000f
+ ubfx \tmpreg, \tmpreg, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
+ cmp \tmpreg, #ID_AA64DFR0_EL1_PMUVer_NI
+ ccmp \tmpreg, #ID_AA64DFR0_EL1_PMUVer_IMP_DEF, #4, ne
+ b.eq 9000f // Skip if no PMU present or IMP_DEF
msr pmuserenr_el0, xzr // Disable PMU access from EL0
9000:
.endm
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index cf2987464c18..1ca947d5c939 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -40,6 +40,10 @@
*/
#define dgh() asm volatile("hint #6" : : : "memory")
+#define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \
+ SB_BARRIER_INSN"nop\n", \
+ ARM64_HAS_SB))
+
#ifdef CONFIG_ARM64_PSEUDO_NMI
#define pmr_sync() \
do { \
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index fefac75fa009..28ab96e808ef 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -117,7 +117,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
* flush_dcache_folio is used when the kernel has written to the page
* cache page at virtual address page->virtual.
*
- * If this page isn't mapped (ie, page_mapping == NULL), or it might
+ * If this page isn't mapped (ie, folio_mapping == NULL), or it might
* have userspace mappings, then we _must_ always clean + invalidate
* the dcache entries associated with the kernel mapping.
*
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 270680e2b5c4..a6e5b07b64fd 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -58,6 +58,8 @@ cpucap_is_possible(const unsigned int cap)
return IS_ENABLED(CONFIG_NVIDIA_CARMEL_CNP_ERRATUM);
case ARM64_WORKAROUND_REPEAT_TLBI:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
+ case ARM64_WORKAROUND_SPECULATIVE_SSBS:
+ return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
}
return true;
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8b904a757bd3..558434267271 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -588,14 +588,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0)
{
u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_EL1_SHIFT);
- return val == ID_AA64PFR0_EL1_ELx_32BIT_64BIT;
+ return val == ID_AA64PFR0_EL1_EL1_AARCH32;
}
static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
{
u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_EL0_SHIFT);
- return val == ID_AA64PFR0_EL1_ELx_32BIT_64BIT;
+ return val == ID_AA64PFR0_EL1_EL0_AARCH32;
}
static inline bool id_aa64pfr0_sve(u64 pfr0)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 52f076afeb96..1cb0704c6163 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -86,6 +86,12 @@
#define ARM_CPU_PART_CORTEX_X2 0xD48
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
+#define ARM_CPU_PART_CORTEX_X3 0xD4E
+#define ARM_CPU_PART_NEOVERSE_V2 0xD4F
+#define ARM_CPU_PART_CORTEX_A720 0xD81
+#define ARM_CPU_PART_CORTEX_X4 0xD82
+#define ARM_CPU_PART_NEOVERSE_V3 0xD84
+#define ARM_CPU_PART_CORTEX_X925 0xD85
#define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00
@@ -159,6 +165,12 @@
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
+#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
+#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
+#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
+#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
+#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
+#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index b7afaa026842..fd87c4b8f984 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -59,13 +59,14 @@
.macro __init_el2_debug
mrs x1, id_aa64dfr0_el1
- sbfx x0, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
- cmp x0, #1
- b.lt .Lskip_pmu_\@ // Skip if no PMU present
+ ubfx x0, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
+ cmp x0, #ID_AA64DFR0_EL1_PMUVer_NI
+ ccmp x0, #ID_AA64DFR0_EL1_PMUVer_IMP_DEF, #4, ne
+ b.eq .Lskip_pmu_\@ // Skip if no PMU present or IMP_DEF
mrs x0, pmcr_el0 // Disable debug access traps
ubfx x0, x0, #11, #5 // to EL2 and allow access to
.Lskip_pmu_\@:
- csel x2, xzr, x0, lt // all PMU counters from EL1
+ csel x2, xzr, x0, eq // all PMU counters from EL1
/* Statistical profiling */
ubfx x0, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4
@@ -145,7 +146,7 @@
/* Coprocessor traps */
.macro __init_el2_cptr
__check_hvhe .LnVHE_\@, x1
- mov x0, #(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN)
+ mov x0, #CPACR_ELx_FPEN
msr cpacr_el1, x0
b .Lskip_set_cptr_\@
.LnVHE_\@:
@@ -276,7 +277,7 @@
// (h)VHE case
mrs x0, cpacr_el1 // Disable SVE traps
- orr x0, x0, #(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
+ orr x0, x0, #CPACR_ELx_ZEN
msr cpacr_el1, x0
b .Lskip_set_cptr_\@
@@ -297,7 +298,7 @@
// (h)VHE case
mrs x0, cpacr_el1 // Disable SME traps
- orr x0, x0, #(CPACR_EL1_SMEN_EL0EN | CPACR_EL1_SMEN_EL1EN)
+ orr x0, x0, #CPACR_ELx_SMEN
msr cpacr_el1, x0
b .Lskip_set_cptr_sme_\@
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 81606bf7d5ac..56c148890daf 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -121,6 +121,14 @@
#define ESR_ELx_FSC_SECC (0x18)
#define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n))
+/* Status codes for individual page table levels */
+#define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + n)
+#define ESR_ELx_FSC_PERM_L(n) (ESR_ELx_FSC_PERM + n)
+
+#define ESR_ELx_FSC_FAULT_nL (0x2C)
+#define ESR_ELx_FSC_FAULT_L(n) (((n) < 0 ? ESR_ELx_FSC_FAULT_nL : \
+ ESR_ELx_FSC_FAULT) + (n))
+
/* ISS field definitions for Data Aborts */
#define ESR_ELx_ISV_SHIFT (24)
#define ESR_ELx_ISV (UL(1) << ESR_ELx_ISV_SHIFT)
@@ -152,6 +160,7 @@
#define ESR_ELx_Xs_MASK (GENMASK_ULL(4, 0))
/* ISS field definitions for exceptions taken in to Hyp */
+#define ESR_ELx_FSC_ADDRSZ (0x00)
#define ESR_ELx_CV (UL(1) << 24)
#define ESR_ELx_COND_SHIFT (20)
#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
@@ -379,6 +388,11 @@
#ifndef __ASSEMBLY__
#include <asm/types.h>
+static inline unsigned long esr_brk_comment(unsigned long esr)
+{
+ return esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
+}
+
static inline bool esr_is_data_abort(unsigned long esr)
{
const unsigned long ec = ESR_ELx_EC(esr);
@@ -386,22 +400,53 @@ static inline bool esr_is_data_abort(unsigned long esr)
return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR;
}
+static inline bool esr_is_cfi_brk(unsigned long esr)
+{
+ return ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
+ (esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE;
+}
+
static inline bool esr_fsc_is_translation_fault(unsigned long esr)
{
- /* Translation fault, level -1 */
- if ((esr & ESR_ELx_FSC) == 0b101011)
- return true;
- return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
+ esr = esr & ESR_ELx_FSC;
+
+ return (esr == ESR_ELx_FSC_FAULT_L(3)) ||
+ (esr == ESR_ELx_FSC_FAULT_L(2)) ||
+ (esr == ESR_ELx_FSC_FAULT_L(1)) ||
+ (esr == ESR_ELx_FSC_FAULT_L(0)) ||
+ (esr == ESR_ELx_FSC_FAULT_L(-1));
}
static inline bool esr_fsc_is_permission_fault(unsigned long esr)
{
- return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_PERM;
+ esr = esr & ESR_ELx_FSC;
+
+ return (esr == ESR_ELx_FSC_PERM_L(3)) ||
+ (esr == ESR_ELx_FSC_PERM_L(2)) ||
+ (esr == ESR_ELx_FSC_PERM_L(1)) ||
+ (esr == ESR_ELx_FSC_PERM_L(0));
}
static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
{
- return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_ACCESS;
+ esr = esr & ESR_ELx_FSC;
+
+ return (esr == ESR_ELx_FSC_ACCESS_L(3)) ||
+ (esr == ESR_ELx_FSC_ACCESS_L(2)) ||
+ (esr == ESR_ELx_FSC_ACCESS_L(1)) ||
+ (esr == ESR_ELx_FSC_ACCESS_L(0));
+}
+
+/* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
+static inline bool esr_iss_is_eretax(unsigned long esr)
+{
+ return esr & ESR_ELx_ERET_ISS_ERET;
+}
+
+/* Indicate which key is used for ERETAx (false: A-Key, true: B-Key) */
+static inline bool esr_iss_is_eretab(unsigned long esr)
+{
+ return esr & ESR_ELx_ERET_ISS_ERETA;
}
const char *esr_get_class_string(unsigned long esr);
diff --git a/arch/arm64/include/asm/fb.h b/arch/arm64/include/asm/fb.h
deleted file mode 100644
index 1a495d8fb2ce..000000000000
--- a/arch/arm64/include/asm/fb.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 ARM Ltd.
- */
-#ifndef __ASM_FB_H_
-#define __ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* __ASM_FB_H_ */
diff --git a/arch/arm64/include/asm/fpu.h b/arch/arm64/include/asm/fpu.h
new file mode 100644
index 000000000000..2ae50bdce59b
--- /dev/null
+++ b/arch/arm64/include/asm/fpu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 SiFive
+ */
+
+#ifndef __ASM_FPU_H
+#define __ASM_FPU_H
+
+#include <asm/neon.h>
+
+#define kernel_fpu_available() cpu_has_neon()
+#define kernel_fpu_begin() kernel_neon_begin()
+#define kernel_fpu_end() kernel_neon_end()
+
+#endif /* ! __ASM_FPU_H */
diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
index ab158196480c..dc9cf0bd2a4c 100644
--- a/arch/arm64/include/asm/ftrace.h
+++ b/arch/arm64/include/asm/ftrace.h
@@ -12,17 +12,6 @@
#define HAVE_FUNCTION_GRAPH_FP_TEST
-/*
- * HAVE_FUNCTION_GRAPH_RET_ADDR_PTR means that the architecture can provide a
- * "return address pointer" which can be used to uniquely identify a return
- * address which has been overwritten.
- *
- * On arm64 we use the address of the caller's frame record, which remains the
- * same for the lifetime of the instrumented function, unlike the return
- * address in the LR.
- */
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
-
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
#define ARCH_SUPPORTS_FTRACE_OPS 1
#else
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index 2ddc33d93b13..293f880865e8 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -18,11 +18,11 @@
extern bool arch_hugetlb_migration_supported(struct hstate *h);
#endif
-static inline void arch_clear_hugepage_flags(struct page *page)
+static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
- clear_bit(PG_dcache_clean, &page->flags);
+ clear_bit(PG_dcache_clean, &folio->flags);
}
-#define arch_clear_hugepage_flags arch_clear_hugepage_flags
+#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
#define arch_make_huge_pte arch_make_huge_pte
@@ -46,7 +46,7 @@ extern pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long sz);
#define __HAVE_ARCH_HUGE_PTEP_GET
-extern pte_t huge_ptep_get(pte_t *ptep);
+extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
void __init arm64_hugetlb_cma_reserve(void);
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index db1aeacd4cd9..8c0a36f72d6f 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -135,6 +135,12 @@ enum aarch64_insn_special_register {
AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210
};
+enum aarch64_insn_system_register {
+ AARCH64_INSN_SYSREG_TPIDR_EL1 = 0x4684,
+ AARCH64_INSN_SYSREG_TPIDR_EL2 = 0x6682,
+ AARCH64_INSN_SYSREG_SP_EL0 = 0x4208,
+};
+
enum aarch64_insn_variant {
AARCH64_INSN_VARIANT_32BIT,
AARCH64_INSN_VARIANT_64BIT
@@ -686,6 +692,8 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
}
#endif
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
+u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
+ enum aarch64_insn_system_register sysreg);
s32 aarch64_get_branch_offset(u32 insn);
u32 aarch64_set_branch_offset(u32 insn, s32 offset);
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 8d825522c55c..41fd90895dfc 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -140,6 +140,134 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
#define memcpy_toio(c,a,l) __memcpy_toio((c),(a),(l))
/*
+ * The ARM64 iowrite implementation is intended to support drivers that want to
+ * use write combining. For instance PCI drivers using write combining with a 64
+ * byte __iowrite64_copy() expect to get a 64 byte MemWr TLP on the PCIe bus.
+ *
+ * Newer ARM core have sensitive write combining buffers, it is important that
+ * the stores be contiguous blocks of store instructions. Normal memcpy
+ * approaches have a very low chance to generate write combining.
+ *
+ * Since this is the only API on ARM64 that should be used with write combining
+ * it also integrates the DGH hint which is supposed to lower the latency to
+ * emit the large TLP from the CPU.
+ */
+
+static __always_inline void
+__const_memcpy_toio_aligned32(volatile u32 __iomem *to, const u32 *from,
+ size_t count)
+{
+ switch (count) {
+ case 8:
+ asm volatile("str %w0, [%8, #4 * 0]\n"
+ "str %w1, [%8, #4 * 1]\n"
+ "str %w2, [%8, #4 * 2]\n"
+ "str %w3, [%8, #4 * 3]\n"
+ "str %w4, [%8, #4 * 4]\n"
+ "str %w5, [%8, #4 * 5]\n"
+ "str %w6, [%8, #4 * 6]\n"
+ "str %w7, [%8, #4 * 7]\n"
+ :
+ : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+ "rZ"(from[3]), "rZ"(from[4]), "rZ"(from[5]),
+ "rZ"(from[6]), "rZ"(from[7]), "r"(to));
+ break;
+ case 4:
+ asm volatile("str %w0, [%4, #4 * 0]\n"
+ "str %w1, [%4, #4 * 1]\n"
+ "str %w2, [%4, #4 * 2]\n"
+ "str %w3, [%4, #4 * 3]\n"
+ :
+ : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+ "rZ"(from[3]), "r"(to));
+ break;
+ case 2:
+ asm volatile("str %w0, [%2, #4 * 0]\n"
+ "str %w1, [%2, #4 * 1]\n"
+ :
+ : "rZ"(from[0]), "rZ"(from[1]), "r"(to));
+ break;
+ case 1:
+ __raw_writel(*from, to);
+ break;
+ default:
+ BUILD_BUG();
+ }
+}
+
+void __iowrite32_copy_full(void __iomem *to, const void *from, size_t count);
+
+static __always_inline void
+__iowrite32_copy(void __iomem *to, const void *from, size_t count)
+{
+ if (__builtin_constant_p(count) &&
+ (count == 8 || count == 4 || count == 2 || count == 1)) {
+ __const_memcpy_toio_aligned32(to, from, count);
+ dgh();
+ } else {
+ __iowrite32_copy_full(to, from, count);
+ }
+}
+#define __iowrite32_copy __iowrite32_copy
+
+static __always_inline void
+__const_memcpy_toio_aligned64(volatile u64 __iomem *to, const u64 *from,
+ size_t count)
+{
+ switch (count) {
+ case 8:
+ asm volatile("str %x0, [%8, #8 * 0]\n"
+ "str %x1, [%8, #8 * 1]\n"
+ "str %x2, [%8, #8 * 2]\n"
+ "str %x3, [%8, #8 * 3]\n"
+ "str %x4, [%8, #8 * 4]\n"
+ "str %x5, [%8, #8 * 5]\n"
+ "str %x6, [%8, #8 * 6]\n"
+ "str %x7, [%8, #8 * 7]\n"
+ :
+ : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+ "rZ"(from[3]), "rZ"(from[4]), "rZ"(from[5]),
+ "rZ"(from[6]), "rZ"(from[7]), "r"(to));
+ break;
+ case 4:
+ asm volatile("str %x0, [%4, #8 * 0]\n"
+ "str %x1, [%4, #8 * 1]\n"
+ "str %x2, [%4, #8 * 2]\n"
+ "str %x3, [%4, #8 * 3]\n"
+ :
+ : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+ "rZ"(from[3]), "r"(to));
+ break;
+ case 2:
+ asm volatile("str %x0, [%2, #8 * 0]\n"
+ "str %x1, [%2, #8 * 1]\n"
+ :
+ : "rZ"(from[0]), "rZ"(from[1]), "r"(to));
+ break;
+ case 1:
+ __raw_writeq(*from, to);
+ break;
+ default:
+ BUILD_BUG();
+ }
+}
+
+void __iowrite64_copy_full(void __iomem *to, const void *from, size_t count);
+
+static __always_inline void
+__iowrite64_copy(void __iomem *to, const void *from, size_t count)
+{
+ if (__builtin_constant_p(count) &&
+ (count == 8 || count == 4 || count == 2 || count == 1)) {
+ __const_memcpy_toio_aligned64(to, from, count);
+ dgh();
+ } else {
+ __iowrite64_copy_full(to, from, count);
+ }
+}
+#define __iowrite64_copy __iowrite64_copy
+
+/*
* I/O memory mapping functions.
*/
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index 0a7186a93882..d4d7451c2c12 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -5,7 +5,6 @@
#ifndef __ASM_IRQFLAGS_H
#define __ASM_IRQFLAGS_H
-#include <asm/alternative.h>
#include <asm/barrier.h>
#include <asm/ptrace.h>
#include <asm/sysreg.h>
diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
index 6aafbb789991..4e753908b801 100644
--- a/arch/arm64/include/asm/jump_label.h
+++ b/arch/arm64/include/asm/jump_label.h
@@ -15,17 +15,23 @@
#define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE
+#define JUMP_TABLE_ENTRY(key, label) \
+ ".pushsection __jump_table, \"aw\"\n\t" \
+ ".align 3\n\t" \
+ ".long 1b - ., %l["#label"] - .\n\t" \
+ ".quad %c0 - .\n\t" \
+ ".popsection\n\t" \
+ : : "i"(key) : : label
+
static __always_inline bool arch_static_branch(struct static_key * const key,
const bool branch)
{
+ char *k = &((char *)key)[branch];
+
asm goto(
"1: nop \n\t"
- " .pushsection __jump_table, \"aw\" \n\t"
- " .align 3 \n\t"
- " .long 1b - ., %l[l_yes] - . \n\t"
- " .quad %c0 - . \n\t"
- " .popsection \n\t"
- : : "i"(&((char *)key)[branch]) : : l_yes);
+ JUMP_TABLE_ENTRY(k, l_yes)
+ );
return false;
l_yes:
@@ -35,15 +41,11 @@ l_yes:
static __always_inline bool arch_static_branch_jump(struct static_key * const key,
const bool branch)
{
+ char *k = &((char *)key)[branch];
asm goto(
"1: b %l[l_yes] \n\t"
- " .pushsection __jump_table, \"aw\" \n\t"
- " .align 3 \n\t"
- " .long 1b - ., %l[l_yes] - . \n\t"
- " .quad %c0 - . \n\t"
- " .popsection \n\t"
- : : "i"(&((char *)key)[branch]) : : l_yes);
-
+ JUMP_TABLE_ENTRY(k, l_yes)
+ );
return false;
l_yes:
return true;
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index e01bb5ca13b7..d81cc746e0eb 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -102,7 +102,6 @@
#define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
-#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME | HCRX_EL2_TCR2En)
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM)
/* TCR_EL2 Registers bits */
@@ -305,6 +304,12 @@
GENMASK(19, 14) | \
BIT(11))
+#define CPTR_VHE_EL2_RES0 (GENMASK(63, 32) | \
+ GENMASK(27, 26) | \
+ GENMASK(23, 22) | \
+ GENMASK(19, 18) | \
+ GENMASK(15, 0))
+
/* Hyp Debug Configuration Register bits */
#define MDCR_EL2_E2TB_MASK (UL(0x3))
#define MDCR_EL2_E2TB_SHIFT (UL(24))
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 24b5e6b23417..2181a11b9d92 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -73,10 +73,8 @@ enum __kvm_host_smccc_func {
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range,
__KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context,
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
- __KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr,
- __KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr,
- __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs,
- __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs,
+ __KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs,
+ __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_init_traps,
__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
@@ -234,6 +232,8 @@ extern void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
phys_addr_t start, unsigned long pages);
extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
+extern int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding);
+
extern void __kvm_timer_set_cntvoff(u64 cntvoff);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
@@ -241,8 +241,6 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
extern void __kvm_adjust_pc(struct kvm_vcpu *vcpu);
extern u64 __vgic_v3_get_gic_config(void);
-extern u64 __vgic_v3_read_vmcr(void);
-extern void __vgic_v3_write_vmcr(u32 vmcr);
extern void __vgic_v3_init_lrs(void);
extern u64 __kvm_get_mdcr_el2(void);
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 975af30af31f..a601a9305b10 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -11,6 +11,7 @@
#ifndef __ARM64_KVM_EMULATE_H__
#define __ARM64_KVM_EMULATE_H__
+#include <linux/bitfield.h>
#include <linux/kvm_host.h>
#include <asm/debug-monitors.h>
@@ -55,6 +56,14 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
+static inline void kvm_inject_nested_sve_trap(struct kvm_vcpu *vcpu)
+{
+ u64 esr = FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SVE) |
+ ESR_ELx_IL;
+
+ kvm_inject_nested_sync(vcpu, esr);
+}
+
#if defined(__KVM_VHE_HYPERVISOR__) || defined(__KVM_NVHE_HYPERVISOR__)
static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
{
@@ -69,39 +78,17 @@ static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
{
- vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
- if (has_vhe() || has_hvhe())
- vcpu->arch.hcr_el2 |= HCR_E2H;
- if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
- /* route synchronous external abort exceptions to EL2 */
- vcpu->arch.hcr_el2 |= HCR_TEA;
- /* trap error record accesses */
- vcpu->arch.hcr_el2 |= HCR_TERR;
- }
+ if (!vcpu_has_run_once(vcpu))
+ vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
- if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB)) {
- vcpu->arch.hcr_el2 |= HCR_FWB;
- } else {
- /*
- * For non-FWB CPUs, we trap VM ops (HCR_EL2.TVM) until M+C
- * get set in SCTLR_EL1 such that we can detect when the guest
- * MMU gets turned on and do the necessary cache maintenance
- * then.
- */
+ /*
+ * For non-FWB CPUs, we trap VM ops (HCR_EL2.TVM) until M+C
+ * get set in SCTLR_EL1 such that we can detect when the guest
+ * MMU gets turned on and do the necessary cache maintenance
+ * then.
+ */
+ if (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
vcpu->arch.hcr_el2 |= HCR_TVM;
- }
-
- if (cpus_have_final_cap(ARM64_HAS_EVT) &&
- !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE))
- vcpu->arch.hcr_el2 |= HCR_TID4;
- else
- vcpu->arch.hcr_el2 |= HCR_TID2;
-
- if (vcpu_el1_is_32bit(vcpu))
- vcpu->arch.hcr_el2 &= ~HCR_RW;
-
- if (kvm_has_mte(vcpu->kvm))
- vcpu->arch.hcr_el2 |= HCR_ATA;
}
static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu)
@@ -125,16 +112,6 @@ static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
vcpu->arch.hcr_el2 |= HCR_TWI;
}
-static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu)
-{
- vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
-}
-
-static inline void vcpu_ptrauth_disable(struct kvm_vcpu *vcpu)
-{
- vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK);
-}
-
static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
{
return vcpu->arch.vsesr_el2;
@@ -567,6 +544,68 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
vcpu_set_flag((v), e); \
} while (0)
+#define __build_check_all_or_none(r, bits) \
+ BUILD_BUG_ON(((r) & (bits)) && ((r) & (bits)) != (bits))
+
+#define __cpacr_to_cptr_clr(clr, set) \
+ ({ \
+ u64 cptr = 0; \
+ \
+ if ((set) & CPACR_ELx_FPEN) \
+ cptr |= CPTR_EL2_TFP; \
+ if ((set) & CPACR_ELx_ZEN) \
+ cptr |= CPTR_EL2_TZ; \
+ if ((set) & CPACR_ELx_SMEN) \
+ cptr |= CPTR_EL2_TSM; \
+ if ((clr) & CPACR_ELx_TTA) \
+ cptr |= CPTR_EL2_TTA; \
+ if ((clr) & CPTR_EL2_TAM) \
+ cptr |= CPTR_EL2_TAM; \
+ if ((clr) & CPTR_EL2_TCPAC) \
+ cptr |= CPTR_EL2_TCPAC; \
+ \
+ cptr; \
+ })
+
+#define __cpacr_to_cptr_set(clr, set) \
+ ({ \
+ u64 cptr = 0; \
+ \
+ if ((clr) & CPACR_ELx_FPEN) \
+ cptr |= CPTR_EL2_TFP; \
+ if ((clr) & CPACR_ELx_ZEN) \
+ cptr |= CPTR_EL2_TZ; \
+ if ((clr) & CPACR_ELx_SMEN) \
+ cptr |= CPTR_EL2_TSM; \
+ if ((set) & CPACR_ELx_TTA) \
+ cptr |= CPTR_EL2_TTA; \
+ if ((set) & CPTR_EL2_TAM) \
+ cptr |= CPTR_EL2_TAM; \
+ if ((set) & CPTR_EL2_TCPAC) \
+ cptr |= CPTR_EL2_TCPAC; \
+ \
+ cptr; \
+ })
+
+#define cpacr_clear_set(clr, set) \
+ do { \
+ BUILD_BUG_ON((set) & CPTR_VHE_EL2_RES0); \
+ BUILD_BUG_ON((clr) & CPACR_ELx_E0POE); \
+ __build_check_all_or_none((clr), CPACR_ELx_FPEN); \
+ __build_check_all_or_none((set), CPACR_ELx_FPEN); \
+ __build_check_all_or_none((clr), CPACR_ELx_ZEN); \
+ __build_check_all_or_none((set), CPACR_ELx_ZEN); \
+ __build_check_all_or_none((clr), CPACR_ELx_SMEN); \
+ __build_check_all_or_none((set), CPACR_ELx_SMEN); \
+ \
+ if (has_vhe() || has_hvhe()) \
+ sysreg_clear_set(cpacr_el1, clr, set); \
+ else \
+ sysreg_clear_set(cptr_el2, \
+ __cpacr_to_cptr_clr(clr, set), \
+ __cpacr_to_cptr_set(clr, set));\
+ } while (0)
+
static __always_inline void kvm_write_cptr_el2(u64 val)
{
if (has_vhe() || has_hvhe())
@@ -580,23 +619,20 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
u64 val;
if (has_vhe()) {
- val = (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |
- CPACR_EL1_ZEN_EL1EN);
+ val = (CPACR_ELx_FPEN | CPACR_EL1_ZEN_EL1EN);
if (cpus_have_final_cap(ARM64_SME))
val |= CPACR_EL1_SMEN_EL1EN;
} else if (has_hvhe()) {
- val = (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
+ val = CPACR_ELx_FPEN;
- if (!vcpu_has_sve(vcpu) ||
- (vcpu->arch.fp_state != FP_STATE_GUEST_OWNED))
- val |= CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN;
+ if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
+ val |= CPACR_ELx_ZEN;
if (cpus_have_final_cap(ARM64_SME))
- val |= CPACR_EL1_SMEN_EL1EN | CPACR_EL1_SMEN_EL0EN;
+ val |= CPACR_ELx_SMEN;
} else {
val = CPTR_NVHE_EL2_RES1;
- if (vcpu_has_sve(vcpu) &&
- (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED))
+ if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
val |= CPTR_EL2_TZ;
if (cpus_have_final_cap(ARM64_SME))
val &= ~CPTR_EL2_TSM;
@@ -611,4 +647,50 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
kvm_write_cptr_el2(val);
}
+
+/*
+ * Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
+ * format if E2H isn't set.
+ */
+static inline u64 vcpu_sanitised_cptr_el2(const struct kvm_vcpu *vcpu)
+{
+ u64 cptr = __vcpu_sys_reg(vcpu, CPTR_EL2);
+
+ if (!vcpu_el2_e2h_is_set(vcpu))
+ cptr = translate_cptr_el2_to_cpacr_el1(cptr);
+
+ return cptr;
+}
+
+static inline bool ____cptr_xen_trap_enabled(const struct kvm_vcpu *vcpu,
+ unsigned int xen)
+{
+ switch (xen) {
+ case 0b00:
+ case 0b10:
+ return true;
+ case 0b01:
+ return vcpu_el2_tge_is_set(vcpu) && !vcpu_is_el2(vcpu);
+ case 0b11:
+ default:
+ return false;
+ }
+}
+
+#define __guest_hyp_cptr_xen_trap_enabled(vcpu, xen) \
+ (!vcpu_has_nv(vcpu) ? false : \
+ ____cptr_xen_trap_enabled(vcpu, \
+ SYS_FIELD_GET(CPACR_ELx, xen, \
+ vcpu_sanitised_cptr_el2(vcpu))))
+
+static inline bool guest_hyp_fpsimd_traps_enabled(const struct kvm_vcpu *vcpu)
+{
+ return __guest_hyp_cptr_xen_trap_enabled(vcpu, FPEN);
+}
+
+static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
+{
+ return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
+}
+
#endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 9e8a496fb284..a33f5996ca9f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -76,6 +76,7 @@ static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
extern unsigned int __ro_after_init kvm_sve_max_vl;
+extern unsigned int __ro_after_init kvm_host_sve_max_vl;
int __init kvm_arm_init_sve(void);
u32 __attribute_const__ kvm_target_cpu(void);
@@ -188,6 +189,33 @@ struct kvm_s2_mmu {
uint64_t split_page_chunk_size;
struct kvm_arch *arch;
+
+ /*
+ * For a shadow stage-2 MMU, the virtual vttbr used by the
+ * host to parse the guest S2.
+ * This either contains:
+ * - the virtual VTTBR programmed by the guest hypervisor with
+ * CnP cleared
+ * - The value 1 (VMID=0, BADDR=0, CnP=1) if invalid
+ *
+ * We also cache the full VTCR which gets used for TLB invalidation,
+ * taking the ARM ARM's "Any of the bits in VTCR_EL2 are permitted
+ * to be cached in a TLB" to the letter.
+ */
+ u64 tlb_vttbr;
+ u64 tlb_vtcr;
+
+ /*
+ * true when this represents a nested context where virtual
+ * HCR_EL2.VM == 1
+ */
+ bool nested_stage2_enabled;
+
+ /*
+ * 0: Nobody is currently using this, check vttbr for validity
+ * >0: Somebody is actively using this.
+ */
+ atomic_t refcnt;
};
struct kvm_arch_memory_slot {
@@ -211,6 +239,7 @@ typedef unsigned int pkvm_handle_t;
struct kvm_protected_vm {
pkvm_handle_t handle;
struct kvm_hyp_memcache teardown_mc;
+ bool enabled;
};
struct kvm_mpidr_data {
@@ -220,20 +249,10 @@ struct kvm_mpidr_data {
static inline u16 kvm_mpidr_index(struct kvm_mpidr_data *data, u64 mpidr)
{
- unsigned long mask = data->mpidr_mask;
- u64 aff = mpidr & MPIDR_HWID_BITMASK;
- int nbits, bit, bit_idx = 0;
- u16 index = 0;
+ unsigned long index = 0, mask = data->mpidr_mask;
+ unsigned long aff = mpidr & MPIDR_HWID_BITMASK;
- /*
- * If this looks like RISC-V's BEXT or x86's PEXT
- * instructions, it isn't by accident.
- */
- nbits = fls(mask);
- for_each_set_bit(bit, &mask, nbits) {
- index |= (aff & BIT(bit)) >> (bit - bit_idx);
- bit_idx++;
- }
+ bitmap_gather(&index, &aff, &mask, fls(mask));
return index;
}
@@ -264,6 +283,14 @@ struct kvm_arch {
*/
u64 fgu[__NR_FGT_GROUP_IDS__];
+ /*
+ * Stage 2 paging state for VMs with nested S2 using a virtual
+ * VMID.
+ */
+ struct kvm_s2_mmu *nested_mmus;
+ size_t nested_mmus_size;
+ int nested_mmus_next;
+
/* Interrupt controller */
struct vgic_dist vgic;
@@ -335,11 +362,11 @@ struct kvm_arch {
* Atomic access to multiple idregs are guarded by kvm_arch.config_lock.
*/
#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id))
-#define IDX_IDREG(idx) sys_reg(3, 0, 0, ((idx) >> 3) + 1, (idx) & Op2_mask)
-#define IDREG(kvm, id) ((kvm)->arch.id_regs[IDREG_IDX(id)])
#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1)
u64 id_regs[KVM_ARM_ID_REG_NUM];
+ u64 ctr_el0;
+
/* Masks for VNCR-baked sysregs */
struct kvm_sysreg_masks *sysreg_masks;
@@ -431,6 +458,7 @@ enum vcpu_sysreg {
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
HACR_EL2, /* Hypervisor Auxiliary Control Register */
+ ZCR_EL2, /* SVE Control Register (EL2) */
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
TCR_EL2, /* Translation Control Register (EL2) */
@@ -530,8 +558,64 @@ struct kvm_cpu_context {
u64 *vncr_array;
};
+struct cpu_sve_state {
+ __u64 zcr_el1;
+
+ /*
+ * Ordering is important since __sve_save_state/__sve_restore_state
+ * relies on it.
+ */
+ __u32 fpsr;
+ __u32 fpcr;
+
+ /* Must be SVE_VQ_BYTES (128 bit) aligned. */
+ __u8 sve_regs[];
+};
+
+/*
+ * This structure is instantiated on a per-CPU basis, and contains
+ * data that is:
+ *
+ * - tied to a single physical CPU, and
+ * - either have a lifetime that does not extend past vcpu_put()
+ * - or is an invariant for the lifetime of the system
+ *
+ * Use host_data_ptr(field) as a way to access a pointer to such a
+ * field.
+ */
struct kvm_host_data {
struct kvm_cpu_context host_ctxt;
+
+ /*
+ * All pointers in this union are hyp VA.
+ * sve_state is only used in pKVM and if system_supports_sve().
+ */
+ union {
+ struct user_fpsimd_state *fpsimd_state;
+ struct cpu_sve_state *sve_state;
+ };
+
+ /* Ownership of the FP regs */
+ enum {
+ FP_STATE_FREE,
+ FP_STATE_HOST_OWNED,
+ FP_STATE_GUEST_OWNED,
+ } fp_owner;
+
+ /*
+ * host_debug_state contains the host registers which are
+ * saved and restored during world switches.
+ */
+ struct {
+ /* {Break,watch}point registers */
+ struct kvm_guest_debug_arch regs;
+ /* Statistical profiling extension */
+ u64 pmscr_el1;
+ /* Self-hosted trace */
+ u64 trfcr_el1;
+ /* Values of trap registers for the host before guest entry. */
+ u64 mdcr_el2;
+ } host_debug_state;
};
struct kvm_host_psci_config {
@@ -592,19 +676,9 @@ struct kvm_vcpu_arch {
u64 mdcr_el2;
u64 cptr_el2;
- /* Values of trap registers for the host before guest entry. */
- u64 mdcr_el2_host;
-
/* Exception Information */
struct kvm_vcpu_fault_info fault;
- /* Ownership of the FP regs */
- enum {
- FP_STATE_FREE,
- FP_STATE_HOST_OWNED,
- FP_STATE_GUEST_OWNED,
- } fp_state;
-
/* Configuration flags, set once and for all before the vcpu can run */
u8 cflags;
@@ -627,11 +701,10 @@ struct kvm_vcpu_arch {
* We maintain more than a single set of debug registers to support
* debugging the guest from the host and to maintain separate host and
* guest state during world switches. vcpu_debug_state are the debug
- * registers of the vcpu as the guest sees them. host_debug_state are
- * the host registers which are saved and restored during
- * world switches. external_debug_state contains the debug
- * values we want to debug the guest. This is set via the
- * KVM_SET_GUEST_DEBUG ioctl.
+ * registers of the vcpu as the guest sees them.
+ *
+ * external_debug_state contains the debug values we want to debug the
+ * guest. This is set via the KVM_SET_GUEST_DEBUG ioctl.
*
* debug_ptr points to the set of debug registers that should be loaded
* onto the hardware when running the guest.
@@ -640,18 +713,6 @@ struct kvm_vcpu_arch {
struct kvm_guest_debug_arch vcpu_debug_state;
struct kvm_guest_debug_arch external_debug_state;
- struct user_fpsimd_state *host_fpsimd_state; /* hyp VA */
- struct task_struct *parent_task;
-
- struct {
- /* {Break,watch}point registers */
- struct kvm_guest_debug_arch regs;
- /* Statistical profiling extension */
- u64 pmscr_el1;
- /* Self-hosted trace */
- u64 trfcr_el1;
- } host_debug_state;
-
/* VGIC state */
struct vgic_cpu vgic_cpu;
struct arch_timer_cpu timer_cpu;
@@ -817,8 +878,6 @@ struct kvm_vcpu_arch {
#define DEBUG_STATE_SAVE_SPE __vcpu_single_flag(iflags, BIT(5))
/* Save TRBE context if active */
#define DEBUG_STATE_SAVE_TRBE __vcpu_single_flag(iflags, BIT(6))
-/* vcpu running in HYP context */
-#define VCPU_HYP_CONTEXT __vcpu_single_flag(iflags, BIT(7))
/* SVE enabled for host EL0 */
#define HOST_SVE_ENABLED __vcpu_single_flag(sflags, BIT(0))
@@ -844,6 +903,9 @@ struct kvm_vcpu_arch {
#define vcpu_sve_max_vq(vcpu) sve_vq_from_vl((vcpu)->arch.sve_max_vl)
+#define vcpu_sve_zcr_elx(vcpu) \
+ (unlikely(is_hyp_ctxt(vcpu)) ? ZCR_EL2 : ZCR_EL1)
+
#define vcpu_sve_state_size(vcpu) ({ \
size_t __size_ret; \
unsigned int __vcpu_vq; \
@@ -896,7 +958,7 @@ struct kvm_vcpu_arch {
* Don't bother with VNCR-based accesses in the nVHE code, it has no
* business dealing with NV.
*/
-static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
+static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
{
#if !defined (__KVM_NVHE_HYPERVISOR__)
if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
@@ -906,6 +968,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
return (u64 *)&ctxt->sys_regs[r];
}
+#define __ctxt_sys_reg(c,r) \
+ ({ \
+ BUILD_BUG_ON(__builtin_constant_p(r) && \
+ (r) >= NR_SYS_REGS); \
+ ___ctxt_sys_reg(c, r); \
+ })
+
#define ctxt_sys_reg(c,r) (*__ctxt_sys_reg(c,r))
u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
@@ -961,6 +1030,7 @@ static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break;
case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break;
case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
+ case ZCR_EL1: *val = read_sysreg_s(SYS_ZCR_EL12); break;
default: return false;
}
@@ -1006,6 +1076,7 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break;
case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break;
case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break;
+ case ZCR_EL1: write_sysreg_s(val, SYS_ZCR_EL12); break;
default: return false;
}
@@ -1115,7 +1186,7 @@ int __init populate_nv_trap_config(void);
bool lock_all_vcpus(struct kvm *kvm);
void unlock_all_vcpus(struct kvm *kvm);
-void kvm_init_sysreg(struct kvm_vcpu *);
+void kvm_calculate_traps(struct kvm_vcpu *vcpu);
/* MMIO helpers */
void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
@@ -1168,6 +1239,44 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
DECLARE_KVM_HYP_PER_CPU(struct kvm_host_data, kvm_host_data);
+/*
+ * How we access per-CPU host data depends on the where we access it from,
+ * and the mode we're in:
+ *
+ * - VHE and nVHE hypervisor bits use their locally defined instance
+ *
+ * - the rest of the kernel use either the VHE or nVHE one, depending on
+ * the mode we're running in.
+ *
+ * Unless we're in protected mode, fully deprivileged, and the nVHE
+ * per-CPU stuff is exclusively accessible to the protected EL2 code.
+ * In this case, the EL1 code uses the *VHE* data as its private state
+ * (which makes sense in a way as there shouldn't be any shared state
+ * between the host and the hypervisor).
+ *
+ * Yes, this is all totally trivial. Shoot me now.
+ */
+#if defined(__KVM_NVHE_HYPERVISOR__) || defined(__KVM_VHE_HYPERVISOR__)
+#define host_data_ptr(f) (&this_cpu_ptr(&kvm_host_data)->f)
+#else
+#define host_data_ptr(f) \
+ (static_branch_unlikely(&kvm_protected_mode_initialized) ? \
+ &this_cpu_ptr(&kvm_host_data)->f : \
+ &this_cpu_ptr_hyp_sym(kvm_host_data)->f)
+#endif
+
+/* Check whether the FP regs are owned by the guest */
+static inline bool guest_owns_fp_regs(void)
+{
+ return *host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED;
+}
+
+/* Check whether the FP regs are owned by the host */
+static inline bool host_owns_fp_regs(void)
+{
+ return *host_data_ptr(fp_owner) == FP_STATE_HOST_OWNED;
+}
+
static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
{
/* The host's MPIDR is immutable, so let's set it up at boot time */
@@ -1180,7 +1289,6 @@ static inline bool kvm_system_needs_idmapped_vectors(void)
}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
void kvm_arm_init_debug(void);
void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu);
@@ -1211,7 +1319,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
-void kvm_vcpu_unshare_task_fp(struct kvm_vcpu *vcpu);
static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
{
@@ -1239,6 +1346,7 @@ void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu);
int __init kvm_set_ipa_limit(void);
+u32 kvm_get_pa_bits(struct kvm *kvm);
#define __KVM_HAVE_ARCH_VM_ALLOC
struct kvm *kvm_arch_alloc_vm(void);
@@ -1247,10 +1355,9 @@ struct kvm *kvm_arch_alloc_vm(void);
#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE
-static inline bool kvm_vm_is_protected(struct kvm *kvm)
-{
- return false;
-}
+#define kvm_vm_is_protected(kvm) (is_protected_kvm_enabled() && (kvm)->arch.pkvm.enabled)
+
+#define vcpu_is_protected(vcpu) kvm_vm_is_protected((vcpu)->kvm)
int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
@@ -1275,6 +1382,8 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
#define vcpu_has_feature(v, f) __vcpu_has_feature(&(v)->kvm->arch, (f))
+#define kvm_vcpu_initialized(v) vcpu_get_flag(vcpu, VCPU_INITIALIZED)
+
int kvm_trng_call(struct kvm_vcpu *vcpu);
#ifdef CONFIG_KVM
extern phys_addr_t hyp_mem_base;
@@ -1287,6 +1396,24 @@ static inline void kvm_hyp_reserve(void) { }
void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
+static inline u64 *__vm_id_reg(struct kvm_arch *ka, u32 reg)
+{
+ switch (reg) {
+ case sys_reg(3, 0, 0, 1, 0) ... sys_reg(3, 0, 0, 7, 7):
+ return &ka->id_regs[IDREG_IDX(reg)];
+ case SYS_CTR_EL0:
+ return &ka->ctr_el0;
+ default:
+ WARN_ON_ONCE(1);
+ return NULL;
+ }
+}
+
+#define kvm_read_vm_id_reg(kvm, reg) \
+ ({ u64 __val = *__vm_id_reg(&(kvm)->arch, reg); __val; })
+
+void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
+
#define __expand_field_sign_unsigned(id, fld, val) \
((u64)SYS_FIELD_VALUE(id, fld, val))
@@ -1303,7 +1430,7 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
#define get_idreg_field_unsigned(kvm, id, fld) \
({ \
- u64 __val = IDREG((kvm), SYS_##id); \
+ u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id); \
FIELD_GET(id##_##fld##_MASK, __val); \
})
@@ -1331,4 +1458,19 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
+/* Check for a given level of PAuth support */
+#define kvm_has_pauth(k, l) \
+ ({ \
+ bool pa, pi, pa3; \
+ \
+ pa = kvm_has_feat((k), ID_AA64ISAR1_EL1, APA, l); \
+ pa &= kvm_has_feat((k), ID_AA64ISAR1_EL1, GPA, IMP); \
+ pi = kvm_has_feat((k), ID_AA64ISAR1_EL1, API, l); \
+ pi &= kvm_has_feat((k), ID_AA64ISAR1_EL1, GPI, IMP); \
+ pa3 = kvm_has_feat((k), ID_AA64ISAR2_EL1, APA3, l); \
+ pa3 &= kvm_has_feat((k), ID_AA64ISAR2_EL1, GPA3, IMP); \
+ \
+ (pa + pi + pa3) == 1; \
+ })
+
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 3e2a1ac0c9bb..c838309e4ec4 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -80,8 +80,8 @@ void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if);
-void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if);
-void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if);
+void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if);
+void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if);
int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
#ifdef __KVM_NVHE_HYPERVISOR__
@@ -111,7 +111,8 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu);
void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
-void __sve_restore_state(void *sve_pffr, u32 *fpsr);
+void __sve_save_state(void *sve_pffr, u32 *fpsr, int save_ffr);
+void __sve_restore_state(void *sve_pffr, u32 *fpsr, int restore_ffr);
u64 __guest_enter(struct kvm_vcpu *vcpu);
@@ -123,8 +124,8 @@ void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
#endif
#ifdef __KVM_NVHE_HYPERVISOR__
-void __pkvm_init_switch_pgd(phys_addr_t phys, unsigned long size,
- phys_addr_t pgd, void *sp, void *cont_fn);
+void __pkvm_init_switch_pgd(phys_addr_t pgd, unsigned long sp,
+ void (*fn)(void));
int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
unsigned long *per_cpu_base, u32 hyp_va_bits);
void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
@@ -142,5 +143,6 @@ extern u64 kvm_nvhe_sym(id_aa64smfr0_el1_sys_val);
extern unsigned long kvm_nvhe_sym(__icache_flags);
extern unsigned int kvm_nvhe_sym(kvm_arm_vmid_bits);
+extern unsigned int kvm_nvhe_sym(kvm_host_sve_max_vl);
#endif /* __ARM64_KVM_HYP_H__ */
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index d5e48d870461..216ca424bb16 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -98,6 +98,7 @@ alternative_cb_end
#include <asm/mmu_context.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_host.h>
+#include <asm/kvm_nested.h>
void kvm_update_va_mask(struct alt_instr *alt,
__le32 *origptr, __le32 *updptr, int nr_inst);
@@ -165,6 +166,10 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr);
void __init free_hyp_pgds(void);
+void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size);
+void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end);
+void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end);
+
void stage2_unmap_vm(struct kvm *kvm);
int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long type);
void kvm_uninit_stage2_mmu(struct kvm *kvm);
@@ -326,5 +331,26 @@ static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
{
return container_of(mmu->arch, struct kvm, arch);
}
+
+static inline u64 get_vmid(u64 vttbr)
+{
+ return (vttbr & VTTBR_VMID_MASK(kvm_get_vmid_bits())) >>
+ VTTBR_VMID_SHIFT;
+}
+
+static inline bool kvm_s2_mmu_valid(struct kvm_s2_mmu *mmu)
+{
+ return !(mmu->tlb_vttbr & VTTBR_CNP_BIT);
+}
+
+static inline bool kvm_is_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
+{
+ /*
+ * Be careful, mmu may not be fully initialised so do look at
+ * *any* of its fields.
+ */
+ return &kvm->arch.mmu != mmu;
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __ARM64_KVM_MMU_H__ */
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index c77d795556e1..5b06c31035a2 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -5,6 +5,7 @@
#include <linux/bitfield.h>
#include <linux/kvm_host.h>
#include <asm/kvm_emulate.h>
+#include <asm/kvm_pgtable.h>
static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
{
@@ -32,7 +33,7 @@ static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
{
- u64 cpacr_el1 = 0;
+ u64 cpacr_el1 = CPACR_ELx_RES1;
if (cptr_el2 & CPTR_EL2_TTA)
cpacr_el1 |= CPACR_ELx_TTA;
@@ -41,6 +42,8 @@ static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
if (!(cptr_el2 & CPTR_EL2_TZ))
cpacr_el1 |= CPACR_ELx_ZEN;
+ cpacr_el1 |= cptr_el2 & (CPTR_EL2_TCPAC | CPTR_EL2_TAM);
+
return cpacr_el1;
}
@@ -60,7 +63,146 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
return ttbr0 & ~GENMASK_ULL(63, 48);
}
+extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
+extern void kvm_init_nested(struct kvm *kvm);
+extern int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu);
+extern void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu);
+extern struct kvm_s2_mmu *lookup_s2_mmu(struct kvm_vcpu *vcpu);
+
+union tlbi_info;
+
+extern void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid,
+ const union tlbi_info *info,
+ void (*)(struct kvm_s2_mmu *,
+ const union tlbi_info *));
+extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
+extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
+
+struct kvm_s2_trans {
+ phys_addr_t output;
+ unsigned long block_size;
+ bool writable;
+ bool readable;
+ int level;
+ u32 esr;
+ u64 upper_attr;
+};
+
+static inline phys_addr_t kvm_s2_trans_output(struct kvm_s2_trans *trans)
+{
+ return trans->output;
+}
+
+static inline unsigned long kvm_s2_trans_size(struct kvm_s2_trans *trans)
+{
+ return trans->block_size;
+}
+
+static inline u32 kvm_s2_trans_esr(struct kvm_s2_trans *trans)
+{
+ return trans->esr;
+}
+
+static inline bool kvm_s2_trans_readable(struct kvm_s2_trans *trans)
+{
+ return trans->readable;
+}
+
+static inline bool kvm_s2_trans_writable(struct kvm_s2_trans *trans)
+{
+ return trans->writable;
+}
+
+static inline bool kvm_s2_trans_executable(struct kvm_s2_trans *trans)
+{
+ return !(trans->upper_attr & BIT(54));
+}
+
+extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+ struct kvm_s2_trans *result);
+extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
+ struct kvm_s2_trans *trans);
+extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2);
+extern void kvm_nested_s2_wp(struct kvm *kvm);
+extern void kvm_nested_s2_unmap(struct kvm *kvm);
+extern void kvm_nested_s2_flush(struct kvm *kvm);
+
+unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val);
+
+static inline bool kvm_supported_tlbi_s1e1_op(struct kvm_vcpu *vpcu, u32 instr)
+{
+ struct kvm *kvm = vpcu->kvm;
+ u8 CRm = sys_reg_CRm(instr);
+
+ if (!(sys_reg_Op0(instr) == TLBI_Op0 &&
+ sys_reg_Op1(instr) == TLBI_Op1_EL1))
+ return false;
+
+ if (!(sys_reg_CRn(instr) == TLBI_CRn_XS ||
+ (sys_reg_CRn(instr) == TLBI_CRn_nXS &&
+ kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))))
+ return false;
+
+ if (CRm == TLBI_CRm_nROS &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ return false;
+
+ if ((CRm == TLBI_CRm_RIS || CRm == TLBI_CRm_ROS ||
+ CRm == TLBI_CRm_RNS) &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+ return false;
+
+ return true;
+}
+
+static inline bool kvm_supported_tlbi_s1e2_op(struct kvm_vcpu *vpcu, u32 instr)
+{
+ struct kvm *kvm = vpcu->kvm;
+ u8 CRm = sys_reg_CRm(instr);
+
+ if (!(sys_reg_Op0(instr) == TLBI_Op0 &&
+ sys_reg_Op1(instr) == TLBI_Op1_EL2))
+ return false;
+
+ if (!(sys_reg_CRn(instr) == TLBI_CRn_XS ||
+ (sys_reg_CRn(instr) == TLBI_CRn_nXS &&
+ kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))))
+ return false;
+
+ if (CRm == TLBI_CRm_IPAIS || CRm == TLBI_CRm_IPAONS)
+ return false;
+
+ if (CRm == TLBI_CRm_nROS &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ return false;
+
+ if ((CRm == TLBI_CRm_RIS || CRm == TLBI_CRm_ROS ||
+ CRm == TLBI_CRm_RNS) &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+ return false;
+
+ return true;
+}
int kvm_init_nv_sysregs(struct kvm *kvm);
+#ifdef CONFIG_ARM64_PTR_AUTH
+bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr);
+#else
+static inline bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
+{
+ /* We really should never execute this... */
+ WARN_ON_ONCE(1);
+ *elr = 0xbad9acc0debadbad;
+ return false;
+}
+#endif
+
+#define KVM_NV_GUEST_MAP_SZ (KVM_PGTABLE_PROT_SW1 | KVM_PGTABLE_PROT_SW0)
+
+static inline u64 kvm_encode_nested_level(struct kvm_s2_trans *trans)
+{
+ return FIELD_PREP(KVM_NV_GUEST_MAP_SZ, trans->level);
+}
+
#endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index ad9cfb5c1ff4..cd56acd9a842 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -128,4 +128,13 @@ static inline unsigned long hyp_ffa_proxy_pages(void)
return (2 * KVM_FFA_MBOX_NR_PAGES) + DIV_ROUND_UP(desc_max, PAGE_SIZE);
}
+static inline size_t pkvm_host_sve_state_size(void)
+{
+ if (!system_supports_sve())
+ return 0;
+
+ return size_add(sizeof(struct cpu_sve_state),
+ SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
+}
+
#endif /* __ARM64_KVM_PKVM_H__ */
diff --git a/arch/arm64/include/asm/kvm_ptrauth.h b/arch/arm64/include/asm/kvm_ptrauth.h
index 0cd0965255d2..d81bac256abc 100644
--- a/arch/arm64/include/asm/kvm_ptrauth.h
+++ b/arch/arm64/include/asm/kvm_ptrauth.h
@@ -99,5 +99,26 @@ alternative_else_nop_endif
.macro ptrauth_switch_to_hyp g_ctxt, h_ctxt, reg1, reg2, reg3
.endm
#endif /* CONFIG_ARM64_PTR_AUTH */
+
+#else /* !__ASSEMBLY */
+
+#define __ptrauth_save_key(ctxt, key) \
+ do { \
+ u64 __val; \
+ __val = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \
+ ctxt_sys_reg(ctxt, key ## KEYLO_EL1) = __val; \
+ __val = read_sysreg_s(SYS_ ## key ## KEYHI_EL1); \
+ ctxt_sys_reg(ctxt, key ## KEYHI_EL1) = __val; \
+ } while(0)
+
+#define ptrauth_save_keys(ctxt) \
+ do { \
+ __ptrauth_save_key(ctxt, APIA); \
+ __ptrauth_save_key(ctxt, APIB); \
+ __ptrauth_save_key(ctxt, APDA); \
+ __ptrauth_save_key(ctxt, APDB); \
+ __ptrauth_save_key(ctxt, APGA); \
+ } while(0)
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_KVM_PTRAUTH_H */
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index c768d16b81a4..bd19f4c758b7 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -72,11 +72,11 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
{
unsigned long tcr = read_sysreg(tcr_el1);
- if ((tcr & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET == t0sz)
+ if ((tcr & TCR_T0SZ_MASK) == t0sz)
return;
tcr &= ~TCR_T0SZ_MASK;
- tcr |= t0sz << TCR_T0SZ_OFFSET;
+ tcr |= t0sz;
write_sysreg(tcr, tcr_el1);
isb();
}
diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
index 91fbd5c8a391..0f84518632b4 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -182,7 +182,7 @@ void mte_check_tfsr_el1(void);
static inline void mte_check_tfsr_entry(void)
{
- if (!system_supports_mte())
+ if (!kasan_hw_tags_enabled())
return;
mte_check_tfsr_el1();
@@ -190,7 +190,7 @@ static inline void mte_check_tfsr_entry(void)
static inline void mte_check_tfsr_exit(void)
{
- if (!system_supports_mte())
+ if (!kasan_hw_tags_enabled())
return;
/*
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index ef207a0d4f0d..1f60aa1bc750 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -170,6 +170,7 @@
#define PTE_CONT (_AT(pteval_t, 1) << 52) /* Contiguous range */
#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */
#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */
+#define PTE_SWBITS_MASK _AT(pteval_t, (BIT(63) | GENMASK(58, 55)))
#define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (50 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
#ifdef CONFIG_ARM64_PA_BITS_52
@@ -297,6 +298,7 @@
#define TCR_TBI1 (UL(1) << 38)
#define TCR_HA (UL(1) << 39)
#define TCR_HD (UL(1) << 40)
+#define TCR_TBID0 (UL(1) << 51)
#define TCR_TBID1 (UL(1) << 52)
#define TCR_NFD0 (UL(1) << 53)
#define TCR_NFD1 (UL(1) << 54)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index dd9ee67d1d87..b11cfb9fdd37 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -18,14 +18,21 @@
#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
#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.
+ * PTE_PRESENT_INVALID=1 & PTE_VALID=0 indicates that the pte's fields should be
+ * interpreted according to the HW layout by SW but any attempted HW access to
+ * the address will result in a fault. pte_present() returns true.
*/
-#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */
+#define PTE_PRESENT_INVALID (PTE_NG) /* only when !PTE_VALID */
+
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+#define PTE_UFFD_WP (_AT(pteval_t, 1) << 58) /* uffd-wp tracking */
+#define PTE_SWP_UFFD_WP (_AT(pteval_t, 1) << 3) /* only for swp ptes */
+#else
+#define PTE_UFFD_WP (_AT(pteval_t, 0))
+#define PTE_SWP_UFFD_WP (_AT(pteval_t, 0))
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
@@ -103,7 +110,7 @@ static inline bool __pure lpa2_is_enabled(void)
__val; \
})
-#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PRESENT_INVALID | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
/* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */
#define PAGE_SHARED __pgprot(_PAGE_SHARED)
#define PAGE_SHARED_EXEC __pgprot(_PAGE_SHARED_EXEC)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index afdd56d26ad7..7a4f5604be3f 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -49,12 +49,6 @@
__flush_tlb_range(vma, addr, end, PUD_SIZE, false, 1)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-static inline bool arch_thp_swp_supported(void)
-{
- return !system_supports_mte();
-}
-#define arch_thp_swp_supported arch_thp_swp_supported
-
/*
* Outside of a few very special situations (e.g. hibernation), we always
* use broadcast TLB invalidation instructions, therefore a spurious page
@@ -105,7 +99,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
/*
* The following only work if pte_present(). Undefined behaviour otherwise.
*/
-#define pte_present(pte) (!!(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)))
+#define pte_present(pte) (pte_valid(pte) || pte_present_invalid(pte))
#define pte_young(pte) (!!(pte_val(pte) & PTE_AF))
#define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL))
#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
@@ -132,6 +126,8 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
#define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte))
#define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID))
+#define pte_present_invalid(pte) \
+ ((pte_val(pte) & (PTE_VALID | PTE_PRESENT_INVALID)) == PTE_PRESENT_INVALID)
/*
* Execute-only user mappings do not have the PTE_USER bit set. All valid
* kernel mappings have the PTE_UXN bit set.
@@ -261,6 +257,13 @@ static inline pte_t pte_mkpresent(pte_t pte)
return set_pte_bit(pte, __pgprot(PTE_VALID));
}
+static inline pte_t pte_mkinvalid(pte_t pte)
+{
+ pte = set_pte_bit(pte, __pgprot(PTE_PRESENT_INVALID));
+ pte = clear_pte_bit(pte, __pgprot(PTE_VALID));
+ return pte;
+}
+
static inline pmd_t pmd_mkcont(pmd_t pmd)
{
return __pmd(pmd_val(pmd) | PMD_SECT_CONT);
@@ -271,9 +274,31 @@ static inline pte_t pte_mkdevmap(pte_t pte)
return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
}
-static inline void __set_pte(pte_t *ptep, pte_t pte)
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+static inline int pte_uffd_wp(pte_t pte)
+{
+ return !!(pte_val(pte) & PTE_UFFD_WP);
+}
+
+static inline pte_t pte_mkuffd_wp(pte_t pte)
+{
+ return pte_wrprotect(set_pte_bit(pte, __pgprot(PTE_UFFD_WP)));
+}
+
+static inline pte_t pte_clear_uffd_wp(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(PTE_UFFD_WP));
+}
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
+static inline void __set_pte_nosync(pte_t *ptep, pte_t pte)
{
WRITE_ONCE(*ptep, pte);
+}
+
+static inline void __set_pte(pte_t *ptep, pte_t pte)
+{
+ __set_pte_nosync(ptep, pte);
/*
* Only if the new pte is valid and kernel, otherwise TLB maintenance
@@ -463,13 +488,39 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
return clear_pte_bit(pte, __pgprot(PTE_SWP_EXCLUSIVE));
}
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+static inline pte_t pte_swp_mkuffd_wp(pte_t pte)
+{
+ return set_pte_bit(pte, __pgprot(PTE_SWP_UFFD_WP));
+}
+
+static inline int pte_swp_uffd_wp(pte_t pte)
+{
+ return !!(pte_val(pte) & PTE_SWP_UFFD_WP);
+}
+
+static inline pte_t pte_swp_clear_uffd_wp(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(PTE_SWP_UFFD_WP));
+}
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
#ifdef CONFIG_NUMA_BALANCING
/*
* See the comment in include/linux/pgtable.h
*/
static inline int pte_protnone(pte_t pte)
{
- return (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) == PTE_PROT_NONE;
+ /*
+ * pte_present_invalid() tells us that the pte is invalid from HW
+ * perspective but present from SW perspective, so the fields are to be
+ * interpretted as per the HW layout. The second 2 checks are the unique
+ * encoding that we use for PROT_NONE. It is insufficient to only use
+ * the first check because we share the same encoding scheme with pmds
+ * which support pmd_mkinvalid(), so can be present-invalid without
+ * being PROT_NONE.
+ */
+ return pte_present_invalid(pte) && !pte_user(pte) && !pte_user_exec(pte);
}
static inline int pmd_protnone(pmd_t pmd)
@@ -478,12 +529,7 @@ 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);
-}
+#define pmd_present(pmd) pte_present(pmd_pte(pmd))
/*
* THP definitions.
@@ -508,16 +554,16 @@ static inline int pmd_trans_huge(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)))
-
-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))
+#define pmd_mkinvalid(pmd) pte_pmd(pte_mkinvalid(pmd_pte(pmd)))
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+#define pmd_uffd_wp(pmd) pte_uffd_wp(pmd_pte(pmd))
+#define pmd_mkuffd_wp(pmd) pte_pmd(pte_mkuffd_wp(pmd_pte(pmd)))
+#define pmd_clear_uffd_wp(pmd) pte_pmd(pte_clear_uffd_wp(pmd_pte(pmd)))
+#define pmd_swp_uffd_wp(pmd) pte_swp_uffd_wp(pmd_pte(pmd))
+#define pmd_swp_mkuffd_wp(pmd) pte_pmd(pte_swp_mkuffd_wp(pmd_pte(pmd)))
+#define pmd_swp_clear_uffd_wp(pmd) \
+ pte_pmd(pte_swp_clear_uffd_wp(pmd_pte(pmd)))
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
#define pmd_write(pmd) pte_write(pmd_pte(pmd))
@@ -709,7 +755,11 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
#define pud_none(pud) (!pud_val(pud))
#define pud_bad(pud) (!pud_table(pud))
#define pud_present(pud) pte_present(pud_pte(pud))
+#ifndef __PAGETABLE_PMD_FOLDED
#define pud_leaf(pud) (pud_present(pud) && !pud_table(pud))
+#else
+#define pud_leaf(pud) false
+#endif
#define pud_valid(pud) pte_valid(pud_pte(pud))
#define pud_user(pud) pte_user(pud_pte(pud))
#define pud_user_exec(pud) pte_user_exec(pud_pte(pud))
@@ -760,6 +810,7 @@ static inline pmd_t *pud_pgtable(pud_t pud)
#else
+#define pud_valid(pud) false
#define pud_page_paddr(pud) ({ BUILD_BUG(); 0; })
#define pud_user_exec(pud) pud_user(pud) /* Always 0 with folding */
@@ -1005,6 +1056,8 @@ static inline p4d_t *p4d_offset_kimg(pgd_t *pgdp, u64 addr)
static inline bool pgtable_l5_enabled(void) { return false; }
+#define p4d_index(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
+
/* Match p4d_offset folding in <asm/generic/pgtable-nop4d.h> */
#define p4d_set_fixmap(addr) NULL
#define p4d_set_fixmap_offset(p4dp, addr) ((p4d_t *)p4dp)
@@ -1012,6 +1065,28 @@ static inline bool pgtable_l5_enabled(void) { return false; }
#define p4d_offset_kimg(dir,addr) ((p4d_t *)dir)
+static inline
+p4d_t *p4d_offset_lockless_folded(pgd_t *pgdp, pgd_t pgd, unsigned long addr)
+{
+ /*
+ * With runtime folding of the pud, pud_offset_lockless() passes
+ * the 'pgd_t *' we return here to p4d_to_folded_pud(), which
+ * will offset the pointer assuming that it points into
+ * a page-table page. However, the fast GUP path passes us a
+ * pgd_t allocated on the stack and so we must use the original
+ * pointer in 'pgdp' to construct the p4d pointer instead of
+ * using the generic p4d_offset_lockless() implementation.
+ *
+ * Note: reusing the original pointer means that we may
+ * dereference the same (live) page-table entry multiple times.
+ * This is safe because it is still only loaded once in the
+ * context of each level and the CPU guarantees same-address
+ * read-after-read ordering.
+ */
+ return p4d_offset(pgdp, addr);
+}
+#define p4d_offset_lockless p4d_offset_lockless_folded
+
#endif /* CONFIG_PGTABLE_LEVELS > 4 */
#define pgd_ERROR(e) \
@@ -1027,8 +1102,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
* 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_ATTRINDX_MASK;
+ PTE_PRESENT_INVALID | PTE_VALID | PTE_WRITE |
+ PTE_GP | PTE_ATTRINDX_MASK;
/* preserve the hardware dirty information */
if (pte_hw_dirty(pte))
pte = set_pte_bit(pte, __pgprot(PTE_DIRTY));
@@ -1076,17 +1151,17 @@ static inline int pgd_devmap(pgd_t pgd)
#ifdef CONFIG_PAGE_TABLE_CHECK
static inline bool pte_user_accessible_page(pte_t pte)
{
- return pte_present(pte) && (pte_user(pte) || pte_user_exec(pte));
+ return pte_valid(pte) && (pte_user(pte) || pte_user_exec(pte));
}
static inline bool pmd_user_accessible_page(pmd_t pmd)
{
- return pmd_leaf(pmd) && !pmd_present_invalid(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+ return pmd_valid(pmd) && !pmd_table(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
}
static inline bool pud_user_accessible_page(pud_t pud)
{
- return pud_leaf(pud) && (pud_user(pud) || pud_user_exec(pud));
+ return pud_valid(pud) && !pud_table(pud) && (pud_user(pud) || pud_user_exec(pud));
}
#endif
@@ -1227,6 +1302,46 @@ static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
__ptep_set_wrprotect(mm, address, ptep);
}
+static inline void __clear_young_dirty_pte(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, cydp_t flags)
+{
+ pte_t old_pte;
+
+ do {
+ old_pte = pte;
+
+ if (flags & CYDP_CLEAR_YOUNG)
+ pte = pte_mkold(pte);
+ if (flags & CYDP_CLEAR_DIRTY)
+ pte = pte_mkclean(pte);
+
+ pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
+ pte_val(old_pte), pte_val(pte));
+ } while (pte_val(pte) != pte_val(old_pte));
+}
+
+static inline void __clear_young_dirty_ptes(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, cydp_t flags)
+{
+ pte_t pte;
+
+ for (;;) {
+ pte = __ptep_get(ptep);
+
+ if (flags == (CYDP_CLEAR_YOUNG | CYDP_CLEAR_DIRTY))
+ __set_pte(ptep, pte_mkclean(pte_mkold(pte)));
+ else
+ __clear_young_dirty_pte(vma, addr, ptep, pte, flags);
+
+ if (--nr == 0)
+ break;
+ ptep++;
+ addr += PAGE_SIZE;
+ }
+}
+
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
static inline void pmdp_set_wrprotect(struct mm_struct *mm,
@@ -1248,15 +1363,16 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
* Encode and decode a swap entry:
* bits 0-1: present (must be zero)
* bits 2: remember PG_anon_exclusive
- * bits 3-7: swap type
- * bits 8-57: swap offset
- * bit 58: PTE_PROT_NONE (must be zero)
+ * bit 3: remember uffd-wp state
+ * bits 6-10: swap type
+ * bit 11: PTE_PRESENT_INVALID (must be zero)
+ * bits 12-61: swap offset
*/
-#define __SWP_TYPE_SHIFT 3
+#define __SWP_TYPE_SHIFT 6
#define __SWP_TYPE_BITS 5
-#define __SWP_OFFSET_BITS 50
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
-#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+#define __SWP_OFFSET_SHIFT 12
+#define __SWP_OFFSET_BITS 50
#define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1)
#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
@@ -1280,12 +1396,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
#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;
-}
+extern int arch_prepare_to_swap(struct folio *folio);
#define __HAVE_ARCH_SWAP_INVALIDATE
static inline void arch_swap_invalidate_page(int type, pgoff_t offset)
@@ -1301,11 +1412,7 @@ static inline void arch_swap_invalidate_area(int type)
}
#define __HAVE_ARCH_SWAP_RESTORE
-static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
-{
- if (system_supports_mte())
- mte_restore_tags(entry, &folio->page);
-}
+extern void arch_swap_restore(swp_entry_t entry, struct folio *folio);
#endif /* CONFIG_ARM64_MTE */
@@ -1392,6 +1499,9 @@ extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t entry, int dirty);
+extern void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, cydp_t flags);
static __always_inline void contpte_try_fold(struct mm_struct *mm,
unsigned long addr, pte_t *ptep, pte_t pte)
@@ -1616,6 +1726,17 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
}
+#define clear_young_dirty_ptes clear_young_dirty_ptes
+static inline void clear_young_dirty_ptes(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, cydp_t flags)
+{
+ if (likely(nr == 1 && !pte_cont(__ptep_get(ptep))))
+ __clear_young_dirty_ptes(vma, addr, ptep, nr, flags);
+ else
+ contpte_clear_young_dirty_ptes(vma, addr, ptep, nr, flags);
+}
+
#else /* CONFIG_ARM64_CONTPTE */
#define ptep_get __ptep_get
@@ -1635,6 +1756,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
#define wrprotect_ptes __wrprotect_ptes
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
#define ptep_set_access_flags __ptep_set_access_flags
+#define clear_young_dirty_ptes __clear_young_dirty_ptes
#endif /* CONFIG_ARM64_CONTPTE */
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 47ec58031f11..0abe975d68a8 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -21,35 +21,12 @@
#define INIT_PSTATE_EL2 \
(PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL2h)
-/*
- * PMR values used to mask/unmask interrupts.
- *
- * GIC priority masking works as follows: if an IRQ's priority is a higher value
- * than the value held in PMR, that IRQ is masked. Lowering the value of PMR
- * means masking more IRQs (or at least that the same IRQs remain masked).
- *
- * To mask interrupts, we clear the most significant bit of PMR.
- *
- * Some code sections either automatically switch back to PSR.I or explicitly
- * require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included
- * in the priority mask, it indicates that PSR.I should be set and
- * 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_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; \
- })
+#include <linux/irqchip/arm-gic-v3-prio.h>
+
+#define GIC_PRIO_IRQON GICV3_PRIO_UNMASKED
+#define GIC_PRIO_IRQOFF GICV3_PRIO_IRQ
+
+#define GIC_PRIO_PSR_I_SET GICV3_PRIO_PSR_I_SET
/* Additional SPSR bits not exposed in the UABI */
#define PSR_MODE_THREAD_BIT (1 << 0)
diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
new file mode 100644
index 000000000000..be5915669d23
--- /dev/null
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RUNTIME_CONST_H
+#define _ASM_RUNTIME_CONST_H
+
+#include <asm/cacheflush.h>
+
+/* Sigh. You can still run arm64 in BE mode */
+#include <asm/byteorder.h>
+
+#define runtime_const_ptr(sym) ({ \
+ typeof(sym) __ret; \
+ asm_inline("1:\t" \
+ "movz %0, #0xcdef\n\t" \
+ "movk %0, #0x89ab, lsl #16\n\t" \
+ "movk %0, #0x4567, lsl #32\n\t" \
+ "movk %0, #0x0123, lsl #48\n\t" \
+ ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \
+ ".long 1b - .\n\t" \
+ ".popsection" \
+ :"=r" (__ret)); \
+ __ret; })
+
+#define runtime_const_shift_right_32(val, sym) ({ \
+ unsigned long __ret; \
+ asm_inline("1:\t" \
+ "lsr %w0,%w1,#12\n\t" \
+ ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \
+ ".long 1b - .\n\t" \
+ ".popsection" \
+ :"=r" (__ret) \
+ :"r" (0u+(val))); \
+ __ret; })
+
+#define runtime_const_init(type, sym) do { \
+ extern s32 __start_runtime_##type##_##sym[]; \
+ extern s32 __stop_runtime_##type##_##sym[]; \
+ runtime_const_fixup(__runtime_fixup_##type, \
+ (unsigned long)(sym), \
+ __start_runtime_##type##_##sym, \
+ __stop_runtime_##type##_##sym); \
+} while (0)
+
+/* 16-bit immediate for wide move (movz and movk) in bits 5..20 */
+static inline void __runtime_fixup_16(__le32 *p, unsigned int val)
+{
+ u32 insn = le32_to_cpu(*p);
+ insn &= 0xffe0001f;
+ insn |= (val & 0xffff) << 5;
+ *p = cpu_to_le32(insn);
+}
+
+static inline void __runtime_fixup_caches(void *where, unsigned int insns)
+{
+ unsigned long va = (unsigned long)where;
+ caches_clean_inval_pou(va, va + 4*insns);
+}
+
+static inline void __runtime_fixup_ptr(void *where, unsigned long val)
+{
+ __le32 *p = lm_alias(where);
+ __runtime_fixup_16(p, val);
+ __runtime_fixup_16(p+1, val >> 16);
+ __runtime_fixup_16(p+2, val >> 32);
+ __runtime_fixup_16(p+3, val >> 48);
+ __runtime_fixup_caches(where, 4);
+}
+
+/* Immediate value is 6 bits starting at bit #16 */
+static inline void __runtime_fixup_shift(void *where, unsigned long val)
+{
+ __le32 *p = lm_alias(where);
+ u32 insn = le32_to_cpu(*p);
+ insn &= 0xffc0ffff;
+ insn |= (val & 63) << 16;
+ *p = cpu_to_le32(insn);
+ __runtime_fixup_caches(where, 1);
+}
+
+static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
+ unsigned long val, s32 *start, s32 *end)
+{
+ while (start < end) {
+ fn(*start + (void *)start, val);
+ start++;
+ }
+}
+
+#endif
diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h
index 30256233788b..b83975555314 100644
--- a/arch/arm64/include/asm/seccomp.h
+++ b/arch/arm64/include/asm/seccomp.h
@@ -8,13 +8,13 @@
#ifndef _ASM_SECCOMP_H
#define _ASM_SECCOMP_H
-#include <asm/unistd.h>
+#include <asm/unistd_compat_32.h>
#ifdef CONFIG_COMPAT
-#define __NR_seccomp_read_32 __NR_compat_read
-#define __NR_seccomp_write_32 __NR_compat_write
-#define __NR_seccomp_exit_32 __NR_compat_exit
-#define __NR_seccomp_sigreturn_32 __NR_compat_rt_sigreturn
+#define __NR_seccomp_read_32 __NR_compat32_read
+#define __NR_seccomp_write_32 __NR_compat32_write
+#define __NR_seccomp_exit_32 __NR_compat32_exit
+#define __NR_seccomp_sigreturn_32 __NR_compat32_rt_sigreturn
#endif /* CONFIG_COMPAT */
#include <asm-generic/seccomp.h>
@@ -23,8 +23,9 @@
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "aarch64"
#ifdef CONFIG_COMPAT
+#include <asm/unistd_compat_32.h>
# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_ARM
-# define SECCOMP_ARCH_COMPAT_NR __NR_compat_syscalls
+# define SECCOMP_ARCH_COMPAT_NR __NR_compat32_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "arm"
#endif
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index efb13112b408..2510eec026f7 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -25,22 +25,11 @@
#ifndef __ASSEMBLY__
-#include <asm/percpu.h>
-
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <linux/thread_info.h>
-DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
-
-/*
- * We don't use this_cpu_read(cpu_number) as that has implicit writes to
- * preempt_count, and associated (compiler) barriers, that we'd like to avoid
- * the expense of. If we're preemptible, the value can be stale at use anyway.
- * And we can't use this_cpu_ptr() either, as that winds up recursing back
- * here under CONFIG_DEBUG_PREEMPT=y.
- */
-#define raw_smp_processor_id() (*raw_cpu_ptr(&cpu_number))
+#define raw_smp_processor_id() (current_thread_info()->cpu)
/*
* Logical CPU mapping.
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 9e8999592f3a..4a9ea103817e 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -654,6 +654,23 @@
#define OP_AT_S12E0W sys_insn(AT_Op0, 4, AT_CRn, 8, 7)
/* TLBI instructions */
+#define TLBI_Op0 1
+
+#define TLBI_Op1_EL1 0 /* Accessible from EL1 or higher */
+#define TLBI_Op1_EL2 4 /* Accessible from EL2 or higher */
+
+#define TLBI_CRn_XS 8 /* Extra Slow (the common one) */
+#define TLBI_CRn_nXS 9 /* not Extra Slow (which nobody uses)*/
+
+#define TLBI_CRm_IPAIS 0 /* S2 Inner-Shareable */
+#define TLBI_CRm_nROS 1 /* non-Range, Outer-Sharable */
+#define TLBI_CRm_RIS 2 /* Range, Inner-Sharable */
+#define TLBI_CRm_nRIS 3 /* non-Range, Inner-Sharable */
+#define TLBI_CRm_IPAONS 4 /* S2 Outer and Non-Shareable */
+#define TLBI_CRm_ROS 5 /* Range, Outer-Sharable */
+#define TLBI_CRm_RNS 6 /* Range, Non-Sharable */
+#define TLBI_CRm_nRNS 7 /* non-Range, Non-Sharable */
+
#define OP_TLBI_VMALLE1OS sys_insn(1, 0, 8, 1, 0)
#define OP_TLBI_VAE1OS sys_insn(1, 0, 8, 1, 1)
#define OP_TLBI_ASIDE1OS sys_insn(1, 0, 8, 1, 2)
@@ -872,10 +889,6 @@
/* Position the attr at the correct index */
#define MAIR_ATTRIDX(attr, idx) ((attr) << ((idx) * 8))
-/* id_aa64pfr0 */
-#define ID_AA64PFR0_EL1_ELx_64BIT_ONLY 0x1
-#define ID_AA64PFR0_EL1_ELx_32BIT_64BIT 0x2
-
/* id_aa64mmfr0 */
#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN 0x0
#define ID_AA64MMFR0_EL1_TGRAN4_LPA2 ID_AA64MMFR0_EL1_TGRAN4_52_BIT
@@ -1036,18 +1049,18 @@
* Permission Indirection Extension (PIE) permission encodings.
* Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
*/
-#define PIE_NONE_O 0x0
-#define PIE_R_O 0x1
-#define PIE_X_O 0x2
-#define PIE_RX_O 0x3
-#define PIE_RW_O 0x5
-#define PIE_RWnX_O 0x6
-#define PIE_RWX_O 0x7
-#define PIE_R 0x8
-#define PIE_GCS 0x9
-#define PIE_RX 0xa
-#define PIE_RW 0xc
-#define PIE_RWX 0xe
+#define PIE_NONE_O UL(0x0)
+#define PIE_R_O UL(0x1)
+#define PIE_X_O UL(0x2)
+#define PIE_RX_O UL(0x3)
+#define PIE_RW_O UL(0x5)
+#define PIE_RWnX_O UL(0x6)
+#define PIE_RWX_O UL(0x7)
+#define PIE_R UL(0x8)
+#define PIE_GCS UL(0x9)
+#define PIE_RX UL(0xa)
+#define PIE_RW UL(0xc)
+#define PIE_RWX UL(0xe)
#define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4))
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index a75de2665d84..95fbc8c05607 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -142,17 +142,24 @@ static inline unsigned long get_trans_granule(void)
* EL1, Inner Shareable".
*
*/
-#define __TLBI_VADDR_RANGE(baddr, asid, scale, num, ttl) \
- ({ \
- unsigned long __ta = (baddr); \
- unsigned long __ttl = (ttl >= 1 && ttl <= 3) ? ttl : 0; \
- __ta &= GENMASK_ULL(36, 0); \
- __ta |= __ttl << 37; \
- __ta |= (unsigned long)(num) << 39; \
- __ta |= (unsigned long)(scale) << 44; \
- __ta |= get_trans_granule() << 46; \
- __ta |= (unsigned long)(asid) << 48; \
- __ta; \
+#define TLBIR_ASID_MASK GENMASK_ULL(63, 48)
+#define TLBIR_TG_MASK GENMASK_ULL(47, 46)
+#define TLBIR_SCALE_MASK GENMASK_ULL(45, 44)
+#define TLBIR_NUM_MASK GENMASK_ULL(43, 39)
+#define TLBIR_TTL_MASK GENMASK_ULL(38, 37)
+#define TLBIR_BADDR_MASK GENMASK_ULL(36, 0)
+
+#define __TLBI_VADDR_RANGE(baddr, asid, scale, num, ttl) \
+ ({ \
+ unsigned long __ta = 0; \
+ unsigned long __ttl = (ttl >= 1 && ttl <= 3) ? ttl : 0; \
+ __ta |= FIELD_PREP(TLBIR_BADDR_MASK, baddr); \
+ __ta |= FIELD_PREP(TLBIR_TTL_MASK, __ttl); \
+ __ta |= FIELD_PREP(TLBIR_NUM_MASK, num); \
+ __ta |= FIELD_PREP(TLBIR_SCALE_MASK, scale); \
+ __ta |= FIELD_PREP(TLBIR_TG_MASK, get_trans_granule()); \
+ __ta |= FIELD_PREP(TLBIR_ASID_MASK, asid); \
+ __ta; \
})
/* These macros are used by the TLBI RANGE feature. */
@@ -439,11 +446,11 @@ static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
* When not uses TLB range ops, we can handle up to
* (MAX_DVM_OPS - 1) pages;
* When uses TLB range ops, we can handle up to
- * (MAX_TLBI_RANGE_PAGES - 1) pages.
+ * MAX_TLBI_RANGE_PAGES pages.
*/
if ((!system_supports_tlb_range() &&
(end - start) >= (MAX_DVM_OPS * stride)) ||
- pages >= MAX_TLBI_RANGE_PAGES) {
+ pages > MAX_TLBI_RANGE_PAGES) {
flush_tlb_mm(vma->vm_mm);
return;
}
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index a323b109b9c4..0f6ef432fb84 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -35,9 +35,9 @@ void update_freq_counters_refs(void);
/* Enable topology flag updates */
#define arch_update_cpu_topology topology_update_cpu_topology
-/* Replace task scheduler's default thermal pressure API */
-#define arch_scale_thermal_pressure topology_get_thermal_pressure
-#define arch_update_thermal_pressure topology_update_thermal_pressure
+/* Replace task scheduler's default HW pressure API */
+#define arch_scale_hw_pressure topology_get_hw_pressure
+#define arch_update_hw_pressure topology_update_hw_pressure
#include <asm-generic/topology.h>
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 14be5000c5a0..28f665e0975a 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -184,29 +184,40 @@ static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
* The "__xxx_error" versions set the third argument to -EFAULT if an error
* occurs, and leave it unchanged on success.
*/
-#define __get_mem_asm(load, reg, x, addr, err, type) \
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+#define __get_mem_asm(load, reg, x, addr, label, type) \
+ asm_goto_output( \
+ "1: " load " " reg "0, [%1]\n" \
+ _ASM_EXTABLE_##type##ACCESS_ERR(1b, %l2, %w0) \
+ : "=r" (x) \
+ : "r" (addr) : : label)
+#else
+#define __get_mem_asm(load, reg, x, addr, label, type) do { \
+ int __gma_err = 0; \
asm volatile( \
"1: " load " " reg "1, [%2]\n" \
"2:\n" \
_ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 2b, %w0, %w1) \
- : "+r" (err), "=r" (x) \
- : "r" (addr))
+ : "+r" (__gma_err), "=r" (x) \
+ : "r" (addr)); \
+ if (__gma_err) goto label; } while (0)
+#endif
-#define __raw_get_mem(ldr, x, ptr, err, type) \
+#define __raw_get_mem(ldr, x, ptr, label, type) \
do { \
unsigned long __gu_val; \
switch (sizeof(*(ptr))) { \
case 1: \
- __get_mem_asm(ldr "b", "%w", __gu_val, (ptr), (err), type); \
+ __get_mem_asm(ldr "b", "%w", __gu_val, (ptr), label, type); \
break; \
case 2: \
- __get_mem_asm(ldr "h", "%w", __gu_val, (ptr), (err), type); \
+ __get_mem_asm(ldr "h", "%w", __gu_val, (ptr), label, type); \
break; \
case 4: \
- __get_mem_asm(ldr, "%w", __gu_val, (ptr), (err), type); \
+ __get_mem_asm(ldr, "%w", __gu_val, (ptr), label, type); \
break; \
case 8: \
- __get_mem_asm(ldr, "%x", __gu_val, (ptr), (err), type); \
+ __get_mem_asm(ldr, "%x", __gu_val, (ptr), label, type); \
break; \
default: \
BUILD_BUG(); \
@@ -219,27 +230,34 @@ do { \
* uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions,
* we must evaluate these outside of the critical section.
*/
-#define __raw_get_user(x, ptr, err) \
+#define __raw_get_user(x, ptr, label) \
do { \
__typeof__(*(ptr)) __user *__rgu_ptr = (ptr); \
__typeof__(x) __rgu_val; \
__chk_user_ptr(ptr); \
- \
- uaccess_ttbr0_enable(); \
- __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, err, U); \
- uaccess_ttbr0_disable(); \
- \
- (x) = __rgu_val; \
+ do { \
+ __label__ __rgu_failed; \
+ uaccess_ttbr0_enable(); \
+ __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, __rgu_failed, U); \
+ uaccess_ttbr0_disable(); \
+ (x) = __rgu_val; \
+ break; \
+ __rgu_failed: \
+ uaccess_ttbr0_disable(); \
+ goto label; \
+ } while (0); \
} while (0)
#define __get_user_error(x, ptr, err) \
do { \
+ __label__ __gu_failed; \
__typeof__(*(ptr)) __user *__p = (ptr); \
might_fault(); \
if (access_ok(__p, sizeof(*__p))) { \
__p = uaccess_mask_ptr(__p); \
- __raw_get_user((x), __p, (err)); \
+ __raw_get_user((x), __p, __gu_failed); \
} else { \
+ __gu_failed: \
(x) = (__force __typeof__(x))0; (err) = -EFAULT; \
} \
} while (0)
@@ -262,40 +280,42 @@ do { \
do { \
__typeof__(dst) __gkn_dst = (dst); \
__typeof__(src) __gkn_src = (src); \
- int __gkn_err = 0; \
- \
- __mte_enable_tco_async(); \
- __raw_get_mem("ldr", *((type *)(__gkn_dst)), \
- (__force type *)(__gkn_src), __gkn_err, K); \
- __mte_disable_tco_async(); \
+ do { \
+ __label__ __gkn_label; \
\
- if (unlikely(__gkn_err)) \
+ __mte_enable_tco_async(); \
+ __raw_get_mem("ldr", *((type *)(__gkn_dst)), \
+ (__force type *)(__gkn_src), __gkn_label, K); \
+ __mte_disable_tco_async(); \
+ break; \
+ __gkn_label: \
+ __mte_disable_tco_async(); \
goto err_label; \
+ } while (0); \
} while (0)
-#define __put_mem_asm(store, reg, x, addr, err, type) \
- asm volatile( \
- "1: " store " " reg "1, [%2]\n" \
+#define __put_mem_asm(store, reg, x, addr, label, type) \
+ asm goto( \
+ "1: " store " " reg "0, [%1]\n" \
"2:\n" \
- _ASM_EXTABLE_##type##ACCESS_ERR(1b, 2b, %w0) \
- : "+r" (err) \
- : "rZ" (x), "r" (addr))
+ _ASM_EXTABLE_##type##ACCESS(1b, %l2) \
+ : : "rZ" (x), "r" (addr) : : label)
-#define __raw_put_mem(str, x, ptr, err, type) \
+#define __raw_put_mem(str, x, ptr, label, type) \
do { \
__typeof__(*(ptr)) __pu_val = (x); \
switch (sizeof(*(ptr))) { \
case 1: \
- __put_mem_asm(str "b", "%w", __pu_val, (ptr), (err), type); \
+ __put_mem_asm(str "b", "%w", __pu_val, (ptr), label, type); \
break; \
case 2: \
- __put_mem_asm(str "h", "%w", __pu_val, (ptr), (err), type); \
+ __put_mem_asm(str "h", "%w", __pu_val, (ptr), label, type); \
break; \
case 4: \
- __put_mem_asm(str, "%w", __pu_val, (ptr), (err), type); \
+ __put_mem_asm(str, "%w", __pu_val, (ptr), label, type); \
break; \
case 8: \
- __put_mem_asm(str, "%x", __pu_val, (ptr), (err), type); \
+ __put_mem_asm(str, "%x", __pu_val, (ptr), label, type); \
break; \
default: \
BUILD_BUG(); \
@@ -307,25 +327,34 @@ do { \
* uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions,
* we must evaluate these outside of the critical section.
*/
-#define __raw_put_user(x, ptr, err) \
+#define __raw_put_user(x, ptr, label) \
do { \
+ __label__ __rpu_failed; \
__typeof__(*(ptr)) __user *__rpu_ptr = (ptr); \
__typeof__(*(ptr)) __rpu_val = (x); \
__chk_user_ptr(__rpu_ptr); \
\
- uaccess_ttbr0_enable(); \
- __raw_put_mem("sttr", __rpu_val, __rpu_ptr, err, U); \
- uaccess_ttbr0_disable(); \
+ do { \
+ uaccess_ttbr0_enable(); \
+ __raw_put_mem("sttr", __rpu_val, __rpu_ptr, __rpu_failed, U); \
+ uaccess_ttbr0_disable(); \
+ break; \
+ __rpu_failed: \
+ uaccess_ttbr0_disable(); \
+ goto label; \
+ } while (0); \
} while (0)
#define __put_user_error(x, ptr, err) \
do { \
+ __label__ __pu_failed; \
__typeof__(*(ptr)) __user *__p = (ptr); \
might_fault(); \
if (access_ok(__p, sizeof(*__p))) { \
__p = uaccess_mask_ptr(__p); \
- __raw_put_user((x), __p, (err)); \
+ __raw_put_user((x), __p, __pu_failed); \
} else { \
+ __pu_failed: \
(err) = -EFAULT; \
} \
} while (0)
@@ -348,15 +377,18 @@ do { \
do { \
__typeof__(dst) __pkn_dst = (dst); \
__typeof__(src) __pkn_src = (src); \
- int __pkn_err = 0; \
\
- __mte_enable_tco_async(); \
- __raw_put_mem("str", *((type *)(__pkn_src)), \
- (__force type *)(__pkn_dst), __pkn_err, K); \
- __mte_disable_tco_async(); \
- \
- if (unlikely(__pkn_err)) \
+ do { \
+ __label__ __pkn_err; \
+ __mte_enable_tco_async(); \
+ __raw_put_mem("str", *((type *)(__pkn_src)), \
+ (__force type *)(__pkn_dst), __pkn_err, K); \
+ __mte_disable_tco_async(); \
+ break; \
+ __pkn_err: \
+ __mte_disable_tco_async(); \
goto err_label; \
+ } while (0); \
} while(0)
extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
@@ -381,6 +413,51 @@ extern unsigned long __must_check __arch_copy_to_user(void __user *to, const voi
__actu_ret; \
})
+static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len)
+{
+ if (unlikely(!access_ok(ptr,len)))
+ return 0;
+ uaccess_ttbr0_enable();
+ return 1;
+}
+#define user_access_begin(a,b) user_access_begin(a,b)
+#define user_access_end() uaccess_ttbr0_disable()
+#define unsafe_put_user(x, ptr, label) \
+ __raw_put_mem("sttr", x, uaccess_mask_ptr(ptr), label, U)
+#define unsafe_get_user(x, ptr, label) \
+ __raw_get_mem("ldtr", x, uaccess_mask_ptr(ptr), label, U)
+
+/*
+ * KCSAN uses these to save and restore ttbr state.
+ * We do not support KCSAN with ARM64_SW_TTBR0_PAN, so
+ * they are no-ops.
+ */
+static inline unsigned long user_access_save(void) { return 0; }
+static inline void user_access_restore(unsigned long enabled) { }
+
+/*
+ * We want the unsafe accessors to always be inlined and use
+ * the error labels - thus the macro games.
+ */
+#define unsafe_copy_loop(dst, src, len, type, label) \
+ while (len >= sizeof(type)) { \
+ unsafe_put_user(*(type *)(src),(type __user *)(dst),label); \
+ dst += sizeof(type); \
+ src += sizeof(type); \
+ len -= sizeof(type); \
+ }
+
+#define unsafe_copy_to_user(_dst,_src,_len,label) \
+do { \
+ char __user *__ucu_dst = (_dst); \
+ const char *__ucu_src = (_src); \
+ size_t __ucu_len = (_len); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
+} while (0)
+
#define INLINE_COPY_TO_USER
#define INLINE_COPY_FROM_USER
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 491b2b9bd553..80618c9bbcd8 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -17,35 +17,17 @@
#define __ARCH_WANT_SYS_VFORK
/*
- * Compat syscall numbers used by the AArch64 kernel.
- */
-#define __NR_compat_restart_syscall 0
-#define __NR_compat_exit 1
-#define __NR_compat_read 3
-#define __NR_compat_write 4
-#define __NR_compat_gettimeofday 78
-#define __NR_compat_sigreturn 119
-#define __NR_compat_rt_sigreturn 173
-#define __NR_compat_clock_gettime 263
-#define __NR_compat_clock_getres 264
-#define __NR_compat_clock_gettime64 403
-#define __NR_compat_clock_getres_time64 406
-
-/*
* The following SVCs are ARM private.
*/
#define __ARM_NR_COMPAT_BASE 0x0f0000
#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE + 2)
#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 462
#endif
#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_NEW_STAT
-#ifndef __COMPAT_SYSCALL_NR
-#include <uapi/asm/unistd.h>
-#endif
+#include <asm/unistd_64.h>
#define NR_syscalls (__NR_syscalls)
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 7118282d1c79..e0b1a0b57f75 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -1,936 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * AArch32 (compat) system call definitions.
- *
- * Copyright (C) 2001-2005 Russell King
- * Copyright (C) 2012 ARM Ltd.
- */
+#ifndef _UAPI__ASM_ARM_UNISTD_H
+#define _UAPI__ASM_ARM_UNISTD_H
-#ifndef __SYSCALL
-#define __SYSCALL(x, y)
-#endif
+#include <asm/unistd_32.h>
-#define __NR_restart_syscall 0
-__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
-#define __NR_exit 1
-__SYSCALL(__NR_exit, sys_exit)
-#define __NR_fork 2
-__SYSCALL(__NR_fork, sys_fork)
-#define __NR_read 3
-__SYSCALL(__NR_read, sys_read)
-#define __NR_write 4
-__SYSCALL(__NR_write, sys_write)
-#define __NR_open 5
-__SYSCALL(__NR_open, compat_sys_open)
-#define __NR_close 6
-__SYSCALL(__NR_close, sys_close)
- /* 7 was sys_waitpid */
-__SYSCALL(7, sys_ni_syscall)
-#define __NR_creat 8
-__SYSCALL(__NR_creat, sys_creat)
-#define __NR_link 9
-__SYSCALL(__NR_link, sys_link)
-#define __NR_unlink 10
-__SYSCALL(__NR_unlink, sys_unlink)
-#define __NR_execve 11
-__SYSCALL(__NR_execve, compat_sys_execve)
-#define __NR_chdir 12
-__SYSCALL(__NR_chdir, sys_chdir)
- /* 13 was sys_time */
-__SYSCALL(13, sys_ni_syscall)
-#define __NR_mknod 14
-__SYSCALL(__NR_mknod, sys_mknod)
-#define __NR_chmod 15
-__SYSCALL(__NR_chmod, sys_chmod)
-#define __NR_lchown 16
-__SYSCALL(__NR_lchown, sys_lchown16)
- /* 17 was sys_break */
-__SYSCALL(17, sys_ni_syscall)
- /* 18 was sys_stat */
-__SYSCALL(18, sys_ni_syscall)
-#define __NR_lseek 19
-__SYSCALL(__NR_lseek, compat_sys_lseek)
-#define __NR_getpid 20
-__SYSCALL(__NR_getpid, sys_getpid)
-#define __NR_mount 21
-__SYSCALL(__NR_mount, sys_mount)
- /* 22 was sys_umount */
-__SYSCALL(22, sys_ni_syscall)
-#define __NR_setuid 23
-__SYSCALL(__NR_setuid, sys_setuid16)
-#define __NR_getuid 24
-__SYSCALL(__NR_getuid, sys_getuid16)
- /* 25 was sys_stime */
-__SYSCALL(25, sys_ni_syscall)
-#define __NR_ptrace 26
-__SYSCALL(__NR_ptrace, compat_sys_ptrace)
- /* 27 was sys_alarm */
-__SYSCALL(27, sys_ni_syscall)
- /* 28 was sys_fstat */
-__SYSCALL(28, sys_ni_syscall)
-#define __NR_pause 29
-__SYSCALL(__NR_pause, sys_pause)
- /* 30 was sys_utime */
-__SYSCALL(30, sys_ni_syscall)
- /* 31 was sys_stty */
-__SYSCALL(31, sys_ni_syscall)
- /* 32 was sys_gtty */
-__SYSCALL(32, sys_ni_syscall)
-#define __NR_access 33
-__SYSCALL(__NR_access, sys_access)
-#define __NR_nice 34
-__SYSCALL(__NR_nice, sys_nice)
- /* 35 was sys_ftime */
-__SYSCALL(35, sys_ni_syscall)
-#define __NR_sync 36
-__SYSCALL(__NR_sync, sys_sync)
-#define __NR_kill 37
-__SYSCALL(__NR_kill, sys_kill)
-#define __NR_rename 38
-__SYSCALL(__NR_rename, sys_rename)
-#define __NR_mkdir 39
-__SYSCALL(__NR_mkdir, sys_mkdir)
-#define __NR_rmdir 40
-__SYSCALL(__NR_rmdir, sys_rmdir)
-#define __NR_dup 41
-__SYSCALL(__NR_dup, sys_dup)
-#define __NR_pipe 42
-__SYSCALL(__NR_pipe, sys_pipe)
-#define __NR_times 43
-__SYSCALL(__NR_times, compat_sys_times)
- /* 44 was sys_prof */
-__SYSCALL(44, sys_ni_syscall)
-#define __NR_brk 45
-__SYSCALL(__NR_brk, sys_brk)
-#define __NR_setgid 46
-__SYSCALL(__NR_setgid, sys_setgid16)
-#define __NR_getgid 47
-__SYSCALL(__NR_getgid, sys_getgid16)
- /* 48 was sys_signal */
-__SYSCALL(48, sys_ni_syscall)
-#define __NR_geteuid 49
-__SYSCALL(__NR_geteuid, sys_geteuid16)
-#define __NR_getegid 50
-__SYSCALL(__NR_getegid, sys_getegid16)
-#define __NR_acct 51
-__SYSCALL(__NR_acct, sys_acct)
-#define __NR_umount2 52
-__SYSCALL(__NR_umount2, sys_umount)
- /* 53 was sys_lock */
-__SYSCALL(53, sys_ni_syscall)
-#define __NR_ioctl 54
-__SYSCALL(__NR_ioctl, compat_sys_ioctl)
-#define __NR_fcntl 55
-__SYSCALL(__NR_fcntl, compat_sys_fcntl)
- /* 56 was sys_mpx */
-__SYSCALL(56, sys_ni_syscall)
-#define __NR_setpgid 57
-__SYSCALL(__NR_setpgid, sys_setpgid)
- /* 58 was sys_ulimit */
-__SYSCALL(58, sys_ni_syscall)
- /* 59 was sys_olduname */
-__SYSCALL(59, sys_ni_syscall)
-#define __NR_umask 60
-__SYSCALL(__NR_umask, sys_umask)
-#define __NR_chroot 61
-__SYSCALL(__NR_chroot, sys_chroot)
-#define __NR_ustat 62
-__SYSCALL(__NR_ustat, compat_sys_ustat)
-#define __NR_dup2 63
-__SYSCALL(__NR_dup2, sys_dup2)
-#define __NR_getppid 64
-__SYSCALL(__NR_getppid, sys_getppid)
-#define __NR_getpgrp 65
-__SYSCALL(__NR_getpgrp, sys_getpgrp)
-#define __NR_setsid 66
-__SYSCALL(__NR_setsid, sys_setsid)
-#define __NR_sigaction 67
-__SYSCALL(__NR_sigaction, compat_sys_sigaction)
- /* 68 was sys_sgetmask */
-__SYSCALL(68, sys_ni_syscall)
- /* 69 was sys_ssetmask */
-__SYSCALL(69, sys_ni_syscall)
-#define __NR_setreuid 70
-__SYSCALL(__NR_setreuid, sys_setreuid16)
-#define __NR_setregid 71
-__SYSCALL(__NR_setregid, sys_setregid16)
-#define __NR_sigsuspend 72
-__SYSCALL(__NR_sigsuspend, sys_sigsuspend)
-#define __NR_sigpending 73
-__SYSCALL(__NR_sigpending, compat_sys_sigpending)
-#define __NR_sethostname 74
-__SYSCALL(__NR_sethostname, sys_sethostname)
-#define __NR_setrlimit 75
-__SYSCALL(__NR_setrlimit, compat_sys_setrlimit)
- /* 76 was compat_sys_getrlimit */
-__SYSCALL(76, sys_ni_syscall)
-#define __NR_getrusage 77
-__SYSCALL(__NR_getrusage, compat_sys_getrusage)
-#define __NR_gettimeofday 78
-__SYSCALL(__NR_gettimeofday, compat_sys_gettimeofday)
-#define __NR_settimeofday 79
-__SYSCALL(__NR_settimeofday, compat_sys_settimeofday)
-#define __NR_getgroups 80
-__SYSCALL(__NR_getgroups, sys_getgroups16)
-#define __NR_setgroups 81
-__SYSCALL(__NR_setgroups, sys_setgroups16)
- /* 82 was compat_sys_select */
-__SYSCALL(82, sys_ni_syscall)
-#define __NR_symlink 83
-__SYSCALL(__NR_symlink, sys_symlink)
- /* 84 was sys_lstat */
-__SYSCALL(84, sys_ni_syscall)
-#define __NR_readlink 85
-__SYSCALL(__NR_readlink, sys_readlink)
-#define __NR_uselib 86
-__SYSCALL(__NR_uselib, sys_uselib)
-#define __NR_swapon 87
-__SYSCALL(__NR_swapon, sys_swapon)
-#define __NR_reboot 88
-__SYSCALL(__NR_reboot, sys_reboot)
- /* 89 was sys_readdir */
-__SYSCALL(89, sys_ni_syscall)
- /* 90 was sys_mmap */
-__SYSCALL(90, sys_ni_syscall)
-#define __NR_munmap 91
-__SYSCALL(__NR_munmap, sys_munmap)
-#define __NR_truncate 92
-__SYSCALL(__NR_truncate, compat_sys_truncate)
-#define __NR_ftruncate 93
-__SYSCALL(__NR_ftruncate, compat_sys_ftruncate)
-#define __NR_fchmod 94
-__SYSCALL(__NR_fchmod, sys_fchmod)
-#define __NR_fchown 95
-__SYSCALL(__NR_fchown, sys_fchown16)
-#define __NR_getpriority 96
-__SYSCALL(__NR_getpriority, sys_getpriority)
-#define __NR_setpriority 97
-__SYSCALL(__NR_setpriority, sys_setpriority)
- /* 98 was sys_profil */
-__SYSCALL(98, sys_ni_syscall)
-#define __NR_statfs 99
-__SYSCALL(__NR_statfs, compat_sys_statfs)
-#define __NR_fstatfs 100
-__SYSCALL(__NR_fstatfs, compat_sys_fstatfs)
- /* 101 was sys_ioperm */
-__SYSCALL(101, sys_ni_syscall)
- /* 102 was sys_socketcall */
-__SYSCALL(102, sys_ni_syscall)
-#define __NR_syslog 103
-__SYSCALL(__NR_syslog, sys_syslog)
-#define __NR_setitimer 104
-__SYSCALL(__NR_setitimer, compat_sys_setitimer)
-#define __NR_getitimer 105
-__SYSCALL(__NR_getitimer, compat_sys_getitimer)
-#define __NR_stat 106
-__SYSCALL(__NR_stat, compat_sys_newstat)
-#define __NR_lstat 107
-__SYSCALL(__NR_lstat, compat_sys_newlstat)
-#define __NR_fstat 108
-__SYSCALL(__NR_fstat, compat_sys_newfstat)
- /* 109 was sys_uname */
-__SYSCALL(109, sys_ni_syscall)
- /* 110 was sys_iopl */
-__SYSCALL(110, sys_ni_syscall)
-#define __NR_vhangup 111
-__SYSCALL(__NR_vhangup, sys_vhangup)
- /* 112 was sys_idle */
-__SYSCALL(112, sys_ni_syscall)
- /* 113 was sys_syscall */
-__SYSCALL(113, sys_ni_syscall)
-#define __NR_wait4 114
-__SYSCALL(__NR_wait4, compat_sys_wait4)
-#define __NR_swapoff 115
-__SYSCALL(__NR_swapoff, sys_swapoff)
-#define __NR_sysinfo 116
-__SYSCALL(__NR_sysinfo, compat_sys_sysinfo)
- /* 117 was sys_ipc */
-__SYSCALL(117, sys_ni_syscall)
-#define __NR_fsync 118
-__SYSCALL(__NR_fsync, sys_fsync)
-#define __NR_sigreturn 119
-__SYSCALL(__NR_sigreturn, compat_sys_sigreturn)
-#define __NR_clone 120
-__SYSCALL(__NR_clone, sys_clone)
-#define __NR_setdomainname 121
-__SYSCALL(__NR_setdomainname, sys_setdomainname)
-#define __NR_uname 122
-__SYSCALL(__NR_uname, sys_newuname)
- /* 123 was sys_modify_ldt */
-__SYSCALL(123, sys_ni_syscall)
-#define __NR_adjtimex 124
-__SYSCALL(__NR_adjtimex, sys_adjtimex_time32)
-#define __NR_mprotect 125
-__SYSCALL(__NR_mprotect, sys_mprotect)
-#define __NR_sigprocmask 126
-__SYSCALL(__NR_sigprocmask, compat_sys_sigprocmask)
- /* 127 was sys_create_module */
-__SYSCALL(127, sys_ni_syscall)
-#define __NR_init_module 128
-__SYSCALL(__NR_init_module, sys_init_module)
-#define __NR_delete_module 129
-__SYSCALL(__NR_delete_module, sys_delete_module)
- /* 130 was sys_get_kernel_syms */
-__SYSCALL(130, sys_ni_syscall)
-#define __NR_quotactl 131
-__SYSCALL(__NR_quotactl, sys_quotactl)
-#define __NR_getpgid 132
-__SYSCALL(__NR_getpgid, sys_getpgid)
-#define __NR_fchdir 133
-__SYSCALL(__NR_fchdir, sys_fchdir)
-#define __NR_bdflush 134
-__SYSCALL(__NR_bdflush, sys_ni_syscall)
-#define __NR_sysfs 135
-__SYSCALL(__NR_sysfs, sys_sysfs)
-#define __NR_personality 136
-__SYSCALL(__NR_personality, sys_personality)
- /* 137 was sys_afs_syscall */
-__SYSCALL(137, sys_ni_syscall)
-#define __NR_setfsuid 138
-__SYSCALL(__NR_setfsuid, sys_setfsuid16)
-#define __NR_setfsgid 139
-__SYSCALL(__NR_setfsgid, sys_setfsgid16)
-#define __NR__llseek 140
-__SYSCALL(__NR__llseek, sys_llseek)
-#define __NR_getdents 141
-__SYSCALL(__NR_getdents, compat_sys_getdents)
-#define __NR__newselect 142
-__SYSCALL(__NR__newselect, compat_sys_select)
-#define __NR_flock 143
-__SYSCALL(__NR_flock, sys_flock)
-#define __NR_msync 144
-__SYSCALL(__NR_msync, sys_msync)
-#define __NR_readv 145
-__SYSCALL(__NR_readv, sys_readv)
-#define __NR_writev 146
-__SYSCALL(__NR_writev, sys_writev)
-#define __NR_getsid 147
-__SYSCALL(__NR_getsid, sys_getsid)
-#define __NR_fdatasync 148
-__SYSCALL(__NR_fdatasync, sys_fdatasync)
- /* 149 was sys_sysctl */
-__SYSCALL(149, sys_ni_syscall)
-#define __NR_mlock 150
-__SYSCALL(__NR_mlock, sys_mlock)
-#define __NR_munlock 151
-__SYSCALL(__NR_munlock, sys_munlock)
-#define __NR_mlockall 152
-__SYSCALL(__NR_mlockall, sys_mlockall)
-#define __NR_munlockall 153
-__SYSCALL(__NR_munlockall, sys_munlockall)
-#define __NR_sched_setparam 154
-__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
-#define __NR_sched_getparam 155
-__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
-#define __NR_sched_setscheduler 156
-__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
-#define __NR_sched_getscheduler 157
-__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
-#define __NR_sched_yield 158
-__SYSCALL(__NR_sched_yield, sys_sched_yield)
-#define __NR_sched_get_priority_max 159
-__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
-#define __NR_sched_get_priority_min 160
-__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
-#define __NR_sched_rr_get_interval 161
-__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval_time32)
-#define __NR_nanosleep 162
-__SYSCALL(__NR_nanosleep, sys_nanosleep_time32)
-#define __NR_mremap 163
-__SYSCALL(__NR_mremap, sys_mremap)
-#define __NR_setresuid 164
-__SYSCALL(__NR_setresuid, sys_setresuid16)
-#define __NR_getresuid 165
-__SYSCALL(__NR_getresuid, sys_getresuid16)
- /* 166 was sys_vm86 */
-__SYSCALL(166, sys_ni_syscall)
- /* 167 was sys_query_module */
-__SYSCALL(167, sys_ni_syscall)
-#define __NR_poll 168
-__SYSCALL(__NR_poll, sys_poll)
-#define __NR_nfsservctl 169
-__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
-#define __NR_setresgid 170
-__SYSCALL(__NR_setresgid, sys_setresgid16)
-#define __NR_getresgid 171
-__SYSCALL(__NR_getresgid, sys_getresgid16)
-#define __NR_prctl 172
-__SYSCALL(__NR_prctl, sys_prctl)
-#define __NR_rt_sigreturn 173
-__SYSCALL(__NR_rt_sigreturn, compat_sys_rt_sigreturn)
-#define __NR_rt_sigaction 174
-__SYSCALL(__NR_rt_sigaction, compat_sys_rt_sigaction)
-#define __NR_rt_sigprocmask 175
-__SYSCALL(__NR_rt_sigprocmask, compat_sys_rt_sigprocmask)
-#define __NR_rt_sigpending 176
-__SYSCALL(__NR_rt_sigpending, compat_sys_rt_sigpending)
-#define __NR_rt_sigtimedwait 177
-__SYSCALL(__NR_rt_sigtimedwait, compat_sys_rt_sigtimedwait_time32)
-#define __NR_rt_sigqueueinfo 178
-__SYSCALL(__NR_rt_sigqueueinfo, compat_sys_rt_sigqueueinfo)
-#define __NR_rt_sigsuspend 179
-__SYSCALL(__NR_rt_sigsuspend, compat_sys_rt_sigsuspend)
-#define __NR_pread64 180
-__SYSCALL(__NR_pread64, compat_sys_aarch32_pread64)
-#define __NR_pwrite64 181
-__SYSCALL(__NR_pwrite64, compat_sys_aarch32_pwrite64)
-#define __NR_chown 182
-__SYSCALL(__NR_chown, sys_chown16)
-#define __NR_getcwd 183
-__SYSCALL(__NR_getcwd, sys_getcwd)
-#define __NR_capget 184
-__SYSCALL(__NR_capget, sys_capget)
-#define __NR_capset 185
-__SYSCALL(__NR_capset, sys_capset)
-#define __NR_sigaltstack 186
-__SYSCALL(__NR_sigaltstack, compat_sys_sigaltstack)
-#define __NR_sendfile 187
-__SYSCALL(__NR_sendfile, compat_sys_sendfile)
- /* 188 reserved */
-__SYSCALL(188, sys_ni_syscall)
- /* 189 reserved */
-__SYSCALL(189, sys_ni_syscall)
-#define __NR_vfork 190
-__SYSCALL(__NR_vfork, sys_vfork)
-#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
-__SYSCALL(__NR_ugetrlimit, compat_sys_getrlimit) /* SuS compliant getrlimit */
-#define __NR_mmap2 192
-__SYSCALL(__NR_mmap2, compat_sys_aarch32_mmap2)
-#define __NR_truncate64 193
-__SYSCALL(__NR_truncate64, compat_sys_aarch32_truncate64)
-#define __NR_ftruncate64 194
-__SYSCALL(__NR_ftruncate64, compat_sys_aarch32_ftruncate64)
-#define __NR_stat64 195
-__SYSCALL(__NR_stat64, sys_stat64)
-#define __NR_lstat64 196
-__SYSCALL(__NR_lstat64, sys_lstat64)
-#define __NR_fstat64 197
-__SYSCALL(__NR_fstat64, sys_fstat64)
-#define __NR_lchown32 198
-__SYSCALL(__NR_lchown32, sys_lchown)
-#define __NR_getuid32 199
-__SYSCALL(__NR_getuid32, sys_getuid)
-#define __NR_getgid32 200
-__SYSCALL(__NR_getgid32, sys_getgid)
-#define __NR_geteuid32 201
-__SYSCALL(__NR_geteuid32, sys_geteuid)
-#define __NR_getegid32 202
-__SYSCALL(__NR_getegid32, sys_getegid)
-#define __NR_setreuid32 203
-__SYSCALL(__NR_setreuid32, sys_setreuid)
-#define __NR_setregid32 204
-__SYSCALL(__NR_setregid32, sys_setregid)
-#define __NR_getgroups32 205
-__SYSCALL(__NR_getgroups32, sys_getgroups)
-#define __NR_setgroups32 206
-__SYSCALL(__NR_setgroups32, sys_setgroups)
-#define __NR_fchown32 207
-__SYSCALL(__NR_fchown32, sys_fchown)
-#define __NR_setresuid32 208
-__SYSCALL(__NR_setresuid32, sys_setresuid)
-#define __NR_getresuid32 209
-__SYSCALL(__NR_getresuid32, sys_getresuid)
-#define __NR_setresgid32 210
-__SYSCALL(__NR_setresgid32, sys_setresgid)
-#define __NR_getresgid32 211
-__SYSCALL(__NR_getresgid32, sys_getresgid)
-#define __NR_chown32 212
-__SYSCALL(__NR_chown32, sys_chown)
-#define __NR_setuid32 213
-__SYSCALL(__NR_setuid32, sys_setuid)
-#define __NR_setgid32 214
-__SYSCALL(__NR_setgid32, sys_setgid)
-#define __NR_setfsuid32 215
-__SYSCALL(__NR_setfsuid32, sys_setfsuid)
-#define __NR_setfsgid32 216
-__SYSCALL(__NR_setfsgid32, sys_setfsgid)
-#define __NR_getdents64 217
-__SYSCALL(__NR_getdents64, sys_getdents64)
-#define __NR_pivot_root 218
-__SYSCALL(__NR_pivot_root, sys_pivot_root)
-#define __NR_mincore 219
-__SYSCALL(__NR_mincore, sys_mincore)
-#define __NR_madvise 220
-__SYSCALL(__NR_madvise, sys_madvise)
-#define __NR_fcntl64 221
-__SYSCALL(__NR_fcntl64, compat_sys_fcntl64)
- /* 222 for tux */
-__SYSCALL(222, sys_ni_syscall)
- /* 223 is unused */
-__SYSCALL(223, sys_ni_syscall)
-#define __NR_gettid 224
-__SYSCALL(__NR_gettid, sys_gettid)
-#define __NR_readahead 225
-__SYSCALL(__NR_readahead, compat_sys_aarch32_readahead)
-#define __NR_setxattr 226
-__SYSCALL(__NR_setxattr, sys_setxattr)
-#define __NR_lsetxattr 227
-__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
-#define __NR_fsetxattr 228
-__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
-#define __NR_getxattr 229
-__SYSCALL(__NR_getxattr, sys_getxattr)
-#define __NR_lgetxattr 230
-__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
-#define __NR_fgetxattr 231
-__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
-#define __NR_listxattr 232
-__SYSCALL(__NR_listxattr, sys_listxattr)
-#define __NR_llistxattr 233
-__SYSCALL(__NR_llistxattr, sys_llistxattr)
-#define __NR_flistxattr 234
-__SYSCALL(__NR_flistxattr, sys_flistxattr)
-#define __NR_removexattr 235
-__SYSCALL(__NR_removexattr, sys_removexattr)
-#define __NR_lremovexattr 236
-__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
-#define __NR_fremovexattr 237
-__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
-#define __NR_tkill 238
-__SYSCALL(__NR_tkill, sys_tkill)
-#define __NR_sendfile64 239
-__SYSCALL(__NR_sendfile64, sys_sendfile64)
-#define __NR_futex 240
-__SYSCALL(__NR_futex, sys_futex_time32)
-#define __NR_sched_setaffinity 241
-__SYSCALL(__NR_sched_setaffinity, compat_sys_sched_setaffinity)
-#define __NR_sched_getaffinity 242
-__SYSCALL(__NR_sched_getaffinity, compat_sys_sched_getaffinity)
-#define __NR_io_setup 243
-__SYSCALL(__NR_io_setup, compat_sys_io_setup)
-#define __NR_io_destroy 244
-__SYSCALL(__NR_io_destroy, sys_io_destroy)
-#define __NR_io_getevents 245
-__SYSCALL(__NR_io_getevents, sys_io_getevents_time32)
-#define __NR_io_submit 246
-__SYSCALL(__NR_io_submit, compat_sys_io_submit)
-#define __NR_io_cancel 247
-__SYSCALL(__NR_io_cancel, sys_io_cancel)
-#define __NR_exit_group 248
-__SYSCALL(__NR_exit_group, sys_exit_group)
- /* 249 was lookup_dcookie */
-__SYSCALL(249, sys_ni_syscall)
-#define __NR_epoll_create 250
-__SYSCALL(__NR_epoll_create, sys_epoll_create)
-#define __NR_epoll_ctl 251
-__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
-#define __NR_epoll_wait 252
-__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
-#define __NR_remap_file_pages 253
-__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
- /* 254 for set_thread_area */
-__SYSCALL(254, sys_ni_syscall)
- /* 255 for get_thread_area */
-__SYSCALL(255, sys_ni_syscall)
-#define __NR_set_tid_address 256
-__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
-#define __NR_timer_create 257
-__SYSCALL(__NR_timer_create, compat_sys_timer_create)
-#define __NR_timer_settime 258
-__SYSCALL(__NR_timer_settime, sys_timer_settime32)
-#define __NR_timer_gettime 259
-__SYSCALL(__NR_timer_gettime, sys_timer_gettime32)
-#define __NR_timer_getoverrun 260
-__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
-#define __NR_timer_delete 261
-__SYSCALL(__NR_timer_delete, sys_timer_delete)
-#define __NR_clock_settime 262
-__SYSCALL(__NR_clock_settime, sys_clock_settime32)
-#define __NR_clock_gettime 263
-__SYSCALL(__NR_clock_gettime, sys_clock_gettime32)
-#define __NR_clock_getres 264
-__SYSCALL(__NR_clock_getres, sys_clock_getres_time32)
-#define __NR_clock_nanosleep 265
-__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep_time32)
-#define __NR_statfs64 266
-__SYSCALL(__NR_statfs64, compat_sys_aarch32_statfs64)
-#define __NR_fstatfs64 267
-__SYSCALL(__NR_fstatfs64, compat_sys_aarch32_fstatfs64)
-#define __NR_tgkill 268
-__SYSCALL(__NR_tgkill, sys_tgkill)
-#define __NR_utimes 269
-__SYSCALL(__NR_utimes, sys_utimes_time32)
-#define __NR_arm_fadvise64_64 270
-__SYSCALL(__NR_arm_fadvise64_64, compat_sys_aarch32_fadvise64_64)
-#define __NR_pciconfig_iobase 271
-__SYSCALL(__NR_pciconfig_iobase, sys_pciconfig_iobase)
-#define __NR_pciconfig_read 272
-__SYSCALL(__NR_pciconfig_read, sys_pciconfig_read)
-#define __NR_pciconfig_write 273
-__SYSCALL(__NR_pciconfig_write, sys_pciconfig_write)
-#define __NR_mq_open 274
-__SYSCALL(__NR_mq_open, compat_sys_mq_open)
-#define __NR_mq_unlink 275
-__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
-#define __NR_mq_timedsend 276
-__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend_time32)
-#define __NR_mq_timedreceive 277
-__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive_time32)
-#define __NR_mq_notify 278
-__SYSCALL(__NR_mq_notify, compat_sys_mq_notify)
-#define __NR_mq_getsetattr 279
-__SYSCALL(__NR_mq_getsetattr, compat_sys_mq_getsetattr)
-#define __NR_waitid 280
-__SYSCALL(__NR_waitid, compat_sys_waitid)
-#define __NR_socket 281
-__SYSCALL(__NR_socket, sys_socket)
-#define __NR_bind 282
-__SYSCALL(__NR_bind, sys_bind)
-#define __NR_connect 283
-__SYSCALL(__NR_connect, sys_connect)
-#define __NR_listen 284
-__SYSCALL(__NR_listen, sys_listen)
-#define __NR_accept 285
-__SYSCALL(__NR_accept, sys_accept)
-#define __NR_getsockname 286
-__SYSCALL(__NR_getsockname, sys_getsockname)
-#define __NR_getpeername 287
-__SYSCALL(__NR_getpeername, sys_getpeername)
-#define __NR_socketpair 288
-__SYSCALL(__NR_socketpair, sys_socketpair)
-#define __NR_send 289
-__SYSCALL(__NR_send, sys_send)
-#define __NR_sendto 290
-__SYSCALL(__NR_sendto, sys_sendto)
-#define __NR_recv 291
-__SYSCALL(__NR_recv, compat_sys_recv)
-#define __NR_recvfrom 292
-__SYSCALL(__NR_recvfrom, compat_sys_recvfrom)
-#define __NR_shutdown 293
-__SYSCALL(__NR_shutdown, sys_shutdown)
-#define __NR_setsockopt 294
-__SYSCALL(__NR_setsockopt, sys_setsockopt)
-#define __NR_getsockopt 295
-__SYSCALL(__NR_getsockopt, sys_getsockopt)
-#define __NR_sendmsg 296
-__SYSCALL(__NR_sendmsg, compat_sys_sendmsg)
-#define __NR_recvmsg 297
-__SYSCALL(__NR_recvmsg, compat_sys_recvmsg)
-#define __NR_semop 298
-__SYSCALL(__NR_semop, sys_semop)
-#define __NR_semget 299
-__SYSCALL(__NR_semget, sys_semget)
-#define __NR_semctl 300
-__SYSCALL(__NR_semctl, compat_sys_old_semctl)
-#define __NR_msgsnd 301
-__SYSCALL(__NR_msgsnd, compat_sys_msgsnd)
-#define __NR_msgrcv 302
-__SYSCALL(__NR_msgrcv, compat_sys_msgrcv)
-#define __NR_msgget 303
-__SYSCALL(__NR_msgget, sys_msgget)
-#define __NR_msgctl 304
-__SYSCALL(__NR_msgctl, compat_sys_old_msgctl)
-#define __NR_shmat 305
-__SYSCALL(__NR_shmat, compat_sys_shmat)
-#define __NR_shmdt 306
-__SYSCALL(__NR_shmdt, sys_shmdt)
-#define __NR_shmget 307
-__SYSCALL(__NR_shmget, sys_shmget)
-#define __NR_shmctl 308
-__SYSCALL(__NR_shmctl, compat_sys_old_shmctl)
-#define __NR_add_key 309
-__SYSCALL(__NR_add_key, sys_add_key)
-#define __NR_request_key 310
-__SYSCALL(__NR_request_key, sys_request_key)
-#define __NR_keyctl 311
-__SYSCALL(__NR_keyctl, compat_sys_keyctl)
-#define __NR_semtimedop 312
-__SYSCALL(__NR_semtimedop, sys_semtimedop_time32)
-#define __NR_vserver 313
-__SYSCALL(__NR_vserver, sys_ni_syscall)
-#define __NR_ioprio_set 314
-__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
-#define __NR_ioprio_get 315
-__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
-#define __NR_inotify_init 316
-__SYSCALL(__NR_inotify_init, sys_inotify_init)
-#define __NR_inotify_add_watch 317
-__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
-#define __NR_inotify_rm_watch 318
-__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
-#define __NR_mbind 319
-__SYSCALL(__NR_mbind, sys_mbind)
-#define __NR_get_mempolicy 320
-__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
-#define __NR_set_mempolicy 321
-__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
-#define __NR_openat 322
-__SYSCALL(__NR_openat, compat_sys_openat)
-#define __NR_mkdirat 323
-__SYSCALL(__NR_mkdirat, sys_mkdirat)
-#define __NR_mknodat 324
-__SYSCALL(__NR_mknodat, sys_mknodat)
-#define __NR_fchownat 325
-__SYSCALL(__NR_fchownat, sys_fchownat)
-#define __NR_futimesat 326
-__SYSCALL(__NR_futimesat, sys_futimesat_time32)
-#define __NR_fstatat64 327
-__SYSCALL(__NR_fstatat64, sys_fstatat64)
-#define __NR_unlinkat 328
-__SYSCALL(__NR_unlinkat, sys_unlinkat)
-#define __NR_renameat 329
-__SYSCALL(__NR_renameat, sys_renameat)
-#define __NR_linkat 330
-__SYSCALL(__NR_linkat, sys_linkat)
-#define __NR_symlinkat 331
-__SYSCALL(__NR_symlinkat, sys_symlinkat)
-#define __NR_readlinkat 332
-__SYSCALL(__NR_readlinkat, sys_readlinkat)
-#define __NR_fchmodat 333
-__SYSCALL(__NR_fchmodat, sys_fchmodat)
-#define __NR_faccessat 334
-__SYSCALL(__NR_faccessat, sys_faccessat)
-#define __NR_pselect6 335
-__SYSCALL(__NR_pselect6, compat_sys_pselect6_time32)
-#define __NR_ppoll 336
-__SYSCALL(__NR_ppoll, compat_sys_ppoll_time32)
-#define __NR_unshare 337
-__SYSCALL(__NR_unshare, sys_unshare)
-#define __NR_set_robust_list 338
-__SYSCALL(__NR_set_robust_list, compat_sys_set_robust_list)
-#define __NR_get_robust_list 339
-__SYSCALL(__NR_get_robust_list, compat_sys_get_robust_list)
-#define __NR_splice 340
-__SYSCALL(__NR_splice, sys_splice)
-#define __NR_sync_file_range2 341
-__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, sys_vmsplice)
-#define __NR_move_pages 344
-__SYSCALL(__NR_move_pages, sys_move_pages)
-#define __NR_getcpu 345
-__SYSCALL(__NR_getcpu, sys_getcpu)
-#define __NR_epoll_pwait 346
-__SYSCALL(__NR_epoll_pwait, compat_sys_epoll_pwait)
-#define __NR_kexec_load 347
-__SYSCALL(__NR_kexec_load, compat_sys_kexec_load)
-#define __NR_utimensat 348
-__SYSCALL(__NR_utimensat, sys_utimensat_time32)
-#define __NR_signalfd 349
-__SYSCALL(__NR_signalfd, compat_sys_signalfd)
-#define __NR_timerfd_create 350
-__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
-#define __NR_eventfd 351
-__SYSCALL(__NR_eventfd, sys_eventfd)
-#define __NR_fallocate 352
-__SYSCALL(__NR_fallocate, compat_sys_aarch32_fallocate)
-#define __NR_timerfd_settime 353
-__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime32)
-#define __NR_timerfd_gettime 354
-__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime32)
-#define __NR_signalfd4 355
-__SYSCALL(__NR_signalfd4, compat_sys_signalfd4)
-#define __NR_eventfd2 356
-__SYSCALL(__NR_eventfd2, sys_eventfd2)
-#define __NR_epoll_create1 357
-__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
-#define __NR_dup3 358
-__SYSCALL(__NR_dup3, sys_dup3)
-#define __NR_pipe2 359
-__SYSCALL(__NR_pipe2, sys_pipe2)
-#define __NR_inotify_init1 360
-__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-#define __NR_preadv 361
-__SYSCALL(__NR_preadv, compat_sys_preadv)
-#define __NR_pwritev 362
-__SYSCALL(__NR_pwritev, compat_sys_pwritev)
-#define __NR_rt_tgsigqueueinfo 363
-__SYSCALL(__NR_rt_tgsigqueueinfo, compat_sys_rt_tgsigqueueinfo)
-#define __NR_perf_event_open 364
-__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
-#define __NR_recvmmsg 365
-__SYSCALL(__NR_recvmmsg, compat_sys_recvmmsg_time32)
-#define __NR_accept4 366
-__SYSCALL(__NR_accept4, sys_accept4)
-#define __NR_fanotify_init 367
-__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
-#define __NR_fanotify_mark 368
-__SYSCALL(__NR_fanotify_mark, compat_sys_fanotify_mark)
-#define __NR_prlimit64 369
-__SYSCALL(__NR_prlimit64, sys_prlimit64)
-#define __NR_name_to_handle_at 370
-__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
-#define __NR_open_by_handle_at 371
-__SYSCALL(__NR_open_by_handle_at, compat_sys_open_by_handle_at)
-#define __NR_clock_adjtime 372
-__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime32)
-#define __NR_syncfs 373
-__SYSCALL(__NR_syncfs, sys_syncfs)
-#define __NR_sendmmsg 374
-__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, sys_process_vm_readv)
-#define __NR_process_vm_writev 377
-__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
-#define __NR_kcmp 378
-__SYSCALL(__NR_kcmp, sys_kcmp)
-#define __NR_finit_module 379
-__SYSCALL(__NR_finit_module, sys_finit_module)
-#define __NR_sched_setattr 380
-__SYSCALL(__NR_sched_setattr, sys_sched_setattr)
-#define __NR_sched_getattr 381
-__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
-#define __NR_renameat2 382
-__SYSCALL(__NR_renameat2, sys_renameat2)
-#define __NR_seccomp 383
-__SYSCALL(__NR_seccomp, sys_seccomp)
-#define __NR_getrandom 384
-__SYSCALL(__NR_getrandom, sys_getrandom)
-#define __NR_memfd_create 385
-__SYSCALL(__NR_memfd_create, sys_memfd_create)
-#define __NR_bpf 386
-__SYSCALL(__NR_bpf, sys_bpf)
-#define __NR_execveat 387
-__SYSCALL(__NR_execveat, compat_sys_execveat)
-#define __NR_userfaultfd 388
-__SYSCALL(__NR_userfaultfd, sys_userfaultfd)
-#define __NR_membarrier 389
-__SYSCALL(__NR_membarrier, sys_membarrier)
-#define __NR_mlock2 390
-__SYSCALL(__NR_mlock2, sys_mlock2)
-#define __NR_copy_file_range 391
-__SYSCALL(__NR_copy_file_range, sys_copy_file_range)
-#define __NR_preadv2 392
-__SYSCALL(__NR_preadv2, compat_sys_preadv2)
-#define __NR_pwritev2 393
-__SYSCALL(__NR_pwritev2, compat_sys_pwritev2)
-#define __NR_pkey_mprotect 394
-__SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect)
-#define __NR_pkey_alloc 395
-__SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
-#define __NR_pkey_free 396
-__SYSCALL(__NR_pkey_free, sys_pkey_free)
-#define __NR_statx 397
-__SYSCALL(__NR_statx, sys_statx)
-#define __NR_rseq 398
-__SYSCALL(__NR_rseq, sys_rseq)
-#define __NR_io_pgetevents 399
-__SYSCALL(__NR_io_pgetevents, compat_sys_io_pgetevents)
-#define __NR_migrate_pages 400
-__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
-#define __NR_kexec_file_load 401
-__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load)
-/* 402 is unused */
-#define __NR_clock_gettime64 403
-__SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
-#define __NR_clock_settime64 404
-__SYSCALL(__NR_clock_settime64, sys_clock_settime)
-#define __NR_clock_adjtime64 405
-__SYSCALL(__NR_clock_adjtime64, sys_clock_adjtime)
-#define __NR_clock_getres_time64 406
-__SYSCALL(__NR_clock_getres_time64, sys_clock_getres)
-#define __NR_clock_nanosleep_time64 407
-__SYSCALL(__NR_clock_nanosleep_time64, sys_clock_nanosleep)
-#define __NR_timer_gettime64 408
-__SYSCALL(__NR_timer_gettime64, sys_timer_gettime)
-#define __NR_timer_settime64 409
-__SYSCALL(__NR_timer_settime64, sys_timer_settime)
-#define __NR_timerfd_gettime64 410
-__SYSCALL(__NR_timerfd_gettime64, sys_timerfd_gettime)
-#define __NR_timerfd_settime64 411
-__SYSCALL(__NR_timerfd_settime64, sys_timerfd_settime)
-#define __NR_utimensat_time64 412
-__SYSCALL(__NR_utimensat_time64, sys_utimensat)
-#define __NR_pselect6_time64 413
-__SYSCALL(__NR_pselect6_time64, compat_sys_pselect6_time64)
-#define __NR_ppoll_time64 414
-__SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64)
-#define __NR_io_pgetevents_time64 416
-__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents)
-#define __NR_recvmmsg_time64 417
-__SYSCALL(__NR_recvmmsg_time64, compat_sys_recvmmsg_time64)
-#define __NR_mq_timedsend_time64 418
-__SYSCALL(__NR_mq_timedsend_time64, sys_mq_timedsend)
-#define __NR_mq_timedreceive_time64 419
-__SYSCALL(__NR_mq_timedreceive_time64, sys_mq_timedreceive)
-#define __NR_semtimedop_time64 420
-__SYSCALL(__NR_semtimedop_time64, sys_semtimedop)
-#define __NR_rt_sigtimedwait_time64 421
-__SYSCALL(__NR_rt_sigtimedwait_time64, compat_sys_rt_sigtimedwait_time64)
-#define __NR_futex_time64 422
-__SYSCALL(__NR_futex_time64, sys_futex)
-#define __NR_sched_rr_get_interval_time64 423
-__SYSCALL(__NR_sched_rr_get_interval_time64, sys_sched_rr_get_interval)
-#define __NR_pidfd_send_signal 424
-__SYSCALL(__NR_pidfd_send_signal, sys_pidfd_send_signal)
-#define __NR_io_uring_setup 425
-__SYSCALL(__NR_io_uring_setup, sys_io_uring_setup)
-#define __NR_io_uring_enter 426
-__SYSCALL(__NR_io_uring_enter, sys_io_uring_enter)
-#define __NR_io_uring_register 427
-__SYSCALL(__NR_io_uring_register, sys_io_uring_register)
-#define __NR_open_tree 428
-__SYSCALL(__NR_open_tree, sys_open_tree)
-#define __NR_move_mount 429
-__SYSCALL(__NR_move_mount, sys_move_mount)
-#define __NR_fsopen 430
-__SYSCALL(__NR_fsopen, sys_fsopen)
-#define __NR_fsconfig 431
-__SYSCALL(__NR_fsconfig, sys_fsconfig)
-#define __NR_fsmount 432
-__SYSCALL(__NR_fsmount, sys_fsmount)
-#define __NR_fspick 433
-__SYSCALL(__NR_fspick, sys_fspick)
-#define __NR_pidfd_open 434
-__SYSCALL(__NR_pidfd_open, sys_pidfd_open)
-#define __NR_clone3 435
-__SYSCALL(__NR_clone3, sys_clone3)
-#define __NR_close_range 436
-__SYSCALL(__NR_close_range, sys_close_range)
-#define __NR_openat2 437
-__SYSCALL(__NR_openat2, sys_openat2)
-#define __NR_pidfd_getfd 438
-__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)
-#define __NR_epoll_pwait2 441
-__SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2)
-#define __NR_mount_setattr 442
-__SYSCALL(__NR_mount_setattr, sys_mount_setattr)
-#define __NR_quotactl_fd 443
-__SYSCALL(__NR_quotactl_fd, sys_quotactl_fd)
-#define __NR_landlock_create_ruleset 444
-__SYSCALL(__NR_landlock_create_ruleset, sys_landlock_create_ruleset)
-#define __NR_landlock_add_rule 445
-__SYSCALL(__NR_landlock_add_rule, sys_landlock_add_rule)
-#define __NR_landlock_restrict_self 446
-__SYSCALL(__NR_landlock_restrict_self, sys_landlock_restrict_self)
-#define __NR_process_mrelease 448
-__SYSCALL(__NR_process_mrelease, sys_process_mrelease)
-#define __NR_futex_waitv 449
-__SYSCALL(__NR_futex_waitv, sys_futex_waitv)
-#define __NR_set_mempolicy_home_node 450
-__SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node)
-#define __NR_cachestat 451
-__SYSCALL(__NR_cachestat, sys_cachestat)
-#define __NR_fchmodat2 452
-__SYSCALL(__NR_fchmodat2, sys_fchmodat2)
-#define __NR_map_shadow_stack 453
-__SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack)
-#define __NR_futex_wake 454
-__SYSCALL(__NR_futex_wake, sys_futex_wake)
-#define __NR_futex_wait 455
-__SYSCALL(__NR_futex_wait, sys_futex_wait)
-#define __NR_futex_requeue 456
-__SYSCALL(__NR_futex_requeue, sys_futex_requeue)
-#define __NR_statmount 457
-__SYSCALL(__NR_statmount, sys_statmount)
-#define __NR_listmount 458
-__SYSCALL(__NR_listmount, sys_listmount)
-#define __NR_lsm_get_self_attr 459
-__SYSCALL(__NR_lsm_get_self_attr, sys_lsm_get_self_attr)
-#define __NR_lsm_set_self_attr 460
-__SYSCALL(__NR_lsm_set_self_attr, sys_lsm_set_self_attr)
-#define __NR_lsm_list_modules 461
-__SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
+#define __NR_sync_file_range2 __NR_arm_sync_file_range
-/*
- * Please add new compat syscalls above this comment and update
- * __NR_compat_syscalls in asm/unistd.h.
- */
+#endif /* _UAPI__ASM_ARM_UNISTD_H */
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index ecb6fd4c3c64..778c1202bbbf 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -8,7 +8,7 @@
#ifndef __ASSEMBLY__
#include <asm/barrier.h>
-#include <asm/unistd.h>
+#include <asm/unistd_compat_32.h>
#include <asm/errno.h>
#include <asm/vdso/compat_barrier.h>
@@ -24,7 +24,7 @@ int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
register struct timezone *tz asm("r1") = _tz;
register struct __kernel_old_timeval *tv asm("r0") = _tv;
register long ret asm ("r0");
- register long nr asm("r7") = __NR_compat_gettimeofday;
+ register long nr asm("r7") = __NR_compat32_gettimeofday;
asm volatile(
" swi #0\n"
@@ -41,7 +41,7 @@ long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
register struct __kernel_timespec *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
- register long nr asm("r7") = __NR_compat_clock_gettime64;
+ register long nr asm("r7") = __NR_compat32_clock_gettime64;
asm volatile(
" swi #0\n"
@@ -58,7 +58,7 @@ long clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
register struct old_timespec32 *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
- register long nr asm("r7") = __NR_compat_clock_gettime;
+ register long nr asm("r7") = __NR_compat32_clock_gettime;
asm volatile(
" swi #0\n"
@@ -75,7 +75,7 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
register struct __kernel_timespec *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
- register long nr asm("r7") = __NR_compat_clock_getres_time64;
+ register long nr asm("r7") = __NR_compat32_clock_getres_time64;
asm volatile(
" swi #0\n"
@@ -92,7 +92,7 @@ int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
register struct old_timespec32 *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
- register long nr asm("r7") = __NR_compat_clock_getres;
+ register long nr asm("r7") = __NR_compat32_clock_getres;
asm volatile(
" swi #0\n"
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 261d6e9df2e1..ebf4a9f943ed 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -82,6 +82,12 @@ bool is_kvm_arm_initialised(void);
DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
+static inline bool is_pkvm_initialized(void)
+{
+ return IS_ENABLED(CONFIG_KVM) &&
+ static_branch_likely(&kvm_protected_mode_initialized);
+}
+
/* Reports the availability of HYP mode */
static inline bool is_hyp_mode_available(void)
{
@@ -89,8 +95,7 @@ static inline bool is_hyp_mode_available(void)
* If KVM protected mode is initialized, all CPUs must have been booted
* in EL2. Avoid checking __boot_cpu_mode as CPUs now come up in EL1.
*/
- if (IS_ENABLED(CONFIG_KVM) &&
- static_branch_likely(&kvm_protected_mode_initialized))
+ if (is_pkvm_initialized())
return true;
return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 &&
@@ -104,8 +109,7 @@ static inline bool is_hyp_mode_mismatched(void)
* If KVM protected mode is initialized, all CPUs must have been booted
* in EL2. Avoid checking __boot_cpu_mode as CPUs now come up in EL1.
*/
- if (IS_ENABLED(CONFIG_KVM) &&
- static_branch_likely(&kvm_protected_mode_initialized))
+ if (is_pkvm_initialized())
return false;
return __boot_cpu_mode[0] != __boot_cpu_mode[1];
diff --git a/arch/arm64/include/asm/word-at-a-time.h b/arch/arm64/include/asm/word-at-a-time.h
index 14251abee23c..824ca6987a51 100644
--- a/arch/arm64/include/asm/word-at-a-time.h
+++ b/arch/arm64/include/asm/word-at-a-time.h
@@ -27,20 +27,15 @@ static inline unsigned long has_zero(unsigned long a, unsigned long *bits,
}
#define prep_zero_mask(a, bits, c) (bits)
+#define create_zero_mask(bits) (bits)
+#define find_zero(bits) (__ffs(bits) >> 3)
-static inline unsigned long create_zero_mask(unsigned long bits)
+static inline unsigned long zero_bytemask(unsigned long bits)
{
bits = (bits - 1) & ~bits;
return bits >> 7;
}
-static inline unsigned long find_zero(unsigned long mask)
-{
- return fls64(mask) >> 3;
-}
-
-#define zero_bytemask(mask) (mask)
-
#else /* __AARCH64EB__ */
#include <asm-generic/word-at-a-time.h>
#endif
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index 602d137932dc..c6d141d7b7d7 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_64.h
generic-y += kvm_para.h
diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
index ce2ee8f1e361..df36f23876e8 100644
--- a/arch/arm64/include/uapi/asm/unistd.h
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -1,25 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright (C) 2012 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define __ARCH_WANT_RENAMEAT
-#define __ARCH_WANT_NEW_STAT
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_TIME32_SYSCALLS
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_MEMFD_SECRET
-
-#include <asm-generic/unistd.h>
+#include <asm/unistd_64.h>
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 763824963ed1..2b112f3b7510 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -46,7 +46,6 @@ obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o
diff --git a/arch/arm64/kernel/Makefile.syscalls b/arch/arm64/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..3cfafd003b2d
--- /dev/null
+++ b/arch/arm64/kernel/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscall_abis_64 += renameat newstat rlimit memfd_secret
+
+syscalltbl = arch/arm64/tools/syscall_%.tbl
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index dba8fcec7f33..e6f66491fbe9 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -26,9 +26,11 @@
#include <linux/libfdt.h>
#include <linux/smp.h>
#include <linux/serial_core.h>
+#include <linux/suspend.h>
#include <linux/pgtable.h>
#include <acpi/ghes.h>
+#include <acpi/processor.h>
#include <asm/cputype.h>
#include <asm/cpu_ops.h>
#include <asm/daifflags.h>
@@ -44,6 +46,7 @@ EXPORT_SYMBOL(acpi_pci_disabled);
static bool param_acpi_off __initdata;
static bool param_acpi_on __initdata;
static bool param_acpi_force __initdata;
+static bool param_acpi_nospcr __initdata;
static int __init parse_acpi(char *arg)
{
@@ -57,6 +60,8 @@ static int __init parse_acpi(char *arg)
param_acpi_on = true;
else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */
param_acpi_force = true;
+ else if (strcmp(arg, "nospcr") == 0) /* disable SPCR as default console */
+ param_acpi_nospcr = true;
else
return -EINVAL; /* Core will print when we return error */
@@ -227,7 +232,29 @@ done:
if (earlycon_acpi_spcr_enable)
early_init_dt_scan_chosen_stdout();
} else {
- acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
+#ifdef CONFIG_HIBERNATION
+ struct acpi_table_header *facs = NULL;
+ acpi_get_table(ACPI_SIG_FACS, 1, &facs);
+ if (facs) {
+ swsusp_hardware_signature =
+ ((struct acpi_table_facs *)facs)->hardware_signature;
+ acpi_put_table(facs);
+ }
+#endif
+
+ /*
+ * For varying privacy and security reasons, sometimes need
+ * to completely silence the serial console output, and only
+ * enable it when needed.
+ * But there are many existing systems that depend on this
+ * behaviour, use acpi=nospcr to disable console in ACPI SPCR
+ * table as default serial console.
+ */
+ acpi_parse_spcr(earlycon_acpi_spcr_enable,
+ !param_acpi_nospcr);
+ pr_info("Use ACPI SPCR as default console: %s\n",
+ param_acpi_nospcr ? "No" : "Yes");
+
if (IS_ENABLED(CONFIG_ACPI_BGRT))
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
}
@@ -413,107 +440,23 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
memblock_mark_nomap(addr, size);
}
-#ifdef CONFIG_ACPI_FFH
-/*
- * Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
- * specified in https://developer.arm.com/docs/den0048/latest
- */
-struct acpi_ffh_data {
- struct acpi_ffh_info info;
- void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
- unsigned long a2, unsigned long a3,
- unsigned long a4, unsigned long a5,
- unsigned long a6, unsigned long a7,
- struct arm_smccc_res *args,
- struct arm_smccc_quirk *res);
- void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
- struct arm_smccc_1_2_regs *res);
-};
-
-int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
+ int *pcpu)
{
- enum arm_smccc_conduit conduit;
- struct acpi_ffh_data *ffh_ctxt;
-
- if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
- return -EOPNOTSUPP;
-
- conduit = arm_smccc_1_1_get_conduit();
- if (conduit == SMCCC_CONDUIT_NONE) {
- pr_err("%s: invalid SMCCC conduit\n", __func__);
- return -EOPNOTSUPP;
+ /* If an error code is passed in this stub can't fix it */
+ if (*pcpu < 0) {
+ pr_warn_once("Unable to map CPU to valid ID\n");
+ return *pcpu;
}
- ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
- if (!ffh_ctxt)
- return -ENOMEM;
-
- if (conduit == SMCCC_CONDUIT_SMC) {
- ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
- ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
- } else {
- ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
- ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
- }
-
- memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));
-
- *region_ctxt = ffh_ctxt;
- return AE_OK;
-}
-
-static bool acpi_ffh_smccc_owner_allowed(u32 fid)
-{
- int owner = ARM_SMCCC_OWNER_NUM(fid);
-
- if (owner == ARM_SMCCC_OWNER_STANDARD ||
- owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
- return true;
-
- return false;
+ return 0;
}
+EXPORT_SYMBOL(acpi_map_cpu);
-int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
+int acpi_unmap_cpu(int cpu)
{
- int ret = 0;
- struct acpi_ffh_data *ffh_ctxt = region_context;
-
- if (ffh_ctxt->info.offset == 0) {
- /* SMC/HVC 32bit call */
- struct arm_smccc_res res;
- u32 a[8] = { 0 }, *ptr = (u32 *)value;
-
- if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
- !acpi_ffh_smccc_owner_allowed(*ptr) ||
- ffh_ctxt->info.length > 32) {
- ret = AE_ERROR;
- } else {
- int idx, len = ffh_ctxt->info.length >> 2;
-
- for (idx = 0; idx < len; idx++)
- a[idx] = *(ptr + idx);
-
- ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
- a[5], a[6], a[7], &res, NULL);
- memcpy(value, &res, sizeof(res));
- }
-
- } else if (ffh_ctxt->info.offset == 1) {
- /* SMC/HVC 64bit call */
- struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;
-
- if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
- !acpi_ffh_smccc_owner_allowed(r->a0) ||
- ffh_ctxt->info.length > sizeof(*r)) {
- ret = AE_ERROR;
- } else {
- ffh_ctxt->invoke_ffh64_fn(r, r);
- memcpy(value, r, ffh_ctxt->info.length);
- }
- } else {
- ret = AE_ERROR;
- }
-
- return ret;
+ return 0;
}
-#endif /* CONFIG_ACPI_FFH */
+EXPORT_SYMBOL(acpi_unmap_cpu);
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
index e51535a5f939..0c036a9a3c33 100644
--- a/arch/arm64/kernel/acpi_numa.c
+++ b/arch/arm64/kernel/acpi_numa.c
@@ -34,17 +34,6 @@ int __init acpi_numa_get_nid(unsigned int cpu)
return acpi_early_node_map[cpu];
}
-static inline int get_cpu_for_acpi_id(u32 uid)
-{
- int cpu;
-
- for (cpu = 0; cpu < nr_cpu_ids; cpu++)
- if (uid == get_acpi_id_for_cpu(cpu))
- return cpu;
-
- return -EINVAL;
-}
-
static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header,
const unsigned long end)
{
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index dd6ce86d4332..e737c6295ec7 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -462,6 +462,9 @@ static int run_all_insn_set_hw_mode(unsigned int cpu)
for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) {
struct insn_emulation *insn = insn_emulations[i];
bool enable = READ_ONCE(insn->current_mode) == INSN_HW;
+ if (insn->status == INSN_UNAVAILABLE)
+ continue;
+
if (insn->set_hw_mode && insn->set_hw_mode(enable)) {
pr_warn("CPU[%u] cannot support the emulation of %s",
cpu, insn->name);
@@ -504,7 +507,7 @@ static int update_insn_emulation_mode(struct insn_emulation *insn,
return ret;
}
-static int emulation_proc_handler(struct ctl_table *table, int write,
+static int emulation_proc_handler(const struct ctl_table *table, int write,
void *buffer, size_t *lenp,
loff_t *ppos)
{
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 81496083c041..27de1dddb0ab 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -128,6 +128,7 @@ int main(void)
DEFINE(VCPU_FAULT_DISR, offsetof(struct kvm_vcpu, arch.fault.disr_el1));
DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2));
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_cpu_context, regs));
+ DEFINE(CPU_ELR_EL2, offsetof(struct kvm_cpu_context, sys_regs[ELR_EL2]));
DEFINE(CPU_RGSR_EL1, offsetof(struct kvm_cpu_context, sys_regs[RGSR_EL1]));
DEFINE(CPU_GCR_EL1, offsetof(struct kvm_cpu_context, sys_regs[GCR_EL1]));
DEFINE(CPU_APIAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIAKEYLO_EL1]));
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 76b8dd37092a..617424b73f8c 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -432,6 +432,21 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = {
};
#endif
+#ifdef CONFIG_ARM64_ERRATUM_3194386
+static const struct midr_range erratum_spec_ssbs_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+ {}
+};
+#endif
+
const struct arm64_cpu_capabilities arm64_errata[] = {
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
{
@@ -729,6 +744,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
},
#endif
+#ifdef CONFIG_ARM64_ERRATUM_3194386
+ {
+ .desc = "SSBS not fully self-synchronizing",
+ .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
+ ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
+ },
+#endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
{
.desc = "ARM errata 2966298, 3117295",
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 56583677c1f2..646ecd3069fd 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -285,8 +285,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_FP_SHIFT, 4, ID_AA64PFR0_EL1_FP_NI),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL3_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL2_SHIFT, 4, 0),
- ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL1_SHIFT, 4, ID_AA64PFR0_EL1_ELx_64BIT_ONLY),
- ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL0_SHIFT, 4, ID_AA64PFR0_EL1_ELx_64BIT_ONLY),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL1_SHIFT, 4, ID_AA64PFR0_EL1_EL1_IMP),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL0_SHIFT, 4, ID_AA64PFR0_EL1_EL0_IMP),
ARM64_FTR_END,
};
@@ -429,6 +429,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_ECBHB_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_TIDCP1_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_AFP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_HCX_SHIFT, 4, 0),
@@ -2307,6 +2308,14 @@ static void user_feature_fixup(void)
if (regp)
regp->user_mask &= ~ID_AA64ISAR1_EL1_BF16_MASK;
}
+
+ if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) {
+ struct arm64_ftr_reg *regp;
+
+ regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1);
+ if (regp)
+ regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK;
+ }
}
static void elf_hwcap_fixup(void)
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
deleted file mode 100644
index f372295207fb..000000000000
--- a/arch/arm64/kernel/cpuidle.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * ARM64 CPU idle arch support
- *
- * Copyright (C) 2014 ARM Ltd.
- * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
- */
-
-#include <linux/acpi.h>
-#include <linux/cpuidle.h>
-#include <linux/cpu_pm.h>
-#include <linux/psci.h>
-
-#ifdef CONFIG_ACPI_PROCESSOR_IDLE
-
-#include <acpi/processor.h>
-
-#define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags))
-
-static int psci_acpi_cpu_init_idle(unsigned int cpu)
-{
- int i, count;
- struct acpi_lpi_state *lpi;
- struct acpi_processor *pr = per_cpu(processors, cpu);
-
- if (unlikely(!pr || !pr->flags.has_lpi))
- return -EINVAL;
-
- /*
- * If the PSCI cpu_suspend function hook has not been initialized
- * idle states must not be enabled, so bail out
- */
- if (!psci_ops.cpu_suspend)
- return -EOPNOTSUPP;
-
- count = pr->power.count - 1;
- if (count <= 0)
- return -ENODEV;
-
- for (i = 0; i < count; i++) {
- u32 state;
-
- lpi = &pr->power.lpi_states[i + 1];
- /*
- * Only bits[31:0] represent a PSCI power_state while
- * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
- */
- state = lpi->address;
- if (!psci_power_state_is_valid(state)) {
- pr_warn("Invalid PSCI power state %#x\n", state);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-int acpi_processor_ffh_lpi_probe(unsigned int cpu)
-{
- return psci_acpi_cpu_init_idle(cpu);
-}
-
-__cpuidle int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
-{
- u32 state = lpi->address;
-
- if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
- return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM_RCU(psci_cpu_suspend_enter,
- lpi->index, state);
- else
- return CPU_PM_CPU_IDLE_ENTER_PARAM_RCU(psci_cpu_suspend_enter,
- lpi->index, state);
-}
-#endif
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 64f2ecbdfe5c..024a7b245056 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -312,9 +312,7 @@ static int call_break_hook(struct pt_regs *regs, unsigned long esr)
* entirely not preemptible, and we can use rcu list safely here.
*/
list_for_each_entry_rcu(hook, list, node) {
- unsigned long comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
-
- if ((comment & ~hook->mask) == hook->imm)
+ if ((esr_brk_comment(esr) & ~hook->mask) == hook->imm)
fn = hook->fn;
}
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 9afcc690fe73..712718aed5dd 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -9,7 +9,9 @@
#include <linux/efi.h>
#include <linux/init.h>
+#include <linux/kmemleak.h>
#include <linux/screen_info.h>
+#include <linux/vmalloc.h>
#include <asm/efi.h>
#include <asm/stacktrace.h>
@@ -212,6 +214,7 @@ l: if (!p) {
return -ENOMEM;
}
+ kmemleak_not_leak(p);
efi_rt_stack_top = p + THREAD_SIZE;
return 0;
}
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index ebb0158997ca..77006df20a75 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -535,7 +535,7 @@ static unsigned int find_supported_vector_length(enum vec_type type,
#if defined(CONFIG_ARM64_SVE) && defined(CONFIG_SYSCTL)
-static int vec_proc_do_default_vl(struct ctl_table *table, int write,
+static int vec_proc_do_default_vl(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
struct vl_info *info = table->extra1;
@@ -1535,6 +1535,27 @@ static void fpsimd_save_kernel_state(struct task_struct *task)
task->thread.kernel_fpsimd_cpu = smp_processor_id();
}
+/*
+ * Invalidate any task's FPSIMD state that is present on this cpu.
+ * The FPSIMD context should be acquired with get_cpu_fpsimd_context()
+ * before calling this function.
+ */
+static void fpsimd_flush_cpu_state(void)
+{
+ WARN_ON(!system_supports_fpsimd());
+ __this_cpu_write(fpsimd_last_state.st, NULL);
+
+ /*
+ * Leaving streaming mode enabled will cause issues for any kernel
+ * NEON and leaving streaming mode or ZA enabled may increase power
+ * consumption.
+ */
+ if (system_supports_sme())
+ sme_smstop();
+
+ set_thread_flag(TIF_FOREIGN_FPSTATE);
+}
+
void fpsimd_thread_switch(struct task_struct *next)
{
bool wrong_task, wrong_cpu;
@@ -1552,7 +1573,7 @@ void fpsimd_thread_switch(struct task_struct *next)
if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) {
fpsimd_load_kernel_state(next);
- set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
+ fpsimd_flush_cpu_state();
} else {
/*
* Fix up TIF_FOREIGN_FPSTATE to correctly describe next's
@@ -1843,27 +1864,6 @@ void fpsimd_flush_task_state(struct task_struct *t)
}
/*
- * Invalidate any task's FPSIMD state that is present on this cpu.
- * The FPSIMD context should be acquired with get_cpu_fpsimd_context()
- * before calling this function.
- */
-static void fpsimd_flush_cpu_state(void)
-{
- WARN_ON(!system_supports_fpsimd());
- __this_cpu_write(fpsimd_last_state.st, NULL);
-
- /*
- * Leaving streaming mode enabled will cause issues for any kernel
- * NEON and leaving streaming mode or ZA enabled may increase power
- * consumption.
- */
- if (system_supports_sme())
- sme_smstop();
-
- set_thread_flag(TIF_FOREIGN_FPSTATE);
-}
-
-/*
* Save the FPSIMD state to memory and invalidate cpu view.
* This function must be called with preemption disabled.
*/
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 2f5755192c2b..722ac45f9f7b 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -655,7 +655,7 @@ static int breakpoint_handler(unsigned long unused, unsigned long esr,
perf_bp_event(bp, regs);
/* Do we need to handle the stepping? */
- if (uses_default_overflow_handler(bp))
+ if (is_default_overflow_handler(bp))
step = 1;
unlock:
rcu_read_unlock();
@@ -734,7 +734,7 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val,
static int watchpoint_report(struct perf_event *wp, unsigned long addr,
struct pt_regs *regs)
{
- int step = uses_default_overflow_handler(wp);
+ int step = is_default_overflow_handler(wp);
struct arch_hw_breakpoint *info = counter_arch_bp(wp);
info->trigger = addr;
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index ba4f8f7d6a91..8f5422ed1b75 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -105,11 +105,6 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
-#ifdef CONFIG_ARM64_PSEUDO_NMI
-/* Static key checked in GIC_PRIO_IRQOFF. */
-KVM_NVHE_ALIAS(gic_nonsecure_priorities);
-#endif
-
/* EL2 exception handling */
KVM_NVHE_ALIAS(__start___kvm_ex_table);
KVM_NVHE_ALIAS(__stop___kvm_ex_table);
diff --git a/arch/arm64/kernel/io.c b/arch/arm64/kernel/io.c
index aa7a4ec6a3ae..ef48089fbfe1 100644
--- a/arch/arm64/kernel/io.c
+++ b/arch/arm64/kernel/io.c
@@ -38,6 +38,48 @@ void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
EXPORT_SYMBOL(__memcpy_fromio);
/*
+ * This generates a memcpy that works on a from/to address which is aligned to
+ * bits. Count is in terms of the number of bits sized quantities to copy. It
+ * optimizes to use the STR groupings when possible so that it is WC friendly.
+ */
+#define memcpy_toio_aligned(to, from, count, bits) \
+ ({ \
+ volatile u##bits __iomem *_to = to; \
+ const u##bits *_from = from; \
+ size_t _count = count; \
+ const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
+ \
+ for (; _from < _end_from; _from += 8, _to += 8) \
+ __const_memcpy_toio_aligned##bits(_to, _from, 8); \
+ if ((_count % 8) >= 4) { \
+ __const_memcpy_toio_aligned##bits(_to, _from, 4); \
+ _from += 4; \
+ _to += 4; \
+ } \
+ if ((_count % 4) >= 2) { \
+ __const_memcpy_toio_aligned##bits(_to, _from, 2); \
+ _from += 2; \
+ _to += 2; \
+ } \
+ if (_count % 2) \
+ __const_memcpy_toio_aligned##bits(_to, _from, 1); \
+ })
+
+void __iowrite64_copy_full(void __iomem *to, const void *from, size_t count)
+{
+ memcpy_toio_aligned(to, from, count, 64);
+ dgh();
+}
+EXPORT_SYMBOL(__iowrite64_copy_full);
+
+void __iowrite32_copy_full(void __iomem *to, const void *from, size_t count)
+{
+ memcpy_toio_aligned(to, from, count, 32);
+ dgh();
+}
+EXPORT_SYMBOL(__iowrite32_copy_full);
+
+/*
* Copy data from "real" memory space to IO memory space.
*/
void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 47e0be610bb6..36b25af56324 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -12,144 +12,18 @@
#include <linux/bitops.h>
#include <linux/elf.h>
#include <linux/ftrace.h>
-#include <linux/gfp.h>
#include <linux/kasan.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/moduleloader.h>
#include <linux/random.h>
#include <linux/scs.h>
-#include <linux/vmalloc.h>
#include <asm/alternative.h>
#include <asm/insn.h>
#include <asm/scs.h>
#include <asm/sections.h>
-static u64 module_direct_base __ro_after_init = 0;
-static u64 module_plt_base __ro_after_init = 0;
-
-/*
- * Choose a random page-aligned base address for a window of 'size' bytes which
- * entirely contains the interval [start, end - 1].
- */
-static u64 __init random_bounding_box(u64 size, u64 start, u64 end)
-{
- u64 max_pgoff, pgoff;
-
- if ((end - start) >= size)
- return 0;
-
- max_pgoff = (size - (end - start)) / PAGE_SIZE;
- pgoff = get_random_u32_inclusive(0, max_pgoff);
-
- return start - pgoff * PAGE_SIZE;
-}
-
-/*
- * Modules may directly reference data and text anywhere within the kernel
- * image and other modules. References using PREL32 relocations have a +/-2G
- * range, and so we need to ensure that the entire kernel image and all modules
- * fall within a 2G window such that these are always within range.
- *
- * Modules may directly branch to functions and code within the kernel text,
- * and to functions and code within other modules. These branches will use
- * CALL26/JUMP26 relocations with a +/-128M range. Without PLTs, we must ensure
- * that the entire kernel text and all module text falls within a 128M window
- * such that these are always within range. With PLTs, we can expand this to a
- * 2G window.
- *
- * We chose the 128M region to surround the entire kernel image (rather than
- * just the text) as using the same bounds for the 128M and 2G regions ensures
- * by construction that we never select a 128M region that is not a subset of
- * the 2G region. For very large and unusual kernel configurations this means
- * we may fall back to PLTs where they could have been avoided, but this keeps
- * the logic significantly simpler.
- */
-static int __init module_init_limits(void)
-{
- u64 kernel_end = (u64)_end;
- u64 kernel_start = (u64)_text;
- u64 kernel_size = kernel_end - kernel_start;
-
- /*
- * The default modules region is placed immediately below the kernel
- * image, and is large enough to use the full 2G relocation range.
- */
- BUILD_BUG_ON(KIMAGE_VADDR != MODULES_END);
- BUILD_BUG_ON(MODULES_VSIZE < SZ_2G);
-
- if (!kaslr_enabled()) {
- if (kernel_size < SZ_128M)
- module_direct_base = kernel_end - SZ_128M;
- if (kernel_size < SZ_2G)
- module_plt_base = kernel_end - SZ_2G;
- } else {
- u64 min = kernel_start;
- u64 max = kernel_end;
-
- if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
- pr_info("2G module region forced by RANDOMIZE_MODULE_REGION_FULL\n");
- } else {
- module_direct_base = random_bounding_box(SZ_128M, min, max);
- if (module_direct_base) {
- min = module_direct_base;
- max = module_direct_base + SZ_128M;
- }
- }
-
- module_plt_base = random_bounding_box(SZ_2G, min, max);
- }
-
- pr_info("%llu pages in range for non-PLT usage",
- module_direct_base ? (SZ_128M - kernel_size) / PAGE_SIZE : 0);
- pr_info("%llu pages in range for PLT usage",
- module_plt_base ? (SZ_2G - kernel_size) / PAGE_SIZE : 0);
-
- return 0;
-}
-subsys_initcall(module_init_limits);
-
-void *module_alloc(unsigned long size)
-{
- void *p = NULL;
-
- /*
- * Where possible, prefer to allocate within direct branch range of the
- * kernel such that no PLTs are necessary.
- */
- if (module_direct_base) {
- p = __vmalloc_node_range(size, MODULE_ALIGN,
- module_direct_base,
- module_direct_base + SZ_128M,
- GFP_KERNEL | __GFP_NOWARN,
- PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
- }
-
- if (!p && module_plt_base) {
- p = __vmalloc_node_range(size, MODULE_ALIGN,
- module_plt_base,
- module_plt_base + SZ_2G,
- GFP_KERNEL | __GFP_NOWARN,
- PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
- }
-
- if (!p) {
- pr_warn_ratelimited("%s: unable to allocate memory\n",
- __func__);
- }
-
- if (p && (kasan_alloc_module_shadow(p, size, GFP_KERNEL) < 0)) {
- vfree(p);
- return NULL;
- }
-
- /* Memory is intended to be executable, reset the pointer tag. */
- return kasan_reset_tag(p);
-}
-
enum aarch64_reloc_op {
RELOC_OP_NONE,
RELOC_OP_ABS,
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index dcdcccd40891..6174671be7c1 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -582,12 +582,9 @@ subsys_initcall(register_mte_tcf_preferred_sysctl);
size_t mte_probe_user_range(const char __user *uaddr, size_t size)
{
const char __user *end = uaddr + size;
- int err = 0;
char val;
- __raw_get_user(val, uaddr, err);
- if (err)
- return size;
+ __raw_get_user(val, uaddr, efault);
uaddr = PTR_ALIGN(uaddr, MTE_GRANULE_SIZE);
while (uaddr < end) {
@@ -595,12 +592,13 @@ size_t mte_probe_user_range(const char __user *uaddr, size_t size)
* A read is sufficient for mte, the caller should have probed
* for the pte write permission if required.
*/
- __raw_get_user(val, uaddr, err);
- if (err)
- return end - uaddr;
+ __raw_get_user(val, uaddr, efault);
uaddr += MTE_GRANULE_SIZE;
}
(void)val;
return 0;
+
+efault:
+ return end - uaddr;
}
diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
index 255534930368..945df74005c7 100644
--- a/arch/arm64/kernel/patching.c
+++ b/arch/arm64/kernel/patching.c
@@ -36,7 +36,7 @@ static void __kprobes *patch_map(void *addr, int fixmap)
if (image)
page = phys_to_page(__pa_symbol(addr));
- else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
+ else if (IS_ENABLED(CONFIG_EXECMEM))
page = vmalloc_to_page(addr);
else
return addr;
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 6d157f32187b..e8ed5673f481 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -10,94 +10,12 @@
#include <asm/pointer_auth.h>
-struct frame_tail {
- struct frame_tail __user *fp;
- unsigned long lr;
-} __attribute__((packed));
-
-/*
- * Get the return address for a single stackframe and return a pointer to the
- * next frame tail.
- */
-static struct frame_tail __user *
-user_backtrace(struct frame_tail __user *tail,
- struct perf_callchain_entry_ctx *entry)
-{
- struct frame_tail buftail;
- unsigned long err;
- unsigned long lr;
-
- /* Also check accessibility of one struct frame_tail beyond */
- if (!access_ok(tail, sizeof(buftail)))
- return NULL;
-
- pagefault_disable();
- err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
- pagefault_enable();
-
- if (err)
- return NULL;
-
- lr = ptrauth_strip_user_insn_pac(buftail.lr);
-
- perf_callchain_store(entry, lr);
-
- /*
- * Frame pointers should strictly progress back up the stack
- * (towards higher addresses).
- */
- if (tail >= buftail.fp)
- return NULL;
-
- return buftail.fp;
-}
-
-#ifdef CONFIG_COMPAT
-/*
- * The registers we're interested in are at the end of the variable
- * length saved register structure. The fp points at the end of this
- * structure so the address of this struct is:
- * (struct compat_frame_tail *)(xxx->fp)-1
- *
- * This code has been adapted from the ARM OProfile support.
- */
-struct compat_frame_tail {
- compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */
- u32 sp;
- u32 lr;
-} __attribute__((packed));
-
-static struct compat_frame_tail __user *
-compat_user_backtrace(struct compat_frame_tail __user *tail,
- struct perf_callchain_entry_ctx *entry)
+static bool callchain_trace(void *data, unsigned long pc)
{
- struct compat_frame_tail buftail;
- unsigned long err;
-
- /* Also check accessibility of one struct frame_tail beyond */
- if (!access_ok(tail, sizeof(buftail)))
- return NULL;
-
- pagefault_disable();
- err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
- pagefault_enable();
-
- if (err)
- return NULL;
-
- perf_callchain_store(entry, buftail.lr);
-
- /*
- * Frame pointers should strictly progress back up the stack
- * (towards higher addresses).
- */
- if (tail + 1 >= (struct compat_frame_tail __user *)
- compat_ptr(buftail.fp))
- return NULL;
+ struct perf_callchain_entry_ctx *entry = data;
- return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
+ return perf_callchain_store(entry, pc) == 0;
}
-#endif /* CONFIG_COMPAT */
void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
struct pt_regs *regs)
@@ -107,35 +25,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
return;
}
- perf_callchain_store(entry, regs->pc);
-
- if (!compat_user_mode(regs)) {
- /* AARCH64 mode */
- struct frame_tail __user *tail;
-
- tail = (struct frame_tail __user *)regs->regs[29];
-
- while (entry->nr < entry->max_stack &&
- tail && !((unsigned long)tail & 0x7))
- tail = user_backtrace(tail, entry);
- } else {
-#ifdef CONFIG_COMPAT
- /* AARCH32 compat mode */
- struct compat_frame_tail __user *tail;
-
- tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
-
- while ((entry->nr < entry->max_stack) &&
- tail && !((unsigned long)tail & 0x3))
- tail = compat_user_backtrace(tail, entry);
-#endif
- }
-}
-
-static bool callchain_trace(void *data, unsigned long pc)
-{
- struct perf_callchain_entry_ctx *entry = data;
- return perf_callchain_store(entry, pc) == 0;
+ arch_stack_walk_user(callchain_trace, entry, regs);
}
void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index 4393b41f0b71..4d11a8c29181 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -19,12 +19,6 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS))
# disable LTO
KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
-GCOV_PROFILE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-UBSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-
hostprogs := relacheck
quiet_cmd_piobjcopy = $(quiet_cmd_objcopy)
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index aad399796e81..29d4b6244a6f 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -108,6 +108,7 @@ static const struct ftr_set_desc pfr0 __prel64_initconst = {
.override = &id_aa64pfr0_override,
.fields = {
FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter),
+ FIELD("el0", ID_AA64PFR0_EL1_EL0_SHIFT, NULL),
{}
},
};
@@ -209,8 +210,8 @@ static const struct {
char alias[FTR_ALIAS_NAME_LEN];
char feature[FTR_ALIAS_OPTION_LEN];
} aliases[] __initconst = {
- { "kvm_arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
- { "kvm_arm.mode=protected", "id_aa64mmfr1.vh=0" },
+ { "kvm_arm.mode=nvhe", "arm64_sw.hvhe=0 id_aa64mmfr1.vh=0" },
+ { "kvm_arm.mode=protected", "arm64_sw.hvhe=1" },
{ "arm64.nosve", "id_aa64pfr0.sve=0" },
{ "arm64.nosme", "id_aa64pfr1.sme=0" },
{ "arm64.nobti", "id_aa64pfr1.bt=0" },
@@ -223,6 +224,7 @@ static const struct {
{ "nokaslr", "arm64_sw.nokaslr=1" },
{ "rodata=off", "arm64_sw.rodataoff=1" },
{ "arm64.nolva", "id_aa64mmfr2.varange=0" },
+ { "arm64.no32bit_el0", "id_aa64pfr0.el0=1" },
};
static int __init parse_hexdigit(const char *p, u64 *v)
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index 5fa08e13e17e..f374a3e5a5fe 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -173,7 +173,7 @@ static void __init remap_idmap_for_lpa2(void)
* Don't bother with the FDT, we no longer need it after this.
*/
memset(init_idmap_pg_dir, 0,
- (u64)init_idmap_pg_dir - (u64)init_idmap_pg_end);
+ (u64)init_idmap_pg_end - (u64)init_idmap_pg_dir);
create_init_idmap(init_idmap_pg_dir, mask);
dsb(ishst);
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 327855a11df2..4268678d0e86 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -129,13 +129,6 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
return 0;
}
-void *alloc_insn_page(void)
-{
- return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
- GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
- NUMA_NO_NODE, __builtin_return_address(0));
-}
-
/* arm kprobe: install breakpoint in text */
void __kprobes arch_arm_kprobe(struct kprobe *p)
{
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 6268a13a1d58..da53722f95d4 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -558,6 +558,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void)
/* SCTLR_EL1.DSSBS was initialised to 0 during boot */
set_pstate_ssbs(0);
+
+ /*
+ * SSBS is self-synchronizing and is intended to affect subsequent
+ * speculative instructions, but some CPUs can speculate with a stale
+ * value of SSBS.
+ *
+ * Mitigate this with an unconditional speculation barrier, as CPUs
+ * could mis-speculate branches and bypass a conditional barrier.
+ */
+ if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386))
+ spec_bar();
+
return SPECTRE_MITIGATED;
}
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 29a8e444db83..fabd732d0a2d 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -40,7 +40,7 @@ static int cpu_psci_cpu_boot(unsigned int cpu)
{
phys_addr_t pa_secondary_entry = __pa_symbol(secondary_entry);
int err = psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry);
- if (err)
+ if (err && err != -EPERM)
pr_err("failed to boot CPU%d (%d)\n", cpu, err);
return err;
diff --git a/arch/arm64/kernel/reloc_test_core.c b/arch/arm64/kernel/reloc_test_core.c
index 99f2ffe9fc05..5b0891146054 100644
--- a/arch/arm64/kernel/reloc_test_core.c
+++ b/arch/arm64/kernel/reloc_test_core.c
@@ -74,4 +74,5 @@ static void __exit reloc_test_exit(void)
module_init(reloc_test_init);
module_exit(reloc_test_exit);
+MODULE_DESCRIPTION("Relocation testing module");
MODULE_LICENSE("GPL v2");
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 65a052bf741f..a096e2451044 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -298,8 +298,15 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
dynamic_scs_init();
/*
- * Unmask SError as soon as possible after initializing earlycon so
- * that we can report any SErrors immediately.
+ * The primary CPU enters the kernel with all DAIF exceptions masked.
+ *
+ * We must unmask Debug and SError before preemption or scheduling is
+ * possible to ensure that these are consistently unmasked across
+ * threads, and we want to unmask SError as soon as possible after
+ * initializing earlycon so that we can report any SErrors immediately.
+ *
+ * IRQ and FIQ will be unmasked after the root irqchip has been
+ * detected and initialized.
*/
local_daif_restore(DAIF_PROCCTX_NOIRQ);
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index bbd542704730..81e798b6dada 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -17,7 +17,7 @@
#include <asm/signal32.h>
#include <asm/traps.h>
#include <linux/uaccess.h>
-#include <asm/unistd.h>
+#include <asm/unistd_compat_32.h>
#include <asm/vdso.h>
struct compat_vfp_sigframe {
@@ -451,7 +451,7 @@ int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
void compat_setup_restart_syscall(struct pt_regs *regs)
{
- regs->regs[7] = __NR_compat_restart_syscall;
+ regs->regs[7] = __NR_compat32_restart_syscall;
}
/*
diff --git a/arch/arm64/kernel/sigreturn32.S b/arch/arm64/kernel/sigreturn32.S
index ccbd4aab4ba4..6f486b95b413 100644
--- a/arch/arm64/kernel/sigreturn32.S
+++ b/arch/arm64/kernel/sigreturn32.S
@@ -13,7 +13,7 @@
* need two 16-bit instructions.
*/
-#include <asm/unistd.h>
+#include <asm/unistd_compat_32.h>
.section .rodata
.globl __aarch32_sigret_code_start
@@ -22,26 +22,26 @@ __aarch32_sigret_code_start:
/*
* ARM Code
*/
- .byte __NR_compat_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_sigreturn
- .byte __NR_compat_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_sigreturn
+ .byte __NR_compat32_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat32_sigreturn
+ .byte __NR_compat32_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat32_sigreturn
/*
* Thumb code
*/
- .byte __NR_compat_sigreturn, 0x27 // svc #__NR_compat_sigreturn
- .byte __NR_compat_sigreturn, 0xdf // mov r7, #__NR_compat_sigreturn
+ .byte __NR_compat32_sigreturn, 0x27 // svc #__NR_compat32_sigreturn
+ .byte __NR_compat32_sigreturn, 0xdf // mov r7, #__NR_compat32_sigreturn
/*
* ARM code
*/
- .byte __NR_compat_rt_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_rt_sigreturn
- .byte __NR_compat_rt_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_rt_sigreturn
+ .byte __NR_compat32_rt_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat32_rt_sigreturn
+ .byte __NR_compat32_rt_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat32_rt_sigreturn
/*
* Thumb code
*/
- .byte __NR_compat_rt_sigreturn, 0x27 // svc #__NR_compat_rt_sigreturn
- .byte __NR_compat_rt_sigreturn, 0xdf // mov r7, #__NR_compat_rt_sigreturn
+ .byte __NR_compat32_rt_sigreturn, 0x27 // svc #__NR_compat32_rt_sigreturn
+ .byte __NR_compat32_rt_sigreturn, 0xdf // mov r7, #__NR_compat32_rt_sigreturn
.globl __aarch32_sigret_code_end
__aarch32_sigret_code_end:
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 4ced34f62dab..5e18fbcee9a2 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -55,9 +55,6 @@
#include <trace/events/ipi.h>
-DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
-EXPORT_PER_CPU_SYMBOL(cpu_number);
-
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -132,7 +129,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
/* Now bring the CPU into our world */
ret = boot_secondary(cpu, idle);
if (ret) {
- pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
+ if (ret != -EPERM)
+ pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
return ret;
}
@@ -264,6 +262,13 @@ asmlinkage notrace void secondary_start_kernel(void)
set_cpu_online(cpu, true);
complete(&cpu_running);
+ /*
+ * Secondary CPUs enter the kernel with all DAIF exceptions masked.
+ *
+ * As with setup_arch() we must unmask Debug and SError exceptions, and
+ * as the root irqchip has already been detected and initialized we can
+ * unmask IRQ and FIQ at the same time.
+ */
local_daif_restore(DAIF_PROCCTX);
/*
@@ -503,6 +508,59 @@ static int __init smp_cpu_setup(int cpu)
static bool bootcpu_valid __initdata;
static unsigned int cpu_count = 1;
+int arch_register_cpu(int cpu)
+{
+ acpi_handle acpi_handle = acpi_get_processor_handle(cpu);
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+
+ if (!acpi_disabled && !acpi_handle &&
+ IS_ENABLED(CONFIG_ACPI_HOTPLUG_CPU))
+ return -EPROBE_DEFER;
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+ /* For now block anything that looks like physical CPU Hotplug */
+ if (invalid_logical_cpuid(cpu) || !cpu_present(cpu)) {
+ pr_err_once("Changing CPU present bit is not supported\n");
+ return -ENODEV;
+ }
+#endif
+
+ /*
+ * Availability of the acpi handle is sufficient to establish
+ * that _STA has aleady been checked. No need to recheck here.
+ */
+ c->hotpluggable = arch_cpu_is_hotpluggable(cpu);
+
+ return register_cpu(c, cpu);
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+void arch_unregister_cpu(int cpu)
+{
+ acpi_handle acpi_handle = acpi_get_processor_handle(cpu);
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+ acpi_status status;
+ unsigned long long sta;
+
+ if (!acpi_handle) {
+ pr_err_once("Removing a CPU without associated ACPI handle\n");
+ return;
+ }
+
+ status = acpi_evaluate_integer(acpi_handle, "_STA", NULL, &sta);
+ if (ACPI_FAILURE(status))
+ return;
+
+ /* For now do not allow anything that looks like physical CPU HP */
+ if (cpu_present(cpu) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
+ pr_err_once("Changing CPU present bit is not supported\n");
+ return;
+ }
+
+ unregister_cpu(c);
+}
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
#ifdef CONFIG_ACPI
static struct acpi_madt_generic_interrupt cpu_madt_gicc[NR_CPUS];
@@ -523,7 +581,8 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
{
u64 hwid = processor->arm_mpidr;
- if (!acpi_gicc_is_usable(processor)) {
+ if (!(processor->flags &
+ (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) {
pr_debug("skipping disabled CPU entry with 0x%llx MPIDR\n", hwid);
return;
}
@@ -742,8 +801,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
*/
for_each_possible_cpu(cpu) {
- per_cpu(cpu_number, cpu) = cpu;
-
if (cpu == smp_processor_id())
continue;
@@ -760,13 +817,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
}
-static const char *ipi_types[NR_IPI] __tracepoint_string = {
+static const char *ipi_types[MAX_IPI] __tracepoint_string = {
[IPI_RESCHEDULE] = "Rescheduling interrupts",
[IPI_CALL_FUNC] = "Function call interrupts",
[IPI_CPU_STOP] = "CPU stop interrupts",
[IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts",
[IPI_TIMER] = "Timer broadcast interrupts",
[IPI_IRQ_WORK] = "IRQ work interrupts",
+ [IPI_CPU_BACKTRACE] = "CPU backtrace interrupts",
+ [IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts",
};
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
@@ -777,7 +836,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
{
unsigned int cpu, i;
- for (i = 0; i < NR_IPI; i++) {
+ for (i = 0; i < MAX_IPI; i++) {
seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
prec >= 4 ? " " : "");
for_each_online_cpu(cpu)
@@ -1021,12 +1080,12 @@ void __init set_smp_ipi_range(int ipi_base, int n)
if (ipi_should_be_nmi(i)) {
err = request_percpu_nmi(ipi_base + i, ipi_handler,
- "IPI", &cpu_number);
+ "IPI", &irq_stat);
WARN(err, "Could not request IPI %d as NMI, err=%d\n",
i, err);
} else {
err = request_percpu_irq(ipi_base + i, ipi_handler,
- "IPI", &cpu_number);
+ "IPI", &irq_stat);
WARN(err, "Could not request IPI %d as IRQ, err=%d\n",
i, err);
}
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 684c26511696..6b3258860377 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -324,3 +324,123 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
dump_backtrace(NULL, tsk, loglvl);
barrier();
}
+
+/*
+ * The struct defined for userspace stack frame in AARCH64 mode.
+ */
+struct frame_tail {
+ struct frame_tail __user *fp;
+ unsigned long lr;
+} __attribute__((packed));
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static struct frame_tail __user *
+unwind_user_frame(struct frame_tail __user *tail, void *cookie,
+ stack_trace_consume_fn consume_entry)
+{
+ struct frame_tail buftail;
+ unsigned long err;
+ unsigned long lr;
+
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(tail, sizeof(buftail)))
+ return NULL;
+
+ pagefault_disable();
+ err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
+ pagefault_enable();
+
+ if (err)
+ return NULL;
+
+ lr = ptrauth_strip_user_insn_pac(buftail.lr);
+
+ if (!consume_entry(cookie, lr))
+ return NULL;
+
+ /*
+ * Frame pointers should strictly progress back up the stack
+ * (towards higher addresses).
+ */
+ if (tail >= buftail.fp)
+ return NULL;
+
+ return buftail.fp;
+}
+
+#ifdef CONFIG_COMPAT
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct compat_frame_tail *)(xxx->fp)-1
+ *
+ * This code has been adapted from the ARM OProfile support.
+ */
+struct compat_frame_tail {
+ compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */
+ u32 sp;
+ u32 lr;
+} __attribute__((packed));
+
+static struct compat_frame_tail __user *
+unwind_compat_user_frame(struct compat_frame_tail __user *tail, void *cookie,
+ stack_trace_consume_fn consume_entry)
+{
+ struct compat_frame_tail buftail;
+ unsigned long err;
+
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(tail, sizeof(buftail)))
+ return NULL;
+
+ pagefault_disable();
+ err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
+ pagefault_enable();
+
+ if (err)
+ return NULL;
+
+ if (!consume_entry(cookie, buftail.lr))
+ return NULL;
+
+ /*
+ * Frame pointers should strictly progress back up the stack
+ * (towards higher addresses).
+ */
+ if (tail + 1 >= (struct compat_frame_tail __user *)
+ compat_ptr(buftail.fp))
+ return NULL;
+
+ return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
+}
+#endif /* CONFIG_COMPAT */
+
+
+void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
+ const struct pt_regs *regs)
+{
+ if (!consume_entry(cookie, regs->pc))
+ return;
+
+ if (!compat_user_mode(regs)) {
+ /* AARCH64 mode */
+ struct frame_tail __user *tail;
+
+ tail = (struct frame_tail __user *)regs->regs[29];
+ while (tail && !((unsigned long)tail & 0x7))
+ tail = unwind_user_frame(tail, cookie, consume_entry);
+ } else {
+#ifdef CONFIG_COMPAT
+ /* AARCH32 compat mode */
+ struct compat_frame_tail __user *tail;
+
+ tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
+ while (tail && !((unsigned long)tail & 0x3))
+ tail = unwind_compat_user_frame(tail, cookie, consume_entry);
+#endif
+ }
+}
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index d5ffaaab31a7..f08408b6e826 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -48,14 +48,16 @@ asmlinkage long __arm64_sys_ni_syscall(const struct pt_regs *__unused)
*/
#define __arm64_sys_personality __arm64_sys_arm64_personality
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+
#undef __SYSCALL
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
-#include <asm/unistd.h>
+#include <asm/syscall_table_64.h>
#undef __SYSCALL
#define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
const syscall_fn_t sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table_64.h>
};
diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c
index fc40386afb1b..96bcfb907443 100644
--- a/arch/arm64/kernel/sys32.c
+++ b/arch/arm64/kernel/sys32.c
@@ -5,17 +5,12 @@
* Copyright (C) 2015 ARM Ltd.
*/
-/*
- * Needed to avoid conflicting __NR_* macros between uapi/asm/unistd.h and
- * asm/unistd32.h.
- */
-#define __COMPAT_SYSCALL_NR
-
#include <linux/compat.h>
#include <linux/compiler.h>
#include <linux/syscalls.h>
#include <asm/syscall.h>
+#include <asm/unistd_compat_32.h>
asmlinkage long compat_sys_sigreturn(void);
asmlinkage long compat_sys_rt_sigreturn(void);
@@ -122,14 +117,16 @@ COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
}
+#define __SYSCALL_WITH_COMPAT(nr, sym, compat) __SYSCALL(nr, compat)
+
#undef __SYSCALL
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
-#include <asm/unistd32.h>
+#include <asm/syscall_table_32.h>
#undef __SYSCALL
#define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
-const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = {
- [0 ... __NR_compat_syscalls - 1] = __arm64_sys_ni_syscall,
-#include <asm/unistd32.h>
+const syscall_fn_t compat_sys_call_table[__NR_compat32_syscalls] = {
+ [0 ... __NR_compat32_syscalls - 1] = __arm64_sys_ni_syscall,
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index ad198262b981..c442fcec6b9e 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -14,6 +14,7 @@
#include <asm/syscall.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
+#include <asm/unistd_compat_32.h>
long compat_arm_syscall(struct pt_regs *regs, int scno);
long sys_ni_syscall(void);
@@ -53,17 +54,15 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
syscall_set_return_value(current, regs, 0, ret);
/*
- * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(),
- * but not enough for arm64 stack utilization comfort. To keep
- * reasonable stack head room, reduce the maximum offset to 9 bits.
+ * This value will get limited by KSTACK_OFFSET_MAX(), which is 10
+ * bits. The actual entropy will be further reduced by the compiler
+ * when applying stack alignment constraints: the AAPCS mandates a
+ * 16-byte aligned SP at function boundaries, which will remove the
+ * 4 low bits from any entropy chosen here.
*
- * The actual entropy will be further reduced by the compiler when
- * applying stack alignment constraints: the AAPCS mandates a
- * 16-byte (i.e. 4-bit) aligned SP at function boundaries.
- *
- * The resulting 5 bits of entropy is seen in SP[8:4].
+ * The resulting 6 bits of entropy is seen in SP[9:4].
*/
- choose_random_kstack_offset(get_random_u16() & 0x1FF);
+ choose_random_kstack_offset(get_random_u16());
}
static inline bool has_syscall_work(unsigned long flags)
@@ -155,7 +154,7 @@ void do_el0_svc(struct pt_regs *regs)
#ifdef CONFIG_COMPAT
void do_el0_svc_compat(struct pt_regs *regs)
{
- el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
+ el0_svc_common(regs, regs->regs[7], __NR_compat32_syscalls,
compat_sys_call_table);
}
#endif
diff --git a/arch/arm64/kernel/trace-events-emulation.h b/arch/arm64/kernel/trace-events-emulation.h
index 6c40f58b844a..c51b547b583e 100644
--- a/arch/arm64/kernel/trace-events-emulation.h
+++ b/arch/arm64/kernel/trace-events-emulation.h
@@ -18,7 +18,7 @@ TRACE_EVENT(instruction_emulation,
),
TP_fast_assign(
- __assign_str(instr, instr);
+ __assign_str(instr);
__entry->addr = addr;
),
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 215e6d7f2df8..9e22683aa921 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -1105,8 +1105,6 @@ static struct break_hook ubsan_break_hook = {
};
#endif
-#define esr_comment(esr) ((esr) & ESR_ELx_BRK64_ISS_COMMENT_MASK)
-
/*
* Initial handler for AArch64 BRK exceptions
* This handler only used until debug_traps_init().
@@ -1115,15 +1113,15 @@ int __init early_brk64(unsigned long addr, unsigned long esr,
struct pt_regs *regs)
{
#ifdef CONFIG_CFI_CLANG
- if ((esr_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE)
+ if (esr_is_cfi_brk(esr))
return cfi_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
#ifdef CONFIG_KASAN_SW_TAGS
- if ((esr_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM)
+ if ((esr_brk_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM)
return kasan_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
#ifdef CONFIG_UBSAN_TRAP
- if ((esr_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM)
+ if ((esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM)
return ubsan_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
return bug_handler(regs, esr) != DBG_HOOK_HANDLED;
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index 8818287f1095..d11da6461278 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -21,7 +21,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti
# potential future proofing if we end up with internal calls to the exported
# routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so
# preparation in build-time C")).
-ldflags-y := -shared -soname=linux-vdso.so.1 --hash-style=sysv \
+ldflags-y := -shared -soname=linux-vdso.so.1 \
-Bsymbolic --build-id=sha1 -n $(btildflags-y)
ifdef CONFIG_LD_ORPHAN_WARN
@@ -40,11 +40,6 @@ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
$(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) \
$(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
-Wmissing-prototypes -Wmissing-declarations
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-UBSAN_SANITIZE := n
-OBJECT_FILES_NON_STANDARD := y
-KCOV_INSTRUMENT := n
CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -fasynchronous-unwind-tables
@@ -52,9 +47,6 @@ ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
endif
-# Disable gcov profiling for VDSO code
-GCOV_PROFILE := n
-
targets += vdso.lds
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
@@ -68,7 +60,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index f5f80fdce0fe..25a2cb6317f3 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -98,7 +98,7 @@ VDSO_AFLAGS += -D__ASSEMBLY__
# From arm vDSO Makefile
VDSO_LDFLAGS += -Bsymbolic --no-undefined -soname=linux-vdso.so.1
VDSO_LDFLAGS += -z max-page-size=4096 -z common-page-size=4096
-VDSO_LDFLAGS += -shared --hash-style=sysv --build-id=sha1
+VDSO_LDFLAGS += -shared --build-id=sha1
VDSO_LDFLAGS += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
@@ -136,7 +136,7 @@ $(obj)/vdso32.so.dbg: $(obj)/vdso.so.raw $(obj)/$(munge) FORCE
$(call if_changed,vdsomunge)
# Link rule for the .so file, .lds has to be first
-$(obj)/vdso.so.raw: $(src)/vdso.lds $(obj-vdso) FORCE
+$(obj)/vdso.so.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,vdsold_and_vdso_check)
# Compilation rules for the vDSO sources
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 755a22d4f840..55a8e310ea12 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -264,6 +264,9 @@ SECTIONS
EXIT_DATA
}
+ RUNTIME_CONST(shift, d_hash_shift)
+ RUNTIME_CONST(ptr, dentry_hashtable)
+
PERCPU_SECTION(L1_CACHE_BYTES)
HYPERVISOR_PERCPU_SECTION
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index c0c050e53157..a6497228c5a8 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -3,7 +3,7 @@
# Makefile for Kernel-based Virtual Machine module
#
-ccflags-y += -I $(srctree)/$(src)
+ccflags-y += -I $(src)
include $(srctree)/virt/kvm/Makefile.kvm
@@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
vgic/vgic-its.o vgic/vgic-debug.o
kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o pmu.o
+kvm-$(CONFIG_ARM64_PTR_AUTH) += pauth.o
always-y := hyp_constants.h hyp-constants.s
@@ -30,7 +31,7 @@ define rule_gen_hyp_constants
$(call filechk,offsets,__HYP_CONSTANTS_H__)
endef
-CFLAGS_hyp-constants.o = -I $(srctree)/$(src)/hyp/include
+CFLAGS_hyp-constants.o = -I $(src)/hyp/include
$(obj)/hyp-constants.s: $(src)/hyp/hyp-constants.c FORCE
$(call if_changed_dep,cc_s_c)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index c4a0a35e02c7..a7ca776b51ec 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -35,10 +35,11 @@
#include <asm/virt.h>
#include <asm/kvm_arm.h>
#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_nested.h>
#include <asm/kvm_pkvm.h>
-#include <asm/kvm_emulate.h>
+#include <asm/kvm_ptrauth.h>
#include <asm/sections.h>
#include <kvm/arm_hypercalls.h>
@@ -47,6 +48,15 @@
static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;
+enum kvm_wfx_trap_policy {
+ KVM_WFX_NOTRAP_SINGLE_TASK, /* Default option */
+ KVM_WFX_NOTRAP,
+ KVM_WFX_TRAP,
+};
+
+static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
+static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
+
DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
@@ -69,15 +79,42 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
}
+/*
+ * This functions as an allow-list of protected VM capabilities.
+ * Features not explicitly allowed by this function are denied.
+ */
+static bool pkvm_ext_allowed(struct kvm *kvm, long ext)
+{
+ switch (ext) {
+ case KVM_CAP_IRQCHIP:
+ case KVM_CAP_ARM_PSCI:
+ case KVM_CAP_ARM_PSCI_0_2:
+ case KVM_CAP_NR_VCPUS:
+ case KVM_CAP_MAX_VCPUS:
+ case KVM_CAP_MAX_VCPU_ID:
+ case KVM_CAP_MSI_DEVID:
+ case KVM_CAP_ARM_VM_IPA_SIZE:
+ case KVM_CAP_ARM_PMU_V3:
+ case KVM_CAP_ARM_SVE:
+ case KVM_CAP_ARM_PTRAUTH_ADDRESS:
+ case KVM_CAP_ARM_PTRAUTH_GENERIC:
+ return true;
+ default:
+ return false;
+ }
+}
+
int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
struct kvm_enable_cap *cap)
{
- int r;
- u64 new_cap;
+ int r = -EINVAL;
if (cap->flags)
return -EINVAL;
+ if (kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, cap->cap))
+ return -EINVAL;
+
switch (cap->cap) {
case KVM_CAP_ARM_NISV_TO_USER:
r = 0;
@@ -86,9 +123,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
break;
case KVM_CAP_ARM_MTE:
mutex_lock(&kvm->lock);
- if (!system_supports_mte() || kvm->created_vcpus) {
- r = -EINVAL;
- } else {
+ if (system_supports_mte() && !kvm->created_vcpus) {
r = 0;
set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags);
}
@@ -99,25 +134,22 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
set_bit(KVM_ARCH_FLAG_SYSTEM_SUSPEND_ENABLED, &kvm->arch.flags);
break;
case KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE:
- new_cap = cap->args[0];
-
mutex_lock(&kvm->slots_lock);
/*
* To keep things simple, allow changing the chunk
* size only when no memory slots have been created.
*/
- if (!kvm_are_all_memslots_empty(kvm)) {
- r = -EINVAL;
- } else if (new_cap && !kvm_is_block_size_supported(new_cap)) {
- r = -EINVAL;
- } else {
- r = 0;
- kvm->arch.mmu.split_page_chunk_size = new_cap;
+ if (kvm_are_all_memslots_empty(kvm)) {
+ u64 new_cap = cap->args[0];
+
+ if (!new_cap || kvm_is_block_size_supported(new_cap)) {
+ r = 0;
+ kvm->arch.mmu.split_page_chunk_size = new_cap;
+ }
}
mutex_unlock(&kvm->slots_lock);
break;
default:
- r = -EINVAL;
break;
}
@@ -147,6 +179,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
mutex_unlock(&kvm->lock);
#endif
+ kvm_init_nested(kvm);
+
ret = kvm_share_hyp(kvm, kvm + 1);
if (ret)
return ret;
@@ -195,6 +229,23 @@ void kvm_arch_create_vm_debugfs(struct kvm *kvm)
kvm_sys_regs_create_debugfs(kvm);
}
+static void kvm_destroy_mpidr_data(struct kvm *kvm)
+{
+ struct kvm_mpidr_data *data;
+
+ mutex_lock(&kvm->arch.config_lock);
+
+ data = rcu_dereference_protected(kvm->arch.mpidr_data,
+ lockdep_is_held(&kvm->arch.config_lock));
+ if (data) {
+ rcu_assign_pointer(kvm->arch.mpidr_data, NULL);
+ synchronize_rcu();
+ kfree(data);
+ }
+
+ mutex_unlock(&kvm->arch.config_lock);
+}
+
/**
* kvm_arch_destroy_vm - destroy the VM data structure
* @kvm: pointer to the KVM struct
@@ -209,7 +260,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
if (is_protected_kvm_enabled())
pkvm_destroy_hyp_vm(kvm);
- kfree(kvm->arch.mpidr_data);
+ kvm_destroy_mpidr_data(kvm);
+
kfree(kvm->arch.sysreg_masks);
kvm_destroy_vcpus(kvm);
@@ -218,9 +270,47 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kvm_arm_teardown_hypercalls(kvm);
}
+static bool kvm_has_full_ptr_auth(void)
+{
+ bool apa, gpa, api, gpi, apa3, gpa3;
+ u64 isar1, isar2, val;
+
+ /*
+ * Check that:
+ *
+ * - both Address and Generic auth are implemented for a given
+ * algorithm (Q5, IMPDEF or Q3)
+ * - only a single algorithm is implemented.
+ */
+ if (!system_has_full_ptr_auth())
+ return false;
+
+ isar1 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
+ isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
+
+ apa = !!FIELD_GET(ID_AA64ISAR1_EL1_APA_MASK, isar1);
+ val = FIELD_GET(ID_AA64ISAR1_EL1_GPA_MASK, isar1);
+ gpa = (val == ID_AA64ISAR1_EL1_GPA_IMP);
+
+ api = !!FIELD_GET(ID_AA64ISAR1_EL1_API_MASK, isar1);
+ val = FIELD_GET(ID_AA64ISAR1_EL1_GPI_MASK, isar1);
+ gpi = (val == ID_AA64ISAR1_EL1_GPI_IMP);
+
+ apa3 = !!FIELD_GET(ID_AA64ISAR2_EL1_APA3_MASK, isar2);
+ val = FIELD_GET(ID_AA64ISAR2_EL1_GPA3_MASK, isar2);
+ gpa3 = (val == ID_AA64ISAR2_EL1_GPA3_IMP);
+
+ return (apa == gpa && api == gpi && apa3 == gpa3 &&
+ (apa + api + apa3) == 1);
+}
+
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
{
int r;
+
+ if (kvm && kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, ext))
+ return 0;
+
switch (ext) {
case KVM_CAP_IRQCHIP:
r = vgic_present;
@@ -311,7 +401,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
break;
case KVM_CAP_ARM_PTRAUTH_ADDRESS:
case KVM_CAP_ARM_PTRAUTH_GENERIC:
- r = system_has_full_ptr_auth();
+ r = kvm_has_full_ptr_auth();
break;
case KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE:
if (kvm)
@@ -378,12 +468,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
- /*
- * Default value for the FP state, will be overloaded at load
- * time if we support FP (pretty likely)
- */
- vcpu->arch.fp_state = FP_STATE_FREE;
-
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);
@@ -395,6 +479,13 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
+ /*
+ * This vCPU may have been created after mpidr_data was initialized.
+ * Throw out the pre-computed mappings if that is the case which forces
+ * KVM to fall back to iteratively searching the vCPUs.
+ */
+ kvm_destroy_mpidr_data(vcpu->kvm);
+
err = kvm_vgic_vcpu_init(vcpu);
if (err)
return err;
@@ -428,11 +519,70 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
}
+static void vcpu_set_pauth_traps(struct kvm_vcpu *vcpu)
+{
+ if (vcpu_has_ptrauth(vcpu)) {
+ /*
+ * Either we're running running an L2 guest, and the API/APK
+ * bits come from L1's HCR_EL2, or API/APK are both set.
+ */
+ if (unlikely(vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu))) {
+ u64 val;
+
+ val = __vcpu_sys_reg(vcpu, HCR_EL2);
+ val &= (HCR_API | HCR_APK);
+ vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK);
+ vcpu->arch.hcr_el2 |= val;
+ } else {
+ vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
+ }
+
+ /*
+ * Save the host keys if there is any chance for the guest
+ * to use pauth, as the entry code will reload the guest
+ * keys in that case.
+ * Protected mode is the exception to that rule, as the
+ * entry into the EL2 code eagerly switch back and forth
+ * between host and hyp keys (and kvm_hyp_ctxt is out of
+ * reach anyway).
+ */
+ if (is_protected_kvm_enabled())
+ return;
+
+ if (vcpu->arch.hcr_el2 & (HCR_API | HCR_APK)) {
+ struct kvm_cpu_context *ctxt;
+ ctxt = this_cpu_ptr_hyp_sym(kvm_hyp_ctxt);
+ ptrauth_save_keys(ctxt);
+ }
+ }
+}
+
+static bool kvm_vcpu_should_clear_twi(struct kvm_vcpu *vcpu)
+{
+ if (unlikely(kvm_wfi_trap_policy != KVM_WFX_NOTRAP_SINGLE_TASK))
+ return kvm_wfi_trap_policy == KVM_WFX_NOTRAP;
+
+ return single_task_running() &&
+ (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) ||
+ vcpu->kvm->arch.vgic.nassgireq);
+}
+
+static bool kvm_vcpu_should_clear_twe(struct kvm_vcpu *vcpu)
+{
+ if (unlikely(kvm_wfe_trap_policy != KVM_WFX_NOTRAP_SINGLE_TASK))
+ return kvm_wfe_trap_policy == KVM_WFX_NOTRAP;
+
+ return single_task_running();
+}
+
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
struct kvm_s2_mmu *mmu;
int *last_ran;
+ if (vcpu_has_nv(vcpu))
+ kvm_vcpu_load_hw_mmu(vcpu);
+
mmu = vcpu->arch.hw_mmu;
last_ran = this_cpu_ptr(mmu->last_vcpu_ran);
@@ -461,13 +611,18 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
- if (single_task_running())
- vcpu_clear_wfx_traps(vcpu);
+ if (kvm_vcpu_should_clear_twe(vcpu))
+ vcpu->arch.hcr_el2 &= ~HCR_TWE;
+ else
+ vcpu->arch.hcr_el2 |= HCR_TWE;
+
+ if (kvm_vcpu_should_clear_twi(vcpu))
+ vcpu->arch.hcr_el2 &= ~HCR_TWI;
else
- vcpu_set_wfx_traps(vcpu);
+ vcpu->arch.hcr_el2 |= HCR_TWI;
+
+ vcpu_set_pauth_traps(vcpu);
- if (vcpu_has_ptrauth(vcpu))
- vcpu_ptrauth_disable(vcpu);
kvm_arch_vcpu_load_debug_state_flags(vcpu);
if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
@@ -483,6 +638,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_timer_vcpu_put(vcpu);
kvm_vgic_put(vcpu);
kvm_vcpu_pmu_restore_host(vcpu);
+ if (vcpu_has_nv(vcpu))
+ kvm_vcpu_put_hw_mmu(vcpu);
kvm_arm_vmid_clear_active();
vcpu_clear_on_unsupported_cpu(vcpu);
@@ -580,11 +737,6 @@ unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
}
#endif
-static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
-{
- return vcpu_get_flag(vcpu, VCPU_INITIALIZED);
-}
-
static void kvm_init_mpidr_data(struct kvm *kvm)
{
struct kvm_mpidr_data *data = NULL;
@@ -594,7 +746,8 @@ static void kvm_init_mpidr_data(struct kvm *kvm)
mutex_lock(&kvm->arch.config_lock);
- if (kvm->arch.mpidr_data || atomic_read(&kvm->online_vcpus) == 1)
+ if (rcu_access_pointer(kvm->arch.mpidr_data) ||
+ atomic_read(&kvm->online_vcpus) == 1)
goto out;
kvm_for_each_vcpu(c, vcpu, kvm) {
@@ -631,7 +784,7 @@ static void kvm_init_mpidr_data(struct kvm *kvm)
data->cmpidr_to_idx[index] = c;
}
- kvm->arch.mpidr_data = data;
+ rcu_assign_pointer(kvm->arch.mpidr_data, data);
out:
mutex_unlock(&kvm->arch.config_lock);
}
@@ -683,7 +836,7 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
* This needs to happen after NV has imposed its own restrictions on
* the feature set
*/
- kvm_init_sysreg(vcpu);
+ kvm_calculate_traps(vcpu);
ret = kvm_timer_enable(vcpu);
if (ret)
@@ -790,9 +943,8 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
* doorbells to be signalled, should an interrupt become pending.
*/
preempt_disable();
- kvm_vgic_vmcr_sync(vcpu);
vcpu_set_flag(vcpu, IN_WFI);
- vgic_v4_put(vcpu);
+ kvm_vgic_put(vcpu);
preempt_enable();
kvm_vcpu_halt(vcpu);
@@ -800,7 +952,7 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
preempt_disable();
vcpu_clear_flag(vcpu, IN_WFI);
- vgic_v4_load(vcpu);
+ kvm_vgic_load(vcpu);
preempt_enable();
}
@@ -980,13 +1132,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
if (run->exit_reason == KVM_EXIT_MMIO) {
ret = kvm_handle_mmio_return(vcpu);
- if (ret)
+ if (ret <= 0)
return ret;
}
vcpu_load(vcpu);
- if (run->immediate_exit) {
+ if (!vcpu->wants_to_run) {
ret = -EINTR;
goto out;
}
@@ -1270,7 +1422,7 @@ static unsigned long system_supported_vcpu_features(void)
if (!system_supports_sve())
clear_bit(KVM_ARM_VCPU_SVE, &features);
- if (!system_has_full_ptr_auth()) {
+ if (!kvm_has_full_ptr_auth()) {
clear_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, &features);
clear_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, &features);
}
@@ -1306,11 +1458,6 @@ static int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,
test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, &features))
return -EINVAL;
- /* Disallow NV+SVE for the time being */
- if (test_bit(KVM_ARM_VCPU_HAS_EL2, &features) &&
- test_bit(KVM_ARM_VCPU_SVE, &features))
- return -EINVAL;
-
if (!test_bit(KVM_ARM_VCPU_EL1_32BIT, &features))
return 0;
@@ -1346,6 +1493,10 @@ static int kvm_setup_vcpu(struct kvm_vcpu *vcpu)
if (kvm_vcpu_has_pmu(vcpu) && !kvm->arch.arm_pmu)
ret = kvm_arm_set_default_pmu(kvm);
+ /* Prepare for nested if required */
+ if (!ret && vcpu_has_nv(vcpu))
+ ret = kvm_vcpu_init_nested(vcpu);
+
return ret;
}
@@ -1818,6 +1969,11 @@ static unsigned long nvhe_percpu_order(void)
return size ? get_order(size) : 0;
}
+static size_t pkvm_host_sve_state_order(void)
+{
+ return get_order(pkvm_host_sve_state_size());
+}
+
/* A lookup table holding the hypervisor VA for each vector slot */
static void *hyp_spectre_vector_selector[BP_HARDEN_EL2_SLOTS];
@@ -1971,7 +2127,7 @@ static void cpu_set_hyp_vector(void)
static void cpu_hyp_init_context(void)
{
- kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt);
+ kvm_init_host_cpu_context(host_data_ptr(host_ctxt));
if (!is_kernel_in_hyp_mode())
cpu_init_hyp_mode();
@@ -2197,12 +2353,20 @@ static void __init teardown_subsystems(void)
static void __init teardown_hyp_mode(void)
{
+ bool free_sve = system_supports_sve() && is_protected_kvm_enabled();
int cpu;
free_hyp_pgds();
for_each_possible_cpu(cpu) {
free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
+
+ if (free_sve) {
+ struct cpu_sve_state *sve_state;
+
+ sve_state = per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state;
+ free_pages((unsigned long) sve_state, pkvm_host_sve_state_order());
+ }
}
}
@@ -2285,6 +2449,58 @@ static int __init kvm_hyp_init_protection(u32 hyp_va_bits)
return 0;
}
+static int init_pkvm_host_sve_state(void)
+{
+ int cpu;
+
+ if (!system_supports_sve())
+ return 0;
+
+ /* Allocate pages for host sve state in protected mode. */
+ for_each_possible_cpu(cpu) {
+ struct page *page = alloc_pages(GFP_KERNEL, pkvm_host_sve_state_order());
+
+ if (!page)
+ return -ENOMEM;
+
+ per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state = page_address(page);
+ }
+
+ /*
+ * Don't map the pages in hyp since these are only used in protected
+ * mode, which will (re)create its own mapping when initialized.
+ */
+
+ return 0;
+}
+
+/*
+ * Finalizes the initialization of hyp mode, once everything else is initialized
+ * and the initialziation process cannot fail.
+ */
+static void finalize_init_hyp_mode(void)
+{
+ int cpu;
+
+ if (system_supports_sve() && is_protected_kvm_enabled()) {
+ for_each_possible_cpu(cpu) {
+ struct cpu_sve_state *sve_state;
+
+ sve_state = per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state;
+ per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state =
+ kern_hyp_va(sve_state);
+ }
+ } else {
+ for_each_possible_cpu(cpu) {
+ struct user_fpsimd_state *fpsimd_state;
+
+ fpsimd_state = &per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->host_ctxt.fp_regs;
+ per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->fpsimd_state =
+ kern_hyp_va(fpsimd_state);
+ }
+ }
+}
+
static void pkvm_hyp_init_ptrauth(void)
{
struct kvm_cpu_context *hyp_ctxt;
@@ -2453,6 +2669,10 @@ static int __init init_hyp_mode(void)
goto out_err;
}
+ err = init_pkvm_host_sve_state();
+ if (err)
+ goto out_err;
+
err = kvm_hyp_init_protection(hyp_va_bits);
if (err) {
kvm_err("Failed to init hyp memory protection\n");
@@ -2470,21 +2690,27 @@ out_err:
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
{
- struct kvm_vcpu *vcpu;
+ struct kvm_vcpu *vcpu = NULL;
+ struct kvm_mpidr_data *data;
unsigned long i;
mpidr &= MPIDR_HWID_BITMASK;
- if (kvm->arch.mpidr_data) {
- u16 idx = kvm_mpidr_index(kvm->arch.mpidr_data, mpidr);
+ rcu_read_lock();
+ data = rcu_dereference(kvm->arch.mpidr_data);
- vcpu = kvm_get_vcpu(kvm,
- kvm->arch.mpidr_data->cmpidr_to_idx[idx]);
+ if (data) {
+ u16 idx = kvm_mpidr_index(data, mpidr);
+
+ vcpu = kvm_get_vcpu(kvm, data->cmpidr_to_idx[idx]);
if (mpidr != kvm_vcpu_get_mpidr_aff(vcpu))
vcpu = NULL;
+ }
+
+ rcu_read_unlock();
+ if (vcpu)
return vcpu;
- }
kvm_for_each_vcpu(i, vcpu, kvm) {
if (mpidr == kvm_vcpu_get_mpidr_aff(vcpu))
@@ -2611,6 +2837,13 @@ static __init int kvm_arm_init(void)
if (err)
goto out_subs;
+ /*
+ * This should be called after initialization is done and failure isn't
+ * possible anymore.
+ */
+ if (!in_hyp_mode)
+ finalize_init_hyp_mode();
+
kvm_arm_initialised = true;
return 0;
@@ -2663,6 +2896,36 @@ static int __init early_kvm_mode_cfg(char *arg)
}
early_param("kvm-arm.mode", early_kvm_mode_cfg);
+static int __init early_kvm_wfx_trap_policy_cfg(char *arg, enum kvm_wfx_trap_policy *p)
+{
+ if (!arg)
+ return -EINVAL;
+
+ if (strcmp(arg, "trap") == 0) {
+ *p = KVM_WFX_TRAP;
+ return 0;
+ }
+
+ if (strcmp(arg, "notrap") == 0) {
+ *p = KVM_WFX_NOTRAP;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int __init early_kvm_wfi_trap_policy_cfg(char *arg)
+{
+ return early_kvm_wfx_trap_policy_cfg(arg, &kvm_wfi_trap_policy);
+}
+early_param("kvm-arm.wfi_trap_policy", early_kvm_wfi_trap_policy_cfg);
+
+static int __init early_kvm_wfe_trap_policy_cfg(char *arg)
+{
+ return early_kvm_wfx_trap_policy_cfg(arg, &kvm_wfe_trap_policy);
+}
+early_param("kvm-arm.wfe_trap_policy", early_kvm_wfe_trap_policy_cfg);
+
enum kvm_mode kvm_get_mode(void)
{
return kvm_mode;
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 4697ba41b3a9..05166eccea0a 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -79,6 +79,12 @@ enum cgt_group_id {
CGT_MDCR_E2TB,
CGT_MDCR_TDCC,
+ CGT_CPACR_E0POE,
+ CGT_CPTR_TAM,
+ CGT_CPTR_TCPAC,
+
+ CGT_HCRX_TCR2En,
+
/*
* Anything after this point is a combination of coarse trap
* controls, which must all be evaluated to decide what to do.
@@ -89,6 +95,7 @@ enum cgt_group_id {
CGT_HCR_TTLB_TTLBIS,
CGT_HCR_TTLB_TTLBOS,
CGT_HCR_TVM_TRVM,
+ CGT_HCR_TVM_TRVM_HCRX_TCR2En,
CGT_HCR_TPU_TICAB,
CGT_HCR_TPU_TOCU,
CGT_HCR_NV1_nNV2_ENSCXT,
@@ -106,6 +113,8 @@ enum cgt_group_id {
CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
CGT_CNTHCTL_EL1PTEN,
+ CGT_CPTR_TTA,
+
/* Must be last */
__NR_CGT_GROUP_IDS__
};
@@ -345,6 +354,30 @@ static const struct trap_bits coarse_trap_bits[] = {
.mask = MDCR_EL2_TDCC,
.behaviour = BEHAVE_FORWARD_ANY,
},
+ [CGT_CPACR_E0POE] = {
+ .index = CPTR_EL2,
+ .value = CPACR_ELx_E0POE,
+ .mask = CPACR_ELx_E0POE,
+ .behaviour = BEHAVE_FORWARD_ANY,
+ },
+ [CGT_CPTR_TAM] = {
+ .index = CPTR_EL2,
+ .value = CPTR_EL2_TAM,
+ .mask = CPTR_EL2_TAM,
+ .behaviour = BEHAVE_FORWARD_ANY,
+ },
+ [CGT_CPTR_TCPAC] = {
+ .index = CPTR_EL2,
+ .value = CPTR_EL2_TCPAC,
+ .mask = CPTR_EL2_TCPAC,
+ .behaviour = BEHAVE_FORWARD_ANY,
+ },
+ [CGT_HCRX_TCR2En] = {
+ .index = HCRX_EL2,
+ .value = 0,
+ .mask = HCRX_EL2_TCR2En,
+ .behaviour = BEHAVE_FORWARD_ANY,
+ },
};
#define MCB(id, ...) \
@@ -359,6 +392,8 @@ static const enum cgt_group_id *coarse_control_combo[] = {
MCB(CGT_HCR_TTLB_TTLBIS, CGT_HCR_TTLB, CGT_HCR_TTLBIS),
MCB(CGT_HCR_TTLB_TTLBOS, CGT_HCR_TTLB, CGT_HCR_TTLBOS),
MCB(CGT_HCR_TVM_TRVM, CGT_HCR_TVM, CGT_HCR_TRVM),
+ MCB(CGT_HCR_TVM_TRVM_HCRX_TCR2En,
+ CGT_HCR_TVM, CGT_HCR_TRVM, CGT_HCRX_TCR2En),
MCB(CGT_HCR_TPU_TICAB, CGT_HCR_TPU, CGT_HCR_TICAB),
MCB(CGT_HCR_TPU_TOCU, CGT_HCR_TPU, CGT_HCR_TOCU),
MCB(CGT_HCR_NV1_nNV2_ENSCXT, CGT_HCR_NV1_nNV2, CGT_HCR_ENSCXT),
@@ -410,12 +445,26 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
return BEHAVE_FORWARD_ANY;
}
+static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
+{
+ u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);
+
+ if (!vcpu_el2_e2h_is_set(vcpu))
+ val = translate_cptr_el2_to_cpacr_el1(val);
+
+ if (val & CPACR_ELx_TTA)
+ return BEHAVE_FORWARD_ANY;
+
+ return BEHAVE_HANDLE_LOCALLY;
+}
+
#define CCC(id, fn) \
[id - __COMPLEX_CONDITIONS__] = fn
static const complex_condition_check ccc[] = {
CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
+ CCC(CGT_CPTR_TTA, check_cptr_tta),
};
/*
@@ -622,6 +671,7 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
SR_TRAP(SYS_MAIR_EL1, CGT_HCR_TVM_TRVM),
SR_TRAP(SYS_AMAIR_EL1, CGT_HCR_TVM_TRVM),
SR_TRAP(SYS_CONTEXTIDR_EL1, CGT_HCR_TVM_TRVM),
+ SR_TRAP(SYS_TCR2_EL1, CGT_HCR_TVM_TRVM_HCRX_TCR2En),
SR_TRAP(SYS_DC_ZVA, CGT_HCR_TDZ),
SR_TRAP(SYS_DC_GVA, CGT_HCR_TDZ),
SR_TRAP(SYS_DC_GZVA, CGT_HCR_TDZ),
@@ -1000,6 +1050,59 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
SR_TRAP(SYS_TRBPTR_EL1, CGT_MDCR_E2TB),
SR_TRAP(SYS_TRBSR_EL1, CGT_MDCR_E2TB),
SR_TRAP(SYS_TRBTRG_EL1, CGT_MDCR_E2TB),
+ SR_TRAP(SYS_CPACR_EL1, CGT_CPTR_TCPAC),
+ SR_TRAP(SYS_AMUSERENR_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCFGR_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCGCR_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCNTENCLR0_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCNTENCLR1_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCNTENSET0_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCNTENSET1_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMCR_EL0, CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR0_EL0(0), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR0_EL0(1), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR0_EL0(2), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR0_EL0(3), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(0), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(1), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(2), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(3), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(4), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(5), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(6), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(7), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(8), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(9), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(10), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(11), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(12), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(13), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(14), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVCNTR1_EL0(15), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER0_EL0(0), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER0_EL0(1), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER0_EL0(2), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER0_EL0(3), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(0), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(1), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(2), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(3), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(4), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(5), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(6), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(7), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(8), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(9), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(10), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(11), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(12), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(13), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(14), CGT_CPTR_TAM),
+ SR_TRAP(SYS_AMEVTYPER1_EL0(15), CGT_CPTR_TAM),
+ SR_TRAP(SYS_POR_EL0, CGT_CPACR_E0POE),
+ /* op0=2, op1=1, and CRn<0b1000 */
+ SR_RANGE_TRAP(sys_reg(2, 1, 0, 0, 0),
+ sys_reg(2, 1, 7, 15, 7), CGT_CPTR_TTA),
SR_TRAP(SYS_CNTP_TVAL_EL0, CGT_CNTHCTL_EL1PTEN),
SR_TRAP(SYS_CNTP_CVAL_EL0, CGT_CNTHCTL_EL1PTEN),
SR_TRAP(SYS_CNTP_CTL_EL0, CGT_CNTHCTL_EL1PTEN),
@@ -1071,6 +1174,7 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
SR_FGT(SYS_TPIDRRO_EL0, HFGxTR, TPIDRRO_EL0, 1),
SR_FGT(SYS_TPIDR_EL1, HFGxTR, TPIDR_EL1, 1),
SR_FGT(SYS_TCR_EL1, HFGxTR, TCR_EL1, 1),
+ SR_FGT(SYS_TCR2_EL1, HFGxTR, TCR_EL1, 1),
SR_FGT(SYS_SCXTNUM_EL0, HFGxTR, SCXTNUM_EL0, 1),
SR_FGT(SYS_SCXTNUM_EL1, HFGxTR, SCXTNUM_EL1, 1),
SR_FGT(SYS_SCTLR_EL1, HFGxTR, SCTLR_EL1, 1),
@@ -2117,6 +2221,26 @@ inject:
return true;
}
+static bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
+{
+ bool control_bit_set;
+
+ if (!vcpu_has_nv(vcpu))
+ return false;
+
+ control_bit_set = __vcpu_sys_reg(vcpu, HCR_EL2) & control_bit;
+ if (!is_hyp_ctxt(vcpu) && control_bit_set) {
+ kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+ return true;
+ }
+ return false;
+}
+
+bool forward_smc_trap(struct kvm_vcpu *vcpu)
+{
+ return forward_traps(vcpu, HCR_TSC);
+}
+
static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
{
u64 mode = spsr & PSR_MODE_MASK;
@@ -2152,44 +2276,47 @@ static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
{
- u64 spsr, elr, mode;
- bool direct_eret;
+ u64 spsr, elr, esr;
/*
- * Going through the whole put/load motions is a waste of time
- * if this is a VHE guest hypervisor returning to its own
- * userspace, or the hypervisor performing a local exception
- * return. No need to save/restore registers, no need to
- * switch S2 MMU. Just do the canonical ERET.
+ * Forward this trap to the virtual EL2 if the virtual
+ * HCR_EL2.NV bit is set and this is coming from !EL2.
*/
+ if (forward_traps(vcpu, HCR_NV))
+ return;
+
spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
spsr = kvm_check_illegal_exception_return(vcpu, spsr);
- mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
-
- direct_eret = (mode == PSR_MODE_EL0t &&
- vcpu_el2_e2h_is_set(vcpu) &&
- vcpu_el2_tge_is_set(vcpu));
- direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
-
- if (direct_eret) {
- *vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
- *vcpu_cpsr(vcpu) = spsr;
- trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
- return;
+ /* Check for an ERETAx */
+ esr = kvm_vcpu_get_esr(vcpu);
+ if (esr_iss_is_eretax(esr) && !kvm_auth_eretax(vcpu, &elr)) {
+ /*
+ * Oh no, ERETAx failed to authenticate.
+ *
+ * If we have FPACCOMBINE and we don't have a pending
+ * Illegal Execution State exception (which has priority
+ * over FPAC), deliver an exception right away.
+ *
+ * Otherwise, let the mangled ELR value trickle down the
+ * ERET handling, and the guest will have a little surprise.
+ */
+ if (kvm_has_pauth(vcpu->kvm, FPACCOMBINE) && !(spsr & PSR_IL_BIT)) {
+ esr &= ESR_ELx_ERET_ISS_ERETA;
+ esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_FPAC);
+ kvm_inject_nested_sync(vcpu, esr);
+ return;
+ }
}
preempt_disable();
kvm_arch_vcpu_put(vcpu);
- elr = __vcpu_sys_reg(vcpu, ELR_EL2);
+ if (!esr_iss_is_eretax(esr))
+ elr = __vcpu_sys_reg(vcpu, ELR_EL2);
trace_kvm_nested_eret(vcpu, elr, spsr);
- /*
- * Note that the current exception level is always the virtual EL2,
- * since we set HCR_EL2.NV bit only when entering the virtual EL2.
- */
*vcpu_pc(vcpu) = elr;
*vcpu_cpsr(vcpu) = spsr;
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 826307e19e3a..c53e5b14038d 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -14,19 +14,6 @@
#include <asm/kvm_mmu.h>
#include <asm/sysreg.h>
-void kvm_vcpu_unshare_task_fp(struct kvm_vcpu *vcpu)
-{
- struct task_struct *p = vcpu->arch.parent_task;
- struct user_fpsimd_state *fpsimd;
-
- if (!is_protected_kvm_enabled() || !p)
- return;
-
- fpsimd = &p->thread.uw.fpsimd_state;
- kvm_unshare_hyp(fpsimd, fpsimd + 1);
- put_task_struct(p);
-}
-
/*
* Called on entry to KVM_RUN unless this vcpu previously ran at least
* once and the most recent prior KVM_RUN for this vcpu was called from
@@ -38,30 +25,18 @@ void kvm_vcpu_unshare_task_fp(struct kvm_vcpu *vcpu)
*/
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
{
- int ret;
-
struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
+ int ret;
- kvm_vcpu_unshare_task_fp(vcpu);
+ /* pKVM has its own tracking of the host fpsimd state. */
+ if (is_protected_kvm_enabled())
+ return 0;
/* Make sure the host task fpsimd state is visible to hyp: */
ret = kvm_share_hyp(fpsimd, fpsimd + 1);
if (ret)
return ret;
- vcpu->arch.host_fpsimd_state = kern_hyp_va(fpsimd);
-
- /*
- * We need to keep current's task_struct pinned until its data has been
- * unshared with the hypervisor to make sure it is not re-used by the
- * kernel and donated to someone else while already shared -- see
- * kvm_vcpu_unshare_task_fp() for the matching put_task_struct().
- */
- if (is_protected_kvm_enabled()) {
- get_task_struct(current);
- vcpu->arch.parent_task = current;
- }
-
return 0;
}
@@ -86,7 +61,8 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
* guest in kvm_arch_vcpu_ctxflush_fp() and override this to
* FP_STATE_FREE if the flag set.
*/
- vcpu->arch.fp_state = FP_STATE_HOST_OWNED;
+ *host_data_ptr(fp_owner) = FP_STATE_HOST_OWNED;
+ *host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state);
vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
@@ -110,10 +86,17 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
* been saved, this is very unlikely to happen.
*/
if (read_sysreg_s(SYS_SVCR) & (SVCR_SM_MASK | SVCR_ZA_MASK)) {
- vcpu->arch.fp_state = FP_STATE_FREE;
+ *host_data_ptr(fp_owner) = FP_STATE_FREE;
fpsimd_save_and_flush_cpu_state();
}
}
+
+ /*
+ * If normal guests gain SME support, maintain this behavior for pKVM
+ * guests, which don't support SME.
+ */
+ WARN_ON(is_protected_kvm_enabled() && system_supports_sme() &&
+ read_sysreg_s(SYS_SVCR));
}
/*
@@ -126,7 +109,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
{
if (test_thread_flag(TIF_FOREIGN_FPSTATE))
- vcpu->arch.fp_state = FP_STATE_FREE;
+ *host_data_ptr(fp_owner) = FP_STATE_FREE;
}
/*
@@ -142,8 +125,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
WARN_ON_ONCE(!irqs_disabled());
- if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) {
-
+ if (guest_owns_fp_regs()) {
/*
* Currently we do not support SME guests so SVCR is
* always 0 and we just need a variable to point to.
@@ -186,9 +168,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
if (has_vhe() && system_supports_sme()) {
/* Also restore EL0 state seen on entry */
if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
- sysreg_clear_set(CPACR_EL1, 0,
- CPACR_EL1_SMEN_EL0EN |
- CPACR_EL1_SMEN_EL1EN);
+ sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
else
sysreg_clear_set(CPACR_EL1,
CPACR_EL1_SMEN_EL0EN,
@@ -196,16 +176,47 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
isb();
}
- if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) {
+ if (guest_owns_fp_regs()) {
if (vcpu_has_sve(vcpu)) {
- __vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
-
- /* Restore the VL that was saved when bound to the CPU */
- if (!has_vhe())
+ u64 zcr = read_sysreg_el1(SYS_ZCR);
+
+ /*
+ * If the vCPU is in the hyp context then ZCR_EL1 is
+ * loaded with its vEL2 counterpart.
+ */
+ __vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)) = zcr;
+
+ /*
+ * Restore the VL that was saved when bound to the CPU,
+ * which is the maximum VL for the guest. Because the
+ * layout of the data when saving the sve state depends
+ * on the VL, we need to use a consistent (i.e., the
+ * maximum) VL.
+ * Note that this means that at guest exit ZCR_EL1 is
+ * not necessarily the same as on guest entry.
+ *
+ * ZCR_EL2 holds the guest hypervisor's VL when running
+ * a nested guest, which could be smaller than the
+ * max for the vCPU. Similar to above, we first need to
+ * switch to a VL consistent with the layout of the
+ * vCPU's SVE state. KVM support for NV implies VHE, so
+ * using the ZCR_EL1 alias is safe.
+ */
+ if (!has_vhe() || (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)))
sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1,
SYS_ZCR_EL1);
}
+ /*
+ * Flush (save and invalidate) the fpsimd/sve state so that if
+ * the host tries to use fpsimd/sve, it's not using stale data
+ * from the guest.
+ *
+ * Flushing the state sets the TIF_FOREIGN_FPSTATE bit for the
+ * context unconditionally, in both nVHE and VHE. This allows
+ * the kernel to restore the fpsimd/sve state, including ZCR_EL1
+ * when needed.
+ */
fpsimd_save_and_flush_cpu_state();
} else if (has_vhe() && system_supports_sve()) {
/*
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index e2f762d959bb..11098eb7eb44 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -251,6 +251,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case PSR_AA32_MODE_SVC:
case PSR_AA32_MODE_ABT:
case PSR_AA32_MODE_UND:
+ case PSR_AA32_MODE_SYS:
if (!vcpu_el1_is_32bit(vcpu))
return -EINVAL;
break;
@@ -276,7 +277,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) {
int i, nr_reg;
- switch (*vcpu_cpsr(vcpu)) {
+ switch (*vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK) {
/*
* Either we are dealing with user mode, and only the
* first 15 registers (+ PC) must be narrowed to 32bit.
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 617ae6dea5d5..d7c2990e7c9e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -56,6 +56,13 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
static int handle_smc(struct kvm_vcpu *vcpu)
{
/*
+ * Forward this trapped smc instruction to the virtual EL2 if
+ * the guest has asked for it.
+ */
+ if (forward_smc_trap(vcpu))
+ return 1;
+
+ /*
* "If an SMC instruction executed at Non-secure EL1 is
* trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
* Trap exception, not a Secure Monitor Call exception [...]"
@@ -87,11 +94,19 @@ static int handle_smc(struct kvm_vcpu *vcpu)
}
/*
- * Guest access to FP/ASIMD registers are routed to this handler only
- * when the system doesn't support FP/ASIMD.
+ * This handles the cases where the system does not support FP/ASIMD or when
+ * we are running nested virtualization and the guest hypervisor is trapping
+ * FP/ASIMD accesses by its guest guest.
+ *
+ * All other handling of guest vs. host FP/ASIMD register state is handled in
+ * fixup_guest_exit().
*/
-static int handle_no_fpsimd(struct kvm_vcpu *vcpu)
+static int kvm_handle_fpasimd(struct kvm_vcpu *vcpu)
{
+ if (guest_hyp_fpsimd_traps_enabled(vcpu))
+ return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+ /* This is the case when the system doesn't support FP/ASIMD. */
kvm_inject_undefined(vcpu);
return 1;
}
@@ -202,24 +217,48 @@ static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu)
*/
static int handle_sve(struct kvm_vcpu *vcpu)
{
+ if (guest_hyp_sve_traps_enabled(vcpu))
+ return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
kvm_inject_undefined(vcpu);
return 1;
}
/*
- * Guest usage of a ptrauth instruction (which the guest EL1 did not turn into
- * a NOP). If we get here, it is that we didn't fixup ptrauth on exit, and all
- * that we can do is give the guest an UNDEF.
+ * Two possibilities to handle a trapping ptrauth instruction:
+ *
+ * - Guest usage of a ptrauth instruction (which the guest EL1 did not
+ * turn into a NOP). If we get here, it is because we didn't enable
+ * ptrauth for the guest. This results in an UNDEF, as it isn't
+ * supposed to use ptrauth without being told it could.
+ *
+ * - Running an L2 NV guest while L1 has left HCR_EL2.API==0, and for
+ * which we reinject the exception into L1.
+ *
+ * Anything else is an emulation bug (hence the WARN_ON + UNDEF).
*/
static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
{
+ if (!vcpu_has_ptrauth(vcpu)) {
+ kvm_inject_undefined(vcpu);
+ return 1;
+ }
+
+ if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+ kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+ return 1;
+ }
+
+ /* Really shouldn't be here! */
+ WARN_ON_ONCE(1);
kvm_inject_undefined(vcpu);
return 1;
}
static int kvm_handle_eret(struct kvm_vcpu *vcpu)
{
- if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
+ if (esr_iss_is_eretax(kvm_vcpu_get_esr(vcpu)) &&
+ !vcpu_has_ptrauth(vcpu))
return kvm_handle_ptrauth(vcpu);
/*
@@ -276,7 +315,7 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
[ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
[ESR_ELx_EC_BRK64] = kvm_handle_guest_debug,
- [ESR_ELx_EC_FP_ASIMD] = handle_no_fpsimd,
+ [ESR_ELx_EC_FP_ASIMD] = kvm_handle_fpasimd,
[ESR_ELx_EC_PAC] = kvm_handle_ptrauth,
};
@@ -383,6 +422,20 @@ void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index)
kvm_handle_guest_serror(vcpu, kvm_vcpu_get_esr(vcpu));
}
+static void print_nvhe_hyp_panic(const char *name, u64 panic_addr)
+{
+ kvm_err("nVHE hyp %s at: [<%016llx>] %pB!\n", name, panic_addr,
+ (void *)(panic_addr + kaslr_offset()));
+}
+
+static void kvm_nvhe_report_cfi_failure(u64 panic_addr)
+{
+ print_nvhe_hyp_panic("CFI failure", panic_addr);
+
+ if (IS_ENABLED(CONFIG_CFI_PERMISSIVE))
+ kvm_err(" (CONFIG_CFI_PERMISSIVE ignored for hyp failures)\n");
+}
+
void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,
u64 elr_virt, u64 elr_phys,
u64 par, uintptr_t vcpu,
@@ -395,7 +448,7 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,
if (mode != PSR_MODE_EL2t && mode != PSR_MODE_EL2h) {
kvm_err("Invalid host exception to nVHE hyp!\n");
} else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
- (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) {
+ esr_brk_comment(esr) == BUG_BRK_IMM) {
const char *file = NULL;
unsigned int line = 0;
@@ -411,11 +464,11 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,
if (file)
kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line);
else
- kvm_err("nVHE hyp BUG at: [<%016llx>] %pB!\n", panic_addr,
- (void *)(panic_addr + kaslr_offset()));
+ print_nvhe_hyp_panic("BUG", panic_addr);
+ } else if (IS_ENABLED(CONFIG_CFI_CLANG) && esr_is_cfi_brk(esr)) {
+ kvm_nvhe_report_cfi_failure(panic_addr);
} else {
- kvm_err("nVHE hyp panic at: [<%016llx>] %pB!\n", panic_addr,
- (void *)(panic_addr + kaslr_offset()));
+ print_nvhe_hyp_panic("panic", panic_addr);
}
/* Dump the nVHE hypervisor backtrace */
diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
index a38dea6186c9..d61e44642f98 100644
--- a/arch/arm64/kvm/hyp/Makefile
+++ b/arch/arm64/kvm/hyp/Makefile
@@ -3,7 +3,7 @@
# Makefile for Kernel-based Virtual Machine module, HYP part
#
-incdir := $(srctree)/$(src)/include
+incdir := $(src)/include
subdir-asflags-y := -I$(incdir)
subdir-ccflags-y := -I$(incdir)
diff --git a/arch/arm64/kvm/hyp/aarch32.c b/arch/arm64/kvm/hyp/aarch32.c
index 8d9670e6615d..449fa58cf3b6 100644
--- a/arch/arm64/kvm/hyp/aarch32.c
+++ b/arch/arm64/kvm/hyp/aarch32.c
@@ -50,9 +50,23 @@ bool kvm_condition_valid32(const struct kvm_vcpu *vcpu)
u32 cpsr_cond;
int cond;
- /* Top two bits non-zero? Unconditional. */
- if (kvm_vcpu_get_esr(vcpu) >> 30)
+ /*
+ * These are the exception classes that could fire with a
+ * conditional instruction.
+ */
+ switch (kvm_vcpu_trap_get_class(vcpu)) {
+ case ESR_ELx_EC_CP15_32:
+ case ESR_ELx_EC_CP15_64:
+ case ESR_ELx_EC_CP14_MR:
+ case ESR_ELx_EC_CP14_LS:
+ case ESR_ELx_EC_FP_ASIMD:
+ case ESR_ELx_EC_CP10_ID:
+ case ESR_ELx_EC_CP14_64:
+ case ESR_ELx_EC_SVC32:
+ break;
+ default:
return true;
+ }
/* Is condition field valid? */
cond = kvm_vcpu_get_condition(vcpu);
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index f3aa7738b477..4433a234aa9b 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -83,6 +83,14 @@ alternative_else_nop_endif
eret
sb
+SYM_INNER_LABEL(__guest_exit_restore_elr_and_panic, SYM_L_GLOBAL)
+ // x2-x29,lr: vcpu regs
+ // vcpu x0-x1 on the stack
+
+ adr_this_cpu x0, kvm_hyp_ctxt, x1
+ ldr x0, [x0, #CPU_ELR_EL2]
+ msr elr_el2, x0
+
SYM_INNER_LABEL(__guest_exit_panic, SYM_L_GLOBAL)
// x2-x29,lr: vcpu regs
// vcpu x0-x1 on the stack
diff --git a/arch/arm64/kvm/hyp/fpsimd.S b/arch/arm64/kvm/hyp/fpsimd.S
index 61e6f3ba7b7d..e950875e31ce 100644
--- a/arch/arm64/kvm/hyp/fpsimd.S
+++ b/arch/arm64/kvm/hyp/fpsimd.S
@@ -25,3 +25,9 @@ SYM_FUNC_START(__sve_restore_state)
sve_load 0, x1, x2, 3
ret
SYM_FUNC_END(__sve_restore_state)
+
+SYM_FUNC_START(__sve_save_state)
+ mov x2, #1
+ sve_save 0, x1, x2, 3
+ ret
+SYM_FUNC_END(__sve_save_state)
diff --git a/arch/arm64/kvm/hyp/include/hyp/debug-sr.h b/arch/arm64/kvm/hyp/include/hyp/debug-sr.h
index 961bbef104a6..d00093699aaf 100644
--- a/arch/arm64/kvm/hyp/include/hyp/debug-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/debug-sr.h
@@ -135,9 +135,9 @@ static inline void __debug_switch_to_guest_common(struct kvm_vcpu *vcpu)
if (!vcpu_get_flag(vcpu, DEBUG_DIRTY))
return;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
+ host_dbg = host_data_ptr(host_debug_state.regs);
guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
__debug_save_state(host_dbg, host_ctxt);
@@ -154,9 +154,9 @@ static inline void __debug_switch_to_host_common(struct kvm_vcpu *vcpu)
if (!vcpu_get_flag(vcpu, DEBUG_DIRTY))
return;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
+ host_dbg = host_data_ptr(host_debug_state.regs);
guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
__debug_save_state(guest_dbg, guest_ctxt);
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e3fcf8c4d5b4..f59ccfe11ab9 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -27,6 +27,7 @@
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_nested.h>
+#include <asm/kvm_ptrauth.h>
#include <asm/fpsimd.h>
#include <asm/debug-monitors.h>
#include <asm/processor.h>
@@ -39,12 +40,6 @@ struct kvm_exception_table_entry {
extern struct kvm_exception_table_entry __start___kvm_ex_table;
extern struct kvm_exception_table_entry __stop___kvm_ex_table;
-/* Check whether the FP regs are owned by the guest */
-static inline bool guest_owns_fp_regs(struct kvm_vcpu *vcpu)
-{
- return vcpu->arch.fp_state == FP_STATE_GUEST_OWNED;
-}
-
/* Save the 32-bit only FPSIMD system register state */
static inline void __fpsimd_save_fpexc32(struct kvm_vcpu *vcpu)
{
@@ -155,7 +150,7 @@ static inline bool cpu_has_amu(void)
static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
{
- struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
CHECK_FGT_MASKS(HFGRTR_EL2);
@@ -191,7 +186,7 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
{
- struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
if (!cpus_have_final_cap(ARM64_HAS_FGT))
@@ -226,13 +221,13 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
write_sysreg(0, pmselr_el0);
- hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ hctxt = host_data_ptr(host_ctxt);
ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0);
write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
vcpu_set_flag(vcpu, PMUSERENR_ON_CPU);
}
- vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
+ *host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2);
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
if (cpus_have_final_cap(ARM64_HAS_HCX)) {
@@ -254,13 +249,13 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
{
- write_sysreg(vcpu->arch.mdcr_el2_host, mdcr_el2);
+ write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
write_sysreg(0, hstr_el2);
if (kvm_arm_support_pmu_v3()) {
struct kvm_cpu_context *hctxt;
- hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ hctxt = host_data_ptr(host_ctxt);
write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0);
vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU);
}
@@ -271,10 +266,8 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
__deactivate_traps_hfgxtr(vcpu);
}
-static inline void ___activate_traps(struct kvm_vcpu *vcpu)
+static inline void ___activate_traps(struct kvm_vcpu *vcpu, u64 hcr)
{
- u64 hcr = vcpu->arch.hcr_el2;
-
if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM))
hcr |= HCR_TVM;
@@ -321,12 +314,39 @@ static bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
{
+ /*
+ * The vCPU's saved SVE state layout always matches the max VL of the
+ * vCPU. Start off with the max VL so we can load the SVE state.
+ */
sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
__sve_restore_state(vcpu_sve_pffr(vcpu),
- &vcpu->arch.ctxt.fp_regs.fpsr);
- write_sysreg_el1(__vcpu_sys_reg(vcpu, ZCR_EL1), SYS_ZCR);
+ &vcpu->arch.ctxt.fp_regs.fpsr,
+ true);
+
+ /*
+ * The effective VL for a VM could differ from the max VL when running a
+ * nested guest, as the guest hypervisor could select a smaller VL. Slap
+ * that into hardware before wrapping up.
+ */
+ if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu))
+ sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2);
+
+ write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
}
+static inline void __hyp_sve_save_host(void)
+{
+ struct cpu_sve_state *sve_state = *host_data_ptr(sve_state);
+
+ sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR);
+ write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+ __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
+ &sve_state->fpsr,
+ true);
+}
+
+static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu);
+
/*
* We trap the first access to the FP/SIMD to save the host context and
* restore the guest context lazily.
@@ -337,7 +357,6 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
{
bool sve_guest;
u8 esr_ec;
- u64 reg;
if (!system_supports_fpsimd())
return false;
@@ -348,10 +367,19 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
/* Only handle traps the vCPU can support here: */
switch (esr_ec) {
case ESR_ELx_EC_FP_ASIMD:
+ /* Forward traps to the guest hypervisor as required */
+ if (guest_hyp_fpsimd_traps_enabled(vcpu))
+ return false;
break;
+ case ESR_ELx_EC_SYS64:
+ if (WARN_ON_ONCE(!is_hyp_ctxt(vcpu)))
+ return false;
+ fallthrough;
case ESR_ELx_EC_SVE:
if (!sve_guest)
return false;
+ if (guest_hyp_sve_traps_enabled(vcpu))
+ return false;
break;
default:
return false;
@@ -360,24 +388,15 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
/* Valid trap. Switch the context: */
/* First disable enough traps to allow us to update the registers */
- if (has_vhe() || has_hvhe()) {
- reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
- if (sve_guest)
- reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
-
- sysreg_clear_set(cpacr_el1, 0, reg);
- } else {
- reg = CPTR_EL2_TFP;
- if (sve_guest)
- reg |= CPTR_EL2_TZ;
-
- sysreg_clear_set(cptr_el2, reg, 0);
- }
+ if (sve_guest || (is_protected_kvm_enabled() && system_supports_sve()))
+ cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+ else
+ cpacr_clear_set(0, CPACR_ELx_FPEN);
isb();
/* Write out the host state if it's in the registers */
- if (vcpu->arch.fp_state == FP_STATE_HOST_OWNED)
- __fpsimd_save_state(vcpu->arch.host_fpsimd_state);
+ if (host_owns_fp_regs())
+ kvm_hyp_save_fpsimd_host(vcpu);
/* Restore the guest state */
if (sve_guest)
@@ -389,7 +408,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
if (!(read_sysreg(hcr_el2) & HCR_RW))
write_sysreg(__vcpu_sys_reg(vcpu, FPEXC32_EL2), fpexc32_el2);
- vcpu->arch.fp_state = FP_STATE_GUEST_OWNED;
+ *host_data_ptr(fp_owner) = FP_STATE_GUEST_OWNED;
return true;
}
@@ -449,60 +468,6 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
return true;
}
-static inline bool esr_is_ptrauth_trap(u64 esr)
-{
- switch (esr_sys64_to_sysreg(esr)) {
- case SYS_APIAKEYLO_EL1:
- case SYS_APIAKEYHI_EL1:
- case SYS_APIBKEYLO_EL1:
- case SYS_APIBKEYHI_EL1:
- case SYS_APDAKEYLO_EL1:
- case SYS_APDAKEYHI_EL1:
- case SYS_APDBKEYLO_EL1:
- case SYS_APDBKEYHI_EL1:
- case SYS_APGAKEYLO_EL1:
- case SYS_APGAKEYHI_EL1:
- return true;
- }
-
- return false;
-}
-
-#define __ptrauth_save_key(ctxt, key) \
- do { \
- u64 __val; \
- __val = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \
- ctxt_sys_reg(ctxt, key ## KEYLO_EL1) = __val; \
- __val = read_sysreg_s(SYS_ ## key ## KEYHI_EL1); \
- ctxt_sys_reg(ctxt, key ## KEYHI_EL1) = __val; \
-} while(0)
-
-DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
-
-static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
-{
- struct kvm_cpu_context *ctxt;
- u64 val;
-
- if (!vcpu_has_ptrauth(vcpu))
- return false;
-
- ctxt = this_cpu_ptr(&kvm_hyp_ctxt);
- __ptrauth_save_key(ctxt, APIA);
- __ptrauth_save_key(ctxt, APIB);
- __ptrauth_save_key(ctxt, APDA);
- __ptrauth_save_key(ctxt, APDB);
- __ptrauth_save_key(ctxt, APGA);
-
- vcpu_ptrauth_enable(vcpu);
-
- val = read_sysreg(hcr_el2);
- val |= (HCR_API | HCR_APK);
- write_sysreg(val, hcr_el2);
-
- return true;
-}
-
static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
{
struct arch_timer_context *ctxt;
@@ -590,9 +555,6 @@ static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
__vgic_v3_perform_cpuif_access(vcpu) == 1)
return true;
- if (esr_is_ptrauth_trap(kvm_vcpu_get_esr(vcpu)))
- return kvm_hyp_handle_ptrauth(vcpu, exit_code);
-
if (kvm_hyp_handle_cntpct(vcpu))
return true;
@@ -753,7 +715,7 @@ guest:
static inline void __kvm_unexpected_el2_exception(void)
{
- extern char __guest_exit_panic[];
+ extern char __guest_exit_restore_elr_and_panic[];
unsigned long addr, fixup;
struct kvm_exception_table_entry *entry, *end;
unsigned long elr_el2 = read_sysreg(elr_el2);
@@ -775,7 +737,8 @@ static inline void __kvm_unexpected_el2_exception(void)
}
/* Trigger a panic after restoring the hyp context. */
- write_sysreg(__guest_exit_panic, elr_el2);
+ this_cpu_ptr(&kvm_hyp_ctxt)->sys_regs[ELR_EL2] = elr_el2;
+ write_sysreg(__guest_exit_restore_elr_and_panic, elr_el2);
}
#endif /* __ARM64_KVM_HYP_SWITCH_H__ */
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 4be6a7fa0070..4c0fdabaf8ae 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -55,6 +55,17 @@ static inline bool ctxt_has_s1pie(struct kvm_cpu_context *ctxt)
return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1PIE, IMP);
}
+static inline bool ctxt_has_tcrx(struct kvm_cpu_context *ctxt)
+{
+ struct kvm_vcpu *vcpu;
+
+ if (!cpus_have_final_cap(ARM64_HAS_TCR2))
+ return false;
+
+ vcpu = ctxt_to_vcpu(ctxt);
+ return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, TCRX, IMP);
+}
+
static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
{
ctxt_sys_reg(ctxt, SCTLR_EL1) = read_sysreg_el1(SYS_SCTLR);
@@ -62,8 +73,14 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
ctxt_sys_reg(ctxt, TTBR0_EL1) = read_sysreg_el1(SYS_TTBR0);
ctxt_sys_reg(ctxt, TTBR1_EL1) = read_sysreg_el1(SYS_TTBR1);
ctxt_sys_reg(ctxt, TCR_EL1) = read_sysreg_el1(SYS_TCR);
- if (cpus_have_final_cap(ARM64_HAS_TCR2))
+ if (ctxt_has_tcrx(ctxt)) {
ctxt_sys_reg(ctxt, TCR2_EL1) = read_sysreg_el1(SYS_TCR2);
+
+ if (ctxt_has_s1pie(ctxt)) {
+ ctxt_sys_reg(ctxt, PIR_EL1) = read_sysreg_el1(SYS_PIR);
+ ctxt_sys_reg(ctxt, PIRE0_EL1) = read_sysreg_el1(SYS_PIRE0);
+ }
+ }
ctxt_sys_reg(ctxt, ESR_EL1) = read_sysreg_el1(SYS_ESR);
ctxt_sys_reg(ctxt, AFSR0_EL1) = read_sysreg_el1(SYS_AFSR0);
ctxt_sys_reg(ctxt, AFSR1_EL1) = read_sysreg_el1(SYS_AFSR1);
@@ -73,10 +90,6 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
ctxt_sys_reg(ctxt, CONTEXTIDR_EL1) = read_sysreg_el1(SYS_CONTEXTIDR);
ctxt_sys_reg(ctxt, AMAIR_EL1) = read_sysreg_el1(SYS_AMAIR);
ctxt_sys_reg(ctxt, CNTKCTL_EL1) = read_sysreg_el1(SYS_CNTKCTL);
- if (ctxt_has_s1pie(ctxt)) {
- ctxt_sys_reg(ctxt, PIR_EL1) = read_sysreg_el1(SYS_PIR);
- ctxt_sys_reg(ctxt, PIRE0_EL1) = read_sysreg_el1(SYS_PIRE0);
- }
ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg_par();
ctxt_sys_reg(ctxt, TPIDR_EL1) = read_sysreg(tpidr_el1);
@@ -138,8 +151,14 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
write_sysreg_el1(ctxt_sys_reg(ctxt, CPACR_EL1), SYS_CPACR);
write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL1), SYS_TTBR0);
write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL1), SYS_TTBR1);
- if (cpus_have_final_cap(ARM64_HAS_TCR2))
+ if (ctxt_has_tcrx(ctxt)) {
write_sysreg_el1(ctxt_sys_reg(ctxt, TCR2_EL1), SYS_TCR2);
+
+ if (ctxt_has_s1pie(ctxt)) {
+ write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1), SYS_PIR);
+ write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0);
+ }
+ }
write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL1), SYS_ESR);
write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL1), SYS_AFSR0);
write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR1_EL1), SYS_AFSR1);
@@ -149,10 +168,6 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
write_sysreg_el1(ctxt_sys_reg(ctxt, CONTEXTIDR_EL1), SYS_CONTEXTIDR);
write_sysreg_el1(ctxt_sys_reg(ctxt, AMAIR_EL1), SYS_AMAIR);
write_sysreg_el1(ctxt_sys_reg(ctxt, CNTKCTL_EL1), SYS_CNTKCTL);
- if (ctxt_has_s1pie(ctxt)) {
- write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1), SYS_PIR);
- write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0);
- }
write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1), par_el1);
write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1), tpidr_el1);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/ffa.h b/arch/arm64/kvm/hyp/include/nvhe/ffa.h
index d9fd5e6c7d3c..146e0aebfa1c 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/ffa.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/ffa.h
@@ -9,7 +9,7 @@
#include <asm/kvm_host.h>
#define FFA_MIN_FUNC_NUM 0x60
-#define FFA_MAX_FUNC_NUM 0x7F
+#define FFA_MAX_FUNC_NUM 0xFF
int hyp_ffa_init(void *pages);
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index 51f043649146..f957890c7e38 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -52,11 +52,11 @@
* Supported by KVM
*/
#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
- FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \
- FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \
- FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL2), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \
- FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL3), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \
- FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), ID_AA64PFR0_EL1_RAS_IMP) \
+ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
+ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
+ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
+ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL3, IMP) | \
+ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, RAS, IMP) \
)
/*
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 82b3d62538a6..24a9a8330d19 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -53,6 +53,11 @@ pkvm_hyp_vcpu_to_hyp_vm(struct pkvm_hyp_vcpu *hyp_vcpu)
return container_of(hyp_vcpu->vcpu.kvm, struct pkvm_hyp_vm, kvm);
}
+static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+ return vcpu_is_protected(&hyp_vcpu->vcpu);
+}
+
void pkvm_hyp_vm_table_init(void *tbl);
int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 2250253a6429..782b34b004be 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -89,24 +89,11 @@ quiet_cmd_hyprel = HYPREL $@
quiet_cmd_hypcopy = HYPCOPY $@
cmd_hypcopy = $(OBJCOPY) --prefix-symbols=__kvm_nvhe_ $< $@
-# Remove ftrace, Shadow Call Stack, and CFI CFLAGS.
-# This is equivalent to the 'notrace', '__noscs', and '__nocfi' annotations.
-KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS) $(CC_FLAGS_CFI), $(KBUILD_CFLAGS))
+# Remove ftrace and Shadow Call Stack CFLAGS.
+# This is equivalent to the 'notrace' and '__noscs' annotations.
+KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS), $(KBUILD_CFLAGS))
# Starting from 13.0.0 llvm emits SHT_REL section '.llvm.call-graph-profile'
# when profile optimization is applied. gen-hyprel does not support SHT_REL and
# causes a build failure. Remove profile optimization flags.
KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%, $(KBUILD_CFLAGS))
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
-
-# KVM nVHE code is run at a different exception code with a different map, so
-# compiler instrumentation that inserts callbacks or checks into the code may
-# cause crashes. Just disable it.
-GCOV_PROFILE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-UBSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-
-# Skip objtool checking for this directory because nVHE code is compiled with
-# non-standard build rules.
-OBJECT_FILES_NON_STANDARD := y
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 7746ea507b6f..53efda0235cf 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -83,10 +83,10 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
{
/* Disable and flush SPE data generation */
if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
- __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_save_spe(host_data_ptr(host_debug_state.pmscr_el1));
/* Disable and flush Self-Hosted Trace generation */
if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
- __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1);
+ __debug_save_trace(host_data_ptr(host_debug_state.trfcr_el1));
}
void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
@@ -97,9 +97,9 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
{
if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
- __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_restore_spe(*host_data_ptr(host_debug_state.pmscr_el1));
if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
- __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
+ __debug_restore_trace(*host_data_ptr(host_debug_state.trfcr_el1));
}
void __debug_switch_to_host(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 320f2eaa14a9..e715c157c2c4 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -67,6 +67,9 @@ struct kvm_ffa_buffers {
*/
static struct kvm_ffa_buffers hyp_buffers;
static struct kvm_ffa_buffers host_buffers;
+static u32 hyp_ffa_version;
+static bool has_version_negotiated;
+static hyp_spinlock_t version_lock;
static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
{
@@ -177,6 +180,14 @@ static void ffa_retrieve_req(struct arm_smccc_res *res, u32 len)
res);
}
+static void ffa_rx_release(struct arm_smccc_res *res)
+{
+ arm_smccc_1_1_smc(FFA_RX_RELEASE,
+ 0, 0,
+ 0, 0, 0, 0, 0,
+ res);
+}
+
static void do_ffa_rxtx_map(struct arm_smccc_res *res,
struct kvm_cpu_context *ctxt)
{
@@ -454,7 +465,7 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
memcpy(buf, host_buffers.tx, fraglen);
ep_mem_access = (void *)buf +
- ffa_mem_desc_offset(buf, 0, FFA_VERSION_1_0);
+ ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
offset = ep_mem_access->composite_off;
if (!offset || buf->ep_count != 1 || buf->sender_id != HOST_FFA_ID) {
ret = FFA_RET_INVALID_PARAMETERS;
@@ -533,7 +544,7 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
fraglen = res->a2;
ep_mem_access = (void *)buf +
- ffa_mem_desc_offset(buf, 0, FFA_VERSION_1_0);
+ ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
offset = ep_mem_access->composite_off;
/*
* We can trust the SPMD to get this right, but let's at least
@@ -543,16 +554,19 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
if (WARN_ON(offset > len ||
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
ret = FFA_RET_ABORTED;
+ ffa_rx_release(res);
goto out_unlock;
}
if (len > ffa_desc_buf.len) {
ret = FFA_RET_NO_MEMORY;
+ ffa_rx_release(res);
goto out_unlock;
}
buf = ffa_desc_buf.buf;
memcpy(buf, hyp_buffers.rx, fraglen);
+ ffa_rx_release(res);
for (fragoff = fraglen; fragoff < len; fragoff += fraglen) {
ffa_mem_frag_rx(res, handle_lo, handle_hi, fragoff);
@@ -563,6 +577,7 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
fraglen = res->a3;
memcpy((void *)buf + fragoff, hyp_buffers.rx, fraglen);
+ ffa_rx_release(res);
}
ffa_mem_reclaim(res, handle_lo, handle_hi, flags);
@@ -600,7 +615,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MSG_POLL:
case FFA_MSG_WAIT:
/* 32-bit variants of 64-bit calls */
- case FFA_MSG_SEND_DIRECT_REQ:
case FFA_MSG_SEND_DIRECT_RESP:
case FFA_RXTX_MAP:
case FFA_MEM_DONATE:
@@ -640,6 +654,132 @@ out_handled:
return true;
}
+static int hyp_ffa_post_init(void)
+{
+ size_t min_rxtx_sz;
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_smc(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0 != FFA_SUCCESS)
+ return -EOPNOTSUPP;
+
+ if (res.a2 != HOST_FFA_ID)
+ return -EINVAL;
+
+ arm_smccc_1_1_smc(FFA_FEATURES, FFA_FN64_RXTX_MAP,
+ 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0 != FFA_SUCCESS)
+ return -EOPNOTSUPP;
+
+ switch (res.a2) {
+ case FFA_FEAT_RXTX_MIN_SZ_4K:
+ min_rxtx_sz = SZ_4K;
+ break;
+ case FFA_FEAT_RXTX_MIN_SZ_16K:
+ min_rxtx_sz = SZ_16K;
+ break;
+ case FFA_FEAT_RXTX_MIN_SZ_64K:
+ min_rxtx_sz = SZ_64K;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (min_rxtx_sz > PAGE_SIZE)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static void do_ffa_version(struct arm_smccc_res *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, ffa_req_version, ctxt, 1);
+
+ if (FFA_MAJOR_VERSION(ffa_req_version) != 1) {
+ res->a0 = FFA_RET_NOT_SUPPORTED;
+ return;
+ }
+
+ hyp_spin_lock(&version_lock);
+ if (has_version_negotiated) {
+ res->a0 = hyp_ffa_version;
+ goto unlock;
+ }
+
+ /*
+ * If the client driver tries to downgrade the version, we need to ask
+ * first if TEE supports it.
+ */
+ if (FFA_MINOR_VERSION(ffa_req_version) < FFA_MINOR_VERSION(hyp_ffa_version)) {
+ arm_smccc_1_1_smc(FFA_VERSION, ffa_req_version, 0,
+ 0, 0, 0, 0, 0,
+ res);
+ if (res->a0 == FFA_RET_NOT_SUPPORTED)
+ goto unlock;
+
+ hyp_ffa_version = ffa_req_version;
+ }
+
+ if (hyp_ffa_post_init())
+ res->a0 = FFA_RET_NOT_SUPPORTED;
+ else {
+ has_version_negotiated = true;
+ res->a0 = hyp_ffa_version;
+ }
+unlock:
+ hyp_spin_unlock(&version_lock);
+}
+
+static void do_ffa_part_get(struct arm_smccc_res *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, uuid0, ctxt, 1);
+ DECLARE_REG(u32, uuid1, ctxt, 2);
+ DECLARE_REG(u32, uuid2, ctxt, 3);
+ DECLARE_REG(u32, uuid3, ctxt, 4);
+ DECLARE_REG(u32, flags, ctxt, 5);
+ u32 count, partition_sz, copy_sz;
+
+ hyp_spin_lock(&host_buffers.lock);
+ if (!host_buffers.rx) {
+ ffa_to_smccc_res(res, FFA_RET_BUSY);
+ goto out_unlock;
+ }
+
+ arm_smccc_1_1_smc(FFA_PARTITION_INFO_GET, uuid0, uuid1,
+ uuid2, uuid3, flags, 0, 0,
+ res);
+
+ if (res->a0 != FFA_SUCCESS)
+ goto out_unlock;
+
+ count = res->a2;
+ if (!count)
+ goto out_unlock;
+
+ if (hyp_ffa_version > FFA_VERSION_1_0) {
+ /* Get the number of partitions deployed in the system */
+ if (flags & 0x1)
+ goto out_unlock;
+
+ partition_sz = res->a3;
+ } else {
+ /* FFA_VERSION_1_0 lacks the size in the response */
+ partition_sz = FFA_1_0_PARTITON_INFO_SZ;
+ }
+
+ copy_sz = partition_sz * count;
+ if (copy_sz > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
+ ffa_to_smccc_res(res, FFA_RET_ABORTED);
+ goto out_unlock;
+ }
+
+ memcpy(host_buffers.rx, hyp_buffers.rx, copy_sz);
+out_unlock:
+ hyp_spin_unlock(&host_buffers.lock);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_res res;
@@ -660,6 +800,11 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
if (!is_ffa_call(func_id))
return false;
+ if (!has_version_negotiated && func_id != FFA_VERSION) {
+ ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS);
+ goto out_handled;
+ }
+
switch (func_id) {
case FFA_FEATURES:
if (!do_ffa_features(&res, host_ctxt))
@@ -686,6 +831,12 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_MEM_FRAG_TX:
do_ffa_mem_frag_tx(&res, host_ctxt);
goto out_handled;
+ case FFA_VERSION:
+ do_ffa_version(&res, host_ctxt);
+ goto out_handled;
+ case FFA_PARTITION_INFO_GET:
+ do_ffa_part_get(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
@@ -700,13 +851,12 @@ out_handled:
int hyp_ffa_init(void *pages)
{
struct arm_smccc_res res;
- size_t min_rxtx_sz;
void *tx, *rx;
if (kvm_host_psci_config.smccc_version < ARM_SMCCC_VERSION_1_2)
return 0;
- arm_smccc_1_1_smc(FFA_VERSION, FFA_VERSION_1_0, 0, 0, 0, 0, 0, 0, &res);
+ arm_smccc_1_1_smc(FFA_VERSION, FFA_VERSION_1_1, 0, 0, 0, 0, 0, 0, &res);
if (res.a0 == FFA_RET_NOT_SUPPORTED)
return 0;
@@ -726,34 +876,10 @@ int hyp_ffa_init(void *pages)
if (FFA_MAJOR_VERSION(res.a0) != 1)
return -EOPNOTSUPP;
- arm_smccc_1_1_smc(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0, &res);
- if (res.a0 != FFA_SUCCESS)
- return -EOPNOTSUPP;
-
- if (res.a2 != HOST_FFA_ID)
- return -EINVAL;
-
- arm_smccc_1_1_smc(FFA_FEATURES, FFA_FN64_RXTX_MAP,
- 0, 0, 0, 0, 0, 0, &res);
- if (res.a0 != FFA_SUCCESS)
- return -EOPNOTSUPP;
-
- switch (res.a2) {
- case FFA_FEAT_RXTX_MIN_SZ_4K:
- min_rxtx_sz = SZ_4K;
- break;
- case FFA_FEAT_RXTX_MIN_SZ_16K:
- min_rxtx_sz = SZ_16K;
- break;
- case FFA_FEAT_RXTX_MIN_SZ_64K:
- min_rxtx_sz = SZ_64K;
- break;
- default:
- return -EINVAL;
- }
-
- if (min_rxtx_sz > PAGE_SIZE)
- return -EOPNOTSUPP;
+ if (FFA_MINOR_VERSION(res.a0) < FFA_MINOR_VERSION(FFA_VERSION_1_1))
+ hyp_ffa_version = res.a0;
+ else
+ hyp_ffa_version = FFA_VERSION_1_1;
tx = pages;
pages += KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE;
@@ -776,5 +902,6 @@ int hyp_ffa_init(void *pages)
.lock = __HYP_SPIN_LOCK_UNLOCKED,
};
+ version_lock = __HYP_SPIN_LOCK_UNLOCKED;
return 0;
}
diff --git a/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c b/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c
index 6bc88a756cb7..b63f4e1c1033 100644
--- a/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c
+++ b/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c
@@ -50,6 +50,9 @@
#ifndef R_AARCH64_ABS64
#define R_AARCH64_ABS64 257
#endif
+#ifndef R_AARCH64_ABS32
+#define R_AARCH64_ABS32 258
+#endif
#ifndef R_AARCH64_PREL64
#define R_AARCH64_PREL64 260
#endif
@@ -383,6 +386,9 @@ static void emit_rela_section(Elf64_Shdr *sh_rela)
case R_AARCH64_ABS64:
emit_rela_abs64(rela, sh_orig_name);
break;
+ /* Allow 32-bit absolute relocation, for kCFI type hashes. */
+ case R_AARCH64_ABS32:
+ break;
/* Allow position-relative data relocations. */
case R_AARCH64_PREL64:
case R_AARCH64_PREL32:
diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S
index 135cfb294ee5..3d610fc51f4d 100644
--- a/arch/arm64/kvm/hyp/nvhe/host.S
+++ b/arch/arm64/kvm/hyp/nvhe/host.S
@@ -197,12 +197,6 @@ SYM_FUNC_END(__host_hvc)
sub x0, sp, x0 // x0'' = sp' - x0' = (sp + x0) - sp = x0
sub sp, sp, x0 // sp'' = sp' - x0 = (sp + x0) - x0 = sp
- /* If a guest is loaded, panic out of it. */
- stp x0, x1, [sp, #-16]!
- get_loaded_vcpu x0, x1
- cbnz x0, __guest_exit_panic
- add sp, sp, #16
-
/*
* The panic may not be clean if the exception is taken before the host
* context has been saved by __host_exit or after the hyp context has
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-init.S b/arch/arm64/kvm/hyp/nvhe/hyp-init.S
index 2994878d68ea..07120b37da35 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-init.S
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-init.S
@@ -5,6 +5,7 @@
*/
#include <linux/arm-smccc.h>
+#include <linux/cfi_types.h>
#include <linux/linkage.h>
#include <asm/alternative.h>
@@ -265,33 +266,38 @@ alternative_else_nop_endif
SYM_CODE_END(__kvm_handle_stub_hvc)
-SYM_FUNC_START(__pkvm_init_switch_pgd)
+/*
+ * void __pkvm_init_switch_pgd(phys_addr_t pgd, unsigned long sp,
+ * void (*fn)(void));
+ *
+ * SYM_TYPED_FUNC_START() allows C to call this ID-mapped function indirectly
+ * using a physical pointer without triggering a kCFI failure.
+ */
+SYM_TYPED_FUNC_START(__pkvm_init_switch_pgd)
/* Turn the MMU off */
pre_disable_mmu_workaround
- mrs x2, sctlr_el2
- bic x3, x2, #SCTLR_ELx_M
- msr sctlr_el2, x3
+ mrs x3, sctlr_el2
+ bic x4, x3, #SCTLR_ELx_M
+ msr sctlr_el2, x4
isb
tlbi alle2
/* Install the new pgtables */
- ldr x3, [x0, #NVHE_INIT_PGD_PA]
- phys_to_ttbr x4, x3
+ phys_to_ttbr x5, x0
alternative_if ARM64_HAS_CNP
- orr x4, x4, #TTBR_CNP_BIT
+ orr x5, x5, #TTBR_CNP_BIT
alternative_else_nop_endif
- msr ttbr0_el2, x4
+ msr ttbr0_el2, x5
/* Set the new stack pointer */
- ldr x0, [x0, #NVHE_INIT_STACK_HYP_VA]
- mov sp, x0
+ mov sp, x1
/* And turn the MMU back on! */
dsb nsh
isb
- set_sctlr_el2 x2
- ret x1
+ set_sctlr_el2 x3
+ ret x2
SYM_FUNC_END(__pkvm_init_switch_pgd)
.popsection
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 2385fd03ed87..f43d845f3c4e 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -23,26 +23,84 @@ DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt);
+static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu)
+{
+ __vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
+ /*
+ * On saving/restoring guest sve state, always use the maximum VL for
+ * the guest. The layout of the data when saving the sve state depends
+ * on the VL, so use a consistent (i.e., the maximum) guest VL.
+ */
+ sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
+ __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true);
+ write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+}
+
+static void __hyp_sve_restore_host(void)
+{
+ struct cpu_sve_state *sve_state = *host_data_ptr(sve_state);
+
+ /*
+ * On saving/restoring host sve state, always use the maximum VL for
+ * the host. The layout of the data when saving the sve state depends
+ * on the VL, so use a consistent (i.e., the maximum) host VL.
+ *
+ * Setting ZCR_EL2 to ZCR_ELx_LEN_MASK sets the effective length
+ * supported by the system (or limited at EL3).
+ */
+ write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+ __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
+ &sve_state->fpsr,
+ true);
+ write_sysreg_el1(sve_state->zcr_el1, SYS_ZCR);
+}
+
+static void fpsimd_sve_flush(void)
+{
+ *host_data_ptr(fp_owner) = FP_STATE_HOST_OWNED;
+}
+
+static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
+{
+ if (!guest_owns_fp_regs())
+ return;
+
+ cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+ isb();
+
+ if (vcpu_has_sve(vcpu))
+ __hyp_sve_save_guest(vcpu);
+ else
+ __fpsimd_save_state(&vcpu->arch.ctxt.fp_regs);
+
+ if (system_supports_sve())
+ __hyp_sve_restore_host();
+ else
+ __fpsimd_restore_state(*host_data_ptr(fpsimd_state));
+
+ *host_data_ptr(fp_owner) = FP_STATE_HOST_OWNED;
+}
+
static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
{
struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
+ fpsimd_sve_flush();
+
hyp_vcpu->vcpu.arch.ctxt = host_vcpu->arch.ctxt;
hyp_vcpu->vcpu.arch.sve_state = kern_hyp_va(host_vcpu->arch.sve_state);
- hyp_vcpu->vcpu.arch.sve_max_vl = host_vcpu->arch.sve_max_vl;
+ /* Limit guest vector length to the maximum supported by the host. */
+ hyp_vcpu->vcpu.arch.sve_max_vl = min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
hyp_vcpu->vcpu.arch.hw_mmu = host_vcpu->arch.hw_mmu;
hyp_vcpu->vcpu.arch.hcr_el2 = host_vcpu->arch.hcr_el2;
hyp_vcpu->vcpu.arch.mdcr_el2 = host_vcpu->arch.mdcr_el2;
- hyp_vcpu->vcpu.arch.cptr_el2 = host_vcpu->arch.cptr_el2;
hyp_vcpu->vcpu.arch.iflags = host_vcpu->arch.iflags;
- hyp_vcpu->vcpu.arch.fp_state = host_vcpu->arch.fp_state;
hyp_vcpu->vcpu.arch.debug_ptr = kern_hyp_va(host_vcpu->arch.debug_ptr);
- hyp_vcpu->vcpu.arch.host_fpsimd_state = host_vcpu->arch.host_fpsimd_state;
hyp_vcpu->vcpu.arch.vsesr_el2 = host_vcpu->arch.vsesr_el2;
@@ -56,15 +114,15 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
struct vgic_v3_cpu_if *host_cpu_if = &host_vcpu->arch.vgic_cpu.vgic_v3;
unsigned int i;
+ fpsimd_sve_sync(&hyp_vcpu->vcpu);
+
host_vcpu->arch.ctxt = hyp_vcpu->vcpu.arch.ctxt;
host_vcpu->arch.hcr_el2 = hyp_vcpu->vcpu.arch.hcr_el2;
- host_vcpu->arch.cptr_el2 = hyp_vcpu->vcpu.arch.cptr_el2;
host_vcpu->arch.fault = hyp_vcpu->vcpu.arch.fault;
host_vcpu->arch.iflags = hyp_vcpu->vcpu.arch.iflags;
- host_vcpu->arch.fp_state = hyp_vcpu->vcpu.arch.fp_state;
host_cpu_if->vgic_hcr = hyp_cpu_if->vgic_hcr;
for (i = 0; i < hyp_cpu_if->used_lrs; ++i)
@@ -82,6 +140,17 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
struct pkvm_hyp_vcpu *hyp_vcpu;
struct kvm *host_kvm;
+ /*
+ * KVM (and pKVM) doesn't support SME guests for now, and
+ * ensures that SME features aren't enabled in pstate when
+ * loading a vcpu. Therefore, if SME features enabled the host
+ * is misbehaving.
+ */
+ if (unlikely(system_supports_sme() && read_sysreg_s(SYS_SVCR))) {
+ ret = -EINVAL;
+ goto out;
+ }
+
host_kvm = kern_hyp_va(host_vcpu->kvm);
hyp_vcpu = pkvm_load_hyp_vcpu(host_kvm->arch.pkvm.handle,
host_vcpu->vcpu_idx);
@@ -178,16 +247,6 @@ static void handle___vgic_v3_get_gic_config(struct kvm_cpu_context *host_ctxt)
cpu_reg(host_ctxt, 1) = __vgic_v3_get_gic_config();
}
-static void handle___vgic_v3_read_vmcr(struct kvm_cpu_context *host_ctxt)
-{
- cpu_reg(host_ctxt, 1) = __vgic_v3_read_vmcr();
-}
-
-static void handle___vgic_v3_write_vmcr(struct kvm_cpu_context *host_ctxt)
-{
- __vgic_v3_write_vmcr(cpu_reg(host_ctxt, 1));
-}
-
static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt)
{
__vgic_v3_init_lrs();
@@ -198,18 +257,18 @@ static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt)
cpu_reg(host_ctxt, 1) = __kvm_get_mdcr_el2();
}
-static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt)
+static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt)
{
DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
- __vgic_v3_save_aprs(kern_hyp_va(cpu_if));
+ __vgic_v3_save_vmcr_aprs(kern_hyp_va(cpu_if));
}
-static void handle___vgic_v3_restore_aprs(struct kvm_cpu_context *host_ctxt)
+static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt)
{
DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
- __vgic_v3_restore_aprs(kern_hyp_va(cpu_if));
+ __vgic_v3_restore_vmcr_aprs(kern_hyp_va(cpu_if));
}
static void handle___pkvm_init(struct kvm_cpu_context *host_ctxt)
@@ -340,10 +399,8 @@ static const hcall_t host_hcall[] = {
HANDLE_FUNC(__kvm_tlb_flush_vmid_range),
HANDLE_FUNC(__kvm_flush_cpu_context),
HANDLE_FUNC(__kvm_timer_set_cntvoff),
- HANDLE_FUNC(__vgic_v3_read_vmcr),
- HANDLE_FUNC(__vgic_v3_write_vmcr),
- HANDLE_FUNC(__vgic_v3_save_aprs),
- HANDLE_FUNC(__vgic_v3_restore_aprs),
+ HANDLE_FUNC(__vgic_v3_save_vmcr_aprs),
+ HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
HANDLE_FUNC(__pkvm_vcpu_init_traps),
HANDLE_FUNC(__pkvm_init_vm),
HANDLE_FUNC(__pkvm_init_vcpu),
@@ -420,11 +477,7 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
handle_host_smc(host_ctxt);
break;
case ESR_ELx_EC_SVE:
- if (has_hvhe())
- sysreg_clear_set(cpacr_el1, 0, (CPACR_EL1_ZEN_EL1EN |
- CPACR_EL1_ZEN_EL0EN));
- else
- sysreg_clear_set(cptr_el2, CPTR_EL2_TZ, 0);
+ cpacr_clear_set(0, CPACR_ELx_ZEN);
isb();
sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
break;
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 861c76021a25..caba3e4bd09e 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -533,7 +533,13 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
int ret = 0;
esr = read_sysreg_el2(SYS_ESR);
- BUG_ON(!__get_fault_info(esr, &fault));
+ if (!__get_fault_info(esr, &fault)) {
+ /*
+ * We've presumably raced with a page-table change which caused
+ * AT to fail, try again.
+ */
+ return;
+ }
addr = (fault.hpfar_el2 & HPFAR_MASK) << 8;
ret = host_stage2_idmap(addr);
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 26dd9a20ad6e..187a5f4d56c0 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -18,6 +18,8 @@ unsigned long __icache_flags;
/* Used by kvm_get_vttbr(). */
unsigned int kvm_arm_vmid_bits;
+unsigned int kvm_host_sve_max_vl;
+
/*
* Set trap register values based on features in ID_AA64PFR0.
*/
@@ -31,9 +33,9 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
/* Protected KVM does not support AArch32 guests. */
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
- PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_ELx_64BIT_ONLY);
+ PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL0_IMP);
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
- PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_ELx_64BIT_ONLY);
+ PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL1_IMP);
/*
* Linux guests assume support for floating-point and Advanced SIMD. Do
@@ -63,7 +65,7 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
/* Trap SVE */
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
if (has_hvhe())
- cptr_clear |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
+ cptr_clear |= CPACR_ELx_ZEN;
else
cptr_set |= CPTR_EL2_TZ;
}
@@ -200,7 +202,7 @@ static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
}
/*
- * Initialize trap register values for protected VMs.
+ * Initialize trap register values in protected mode.
*/
void __pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
{
@@ -430,6 +432,7 @@ static void *map_donated_memory(unsigned long host_va, size_t size)
static void __unmap_donated_memory(void *va, size_t size)
{
+ kvm_flush_dcache_to_poc(va, size);
WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(va),
PAGE_ALIGN(size) >> PAGE_SHIFT));
}
@@ -574,6 +577,8 @@ unlock:
if (ret)
unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu));
+ hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);
+
return ret;
}
diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c
index d57bcb6ab94d..dfe8fe0f7eaf 100644
--- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c
+++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c
@@ -205,7 +205,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on)
struct psci_boot_args *boot_args;
struct kvm_cpu_context *host_ctxt;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
if (is_cpu_on)
boot_args = this_cpu_ptr(&cpu_on_args);
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index bc58d1b515af..174007f3fadd 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -67,6 +67,28 @@ static int divide_memory_pool(void *virt, unsigned long size)
return 0;
}
+static int pkvm_create_host_sve_mappings(void)
+{
+ void *start, *end;
+ int ret, i;
+
+ if (!system_supports_sve())
+ return 0;
+
+ for (i = 0; i < hyp_nr_cpus; i++) {
+ struct kvm_host_data *host_data = per_cpu_ptr(&kvm_host_data, i);
+ struct cpu_sve_state *sve_state = host_data->sve_state;
+
+ start = kern_hyp_va(sve_state);
+ end = start + PAGE_ALIGN(pkvm_host_sve_state_size());
+ ret = pkvm_create_mappings(start, end, PAGE_HYP);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
unsigned long *per_cpu_base,
u32 hyp_va_bits)
@@ -125,6 +147,8 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
return ret;
}
+ pkvm_create_host_sve_mappings();
+
/*
* Map the host sections RO in the hypervisor, but transfer the
* ownership from the host to the hypervisor itself to make sure they
@@ -257,8 +281,7 @@ static int fix_hyp_pgtable_refcnt(void)
void __noreturn __pkvm_init_finalise(void)
{
- struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
- struct kvm_cpu_context *host_ctxt = &host_data->host_ctxt;
+ struct kvm_cpu_context *host_ctxt = host_data_ptr(host_ctxt);
unsigned long nr_pages, reserved_pages, pfn;
int ret;
@@ -316,7 +339,7 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
{
struct kvm_nvhe_init_params *params;
void *virt = hyp_phys_to_virt(phys);
- void (*fn)(phys_addr_t params_pa, void *finalize_fn_va);
+ typeof(__pkvm_init_switch_pgd) *fn;
int ret;
BUG_ON(kvm_check_pvm_sysreg_table());
@@ -340,7 +363,7 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
/* Jump in the idmap page to switch to the new page-tables */
params = this_cpu_ptr(&kvm_init_params);
fn = (typeof(fn))__hyp_pa(__pkvm_init_switch_pgd);
- fn(__hyp_pa(params), __pkvm_init_finalise);
+ fn(params->pgd_pa, params->stack_hyp_va, __pkvm_init_finalise);
unreachable();
}
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index c50f8459e4fc..6af179c6356d 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -40,7 +40,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
{
u64 val;
- ___activate_traps(vcpu);
+ ___activate_traps(vcpu, vcpu->arch.hcr_el2);
__activate_traps_common(vcpu);
val = vcpu->arch.cptr_el2;
@@ -48,15 +48,14 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
if (cpus_have_final_cap(ARM64_SME)) {
if (has_hvhe())
- val &= ~(CPACR_EL1_SMEN_EL1EN | CPACR_EL1_SMEN_EL0EN);
+ val &= ~CPACR_ELx_SMEN;
else
val |= CPTR_EL2_TSM;
}
- if (!guest_owns_fp_regs(vcpu)) {
+ if (!guest_owns_fp_regs()) {
if (has_hvhe())
- val &= ~(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |
- CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
+ val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
else
val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
@@ -182,6 +181,25 @@ static bool kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu, u64 *exit_code)
kvm_handle_pvm_sysreg(vcpu, exit_code));
}
+static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
+{
+ /*
+ * Non-protected kvm relies on the host restoring its sve state.
+ * Protected kvm restores the host's sve state as not to reveal that
+ * fpsimd was used by a guest nor leak upper sve bits.
+ */
+ if (unlikely(is_protected_kvm_enabled() && system_supports_sve())) {
+ __hyp_sve_save_host();
+
+ /* Re-enable SVE traps if not supported for the guest vcpu. */
+ if (!vcpu_has_sve(vcpu))
+ cpacr_clear_set(CPACR_ELx_ZEN, 0);
+
+ } else {
+ __fpsimd_save_state(*host_data_ptr(fpsimd_state));
+ }
+}
+
static const exit_handler_fn hyp_exit_handlers[] = {
[0 ... ESR_ELx_EC_MAX] = NULL,
[ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32,
@@ -191,7 +209,6 @@ static const exit_handler_fn hyp_exit_handlers[] = {
[ESR_ELx_EC_IABT_LOW] = kvm_hyp_handle_iabt_low,
[ESR_ELx_EC_DABT_LOW] = kvm_hyp_handle_dabt_low,
[ESR_ELx_EC_WATCHPT_LOW] = kvm_hyp_handle_watchpt_low,
- [ESR_ELx_EC_PAC] = kvm_hyp_handle_ptrauth,
[ESR_ELx_EC_MOPS] = kvm_hyp_handle_mops,
};
@@ -203,13 +220,12 @@ static const exit_handler_fn pvm_exit_handlers[] = {
[ESR_ELx_EC_IABT_LOW] = kvm_hyp_handle_iabt_low,
[ESR_ELx_EC_DABT_LOW] = kvm_hyp_handle_dabt_low,
[ESR_ELx_EC_WATCHPT_LOW] = kvm_hyp_handle_watchpt_low,
- [ESR_ELx_EC_PAC] = kvm_hyp_handle_ptrauth,
[ESR_ELx_EC_MOPS] = kvm_hyp_handle_mops,
};
static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
{
- if (unlikely(kvm_vm_is_protected(kern_hyp_va(vcpu->kvm))))
+ if (unlikely(vcpu_is_protected(vcpu)))
return pvm_exit_handlers;
return hyp_exit_handlers;
@@ -228,9 +244,7 @@ static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
*/
static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)
{
- struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-
- if (kvm_vm_is_protected(kvm) && vcpu_mode_is_32bit(vcpu)) {
+ if (unlikely(vcpu_is_protected(vcpu) && vcpu_mode_is_32bit(vcpu))) {
/*
* As we have caught the guest red-handed, decide that it isn't
* fit for purpose anymore by making the vcpu invalid. The VMM
@@ -264,7 +278,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
pmr_sync();
}
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
@@ -337,7 +351,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
__sysreg_restore_state_nvhe(host_ctxt);
- if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)
+ if (guest_owns_fp_regs())
__fpsimd_save_fpexc32(vcpu);
__debug_switch_to_host(vcpu);
@@ -367,7 +381,7 @@ asmlinkage void __noreturn hyp_panic(void)
struct kvm_cpu_context *host_ctxt;
struct kvm_vcpu *vcpu;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
vcpu = host_ctxt->__hyp_running_vcpu;
if (vcpu) {
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index edd969a1f36b..2860548d4250 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -276,7 +276,7 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
* of AArch32 feature id registers.
*/
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
- PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_ELx_64BIT_ONLY);
+ PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_EL1_IMP);
return pvm_access_raz_wi(vcpu, p, r);
}
diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c
index 2fc68da4036d..ca3c09df8d7c 100644
--- a/arch/arm64/kvm/hyp/nvhe/tlb.c
+++ b/arch/arm64/kvm/hyp/nvhe/tlb.c
@@ -11,13 +11,23 @@
#include <nvhe/mem_protect.h>
struct tlb_inv_context {
- u64 tcr;
+ struct kvm_s2_mmu *mmu;
+ u64 tcr;
+ u64 sctlr;
};
-static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
- struct tlb_inv_context *cxt,
- bool nsh)
+static void enter_vmid_context(struct kvm_s2_mmu *mmu,
+ struct tlb_inv_context *cxt,
+ bool nsh)
{
+ struct kvm_s2_mmu *host_s2_mmu = &host_mmu.arch.mmu;
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_vcpu *vcpu;
+
+ host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ vcpu = host_ctxt->__hyp_running_vcpu;
+ cxt->mmu = NULL;
+
/*
* We have two requirements:
*
@@ -40,20 +50,55 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
else
dsb(ish);
+ /*
+ * If we're already in the desired context, then there's nothing to do.
+ */
+ if (vcpu) {
+ /*
+ * We're in guest context. However, for this to work, this needs
+ * to be called from within __kvm_vcpu_run(), which ensures that
+ * __hyp_running_vcpu is set to the current guest vcpu.
+ */
+ if (mmu == vcpu->arch.hw_mmu || WARN_ON(mmu != host_s2_mmu))
+ return;
+
+ cxt->mmu = vcpu->arch.hw_mmu;
+ } else {
+ /* We're in host context. */
+ if (mmu == host_s2_mmu)
+ return;
+
+ cxt->mmu = host_s2_mmu;
+ }
+
if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
u64 val;
/*
* For CPUs that are affected by ARM 1319367, we need to
- * avoid a host Stage-1 walk while we have the guest's
- * VMID set in the VTTBR in order to invalidate TLBs.
- * We're guaranteed that the S1 MMU is enabled, so we can
- * simply set the EPD bits to avoid any further TLB fill.
+ * avoid a Stage-1 walk with the old VMID while we have
+ * the new VMID set in the VTTBR in order to invalidate TLBs.
+ * We're guaranteed that the host S1 MMU is enabled, so
+ * we can simply set the EPD bits to avoid any further
+ * TLB fill. For guests, we ensure that the S1 MMU is
+ * temporarily enabled in the next context.
*/
val = cxt->tcr = read_sysreg_el1(SYS_TCR);
val |= TCR_EPD1_MASK | TCR_EPD0_MASK;
write_sysreg_el1(val, SYS_TCR);
isb();
+
+ if (vcpu) {
+ val = cxt->sctlr = read_sysreg_el1(SYS_SCTLR);
+ if (!(val & SCTLR_ELx_M)) {
+ val |= SCTLR_ELx_M;
+ write_sysreg_el1(val, SYS_SCTLR);
+ isb();
+ }
+ } else {
+ /* The host S1 MMU is always enabled. */
+ cxt->sctlr = SCTLR_ELx_M;
+ }
}
/*
@@ -62,18 +107,40 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
* ensuring that we always have an ISB, but not two ISBs back
* to back.
*/
- __load_stage2(mmu, kern_hyp_va(mmu->arch));
+ if (vcpu)
+ __load_host_stage2();
+ else
+ __load_stage2(mmu, kern_hyp_va(mmu->arch));
+
asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT));
}
-static void __tlb_switch_to_host(struct tlb_inv_context *cxt)
+static void exit_vmid_context(struct tlb_inv_context *cxt)
{
- __load_host_stage2();
+ struct kvm_s2_mmu *mmu = cxt->mmu;
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_vcpu *vcpu;
+
+ host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ vcpu = host_ctxt->__hyp_running_vcpu;
+
+ if (!mmu)
+ return;
+
+ if (vcpu)
+ __load_stage2(mmu, kern_hyp_va(mmu->arch));
+ else
+ __load_host_stage2();
if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
- /* Ensure write of the host VMID */
+ /* Ensure write of the old VMID */
isb();
- /* Restore the host's TCR_EL1 */
+
+ if (!(cxt->sctlr & SCTLR_ELx_M)) {
+ write_sysreg_el1(cxt->sctlr, SYS_SCTLR);
+ isb();
+ }
+
write_sysreg_el1(cxt->tcr, SYS_TCR);
}
}
@@ -84,7 +151,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
struct tlb_inv_context cxt;
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt, false);
+ enter_vmid_context(mmu, &cxt, false);
/*
* We could do so much better if we had the VA as well.
@@ -105,7 +172,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
dsb(ish);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
@@ -114,7 +181,7 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
struct tlb_inv_context cxt;
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt, true);
+ enter_vmid_context(mmu, &cxt, true);
/*
* We could do so much better if we had the VA as well.
@@ -135,7 +202,7 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
dsb(nsh);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
@@ -152,7 +219,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
start = round_down(start, stride);
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt, false);
+ enter_vmid_context(mmu, &cxt, false);
__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride,
TLBI_TTL_UNKNOWN);
@@ -162,7 +229,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
dsb(ish);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
@@ -170,13 +237,13 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
struct tlb_inv_context cxt;
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt, false);
+ enter_vmid_context(mmu, &cxt, false);
__tlbi(vmalls12e1is);
dsb(ish);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu)
@@ -184,19 +251,19 @@ void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu)
struct tlb_inv_context cxt;
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt, false);
+ enter_vmid_context(mmu, &cxt, false);
__tlbi(vmalle1);
asm volatile("ic iallu");
dsb(nsh);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_flush_vm_context(void)
{
- /* Same remark as in __tlb_switch_to_guest() */
+ /* Same remark as in enter_vmid_context() */
dsb(ish);
__tlbi(alle1is);
dsb(ish);
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 5a59ef88b646..9e2bbee77491 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -914,12 +914,12 @@ static void stage2_unmap_put_pte(const struct kvm_pgtable_visit_ctx *ctx,
static bool stage2_pte_cacheable(struct kvm_pgtable *pgt, kvm_pte_t pte)
{
u64 memattr = pte & KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR;
- return memattr == KVM_S2_MEMATTR(pgt, NORMAL);
+ return kvm_pte_valid(pte) && memattr == KVM_S2_MEMATTR(pgt, NORMAL);
}
static bool stage2_pte_executable(kvm_pte_t pte)
{
- return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN);
+ return kvm_pte_valid(pte) && !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN);
}
static u64 stage2_map_walker_phys_addr(const struct kvm_pgtable_visit_ctx *ctx,
@@ -979,6 +979,21 @@ static int stage2_map_walker_try_leaf(const struct kvm_pgtable_visit_ctx *ctx,
if (!stage2_pte_needs_update(ctx->old, new))
return -EAGAIN;
+ /* If we're only changing software bits, then store them and go! */
+ if (!kvm_pgtable_walk_shared(ctx) &&
+ !((ctx->old ^ new) & ~KVM_PTE_LEAF_ATTR_HI_SW)) {
+ bool old_is_counted = stage2_pte_is_counted(ctx->old);
+
+ if (old_is_counted != stage2_pte_is_counted(new)) {
+ if (old_is_counted)
+ mm_ops->put_page(ctx->ptep);
+ else
+ mm_ops->get_page(ctx->ptep);
+ }
+ WARN_ON_ONCE(!stage2_try_set_pte(ctx, new));
+ return 0;
+ }
+
if (!stage2_try_break_pte(ctx, data->mmu))
return -EAGAIN;
@@ -1370,7 +1385,7 @@ static int stage2_flush_walker(const struct kvm_pgtable_visit_ctx *ctx,
struct kvm_pgtable *pgt = ctx->arg;
struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops;
- if (!kvm_pte_valid(ctx->old) || !stage2_pte_cacheable(pgt, ctx->old))
+ if (!stage2_pte_cacheable(pgt, ctx->old))
return 0;
if (mm_ops->dcache_clean_inval_poc)
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 6cb638b184b1..7b397fad26f2 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -330,7 +330,7 @@ void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if)
write_gicreg(0, ICH_HCR_EL2);
}
-void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if)
+static void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if)
{
u64 val;
u32 nr_pre_bits;
@@ -363,7 +363,7 @@ void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if)
}
}
-void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if)
+static void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if)
{
u64 val;
u32 nr_pre_bits;
@@ -455,16 +455,35 @@ u64 __vgic_v3_get_gic_config(void)
return val;
}
-u64 __vgic_v3_read_vmcr(void)
+static u64 __vgic_v3_read_vmcr(void)
{
return read_gicreg(ICH_VMCR_EL2);
}
-void __vgic_v3_write_vmcr(u32 vmcr)
+static void __vgic_v3_write_vmcr(u32 vmcr)
{
write_gicreg(vmcr, ICH_VMCR_EL2);
}
+void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if)
+{
+ __vgic_v3_save_aprs(cpu_if);
+ if (cpu_if->vgic_sre)
+ cpu_if->vgic_vmcr = __vgic_v3_read_vmcr();
+}
+
+void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if)
+{
+ /*
+ * If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
+ * is dependent on ICC_SRE_EL1.SRE, and we have to perform the
+ * VMCR_EL2 save/restore in the world switch.
+ */
+ if (cpu_if->vgic_sre)
+ __vgic_v3_write_vmcr(cpu_if->vgic_vmcr);
+ __vgic_v3_restore_aprs(cpu_if);
+}
+
static int __vgic_v3_bpr_min(void)
{
/* See Pseudocode for VPriorityGroup */
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 1581df6aec87..77010b76c150 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -33,11 +33,114 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
+/*
+ * HCR_EL2 bits that the NV guest can freely change (no RES0/RES1
+ * semantics, irrespective of the configuration), but that cannot be
+ * applied to the actual HW as things would otherwise break badly.
+ *
+ * - TGE: we want the guest to use EL1, which is incompatible with
+ * this bit being set
+ *
+ * - API/APK: they are already accounted for by vcpu_load(), and can
+ * only take effect across a load/put cycle (such as ERET)
+ */
+#define NV_HCR_GUEST_EXCLUDE (HCR_TGE | HCR_API | HCR_APK)
+
+static u64 __compute_hcr(struct kvm_vcpu *vcpu)
+{
+ u64 hcr = vcpu->arch.hcr_el2;
+
+ if (!vcpu_has_nv(vcpu))
+ return hcr;
+
+ if (is_hyp_ctxt(vcpu)) {
+ hcr |= HCR_NV | HCR_NV2 | HCR_AT | HCR_TTLB;
+
+ if (!vcpu_el2_e2h_is_set(vcpu))
+ hcr |= HCR_NV1;
+
+ write_sysreg_s(vcpu->arch.ctxt.vncr_array, SYS_VNCR_EL2);
+ }
+
+ return hcr | (__vcpu_sys_reg(vcpu, HCR_EL2) & ~NV_HCR_GUEST_EXCLUDE);
+}
+
+static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
+{
+ u64 cptr;
+
+ /*
+ * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
+ * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
+ * except for some missing controls, such as TAM.
+ * In this case, CPTR_EL2.TAM has the same position with or without
+ * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
+ * shift value for trapping the AMU accesses.
+ */
+ u64 val = CPACR_ELx_TTA | CPTR_EL2_TAM;
+
+ if (guest_owns_fp_regs()) {
+ val |= CPACR_ELx_FPEN;
+ if (vcpu_has_sve(vcpu))
+ val |= CPACR_ELx_ZEN;
+ } else {
+ __activate_traps_fpsimd32(vcpu);
+ }
+
+ if (!vcpu_has_nv(vcpu))
+ goto write;
+
+ /*
+ * The architecture is a bit crap (what a surprise): an EL2 guest
+ * writing to CPTR_EL2 via CPACR_EL1 can't set any of TCPAC or TTA,
+ * as they are RES0 in the guest's view. To work around it, trap the
+ * sucker using the very same bit it can't set...
+ */
+ if (vcpu_el2_e2h_is_set(vcpu) && is_hyp_ctxt(vcpu))
+ val |= CPTR_EL2_TCPAC;
+
+ /*
+ * Layer the guest hypervisor's trap configuration on top of our own if
+ * we're in a nested context.
+ */
+ if (is_hyp_ctxt(vcpu))
+ goto write;
+
+ cptr = vcpu_sanitised_cptr_el2(vcpu);
+
+ /*
+ * Pay attention, there's some interesting detail here.
+ *
+ * The CPTR_EL2.xEN fields are 2 bits wide, although there are only two
+ * meaningful trap states when HCR_EL2.TGE = 0 (running a nested guest):
+ *
+ * - CPTR_EL2.xEN = x0, traps are enabled
+ * - CPTR_EL2.xEN = x1, traps are disabled
+ *
+ * In other words, bit[0] determines if guest accesses trap or not. In
+ * the interest of simplicity, clear the entire field if the guest
+ * hypervisor has traps enabled to dispel any illusion of something more
+ * complicated taking place.
+ */
+ if (!(SYS_FIELD_GET(CPACR_ELx, FPEN, cptr) & BIT(0)))
+ val &= ~CPACR_ELx_FPEN;
+ if (!(SYS_FIELD_GET(CPACR_ELx, ZEN, cptr) & BIT(0)))
+ val &= ~CPACR_ELx_ZEN;
+
+ if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
+ val |= cptr & CPACR_ELx_E0POE;
+
+ val |= cptr & CPTR_EL2_TCPAC;
+
+write:
+ write_sysreg(val, cpacr_el1);
+}
+
static void __activate_traps(struct kvm_vcpu *vcpu)
{
u64 val;
- ___activate_traps(vcpu);
+ ___activate_traps(vcpu, __compute_hcr(vcpu));
if (has_cntpoff()) {
struct timer_map map;
@@ -59,31 +162,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
}
}
- val = read_sysreg(cpacr_el1);
- val |= CPACR_ELx_TTA;
- val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN |
- CPACR_EL1_SMEN_EL0EN | CPACR_EL1_SMEN_EL1EN);
-
- /*
- * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
- * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
- * except for some missing controls, such as TAM.
- * In this case, CPTR_EL2.TAM has the same position with or without
- * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
- * shift value for trapping the AMU accesses.
- */
-
- val |= CPTR_EL2_TAM;
-
- if (guest_owns_fp_regs(vcpu)) {
- if (vcpu_has_sve(vcpu))
- val |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
- } else {
- val &= ~(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
- __activate_traps_fpsimd32(vcpu);
- }
-
- write_sysreg(val, cpacr_el1);
+ __activate_cptr_traps(vcpu);
write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
}
@@ -162,6 +241,8 @@ static void __vcpu_put_deactivate_traps(struct kvm_vcpu *vcpu)
void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu)
{
+ host_data_ptr(host_ctxt)->__hyp_running_vcpu = vcpu;
+
__vcpu_load_switch_sysregs(vcpu);
__vcpu_load_activate_traps(vcpu);
__load_stage2(vcpu->arch.hw_mmu, vcpu->arch.hw_mmu->arch);
@@ -171,18 +252,179 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
{
__vcpu_put_deactivate_traps(vcpu);
__vcpu_put_switch_sysregs(vcpu);
+
+ host_data_ptr(host_ctxt)->__hyp_running_vcpu = NULL;
+}
+
+static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+ u64 esr = kvm_vcpu_get_esr(vcpu);
+ u64 spsr, elr, mode;
+
+ /*
+ * Going through the whole put/load motions is a waste of time
+ * if this is a VHE guest hypervisor returning to its own
+ * userspace, or the hypervisor performing a local exception
+ * return. No need to save/restore registers, no need to
+ * switch S2 MMU. Just do the canonical ERET.
+ *
+ * Unless the trap has to be forwarded further down the line,
+ * of course...
+ */
+ if ((__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_NV) ||
+ (__vcpu_sys_reg(vcpu, HFGITR_EL2) & HFGITR_EL2_ERET))
+ return false;
+
+ spsr = read_sysreg_el1(SYS_SPSR);
+ mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
+
+ switch (mode) {
+ case PSR_MODE_EL0t:
+ if (!(vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)))
+ return false;
+ break;
+ case PSR_MODE_EL2t:
+ mode = PSR_MODE_EL1t;
+ break;
+ case PSR_MODE_EL2h:
+ mode = PSR_MODE_EL1h;
+ break;
+ default:
+ return false;
+ }
+
+ /* If ERETAx fails, take the slow path */
+ if (esr_iss_is_eretax(esr)) {
+ if (!(vcpu_has_ptrauth(vcpu) && kvm_auth_eretax(vcpu, &elr)))
+ return false;
+ } else {
+ elr = read_sysreg_el1(SYS_ELR);
+ }
+
+ spsr = (spsr & ~(PSR_MODE_MASK | PSR_MODE32_BIT)) | mode;
+
+ write_sysreg_el2(spsr, SYS_SPSR);
+ write_sysreg_el2(elr, SYS_ELR);
+
+ return true;
+}
+
+static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
+{
+ __fpsimd_save_state(*host_data_ptr(fpsimd_state));
+}
+
+static bool kvm_hyp_handle_tlbi_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+ int ret = -EINVAL;
+ u32 instr;
+ u64 val;
+
+ /*
+ * Ideally, we would never trap on EL2 S1 TLB invalidations using
+ * the EL1 instructions when the guest's HCR_EL2.{E2H,TGE}=={1,1}.
+ * But "thanks" to FEAT_NV2, we don't trap writes to HCR_EL2,
+ * meaning that we can't track changes to the virtual TGE bit. So we
+ * have to leave HCR_EL2.TTLB set on the host. Oopsie...
+ *
+ * Try and handle these invalidation as quickly as possible, without
+ * fully exiting. Note that we don't need to consider any forwarding
+ * here, as having E2H+TGE set is the very definition of being
+ * InHost.
+ *
+ * For the lesser hypervisors out there that have failed to get on
+ * with the VHE program, we can also handle the nVHE style of EL2
+ * invalidation.
+ */
+ if (!(is_hyp_ctxt(vcpu)))
+ return false;
+
+ instr = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
+ val = vcpu_get_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu));
+
+ if ((kvm_supported_tlbi_s1e1_op(vcpu, instr) &&
+ vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)) ||
+ kvm_supported_tlbi_s1e2_op (vcpu, instr))
+ ret = __kvm_tlbi_s1e2(NULL, val, instr);
+
+ if (ret)
+ return false;
+
+ __kvm_skip_instr(vcpu);
+
+ return true;
+}
+
+static bool kvm_hyp_handle_cpacr_el1(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+ u64 esr = kvm_vcpu_get_esr(vcpu);
+ int rt;
+
+ if (!is_hyp_ctxt(vcpu) || esr_sys64_to_sysreg(esr) != SYS_CPACR_EL1)
+ return false;
+
+ rt = kvm_vcpu_sys_get_rt(vcpu);
+
+ if ((esr & ESR_ELx_SYS64_ISS_DIR_MASK) == ESR_ELx_SYS64_ISS_DIR_READ) {
+ vcpu_set_reg(vcpu, rt, __vcpu_sys_reg(vcpu, CPTR_EL2));
+ } else {
+ vcpu_write_sys_reg(vcpu, vcpu_get_reg(vcpu, rt), CPTR_EL2);
+ __activate_cptr_traps(vcpu);
+ }
+
+ __kvm_skip_instr(vcpu);
+
+ return true;
+}
+
+static bool kvm_hyp_handle_zcr_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+ u32 sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
+
+ if (!vcpu_has_nv(vcpu))
+ return false;
+
+ if (sysreg != SYS_ZCR_EL2)
+ return false;
+
+ if (guest_owns_fp_regs())
+ return false;
+
+ /*
+ * ZCR_EL2 traps are handled in the slow path, with the expectation
+ * that the guest's FP context has already been loaded onto the CPU.
+ *
+ * Load the guest's FP context and unconditionally forward to the
+ * slow path for handling (i.e. return false).
+ */
+ kvm_hyp_handle_fpsimd(vcpu, exit_code);
+ return false;
+}
+
+static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+ if (kvm_hyp_handle_tlbi_el2(vcpu, exit_code))
+ return true;
+
+ if (kvm_hyp_handle_cpacr_el1(vcpu, exit_code))
+ return true;
+
+ if (kvm_hyp_handle_zcr_el2(vcpu, exit_code))
+ return true;
+
+ return kvm_hyp_handle_sysreg(vcpu, exit_code);
}
static const exit_handler_fn hyp_exit_handlers[] = {
[0 ... ESR_ELx_EC_MAX] = NULL,
[ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32,
- [ESR_ELx_EC_SYS64] = kvm_hyp_handle_sysreg,
+ [ESR_ELx_EC_SYS64] = kvm_hyp_handle_sysreg_vhe,
[ESR_ELx_EC_SVE] = kvm_hyp_handle_fpsimd,
[ESR_ELx_EC_FP_ASIMD] = kvm_hyp_handle_fpsimd,
[ESR_ELx_EC_IABT_LOW] = kvm_hyp_handle_iabt_low,
[ESR_ELx_EC_DABT_LOW] = kvm_hyp_handle_dabt_low,
[ESR_ELx_EC_WATCHPT_LOW] = kvm_hyp_handle_watchpt_low,
- [ESR_ELx_EC_PAC] = kvm_hyp_handle_ptrauth,
+ [ESR_ELx_EC_ERET] = kvm_hyp_handle_eret,
[ESR_ELx_EC_MOPS] = kvm_hyp_handle_mops,
};
@@ -197,7 +439,7 @@ static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)
* If we were in HYP context on entry, adjust the PSTATE view
* so that the usual helpers work correctly.
*/
- if (unlikely(vcpu_get_flag(vcpu, VCPU_HYP_CONTEXT))) {
+ if (vcpu_has_nv(vcpu) && (read_sysreg(hcr_el2) & HCR_NV)) {
u64 mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
switch (mode) {
@@ -221,8 +463,7 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
struct kvm_cpu_context *guest_ctxt;
u64 exit_code;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
- host_ctxt->__hyp_running_vcpu = vcpu;
+ host_ctxt = host_data_ptr(host_ctxt);
guest_ctxt = &vcpu->arch.ctxt;
sysreg_save_host_state_vhe(host_ctxt);
@@ -240,11 +481,6 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
sysreg_restore_guest_state_vhe(guest_ctxt);
__debug_switch_to_guest(vcpu);
- if (is_hyp_ctxt(vcpu))
- vcpu_set_flag(vcpu, VCPU_HYP_CONTEXT);
- else
- vcpu_clear_flag(vcpu, VCPU_HYP_CONTEXT);
-
do {
/* Jump in the fire! */
exit_code = __guest_enter(vcpu);
@@ -258,7 +494,7 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
sysreg_restore_host_state_vhe(host_ctxt);
- if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)
+ if (guest_owns_fp_regs())
__fpsimd_save_fpexc32(vcpu);
__debug_switch_to_host(vcpu);
@@ -301,12 +537,12 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
return ret;
}
-static void __hyp_call_panic(u64 spsr, u64 elr, u64 par)
+static void __noreturn __hyp_call_panic(u64 spsr, u64 elr, u64 par)
{
struct kvm_cpu_context *host_ctxt;
struct kvm_vcpu *vcpu;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
vcpu = host_ctxt->__hyp_running_vcpu;
__deactivate_traps(vcpu);
@@ -326,7 +562,6 @@ void __noreturn hyp_panic(void)
u64 par = read_sysreg_par();
__hyp_call_panic(spsr, elr, par);
- unreachable();
}
asmlinkage void kvm_unexpected_el2_exception(void)
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index a8b9ea496706..e12bd7d6d2dc 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -67,7 +67,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
struct kvm_cpu_context *host_ctxt;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
__sysreg_save_user_state(host_ctxt);
/*
@@ -110,7 +110,7 @@ void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu)
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
struct kvm_cpu_context *host_ctxt;
- host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ host_ctxt = host_data_ptr(host_ctxt);
__sysreg_save_el1_state(guest_ctxt);
__sysreg_save_user_state(guest_ctxt);
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index 1a60b95381e8..3d50a1bd2bdb 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -17,8 +17,8 @@ struct tlb_inv_context {
u64 sctlr;
};
-static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
- struct tlb_inv_context *cxt)
+static void enter_vmid_context(struct kvm_s2_mmu *mmu,
+ struct tlb_inv_context *cxt)
{
struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
u64 val;
@@ -67,7 +67,7 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
isb();
}
-static void __tlb_switch_to_host(struct tlb_inv_context *cxt)
+static void exit_vmid_context(struct tlb_inv_context *cxt)
{
/*
* We're done with the TLB operation, let's restore the host's
@@ -97,7 +97,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
dsb(ishst);
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt);
+ enter_vmid_context(mmu, &cxt);
/*
* We could do so much better if we had the VA as well.
@@ -118,7 +118,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
dsb(ish);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
@@ -129,7 +129,7 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
dsb(nshst);
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt);
+ enter_vmid_context(mmu, &cxt);
/*
* We could do so much better if we had the VA as well.
@@ -150,7 +150,7 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
dsb(nsh);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
@@ -169,7 +169,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
dsb(ishst);
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt);
+ enter_vmid_context(mmu, &cxt);
__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride,
TLBI_TTL_UNKNOWN);
@@ -179,7 +179,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
dsb(ish);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
@@ -189,13 +189,13 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
dsb(ishst);
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt);
+ enter_vmid_context(mmu, &cxt);
__tlbi(vmalls12e1is);
dsb(ish);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu)
@@ -203,14 +203,14 @@ void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu)
struct tlb_inv_context cxt;
/* Switch to requested VMID */
- __tlb_switch_to_guest(mmu, &cxt);
+ enter_vmid_context(mmu, &cxt);
__tlbi(vmalle1);
asm volatile("ic iallu");
dsb(nsh);
isb();
- __tlb_switch_to_host(&cxt);
+ exit_vmid_context(&cxt);
}
void __kvm_flush_vm_context(void)
@@ -219,3 +219,150 @@ void __kvm_flush_vm_context(void)
__tlbi(alle1is);
dsb(ish);
}
+
+/*
+ * TLB invalidation emulation for NV. For any given instruction, we
+ * perform the following transformtions:
+ *
+ * - a TLBI targeting EL2 S1 is remapped to EL1 S1
+ * - a non-shareable TLBI is upgraded to being inner-shareable
+ * - an outer-shareable TLBI is also mapped to inner-shareable
+ * - an nXS TLBI is upgraded to XS
+ */
+int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding)
+{
+ struct tlb_inv_context cxt;
+ int ret = 0;
+
+ /*
+ * The guest will have provided its own DSB ISHST before trapping.
+ * If it hasn't, that's its own problem, and we won't paper over it
+ * (plus, there is plenty of extra synchronisation before we even
+ * get here...).
+ */
+
+ if (mmu)
+ enter_vmid_context(mmu, &cxt);
+
+ switch (sys_encoding) {
+ case OP_TLBI_ALLE2:
+ case OP_TLBI_ALLE2IS:
+ case OP_TLBI_ALLE2OS:
+ case OP_TLBI_VMALLE1:
+ case OP_TLBI_VMALLE1IS:
+ case OP_TLBI_VMALLE1OS:
+ case OP_TLBI_ALLE2NXS:
+ case OP_TLBI_ALLE2ISNXS:
+ case OP_TLBI_ALLE2OSNXS:
+ case OP_TLBI_VMALLE1NXS:
+ case OP_TLBI_VMALLE1ISNXS:
+ case OP_TLBI_VMALLE1OSNXS:
+ __tlbi(vmalle1is);
+ break;
+ case OP_TLBI_VAE2:
+ case OP_TLBI_VAE2IS:
+ case OP_TLBI_VAE2OS:
+ case OP_TLBI_VAE1:
+ case OP_TLBI_VAE1IS:
+ case OP_TLBI_VAE1OS:
+ case OP_TLBI_VAE2NXS:
+ case OP_TLBI_VAE2ISNXS:
+ case OP_TLBI_VAE2OSNXS:
+ case OP_TLBI_VAE1NXS:
+ case OP_TLBI_VAE1ISNXS:
+ case OP_TLBI_VAE1OSNXS:
+ __tlbi(vae1is, va);
+ break;
+ case OP_TLBI_VALE2:
+ case OP_TLBI_VALE2IS:
+ case OP_TLBI_VALE2OS:
+ case OP_TLBI_VALE1:
+ case OP_TLBI_VALE1IS:
+ case OP_TLBI_VALE1OS:
+ case OP_TLBI_VALE2NXS:
+ case OP_TLBI_VALE2ISNXS:
+ case OP_TLBI_VALE2OSNXS:
+ case OP_TLBI_VALE1NXS:
+ case OP_TLBI_VALE1ISNXS:
+ case OP_TLBI_VALE1OSNXS:
+ __tlbi(vale1is, va);
+ break;
+ case OP_TLBI_ASIDE1:
+ case OP_TLBI_ASIDE1IS:
+ case OP_TLBI_ASIDE1OS:
+ case OP_TLBI_ASIDE1NXS:
+ case OP_TLBI_ASIDE1ISNXS:
+ case OP_TLBI_ASIDE1OSNXS:
+ __tlbi(aside1is, va);
+ break;
+ case OP_TLBI_VAAE1:
+ case OP_TLBI_VAAE1IS:
+ case OP_TLBI_VAAE1OS:
+ case OP_TLBI_VAAE1NXS:
+ case OP_TLBI_VAAE1ISNXS:
+ case OP_TLBI_VAAE1OSNXS:
+ __tlbi(vaae1is, va);
+ break;
+ case OP_TLBI_VAALE1:
+ case OP_TLBI_VAALE1IS:
+ case OP_TLBI_VAALE1OS:
+ case OP_TLBI_VAALE1NXS:
+ case OP_TLBI_VAALE1ISNXS:
+ case OP_TLBI_VAALE1OSNXS:
+ __tlbi(vaale1is, va);
+ break;
+ case OP_TLBI_RVAE2:
+ case OP_TLBI_RVAE2IS:
+ case OP_TLBI_RVAE2OS:
+ case OP_TLBI_RVAE1:
+ case OP_TLBI_RVAE1IS:
+ case OP_TLBI_RVAE1OS:
+ case OP_TLBI_RVAE2NXS:
+ case OP_TLBI_RVAE2ISNXS:
+ case OP_TLBI_RVAE2OSNXS:
+ case OP_TLBI_RVAE1NXS:
+ case OP_TLBI_RVAE1ISNXS:
+ case OP_TLBI_RVAE1OSNXS:
+ __tlbi(rvae1is, va);
+ break;
+ case OP_TLBI_RVALE2:
+ case OP_TLBI_RVALE2IS:
+ case OP_TLBI_RVALE2OS:
+ case OP_TLBI_RVALE1:
+ case OP_TLBI_RVALE1IS:
+ case OP_TLBI_RVALE1OS:
+ case OP_TLBI_RVALE2NXS:
+ case OP_TLBI_RVALE2ISNXS:
+ case OP_TLBI_RVALE2OSNXS:
+ case OP_TLBI_RVALE1NXS:
+ case OP_TLBI_RVALE1ISNXS:
+ case OP_TLBI_RVALE1OSNXS:
+ __tlbi(rvale1is, va);
+ break;
+ case OP_TLBI_RVAAE1:
+ case OP_TLBI_RVAAE1IS:
+ case OP_TLBI_RVAAE1OS:
+ case OP_TLBI_RVAAE1NXS:
+ case OP_TLBI_RVAAE1ISNXS:
+ case OP_TLBI_RVAAE1OSNXS:
+ __tlbi(rvaae1is, va);
+ break;
+ case OP_TLBI_RVAALE1:
+ case OP_TLBI_RVAALE1IS:
+ case OP_TLBI_RVAALE1OS:
+ case OP_TLBI_RVAALE1NXS:
+ case OP_TLBI_RVAALE1ISNXS:
+ case OP_TLBI_RVAALE1OSNXS:
+ __tlbi(rvaale1is, va);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ dsb(ish);
+ isb();
+
+ if (mmu)
+ exit_vmid_context(&cxt);
+
+ return ret;
+}
diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c
index 200c8019a82a..cd6b7b83e2c3 100644
--- a/arch/arm64/kvm/mmio.c
+++ b/arch/arm64/kvm/mmio.c
@@ -86,7 +86,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)
/* Detect an already handled MMIO return */
if (unlikely(!vcpu->mmio_needed))
- return 0;
+ return 1;
vcpu->mmio_needed = 0;
@@ -117,7 +117,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)
*/
kvm_incr_pc(vcpu);
- return 0;
+ return 1;
}
int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
@@ -133,11 +133,19 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
/*
* No valid syndrome? Ask userspace for help if it has
* volunteered to do so, and bail out otherwise.
+ *
+ * In the protected VM case, there isn't much userspace can do
+ * though, so directly deliver an exception to the guest.
*/
if (!kvm_vcpu_dabt_isvalid(vcpu)) {
trace_kvm_mmio_nisv(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu),
kvm_vcpu_get_hfar(vcpu), fault_ipa);
+ if (vcpu_is_protected(vcpu)) {
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
+ return 1;
+ }
+
if (test_bit(KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER,
&vcpu->kvm->arch.flags)) {
run->exit_reason = KVM_EXIT_ARM_NISV;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index dc04bc767865..6981b1bc0946 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -328,18 +328,23 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
may_block));
}
-static void unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
+void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
{
__unmap_stage2_range(mmu, start, size, true);
}
+void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
+{
+ stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_flush);
+}
+
static void stage2_flush_memslot(struct kvm *kvm,
struct kvm_memory_slot *memslot)
{
phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT;
phys_addr_t end = addr + PAGE_SIZE * memslot->npages;
- stage2_apply_range_resched(&kvm->arch.mmu, addr, end, kvm_pgtable_stage2_flush);
+ kvm_stage2_flush_range(&kvm->arch.mmu, addr, end);
}
/**
@@ -362,6 +367,8 @@ static void stage2_flush_vm(struct kvm *kvm)
kvm_for_each_memslot(memslot, bkt, slots)
stage2_flush_memslot(kvm, memslot);
+ kvm_nested_s2_flush(kvm);
+
write_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, idx);
}
@@ -855,21 +862,9 @@ static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = {
.icache_inval_pou = invalidate_icache_guest_page,
};
-/**
- * kvm_init_stage2_mmu - Initialise a S2 MMU structure
- * @kvm: The pointer to the KVM structure
- * @mmu: The pointer to the s2 MMU structure
- * @type: The machine type of the virtual machine
- *
- * Allocates only the stage-2 HW PGD level table(s).
- * Note we don't need locking here as this is only called when the VM is
- * created, which can only be done once.
- */
-int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long type)
+static int kvm_init_ipa_range(struct kvm_s2_mmu *mmu, unsigned long type)
{
u32 kvm_ipa_limit = get_kvm_ipa_limit();
- int cpu, err;
- struct kvm_pgtable *pgt;
u64 mmfr0, mmfr1;
u32 phys_shift;
@@ -896,11 +891,51 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
mmu->vtcr = kvm_get_vtcr(mmfr0, mmfr1, phys_shift);
+ return 0;
+}
+
+/**
+ * kvm_init_stage2_mmu - Initialise a S2 MMU structure
+ * @kvm: The pointer to the KVM structure
+ * @mmu: The pointer to the s2 MMU structure
+ * @type: The machine type of the virtual machine
+ *
+ * Allocates only the stage-2 HW PGD level table(s).
+ * Note we don't need locking here as this is only called in two cases:
+ *
+ * - when the VM is created, which can't race against anything
+ *
+ * - when secondary kvm_s2_mmu structures are initialised for NV
+ * guests, and the caller must hold kvm->lock as this is called on a
+ * per-vcpu basis.
+ */
+int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long type)
+{
+ int cpu, err;
+ struct kvm_pgtable *pgt;
+
+ /*
+ * If we already have our page tables in place, and that the
+ * MMU context is the canonical one, we have a bug somewhere,
+ * as this is only supposed to ever happen once per VM.
+ *
+ * Otherwise, we're building nested page tables, and that's
+ * probably because userspace called KVM_ARM_VCPU_INIT more
+ * than once on the same vcpu. Since that's actually legal,
+ * don't kick a fuss and leave gracefully.
+ */
if (mmu->pgt != NULL) {
+ if (kvm_is_nested_s2_mmu(kvm, mmu))
+ return 0;
+
kvm_err("kvm_arch already initialized?\n");
return -EINVAL;
}
+ err = kvm_init_ipa_range(mmu, type);
+ if (err)
+ return err;
+
pgt = kzalloc(sizeof(*pgt), GFP_KERNEL_ACCOUNT);
if (!pgt)
return -ENOMEM;
@@ -925,6 +960,10 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
mmu->pgt = pgt;
mmu->pgd_phys = __pa(pgt->pgd);
+
+ if (kvm_is_nested_s2_mmu(kvm, mmu))
+ kvm_init_nested_s2_mmu(mmu);
+
return 0;
out_destroy_pgtable:
@@ -976,7 +1015,7 @@ static void stage2_unmap_memslot(struct kvm *kvm,
if (!(vma->vm_flags & VM_PFNMAP)) {
gpa_t gpa = addr + (vm_start - memslot->userspace_addr);
- unmap_stage2_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
+ kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
}
hva = vm_end;
} while (hva < reg_end);
@@ -1003,6 +1042,8 @@ void stage2_unmap_vm(struct kvm *kvm)
kvm_for_each_memslot(memslot, bkt, slots)
stage2_unmap_memslot(kvm, memslot);
+ kvm_nested_s2_unmap(kvm);
+
write_unlock(&kvm->mmu_lock);
mmap_read_unlock(current->mm);
srcu_read_unlock(&kvm->srcu, idx);
@@ -1102,12 +1143,12 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
}
/**
- * stage2_wp_range() - write protect stage2 memory region range
+ * kvm_stage2_wp_range() - write protect stage2 memory region range
* @mmu: The KVM stage-2 MMU pointer
* @addr: Start address of range
* @end: End address of range
*/
-static void stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
+void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
{
stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_wrprotect);
}
@@ -1138,7 +1179,8 @@ static void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
write_lock(&kvm->mmu_lock);
- stage2_wp_range(&kvm->arch.mmu, start, end);
+ kvm_stage2_wp_range(&kvm->arch.mmu, start, end);
+ kvm_nested_s2_wp(kvm);
write_unlock(&kvm->mmu_lock);
kvm_flush_remote_tlbs_memslot(kvm, memslot);
}
@@ -1192,7 +1234,7 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
lockdep_assert_held_write(&kvm->mmu_lock);
- stage2_wp_range(&kvm->arch.mmu, start, end);
+ kvm_stage2_wp_range(&kvm->arch.mmu, start, end);
/*
* Eager-splitting is done when manual-protect is set. We
@@ -1204,6 +1246,8 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
*/
if (kvm_dirty_log_manual_protect_and_init_set(kvm))
kvm_mmu_split_huge_pages(kvm, start, end);
+
+ kvm_nested_s2_wp(kvm);
}
static void kvm_send_hwpoison_signal(unsigned long address, short lsb)
@@ -1375,6 +1419,7 @@ static bool kvm_vma_mte_allowed(struct vm_area_struct *vma)
}
static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
+ struct kvm_s2_trans *nested,
struct kvm_memory_slot *memslot, unsigned long hva,
bool fault_is_perm)
{
@@ -1383,6 +1428,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
bool exec_fault, mte_allowed;
bool device = false, vfio_allow_any_uc = false;
unsigned long mmu_seq;
+ phys_addr_t ipa = fault_ipa;
struct kvm *kvm = vcpu->kvm;
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
struct vm_area_struct *vma;
@@ -1466,10 +1512,38 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
}
vma_pagesize = 1UL << vma_shift;
+
+ if (nested) {
+ unsigned long max_map_size;
+
+ max_map_size = force_pte ? PAGE_SIZE : PUD_SIZE;
+
+ ipa = kvm_s2_trans_output(nested);
+
+ /*
+ * If we're about to create a shadow stage 2 entry, then we
+ * can only create a block mapping if the guest stage 2 page
+ * table uses at least as big a mapping.
+ */
+ max_map_size = min(kvm_s2_trans_size(nested), max_map_size);
+
+ /*
+ * Be careful that if the mapping size falls between
+ * two host sizes, take the smallest of the two.
+ */
+ if (max_map_size >= PMD_SIZE && max_map_size < PUD_SIZE)
+ max_map_size = PMD_SIZE;
+ else if (max_map_size >= PAGE_SIZE && max_map_size < PMD_SIZE)
+ max_map_size = PAGE_SIZE;
+
+ force_pte = (max_map_size == PAGE_SIZE);
+ vma_pagesize = min(vma_pagesize, (long)max_map_size);
+ }
+
if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)
fault_ipa &= ~(vma_pagesize - 1);
- gfn = fault_ipa >> PAGE_SHIFT;
+ gfn = ipa >> PAGE_SHIFT;
mte_allowed = kvm_vma_mte_allowed(vma);
vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
@@ -1520,10 +1594,31 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (exec_fault && device)
return -ENOEXEC;
+ /*
+ * Potentially reduce shadow S2 permissions to match the guest's own
+ * S2. For exec faults, we'd only reach this point if the guest
+ * actually allowed it (see kvm_s2_handle_perm_fault).
+ *
+ * Also encode the level of the original translation in the SW bits
+ * of the leaf entry as a proxy for the span of that translation.
+ * This will be retrieved on TLB invalidation from the guest and
+ * used to limit the invalidation scope if a TTL hint or a range
+ * isn't provided.
+ */
+ if (nested) {
+ writable &= kvm_s2_trans_writable(nested);
+ if (!kvm_s2_trans_readable(nested))
+ prot &= ~KVM_PGTABLE_PROT_R;
+
+ prot |= kvm_encode_nested_level(nested);
+ }
+
read_lock(&kvm->mmu_lock);
pgt = vcpu->arch.hw_mmu->pgt;
- if (mmu_invalidate_retry(kvm, mmu_seq))
+ if (mmu_invalidate_retry(kvm, mmu_seq)) {
+ ret = -EAGAIN;
goto out_unlock;
+ }
/*
* If we are not forced to use page mapping, check if we are
@@ -1564,7 +1659,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
prot |= KVM_PGTABLE_PROT_NORMAL_NC;
else
prot |= KVM_PGTABLE_PROT_DEVICE;
- } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
+ } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC) &&
+ (!nested || kvm_s2_trans_executable(nested))) {
prot |= KVM_PGTABLE_PROT_X;
}
@@ -1573,14 +1669,23 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
* permissions only if vma_pagesize equals fault_granule. Otherwise,
* kvm_pgtable_stage2_map() should be called to change block size.
*/
- if (fault_is_perm && vma_pagesize == fault_granule)
+ if (fault_is_perm && vma_pagesize == fault_granule) {
+ /*
+ * Drop the SW bits in favour of those stored in the
+ * PTE, which will be preserved.
+ */
+ prot &= ~KVM_NV_GUEST_MAP_SZ;
ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
- else
+ } else {
ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
__pfn_to_phys(pfn), prot,
memcache,
KVM_PGTABLE_WALK_HANDLE_FAULT |
KVM_PGTABLE_WALK_SHARED);
+ }
+
+out_unlock:
+ read_unlock(&kvm->mmu_lock);
/* Mark the page dirty only if the fault is handled successfully */
if (writable && !ret) {
@@ -1588,8 +1693,6 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
mark_page_dirty_in_slot(kvm, memslot, gfn);
}
-out_unlock:
- read_unlock(&kvm->mmu_lock);
kvm_release_pfn_clean(pfn);
return ret != -EAGAIN ? ret : 0;
}
@@ -1624,8 +1727,10 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
*/
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
{
+ struct kvm_s2_trans nested_trans, *nested = NULL;
unsigned long esr;
- phys_addr_t fault_ipa;
+ phys_addr_t fault_ipa; /* The address we faulted on */
+ phys_addr_t ipa; /* Always the IPA in the L1 guest phys space */
struct kvm_memory_slot *memslot;
unsigned long hva;
bool is_iabt, write_fault, writable;
@@ -1634,7 +1739,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
esr = kvm_vcpu_get_esr(vcpu);
- fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
+ ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
if (esr_fsc_is_translation_fault(esr)) {
@@ -1684,7 +1789,42 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
idx = srcu_read_lock(&vcpu->kvm->srcu);
- gfn = fault_ipa >> PAGE_SHIFT;
+ /*
+ * We may have faulted on a shadow stage 2 page table if we are
+ * running a nested guest. In this case, we have to resolve the L2
+ * IPA to the L1 IPA first, before knowing what kind of memory should
+ * back the L1 IPA.
+ *
+ * If the shadow stage 2 page table walk faults, then we simply inject
+ * this to the guest and carry on.
+ *
+ * If there are no shadow S2 PTs because S2 is disabled, there is
+ * nothing to walk and we treat it as a 1:1 before going through the
+ * canonical translation.
+ */
+ if (kvm_is_nested_s2_mmu(vcpu->kvm,vcpu->arch.hw_mmu) &&
+ vcpu->arch.hw_mmu->nested_stage2_enabled) {
+ u32 esr;
+
+ ret = kvm_walk_nested_s2(vcpu, fault_ipa, &nested_trans);
+ if (ret) {
+ esr = kvm_s2_trans_esr(&nested_trans);
+ kvm_inject_s2_fault(vcpu, esr);
+ goto out_unlock;
+ }
+
+ ret = kvm_s2_handle_perm_fault(vcpu, &nested_trans);
+ if (ret) {
+ esr = kvm_s2_trans_esr(&nested_trans);
+ kvm_inject_s2_fault(vcpu, esr);
+ goto out_unlock;
+ }
+
+ ipa = kvm_s2_trans_output(&nested_trans);
+ nested = &nested_trans;
+ }
+
+ gfn = ipa >> PAGE_SHIFT;
memslot = gfn_to_memslot(vcpu->kvm, gfn);
hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
write_fault = kvm_is_write_fault(vcpu);
@@ -1728,13 +1868,13 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
* faulting VA. This is always 12 bits, irrespective
* of the page size.
*/
- fault_ipa |= kvm_vcpu_get_hfar(vcpu) & ((1 << 12) - 1);
- ret = io_mem_abort(vcpu, fault_ipa);
+ ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+ ret = io_mem_abort(vcpu, ipa);
goto out_unlock;
}
/* Userspace should not be able to register out-of-bounds IPAs */
- VM_BUG_ON(fault_ipa >= kvm_phys_size(vcpu->arch.hw_mmu));
+ VM_BUG_ON(ipa >= kvm_phys_size(vcpu->arch.hw_mmu));
if (esr_fsc_is_access_flag_fault(esr)) {
handle_access_fault(vcpu, fault_ipa);
@@ -1742,7 +1882,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
goto out_unlock;
}
- ret = user_mem_abort(vcpu, fault_ipa, memslot, hva,
+ ret = user_mem_abort(vcpu, fault_ipa, nested, memslot, hva,
esr_fsc_is_permission_fault(esr));
if (ret == 0)
ret = 1;
@@ -1765,40 +1905,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
(range->end - range->start) << PAGE_SHIFT,
range->may_block);
- return false;
-}
-
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- kvm_pfn_t pfn = pte_pfn(range->arg.pte);
-
- if (!kvm->arch.mmu.pgt)
- return false;
-
- WARN_ON(range->end - range->start != 1);
-
- /*
- * If the page isn't tagged, defer to user_mem_abort() for sanitising
- * the MTE tags. The S2 pte should have been unmapped by
- * mmu_notifier_invalidate_range_end().
- */
- if (kvm_has_mte(kvm) && !page_mte_tagged(pfn_to_page(pfn)))
- return false;
-
- /*
- * We've moved a page around, probably through CoW, so let's treat
- * it just like a translation fault and the map handler will clean
- * the cache to the PoC.
- *
- * The MMU notifiers will have unmapped a huge PMD before calling
- * ->change_pte() (which in turn calls kvm_set_spte_gfn()) and
- * therefore we never need to clear out a huge PMD through this
- * calling path and a memcache is not required.
- */
- kvm_pgtable_stage2_map(kvm->arch.mmu.pgt, range->start << PAGE_SHIFT,
- PAGE_SIZE, __pfn_to_phys(pfn),
- KVM_PGTABLE_PROT_R, NULL, 0);
-
+ kvm_nested_s2_unmap(kvm);
return false;
}
@@ -1812,6 +1919,10 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT,
size, true);
+ /*
+ * TODO: Handle nested_mmu structures here using the reverse mapping in
+ * a later version of patch series.
+ */
}
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
@@ -2054,11 +2165,6 @@ void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen)
{
}
-void kvm_arch_flush_shadow_all(struct kvm *kvm)
-{
- kvm_uninit_stage2_mmu(kvm);
-}
-
void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot)
{
@@ -2066,7 +2172,8 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
phys_addr_t size = slot->npages << PAGE_SHIFT;
write_lock(&kvm->mmu_lock);
- unmap_stage2_range(&kvm->arch.mmu, gpa, size);
+ kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size);
+ kvm_nested_s2_unmap(kvm);
write_unlock(&kvm->mmu_lock);
}
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index ced30c90521a..de789e0f1ae9 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -4,10 +4,13 @@
* Author: Jintack Lim <jintack.lim@linaro.org>
*/
+#include <linux/bitfield.h>
#include <linux/kvm.h>
#include <linux/kvm_host.h>
+#include <asm/kvm_arm.h>
#include <asm/kvm_emulate.h>
+#include <asm/kvm_mmu.h>
#include <asm/kvm_nested.h>
#include <asm/sysreg.h>
@@ -17,151 +20,910 @@
#define NV_FTR(r, f) ID_AA64##r##_EL1_##f
/*
- * Our emulated CPU doesn't support all the possible features. For the
- * sake of simplicity (and probably mental sanity), wipe out a number
- * of feature bits we don't intend to support for the time being.
- * This list should get updated as new features get added to the NV
- * support, and new extension to the architecture.
+ * Ratio of live shadow S2 MMU per vcpu. This is a trade-off between
+ * memory usage and potential number of different sets of S2 PTs in
+ * the guests. Running out of S2 MMUs only affects performance (we
+ * will invalidate them more often).
*/
-static u64 limit_nv_id_reg(u32 id, u64 val)
+#define S2_MMU_PER_VCPU 2
+
+void kvm_init_nested(struct kvm *kvm)
{
- u64 tmp;
+ kvm->arch.nested_mmus = NULL;
+ kvm->arch.nested_mmus_size = 0;
+}
- switch (id) {
- case SYS_ID_AA64ISAR0_EL1:
- /* Support everything but TME, O.S. and Range TLBIs */
- val &= ~(NV_FTR(ISAR0, TLB) |
- NV_FTR(ISAR0, TME));
- break;
+static int init_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
+{
+ /*
+ * We only initialise the IPA range on the canonical MMU, which
+ * defines the contract between KVM and userspace on where the
+ * "hardware" is in the IPA space. This affects the validity of MMIO
+ * exits forwarded to userspace, for example.
+ *
+ * For nested S2s, we use the PARange as exposed to the guest, as it
+ * is allowed to use it at will to expose whatever memory map it
+ * wants to its own guests as it would be on real HW.
+ */
+ return kvm_init_stage2_mmu(kvm, mmu, kvm_get_pa_bits(kvm));
+}
- case SYS_ID_AA64ISAR1_EL1:
- /* Support everything but PtrAuth and Spec Invalidation */
- val &= ~(GENMASK_ULL(63, 56) |
- NV_FTR(ISAR1, SPECRES) |
- NV_FTR(ISAR1, GPI) |
- NV_FTR(ISAR1, GPA) |
- NV_FTR(ISAR1, API) |
- NV_FTR(ISAR1, APA));
- break;
+int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_s2_mmu *tmp;
+ int num_mmus, ret = 0;
+
+ /*
+ * Let's treat memory allocation failures as benign: If we fail to
+ * allocate anything, return an error and keep the allocated array
+ * alive. Userspace may try to recover by intializing the vcpu
+ * again, and there is no reason to affect the whole VM for this.
+ */
+ num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
+ tmp = kvrealloc(kvm->arch.nested_mmus,
+ size_mul(sizeof(*kvm->arch.nested_mmus), kvm->arch.nested_mmus_size),
+ size_mul(sizeof(*kvm->arch.nested_mmus), num_mmus),
+ GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ if (!tmp)
+ return -ENOMEM;
+
+ /*
+ * If we went through a realocation, adjust the MMU back-pointers in
+ * the previously initialised kvm_pgtable structures.
+ */
+ if (kvm->arch.nested_mmus != tmp)
+ for (int i = 0; i < kvm->arch.nested_mmus_size; i++)
+ tmp[i].pgt->mmu = &tmp[i];
+
+ for (int i = kvm->arch.nested_mmus_size; !ret && i < num_mmus; i++)
+ ret = init_nested_s2_mmu(kvm, &tmp[i]);
+
+ if (ret) {
+ for (int i = kvm->arch.nested_mmus_size; i < num_mmus; i++)
+ kvm_free_stage2_pgd(&tmp[i]);
+
+ return ret;
+ }
- case SYS_ID_AA64PFR0_EL1:
- /* No AMU, MPAM, S-EL2, RAS or SVE */
- val &= ~(GENMASK_ULL(55, 52) |
- NV_FTR(PFR0, AMU) |
- NV_FTR(PFR0, MPAM) |
- NV_FTR(PFR0, SEL2) |
- NV_FTR(PFR0, RAS) |
- NV_FTR(PFR0, SVE) |
- NV_FTR(PFR0, EL3) |
- NV_FTR(PFR0, EL2) |
- NV_FTR(PFR0, EL1));
- /* 64bit EL1/EL2/EL3 only */
- val |= FIELD_PREP(NV_FTR(PFR0, EL1), 0b0001);
- val |= FIELD_PREP(NV_FTR(PFR0, EL2), 0b0001);
- val |= FIELD_PREP(NV_FTR(PFR0, EL3), 0b0001);
+ kvm->arch.nested_mmus_size = num_mmus;
+ kvm->arch.nested_mmus = tmp;
+
+ return 0;
+}
+
+struct s2_walk_info {
+ int (*read_desc)(phys_addr_t pa, u64 *desc, void *data);
+ void *data;
+ u64 baddr;
+ unsigned int max_oa_bits;
+ unsigned int pgshift;
+ unsigned int sl;
+ unsigned int t0sz;
+ bool be;
+};
+
+static unsigned int ps_to_output_size(unsigned int ps)
+{
+ switch (ps) {
+ case 0: return 32;
+ case 1: return 36;
+ case 2: return 40;
+ case 3: return 42;
+ case 4: return 44;
+ case 5:
+ default:
+ return 48;
+ }
+}
+
+static u32 compute_fsc(int level, u32 fsc)
+{
+ return fsc | (level & 0x3);
+}
+
+static int esr_s2_fault(struct kvm_vcpu *vcpu, int level, u32 fsc)
+{
+ u32 esr;
+
+ esr = kvm_vcpu_get_esr(vcpu) & ~ESR_ELx_FSC;
+ esr |= compute_fsc(level, fsc);
+ return esr;
+}
+
+static int get_ia_size(struct s2_walk_info *wi)
+{
+ return 64 - wi->t0sz;
+}
+
+static int check_base_s2_limits(struct s2_walk_info *wi,
+ int level, int input_size, int stride)
+{
+ int start_size, ia_size;
+
+ ia_size = get_ia_size(wi);
+
+ /* Check translation limits */
+ switch (BIT(wi->pgshift)) {
+ case SZ_64K:
+ if (level == 0 || (level == 1 && ia_size <= 42))
+ return -EFAULT;
break;
+ case SZ_16K:
+ if (level == 0 || (level == 1 && ia_size <= 40))
+ return -EFAULT;
+ break;
+ case SZ_4K:
+ if (level < 0 || (level == 0 && ia_size <= 42))
+ return -EFAULT;
+ break;
+ }
+
+ /* Check input size limits */
+ if (input_size > ia_size)
+ return -EFAULT;
+
+ /* Check number of entries in starting level table */
+ start_size = input_size - ((3 - level) * stride + wi->pgshift);
+ if (start_size < 1 || start_size > stride + 4)
+ return -EFAULT;
+
+ return 0;
+}
+
+/* Check if output is within boundaries */
+static int check_output_size(struct s2_walk_info *wi, phys_addr_t output)
+{
+ unsigned int output_size = wi->max_oa_bits;
+
+ if (output_size != 48 && (output & GENMASK_ULL(47, output_size)))
+ return -1;
+
+ return 0;
+}
- case SYS_ID_AA64PFR1_EL1:
- /* Only support SSBS */
- val &= NV_FTR(PFR1, SSBS);
+/*
+ * This is essentially a C-version of the pseudo code from the ARM ARM
+ * AArch64.TranslationTableWalk function. I strongly recommend looking at
+ * that pseudocode in trying to understand this.
+ *
+ * Must be called with the kvm->srcu read lock held
+ */
+static int walk_nested_s2_pgd(phys_addr_t ipa,
+ struct s2_walk_info *wi, struct kvm_s2_trans *out)
+{
+ int first_block_level, level, stride, input_size, base_lower_bound;
+ phys_addr_t base_addr;
+ unsigned int addr_top, addr_bottom;
+ u64 desc; /* page table entry */
+ int ret;
+ phys_addr_t paddr;
+
+ switch (BIT(wi->pgshift)) {
+ default:
+ case SZ_64K:
+ case SZ_16K:
+ level = 3 - wi->sl;
+ first_block_level = 2;
break;
+ case SZ_4K:
+ level = 2 - wi->sl;
+ first_block_level = 1;
+ break;
+ }
+
+ stride = wi->pgshift - 3;
+ input_size = get_ia_size(wi);
+ if (input_size > 48 || input_size < 25)
+ return -EFAULT;
+
+ ret = check_base_s2_limits(wi, level, input_size, stride);
+ if (WARN_ON(ret))
+ return ret;
+
+ base_lower_bound = 3 + input_size - ((3 - level) * stride +
+ wi->pgshift);
+ base_addr = wi->baddr & GENMASK_ULL(47, base_lower_bound);
+
+ if (check_output_size(wi, base_addr)) {
+ out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
+ return 1;
+ }
+
+ addr_top = input_size - 1;
+
+ while (1) {
+ phys_addr_t index;
+
+ addr_bottom = (3 - level) * stride + wi->pgshift;
+ index = (ipa & GENMASK_ULL(addr_top, addr_bottom))
+ >> (addr_bottom - 3);
+
+ paddr = base_addr | index;
+ ret = wi->read_desc(paddr, &desc, wi->data);
+ if (ret < 0)
+ return ret;
- case SYS_ID_AA64MMFR0_EL1:
- /* Hide ECV, ExS, Secure Memory */
- val &= ~(NV_FTR(MMFR0, ECV) |
- NV_FTR(MMFR0, EXS) |
- NV_FTR(MMFR0, TGRAN4_2) |
- NV_FTR(MMFR0, TGRAN16_2) |
- NV_FTR(MMFR0, TGRAN64_2) |
- NV_FTR(MMFR0, SNSMEM));
-
- /* Disallow unsupported S2 page sizes */
- switch (PAGE_SIZE) {
- case SZ_64K:
- val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN16_2), 0b0001);
- fallthrough;
- case SZ_16K:
- val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN4_2), 0b0001);
- fallthrough;
- case SZ_4K:
- /* Support everything */
- break;
- }
/*
- * Since we can't support a guest S2 page size smaller than
- * the host's own page size (due to KVM only populating its
- * own S2 using the kernel's page size), advertise the
- * limitation using FEAT_GTG.
+ * Handle reversedescriptors if endianness differs between the
+ * host and the guest hypervisor.
*/
- switch (PAGE_SIZE) {
- case SZ_4K:
- val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN4_2), 0b0010);
- fallthrough;
- case SZ_16K:
- val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN16_2), 0b0010);
- fallthrough;
- case SZ_64K:
- val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN64_2), 0b0010);
+ if (wi->be)
+ desc = be64_to_cpu((__force __be64)desc);
+ else
+ desc = le64_to_cpu((__force __le64)desc);
+
+ /* Check for valid descriptor at this point */
+ if (!(desc & 1) || ((desc & 3) == 1 && level == 3)) {
+ out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
+ out->upper_attr = desc;
+ return 1;
+ }
+
+ /* We're at the final level or block translation level */
+ if ((desc & 3) == 1 || level == 3)
+ break;
+
+ if (check_output_size(wi, desc)) {
+ out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
+ out->upper_attr = desc;
+ return 1;
+ }
+
+ base_addr = desc & GENMASK_ULL(47, wi->pgshift);
+
+ level += 1;
+ addr_top = addr_bottom - 1;
+ }
+
+ if (level < first_block_level) {
+ out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
+ out->upper_attr = desc;
+ return 1;
+ }
+
+ /*
+ * We don't use the contiguous bit in the stage-2 ptes, so skip check
+ * for misprogramming of the contiguous bit.
+ */
+
+ if (check_output_size(wi, desc)) {
+ out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
+ out->upper_attr = desc;
+ return 1;
+ }
+
+ if (!(desc & BIT(10))) {
+ out->esr = compute_fsc(level, ESR_ELx_FSC_ACCESS);
+ out->upper_attr = desc;
+ return 1;
+ }
+
+ /* Calculate and return the result */
+ paddr = (desc & GENMASK_ULL(47, addr_bottom)) |
+ (ipa & GENMASK_ULL(addr_bottom - 1, 0));
+ out->output = paddr;
+ out->block_size = 1UL << ((3 - level) * stride + wi->pgshift);
+ out->readable = desc & (0b01 << 6);
+ out->writable = desc & (0b10 << 6);
+ out->level = level;
+ out->upper_attr = desc & GENMASK_ULL(63, 52);
+ return 0;
+}
+
+static int read_guest_s2_desc(phys_addr_t pa, u64 *desc, void *data)
+{
+ struct kvm_vcpu *vcpu = data;
+
+ return kvm_read_guest(vcpu->kvm, pa, desc, sizeof(*desc));
+}
+
+static void vtcr_to_walk_info(u64 vtcr, struct s2_walk_info *wi)
+{
+ wi->t0sz = vtcr & TCR_EL2_T0SZ_MASK;
+
+ switch (vtcr & VTCR_EL2_TG0_MASK) {
+ case VTCR_EL2_TG0_4K:
+ wi->pgshift = 12; break;
+ case VTCR_EL2_TG0_16K:
+ wi->pgshift = 14; break;
+ case VTCR_EL2_TG0_64K:
+ default: /* IMPDEF: treat any other value as 64k */
+ wi->pgshift = 16; break;
+ }
+
+ wi->sl = FIELD_GET(VTCR_EL2_SL0_MASK, vtcr);
+ /* Global limit for now, should eventually be per-VM */
+ wi->max_oa_bits = min(get_kvm_ipa_limit(),
+ ps_to_output_size(FIELD_GET(VTCR_EL2_PS_MASK, vtcr)));
+}
+
+int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+ struct kvm_s2_trans *result)
+{
+ u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+ struct s2_walk_info wi;
+ int ret;
+
+ result->esr = 0;
+
+ if (!vcpu_has_nv(vcpu))
+ return 0;
+
+ wi.read_desc = read_guest_s2_desc;
+ wi.data = vcpu;
+ wi.baddr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+
+ vtcr_to_walk_info(vtcr, &wi);
+
+ wi.be = vcpu_read_sys_reg(vcpu, SCTLR_EL2) & SCTLR_ELx_EE;
+
+ ret = walk_nested_s2_pgd(gipa, &wi, result);
+ if (ret)
+ result->esr |= (kvm_vcpu_get_esr(vcpu) & ~ESR_ELx_FSC);
+
+ return ret;
+}
+
+static unsigned int ttl_to_size(u8 ttl)
+{
+ int level = ttl & 3;
+ int gran = (ttl >> 2) & 3;
+ unsigned int max_size = 0;
+
+ switch (gran) {
+ case TLBI_TTL_TG_4K:
+ switch (level) {
+ case 0:
+ break;
+ case 1:
+ max_size = SZ_1G;
+ break;
+ case 2:
+ max_size = SZ_2M;
+ break;
+ case 3:
+ max_size = SZ_4K;
break;
}
- /* Cap PARange to 48bits */
- tmp = FIELD_GET(NV_FTR(MMFR0, PARANGE), val);
- if (tmp > 0b0101) {
- val &= ~NV_FTR(MMFR0, PARANGE);
- val |= FIELD_PREP(NV_FTR(MMFR0, PARANGE), 0b0101);
+ break;
+ case TLBI_TTL_TG_16K:
+ switch (level) {
+ case 0:
+ case 1:
+ break;
+ case 2:
+ max_size = SZ_32M;
+ break;
+ case 3:
+ max_size = SZ_16K;
+ break;
}
break;
-
- case SYS_ID_AA64MMFR1_EL1:
- val &= (NV_FTR(MMFR1, HCX) |
- NV_FTR(MMFR1, PAN) |
- NV_FTR(MMFR1, LO) |
- NV_FTR(MMFR1, HPDS) |
- NV_FTR(MMFR1, VH) |
- NV_FTR(MMFR1, VMIDBits));
+ case TLBI_TTL_TG_64K:
+ switch (level) {
+ case 0:
+ case 1:
+ /* No 52bit IPA support */
+ break;
+ case 2:
+ max_size = SZ_512M;
+ break;
+ case 3:
+ max_size = SZ_64K;
+ break;
+ }
+ break;
+ default: /* No size information */
break;
+ }
- case SYS_ID_AA64MMFR2_EL1:
- val &= ~(NV_FTR(MMFR2, BBM) |
- NV_FTR(MMFR2, TTL) |
- GENMASK_ULL(47, 44) |
- NV_FTR(MMFR2, ST) |
- NV_FTR(MMFR2, CCIDX) |
- NV_FTR(MMFR2, VARange));
+ return max_size;
+}
- /* Force TTL support */
- val |= FIELD_PREP(NV_FTR(MMFR2, TTL), 0b0001);
+/*
+ * Compute the equivalent of the TTL field by parsing the shadow PT. The
+ * granule size is extracted from the cached VTCR_EL2.TG0 while the level is
+ * retrieved from first entry carrying the level as a tag.
+ */
+static u8 get_guest_mapping_ttl(struct kvm_s2_mmu *mmu, u64 addr)
+{
+ u64 tmp, sz = 0, vtcr = mmu->tlb_vtcr;
+ kvm_pte_t pte;
+ u8 ttl, level;
+
+ lockdep_assert_held_write(&kvm_s2_mmu_to_kvm(mmu)->mmu_lock);
+
+ switch (vtcr & VTCR_EL2_TG0_MASK) {
+ case VTCR_EL2_TG0_4K:
+ ttl = (TLBI_TTL_TG_4K << 2);
+ break;
+ case VTCR_EL2_TG0_16K:
+ ttl = (TLBI_TTL_TG_16K << 2);
break;
+ case VTCR_EL2_TG0_64K:
+ default: /* IMPDEF: treat any other value as 64k */
+ ttl = (TLBI_TTL_TG_64K << 2);
+ break;
+ }
- case SYS_ID_AA64MMFR4_EL1:
- val = 0;
- if (!cpus_have_final_cap(ARM64_HAS_HCR_NV1))
- val |= FIELD_PREP(NV_FTR(MMFR4, E2H0),
- ID_AA64MMFR4_EL1_E2H0_NI_NV1);
+ tmp = addr;
+
+again:
+ /* Iteratively compute the block sizes for a particular granule size */
+ switch (vtcr & VTCR_EL2_TG0_MASK) {
+ case VTCR_EL2_TG0_4K:
+ if (sz < SZ_4K) sz = SZ_4K;
+ else if (sz < SZ_2M) sz = SZ_2M;
+ else if (sz < SZ_1G) sz = SZ_1G;
+ else sz = 0;
+ break;
+ case VTCR_EL2_TG0_16K:
+ if (sz < SZ_16K) sz = SZ_16K;
+ else if (sz < SZ_32M) sz = SZ_32M;
+ else sz = 0;
break;
+ case VTCR_EL2_TG0_64K:
+ default: /* IMPDEF: treat any other value as 64k */
+ if (sz < SZ_64K) sz = SZ_64K;
+ else if (sz < SZ_512M) sz = SZ_512M;
+ else sz = 0;
+ break;
+ }
+
+ if (sz == 0)
+ return 0;
+
+ tmp &= ~(sz - 1);
+ if (kvm_pgtable_get_leaf(mmu->pgt, tmp, &pte, NULL))
+ goto again;
+ if (!(pte & PTE_VALID))
+ goto again;
+ level = FIELD_GET(KVM_NV_GUEST_MAP_SZ, pte);
+ if (!level)
+ goto again;
+
+ ttl |= level;
- case SYS_ID_AA64DFR0_EL1:
- /* Only limited support for PMU, Debug, BPs and WPs */
- val &= (NV_FTR(DFR0, PMUVer) |
- NV_FTR(DFR0, WRPs) |
- NV_FTR(DFR0, BRPs) |
- NV_FTR(DFR0, DebugVer));
-
- /* Cap Debug to ARMv8.1 */
- tmp = FIELD_GET(NV_FTR(DFR0, DebugVer), val);
- if (tmp > 0b0111) {
- val &= ~NV_FTR(DFR0, DebugVer);
- val |= FIELD_PREP(NV_FTR(DFR0, DebugVer), 0b0111);
+ /*
+ * We now have found some level information in the shadow S2. Check
+ * that the resulting range is actually including the original IPA.
+ */
+ sz = ttl_to_size(ttl);
+ if (addr < (tmp + sz))
+ return ttl;
+
+ return 0;
+}
+
+unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val)
+{
+ struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+ unsigned long max_size;
+ u8 ttl;
+
+ ttl = FIELD_GET(TLBI_TTL_MASK, val);
+
+ if (!ttl || !kvm_has_feat(kvm, ID_AA64MMFR2_EL1, TTL, IMP)) {
+ /* No TTL, check the shadow S2 for a hint */
+ u64 addr = (val & GENMASK_ULL(35, 0)) << 12;
+ ttl = get_guest_mapping_ttl(mmu, addr);
+ }
+
+ max_size = ttl_to_size(ttl);
+
+ if (!max_size) {
+ /* Compute the maximum extent of the invalidation */
+ switch (mmu->tlb_vtcr & VTCR_EL2_TG0_MASK) {
+ case VTCR_EL2_TG0_4K:
+ max_size = SZ_1G;
+ break;
+ case VTCR_EL2_TG0_16K:
+ max_size = SZ_32M;
+ break;
+ case VTCR_EL2_TG0_64K:
+ default: /* IMPDEF: treat any other value as 64k */
+ /*
+ * No, we do not support 52bit IPA in nested yet. Once
+ * we do, this should be 4TB.
+ */
+ max_size = SZ_512M;
+ break;
}
- break;
+ }
- default:
- /* Unknown register, just wipe it clean */
- val = 0;
+ WARN_ON(!max_size);
+ return max_size;
+}
+
+/*
+ * We can have multiple *different* MMU contexts with the same VMID:
+ *
+ * - S2 being enabled or not, hence differing by the HCR_EL2.VM bit
+ *
+ * - Multiple vcpus using private S2s (huh huh...), hence differing by the
+ * VBBTR_EL2.BADDR address
+ *
+ * - A combination of the above...
+ *
+ * We can always identify which MMU context to pick at run-time. However,
+ * TLB invalidation involving a VMID must take action on all the TLBs using
+ * this particular VMID. This translates into applying the same invalidation
+ * operation to all the contexts that are using this VMID. Moar phun!
+ */
+void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid,
+ const union tlbi_info *info,
+ void (*tlbi_callback)(struct kvm_s2_mmu *,
+ const union tlbi_info *))
+{
+ write_lock(&kvm->mmu_lock);
+
+ for (int i = 0; i < kvm->arch.nested_mmus_size; i++) {
+ struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+ if (!kvm_s2_mmu_valid(mmu))
+ continue;
+
+ if (vmid == get_vmid(mmu->tlb_vttbr))
+ tlbi_callback(mmu, info);
+ }
+
+ write_unlock(&kvm->mmu_lock);
+}
+
+struct kvm_s2_mmu *lookup_s2_mmu(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ bool nested_stage2_enabled;
+ u64 vttbr, vtcr, hcr;
+
+ lockdep_assert_held_write(&kvm->mmu_lock);
+
+ vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+ vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+ hcr = vcpu_read_sys_reg(vcpu, HCR_EL2);
+
+ nested_stage2_enabled = hcr & HCR_VM;
+
+ /* Don't consider the CnP bit for the vttbr match */
+ vttbr &= ~VTTBR_CNP_BIT;
+
+ /*
+ * Two possibilities when looking up a S2 MMU context:
+ *
+ * - either S2 is enabled in the guest, and we need a context that is
+ * S2-enabled and matches the full VTTBR (VMID+BADDR) and VTCR,
+ * which makes it safe from a TLB conflict perspective (a broken
+ * guest won't be able to generate them),
+ *
+ * - or S2 is disabled, and we need a context that is S2-disabled
+ * and matches the VMID only, as all TLBs are tagged by VMID even
+ * if S2 translation is disabled.
+ */
+ for (int i = 0; i < kvm->arch.nested_mmus_size; i++) {
+ struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+ if (!kvm_s2_mmu_valid(mmu))
+ continue;
+
+ if (nested_stage2_enabled &&
+ mmu->nested_stage2_enabled &&
+ vttbr == mmu->tlb_vttbr &&
+ vtcr == mmu->tlb_vtcr)
+ return mmu;
+
+ if (!nested_stage2_enabled &&
+ !mmu->nested_stage2_enabled &&
+ get_vmid(vttbr) == get_vmid(mmu->tlb_vttbr))
+ return mmu;
+ }
+ return NULL;
+}
+
+static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_s2_mmu *s2_mmu;
+ int i;
+
+ lockdep_assert_held_write(&vcpu->kvm->mmu_lock);
+
+ s2_mmu = lookup_s2_mmu(vcpu);
+ if (s2_mmu)
+ goto out;
+
+ /*
+ * Make sure we don't always search from the same point, or we
+ * will always reuse a potentially active context, leaving
+ * free contexts unused.
+ */
+ for (i = kvm->arch.nested_mmus_next;
+ i < (kvm->arch.nested_mmus_size + kvm->arch.nested_mmus_next);
+ i++) {
+ s2_mmu = &kvm->arch.nested_mmus[i % kvm->arch.nested_mmus_size];
+
+ if (atomic_read(&s2_mmu->refcnt) == 0)
+ break;
+ }
+ BUG_ON(atomic_read(&s2_mmu->refcnt)); /* We have struct MMUs to spare */
+
+ /* Set the scene for the next search */
+ kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size;
+
+ /* Clear the old state */
+ if (kvm_s2_mmu_valid(s2_mmu))
+ kvm_stage2_unmap_range(s2_mmu, 0, kvm_phys_size(s2_mmu));
+
+ /*
+ * The virtual VMID (modulo CnP) will be used as a key when matching
+ * an existing kvm_s2_mmu.
+ *
+ * We cache VTCR at allocation time, once and for all. It'd be great
+ * if the guest didn't screw that one up, as this is not very
+ * forgiving...
+ */
+ s2_mmu->tlb_vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2) & ~VTTBR_CNP_BIT;
+ s2_mmu->tlb_vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+ s2_mmu->nested_stage2_enabled = vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_VM;
+
+out:
+ atomic_inc(&s2_mmu->refcnt);
+ return s2_mmu;
+}
+
+void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu)
+{
+ /* CnP being set denotes an invalid entry */
+ mmu->tlb_vttbr = VTTBR_CNP_BIT;
+ mmu->nested_stage2_enabled = false;
+ atomic_set(&mmu->refcnt, 0);
+}
+
+void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
+{
+ if (is_hyp_ctxt(vcpu)) {
+ vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
+ } else {
+ write_lock(&vcpu->kvm->mmu_lock);
+ vcpu->arch.hw_mmu = get_s2_mmu_nested(vcpu);
+ write_unlock(&vcpu->kvm->mmu_lock);
+ }
+}
+
+void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
+{
+ if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) {
+ atomic_dec(&vcpu->arch.hw_mmu->refcnt);
+ vcpu->arch.hw_mmu = NULL;
+ }
+}
+
+/*
+ * Returns non-zero if permission fault is handled by injecting it to the next
+ * level hypervisor.
+ */
+int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, struct kvm_s2_trans *trans)
+{
+ bool forward_fault = false;
+
+ trans->esr = 0;
+
+ if (!kvm_vcpu_trap_is_permission_fault(vcpu))
+ return 0;
+
+ if (kvm_vcpu_trap_is_iabt(vcpu)) {
+ forward_fault = !kvm_s2_trans_executable(trans);
+ } else {
+ bool write_fault = kvm_is_write_fault(vcpu);
+
+ forward_fault = ((write_fault && !trans->writable) ||
+ (!write_fault && !trans->readable));
+ }
+
+ if (forward_fault)
+ trans->esr = esr_s2_fault(vcpu, trans->level, ESR_ELx_FSC_PERM);
+
+ return forward_fault;
+}
+
+int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2)
+{
+ vcpu_write_sys_reg(vcpu, vcpu->arch.fault.far_el2, FAR_EL2);
+ vcpu_write_sys_reg(vcpu, vcpu->arch.fault.hpfar_el2, HPFAR_EL2);
+
+ return kvm_inject_nested_sync(vcpu, esr_el2);
+}
+
+void kvm_nested_s2_wp(struct kvm *kvm)
+{
+ int i;
+
+ lockdep_assert_held_write(&kvm->mmu_lock);
+
+ for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+ struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+ if (kvm_s2_mmu_valid(mmu))
+ kvm_stage2_wp_range(mmu, 0, kvm_phys_size(mmu));
+ }
+}
+
+void kvm_nested_s2_unmap(struct kvm *kvm)
+{
+ int i;
+
+ lockdep_assert_held_write(&kvm->mmu_lock);
+
+ for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+ struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+ if (kvm_s2_mmu_valid(mmu))
+ kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu));
+ }
+}
+
+void kvm_nested_s2_flush(struct kvm *kvm)
+{
+ int i;
+
+ lockdep_assert_held_write(&kvm->mmu_lock);
+
+ for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+ struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+ if (kvm_s2_mmu_valid(mmu))
+ kvm_stage2_flush_range(mmu, 0, kvm_phys_size(mmu));
+ }
+}
+
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
+{
+ int i;
+
+ for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+ struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+ if (!WARN_ON(atomic_read(&mmu->refcnt)))
+ kvm_free_stage2_pgd(mmu);
+ }
+ kfree(kvm->arch.nested_mmus);
+ kvm->arch.nested_mmus = NULL;
+ kvm->arch.nested_mmus_size = 0;
+ kvm_uninit_stage2_mmu(kvm);
+}
+
+/*
+ * Our emulated CPU doesn't support all the possible features. For the
+ * sake of simplicity (and probably mental sanity), wipe out a number
+ * of feature bits we don't intend to support for the time being.
+ * This list should get updated as new features get added to the NV
+ * support, and new extension to the architecture.
+ */
+static void limit_nv_id_regs(struct kvm *kvm)
+{
+ u64 val, tmp;
+
+ /* Support everything but TME */
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64ISAR0_EL1);
+ val &= ~NV_FTR(ISAR0, TME);
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64ISAR0_EL1, val);
+
+ /* Support everything but Spec Invalidation and LS64 */
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64ISAR1_EL1);
+ val &= ~(NV_FTR(ISAR1, LS64) |
+ NV_FTR(ISAR1, SPECRES));
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64ISAR1_EL1, val);
+
+ /* No AMU, MPAM, S-EL2, or RAS */
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1);
+ val &= ~(GENMASK_ULL(55, 52) |
+ NV_FTR(PFR0, AMU) |
+ NV_FTR(PFR0, MPAM) |
+ NV_FTR(PFR0, SEL2) |
+ NV_FTR(PFR0, RAS) |
+ NV_FTR(PFR0, EL3) |
+ NV_FTR(PFR0, EL2) |
+ NV_FTR(PFR0, EL1));
+ /* 64bit EL1/EL2/EL3 only */
+ val |= FIELD_PREP(NV_FTR(PFR0, EL1), 0b0001);
+ val |= FIELD_PREP(NV_FTR(PFR0, EL2), 0b0001);
+ val |= FIELD_PREP(NV_FTR(PFR0, EL3), 0b0001);
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1, val);
+
+ /* Only support BTI, SSBS, CSV2_frac */
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR1_EL1);
+ val &= (NV_FTR(PFR1, BT) |
+ NV_FTR(PFR1, SSBS) |
+ NV_FTR(PFR1, CSV2_frac));
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR1_EL1, val);
+
+ /* Hide ECV, ExS, Secure Memory */
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64MMFR0_EL1);
+ val &= ~(NV_FTR(MMFR0, ECV) |
+ NV_FTR(MMFR0, EXS) |
+ NV_FTR(MMFR0, TGRAN4_2) |
+ NV_FTR(MMFR0, TGRAN16_2) |
+ NV_FTR(MMFR0, TGRAN64_2) |
+ NV_FTR(MMFR0, SNSMEM));
+
+ /* Disallow unsupported S2 page sizes */
+ switch (PAGE_SIZE) {
+ case SZ_64K:
+ val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN16_2), 0b0001);
+ fallthrough;
+ case SZ_16K:
+ val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN4_2), 0b0001);
+ fallthrough;
+ case SZ_4K:
+ /* Support everything */
break;
}
+ /*
+ * Since we can't support a guest S2 page size smaller than
+ * the host's own page size (due to KVM only populating its
+ * own S2 using the kernel's page size), advertise the
+ * limitation using FEAT_GTG.
+ */
+ switch (PAGE_SIZE) {
+ case SZ_4K:
+ val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN4_2), 0b0010);
+ fallthrough;
+ case SZ_16K:
+ val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN16_2), 0b0010);
+ fallthrough;
+ case SZ_64K:
+ val |= FIELD_PREP(NV_FTR(MMFR0, TGRAN64_2), 0b0010);
+ break;
+ }
+ /* Cap PARange to 48bits */
+ tmp = FIELD_GET(NV_FTR(MMFR0, PARANGE), val);
+ if (tmp > 0b0101) {
+ val &= ~NV_FTR(MMFR0, PARANGE);
+ val |= FIELD_PREP(NV_FTR(MMFR0, PARANGE), 0b0101);
+ }
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64MMFR0_EL1, val);
+
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64MMFR1_EL1);
+ val &= (NV_FTR(MMFR1, HCX) |
+ NV_FTR(MMFR1, PAN) |
+ NV_FTR(MMFR1, LO) |
+ NV_FTR(MMFR1, HPDS) |
+ NV_FTR(MMFR1, VH) |
+ NV_FTR(MMFR1, VMIDBits));
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64MMFR1_EL1, val);
+
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64MMFR2_EL1);
+ val &= ~(NV_FTR(MMFR2, BBM) |
+ NV_FTR(MMFR2, TTL) |
+ GENMASK_ULL(47, 44) |
+ NV_FTR(MMFR2, ST) |
+ NV_FTR(MMFR2, CCIDX) |
+ NV_FTR(MMFR2, VARange));
- return val;
+ /* Force TTL support */
+ val |= FIELD_PREP(NV_FTR(MMFR2, TTL), 0b0001);
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64MMFR2_EL1, val);
+
+ val = 0;
+ if (!cpus_have_final_cap(ARM64_HAS_HCR_NV1))
+ val |= FIELD_PREP(NV_FTR(MMFR4, E2H0),
+ ID_AA64MMFR4_EL1_E2H0_NI_NV1);
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64MMFR4_EL1, val);
+
+ /* Only limited support for PMU, Debug, BPs and WPs */
+ val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64DFR0_EL1);
+ val &= (NV_FTR(DFR0, PMUVer) |
+ NV_FTR(DFR0, WRPs) |
+ NV_FTR(DFR0, BRPs) |
+ NV_FTR(DFR0, DebugVer));
+
+ /* Cap Debug to ARMv8.1 */
+ tmp = FIELD_GET(NV_FTR(DFR0, DebugVer), val);
+ if (tmp > 0b0111) {
+ val &= ~NV_FTR(DFR0, DebugVer);
+ val |= FIELD_PREP(NV_FTR(DFR0, DebugVer), 0b0111);
+ }
+ kvm_set_vm_id_reg(kvm, SYS_ID_AA64DFR0_EL1, val);
}
u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
@@ -200,15 +962,13 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
goto out;
kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)),
- GFP_KERNEL);
+ GFP_KERNEL_ACCOUNT);
if (!kvm->arch.sysreg_masks) {
ret = -ENOMEM;
goto out;
}
- for (int i = 0; i < KVM_ARM_ID_REG_NUM; i++)
- kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
- kvm->arch.id_regs[i]);
+ limit_nv_id_regs(kvm);
/* VTTBR_EL2 */
res0 = res1 = 0;
diff --git a/arch/arm64/kvm/pauth.c b/arch/arm64/kvm/pauth.c
new file mode 100644
index 000000000000..d5eb3ae876be
--- /dev/null
+++ b/arch/arm64/kvm/pauth.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 - Google LLC
+ * Author: Marc Zyngier <maz@kernel.org>
+ *
+ * Primitive PAuth emulation for ERETAA/ERETAB.
+ *
+ * This code assumes that is is run from EL2, and that it is part of
+ * the emulation of ERETAx for a guest hypervisor. That's a lot of
+ * baked-in assumptions and shortcuts.
+ *
+ * Do no reuse for anything else!
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/gpr-num.h>
+#include <asm/kvm_emulate.h>
+#include <asm/pointer_auth.h>
+
+/* PACGA Xd, Xn, Xm */
+#define PACGA(d,n,m) \
+ asm volatile(__DEFINE_ASM_GPR_NUMS \
+ ".inst 0x9AC03000 |" \
+ "(.L__gpr_num_%[Rd] << 0) |" \
+ "(.L__gpr_num_%[Rn] << 5) |" \
+ "(.L__gpr_num_%[Rm] << 16)\n" \
+ : [Rd] "=r" ((d)) \
+ : [Rn] "r" ((n)), [Rm] "r" ((m)))
+
+static u64 compute_pac(struct kvm_vcpu *vcpu, u64 ptr,
+ struct ptrauth_key ikey)
+{
+ struct ptrauth_key gkey;
+ u64 mod, pac = 0;
+
+ preempt_disable();
+
+ if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
+ mod = __vcpu_sys_reg(vcpu, SP_EL2);
+ else
+ mod = read_sysreg(sp_el1);
+
+ gkey.lo = read_sysreg_s(SYS_APGAKEYLO_EL1);
+ gkey.hi = read_sysreg_s(SYS_APGAKEYHI_EL1);
+
+ __ptrauth_key_install_nosync(APGA, ikey);
+ isb();
+
+ PACGA(pac, ptr, mod);
+ isb();
+
+ __ptrauth_key_install_nosync(APGA, gkey);
+
+ preempt_enable();
+
+ /* PAC in the top 32bits */
+ return pac;
+}
+
+static bool effective_tbi(struct kvm_vcpu *vcpu, bool bit55)
+{
+ u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+ bool tbi, tbid;
+
+ /*
+ * Since we are authenticating an instruction address, we have
+ * to take TBID into account. If E2H==0, ignore VA[55], as
+ * TCR_EL2 only has a single TBI/TBID. If VA[55] was set in
+ * this case, this is likely a guest bug...
+ */
+ if (!vcpu_el2_e2h_is_set(vcpu)) {
+ tbi = tcr & BIT(20);
+ tbid = tcr & BIT(29);
+ } else if (bit55) {
+ tbi = tcr & TCR_TBI1;
+ tbid = tcr & TCR_TBID1;
+ } else {
+ tbi = tcr & TCR_TBI0;
+ tbid = tcr & TCR_TBID0;
+ }
+
+ return tbi && !tbid;
+}
+
+static int compute_bottom_pac(struct kvm_vcpu *vcpu, bool bit55)
+{
+ static const int maxtxsz = 39; // Revisit these two values once
+ static const int mintxsz = 16; // (if) we support TTST/LVA/LVA2
+ u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+ int txsz;
+
+ if (!vcpu_el2_e2h_is_set(vcpu) || !bit55)
+ txsz = FIELD_GET(TCR_T0SZ_MASK, tcr);
+ else
+ txsz = FIELD_GET(TCR_T1SZ_MASK, tcr);
+
+ return 64 - clamp(txsz, mintxsz, maxtxsz);
+}
+
+static u64 compute_pac_mask(struct kvm_vcpu *vcpu, bool bit55)
+{
+ int bottom_pac;
+ u64 mask;
+
+ bottom_pac = compute_bottom_pac(vcpu, bit55);
+
+ mask = GENMASK(54, bottom_pac);
+ if (!effective_tbi(vcpu, bit55))
+ mask |= GENMASK(63, 56);
+
+ return mask;
+}
+
+static u64 to_canonical_addr(struct kvm_vcpu *vcpu, u64 ptr, u64 mask)
+{
+ bool bit55 = !!(ptr & BIT(55));
+
+ if (bit55)
+ return ptr | mask;
+
+ return ptr & ~mask;
+}
+
+static u64 corrupt_addr(struct kvm_vcpu *vcpu, u64 ptr)
+{
+ bool bit55 = !!(ptr & BIT(55));
+ u64 mask, error_code;
+ int shift;
+
+ if (effective_tbi(vcpu, bit55)) {
+ mask = GENMASK(54, 53);
+ shift = 53;
+ } else {
+ mask = GENMASK(62, 61);
+ shift = 61;
+ }
+
+ if (esr_iss_is_eretab(kvm_vcpu_get_esr(vcpu)))
+ error_code = 2 << shift;
+ else
+ error_code = 1 << shift;
+
+ ptr &= ~mask;
+ ptr |= error_code;
+
+ return ptr;
+}
+
+/*
+ * Authenticate an ERETAA/ERETAB instruction, returning true if the
+ * authentication succeeded and false otherwise. In all cases, *elr
+ * contains the VA to ERET to. Potential exception injection is left
+ * to the caller.
+ */
+bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
+{
+ u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL2);
+ u64 esr = kvm_vcpu_get_esr(vcpu);
+ u64 ptr, cptr, pac, mask;
+ struct ptrauth_key ikey;
+
+ *elr = ptr = vcpu_read_sys_reg(vcpu, ELR_EL2);
+
+ /* We assume we're already in the context of an ERETAx */
+ if (esr_iss_is_eretab(esr)) {
+ if (!(sctlr & SCTLR_EL1_EnIB))
+ return true;
+
+ ikey.lo = __vcpu_sys_reg(vcpu, APIBKEYLO_EL1);
+ ikey.hi = __vcpu_sys_reg(vcpu, APIBKEYHI_EL1);
+ } else {
+ if (!(sctlr & SCTLR_EL1_EnIA))
+ return true;
+
+ ikey.lo = __vcpu_sys_reg(vcpu, APIAKEYLO_EL1);
+ ikey.hi = __vcpu_sys_reg(vcpu, APIAKEYHI_EL1);
+ }
+
+ mask = compute_pac_mask(vcpu, !!(ptr & BIT(55)));
+ cptr = to_canonical_addr(vcpu, ptr, mask);
+
+ pac = compute_pac(vcpu, cptr, ikey);
+
+ /*
+ * Slightly deviate from the pseudocode: if we have a PAC
+ * match with the signed pointer, then it must be good.
+ * Anything after this point is pure error handling.
+ */
+ if ((pac & mask) == (ptr & mask)) {
+ *elr = cptr;
+ return true;
+ }
+
+ /*
+ * Authentication failed, corrupt the canonical address if
+ * PAuth2 isn't implemented, or some XORing if it is.
+ */
+ if (!kvm_has_pauth(vcpu->kvm, PAuth2))
+ cptr = corrupt_addr(vcpu, cptr);
+ else
+ cptr = ptr ^ (pac & mask);
+
+ *elr = cptr;
+ return false;
+}
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index b7be96a53597..85117ea8f351 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -222,7 +222,6 @@ void pkvm_destroy_hyp_vm(struct kvm *host_kvm)
int pkvm_init_host_vm(struct kvm *host_kvm)
{
- mutex_init(&host_kvm->lock);
return 0;
}
@@ -259,6 +258,7 @@ static int __init finalize_pkvm(void)
* at, which would end badly once inaccessible.
*/
kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start);
+ kmemleak_free_part(__hyp_rodata_start, __hyp_rodata_end - __hyp_rodata_start);
kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size);
ret = pkvm_drop_host_privileges();
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index a35ce10e0a9f..82a2a003259c 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -14,7 +14,6 @@
#include <asm/kvm_emulate.h>
#include <kvm/arm_pmu.h>
#include <kvm/arm_vgic.h>
-#include <asm/arm_pmuv3.h>
#define PERF_ATTR_CFG1_COUNTER_64BIT BIT(0)
@@ -54,7 +53,7 @@ static u32 __kvm_pmu_event_mask(unsigned int pmuver)
static u32 kvm_pmu_event_mask(struct kvm *kvm)
{
- u64 dfr0 = IDREG(kvm, SYS_ID_AA64DFR0_EL1);
+ u64 dfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64DFR0_EL1);
u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, dfr0);
return __kvm_pmu_event_mask(pmuver);
diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
index a243934c5568..329819806096 100644
--- a/arch/arm64/kvm/pmu.c
+++ b/arch/arm64/kvm/pmu.c
@@ -232,7 +232,7 @@ bool kvm_set_pmuserenr(u64 val)
if (!vcpu || !vcpu_get_flag(vcpu, PMUSERENR_ON_CPU))
return false;
- hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+ hctxt = host_data_ptr(host_ctxt);
ctxt_sys_reg(hctxt, PMUSERENR_EL0) = val;
return true;
}
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 68d1d05672bd..0b0ae5ae7bc2 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -32,6 +32,7 @@
/* Maximum phys_shift supported for any VM on this host */
static u32 __ro_after_init kvm_ipa_limit;
+unsigned int __ro_after_init kvm_host_sve_max_vl;
/*
* ARMv8 Reset Values
@@ -51,6 +52,8 @@ int __init kvm_arm_init_sve(void)
{
if (system_supports_sve()) {
kvm_sve_max_vl = sve_max_virtualisable_vl();
+ kvm_host_sve_max_vl = sve_max_vl();
+ kvm_nvhe_sym(kvm_host_sve_max_vl) = kvm_host_sve_max_vl;
/*
* The get_sve_reg()/set_sve_reg() ioctl interface will need
@@ -151,7 +154,6 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
{
void *sve_state = vcpu->arch.sve_state;
- kvm_vcpu_unshare_task_fp(vcpu);
kvm_unshare_hyp(vcpu, vcpu + 1);
if (sve_state)
kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
@@ -266,6 +268,12 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
preempt_enable();
}
+u32 kvm_get_pa_bits(struct kvm *kvm)
+{
+ /* Fixed limit until we can configure ID_AA64MMFR0.PARange */
+ return kvm_ipa_limit;
+}
+
u32 get_kvm_ipa_limit(void)
{
return kvm_ipa_limit;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index c9f4f387155f..c90324060436 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -121,6 +121,7 @@ static bool get_el2_to_el1_mapping(unsigned int reg,
MAPPED_EL2_SYSREG(AMAIR_EL2, AMAIR_EL1, NULL );
MAPPED_EL2_SYSREG(ELR_EL2, ELR_EL1, NULL );
MAPPED_EL2_SYSREG(SPSR_EL2, SPSR_EL1, NULL );
+ MAPPED_EL2_SYSREG(ZCR_EL2, ZCR_EL1, NULL );
default:
return false;
}
@@ -383,6 +384,12 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
bool was_enabled = vcpu_has_cache_enabled(vcpu);
u64 val, mask, shift;
+ if (reg_to_encoding(r) == SYS_TCR2_EL1 &&
+ !kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, TCRX, IMP)) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
BUG_ON(!p->is_write);
get_access_mask(r, &mask, &shift);
@@ -1565,20 +1572,37 @@ static u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu,
static u64 read_id_reg(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
{
- return IDREG(vcpu->kvm, reg_to_encoding(r));
+ return kvm_read_vm_id_reg(vcpu->kvm, reg_to_encoding(r));
+}
+
+static bool is_feature_id_reg(u32 encoding)
+{
+ return (sys_reg_Op0(encoding) == 3 &&
+ (sys_reg_Op1(encoding) < 2 || sys_reg_Op1(encoding) == 3) &&
+ sys_reg_CRn(encoding) == 0 &&
+ sys_reg_CRm(encoding) <= 7);
}
/*
* Return true if the register's (Op0, Op1, CRn, CRm, Op2) is
- * (3, 0, 0, crm, op2), where 1<=crm<8, 0<=op2<8.
+ * (3, 0, 0, crm, op2), where 1<=crm<8, 0<=op2<8, which is the range of ID
+ * registers KVM maintains on a per-VM basis.
*/
-static inline bool is_id_reg(u32 id)
+static inline bool is_vm_ftr_id_reg(u32 id)
{
+ if (id == SYS_CTR_EL0)
+ return true;
+
return (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&
sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 1 &&
sys_reg_CRm(id) < 8);
}
+static inline bool is_vcpu_ftr_id_reg(u32 id)
+{
+ return is_feature_id_reg(id) && !is_vm_ftr_id_reg(id);
+}
+
static inline bool is_aa32_id_reg(u32 id)
{
return (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&
@@ -1837,7 +1861,7 @@ static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
ret = arm64_check_features(vcpu, rd, val);
if (!ret)
- IDREG(vcpu->kvm, id) = val;
+ kvm_set_vm_id_reg(vcpu->kvm, id, val);
mutex_unlock(&vcpu->kvm->arch.config_lock);
@@ -1853,6 +1877,18 @@ static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
return ret;
}
+void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val)
+{
+ u64 *p = __vm_id_reg(&kvm->arch, reg);
+
+ lockdep_assert_held(&kvm->arch.config_lock);
+
+ if (KVM_BUG_ON(kvm_vm_has_ran_once(kvm) || !p, kvm))
+ return;
+
+ *p = val;
+}
+
static int get_raz_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
u64 *val)
{
@@ -1872,7 +1908,7 @@ static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
if (p->is_write)
return write_to_read_only(vcpu, p, r);
- p->regval = read_sanitised_ftr_reg(SYS_CTR_EL0);
+ p->regval = kvm_read_vm_id_reg(vcpu->kvm, SYS_CTR_EL0);
return true;
}
@@ -2185,6 +2221,40 @@ static u64 reset_hcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
return __vcpu_sys_reg(vcpu, r->reg) = val;
}
+static unsigned int sve_el2_visibility(const struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+{
+ unsigned int r;
+
+ r = el2_visibility(vcpu, rd);
+ if (r)
+ return r;
+
+ return sve_visibility(vcpu, rd);
+}
+
+static bool access_zcr_el2(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ unsigned int vq;
+
+ if (guest_hyp_sve_traps_enabled(vcpu)) {
+ kvm_inject_nested_sve_trap(vcpu);
+ return true;
+ }
+
+ if (!p->is_write) {
+ p->regval = vcpu_read_sys_reg(vcpu, ZCR_EL2);
+ return true;
+ }
+
+ vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
+ vq = min(vq, vcpu_sve_max_vq(vcpu));
+ vcpu_write_sys_reg(vcpu, vq - 1, ZCR_EL2);
+ return true;
+}
+
/*
* Architected system registers.
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2338,7 +2408,6 @@ static const struct sys_reg_desc sys_reg_descs[] = {
ID_AA64MMFR0_EL1_TGRAN16_2)),
ID_WRITABLE(ID_AA64MMFR1_EL1, ~(ID_AA64MMFR1_EL1_RES0 |
ID_AA64MMFR1_EL1_HCX |
- ID_AA64MMFR1_EL1_XNX |
ID_AA64MMFR1_EL1_TWED |
ID_AA64MMFR1_EL1_XNX |
ID_AA64MMFR1_EL1_VH |
@@ -2458,11 +2527,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_CCSIDR_EL1), access_ccsidr },
{ SYS_DESC(SYS_CLIDR_EL1), access_clidr, reset_clidr, CLIDR_EL1,
- .set_user = set_clidr },
+ .set_user = set_clidr, .val = ~CLIDR_EL1_RES0 },
{ SYS_DESC(SYS_CCSIDR2_EL1), undef_access },
{ SYS_DESC(SYS_SMIDR_EL1), undef_access },
{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
- { SYS_DESC(SYS_CTR_EL0), access_ctr },
+ ID_WRITABLE(CTR_EL0, CTR_EL0_DIC_MASK |
+ CTR_EL0_IDC_MASK |
+ CTR_EL0_DminLine_MASK |
+ CTR_EL0_IminLine_MASK),
{ SYS_DESC(SYS_SVCR), undef_access },
{ PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr,
@@ -2675,6 +2747,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG_VNCR(HFGITR_EL2, reset_val, 0),
EL2_REG_VNCR(HACR_EL2, reset_val, 0),
+ { SYS_DESC(SYS_ZCR_EL2), .access = access_zcr_el2, .reset = reset_val,
+ .visibility = sve_el2_visibility, .reg = ZCR_EL2 },
+
EL2_REG_VNCR(HCRX_EL2, reset_val, 0),
EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
@@ -2728,6 +2803,264 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG(SP_EL2, NULL, reset_unknown, 0),
};
+static bool kvm_supported_tlbi_s12_op(struct kvm_vcpu *vpcu, u32 instr)
+{
+ struct kvm *kvm = vpcu->kvm;
+ u8 CRm = sys_reg_CRm(instr);
+
+ if (sys_reg_CRn(instr) == TLBI_CRn_nXS &&
+ !kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))
+ return false;
+
+ if (CRm == TLBI_CRm_nROS &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ return false;
+
+ return true;
+}
+
+static bool handle_alle1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+
+ if (!kvm_supported_tlbi_s12_op(vcpu, sys_encoding)) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
+ write_lock(&vcpu->kvm->mmu_lock);
+
+ /*
+ * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the
+ * corresponding VMIDs.
+ */
+ kvm_nested_s2_unmap(vcpu->kvm);
+
+ write_unlock(&vcpu->kvm->mmu_lock);
+
+ return true;
+}
+
+static bool kvm_supported_tlbi_ipas2_op(struct kvm_vcpu *vpcu, u32 instr)
+{
+ struct kvm *kvm = vpcu->kvm;
+ u8 CRm = sys_reg_CRm(instr);
+ u8 Op2 = sys_reg_Op2(instr);
+
+ if (sys_reg_CRn(instr) == TLBI_CRn_nXS &&
+ !kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))
+ return false;
+
+ if (CRm == TLBI_CRm_IPAIS && (Op2 == 2 || Op2 == 6) &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+ return false;
+
+ if (CRm == TLBI_CRm_IPAONS && (Op2 == 0 || Op2 == 4) &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ return false;
+
+ if (CRm == TLBI_CRm_IPAONS && (Op2 == 3 || Op2 == 7) &&
+ !kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+ return false;
+
+ return true;
+}
+
+/* Only defined here as this is an internal "abstraction" */
+union tlbi_info {
+ struct {
+ u64 start;
+ u64 size;
+ } range;
+
+ struct {
+ u64 addr;
+ } ipa;
+
+ struct {
+ u64 addr;
+ u32 encoding;
+ } va;
+};
+
+static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu,
+ const union tlbi_info *info)
+{
+ kvm_stage2_unmap_range(mmu, info->range.start, info->range.size);
+}
+
+static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+ u64 limit, vttbr;
+
+ if (!kvm_supported_tlbi_s12_op(vcpu, sys_encoding)) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
+ vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+ limit = BIT_ULL(kvm_get_pa_bits(vcpu->kvm));
+
+ kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
+ &(union tlbi_info) {
+ .range = {
+ .start = 0,
+ .size = limit,
+ },
+ },
+ s2_mmu_unmap_range);
+
+ return true;
+}
+
+static bool handle_ripas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+ u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+ u64 base, range, tg, num, scale;
+ int shift;
+
+ if (!kvm_supported_tlbi_ipas2_op(vcpu, sys_encoding)) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
+ /*
+ * Because the shadow S2 structure doesn't necessarily reflect that
+ * of the guest's S2 (different base granule size, for example), we
+ * decide to ignore TTL and only use the described range.
+ */
+ tg = FIELD_GET(GENMASK(47, 46), p->regval);
+ scale = FIELD_GET(GENMASK(45, 44), p->regval);
+ num = FIELD_GET(GENMASK(43, 39), p->regval);
+ base = p->regval & GENMASK(36, 0);
+
+ switch(tg) {
+ case 1:
+ shift = 12;
+ break;
+ case 2:
+ shift = 14;
+ break;
+ case 3:
+ default: /* IMPDEF: handle tg==0 as 64k */
+ shift = 16;
+ break;
+ }
+
+ base <<= shift;
+ range = __TLBI_RANGE_PAGES(num, scale) << shift;
+
+ kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
+ &(union tlbi_info) {
+ .range = {
+ .start = base,
+ .size = range,
+ },
+ },
+ s2_mmu_unmap_range);
+
+ return true;
+}
+
+static void s2_mmu_unmap_ipa(struct kvm_s2_mmu *mmu,
+ const union tlbi_info *info)
+{
+ unsigned long max_size;
+ u64 base_addr;
+
+ /*
+ * We drop a number of things from the supplied value:
+ *
+ * - NS bit: we're non-secure only.
+ *
+ * - IPA[51:48]: We don't support 52bit IPA just yet...
+ *
+ * And of course, adjust the IPA to be on an actual address.
+ */
+ base_addr = (info->ipa.addr & GENMASK_ULL(35, 0)) << 12;
+ max_size = compute_tlb_inval_range(mmu, info->ipa.addr);
+ base_addr &= ~(max_size - 1);
+
+ kvm_stage2_unmap_range(mmu, base_addr, max_size);
+}
+
+static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+ u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+
+ if (!kvm_supported_tlbi_ipas2_op(vcpu, sys_encoding)) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
+ kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
+ &(union tlbi_info) {
+ .ipa = {
+ .addr = p->regval,
+ },
+ },
+ s2_mmu_unmap_ipa);
+
+ return true;
+}
+
+static void s2_mmu_tlbi_s1e1(struct kvm_s2_mmu *mmu,
+ const union tlbi_info *info)
+{
+ WARN_ON(__kvm_tlbi_s1e2(mmu, info->va.addr, info->va.encoding));
+}
+
+static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+ u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+
+ /*
+ * If we're here, this is because we've trapped on a EL1 TLBI
+ * instruction that affects the EL1 translation regime while
+ * we're running in a context that doesn't allow us to let the
+ * HW do its thing (aka vEL2):
+ *
+ * - HCR_EL2.E2H == 0 : a non-VHE guest
+ * - HCR_EL2.{E2H,TGE} == { 1, 0 } : a VHE guest in guest mode
+ *
+ * We don't expect these helpers to ever be called when running
+ * in a vEL1 context.
+ */
+
+ WARN_ON(!vcpu_is_el2(vcpu));
+
+ if (!kvm_supported_tlbi_s1e1_op(vcpu, sys_encoding)) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
+ kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
+ &(union tlbi_info) {
+ .va = {
+ .addr = p->regval,
+ .encoding = sys_encoding,
+ },
+ },
+ s2_mmu_tlbi_s1e1);
+
+ return true;
+}
+
+#define SYS_INSN(insn, access_fn) \
+ { \
+ SYS_DESC(OP_##insn), \
+ .access = (access_fn), \
+ }
+
static struct sys_reg_desc sys_insn_descs[] = {
{ SYS_DESC(SYS_DC_ISW), access_dcsw },
{ SYS_DESC(SYS_DC_IGSW), access_dcgsw },
@@ -2738,9 +3071,147 @@ static struct sys_reg_desc sys_insn_descs[] = {
{ SYS_DESC(SYS_DC_CISW), access_dcsw },
{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
-};
-static const struct sys_reg_desc *first_idreg;
+ SYS_INSN(TLBI_VMALLE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_ASIDE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAAE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VALE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAALE1OS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_RVAE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAAE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVALE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAALE1IS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_VMALLE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_ASIDE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAAE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VALE1IS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAALE1IS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_RVAE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAAE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVALE1OS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAALE1OS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_RVAE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAAE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVALE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAALE1, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_VMALLE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_ASIDE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAAE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_VALE1, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAALE1, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_VMALLE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_ASIDE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAAE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VALE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAALE1OSNXS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_RVAE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAAE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVALE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAALE1ISNXS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_VMALLE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_ASIDE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAAE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VALE1ISNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAALE1ISNXS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_RVAE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAAE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVALE1OSNXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAALE1OSNXS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_RVAE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAAE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVALE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_RVAALE1NXS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_VMALLE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_ASIDE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAAE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VALE1NXS, handle_tlbi_el1),
+ SYS_INSN(TLBI_VAALE1NXS, handle_tlbi_el1),
+
+ SYS_INSN(TLBI_IPAS2E1IS, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2E1IS, handle_ripas2e1is),
+ SYS_INSN(TLBI_IPAS2LE1IS, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2LE1IS, handle_ripas2e1is),
+
+ SYS_INSN(TLBI_ALLE2OS, trap_undef),
+ SYS_INSN(TLBI_VAE2OS, trap_undef),
+ SYS_INSN(TLBI_ALLE1OS, handle_alle1is),
+ SYS_INSN(TLBI_VALE2OS, trap_undef),
+ SYS_INSN(TLBI_VMALLS12E1OS, handle_vmalls12e1is),
+
+ SYS_INSN(TLBI_RVAE2IS, trap_undef),
+ SYS_INSN(TLBI_RVALE2IS, trap_undef),
+
+ SYS_INSN(TLBI_ALLE1IS, handle_alle1is),
+ SYS_INSN(TLBI_VMALLS12E1IS, handle_vmalls12e1is),
+ SYS_INSN(TLBI_IPAS2E1OS, handle_ipas2e1is),
+ SYS_INSN(TLBI_IPAS2E1, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2E1, handle_ripas2e1is),
+ SYS_INSN(TLBI_RIPAS2E1OS, handle_ripas2e1is),
+ SYS_INSN(TLBI_IPAS2LE1OS, handle_ipas2e1is),
+ SYS_INSN(TLBI_IPAS2LE1, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2LE1, handle_ripas2e1is),
+ SYS_INSN(TLBI_RIPAS2LE1OS, handle_ripas2e1is),
+ SYS_INSN(TLBI_RVAE2OS, trap_undef),
+ SYS_INSN(TLBI_RVALE2OS, trap_undef),
+ SYS_INSN(TLBI_RVAE2, trap_undef),
+ SYS_INSN(TLBI_RVALE2, trap_undef),
+ SYS_INSN(TLBI_ALLE1, handle_alle1is),
+ SYS_INSN(TLBI_VMALLS12E1, handle_vmalls12e1is),
+
+ SYS_INSN(TLBI_IPAS2E1ISNXS, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2E1ISNXS, handle_ripas2e1is),
+ SYS_INSN(TLBI_IPAS2LE1ISNXS, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2LE1ISNXS, handle_ripas2e1is),
+
+ SYS_INSN(TLBI_ALLE2OSNXS, trap_undef),
+ SYS_INSN(TLBI_VAE2OSNXS, trap_undef),
+ SYS_INSN(TLBI_ALLE1OSNXS, handle_alle1is),
+ SYS_INSN(TLBI_VALE2OSNXS, trap_undef),
+ SYS_INSN(TLBI_VMALLS12E1OSNXS, handle_vmalls12e1is),
+
+ SYS_INSN(TLBI_RVAE2ISNXS, trap_undef),
+ SYS_INSN(TLBI_RVALE2ISNXS, trap_undef),
+ SYS_INSN(TLBI_ALLE2ISNXS, trap_undef),
+ SYS_INSN(TLBI_VAE2ISNXS, trap_undef),
+
+ SYS_INSN(TLBI_ALLE1ISNXS, handle_alle1is),
+ SYS_INSN(TLBI_VALE2ISNXS, trap_undef),
+ SYS_INSN(TLBI_VMALLS12E1ISNXS, handle_vmalls12e1is),
+ SYS_INSN(TLBI_IPAS2E1OSNXS, handle_ipas2e1is),
+ SYS_INSN(TLBI_IPAS2E1NXS, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2E1NXS, handle_ripas2e1is),
+ SYS_INSN(TLBI_RIPAS2E1OSNXS, handle_ripas2e1is),
+ SYS_INSN(TLBI_IPAS2LE1OSNXS, handle_ipas2e1is),
+ SYS_INSN(TLBI_IPAS2LE1NXS, handle_ipas2e1is),
+ SYS_INSN(TLBI_RIPAS2LE1NXS, handle_ripas2e1is),
+ SYS_INSN(TLBI_RIPAS2LE1OSNXS, handle_ripas2e1is),
+ SYS_INSN(TLBI_RVAE2OSNXS, trap_undef),
+ SYS_INSN(TLBI_RVALE2OSNXS, trap_undef),
+ SYS_INSN(TLBI_RVAE2NXS, trap_undef),
+ SYS_INSN(TLBI_RVALE2NXS, trap_undef),
+ SYS_INSN(TLBI_ALLE2NXS, trap_undef),
+ SYS_INSN(TLBI_VAE2NXS, trap_undef),
+ SYS_INSN(TLBI_ALLE1NXS, handle_alle1is),
+ SYS_INSN(TLBI_VALE2NXS, trap_undef),
+ SYS_INSN(TLBI_VMALLS12E1NXS, handle_vmalls12e1is),
+};
static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
@@ -2749,7 +3220,7 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
if (p->is_write) {
return ignore_write(vcpu, p);
} else {
- u64 dfr = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
+ u64 dfr = kvm_read_vm_id_reg(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
u32 el3 = kvm_has_feat(vcpu->kvm, ID_AA64PFR0_EL1, EL3, IMP);
p->regval = ((SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr) << 28) |
@@ -3069,12 +3540,14 @@ static bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
for (i = 0; i < n; i++) {
if (!is_32 && table[i].reg && !table[i].reset) {
- kvm_err("sys_reg table %pS entry %d lacks reset\n", &table[i], i);
+ kvm_err("sys_reg table %pS entry %d (%s) lacks reset\n",
+ &table[i], i, table[i].name);
return false;
}
if (i && cmp_sys_reg(&table[i-1], &table[i]) >= 0) {
- kvm_err("sys_reg table %pS entry %d out of order\n", &table[i - 1], i - 1);
+ kvm_err("sys_reg table %pS entry %d (%s -> %s) out of order\n",
+ &table[i], i, table[i - 1].name, table[i].name);
return false;
}
}
@@ -3425,6 +3898,25 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
return false;
}
+static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, u8 pos)
+{
+ unsigned long i, idreg_idx = 0;
+
+ for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
+ const struct sys_reg_desc *r = &sys_reg_descs[i];
+
+ if (!is_vm_ftr_id_reg(reg_to_encoding(r)))
+ continue;
+
+ if (idreg_idx == pos)
+ return r;
+
+ idreg_idx++;
+ }
+
+ return NULL;
+}
+
static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
{
struct kvm *kvm = s->private;
@@ -3436,7 +3928,7 @@ static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags) &&
*iter == (u8)~0) {
*iter = *pos;
- if (*iter >= KVM_ARM_ID_REG_NUM)
+ if (!idregs_debug_find(kvm, *iter))
iter = NULL;
} else {
iter = ERR_PTR(-EBUSY);
@@ -3453,7 +3945,7 @@ static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
(*pos)++;
- if ((kvm->arch.idreg_debugfs_iter + 1) < KVM_ARM_ID_REG_NUM) {
+ if (idregs_debug_find(kvm, kvm->arch.idreg_debugfs_iter + 1)) {
kvm->arch.idreg_debugfs_iter++;
return &kvm->arch.idreg_debugfs_iter;
@@ -3478,16 +3970,16 @@ static void idregs_debug_stop(struct seq_file *s, void *v)
static int idregs_debug_show(struct seq_file *s, void *v)
{
- struct kvm *kvm = s->private;
const struct sys_reg_desc *desc;
+ struct kvm *kvm = s->private;
- desc = first_idreg + kvm->arch.idreg_debugfs_iter;
+ desc = idregs_debug_find(kvm, kvm->arch.idreg_debugfs_iter);
if (!desc->name)
return 0;
seq_printf(s, "%20s:\t%016llx\n",
- desc->name, IDREG(kvm, IDX_IDREG(kvm->arch.idreg_debugfs_iter)));
+ desc->name, kvm_read_vm_id_reg(kvm, reg_to_encoding(desc)));
return 0;
}
@@ -3509,26 +4001,24 @@ void kvm_sys_regs_create_debugfs(struct kvm *kvm)
&idregs_debug_fops);
}
-static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
+static void reset_vm_ftr_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *reg)
{
- const struct sys_reg_desc *idreg = first_idreg;
- u32 id = reg_to_encoding(idreg);
+ u32 id = reg_to_encoding(reg);
struct kvm *kvm = vcpu->kvm;
if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
return;
- lockdep_assert_held(&kvm->arch.config_lock);
-
- /* Initialize all idregs */
- while (is_id_reg(id)) {
- IDREG(kvm, id) = idreg->reset(vcpu, idreg);
+ kvm_set_vm_id_reg(kvm, id, reg->reset(vcpu, reg));
+}
- idreg++;
- id = reg_to_encoding(idreg);
- }
+static void reset_vcpu_ftr_id_reg(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *reg)
+{
+ if (kvm_vcpu_initialized(vcpu))
+ return;
- set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
+ reg->reset(vcpu, reg);
}
/**
@@ -3540,19 +4030,24 @@ static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
*/
void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
{
+ struct kvm *kvm = vcpu->kvm;
unsigned long i;
- kvm_reset_id_regs(vcpu);
-
for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
const struct sys_reg_desc *r = &sys_reg_descs[i];
- if (is_id_reg(reg_to_encoding(r)))
+ if (!r->reset)
continue;
- if (r->reset)
+ if (is_vm_ftr_id_reg(reg_to_encoding(r)))
+ reset_vm_ftr_id_reg(vcpu, r);
+ else if (is_vcpu_ftr_id_reg(reg_to_encoding(r)))
+ reset_vcpu_ftr_id_reg(vcpu, r);
+ else
r->reset(vcpu, r);
}
+
+ set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
}
/**
@@ -3667,8 +4162,8 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
*/
#define FUNCTION_INVARIANT(reg) \
- static u64 get_##reg(struct kvm_vcpu *v, \
- const struct sys_reg_desc *r) \
+ static u64 reset_##reg(struct kvm_vcpu *v, \
+ const struct sys_reg_desc *r) \
{ \
((struct sys_reg_desc *)r)->val = read_sysreg(reg); \
return ((struct sys_reg_desc *)r)->val; \
@@ -3678,18 +4173,11 @@ FUNCTION_INVARIANT(midr_el1)
FUNCTION_INVARIANT(revidr_el1)
FUNCTION_INVARIANT(aidr_el1)
-static u64 get_ctr_el0(struct kvm_vcpu *v, const struct sys_reg_desc *r)
-{
- ((struct sys_reg_desc *)r)->val = read_sanitised_ftr_reg(SYS_CTR_EL0);
- return ((struct sys_reg_desc *)r)->val;
-}
-
/* ->val is filled in by kvm_sys_reg_table_init() */
static struct sys_reg_desc invariant_sys_regs[] __ro_after_init = {
- { SYS_DESC(SYS_MIDR_EL1), NULL, get_midr_el1 },
- { SYS_DESC(SYS_REVIDR_EL1), NULL, get_revidr_el1 },
- { SYS_DESC(SYS_AIDR_EL1), NULL, get_aidr_el1 },
- { SYS_DESC(SYS_CTR_EL0), NULL, get_ctr_el0 },
+ { SYS_DESC(SYS_MIDR_EL1), NULL, reset_midr_el1 },
+ { SYS_DESC(SYS_REVIDR_EL1), NULL, reset_revidr_el1 },
+ { SYS_DESC(SYS_AIDR_EL1), NULL, reset_aidr_el1 },
};
static int get_invariant_sys_reg(u64 id, u64 __user *uaddr)
@@ -3978,14 +4466,6 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
sys_reg_CRm(r), \
sys_reg_Op2(r))
-static bool is_feature_id_reg(u32 encoding)
-{
- return (sys_reg_Op0(encoding) == 3 &&
- (sys_reg_Op1(encoding) < 2 || sys_reg_Op1(encoding) == 3) &&
- sys_reg_CRn(encoding) == 0 &&
- sys_reg_CRm(encoding) <= 7);
-}
-
int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *range)
{
const void *zero_page = page_to_virt(ZERO_PAGE(0));
@@ -4008,20 +4488,11 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *
if (!is_feature_id_reg(encoding) || !reg->set_user)
continue;
- /*
- * For ID registers, we return the writable mask. Other feature
- * registers return a full 64bit mask. That's not necessary
- * compliant with a given revision of the architecture, but the
- * RES0/RES1 definitions allow us to do that.
- */
- if (is_id_reg(encoding)) {
- if (!reg->val ||
- (is_aa32_id_reg(encoding) && !kvm_supports_32bit_el0()))
- continue;
- val = reg->val;
- } else {
- val = ~0UL;
+ if (!reg->val ||
+ (is_aa32_id_reg(encoding) && !kvm_supports_32bit_el0())) {
+ continue;
}
+ val = reg->val;
if (put_user(val, (masks + KVM_ARM_FEATURE_ID_RANGE_INDEX(encoding))))
return -EFAULT;
@@ -4030,11 +4501,34 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *
return 0;
}
-void kvm_init_sysreg(struct kvm_vcpu *vcpu)
+static void vcpu_set_hcr(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
- mutex_lock(&kvm->arch.config_lock);
+ if (has_vhe() || has_hvhe())
+ vcpu->arch.hcr_el2 |= HCR_E2H;
+ if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
+ /* route synchronous external abort exceptions to EL2 */
+ vcpu->arch.hcr_el2 |= HCR_TEA;
+ /* trap error record accesses */
+ vcpu->arch.hcr_el2 |= HCR_TERR;
+ }
+
+ if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
+ vcpu->arch.hcr_el2 |= HCR_FWB;
+
+ if (cpus_have_final_cap(ARM64_HAS_EVT) &&
+ !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE) &&
+ kvm_read_vm_id_reg(kvm, SYS_CTR_EL0) == read_sanitised_ftr_reg(SYS_CTR_EL0))
+ vcpu->arch.hcr_el2 |= HCR_TID4;
+ else
+ vcpu->arch.hcr_el2 |= HCR_TID2;
+
+ if (vcpu_el1_is_32bit(vcpu))
+ vcpu->arch.hcr_el2 &= ~HCR_RW;
+
+ if (kvm_has_mte(vcpu->kvm))
+ vcpu->arch.hcr_el2 |= HCR_ATA;
/*
* In the absence of FGT, we cannot independently trap TLBI
@@ -4043,12 +4537,29 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
*/
if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
vcpu->arch.hcr_el2 |= HCR_TTLBOS;
+}
+
+void kvm_calculate_traps(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+
+ mutex_lock(&kvm->arch.config_lock);
+ vcpu_set_hcr(vcpu);
if (cpus_have_final_cap(ARM64_HAS_HCX)) {
- vcpu->arch.hcrx_el2 = HCRX_GUEST_FLAGS;
+ /*
+ * In general, all HCRX_EL2 bits are gated by a feature.
+ * The only reason we can set SMPME without checking any
+ * feature is that its effects are not directly observable
+ * from the guest.
+ */
+ vcpu->arch.hcrx_el2 = HCRX_EL2_SMPME;
if (kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
vcpu->arch.hcrx_el2 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+
+ if (kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
+ vcpu->arch.hcrx_el2 |= HCRX_EL2_TCR2En;
}
if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
@@ -4104,7 +4615,6 @@ out:
int __init kvm_sys_reg_table_init(void)
{
- struct sys_reg_params params;
bool valid = true;
unsigned int i;
int ret = 0;
@@ -4125,12 +4635,6 @@ int __init kvm_sys_reg_table_init(void)
for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)
invariant_sys_regs[i].reset(NULL, &invariant_sys_regs[i]);
- /* Find the first idreg (SYS_ID_PFR0_EL1) in sys_reg_descs. */
- params = encoding_to_params(SYS_ID_PFR0_EL1);
- first_idreg = find_reg(&params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
- if (!first_idreg)
- return -EINVAL;
-
ret = populate_nv_trap_config();
for (i = 0; !ret && i < ARRAY_SIZE(sys_reg_descs); i++)
diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c
index 389025ce7749..bcbc8c986b1d 100644
--- a/arch/arm64/kvm/vgic/vgic-debug.c
+++ b/arch/arm64/kvm/vgic/vgic-debug.c
@@ -28,27 +28,65 @@ struct vgic_state_iter {
int nr_lpis;
int dist_id;
int vcpu_id;
- int intid;
+ unsigned long intid;
int lpi_idx;
- u32 *lpi_array;
};
-static void iter_next(struct vgic_state_iter *iter)
+static void iter_next(struct kvm *kvm, struct vgic_state_iter *iter)
{
+ struct vgic_dist *dist = &kvm->arch.vgic;
+
if (iter->dist_id == 0) {
iter->dist_id++;
return;
}
+ /*
+ * Let the xarray drive the iterator after the last SPI, as the iterator
+ * has exhausted the sequentially-allocated INTID space.
+ */
+ if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS - 1)) {
+ if (iter->lpi_idx < iter->nr_lpis)
+ xa_find_after(&dist->lpi_xa, &iter->intid,
+ VGIC_LPI_MAX_INTID,
+ LPI_XA_MARK_DEBUG_ITER);
+ iter->lpi_idx++;
+ return;
+ }
+
iter->intid++;
if (iter->intid == VGIC_NR_PRIVATE_IRQS &&
++iter->vcpu_id < iter->nr_cpus)
iter->intid = 0;
+}
- if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS)) {
- if (iter->lpi_idx < iter->nr_lpis)
- iter->intid = iter->lpi_array[iter->lpi_idx];
- iter->lpi_idx++;
+static int iter_mark_lpis(struct kvm *kvm)
+{
+ struct vgic_dist *dist = &kvm->arch.vgic;
+ struct vgic_irq *irq;
+ unsigned long intid;
+ int nr_lpis = 0;
+
+ xa_for_each(&dist->lpi_xa, intid, irq) {
+ if (!vgic_try_get_irq_kref(irq))
+ continue;
+
+ xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
+ nr_lpis++;
+ }
+
+ return nr_lpis;
+}
+
+static void iter_unmark_lpis(struct kvm *kvm)
+{
+ struct vgic_dist *dist = &kvm->arch.vgic;
+ struct vgic_irq *irq;
+ unsigned long intid;
+
+ xa_for_each(&dist->lpi_xa, intid, irq) {
+ xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
+ vgic_put_irq(kvm, irq);
}
}
@@ -61,15 +99,12 @@ static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter,
iter->nr_cpus = nr_cpus;
iter->nr_spis = kvm->arch.vgic.nr_spis;
- if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
- iter->nr_lpis = vgic_copy_lpi_list(kvm, NULL, &iter->lpi_array);
- if (iter->nr_lpis < 0)
- iter->nr_lpis = 0;
- }
+ if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+ iter->nr_lpis = iter_mark_lpis(kvm);
/* Fast forward to the right position if needed */
while (pos--)
- iter_next(iter);
+ iter_next(kvm, iter);
}
static bool end_of_vgic(struct vgic_state_iter *iter)
@@ -114,7 +149,7 @@ static void *vgic_debug_next(struct seq_file *s, void *v, loff_t *pos)
struct vgic_state_iter *iter = kvm->arch.vgic.iter;
++*pos;
- iter_next(iter);
+ iter_next(kvm, iter);
if (end_of_vgic(iter))
iter = NULL;
return iter;
@@ -134,13 +169,14 @@ static void vgic_debug_stop(struct seq_file *s, void *v)
mutex_lock(&kvm->arch.config_lock);
iter = kvm->arch.vgic.iter;
- kfree(iter->lpi_array);
+ iter_unmark_lpis(kvm);
kfree(iter);
kvm->arch.vgic.iter = NULL;
mutex_unlock(&kvm->arch.config_lock);
}
-static void print_dist_state(struct seq_file *s, struct vgic_dist *dist)
+static void print_dist_state(struct seq_file *s, struct vgic_dist *dist,
+ struct vgic_state_iter *iter)
{
bool v3 = dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3;
@@ -149,7 +185,7 @@ static void print_dist_state(struct seq_file *s, struct vgic_dist *dist)
seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2");
seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis);
if (v3)
- seq_printf(s, "nr_lpis:\t%d\n", atomic_read(&dist->lpi_count));
+ seq_printf(s, "nr_lpis:\t%d\n", iter->nr_lpis);
seq_printf(s, "enabled:\t%d\n", dist->enabled);
seq_printf(s, "\n");
@@ -236,7 +272,7 @@ static int vgic_debug_show(struct seq_file *s, void *v)
unsigned long flags;
if (iter->dist_id == 0) {
- print_dist_state(s, &kvm->arch.vgic);
+ print_dist_state(s, &kvm->arch.vgic, iter);
return 0;
}
@@ -246,11 +282,13 @@ static int vgic_debug_show(struct seq_file *s, void *v)
if (iter->vcpu_id < iter->nr_cpus)
vcpu = kvm_get_vcpu(kvm, iter->vcpu_id);
+ /*
+ * Expect this to succeed, as iter_mark_lpis() takes a reference on
+ * every LPI to be visited.
+ */
irq = vgic_get_irq(kvm, vcpu, iter->intid);
- if (!irq) {
- seq_printf(s, " LPI %4d freed\n", iter->intid);
- return 0;
- }
+ if (WARN_ON_ONCE(!irq))
+ return -EINVAL;
raw_spin_lock_irqsave(&irq->irq_lock, flags);
print_irq_state(s, irq, vcpu);
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index f20941f83a07..7f68cf58b978 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -53,8 +53,6 @@ void kvm_vgic_early_init(struct kvm *kvm)
{
struct vgic_dist *dist = &kvm->arch.vgic;
- INIT_LIST_HEAD(&dist->lpi_translation_cache);
- raw_spin_lock_init(&dist->lpi_list_lock);
xa_init_flags(&dist->lpi_xa, XA_FLAGS_LOCK_IRQ);
}
@@ -182,27 +180,22 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
return 0;
}
-/**
- * kvm_vgic_vcpu_init() - Initialize static VGIC VCPU data
- * structures and register VCPU-specific KVM iodevs
- *
- * @vcpu: pointer to the VCPU being created and initialized
- *
- * Only do initialization, but do not actually enable the
- * VGIC CPU interface
- */
-int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
+static int vgic_allocate_private_irqs_locked(struct kvm_vcpu *vcpu)
{
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
- struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
- int ret = 0;
int i;
- vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
+ lockdep_assert_held(&vcpu->kvm->arch.config_lock);
- INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
- raw_spin_lock_init(&vgic_cpu->ap_list_lock);
- atomic_set(&vgic_cpu->vgic_v3.its_vpe.vlpi_count, 0);
+ if (vgic_cpu->private_irqs)
+ return 0;
+
+ vgic_cpu->private_irqs = kcalloc(VGIC_NR_PRIVATE_IRQS,
+ sizeof(struct vgic_irq),
+ GFP_KERNEL_ACCOUNT);
+
+ if (!vgic_cpu->private_irqs)
+ return -ENOMEM;
/*
* Enable and configure all SGIs to be edge-triggered and
@@ -227,9 +220,48 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
}
}
+ return 0;
+}
+
+static int vgic_allocate_private_irqs(struct kvm_vcpu *vcpu)
+{
+ int ret;
+
+ mutex_lock(&vcpu->kvm->arch.config_lock);
+ ret = vgic_allocate_private_irqs_locked(vcpu);
+ mutex_unlock(&vcpu->kvm->arch.config_lock);
+
+ return ret;
+}
+
+/**
+ * kvm_vgic_vcpu_init() - Initialize static VGIC VCPU data
+ * structures and register VCPU-specific KVM iodevs
+ *
+ * @vcpu: pointer to the VCPU being created and initialized
+ *
+ * Only do initialization, but do not actually enable the
+ * VGIC CPU interface
+ */
+int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
+{
+ struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+ struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+ int ret = 0;
+
+ vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
+
+ INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
+ raw_spin_lock_init(&vgic_cpu->ap_list_lock);
+ atomic_set(&vgic_cpu->vgic_v3.its_vpe.vlpi_count, 0);
+
if (!irqchip_in_kernel(vcpu->kvm))
return 0;
+ ret = vgic_allocate_private_irqs(vcpu);
+ if (ret)
+ return ret;
+
/*
* If we are creating a VCPU with a GICv3 we must also register the
* KVM io device for the redistributor that belongs to this VCPU.
@@ -285,10 +317,13 @@ int vgic_init(struct kvm *kvm)
/* Initialize groups on CPUs created before the VGIC type was known */
kvm_for_each_vcpu(idx, vcpu, kvm) {
- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+ ret = vgic_allocate_private_irqs_locked(vcpu);
+ if (ret)
+ goto out;
for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) {
- struct vgic_irq *irq = &vgic_cpu->private_irqs[i];
+ struct vgic_irq *irq = vgic_get_irq(kvm, vcpu, i);
+
switch (dist->vgic_model) {
case KVM_DEV_TYPE_ARM_VGIC_V3:
irq->group = 1;
@@ -300,14 +335,15 @@ int vgic_init(struct kvm *kvm)
break;
default:
ret = -EINVAL;
- goto out;
}
+
+ vgic_put_irq(kvm, irq);
+
+ if (ret)
+ goto out;
}
}
- if (vgic_has_its(kvm))
- vgic_lpi_translation_cache_init(kvm);
-
/*
* If we have GICv4.1 enabled, unconditionally request enable the
* v4 support so that we get HW-accelerated vSGIs. Otherwise, only
@@ -355,15 +391,12 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list)
- vgic_v3_free_redist_region(rdreg);
+ vgic_v3_free_redist_region(kvm, rdreg);
INIT_LIST_HEAD(&dist->rd_regions);
} else {
dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
}
- if (vgic_has_its(kvm))
- vgic_lpi_translation_cache_destroy(kvm);
-
if (vgic_supports_direct_msis(kvm))
vgic_v4_teardown(kvm);
@@ -381,6 +414,9 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
vgic_flush_pending_lpis(vcpu);
INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
+ kfree(vgic_cpu->private_irqs);
+ vgic_cpu->private_irqs = NULL;
+
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
vgic_unregister_redist_iodev(vcpu);
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index e85a495ada9c..40bb43f20bf3 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -23,6 +23,8 @@
#include "vgic.h"
#include "vgic-mmio.h"
+static struct kvm_device_ops kvm_arm_vgic_its_ops;
+
static int vgic_its_save_tables_v0(struct vgic_its *its);
static int vgic_its_restore_tables_v0(struct vgic_its *its);
static int vgic_its_commit_v0(struct vgic_its *its);
@@ -67,7 +69,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
irq->target_vcpu = vcpu;
irq->group = 1;
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
+ xa_lock_irqsave(&dist->lpi_xa, flags);
/*
* There could be a race with another vgic_add_lpi(), so we need to
@@ -82,17 +84,14 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
goto out_unlock;
}
- ret = xa_err(xa_store(&dist->lpi_xa, intid, irq, 0));
+ ret = xa_err(__xa_store(&dist->lpi_xa, intid, irq, 0));
if (ret) {
xa_release(&dist->lpi_xa, intid);
kfree(irq);
- goto out_unlock;
}
- atomic_inc(&dist->lpi_count);
-
out_unlock:
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ xa_unlock_irqrestore(&dist->lpi_xa, flags);
if (ret)
return ERR_PTR(ret);
@@ -150,14 +149,6 @@ struct its_ite {
u32 event_id;
};
-struct vgic_translation_cache_entry {
- struct list_head entry;
- phys_addr_t db;
- u32 devid;
- u32 eventid;
- struct vgic_irq *irq;
-};
-
/**
* struct vgic_its_abi - ITS abi ops and settings
* @cte_esz: collection table entry size
@@ -252,8 +243,10 @@ static struct its_ite *find_ite(struct vgic_its *its, u32 device_id,
#define GIC_LPI_OFFSET 8192
-#define VITS_TYPER_IDBITS 16
-#define VITS_TYPER_DEVBITS 16
+#define VITS_TYPER_IDBITS 16
+#define VITS_MAX_EVENTID (BIT(VITS_TYPER_IDBITS) - 1)
+#define VITS_TYPER_DEVBITS 16
+#define VITS_MAX_DEVID (BIT(VITS_TYPER_DEVBITS) - 1)
#define VITS_DTE_MAX_DEVID_OFFSET (BIT(14) - 1)
#define VITS_ITE_MAX_EVENTID_OFFSET (BIT(16) - 1)
@@ -316,53 +309,6 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
return 0;
}
-#define GIC_LPI_MAX_INTID ((1 << INTERRUPT_ID_BITS_ITS) - 1)
-
-/*
- * Create a snapshot of the current LPIs targeting @vcpu, so that we can
- * enumerate those LPIs without holding any lock.
- * Returns their number and puts the kmalloc'ed array into intid_ptr.
- */
-int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr)
-{
- struct vgic_dist *dist = &kvm->arch.vgic;
- XA_STATE(xas, &dist->lpi_xa, GIC_LPI_OFFSET);
- struct vgic_irq *irq;
- unsigned long flags;
- u32 *intids;
- int irq_count, i = 0;
-
- /*
- * There is an obvious race between allocating the array and LPIs
- * being mapped/unmapped. If we ended up here as a result of a
- * command, we're safe (locks are held, preventing another
- * command). If coming from another path (such as enabling LPIs),
- * we must be careful not to overrun the array.
- */
- irq_count = atomic_read(&dist->lpi_count);
- intids = kmalloc_array(irq_count, sizeof(intids[0]), GFP_KERNEL_ACCOUNT);
- if (!intids)
- return -ENOMEM;
-
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
- rcu_read_lock();
-
- xas_for_each(&xas, irq, GIC_LPI_MAX_INTID) {
- if (i == irq_count)
- break;
- /* We don't need to "get" the IRQ, as we hold the list lock. */
- if (vcpu && irq->target_vcpu != vcpu)
- continue;
- intids[i++] = irq->intid;
- }
-
- rcu_read_unlock();
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
-
- *intid_ptr = intids;
- return i;
-}
-
static int update_affinity(struct vgic_irq *irq, struct kvm_vcpu *vcpu)
{
int ret = 0;
@@ -446,23 +392,18 @@ static u32 max_lpis_propbaser(u64 propbaser)
static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
{
gpa_t pendbase = GICR_PENDBASER_ADDRESS(vcpu->arch.vgic_cpu.pendbaser);
+ struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+ unsigned long intid, flags;
struct vgic_irq *irq;
int last_byte_offset = -1;
int ret = 0;
- u32 *intids;
- int nr_irqs, i;
- unsigned long flags;
u8 pendmask;
- nr_irqs = vgic_copy_lpi_list(vcpu->kvm, vcpu, &intids);
- if (nr_irqs < 0)
- return nr_irqs;
-
- for (i = 0; i < nr_irqs; i++) {
+ xa_for_each(&dist->lpi_xa, intid, irq) {
int byte_offset, bit_nr;
- byte_offset = intids[i] / BITS_PER_BYTE;
- bit_nr = intids[i] % BITS_PER_BYTE;
+ byte_offset = intid / BITS_PER_BYTE;
+ bit_nr = intid % BITS_PER_BYTE;
/*
* For contiguously allocated LPIs chances are we just read
@@ -472,25 +413,23 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
ret = kvm_read_guest_lock(vcpu->kvm,
pendbase + byte_offset,
&pendmask, 1);
- if (ret) {
- kfree(intids);
+ if (ret)
return ret;
- }
+
last_byte_offset = byte_offset;
}
- irq = vgic_get_irq(vcpu->kvm, NULL, intids[i]);
+ irq = vgic_get_irq(vcpu->kvm, NULL, intid);
if (!irq)
continue;
raw_spin_lock_irqsave(&irq->irq_lock, flags);
- irq->pending_latch = pendmask & (1U << bit_nr);
+ if (irq->target_vcpu == vcpu)
+ irq->pending_latch = pendmask & (1U << bit_nr);
vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
vgic_put_irq(vcpu->kvm, irq);
}
- kfree(intids);
-
return ret;
}
@@ -566,51 +505,52 @@ static unsigned long vgic_mmio_read_its_idregs(struct kvm *kvm,
return 0;
}
-static struct vgic_irq *__vgic_its_check_cache(struct vgic_dist *dist,
- phys_addr_t db,
- u32 devid, u32 eventid)
+static struct vgic_its *__vgic_doorbell_to_its(struct kvm *kvm, gpa_t db)
{
- struct vgic_translation_cache_entry *cte;
+ struct kvm_io_device *kvm_io_dev;
+ struct vgic_io_device *iodev;
- list_for_each_entry(cte, &dist->lpi_translation_cache, entry) {
- /*
- * If we hit a NULL entry, there is nothing after this
- * point.
- */
- if (!cte->irq)
- break;
+ kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, db);
+ if (!kvm_io_dev)
+ return ERR_PTR(-EINVAL);
- if (cte->db != db || cte->devid != devid ||
- cte->eventid != eventid)
- continue;
+ if (kvm_io_dev->ops != &kvm_io_gic_ops)
+ return ERR_PTR(-EINVAL);
- /*
- * Move this entry to the head, as it is the most
- * recently used.
- */
- if (!list_is_first(&cte->entry, &dist->lpi_translation_cache))
- list_move(&cte->entry, &dist->lpi_translation_cache);
+ iodev = container_of(kvm_io_dev, struct vgic_io_device, dev);
+ if (iodev->iodev_type != IODEV_ITS)
+ return ERR_PTR(-EINVAL);
- return cte->irq;
- }
+ return iodev->its;
+}
+
+static unsigned long vgic_its_cache_key(u32 devid, u32 eventid)
+{
+ return (((unsigned long)devid) << VITS_TYPER_IDBITS) | eventid;
- return NULL;
}
static struct vgic_irq *vgic_its_check_cache(struct kvm *kvm, phys_addr_t db,
u32 devid, u32 eventid)
{
- struct vgic_dist *dist = &kvm->arch.vgic;
+ unsigned long cache_key = vgic_its_cache_key(devid, eventid);
+ struct vgic_its *its;
struct vgic_irq *irq;
- unsigned long flags;
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
+ if (devid > VITS_MAX_DEVID || eventid > VITS_MAX_EVENTID)
+ return NULL;
- irq = __vgic_its_check_cache(dist, db, devid, eventid);
+ its = __vgic_doorbell_to_its(kvm, db);
+ if (IS_ERR(its))
+ return NULL;
+
+ rcu_read_lock();
+
+ irq = xa_load(&its->translation_cache, cache_key);
if (!vgic_try_get_irq_kref(irq))
irq = NULL;
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ rcu_read_unlock();
return irq;
}
@@ -619,41 +559,13 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
u32 devid, u32 eventid,
struct vgic_irq *irq)
{
- struct vgic_dist *dist = &kvm->arch.vgic;
- struct vgic_translation_cache_entry *cte;
- unsigned long flags;
- phys_addr_t db;
+ unsigned long cache_key = vgic_its_cache_key(devid, eventid);
+ struct vgic_irq *old;
/* Do not cache a directly injected interrupt */
if (irq->hw)
return;
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
-
- if (unlikely(list_empty(&dist->lpi_translation_cache)))
- goto out;
-
- /*
- * We could have raced with another CPU caching the same
- * translation behind our back, so let's check it is not in
- * already
- */
- db = its->vgic_its_base + GITS_TRANSLATER;
- if (__vgic_its_check_cache(dist, db, devid, eventid))
- goto out;
-
- /* Always reuse the last entry (LRU policy) */
- cte = list_last_entry(&dist->lpi_translation_cache,
- typeof(*cte), entry);
-
- /*
- * Caching the translation implies having an extra reference
- * to the interrupt, so drop the potential reference on what
- * was in the cache, and increment it on the new interrupt.
- */
- if (cte->irq)
- vgic_put_irq(kvm, cte->irq);
-
/*
* The irq refcount is guaranteed to be nonzero while holding the
* its_lock, as the ITE (and the reference it holds) cannot be freed.
@@ -661,39 +573,44 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
lockdep_assert_held(&its->its_lock);
vgic_get_irq_kref(irq);
- cte->db = db;
- cte->devid = devid;
- cte->eventid = eventid;
- cte->irq = irq;
+ /*
+ * We could have raced with another CPU caching the same
+ * translation behind our back, ensure we don't leak a
+ * reference if that is the case.
+ */
+ old = xa_store(&its->translation_cache, cache_key, irq, GFP_KERNEL_ACCOUNT);
+ if (old)
+ vgic_put_irq(kvm, old);
+}
- /* Move the new translation to the head of the list */
- list_move(&cte->entry, &dist->lpi_translation_cache);
+static void vgic_its_invalidate_cache(struct vgic_its *its)
+{
+ struct kvm *kvm = its->dev->kvm;
+ struct vgic_irq *irq;
+ unsigned long idx;
-out:
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ xa_for_each(&its->translation_cache, idx, irq) {
+ xa_erase(&its->translation_cache, idx);
+ vgic_put_irq(kvm, irq);
+ }
}
-void vgic_its_invalidate_cache(struct kvm *kvm)
+void vgic_its_invalidate_all_caches(struct kvm *kvm)
{
- struct vgic_dist *dist = &kvm->arch.vgic;
- struct vgic_translation_cache_entry *cte;
- unsigned long flags;
+ struct kvm_device *dev;
+ struct vgic_its *its;
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
+ rcu_read_lock();
- list_for_each_entry(cte, &dist->lpi_translation_cache, entry) {
- /*
- * If we hit a NULL entry, there is nothing after this
- * point.
- */
- if (!cte->irq)
- break;
+ list_for_each_entry_rcu(dev, &kvm->devices, vm_node) {
+ if (dev->ops != &kvm_arm_vgic_its_ops)
+ continue;
- vgic_put_irq(kvm, cte->irq);
- cte->irq = NULL;
+ its = dev->private;
+ vgic_its_invalidate_cache(its);
}
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ rcu_read_unlock();
}
int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
@@ -725,8 +642,6 @@ int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi)
{
u64 address;
- struct kvm_io_device *kvm_io_dev;
- struct vgic_io_device *iodev;
if (!vgic_has_its(kvm))
return ERR_PTR(-ENODEV);
@@ -736,18 +651,7 @@ struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi)
address = (u64)msi->address_hi << 32 | msi->address_lo;
- kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, address);
- if (!kvm_io_dev)
- return ERR_PTR(-EINVAL);
-
- if (kvm_io_dev->ops != &kvm_io_gic_ops)
- return ERR_PTR(-EINVAL);
-
- iodev = container_of(kvm_io_dev, struct vgic_io_device, dev);
- if (iodev->iodev_type != IODEV_ITS)
- return ERR_PTR(-EINVAL);
-
- return iodev->its;
+ return __vgic_doorbell_to_its(kvm, address);
}
/*
@@ -883,7 +787,7 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
* don't bother here since we clear the ITTE anyway and the
* pending state is a property of the ITTE struct.
*/
- vgic_its_invalidate_cache(kvm);
+ vgic_its_invalidate_cache(its);
its_free_ite(kvm, ite);
return 0;
@@ -920,7 +824,7 @@ static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its,
ite->collection = collection;
vcpu = collection_to_vcpu(kvm, collection);
- vgic_its_invalidate_cache(kvm);
+ vgic_its_invalidate_cache(its);
return update_affinity(ite->irq, vcpu);
}
@@ -955,7 +859,7 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id,
switch (type) {
case GITS_BASER_TYPE_DEVICE:
- if (id >= BIT_ULL(VITS_TYPER_DEVBITS))
+ if (id > VITS_MAX_DEVID)
return false;
break;
case GITS_BASER_TYPE_COLLECTION:
@@ -1167,7 +1071,8 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its,
}
/* Requires the its_lock to be held. */
-static void vgic_its_free_device(struct kvm *kvm, struct its_device *device)
+static void vgic_its_free_device(struct kvm *kvm, struct vgic_its *its,
+ struct its_device *device)
{
struct its_ite *ite, *temp;
@@ -1179,7 +1084,7 @@ static void vgic_its_free_device(struct kvm *kvm, struct its_device *device)
list_for_each_entry_safe(ite, temp, &device->itt_head, ite_list)
its_free_ite(kvm, ite);
- vgic_its_invalidate_cache(kvm);
+ vgic_its_invalidate_cache(its);
list_del(&device->dev_list);
kfree(device);
@@ -1191,7 +1096,7 @@ static void vgic_its_free_device_list(struct kvm *kvm, struct vgic_its *its)
struct its_device *cur, *temp;
list_for_each_entry_safe(cur, temp, &its->device_list, dev_list)
- vgic_its_free_device(kvm, cur);
+ vgic_its_free_device(kvm, its, cur);
}
/* its lock must be held */
@@ -1250,7 +1155,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
* by removing the mapping and re-establishing it.
*/
if (device)
- vgic_its_free_device(kvm, device);
+ vgic_its_free_device(kvm, its, device);
/*
* The spec does not say whether unmapping a not-mapped device
@@ -1281,7 +1186,7 @@ static int vgic_its_cmd_handle_mapc(struct kvm *kvm, struct vgic_its *its,
if (!valid) {
vgic_its_free_collection(its, coll_id);
- vgic_its_invalidate_cache(kvm);
+ vgic_its_invalidate_cache(its);
} else {
struct kvm_vcpu *vcpu;
@@ -1372,23 +1277,19 @@ static int vgic_its_cmd_handle_inv(struct kvm *kvm, struct vgic_its *its,
int vgic_its_invall(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
- int irq_count, i = 0;
- u32 *intids;
-
- irq_count = vgic_copy_lpi_list(kvm, vcpu, &intids);
- if (irq_count < 0)
- return irq_count;
+ struct vgic_dist *dist = &kvm->arch.vgic;
+ struct vgic_irq *irq;
+ unsigned long intid;
- for (i = 0; i < irq_count; i++) {
- struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intids[i]);
+ xa_for_each(&dist->lpi_xa, intid, irq) {
+ irq = vgic_get_irq(kvm, NULL, intid);
if (!irq)
continue;
+
update_lpi_config(kvm, irq, vcpu, false);
vgic_put_irq(kvm, irq);
}
- kfree(intids);
-
if (vcpu->arch.vgic_cpu.vgic_v3.its_vpe.its_vm)
its_invall_vpe(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe);
@@ -1431,10 +1332,10 @@ static int vgic_its_cmd_handle_invall(struct kvm *kvm, struct vgic_its *its,
static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
u64 *its_cmd)
{
+ struct vgic_dist *dist = &kvm->arch.vgic;
struct kvm_vcpu *vcpu1, *vcpu2;
struct vgic_irq *irq;
- u32 *intids;
- int irq_count, i;
+ unsigned long intid;
/* We advertise GITS_TYPER.PTA==0, making the address the vcpu ID */
vcpu1 = kvm_get_vcpu_by_id(kvm, its_cmd_get_target_addr(its_cmd));
@@ -1446,12 +1347,8 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
if (vcpu1 == vcpu2)
return 0;
- irq_count = vgic_copy_lpi_list(kvm, vcpu1, &intids);
- if (irq_count < 0)
- return irq_count;
-
- for (i = 0; i < irq_count; i++) {
- irq = vgic_get_irq(kvm, NULL, intids[i]);
+ xa_for_each(&dist->lpi_xa, intid, irq) {
+ irq = vgic_get_irq(kvm, NULL, intid);
if (!irq)
continue;
@@ -1460,9 +1357,8 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
vgic_put_irq(kvm, irq);
}
- vgic_its_invalidate_cache(kvm);
+ vgic_its_invalidate_cache(its);
- kfree(intids);
return 0;
}
@@ -1813,7 +1709,7 @@ static void vgic_mmio_write_its_ctlr(struct kvm *kvm, struct vgic_its *its,
its->enabled = !!(val & GITS_CTLR_ENABLE);
if (!its->enabled)
- vgic_its_invalidate_cache(kvm);
+ vgic_its_invalidate_cache(its);
/*
* Try to process any pending commands. This function bails out early
@@ -1914,47 +1810,6 @@ out:
return ret;
}
-/* Default is 16 cached LPIs per vcpu */
-#define LPI_DEFAULT_PCPU_CACHE_SIZE 16
-
-void vgic_lpi_translation_cache_init(struct kvm *kvm)
-{
- struct vgic_dist *dist = &kvm->arch.vgic;
- unsigned int sz;
- int i;
-
- if (!list_empty(&dist->lpi_translation_cache))
- return;
-
- sz = atomic_read(&kvm->online_vcpus) * LPI_DEFAULT_PCPU_CACHE_SIZE;
-
- for (i = 0; i < sz; i++) {
- struct vgic_translation_cache_entry *cte;
-
- /* An allocation failure is not fatal */
- cte = kzalloc(sizeof(*cte), GFP_KERNEL_ACCOUNT);
- if (WARN_ON(!cte))
- break;
-
- INIT_LIST_HEAD(&cte->entry);
- list_add(&cte->entry, &dist->lpi_translation_cache);
- }
-}
-
-void vgic_lpi_translation_cache_destroy(struct kvm *kvm)
-{
- struct vgic_dist *dist = &kvm->arch.vgic;
- struct vgic_translation_cache_entry *cte, *tmp;
-
- vgic_its_invalidate_cache(kvm);
-
- list_for_each_entry_safe(cte, tmp,
- &dist->lpi_translation_cache, entry) {
- list_del(&cte->entry);
- kfree(cte);
- }
-}
-
#define INITIAL_BASER_VALUE \
(GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWb) | \
GIC_BASER_CACHEABILITY(GITS_BASER, OUTER, SameAsInner) | \
@@ -1987,8 +1842,6 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
kfree(its);
return ret;
}
-
- vgic_lpi_translation_cache_init(dev->kvm);
}
mutex_init(&its->its_lock);
@@ -2006,6 +1859,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
INIT_LIST_HEAD(&its->device_list);
INIT_LIST_HEAD(&its->collection_list);
+ xa_init(&its->translation_cache);
dev->kvm->arch.vgic.msis_require_devid = true;
dev->kvm->arch.vgic.has_its = true;
@@ -2036,6 +1890,8 @@ static void vgic_its_destroy(struct kvm_device *kvm_dev)
vgic_its_free_device_list(kvm, its);
vgic_its_free_collection_list(kvm, its);
+ vgic_its_invalidate_cache(its);
+ xa_destroy(&its->translation_cache);
mutex_unlock(&its->its_lock);
kfree(its);
@@ -2438,7 +2294,7 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id,
ret = vgic_its_restore_itt(its, dev);
if (ret) {
- vgic_its_free_device(its->dev->kvm, dev);
+ vgic_its_free_device(its->dev->kvm, its, dev);
return ret;
}
diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index c15ee1df036a..9e50928f5d7d 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -277,7 +277,7 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu,
return;
vgic_flush_pending_lpis(vcpu);
- vgic_its_invalidate_cache(vcpu->kvm);
+ vgic_its_invalidate_all_caches(vcpu->kvm);
atomic_set_release(&vgic_cpu->ctlr, 0);
} else {
ctlr = atomic_cmpxchg_acquire(&vgic_cpu->ctlr, 0,
@@ -919,8 +919,19 @@ free:
return ret;
}
-void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg)
+void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg)
{
+ struct kvm_vcpu *vcpu;
+ unsigned long c;
+
+ lockdep_assert_held(&kvm->arch.config_lock);
+
+ /* Garbage collect the region */
+ kvm_for_each_vcpu(c, vcpu, kvm) {
+ if (vcpu->arch.vgic_cpu.rdreg == rdreg)
+ vcpu->arch.vgic_cpu.rdreg = NULL;
+ }
+
list_del(&rdreg->list);
kfree(rdreg);
}
@@ -945,7 +956,7 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count)
mutex_lock(&kvm->arch.config_lock);
rdreg = vgic_v3_rdist_region_from_index(kvm, index);
- vgic_v3_free_redist_region(rdreg);
+ vgic_v3_free_redist_region(kvm, rdreg);
mutex_unlock(&kvm->arch.config_lock);
return ret;
}
diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
index 7e9cdb78f7ce..ae5a44d5702d 100644
--- a/arch/arm64/kvm/vgic/vgic-v2.c
+++ b/arch/arm64/kvm/vgic/vgic-v2.c
@@ -464,17 +464,10 @@ void vgic_v2_load(struct kvm_vcpu *vcpu)
kvm_vgic_global_state.vctrl_base + GICH_APR);
}
-void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu)
-{
- struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
-
- cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR);
-}
-
void vgic_v2_put(struct kvm_vcpu *vcpu)
{
struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
- vgic_v2_vmcr_sync(vcpu);
+ cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR);
cpu_if->vgic_apr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_APR);
}
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 4ea3340786b9..ed6e412cd74b 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -722,15 +722,7 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
{
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
- /*
- * If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
- * is dependent on ICC_SRE_EL1.SRE, and we have to perform the
- * VMCR_EL2 save/restore in the world switch.
- */
- if (likely(cpu_if->vgic_sre))
- kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
-
- kvm_call_hyp(__vgic_v3_restore_aprs, cpu_if);
+ kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
if (has_vhe())
__vgic_v3_activate_traps(cpu_if);
@@ -738,24 +730,13 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
WARN_ON(vgic_v4_load(vcpu));
}
-void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu)
-{
- struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
-
- if (likely(cpu_if->vgic_sre))
- cpu_if->vgic_vmcr = kvm_call_hyp_ret(__vgic_v3_read_vmcr);
-}
-
void vgic_v3_put(struct kvm_vcpu *vcpu)
{
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+ kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
WARN_ON(vgic_v4_put(vcpu));
- vgic_v3_vmcr_sync(vcpu);
-
- kvm_call_hyp(__vgic_v3_save_aprs, cpu_if);
-
if (has_vhe())
__vgic_v3_deactivate_traps(cpu_if);
}
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 4ec93587c8cd..f07b3ddff7d4 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -29,9 +29,8 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
* its->cmd_lock (mutex)
* its->its_lock (mutex)
* vgic_cpu->ap_list_lock must be taken with IRQs disabled
- * kvm->lpi_list_lock must be taken with IRQs disabled
- * vgic_dist->lpi_xa.xa_lock must be taken with IRQs disabled
- * vgic_irq->irq_lock must be taken with IRQs disabled
+ * vgic_dist->lpi_xa.xa_lock must be taken with IRQs disabled
+ * vgic_irq->irq_lock must be taken with IRQs disabled
*
* As the ap_list_lock might be taken from the timer interrupt handler,
* we have to disable IRQs before taking this lock and everything lower
@@ -126,7 +125,6 @@ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
__xa_erase(&dist->lpi_xa, irq->intid);
xa_unlock_irqrestore(&dist->lpi_xa, flags);
- atomic_dec(&dist->lpi_count);
kfree_rcu(irq, rcu);
}
@@ -939,17 +937,6 @@ void kvm_vgic_put(struct kvm_vcpu *vcpu)
vgic_v3_put(vcpu);
}
-void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu)
-{
- if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
- return;
-
- if (kvm_vgic_global_state.type == VGIC_V2)
- vgic_v2_vmcr_sync(vcpu);
- else
- vgic_v3_vmcr_sync(vcpu);
-}
-
int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
{
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 0c2b82de8fa3..03d356a12377 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -16,6 +16,7 @@
#define INTERRUPT_ID_BITS_SPIS 10
#define INTERRUPT_ID_BITS_ITS 16
+#define VGIC_LPI_MAX_INTID ((1 << INTERRUPT_ID_BITS_ITS) - 1)
#define VGIC_PRI_BITS 5
#define vgic_irq_is_sgi(intid) ((intid) < VGIC_NR_SGIS)
@@ -214,7 +215,6 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address,
void vgic_v2_init_lrs(void);
void vgic_v2_load(struct kvm_vcpu *vcpu);
void vgic_v2_put(struct kvm_vcpu *vcpu);
-void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu);
void vgic_v2_save_state(struct kvm_vcpu *vcpu);
void vgic_v2_restore_state(struct kvm_vcpu *vcpu);
@@ -253,7 +253,6 @@ bool vgic_v3_check_base(struct kvm *kvm);
void vgic_v3_load(struct kvm_vcpu *vcpu);
void vgic_v3_put(struct kvm_vcpu *vcpu);
-void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu);
bool vgic_has_its(struct kvm *kvm);
int kvm_vgic_register_its_device(void);
@@ -317,7 +316,7 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg)
struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm,
u32 index);
-void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg);
+void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg);
bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size);
@@ -330,14 +329,11 @@ static inline bool vgic_dist_overlap(struct kvm *kvm, gpa_t base, size_t size)
}
bool vgic_lpis_enabled(struct kvm_vcpu *vcpu);
-int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr);
int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
u32 devid, u32 eventid, struct vgic_irq **irq);
struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi);
int vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi);
-void vgic_lpi_translation_cache_init(struct kvm *kvm);
-void vgic_lpi_translation_cache_destroy(struct kvm *kvm);
-void vgic_its_invalidate_cache(struct kvm *kvm);
+void vgic_its_invalidate_all_caches(struct kvm *kvm);
/* GICv4.1 MMIO interface */
int vgic_its_inv_lpi(struct kvm *kvm, struct vgic_irq *irq);
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 29490be2546b..13e6a2829116 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -7,10 +7,8 @@ lib-y := clear_user.o delay.o copy_from_user.o \
ifeq ($(CONFIG_KERNEL_MODE_NEON), y)
obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o
-CFLAGS_REMOVE_xor-neon.o += -mgeneral-regs-only
-CFLAGS_xor-neon.o += -ffreestanding
-# Enable <arm_neon.h>
-CFLAGS_xor-neon.o += -isystem $(shell $(CC) -print-file-name=include)
+CFLAGS_xor-neon.o += $(CC_FLAGS_FPU)
+CFLAGS_REMOVE_xor-neon.o += $(CC_FLAGS_NO_FPU)
endif
lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index a635ab83fee3..b008a9b46a7f 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -1515,3 +1515,14 @@ u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
return insn;
}
+
+u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
+ enum aarch64_insn_system_register sysreg)
+{
+ u32 insn = aarch64_insn_get_mrs_value();
+
+ insn &= ~GENMASK(19, 0);
+ insn |= sysreg << 5;
+ return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT,
+ insn, result);
+}
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 1b64b4c3f8bf..a3edced29ac1 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -361,6 +361,35 @@ void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
}
EXPORT_SYMBOL_GPL(contpte_wrprotect_ptes);
+void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, cydp_t flags)
+{
+ /*
+ * We can safely clear access/dirty without needing to unfold from
+ * the architectures perspective, even when contpte is set. If the
+ * range starts or ends midway through a contpte block, we can just
+ * expand to include the full contpte block. While this is not
+ * exactly what the core-mm asked for, it tracks access/dirty per
+ * folio, not per page. And since we only create a contpte block
+ * when it is covered by a single folio, we can get away with
+ * clearing access/dirty for the whole block.
+ */
+ unsigned long start = addr;
+ unsigned long end = start + nr * PAGE_SIZE;
+
+ if (pte_cont(__ptep_get(ptep + nr - 1)))
+ end = ALIGN(end, CONT_PTE_SIZE);
+
+ if (pte_cont(__ptep_get(ptep))) {
+ start = ALIGN_DOWN(start, CONT_PTE_SIZE);
+ ptep = contpte_align_down(ptep);
+ }
+
+ __clear_young_dirty_ptes(vma, start, ptep, (end - start) / PAGE_SIZE, flags);
+}
+EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes);
+
int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t entry, int dirty)
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 61886e43e3a1..b2b5792b2caa 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -7,7 +7,6 @@
#include <linux/gfp.h>
#include <linux/cache.h>
#include <linux/dma-map-ops.h>
-#include <linux/iommu.h>
#include <xen/xen.h>
#include <asm/cacheflush.h>
@@ -39,15 +38,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
dcache_clean_poc(start, start + size);
}
-#ifdef CONFIG_IOMMU_DMA
-void arch_teardown_dma_ops(struct device *dev)
-{
- dev->dma_ops = NULL;
-}
-#endif
-
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
{
int cls = cache_line_size_of_cpu();
@@ -58,8 +49,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
ARCH_DMA_MINALIGN, cls);
dev->dma_coherent = coherent;
- if (device_iommu_mapped(dev))
- iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
xen_setup_dma_ops(dev);
}
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 8251e2fea9c7..451ba7cbd5ad 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -486,25 +486,6 @@ static void do_bad_area(unsigned long far, unsigned long esr,
}
}
-#define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000)
-#define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000)
-
-static vm_fault_t __do_page_fault(struct mm_struct *mm,
- struct vm_area_struct *vma, unsigned long addr,
- unsigned int mm_flags, unsigned long vm_flags,
- struct pt_regs *regs)
-{
- /*
- * Ok, we have a good vm_area for this memory access, so we can handle
- * it.
- * Check that the permissions on the VMA allow for the fault which
- * occurred.
- */
- if (!(vma->vm_flags & vm_flags))
- return VM_FAULT_BADACCESS;
- return handle_mm_fault(vma, addr, mm_flags, regs);
-}
-
static bool is_el0_instruction_abort(unsigned long esr)
{
return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW;
@@ -529,6 +510,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
unsigned int mm_flags = FAULT_FLAG_DEFAULT;
unsigned long addr = untagged_addr(far);
struct vm_area_struct *vma;
+ int si_code;
if (kprobe_page_fault(regs, esr))
return 0;
@@ -588,7 +570,10 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
if (!(vma->vm_flags & vm_flags)) {
vma_end_read(vma);
- goto lock_mmap;
+ fault = 0;
+ si_code = SEGV_ACCERR;
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ goto bad_area;
}
fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs);
if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
@@ -613,12 +598,19 @@ lock_mmap:
retry:
vma = lock_mm_and_find_vma(mm, addr, regs);
if (unlikely(!vma)) {
- fault = VM_FAULT_BADMAP;
- goto done;
+ fault = 0;
+ si_code = SEGV_MAPERR;
+ goto bad_area;
}
- fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, regs);
+ if (!(vma->vm_flags & vm_flags)) {
+ mmap_read_unlock(mm);
+ fault = 0;
+ si_code = SEGV_ACCERR;
+ goto bad_area;
+ }
+ fault = handle_mm_fault(vma, addr, mm_flags, regs);
/* Quick path to respond to signals */
if (fault_signal_pending(fault, regs)) {
if (!user_mode(regs))
@@ -637,13 +629,12 @@ retry:
mmap_read_unlock(mm);
done:
- /*
- * Handle the "normal" (no error) case first.
- */
- if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP |
- VM_FAULT_BADACCESS))))
+ /* Handle the "normal" (no error) case first. */
+ if (likely(!(fault & VM_FAULT_ERROR)))
return 0;
+ si_code = SEGV_MAPERR;
+bad_area:
/*
* If we are in kernel mode at this point, we have no context to
* handle this fault with.
@@ -678,13 +669,8 @@ done:
arm64_force_sig_mceerr(BUS_MCEERR_AR, far, lsb, inf->name);
} else {
- /*
- * Something tried to access memory that isn't in our memory
- * map.
- */
- arm64_force_sig_fault(SIGSEGV,
- fault == VM_FAULT_BADACCESS ? SEGV_ACCERR : SEGV_MAPERR,
- far, inf->name);
+ /* Something tried to access memory that out of memory map */
+ arm64_force_sig_fault(SIGSEGV, si_code, far, inf->name);
}
return 0;
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index b872b003a55f..5f1e2103888b 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -79,20 +79,6 @@ bool arch_hugetlb_migration_supported(struct hstate *h)
}
#endif
-int pmd_huge(pmd_t pmd)
-{
- return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
-}
-
-int pud_huge(pud_t pud)
-{
-#ifndef __PAGETABLE_PMD_FOLDED
- return pud_val(pud) && !(pud_val(pud) & PUD_TABLE_BIT);
-#else
- return 0;
-#endif
-}
-
static int find_num_contig(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, size_t *pgsize)
{
@@ -141,7 +127,7 @@ static inline int num_contig_ptes(unsigned long size, size_t *pgsize)
return contig_ptes;
}
-pte_t huge_ptep_get(pte_t *ptep)
+pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
int ncontig, i;
size_t pgsize;
@@ -328,7 +314,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
if (sz != PUD_SIZE && pud_none(pud))
return NULL;
/* hugepage or swap? */
- if (pud_huge(pud) || !pud_present(pud))
+ if (pud_leaf(pud) || !pud_present(pud))
return (pte_t *)pudp;
/* table; check the next level */
@@ -340,7 +326,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) &&
pmd_none(pmd))
return NULL;
- if (pmd_huge(pmd) || !pmd_present(pmd))
+ if (pmd_leaf(pmd) || !pmd_present(pmd))
return (pte_t *)pmdp;
if (sz == CONT_PTE_SIZE)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 03efd86dce0a..9b5ab6818f7f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -32,6 +32,7 @@
#include <linux/hugetlb.h>
#include <linux/acpi_iort.h>
#include <linux/kmemleak.h>
+#include <linux/execmem.h>
#include <asm/boot.h>
#include <asm/fixmap.h>
@@ -432,3 +433,142 @@ void dump_mem_limit(void)
pr_emerg("Memory Limit: none\n");
}
}
+
+#ifdef CONFIG_EXECMEM
+static u64 module_direct_base __ro_after_init = 0;
+static u64 module_plt_base __ro_after_init = 0;
+
+/*
+ * Choose a random page-aligned base address for a window of 'size' bytes which
+ * entirely contains the interval [start, end - 1].
+ */
+static u64 __init random_bounding_box(u64 size, u64 start, u64 end)
+{
+ u64 max_pgoff, pgoff;
+
+ if ((end - start) >= size)
+ return 0;
+
+ max_pgoff = (size - (end - start)) / PAGE_SIZE;
+ pgoff = get_random_u32_inclusive(0, max_pgoff);
+
+ return start - pgoff * PAGE_SIZE;
+}
+
+/*
+ * Modules may directly reference data and text anywhere within the kernel
+ * image and other modules. References using PREL32 relocations have a +/-2G
+ * range, and so we need to ensure that the entire kernel image and all modules
+ * fall within a 2G window such that these are always within range.
+ *
+ * Modules may directly branch to functions and code within the kernel text,
+ * and to functions and code within other modules. These branches will use
+ * CALL26/JUMP26 relocations with a +/-128M range. Without PLTs, we must ensure
+ * that the entire kernel text and all module text falls within a 128M window
+ * such that these are always within range. With PLTs, we can expand this to a
+ * 2G window.
+ *
+ * We chose the 128M region to surround the entire kernel image (rather than
+ * just the text) as using the same bounds for the 128M and 2G regions ensures
+ * by construction that we never select a 128M region that is not a subset of
+ * the 2G region. For very large and unusual kernel configurations this means
+ * we may fall back to PLTs where they could have been avoided, but this keeps
+ * the logic significantly simpler.
+ */
+static int __init module_init_limits(void)
+{
+ u64 kernel_end = (u64)_end;
+ u64 kernel_start = (u64)_text;
+ u64 kernel_size = kernel_end - kernel_start;
+
+ /*
+ * The default modules region is placed immediately below the kernel
+ * image, and is large enough to use the full 2G relocation range.
+ */
+ BUILD_BUG_ON(KIMAGE_VADDR != MODULES_END);
+ BUILD_BUG_ON(MODULES_VSIZE < SZ_2G);
+
+ if (!kaslr_enabled()) {
+ if (kernel_size < SZ_128M)
+ module_direct_base = kernel_end - SZ_128M;
+ if (kernel_size < SZ_2G)
+ module_plt_base = kernel_end - SZ_2G;
+ } else {
+ u64 min = kernel_start;
+ u64 max = kernel_end;
+
+ if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
+ pr_info("2G module region forced by RANDOMIZE_MODULE_REGION_FULL\n");
+ } else {
+ module_direct_base = random_bounding_box(SZ_128M, min, max);
+ if (module_direct_base) {
+ min = module_direct_base;
+ max = module_direct_base + SZ_128M;
+ }
+ }
+
+ module_plt_base = random_bounding_box(SZ_2G, min, max);
+ }
+
+ pr_info("%llu pages in range for non-PLT usage",
+ module_direct_base ? (SZ_128M - kernel_size) / PAGE_SIZE : 0);
+ pr_info("%llu pages in range for PLT usage",
+ module_plt_base ? (SZ_2G - kernel_size) / PAGE_SIZE : 0);
+
+ return 0;
+}
+
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ unsigned long fallback_start = 0, fallback_end = 0;
+ unsigned long start = 0, end = 0;
+
+ module_init_limits();
+
+ /*
+ * Where possible, prefer to allocate within direct branch range of the
+ * kernel such that no PLTs are necessary.
+ */
+ if (module_direct_base) {
+ start = module_direct_base;
+ end = module_direct_base + SZ_128M;
+
+ if (module_plt_base) {
+ fallback_start = module_plt_base;
+ fallback_end = module_plt_base + SZ_2G;
+ }
+ } else if (module_plt_base) {
+ start = module_plt_base;
+ end = module_plt_base + SZ_2G;
+ }
+
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = start,
+ .end = end,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ .fallback_start = fallback_start,
+ .fallback_end = fallback_end,
+ },
+ [EXECMEM_KPROBES] = {
+ .start = VMALLOC_START,
+ .end = VMALLOC_END,
+ .pgprot = PAGE_KERNEL_ROX,
+ .alignment = 1,
+ },
+ [EXECMEM_BPF] = {
+ .start = VMALLOC_START,
+ .end = VMALLOC_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 495b732d5af3..353ea5dc32b8 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -109,28 +109,12 @@ EXPORT_SYMBOL(phys_mem_access_prot);
static phys_addr_t __init early_pgtable_alloc(int shift)
{
phys_addr_t phys;
- void *ptr;
phys = memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, 0,
MEMBLOCK_ALLOC_NOLEAKTRACE);
if (!phys)
panic("Failed to allocate page table page\n");
- /*
- * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE
- * slot will be free, so we can (ab)use the FIX_PTE slot to initialise
- * any level of table.
- */
- ptr = pte_set_fixmap(phys);
-
- memset(ptr, 0, PAGE_SIZE);
-
- /*
- * Implicit barriers also ensure the zeroed page is visible to the page
- * table walker
- */
- pte_clear_fixmap();
-
return phys;
}
@@ -140,7 +124,8 @@ 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.
*/
- pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG;
+ pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG |
+ PTE_SWBITS_MASK;
/* creating or taking down mappings is always safe */
if (!pte_valid(__pte(old)) || !pte_valid(__pte(new)))
@@ -172,16 +157,25 @@ bool pgattr_change_is_safe(u64 old, u64 new)
return ((old ^ new) & ~mask) == 0;
}
-static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
- phys_addr_t phys, pgprot_t prot)
+static void init_clear_pgtable(void *table)
{
- pte_t *ptep;
+ clear_page(table);
- ptep = pte_set_fixmap_offset(pmdp, addr);
+ /* Ensure the zeroing is observed by page table walks. */
+ dsb(ishst);
+}
+
+static void init_pte(pte_t *ptep, unsigned long addr, unsigned long end,
+ phys_addr_t phys, pgprot_t prot)
+{
do {
pte_t old_pte = __ptep_get(ptep);
- __set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
+ /*
+ * Required barriers to make this visible to the table walker
+ * are deferred to the end of alloc_init_cont_pte().
+ */
+ __set_pte_nosync(ptep, pfn_pte(__phys_to_pfn(phys), prot));
/*
* After the PTE entry has been populated once, we
@@ -192,8 +186,6 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
phys += PAGE_SIZE;
} while (ptep++, addr += PAGE_SIZE, addr != end);
-
- pte_clear_fixmap();
}
static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
@@ -204,6 +196,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
{
unsigned long next;
pmd_t pmd = READ_ONCE(*pmdp);
+ pte_t *ptep;
BUG_ON(pmd_sect(pmd));
if (pmd_none(pmd)) {
@@ -214,10 +207,14 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
pmdval |= PMD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
pte_phys = pgtable_alloc(PAGE_SHIFT);
+ ptep = pte_set_fixmap(pte_phys);
+ init_clear_pgtable(ptep);
+ ptep += pte_index(addr);
__pmd_populate(pmdp, pte_phys, pmdval);
- pmd = READ_ONCE(*pmdp);
+ } else {
+ BUG_ON(pmd_bad(pmd));
+ ptep = pte_set_fixmap_offset(pmdp, addr);
}
- BUG_ON(pmd_bad(pmd));
do {
pgprot_t __prot = prot;
@@ -229,20 +226,26 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
(flags & NO_CONT_MAPPINGS) == 0)
__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
- init_pte(pmdp, addr, next, phys, __prot);
+ init_pte(ptep, addr, next, phys, __prot);
+ ptep += pte_index(next) - pte_index(addr);
phys += next - addr;
} while (addr = next, addr != end);
+
+ /*
+ * Note: barriers and maintenance necessary to clear the fixmap slot
+ * ensure that all previous pgtable writes are visible to the table
+ * walker.
+ */
+ pte_clear_fixmap();
}
-static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
+static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
- pmd_t *pmdp;
- pmdp = pmd_set_fixmap_offset(pudp, addr);
do {
pmd_t old_pmd = READ_ONCE(*pmdp);
@@ -268,8 +271,6 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
}
phys += next - addr;
} while (pmdp++, addr = next, addr != end);
-
- pmd_clear_fixmap();
}
static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
@@ -279,6 +280,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
{
unsigned long next;
pud_t pud = READ_ONCE(*pudp);
+ pmd_t *pmdp;
/*
* Check for initial section mappings in the pgd/pud.
@@ -292,10 +294,14 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
pudval |= PUD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
pmd_phys = pgtable_alloc(PMD_SHIFT);
+ pmdp = pmd_set_fixmap(pmd_phys);
+ init_clear_pgtable(pmdp);
+ pmdp += pmd_index(addr);
__pud_populate(pudp, pmd_phys, pudval);
- pud = READ_ONCE(*pudp);
+ } else {
+ BUG_ON(pud_bad(pud));
+ pmdp = pmd_set_fixmap_offset(pudp, addr);
}
- BUG_ON(pud_bad(pud));
do {
pgprot_t __prot = prot;
@@ -307,10 +313,13 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
(flags & NO_CONT_MAPPINGS) == 0)
__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
- init_pmd(pudp, addr, next, phys, __prot, pgtable_alloc, flags);
+ init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, flags);
+ pmdp += pmd_index(next) - pmd_index(addr);
phys += next - addr;
} while (addr = next, addr != end);
+
+ pmd_clear_fixmap();
}
static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
@@ -330,12 +339,15 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
p4dval |= P4D_TABLE_PXN;
BUG_ON(!pgtable_alloc);
pud_phys = pgtable_alloc(PUD_SHIFT);
+ pudp = pud_set_fixmap(pud_phys);
+ init_clear_pgtable(pudp);
+ pudp += pud_index(addr);
__p4d_populate(p4dp, pud_phys, p4dval);
- p4d = READ_ONCE(*p4dp);
+ } else {
+ BUG_ON(p4d_bad(p4d));
+ pudp = pud_set_fixmap_offset(p4dp, addr);
}
- BUG_ON(p4d_bad(p4d));
- pudp = pud_set_fixmap_offset(p4dp, addr);
do {
pud_t old_pud = READ_ONCE(*pudp);
@@ -385,12 +397,15 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
pgdval |= PGD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
p4d_phys = pgtable_alloc(P4D_SHIFT);
+ p4dp = p4d_set_fixmap(p4d_phys);
+ init_clear_pgtable(p4dp);
+ p4dp += p4d_index(addr);
__pgd_populate(pgdp, p4d_phys, pgdval);
- pgd = READ_ONCE(*pgdp);
+ } else {
+ BUG_ON(pgd_bad(pgd));
+ p4dp = p4d_set_fixmap_offset(pgdp, addr);
}
- BUG_ON(pgd_bad(pgd));
- p4dp = p4d_set_fixmap_offset(pgdp, addr);
do {
p4d_t old_p4d = READ_ONCE(*p4dp);
@@ -457,11 +472,10 @@ void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
static phys_addr_t __pgd_pgtable_alloc(int shift)
{
- void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL);
- BUG_ON(!ptr);
+ /* Page is zeroed by init_clear_pgtable() so don't duplicate effort. */
+ void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL & ~__GFP_ZERO);
- /* Ensure the zeroed page is visible to the page table walker */
- dsb(ishst);
+ BUG_ON(!ptr);
return __pa(ptr);
}
diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
index a31833e3ddc5..63e8d72f202a 100644
--- a/arch/arm64/mm/mteswap.c
+++ b/arch/arm64/mm/mteswap.c
@@ -68,6 +68,13 @@ void mte_invalidate_tags(int type, pgoff_t offset)
mte_free_tag_storage(tags);
}
+static inline void __mte_invalidate_tags(struct page *page)
+{
+ swp_entry_t entry = page_swap_entry(page);
+
+ mte_invalidate_tags(swp_type(entry), swp_offset(entry));
+}
+
void mte_invalidate_tags_area(int type)
{
swp_entry_t entry = swp_entry(type, 0);
@@ -83,3 +90,41 @@ void mte_invalidate_tags_area(int type)
}
xa_unlock(&mte_pages);
}
+
+int arch_prepare_to_swap(struct folio *folio)
+{
+ long i, nr;
+ int err;
+
+ if (!system_supports_mte())
+ return 0;
+
+ nr = folio_nr_pages(folio);
+
+ for (i = 0; i < nr; i++) {
+ err = mte_save_tags(folio_page(folio, i));
+ if (err)
+ goto out;
+ }
+ return 0;
+
+out:
+ while (i--)
+ __mte_invalidate_tags(folio_page(folio, i));
+ return err;
+}
+
+void arch_swap_restore(swp_entry_t entry, struct folio *folio)
+{
+ long i, nr;
+
+ if (!system_supports_mte())
+ return;
+
+ nr = folio_nr_pages(folio);
+
+ for (i = 0; i < nr; i++) {
+ mte_restore_tags(entry, folio_page(folio, i));
+ entry.val++;
+ }
+}
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 9d40f3ffd8d2..f4bc6c5bac06 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -135,14 +135,6 @@ SYM_FUNC_START(cpu_do_resume)
msr tcr_el1, x8
msr vbar_el1, x9
-
- /*
- * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking
- * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug
- * exception. Mask them until local_daif_restore() in cpu_suspend()
- * resets them.
- */
- disable_daif
msr mdscr_el1, x10
msr sctlr_el1, x12
@@ -466,8 +458,6 @@ SYM_FUNC_START(__cpu_setup)
msr cpacr_el1, xzr // Reset cpacr_el1
mov x1, #1 << 12 // Reset mdscr_el1 and disable
msr mdscr_el1, x1 // access to the DCC from EL0
- isb // Unmask debug exceptions now,
- enable_dbg // since this is per-cpu
reset_pmuserenr_el0 x1 // Disable PMU access from EL0
reset_amuserenr_el0 x1 // Disable AMU access from EL0
diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
index 23b1b34db088..b22ab2f97a30 100644
--- a/arch/arm64/net/bpf_jit.h
+++ b/arch/arm64/net/bpf_jit.h
@@ -297,4 +297,12 @@
#define A64_ADR(Rd, offset) \
aarch64_insn_gen_adr(0, offset, Rd, AARCH64_INSN_ADR_TYPE_ADR)
+/* MRS */
+#define A64_MRS_TPIDR_EL1(Rt) \
+ aarch64_insn_gen_mrs(Rt, AARCH64_INSN_SYSREG_TPIDR_EL1)
+#define A64_MRS_TPIDR_EL2(Rt) \
+ aarch64_insn_gen_mrs(Rt, AARCH64_INSN_SYSREG_TPIDR_EL2)
+#define A64_MRS_SP_EL0(Rt) \
+ aarch64_insn_gen_mrs(Rt, AARCH64_INSN_SYSREG_SP_EL0)
+
#endif /* _BPF_JIT_H */
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 13eac43c632d..dd0bb069df4b 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -29,6 +29,7 @@
#define TCALL_CNT (MAX_BPF_JIT_REG + 2)
#define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
#define FP_BOTTOM (MAX_BPF_JIT_REG + 4)
+#define ARENA_VM_START (MAX_BPF_JIT_REG + 5)
#define check_imm(bits, imm) do { \
if ((((imm) > 0) && ((imm) >> (bits))) || \
@@ -67,6 +68,8 @@ static const int bpf2a64[] = {
/* temporary register for blinding constants */
[BPF_REG_AX] = A64_R(9),
[FP_BOTTOM] = A64_R(27),
+ /* callee saved register for kern_vm_start address */
+ [ARENA_VM_START] = A64_R(28),
};
struct jit_ctx {
@@ -79,6 +82,7 @@ struct jit_ctx {
__le32 *ro_image;
u32 stack_size;
int fpb_offset;
+ u64 user_vm_start;
};
struct bpf_plt {
@@ -295,7 +299,7 @@ static bool is_lsi_offset(int offset, int scale)
#define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8)
static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf,
- bool is_exception_cb)
+ bool is_exception_cb, u64 arena_vm_start)
{
const struct bpf_prog *prog = ctx->prog;
const bool is_main_prog = !bpf_is_subprog(prog);
@@ -306,6 +310,7 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf,
const u8 fp = bpf2a64[BPF_REG_FP];
const u8 tcc = bpf2a64[TCALL_CNT];
const u8 fpb = bpf2a64[FP_BOTTOM];
+ const u8 arena_vm_base = bpf2a64[ARENA_VM_START];
const int idx0 = ctx->idx;
int cur_offset;
@@ -411,6 +416,10 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf,
/* Set up function call stack */
emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
+
+ if (arena_vm_start)
+ emit_a64_mov_i64(arena_vm_base, arena_vm_start, ctx);
+
return 0;
}
@@ -485,20 +494,26 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
{
const u8 code = insn->code;
+ const u8 arena_vm_base = bpf2a64[ARENA_VM_START];
const u8 dst = bpf2a64[insn->dst_reg];
const u8 src = bpf2a64[insn->src_reg];
const u8 tmp = bpf2a64[TMP_REG_1];
const u8 tmp2 = bpf2a64[TMP_REG_2];
const bool isdw = BPF_SIZE(code) == BPF_DW;
+ const bool arena = BPF_MODE(code) == BPF_PROBE_ATOMIC;
const s16 off = insn->off;
- u8 reg;
+ u8 reg = dst;
- if (!off) {
- reg = dst;
- } else {
- emit_a64_mov_i(1, tmp, off, ctx);
- emit(A64_ADD(1, tmp, tmp, dst), ctx);
- reg = tmp;
+ if (off || arena) {
+ if (off) {
+ emit_a64_mov_i(1, tmp, off, ctx);
+ emit(A64_ADD(1, tmp, tmp, dst), ctx);
+ reg = tmp;
+ }
+ if (arena) {
+ emit(A64_ADD(1, tmp, reg, arena_vm_base), ctx);
+ reg = tmp;
+ }
}
switch (insn->imm) {
@@ -567,6 +582,12 @@ static int emit_ll_sc_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
u8 reg;
s32 jmp_offset;
+ if (BPF_MODE(code) == BPF_PROBE_ATOMIC) {
+ /* ll_sc based atomics don't support unsafe pointers yet. */
+ pr_err_once("unknown atomic opcode %02x\n", code);
+ return -EINVAL;
+ }
+
if (!off) {
reg = dst;
} else {
@@ -738,6 +759,7 @@ static void build_epilogue(struct jit_ctx *ctx, bool is_exception_cb)
#define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0)
#define BPF_FIXUP_REG_MASK GENMASK(31, 27)
+#define DONT_CLEAR 5 /* Unused ARM64 register from BPF's POV */
bool ex_handler_bpf(const struct exception_table_entry *ex,
struct pt_regs *regs)
@@ -745,7 +767,8 @@ bool ex_handler_bpf(const struct exception_table_entry *ex,
off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup);
int dst_reg = FIELD_GET(BPF_FIXUP_REG_MASK, ex->fixup);
- regs->regs[dst_reg] = 0;
+ if (dst_reg != DONT_CLEAR)
+ regs->regs[dst_reg] = 0;
regs->pc = (unsigned long)&ex->fixup - offset;
return true;
}
@@ -765,7 +788,9 @@ static int add_exception_handler(const struct bpf_insn *insn,
return 0;
if (BPF_MODE(insn->code) != BPF_PROBE_MEM &&
- BPF_MODE(insn->code) != BPF_PROBE_MEMSX)
+ BPF_MODE(insn->code) != BPF_PROBE_MEMSX &&
+ BPF_MODE(insn->code) != BPF_PROBE_MEM32 &&
+ BPF_MODE(insn->code) != BPF_PROBE_ATOMIC)
return 0;
if (!ctx->prog->aux->extable ||
@@ -810,6 +835,9 @@ static int add_exception_handler(const struct bpf_insn *insn,
ex->insn = ins_offset;
+ if (BPF_CLASS(insn->code) != BPF_LDX)
+ dst_reg = DONT_CLEAR;
+
ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, fixup_offset) |
FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
@@ -829,12 +857,13 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
bool extra_pass)
{
const u8 code = insn->code;
- const u8 dst = bpf2a64[insn->dst_reg];
- const u8 src = bpf2a64[insn->src_reg];
+ u8 dst = bpf2a64[insn->dst_reg];
+ u8 src = bpf2a64[insn->src_reg];
const u8 tmp = bpf2a64[TMP_REG_1];
const u8 tmp2 = bpf2a64[TMP_REG_2];
const u8 fp = bpf2a64[BPF_REG_FP];
const u8 fpb = bpf2a64[FP_BOTTOM];
+ const u8 arena_vm_base = bpf2a64[ARENA_VM_START];
const s16 off = insn->off;
const s32 imm = insn->imm;
const int i = insn - ctx->prog->insnsi;
@@ -853,6 +882,24 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
/* dst = src */
case BPF_ALU | BPF_MOV | BPF_X:
case BPF_ALU64 | BPF_MOV | BPF_X:
+ if (insn_is_cast_user(insn)) {
+ emit(A64_MOV(0, tmp, src), ctx); // 32-bit mov clears the upper 32 bits
+ emit_a64_mov_i(0, dst, ctx->user_vm_start >> 32, ctx);
+ emit(A64_LSL(1, dst, dst, 32), ctx);
+ emit(A64_CBZ(1, tmp, 2), ctx);
+ emit(A64_ORR(1, tmp, dst, tmp), ctx);
+ emit(A64_MOV(1, dst, tmp), ctx);
+ break;
+ } else if (insn_is_mov_percpu_addr(insn)) {
+ if (dst != src)
+ emit(A64_MOV(1, dst, src), ctx);
+ if (cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN))
+ emit(A64_MRS_TPIDR_EL2(tmp), ctx);
+ else
+ emit(A64_MRS_TPIDR_EL1(tmp), ctx);
+ emit(A64_ADD(1, dst, dst, tmp), ctx);
+ break;
+ }
switch (insn->off) {
case 0:
emit(A64_MOV(is64, dst, src), ctx);
@@ -1181,6 +1228,28 @@ emit_cond_jmp:
const u8 r0 = bpf2a64[BPF_REG_0];
bool func_addr_fixed;
u64 func_addr;
+ u32 cpu_offset;
+
+ /* Implement helper call to bpf_get_smp_processor_id() inline */
+ if (insn->src_reg == 0 && insn->imm == BPF_FUNC_get_smp_processor_id) {
+ cpu_offset = offsetof(struct thread_info, cpu);
+
+ emit(A64_MRS_SP_EL0(tmp), ctx);
+ if (is_lsi_offset(cpu_offset, 2)) {
+ emit(A64_LDR32I(r0, tmp, cpu_offset), ctx);
+ } else {
+ emit_a64_mov_i(1, tmp2, cpu_offset, ctx);
+ emit(A64_LDR32(r0, tmp, tmp2), ctx);
+ }
+ break;
+ }
+
+ /* Implement helper call to bpf_get_current_task/_btf() inline */
+ if (insn->src_reg == 0 && (insn->imm == BPF_FUNC_get_current_task ||
+ insn->imm == BPF_FUNC_get_current_task_btf)) {
+ emit(A64_MRS_SP_EL0(r0), ctx);
+ break;
+ }
ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
&func_addr, &func_addr_fixed);
@@ -1237,7 +1306,15 @@ emit_cond_jmp:
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
- if (ctx->fpb_offset > 0 && src == fp) {
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_B:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW:
+ if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
+ emit(A64_ADD(1, tmp2, src, arena_vm_base), ctx);
+ src = tmp2;
+ }
+ if (ctx->fpb_offset > 0 && src == fp && BPF_MODE(insn->code) != BPF_PROBE_MEM32) {
src_adj = fpb;
off_adj = off + ctx->fpb_offset;
} else {
@@ -1322,7 +1399,15 @@ emit_cond_jmp:
case BPF_ST | BPF_MEM | BPF_H:
case BPF_ST | BPF_MEM | BPF_B:
case BPF_ST | BPF_MEM | BPF_DW:
- if (ctx->fpb_offset > 0 && dst == fp) {
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_B:
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_DW:
+ if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
+ emit(A64_ADD(1, tmp2, dst, arena_vm_base), ctx);
+ dst = tmp2;
+ }
+ if (ctx->fpb_offset > 0 && dst == fp && BPF_MODE(insn->code) != BPF_PROBE_MEM32) {
dst_adj = fpb;
off_adj = off + ctx->fpb_offset;
} else {
@@ -1365,6 +1450,10 @@ emit_cond_jmp:
}
break;
}
+
+ ret = add_exception_handler(insn, ctx, dst);
+ if (ret)
+ return ret;
break;
/* STX: *(size *)(dst + off) = src */
@@ -1372,7 +1461,15 @@ emit_cond_jmp:
case BPF_STX | BPF_MEM | BPF_H:
case BPF_STX | BPF_MEM | BPF_B:
case BPF_STX | BPF_MEM | BPF_DW:
- if (ctx->fpb_offset > 0 && dst == fp) {
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_DW:
+ if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
+ emit(A64_ADD(1, tmp2, dst, arena_vm_base), ctx);
+ dst = tmp2;
+ }
+ if (ctx->fpb_offset > 0 && dst == fp && BPF_MODE(insn->code) != BPF_PROBE_MEM32) {
dst_adj = fpb;
off_adj = off + ctx->fpb_offset;
} else {
@@ -1413,16 +1510,26 @@ emit_cond_jmp:
}
break;
}
+
+ ret = add_exception_handler(insn, ctx, dst);
+ if (ret)
+ return ret;
break;
case BPF_STX | BPF_ATOMIC | BPF_W:
case BPF_STX | BPF_ATOMIC | BPF_DW:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_W:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_DW:
if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS))
ret = emit_lse_atomic(insn, ctx);
else
ret = emit_ll_sc_atomic(insn, ctx);
if (ret)
return ret;
+
+ ret = add_exception_handler(insn, ctx, dst);
+ if (ret)
+ return ret;
break;
default:
@@ -1594,6 +1701,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
bool tmp_blinded = false;
bool extra_pass = false;
struct jit_ctx ctx;
+ u64 arena_vm_start;
u8 *image_ptr;
u8 *ro_image_ptr;
@@ -1611,6 +1719,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
prog = tmp;
}
+ arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena);
jit_data = prog->aux->jit_data;
if (!jit_data) {
jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL);
@@ -1641,6 +1750,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
}
ctx.fpb_offset = find_fpb_offset(prog);
+ ctx.user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena);
/*
* 1. Initial fake pass to compute ctx->idx and ctx->offset.
@@ -1648,7 +1758,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
* BPF line info needs ctx->offset[i] to be the offset of
* instruction[i] in jited image, so build prologue first.
*/
- if (build_prologue(&ctx, was_classic, prog->aux->exception_cb)) {
+ if (build_prologue(&ctx, was_classic, prog->aux->exception_cb,
+ arena_vm_start)) {
prog = orig_prog;
goto out_off;
}
@@ -1696,7 +1807,7 @@ skip_init_ctx:
ctx.idx = 0;
ctx.exentry_idx = 0;
- build_prologue(&ctx, was_classic, prog->aux->exception_cb);
+ build_prologue(&ctx, was_classic, prog->aux->exception_cb, arena_vm_start);
if (build_body(&ctx, extra_pass)) {
prog = orig_prog;
@@ -1725,8 +1836,7 @@ skip_init_ctx:
prog->jited_len = 0;
goto out_free_hdr;
}
- if (WARN_ON(bpf_jit_binary_pack_finalize(prog, ro_header,
- header))) {
+ if (WARN_ON(bpf_jit_binary_pack_finalize(ro_header, header))) {
/* ro_header has been freed */
ro_header = NULL;
prog = orig_prog;
@@ -1793,17 +1903,6 @@ u64 bpf_jit_alloc_exec_limit(void)
return VMALLOC_END - VMALLOC_START;
}
-void *bpf_jit_alloc_exec(unsigned long size)
-{
- /* Memory is intended to be executable, reset the pointer tag. */
- return kasan_reset_tag(vmalloc(size));
-}
-
-void bpf_jit_free_exec(void *addr)
-{
- return vfree(addr);
-}
-
/* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
bool bpf_jit_supports_subprog_tailcalls(void)
{
@@ -2048,7 +2147,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx);
if (flags & BPF_TRAMP_F_CALL_ORIG) {
- emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
+ emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
emit_call((const u64)__bpf_tramp_enter, ctx);
}
@@ -2092,7 +2191,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
if (flags & BPF_TRAMP_F_CALL_ORIG) {
im->ip_epilogue = ctx->ro_image + ctx->idx;
- emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
+ emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
emit_call((const u64)__bpf_tramp_exit, ctx);
}
@@ -2176,12 +2275,9 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
bpf_prog_pack_free(image, size);
}
-void arch_protect_bpf_trampoline(void *image, unsigned int size)
-{
-}
-
-void arch_unprotect_bpf_trampoline(void *image, unsigned int size)
+int arch_protect_bpf_trampoline(void *image, unsigned int size)
{
+ return 0;
}
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image,
@@ -2464,6 +2560,41 @@ bool bpf_jit_supports_exceptions(void)
return true;
}
+bool bpf_jit_supports_arena(void)
+{
+ return true;
+}
+
+bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
+{
+ if (!in_arena)
+ return true;
+ switch (insn->code) {
+ case BPF_STX | BPF_ATOMIC | BPF_W:
+ case BPF_STX | BPF_ATOMIC | BPF_DW:
+ if (!cpus_have_cap(ARM64_HAS_LSE_ATOMICS))
+ return false;
+ }
+ return true;
+}
+
+bool bpf_jit_supports_percpu_insn(void)
+{
+ return true;
+}
+
+bool bpf_jit_inlines_helper_call(s32 imm)
+{
+ switch (imm) {
+ case BPF_FUNC_get_smp_processor_id:
+ case BPF_FUNC_get_current_task:
+ case BPF_FUNC_get_current_task_btf:
+ return true;
+ default:
+ return false;
+ }
+}
+
void bpf_jit_free(struct bpf_prog *prog)
{
if (prog->jited) {
diff --git a/arch/arm64/tools/Makefile b/arch/arm64/tools/Makefile
index fa2251d9762d..c2b34e761006 100644
--- a/arch/arm64/tools/Makefile
+++ b/arch/arm64/tools/Makefile
@@ -3,12 +3,16 @@
gen := arch/$(ARCH)/include/generated
kapi := $(gen)/asm
-kapi-hdrs-y := $(kapi)/cpucap-defs.h $(kapi)/sysreg-defs.h
+kapisyshdr-y := cpucap-defs.h sysreg-defs.h
+
+kapi-hdrs-y := $(addprefix $(kapi)/, $(kapisyshdr-y))
targets += $(addprefix ../../../, $(kapi-hdrs-y))
PHONY += kapi
+all: $(syscall64) kapi
+
kapi: $(kapi-hdrs-y)
quiet_cmd_gen_cpucaps = GEN $@
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 62b2838a231a..ac3429d892b9 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -102,4 +102,5 @@ WORKAROUND_NVIDIA_CARMEL_CNP
WORKAROUND_QCOM_FALKOR_E1003
WORKAROUND_REPEAT_TLBI
WORKAROUND_SPECULATIVE_AT
+WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD
diff --git a/arch/arm64/tools/syscall_32.tbl b/arch/arm64/tools/syscall_32.tbl
new file mode 100644
index 000000000000..9a37930d4e26
--- /dev/null
+++ b/arch/arm64/tools/syscall_32.tbl
@@ -0,0 +1,476 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# AArch32 (compat) system call definitions.
+#
+# Copyright (C) 2001-2005 Russell King
+# Copyright (C) 2012 ARM Ltd.
+#
+# This file corresponds to arch/arm/tools/syscall.tbl
+# for the native EABI syscalls and should be kept in sync
+# Instead of the OABI syscalls, it contains pointers to
+# the compat entry points where they differ from the native
+# syscalls.
+#
+0 common restart_syscall sys_restart_syscall
+1 common exit sys_exit
+2 common fork sys_fork
+3 common read sys_read
+4 common write sys_write
+5 common open sys_open compat_sys_open
+6 common close sys_close
+# 7 was sys_waitpid
+8 common creat sys_creat
+9 common link sys_link
+10 common unlink sys_unlink
+11 common execve sys_execve compat_sys_execve
+12 common chdir sys_chdir
+# 13 was sys_time
+14 common mknod sys_mknod
+15 common chmod sys_chmod
+16 common lchown sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19 common lseek sys_lseek compat_sys_lseek
+20 common getpid sys_getpid
+21 common mount sys_mount
+# 22 was sys_umount
+23 common setuid sys_setuid16
+24 common getuid sys_getuid16
+# 25 was sys_stime
+26 common ptrace sys_ptrace compat_sys_ptrace
+# 27 was sys_alarm
+# 28 was sys_fstat
+29 common pause sys_pause
+# 30 was sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33 common access sys_access
+34 common nice sys_nice
+# 35 was sys_ftime
+36 common sync sys_sync
+37 common kill sys_kill
+38 common rename sys_rename
+39 common mkdir sys_mkdir
+40 common rmdir sys_rmdir
+41 common dup sys_dup
+42 common pipe sys_pipe
+43 common times sys_times compat_sys_times
+# 44 was sys_prof
+45 common brk sys_brk
+46 common setgid sys_setgid16
+47 common getgid sys_getgid16
+# 48 was sys_signal
+49 common geteuid sys_geteuid16
+50 common getegid sys_getegid16
+51 common acct sys_acct
+52 common umount2 sys_umount
+# 53 was sys_lock
+54 common ioctl sys_ioctl compat_sys_ioctl
+55 common fcntl sys_fcntl compat_sys_fcntl
+# 56 was sys_mpx
+57 common setpgid sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60 common umask sys_umask
+61 common chroot sys_chroot
+62 common ustat sys_ustat compat_sys_ustat
+63 common dup2 sys_dup2
+64 common getppid sys_getppid
+65 common getpgrp sys_getpgrp
+66 common setsid sys_setsid
+67 common sigaction sys_sigaction compat_sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70 common setreuid sys_setreuid16
+71 common setregid sys_setregid16
+72 common sigsuspend sys_sigsuspend
+73 common sigpending sys_sigpending compat_sys_sigpending
+74 common sethostname sys_sethostname
+75 common setrlimit sys_setrlimit compat_sys_setrlimit
+# 76 was compat_sys_getrlimit
+77 common getrusage sys_getrusage compat_sys_getrusage
+78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday
+79 common settimeofday sys_settimeofday compat_sys_settimeofday
+80 common getgroups sys_getgroups16
+81 common setgroups sys_setgroups16
+# 82 was compat_sys_select
+83 common symlink sys_symlink
+# 84 was sys_lstat
+85 common readlink sys_readlink
+86 common uselib sys_uselib
+87 common swapon sys_swapon
+88 common reboot sys_reboot
+# 89 was sys_readdir
+# 90 was sys_mmap
+91 common munmap sys_munmap
+92 common truncate sys_truncate compat_sys_truncate
+93 common ftruncate sys_ftruncate compat_sys_ftruncate
+94 common fchmod sys_fchmod
+95 common fchown sys_fchown16
+96 common getpriority sys_getpriority
+97 common setpriority sys_setpriority
+# 98 was sys_profil
+99 common statfs sys_statfs compat_sys_statfs
+100 common fstatfs sys_fstatfs compat_sys_fstatfs
+# 101 was sys_ioperm
+# 102 was sys_socketcall
+103 common syslog sys_syslog
+104 common setitimer sys_setitimer compat_sys_setitimer
+105 common getitimer sys_getitimer compat_sys_getitimer
+106 common stat sys_newstat compat_sys_newstat
+107 common lstat sys_newlstat compat_sys_newlstat
+108 common fstat sys_newfstat compat_sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111 common vhangup sys_vhangup
+# 112 was sys_idle
+# 113 was sys_syscall
+114 common wait4 sys_wait4 compat_sys_wait4
+115 common swapoff sys_swapoff
+116 common sysinfo sys_sysinfo compat_sys_sysinfo
+# 117 was sys_ipc
+118 common fsync sys_fsync
+119 common sigreturn sys_sigreturn_wrapper compat_sys_sigreturn
+120 common clone sys_clone
+121 common setdomainname sys_setdomainname
+122 common uname sys_newuname
+# 123 was sys_modify_ldt
+124 common adjtimex sys_adjtimex_time32
+125 common mprotect sys_mprotect
+126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask
+# 127 was sys_create_module
+128 common init_module sys_init_module
+129 common delete_module sys_delete_module
+# 130 was sys_get_kernel_syms
+131 common quotactl sys_quotactl
+132 common getpgid sys_getpgid
+133 common fchdir sys_fchdir
+134 common bdflush sys_ni_syscall
+135 common sysfs sys_sysfs
+136 common personality sys_personality
+# 137 was sys_afs_syscall
+138 common setfsuid sys_setfsuid16
+139 common setfsgid sys_setfsgid16
+140 common _llseek sys_llseek
+141 common getdents sys_getdents compat_sys_getdents
+142 common _newselect sys_select compat_sys_select
+143 common flock sys_flock
+144 common msync sys_msync
+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
+150 common mlock sys_mlock
+151 common munlock sys_munlock
+152 common mlockall sys_mlockall
+153 common munlockall sys_munlockall
+154 common sched_setparam sys_sched_setparam
+155 common sched_getparam sys_sched_getparam
+156 common sched_setscheduler sys_sched_setscheduler
+157 common sched_getscheduler sys_sched_getscheduler
+158 common sched_yield sys_sched_yield
+159 common sched_get_priority_max sys_sched_get_priority_max
+160 common sched_get_priority_min sys_sched_get_priority_min
+161 common sched_rr_get_interval sys_sched_rr_get_interval_time32
+162 common nanosleep sys_nanosleep_time32
+163 common mremap sys_mremap
+164 common setresuid sys_setresuid16
+165 common getresuid sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168 common poll sys_poll
+169 common nfsservctl sys_ni_syscall
+170 common setresgid sys_setresgid16
+171 common getresgid sys_getresgid16
+172 common prctl sys_prctl
+173 common rt_sigreturn sys_rt_sigreturn_wrapper compat_sys_rt_sigreturn
+174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
+175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask
+176 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
+177 common rt_sigtimedwait sys_rt_sigtimedwait_time32 compat_sys_rt_sigtimedwait_time32
+178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
+179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
+180 common pread64 sys_pread64 compat_sys_aarch32_pread64
+181 common pwrite64 sys_pwrite64 compat_sys_aarch32_pwrite64
+182 common chown sys_chown16
+183 common getcwd sys_getcwd
+184 common capget sys_capget
+185 common capset sys_capset
+186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack
+187 common sendfile sys_sendfile compat_sys_sendfile
+# 188 reserved
+# 189 reserved
+190 common vfork sys_vfork
+# SuS compliant getrlimit
+191 common ugetrlimit sys_getrlimit compat_sys_getrlimit
+192 common mmap2 sys_mmap2 compat_sys_aarch32_mmap2
+193 common truncate64 sys_truncate64 compat_sys_aarch32_truncate64
+194 common ftruncate64 sys_ftruncate64 compat_sys_aarch32_ftruncate64
+195 common stat64 sys_stat64
+196 common lstat64 sys_lstat64
+197 common fstat64 sys_fstat64
+198 common lchown32 sys_lchown
+199 common getuid32 sys_getuid
+200 common getgid32 sys_getgid
+201 common geteuid32 sys_geteuid
+202 common getegid32 sys_getegid
+203 common setreuid32 sys_setreuid
+204 common setregid32 sys_setregid
+205 common getgroups32 sys_getgroups
+206 common setgroups32 sys_setgroups
+207 common fchown32 sys_fchown
+208 common setresuid32 sys_setresuid
+209 common getresuid32 sys_getresuid
+210 common setresgid32 sys_setresgid
+211 common getresgid32 sys_getresgid
+212 common chown32 sys_chown
+213 common setuid32 sys_setuid
+214 common setgid32 sys_setgid
+215 common setfsuid32 sys_setfsuid
+216 common setfsgid32 sys_setfsgid
+217 common getdents64 sys_getdents64
+218 common pivot_root sys_pivot_root
+219 common mincore sys_mincore
+220 common madvise sys_madvise
+221 common fcntl64 sys_fcntl64 compat_sys_fcntl64
+# 222 for tux
+# 223 is unused
+224 common gettid sys_gettid
+225 common readahead sys_readahead compat_sys_aarch32_readahead
+226 common setxattr sys_setxattr
+227 common lsetxattr sys_lsetxattr
+228 common fsetxattr sys_fsetxattr
+229 common getxattr sys_getxattr
+230 common lgetxattr sys_lgetxattr
+231 common fgetxattr sys_fgetxattr
+232 common listxattr sys_listxattr
+233 common llistxattr sys_llistxattr
+234 common flistxattr sys_flistxattr
+235 common removexattr sys_removexattr
+236 common lremovexattr sys_lremovexattr
+237 common fremovexattr sys_fremovexattr
+238 common tkill sys_tkill
+239 common sendfile64 sys_sendfile64
+240 common futex sys_futex_time32
+241 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity
+242 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity
+243 common io_setup sys_io_setup compat_sys_io_setup
+244 common io_destroy sys_io_destroy
+245 common io_getevents sys_io_getevents_time32
+246 common io_submit sys_io_submit compat_sys_io_submit
+247 common io_cancel sys_io_cancel
+248 common exit_group sys_exit_group
+249 common lookup_dcookie sys_ni_syscall
+250 common epoll_create sys_epoll_create
+251 common epoll_ctl sys_epoll_ctl
+252 common epoll_wait sys_epoll_wait
+253 common remap_file_pages sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256 common set_tid_address sys_set_tid_address
+257 common timer_create sys_timer_create compat_sys_timer_create
+258 common timer_settime sys_timer_settime32
+259 common timer_gettime sys_timer_gettime32
+260 common timer_getoverrun sys_timer_getoverrun
+261 common timer_delete sys_timer_delete
+262 common clock_settime sys_clock_settime32
+263 common clock_gettime sys_clock_gettime32
+264 common clock_getres sys_clock_getres_time32
+265 common clock_nanosleep sys_clock_nanosleep_time32
+266 common statfs64 sys_statfs64_wrapper compat_sys_aarch32_statfs64
+267 common fstatfs64 sys_fstatfs64_wrapper compat_sys_aarch32_fstatfs64
+268 common tgkill sys_tgkill
+269 common utimes sys_utimes_time32
+270 common arm_fadvise64_64 sys_arm_fadvise64_64 compat_sys_aarch32_fadvise64_64
+271 common pciconfig_iobase sys_pciconfig_iobase
+272 common pciconfig_read sys_pciconfig_read
+273 common pciconfig_write sys_pciconfig_write
+274 common mq_open sys_mq_open compat_sys_mq_open
+275 common mq_unlink sys_mq_unlink
+276 common mq_timedsend sys_mq_timedsend_time32
+277 common mq_timedreceive sys_mq_timedreceive_time32
+278 common mq_notify sys_mq_notify compat_sys_mq_notify
+279 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr
+280 common waitid sys_waitid compat_sys_waitid
+281 common socket sys_socket
+282 common bind sys_bind
+283 common connect sys_connect
+284 common listen sys_listen
+285 common accept sys_accept
+286 common getsockname sys_getsockname
+287 common getpeername sys_getpeername
+288 common socketpair sys_socketpair
+289 common send sys_send
+290 common sendto sys_sendto
+291 common recv sys_recv compat_sys_recv
+292 common recvfrom sys_recvfrom compat_sys_recvfrom
+293 common shutdown sys_shutdown
+294 common setsockopt sys_setsockopt
+295 common getsockopt sys_getsockopt
+296 common sendmsg sys_sendmsg compat_sys_sendmsg
+297 common recvmsg sys_recvmsg compat_sys_recvmsg
+298 common semop sys_semop
+299 common semget sys_semget
+300 common semctl sys_old_semctl compat_sys_old_semctl
+301 common msgsnd sys_msgsnd compat_sys_msgsnd
+302 common msgrcv sys_msgrcv compat_sys_msgrcv
+303 common msgget sys_msgget
+304 common msgctl sys_old_msgctl compat_sys_old_msgctl
+305 common shmat sys_shmat compat_sys_shmat
+306 common shmdt sys_shmdt
+307 common shmget sys_shmget
+308 common shmctl sys_old_shmctl compat_sys_old_shmctl
+309 common add_key sys_add_key
+310 common request_key sys_request_key
+311 common keyctl sys_keyctl compat_sys_keyctl
+312 common semtimedop sys_semtimedop_time32
+313 common vserver sys_ni_syscall
+314 common ioprio_set sys_ioprio_set
+315 common ioprio_get sys_ioprio_get
+316 common inotify_init sys_inotify_init
+317 common inotify_add_watch sys_inotify_add_watch
+318 common inotify_rm_watch sys_inotify_rm_watch
+319 common mbind sys_mbind
+320 common get_mempolicy sys_get_mempolicy
+321 common set_mempolicy sys_set_mempolicy
+322 common openat sys_openat compat_sys_openat
+323 common mkdirat sys_mkdirat
+324 common mknodat sys_mknodat
+325 common fchownat sys_fchownat
+326 common futimesat sys_futimesat_time32
+327 common fstatat64 sys_fstatat64
+328 common unlinkat sys_unlinkat
+329 common renameat sys_renameat
+330 common linkat sys_linkat
+331 common symlinkat sys_symlinkat
+332 common readlinkat sys_readlinkat
+333 common fchmodat sys_fchmodat
+334 common faccessat sys_faccessat
+335 common pselect6 sys_pselect6_time32 compat_sys_pselect6_time32
+336 common ppoll sys_ppoll_time32 compat_sys_ppoll_time32
+337 common unshare sys_unshare
+338 common set_robust_list sys_set_robust_list compat_sys_set_robust_list
+339 common get_robust_list sys_get_robust_list compat_sys_get_robust_list
+340 common splice sys_splice
+341 common arm_sync_file_range sys_sync_file_range2 compat_sys_aarch32_sync_file_range2
+342 common tee sys_tee
+343 common vmsplice sys_vmsplice
+344 common move_pages sys_move_pages
+345 common getcpu sys_getcpu
+346 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
+347 common kexec_load sys_kexec_load compat_sys_kexec_load
+348 common utimensat sys_utimensat_time32
+349 common signalfd sys_signalfd compat_sys_signalfd
+350 common timerfd_create sys_timerfd_create
+351 common eventfd sys_eventfd
+352 common fallocate sys_fallocate compat_sys_aarch32_fallocate
+353 common timerfd_settime sys_timerfd_settime32
+354 common timerfd_gettime sys_timerfd_gettime32
+355 common signalfd4 sys_signalfd4 compat_sys_signalfd4
+356 common eventfd2 sys_eventfd2
+357 common epoll_create1 sys_epoll_create1
+358 common dup3 sys_dup3
+359 common pipe2 sys_pipe2
+360 common inotify_init1 sys_inotify_init1
+361 common preadv sys_preadv compat_sys_preadv
+362 common pwritev sys_pwritev compat_sys_pwritev
+363 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
+364 common perf_event_open sys_perf_event_open
+365 common recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32
+366 common accept4 sys_accept4
+367 common fanotify_init sys_fanotify_init
+368 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark
+369 common prlimit64 sys_prlimit64
+370 common name_to_handle_at sys_name_to_handle_at
+371 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at
+372 common clock_adjtime sys_clock_adjtime32
+373 common syncfs sys_syncfs
+374 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
+375 common setns sys_setns
+376 common process_vm_readv sys_process_vm_readv
+377 common process_vm_writev sys_process_vm_writev
+378 common kcmp sys_kcmp
+379 common finit_module sys_finit_module
+380 common sched_setattr sys_sched_setattr
+381 common sched_getattr sys_sched_getattr
+382 common renameat2 sys_renameat2
+383 common seccomp sys_seccomp
+384 common getrandom sys_getrandom
+385 common memfd_create sys_memfd_create
+386 common bpf sys_bpf
+387 common execveat sys_execveat compat_sys_execveat
+388 common userfaultfd sys_userfaultfd
+389 common membarrier sys_membarrier
+390 common mlock2 sys_mlock2
+391 common copy_file_range sys_copy_file_range
+392 common preadv2 sys_preadv2 compat_sys_preadv2
+393 common pwritev2 sys_pwritev2 compat_sys_pwritev2
+394 common pkey_mprotect sys_pkey_mprotect
+395 common pkey_alloc sys_pkey_alloc
+396 common pkey_free sys_pkey_free
+397 common statx sys_statx
+398 common rseq sys_rseq
+399 common io_pgetevents sys_io_pgetevents_time32 compat_sys_io_pgetevents
+400 common migrate_pages sys_migrate_pages
+401 common kexec_file_load sys_kexec_file_load
+# 402 is unused
+403 common clock_gettime64 sys_clock_gettime
+404 common clock_settime64 sys_clock_settime
+405 common clock_adjtime64 sys_clock_adjtime
+406 common clock_getres_time64 sys_clock_getres
+407 common clock_nanosleep_time64 sys_clock_nanosleep
+408 common timer_gettime64 sys_timer_gettime
+409 common timer_settime64 sys_timer_settime
+410 common timerfd_gettime64 sys_timerfd_gettime
+411 common timerfd_settime64 sys_timerfd_settime
+412 common utimensat_time64 sys_utimensat
+413 common pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
+414 common ppoll_time64 sys_ppoll compat_sys_ppoll_time64
+416 common io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64
+417 common recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
+418 common mq_timedsend_time64 sys_mq_timedsend
+419 common mq_timedreceive_time64 sys_mq_timedreceive
+420 common semtimedop_time64 sys_semtimedop
+421 common rt_sigtimedwait_time64 sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time64
+422 common futex_time64 sys_futex
+423 common sched_rr_get_interval_time64 sys_sched_rr_get_interval
+424 common pidfd_send_signal sys_pidfd_send_signal
+425 common io_uring_setup sys_io_uring_setup
+426 common io_uring_enter sys_io_uring_enter
+427 common io_uring_register sys_io_uring_register
+428 common open_tree sys_open_tree
+429 common move_mount sys_move_mount
+430 common fsopen sys_fsopen
+431 common fsconfig sys_fsconfig
+432 common fsmount sys_fsmount
+433 common fspick sys_fspick
+434 common pidfd_open sys_pidfd_open
+435 common clone3 sys_clone3
+436 common close_range sys_close_range
+437 common openat2 sys_openat2
+438 common pidfd_getfd sys_pidfd_getfd
+439 common faccessat2 sys_faccessat2
+440 common process_madvise sys_process_madvise
+441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
+442 common mount_setattr sys_mount_setattr
+443 common quotactl_fd sys_quotactl_fd
+444 common landlock_create_ruleset sys_landlock_create_ruleset
+445 common landlock_add_rule sys_landlock_add_rule
+446 common landlock_restrict_self sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448 common process_mrelease sys_process_mrelease
+449 common futex_waitv sys_futex_waitv
+450 common set_mempolicy_home_node sys_set_mempolicy_home_node
+451 common cachestat sys_cachestat
+452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
+454 common futex_wake sys_futex_wake
+455 common futex_wait sys_futex_wait
+456 common futex_requeue sys_futex_requeue
+457 common statmount sys_statmount
+458 common listmount sys_listmount
+459 common lsm_get_self_attr sys_lsm_get_self_attr
+460 common lsm_set_self_attr sys_lsm_set_self_attr
+461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/arm64/tools/syscall_64.tbl b/arch/arm64/tools/syscall_64.tbl
new file mode 120000
index 000000000000..63135cf34b65
--- /dev/null
+++ b/arch/arm64/tools/syscall_64.tbl
@@ -0,0 +1 @@
+../../../scripts/syscall.tbl \ No newline at end of file
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a4c1dd4741a4..7ceaa1e0b4bc 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -149,7 +149,7 @@ Res0 63:32
UnsignedEnum 31:28 GIC
0b0000 NI
0b0001 GICv3
- 0b0010 GICv4p1
+ 0b0011 GICv4p1
EndEnum
UnsignedEnum 27:24 Virt_frac
0b0000 NI
@@ -903,7 +903,7 @@ EndEnum
UnsignedEnum 27:24 GIC
0b0000 NI
0b0001 IMP
- 0b0010 V4P1
+ 0b0011 V4P1
EndEnum
SignedEnum 23:20 AdvSIMD
0b0000 IMP
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index d3ac36751ad1..5479707eb5d1 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -37,6 +37,7 @@ config CSKY
select ARCH_INLINE_SPIN_UNLOCK_BH if !PREEMPTION
select ARCH_INLINE_SPIN_UNLOCK_IRQ if !PREEMPTION
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION
+ select ARCH_NEED_CMPXCHG_1_EMU
select ARCH_WANT_FRAME_POINTERS if !CPU_CK610 && $(cc-option,-mbacktrace)
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
select COMMON_CLK
diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c
index 6792aca49999..7f826331d409 100644
--- a/arch/csky/abiv1/mmap.c
+++ b/arch/csky/abiv1/mmap.c
@@ -28,7 +28,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
int do_align = 0;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {
+ .length = len,
+ .low_limit = mm->mmap_base,
+ .high_limit = TASK_SIZE,
+ .align_offset = pgoff << PAGE_SHIFT
+ };
/*
* We only need to do colour alignment if either the I or D
@@ -61,11 +66,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- info.flags = 0;
- info.length = len;
- info.low_limit = mm->mmap_base;
- info.high_limit = TASK_SIZE;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
- info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
}
diff --git a/arch/csky/boot/dts/Makefile b/arch/csky/boot/dts/Makefile
index 5f1f55e911ad..aabffc1912e8 100644
--- a/arch/csky/boot/dts/Makefile
+++ b/arch/csky/boot/dts/Makefile
@@ -1,4 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-dtstree := $(srctree)/$(src)
-
-dtb-y := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+dtb-y := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts))
diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild
index 1117c28cb7e8..9a9bc65b57a9 100644
--- a/arch/csky/include/asm/Kbuild
+++ b/arch/csky/include/asm/Kbuild
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y := syscall_table_32.h
+
generic-y += asm-offsets.h
generic-y += extable.h
-generic-y += gpio.h
generic-y += kvm_para.h
generic-y += mcs_spinlock.h
generic-y += qrwlock.h
diff --git a/arch/csky/include/asm/cmpxchg.h b/arch/csky/include/asm/cmpxchg.h
index 916043b845f1..db6dda47184e 100644
--- a/arch/csky/include/asm/cmpxchg.h
+++ b/arch/csky/include/asm/cmpxchg.h
@@ -6,6 +6,7 @@
#ifdef CONFIG_SMP
#include <linux/bug.h>
#include <asm/barrier.h>
+#include <linux/cmpxchg-emu.h>
#define __xchg_relaxed(new, ptr, size) \
({ \
@@ -61,6 +62,9 @@
__typeof__(old) __old = (old); \
__typeof__(*(ptr)) __ret; \
switch (size) { \
+ case 1: \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+ break; \
case 4: \
asm volatile ( \
"1: ldex.w %0, (%3) \n" \
@@ -91,6 +95,9 @@
__typeof__(old) __old = (old); \
__typeof__(*(ptr)) __ret; \
switch (size) { \
+ case 1: \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+ break; \
case 4: \
asm volatile ( \
"1: ldex.w %0, (%3) \n" \
@@ -122,6 +129,9 @@
__typeof__(old) __old = (old); \
__typeof__(*(ptr)) __ret; \
switch (size) { \
+ case 1: \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+ break; \
case 4: \
asm volatile ( \
RELEASE_FENCE \
diff --git a/arch/csky/include/asm/ftrace.h b/arch/csky/include/asm/ftrace.h
index fd215c38ef27..00f9f7647e3f 100644
--- a/arch/csky/include/asm/ftrace.h
+++ b/arch/csky/include/asm/ftrace.h
@@ -7,8 +7,6 @@
#define HAVE_FUNCTION_GRAPH_FP_TEST
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
-
#define ARCH_SUPPORTS_FTRACE_OPS 1
#define MCOUNT_ADDR ((unsigned long)_mcount)
diff --git a/arch/csky/include/asm/unistd.h b/arch/csky/include/asm/unistd.h
index 9cf97de9a26d..2c2c24de95d8 100644
--- a/arch/csky/include/asm/unistd.h
+++ b/arch/csky/include/asm/unistd.h
@@ -2,4 +2,7 @@
#include <uapi/asm/unistd.h>
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_CLONE
+
#define NR_syscalls (__NR_syscalls)
diff --git a/arch/csky/include/uapi/asm/Kbuild b/arch/csky/include/uapi/asm/Kbuild
index e78470141932..2501e82a1a0a 100644
--- a/arch/csky/include/uapi/asm/Kbuild
+++ b/arch/csky/include/uapi/asm/Kbuild
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
+
generic-y += ucontext.h
diff --git a/arch/csky/include/uapi/asm/unistd.h b/arch/csky/include/uapi/asm/unistd.h
index 7ff6a2466af1..44882179a6e1 100644
--- a/arch/csky/include/uapi/asm/unistd.h
+++ b/arch/csky/include/uapi/asm/unistd.h
@@ -1,14 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_NEW_STAT
-#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_TIME32_SYSCALLS
-#include <asm-generic/unistd.h>
+#include <asm/unistd_32.h>
-#define __NR_set_thread_area (__NR_arch_specific_syscall + 0)
-__SYSCALL(__NR_set_thread_area, sys_set_thread_area)
-#define __NR_cacheflush (__NR_arch_specific_syscall + 1)
-__SYSCALL(__NR_cacheflush, sys_cacheflush)
+#define __NR_sync_file_range2 84
+#undef __NR_sync_file_range
diff --git a/arch/csky/kernel/Makefile.syscalls b/arch/csky/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..3df3b5822fce
--- /dev/null
+++ b/arch/csky/kernel/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += csky time32 stat64 rlimit
+
diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c
index 834cffcfbce3..7ba4b98076de 100644
--- a/arch/csky/kernel/probes/ftrace.c
+++ b/arch/csky/kernel/probes/ftrace.c
@@ -12,6 +12,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe_ctlblk *kcb;
struct pt_regs *regs;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/csky/kernel/syscall.c b/arch/csky/kernel/syscall.c
index 3d30e58a45d2..4540a271ee39 100644
--- a/arch/csky/kernel/syscall.c
+++ b/arch/csky/kernel/syscall.c
@@ -20,7 +20,7 @@ SYSCALL_DEFINE6(mmap2,
unsigned long, prot,
unsigned long, flags,
unsigned long, fd,
- off_t, offset)
+ unsigned long, offset)
{
if (unlikely(offset & (~PAGE_MASK >> 12)))
return -EINVAL;
diff --git a/arch/csky/kernel/syscall_table.c b/arch/csky/kernel/syscall_table.c
index a0c238c5377a..a6eb91a0e2f6 100644
--- a/arch/csky/kernel/syscall_table.c
+++ b/arch/csky/kernel/syscall_table.c
@@ -6,9 +6,11 @@
#undef __SYSCALL
#define __SYSCALL(nr, call)[nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
#define sys_fadvise64_64 sys_csky_fadvise64_64
+#define sys_sync_file_range sys_sync_file_range2
void * const sys_call_table[__NR_syscalls] __page_aligned_data = {
[0 ... __NR_syscalls - 1] = sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/csky/kernel/vdso/Makefile b/arch/csky/kernel/vdso/Makefile
index ddf784a62c11..bc2261f5a8d4 100644
--- a/arch/csky/kernel/vdso/Makefile
+++ b/arch/csky/kernel/vdso/Makefile
@@ -23,15 +23,11 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
obj-y += vdso.o vdso-syms.o
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
-# Disable gcov profiling for VDSO code
-GCOV_PROFILE := n
-KCOV_INSTRUMENT := n
-
# Force dependency
$(obj)/vdso.o: $(obj)/vdso.so
SYSCFLAGS_vdso.so.dbg = $(c_flags)
-$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE
+$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,vdsold)
SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \
-Wl,--build-id=sha1 -Wl,--hash-style=both
@@ -57,4 +53,4 @@ quiet_cmd_vdsold = VDSOLD $@
# Extracts symbol offsets from the VDSO, converting them into an assembly file
# that contains the same symbols at the same offsets.
quiet_cmd_so2s = SO2S $@
- cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@
+ cmd_so2s = $(NM) -D $< | $(src)/so2s.sh > $@
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 3ece3c93fe08..8c1a78c8f527 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
+
generic-y += extable.h
generic-y += iomap.h
generic-y += kvm_para.h
diff --git a/arch/hexagon/include/asm/syscalls.h b/arch/hexagon/include/asm/syscalls.h
new file mode 100644
index 000000000000..40f2d08bec92
--- /dev/null
+++ b/arch/hexagon/include/asm/syscalls.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm-generic/syscalls.h>
+
+asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice,
+ u32 a2, u32 a3, u32 a4, u32 a5);
diff --git a/arch/hexagon/include/asm/unistd.h b/arch/hexagon/include/asm/unistd.h
new file mode 100644
index 000000000000..1f462bade75c
--- /dev/null
+++ b/arch/hexagon/include/asm/unistd.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_FORK
+
+#define __ARCH_BROKEN_SYS_CLONE3
+
+#include <uapi/asm/unistd.h>
diff --git a/arch/hexagon/include/uapi/asm/Kbuild b/arch/hexagon/include/uapi/asm/Kbuild
index e78470141932..2501e82a1a0a 100644
--- a/arch/hexagon/include/uapi/asm/Kbuild
+++ b/arch/hexagon/include/uapi/asm/Kbuild
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
+
generic-y += ucontext.h
diff --git a/arch/hexagon/include/uapi/asm/unistd.h b/arch/hexagon/include/uapi/asm/unistd.h
index 432c4db1b623..a3b0cac25580 100644
--- a/arch/hexagon/include/uapi/asm/unistd.h
+++ b/arch/hexagon/include/uapi/asm/unistd.h
@@ -27,14 +27,7 @@
* See also: syscalltab.c
*/
-#define sys_mmap2 sys_mmap_pgoff
-#define __ARCH_WANT_RENAMEAT
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_SYS_EXECVE
-#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_VFORK
-#define __ARCH_WANT_SYS_FORK
-#define __ARCH_WANT_TIME32_SYSCALLS
+#include <asm/unistd_32.h>
-#include <asm-generic/unistd.h>
+#define __NR_sync_file_range2 84
+#undef __NR_sync_file_range
diff --git a/arch/hexagon/kernel/Makefile.syscalls b/arch/hexagon/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..d2b7c5d44d95
--- /dev/null
+++ b/arch/hexagon/kernel/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += hexagon time32 stat64 rlimit renameat
diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c
index 0fadd582cfc7..b53e2eead4ac 100644
--- a/arch/hexagon/kernel/syscalltab.c
+++ b/arch/hexagon/kernel/syscalltab.c
@@ -11,9 +11,20 @@
#include <asm/syscall.h>
-#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+
+#define sys_mmap2 sys_mmap_pgoff
+
+SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice,
+ SC_ARG64(offset), SC_ARG64(len))
+{
+ return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice);
+}
+#define sys_fadvise64_64 sys_hexagon_fadvise64_64
+
+#define sys_sync_file_range sys_sync_file_range2
void *sys_call_table[__NR_syscalls] = {
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 54ad04dacdee..ebdb7156560c 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -16,10 +16,14 @@ config LOONGARCH
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER
+ select ARCH_HAS_DEBUG_VM_PGTABLE
+ select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KCOV
+ select ARCH_HAS_KERNEL_FPU_SUPPORT if CPU_HAS_FPU
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+ select ARCH_HAS_PTE_DEVMAP
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_INLINE_READ_LOCK if !PREEMPTION
@@ -56,6 +60,7 @@ config LOONGARCH
select ARCH_SUPPORTS_ACPI
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_HUGETLBFS
+ select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
select ARCH_SUPPORTS_LTO_CLANG
select ARCH_SUPPORTS_LTO_CLANG_THIN
select ARCH_SUPPORTS_NUMA_BALANCING
@@ -63,10 +68,12 @@ config LOONGARCH
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
+ select ARCH_WANT_DEFAULT_BPF_JIT
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
select ARCH_WANT_LD_ORPHAN_WARN
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
select ARCH_WANTS_NO_INSTR
+ select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
select BUILDTIME_TABLE_SORT
select COMMON_CLK
select CPU_PM
@@ -101,6 +108,7 @@ config LOONGARCH
select HAVE_ARCH_KFENCE
select HAVE_ARCH_KGDB if PERF_EVENTS
select HAVE_ARCH_MMAP_RND_BITS if MMU
+ select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
@@ -119,7 +127,7 @@ config LOONGARCH
select HAVE_EBPF_JIT
select HAVE_EFFICIENT_UNALIGNED_ACCESS if !ARCH_STRICT_ALIGN
select HAVE_EXIT_THREAD
- select HAVE_FAST_GUP
+ select HAVE_GUP_FAST
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_ARG_ACCESS_API
select HAVE_FUNCTION_ERROR_INJECTION
@@ -138,7 +146,7 @@ config LOONGARCH
select HAVE_LIVEPATCH
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
- select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS
+ select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && !CC_IS_CLANG
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
@@ -174,7 +182,6 @@ config LOONGARCH
select PCI_QUIRKS
select PERF_USE_VMALLOC
select RTC_LIB
- select SMP
select SPARSE_IRQ
select SYSCTL_ARCH_UNALIGN_ALLOW
select SYSCTL_ARCH_UNALIGN_NO_WARN
@@ -257,6 +264,9 @@ config AS_HAS_EXPLICIT_RELOCS
config AS_HAS_FCSR_CLASS
def_bool $(as-instr,movfcsr2gr \$t0$(comma)\$fcsr0)
+config AS_HAS_THIN_ADD_SUB
+ def_bool $(cc-option,-Wa$(comma)-mthin-add-sub)
+
config AS_HAS_LSX_EXTENSION
def_bool $(as-instr,vld \$vr0$(comma)\$a0$(comma)0)
@@ -420,6 +430,7 @@ config EFI_STUB
config SCHED_SMT
bool "SMT scheduler support"
+ depends on SMP
default y
help
Improves scheduler's performance when there are multiple
@@ -599,6 +610,7 @@ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
config RELOCATABLE
bool "Relocatable kernel"
+ select ARCH_HAS_RELR
help
This builds the kernel as a Position Independent Executable (PIE),
which retains all relocation metadata required, so as to relocate
@@ -632,6 +644,26 @@ config RANDOMIZE_BASE_MAX_OFFSET
source "kernel/livepatch/Kconfig"
+config PARAVIRT
+ bool "Enable paravirtualization code"
+ depends on AS_HAS_LVZ_EXTENSION
+ help
+ This changes the kernel so it can modify itself when it is run
+ under a hypervisor, potentially improving performance significantly
+ over full virtualization. However, when run without a hypervisor
+ the kernel is theoretically slower and slightly larger.
+
+config PARAVIRT_TIME_ACCOUNTING
+ bool "Paravirtual steal time accounting"
+ depends on PARAVIRT
+ help
+ Select this option to enable fine granularity task steal time
+ accounting. Time spent executing other tasks in parallel with
+ the current vCPU is discounted from the vCPU power. To account for
+ that, there can be a small performance impact.
+
+ If in doubt, say N here.
+
endmenu
config ARCH_SELECT_MEMORY_MODEL
@@ -682,6 +714,7 @@ config ARCH_HIBERNATION_POSSIBLE
source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
+source "drivers/cpufreq/Kconfig"
endmenu
diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug
index 98d60630c3d4..8b2ce5b5d43e 100644
--- a/arch/loongarch/Kconfig.debug
+++ b/arch/loongarch/Kconfig.debug
@@ -28,6 +28,7 @@ config UNWINDER_PROLOGUE
config UNWINDER_ORC
bool "ORC unwinder"
+ depends on HAVE_OBJTOOL
select OBJTOOL
help
This option enables the ORC (Oops Rewind Capability) unwinder for
diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
index df6caf79537a..ae3f80622f4c 100644
--- a/arch/loongarch/Makefile
+++ b/arch/loongarch/Makefile
@@ -26,6 +26,9 @@ endif
32bit-emul = elf32loongarch
64bit-emul = elf64loongarch
+CC_FLAGS_FPU := -mfpu=64
+CC_FLAGS_NO_FPU := -msoft-float
+
ifdef CONFIG_UNWINDER_ORC
orc_hash_h := arch/$(SRCARCH)/include/generated/asm/orc_hash.h
orc_hash_sh := $(srctree)/scripts/orc_hash.sh
@@ -59,7 +62,7 @@ ld-emul = $(64bit-emul)
cflags-y += -mabi=lp64s
endif
-cflags-y += -pipe -msoft-float
+cflags-y += -pipe $(CC_FLAGS_NO_FPU)
LDFLAGS_vmlinux += -static -n -nostdlib
# When the assembler supports explicit relocation hint, we must use it.
@@ -101,8 +104,9 @@ ifdef CONFIG_OBJTOOL
KBUILD_CFLAGS += -fno-jump-tables
endif
-KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
-KBUILD_RUSTFLAGS_MODULE += -Crelocation-model=pic
+KBUILD_RUSTFLAGS += --target=loongarch64-unknown-none-softfloat
+KBUILD_RUSTFLAGS_KERNEL += -Zdirect-access-external-data=yes
+KBUILD_RUSTFLAGS_MODULE += -Zdirect-access-external-data=no
ifeq ($(CONFIG_RELOCATABLE),y)
KBUILD_CFLAGS_KERNEL += -fPIE
diff --git a/arch/loongarch/boot/dts/loongson-2k0500-ref.dts b/arch/loongarch/boot/dts/loongson-2k0500-ref.dts
index 8aefb0c12672..a34734a6c3ce 100644
--- a/arch/loongarch/boot/dts/loongson-2k0500-ref.dts
+++ b/arch/loongarch/boot/dts/loongson-2k0500-ref.dts
@@ -44,14 +44,14 @@
&gmac0 {
status = "okay";
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
bus_id = <0x0>;
};
&gmac1 {
status = "okay";
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
bus_id = <0x1>;
};
diff --git a/arch/loongarch/boot/dts/loongson-2k0500.dtsi b/arch/loongarch/boot/dts/loongson-2k0500.dtsi
index 444779c21034..3b38ff8853a7 100644
--- a/arch/loongarch/boot/dts/loongson-2k0500.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k0500.dtsi
@@ -6,6 +6,7 @@
/dts-v1/;
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/loongson,ls2k-clk.h>
/ {
#address-cells = <2>;
@@ -19,14 +20,15 @@
compatible = "loongson,la264";
device_type = "cpu";
reg = <0x0>;
- clocks = <&cpu_clk>;
+ clocks = <&clk LOONGSON2_NODE_CLK>;
};
};
- cpu_clk: cpu-clk {
+ ref_100m: clock-ref-100m {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <500000000>;
+ clock-frequency = <100000000>;
+ clock-output-names = "ref_100m";
};
cpuintc: interrupt-controller {
@@ -35,6 +37,28 @@
interrupt-controller;
};
+ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&tsensor 0>;
+
+ trips {
+ cpu-alert {
+ temperature = <33000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+
+ cpu-crit {
+ temperature = <85000>;
+ hysteresis = <5000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
bus@10000000 {
compatible = "simple-bus";
ranges = <0x0 0x10000000 0x0 0x10000000 0x0 0x10000000>,
@@ -52,6 +76,54 @@
ranges = <1 0x0 0x0 0x16400000 0x4000>;
};
+ clk: clock-controller@1fe10400 {
+ compatible = "loongson,ls2k0500-clk";
+ reg = <0x0 0x1fe10400 0x0 0x2c>;
+ #clock-cells = <1>;
+ clocks = <&ref_100m>;
+ clock-names = "ref_100m";
+ };
+
+ dma-controller@1fe10c00 {
+ compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma";
+ reg = <0 0x1fe10c00 0 0x8>;
+ interrupt-parent = <&eiointc>;
+ interrupts = <67>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #dma-cells = <1>;
+ status = "disabled";
+ };
+
+ dma-controller@1fe10c10 {
+ compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma";
+ reg = <0 0x1fe10c10 0 0x8>;
+ interrupt-parent = <&eiointc>;
+ interrupts = <68>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #dma-cells = <1>;
+ status = "disabled";
+ };
+
+ dma-controller@1fe10c20 {
+ compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma";
+ reg = <0 0x1fe10c20 0 0x8>;
+ interrupt-parent = <&eiointc>;
+ interrupts = <69>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #dma-cells = <1>;
+ status = "disabled";
+ };
+
+ dma-controller@1fe10c30 {
+ compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma";
+ reg = <0 0x1fe10c30 0 0x8>;
+ interrupt-parent = <&eiointc>;
+ interrupts = <70>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #dma-cells = <1>;
+ status = "disabled";
+ };
+
liointc0: interrupt-controller@1fe11400 {
compatible = "loongson,liointc-2.0";
reg = <0x0 0x1fe11400 0x0 0x40>,
@@ -139,6 +211,14 @@
status = "disabled";
};
+ tsensor: thermal-sensor@1fe11500 {
+ compatible = "loongson,ls2k0500-thermal", "loongson,ls2k1000-thermal";
+ reg = <0x0 0x1fe11500 0x0 0x30>;
+ interrupt-parent = <&liointc0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <1>;
+ };
+
uart0: serial@1ff40800 {
compatible = "ns16550a";
reg = <0x0 0x1ff40800 0x0 0x10>;
diff --git a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
index ed4d32434041..23cf26cc3e5f 100644
--- a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
+++ b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
@@ -43,7 +43,7 @@
&gmac0 {
status = "okay";
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-handle = <&phy0>;
mdio {
compatible = "snps,dwmac-mdio";
@@ -58,7 +58,7 @@
&gmac1 {
status = "okay";
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-handle = <&phy1>;
mdio {
compatible = "snps,dwmac-mdio";
@@ -113,10 +113,6 @@
status = "okay";
};
-&clk {
- status = "okay";
-};
-
&rtc0 {
status = "okay";
};
diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi
index b6aeb1f70e2a..92180140eb56 100644
--- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi
@@ -159,7 +159,6 @@
#clock-cells = <1>;
clocks = <&ref_100m>;
clock-names = "ref_100m";
- status = "disabled";
};
gpio0: gpio@1fe00500 {
diff --git a/arch/loongarch/boot/dts/loongson-2k2000-ref.dts b/arch/loongarch/boot/dts/loongson-2k2000-ref.dts
index 74b99bd234cc..ea9e6985d0e9 100644
--- a/arch/loongarch/boot/dts/loongson-2k2000-ref.dts
+++ b/arch/loongarch/boot/dts/loongson-2k2000-ref.dts
@@ -92,7 +92,7 @@
&gmac2 {
status = "okay";
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-handle = <&phy2>;
mdio {
compatible = "snps,dwmac-mdio";
diff --git a/arch/loongarch/boot/dts/loongson-2k2000.dtsi b/arch/loongarch/boot/dts/loongson-2k2000.dtsi
index 9eab2d02cbe8..0953c5707825 100644
--- a/arch/loongarch/boot/dts/loongson-2k2000.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k2000.dtsi
@@ -6,6 +6,7 @@
/dts-v1/;
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/loongson,ls2k-clk.h>
/ {
#address-cells = <2>;
@@ -19,21 +20,22 @@
compatible = "loongson,la364";
device_type = "cpu";
reg = <0x0>;
- clocks = <&cpu_clk>;
+ clocks = <&clk LOONGSON2_NODE_CLK>;
};
cpu1: cpu@2 {
compatible = "loongson,la364";
device_type = "cpu";
reg = <0x1>;
- clocks = <&cpu_clk>;
+ clocks = <&clk LOONGSON2_NODE_CLK>;
};
};
- cpu_clk: cpu-clk {
+ ref_100m: clock-ref-100m {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <1400000000>;
+ clock-frequency = <100000000>;
+ clock-output-names = "ref_100m";
};
cpuintc: interrupt-controller {
@@ -42,6 +44,28 @@
interrupt-controller;
};
+ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&tsensor 0>;
+
+ trips {
+ cpu-alert {
+ temperature = <40000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+
+ cpu-crit {
+ temperature = <85000>;
+ hysteresis = <5000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
bus@10000000 {
compatible = "simple-bus";
ranges = <0x0 0x10000000 0x0 0x10000000 0x0 0x10000000>,
@@ -58,6 +82,14 @@
ranges = <1 0x0 0x0 0x18400000 0x4000>;
};
+ clk: clock-controller@10010480 {
+ compatible = "loongson,ls2k2000-clk";
+ reg = <0x0 0x10010480 0x0 0x100>;
+ #clock-cells = <1>;
+ clocks = <&ref_100m>;
+ clock-names = "ref_100m";
+ };
+
pmc: power-management@100d0000 {
compatible = "loongson,ls2k2000-pmc", "loongson,ls2k0500-pmc", "syscon";
reg = <0x0 0x100d0000 0x0 0x58>;
@@ -80,6 +112,15 @@
};
};
+ tsensor: thermal-sensor@1fe01460 {
+ compatible = "loongson,ls2k2000-thermal";
+ reg = <0x0 0x1fe01460 0x0 0x30>,
+ <0x0 0x1fe0019c 0x0 0x4>;
+ interrupt-parent = <&liointc>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <1>;
+ };
+
liointc: interrupt-controller@1fe01400 {
compatible = "loongson,liointc-1.0";
reg = <0x0 0x1fe01400 0x0 0x64>;
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig
index f18c2ba871ef..b4252c357c8e 100644
--- a/arch/loongarch/configs/loongson3_defconfig
+++ b/arch/loongarch/configs/loongson3_defconfig
@@ -14,6 +14,10 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_PSI=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKHEADERS=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_NUMA_BALANCING=y
CONFIG_MEMCG=y
@@ -76,7 +80,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_THROTTLING=y
-CONFIG_BLK_DEV_THROTTLING_LOW=y
CONFIG_BLK_WBT=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_FC_APPID=y
@@ -130,13 +133,22 @@ CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_AH=m
CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
+CONFIG_INET_ESPINTCP=y
+CONFIG_INET_IPCOMP=m
CONFIG_INET_UDP_DIAG=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BBR=m
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
+CONFIG_INET6_ESPINTCP=y
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_MROUTE=y
CONFIG_MPTCP=y
CONFIG_NETWORK_PHY_TIMESTAMPING=y
@@ -152,6 +164,8 @@ CONFIG_NF_CONNTRACK_PPTP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_TABLES=m
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_CT=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -164,6 +178,7 @@ CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
+CONFIG_NFT_FIB_INET=m
CONFIG_NFT_SOCKET=m
CONFIG_NFT_OSF=m
CONFIG_NFT_TPROXY=m
@@ -260,6 +275,7 @@ CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_TABLES_IPV6=y
+CONFIG_NFT_FIB_IPV6=m
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -280,6 +296,7 @@ CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -550,6 +567,7 @@ CONFIG_NGBE=y
CONFIG_TXGBE=y
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_MOTORCOMM_PHY=y
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
@@ -811,6 +829,7 @@ CONFIG_NTB_SWITCHTEC=m
CONFIG_NTB_PERF=m
CONFIG_NTB_TRANSPORT=m
CONFIG_PWM=y
+CONFIG_GENERIC_PHY=y
CONFIG_USB4=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
@@ -876,10 +895,13 @@ CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_CRAMFS=m
CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_ZSTD=y
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
CONFIG_PSTORE=m
@@ -961,3 +983,4 @@ CONFIG_DEBUG_FS=y
CONFIG_SCHEDSTATS=y
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_FTRACE is not set
+CONFIG_UNWINDER_ORC=y
diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild
index 2dbec7853ae8..2bb3676429c0 100644
--- a/arch/loongarch/include/asm/Kbuild
+++ b/arch/loongarch/include/asm/Kbuild
@@ -1,29 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_64.h
generated-y += orc_hash.h
-generic-y += dma-contiguous.h
generic-y += mcs_spinlock.h
generic-y += parport.h
generic-y += early_ioremap.h
generic-y += qrwlock.h
generic-y += qspinlock.h
-generic-y += rwsem.h
-generic-y += segment.h
generic-y += user.h
-generic-y += stat.h
-generic-y += fcntl.h
generic-y += ioctl.h
-generic-y += ioctls.h
-generic-y += mman.h
-generic-y += msgbuf.h
-generic-y += sembuf.h
-generic-y += shmbuf.h
generic-y += statfs.h
-generic-y += socket.h
-generic-y += sockios.h
-generic-y += termbits.h
-generic-y += poll.h
generic-y += param.h
-generic-y += posix_types.h
-generic-y += resource.h
-generic-y += kvm_para.h
diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
index 49e29b29996f..313f66f7913a 100644
--- a/arch/loongarch/include/asm/acpi.h
+++ b/arch/loongarch/include/asm/acpi.h
@@ -8,6 +8,7 @@
#ifndef _ASM_LOONGARCH_ACPI_H
#define _ASM_LOONGARCH_ACPI_H
+#include <asm/smp.h>
#include <asm/suspend.h>
#ifdef CONFIG_ACPI
diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h
index 7bd47d65bf7a..fe198b473f84 100644
--- a/arch/loongarch/include/asm/addrspace.h
+++ b/arch/loongarch/include/asm/addrspace.h
@@ -37,6 +37,10 @@ extern unsigned long vm_map_base;
#define UNCACHE_BASE CSR_DMW0_BASE
#endif
+#ifndef WRITECOMBINE_BASE
+#define WRITECOMBINE_BASE CSR_DMW2_BASE
+#endif
+
#define DMW_PABITS 48
#define TO_PHYS_MASK ((1ULL << DMW_PABITS) - 1)
diff --git a/arch/loongarch/include/asm/asm-prototypes.h b/arch/loongarch/include/asm/asm-prototypes.h
index cf8e1a4e7c19..51f224bcfc65 100644
--- a/arch/loongarch/include/asm/asm-prototypes.h
+++ b/arch/loongarch/include/asm/asm-prototypes.h
@@ -6,3 +6,9 @@
#include <asm/page.h>
#include <asm/ftrace.h>
#include <asm-generic/asm-prototypes.h>
+
+#ifdef CONFIG_ARCH_SUPPORTS_INT128
+__int128_t __ashlti3(__int128_t a, int b);
+__int128_t __ashrti3(__int128_t a, int b);
+__int128_t __lshrti3(__int128_t a, int b);
+#endif
diff --git a/arch/loongarch/include/asm/asmmacro.h b/arch/loongarch/include/asm/asmmacro.h
index 655db7d7a427..8d7f501b0a12 100644
--- a/arch/loongarch/include/asm/asmmacro.h
+++ b/arch/loongarch/include/asm/asmmacro.h
@@ -609,6 +609,7 @@
lu32i.d \reg, 0
lu52i.d \reg, \reg, 0
.pushsection ".la_abs", "aw", %progbits
+ .p2align 3
.dword 766b
.dword \sym
.popsection
diff --git a/arch/loongarch/include/asm/fpu.h b/arch/loongarch/include/asm/fpu.h
index c2d8962fda00..3177674228f8 100644
--- a/arch/loongarch/include/asm/fpu.h
+++ b/arch/loongarch/include/asm/fpu.h
@@ -21,6 +21,7 @@
struct sigcontext;
+#define kernel_fpu_available() cpu_has_fpu
extern void kernel_fpu_begin(void);
extern void kernel_fpu_end(void);
diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/asm/ftrace.h
index de891c2c83d4..c0a682808e07 100644
--- a/arch/loongarch/include/asm/ftrace.h
+++ b/arch/loongarch/include/asm/ftrace.h
@@ -28,7 +28,6 @@ struct dyn_ftrace;
struct dyn_arch_ftrace { };
#define ARCH_SUPPORTS_FTRACE_OPS 1
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
#define ftrace_init_nop ftrace_init_nop
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
diff --git a/arch/loongarch/include/asm/hardirq.h b/arch/loongarch/include/asm/hardirq.h
index 0ef3b18f8980..1d7feb719515 100644
--- a/arch/loongarch/include/asm/hardirq.h
+++ b/arch/loongarch/include/asm/hardirq.h
@@ -12,11 +12,18 @@
extern void ack_bad_irq(unsigned int irq);
#define ack_bad_irq ack_bad_irq
-#define NR_IPI 2
+#define NR_IPI 3
+
+enum ipi_msg_type {
+ IPI_RESCHEDULE,
+ IPI_CALL_FUNCTION,
+ IPI_IRQ_WORK,
+};
typedef struct {
unsigned int ipi_irqs[NR_IPI];
unsigned int __softirq_pending;
+ atomic_t message ____cacheline_aligned_in_smp;
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/include/asm/hw_breakpoint.h
index 21447fb1efc7..d78330916bd1 100644
--- a/arch/loongarch/include/asm/hw_breakpoint.h
+++ b/arch/loongarch/include/asm/hw_breakpoint.h
@@ -75,6 +75,8 @@ do { \
#define CSR_MWPC_NUM 0x3f
#define CTRL_PLV_ENABLE 0x1e
+#define CTRL_PLV0_ENABLE 0x02
+#define CTRL_PLV3_ENABLE 0x10
#define MWPnCFG3_LoadEn 8
#define MWPnCFG3_StoreEn 9
@@ -101,7 +103,7 @@ struct perf_event;
struct perf_event_attr;
extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
- int *gen_len, int *gen_type, int *offset);
+ int *gen_len, int *gen_type);
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
const struct perf_event_attr *attr,
diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
index d8f637f9e400..944482063f14 100644
--- a/arch/loongarch/include/asm/inst.h
+++ b/arch/loongarch/include/asm/inst.h
@@ -12,6 +12,7 @@
#define INSN_NOP 0x03400000
#define INSN_BREAK 0x002a0000
+#define INSN_HVCL 0x002b8000
#define ADDR_IMMMASK_LU52ID 0xFFF0000000000000
#define ADDR_IMMMASK_LU32ID 0x000FFFFF00000000
@@ -67,6 +68,7 @@ enum reg2_op {
revhd_op = 0x11,
extwh_op = 0x16,
extwb_op = 0x17,
+ cpucfg_op = 0x1b,
iocsrrdb_op = 0x19200,
iocsrrdh_op = 0x19201,
iocsrrdw_op = 0x19202,
@@ -530,6 +532,9 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \
DEF_EMIT_REG0I15_FORMAT(break, break_op)
+/* like emit_break(imm) but returns a constant expression */
+#define __emit_break(imm) ((u32)((imm) | (break_op << 15)))
+
#define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \
static inline void emit_##NAME(union loongarch_instruction *insn, \
int offset) \
diff --git a/arch/loongarch/include/asm/io.h b/arch/loongarch/include/asm/io.h
index c2f9979b2979..5e95a60df180 100644
--- a/arch/loongarch/include/asm/io.h
+++ b/arch/loongarch/include/asm/io.h
@@ -25,10 +25,16 @@ extern void __init early_iounmap(void __iomem *addr, unsigned long size);
static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
unsigned long prot_val)
{
- if (prot_val & _CACHE_CC)
+ switch (prot_val & _CACHE_MASK) {
+ case _CACHE_CC:
return (void __iomem *)(unsigned long)(CACHE_BASE + offset);
- else
+ case _CACHE_SUC:
return (void __iomem *)(unsigned long)(UNCACHE_BASE + offset);
+ case _CACHE_WUC:
+ return (void __iomem *)(unsigned long)(WRITECOMBINE_BASE + offset);
+ default:
+ return NULL;
+ }
}
#define ioremap(offset, size) \
diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h
index 218b4da0ea90..480418bc5071 100644
--- a/arch/loongarch/include/asm/irq.h
+++ b/arch/loongarch/include/asm/irq.h
@@ -117,7 +117,16 @@ extern struct fwnode_handle *liointc_handle;
extern struct fwnode_handle *pch_lpc_handle;
extern struct fwnode_handle *pch_pic_handle[MAX_IO_PICS];
-extern irqreturn_t loongson_ipi_interrupt(int irq, void *dev);
+static inline int get_percpu_irq(int vector)
+{
+ struct irq_domain *d;
+
+ d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY);
+ if (d)
+ return irq_create_mapping(d, vector);
+
+ return -EINVAL;
+}
#include <asm-generic/irq.h>
diff --git a/arch/loongarch/include/asm/irq_work.h b/arch/loongarch/include/asm/irq_work.h
new file mode 100644
index 000000000000..d63076e9160d
--- /dev/null
+++ b/arch/loongarch/include/asm/irq_work.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LOONGARCH_IRQ_WORK_H
+#define _ASM_LOONGARCH_IRQ_WORK_H
+
+static inline bool arch_irq_work_has_interrupt(void)
+{
+ return IS_ENABLED(CONFIG_SMP);
+}
+
+#endif /* _ASM_LOONGARCH_IRQ_WORK_H */
diff --git a/arch/loongarch/include/asm/kfence.h b/arch/loongarch/include/asm/kfence.h
index a6a5760da3a3..92636e82957c 100644
--- a/arch/loongarch/include/asm/kfence.h
+++ b/arch/loongarch/include/asm/kfence.h
@@ -10,6 +10,7 @@
#define _ASM_LOONGARCH_KFENCE_H
#include <linux/kfence.h>
+#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include <asm/tlb.h>
diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..44b54965f5b4 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -30,6 +30,16 @@
#define KVM_PRIVATE_MEM_SLOTS 0
#define KVM_HALT_POLL_NS_DEFAULT 500000
+#define KVM_REQ_TLB_FLUSH_GPA KVM_ARCH_REQ(0)
+#define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(1)
+
+#define KVM_GUESTDBG_SW_BP_MASK \
+ (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
+#define KVM_GUESTDBG_VALID_MASK \
+ (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP | KVM_GUESTDBG_SINGLESTEP)
+
+#define KVM_DIRTY_LOG_MANUAL_CAPS \
+ (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | KVM_DIRTY_LOG_INITIALLY_SET)
struct kvm_vm_stat {
struct kvm_vm_stat_generic generic;
@@ -43,6 +53,7 @@ struct kvm_vcpu_stat {
u64 idle_exits;
u64 cpucfg_exits;
u64 signal_exits;
+ u64 hypercall_exits;
};
#define KVM_MEM_HUGEPAGE_CAPABLE (1UL << 0)
@@ -64,6 +75,31 @@ struct kvm_world_switch {
#define MAX_PGTABLE_LEVELS 4
+/*
+ * Physical CPUID is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *
+ * For LOONGARCH_CSR_CPUID register, max CPUID size if 512
+ * For IPI hardware, max destination CPUID size 1024
+ * For extioi interrupt controller, max destination CPUID size is 256
+ * For msgint interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID 256
+
+struct kvm_phyid_info {
+ struct kvm_vcpu *vcpu;
+ bool enabled;
+};
+
+struct kvm_phyid_map {
+ int max_phyid;
+ struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
struct kvm_arch {
/* Guest physical mm */
kvm_pte_t *pgd;
@@ -71,6 +107,8 @@ struct kvm_arch {
unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
unsigned int pte_shifts[MAX_PGTABLE_LEVELS];
unsigned int root_level;
+ spinlock_t phyid_map_lock;
+ struct kvm_phyid_map *phyid_map;
s64 time_offset;
struct kvm_context __percpu *vmcs;
@@ -157,6 +195,7 @@ struct kvm_vcpu_arch {
/* vcpu's vpid */
u64 vpid;
+ gpa_t flush_gpa;
/* Frequency of stable timer in Hz */
u64 timer_mhz;
@@ -168,6 +207,13 @@ struct kvm_vcpu_arch {
struct kvm_mp_state mp_state;
/* cpucfg */
u32 cpucfg[KVM_MAX_CPUCFG_REGS];
+
+ /* paravirt steal time */
+ struct {
+ u64 guest_addr;
+ u64 last_steal;
+ struct gfn_to_hva_cache cache;
+ } st;
};
static inline unsigned long readl_sw_gcsr(struct loongarch_csrs *csr, int reg)
@@ -203,7 +249,6 @@ void kvm_flush_tlb_all(void);
void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa);
int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long badv, bool write);
-void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, bool blockable);
int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
@@ -229,7 +274,6 @@ static inline bool kvm_is_ifetch_fault(struct kvm_vcpu_arch *arch)
static inline void kvm_arch_hardware_unsetup(void) {}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
diff --git a/arch/loongarch/include/asm/kvm_para.h b/arch/loongarch/include/asm/kvm_para.h
new file mode 100644
index 000000000000..335fb86778e2
--- /dev/null
+++ b/arch/loongarch/include/asm/kvm_para.h
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LOONGARCH_KVM_PARA_H
+#define _ASM_LOONGARCH_KVM_PARA_H
+
+/*
+ * Hypercall code field
+ */
+#define HYPERVISOR_KVM 1
+#define HYPERVISOR_VENDOR_SHIFT 8
+#define HYPERCALL_ENCODE(vendor, code) ((vendor << HYPERVISOR_VENDOR_SHIFT) + code)
+
+#define KVM_HCALL_CODE_SERVICE 0
+#define KVM_HCALL_CODE_SWDBG 1
+
+#define KVM_HCALL_SERVICE HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SERVICE)
+#define KVM_HCALL_FUNC_IPI 1
+#define KVM_HCALL_FUNC_NOTIFY 2
+
+#define KVM_HCALL_SWDBG HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SWDBG)
+
+/*
+ * LoongArch hypercall return code
+ */
+#define KVM_HCALL_SUCCESS 0
+#define KVM_HCALL_INVALID_CODE -1UL
+#define KVM_HCALL_INVALID_PARAMETER -2UL
+
+#define KVM_STEAL_PHYS_VALID BIT_ULL(0)
+#define KVM_STEAL_PHYS_MASK GENMASK_ULL(63, 6)
+
+struct kvm_steal_time {
+ __u64 steal;
+ __u32 version;
+ __u32 flags;
+ __u32 pad[12];
+};
+
+/*
+ * Hypercall interface for KVM hypervisor
+ *
+ * a0: function identifier
+ * a1-a6: args
+ * Return value will be placed in a0.
+ * Up to 6 arguments are passed in a1, a2, a3, a4, a5, a6.
+ */
+static __always_inline long kvm_hypercall0(u64 fid)
+{
+ register long ret asm("a0");
+ register unsigned long fun asm("a0") = fid;
+
+ __asm__ __volatile__(
+ "hvcl "__stringify(KVM_HCALL_SERVICE)
+ : "=r" (ret)
+ : "r" (fun)
+ : "memory"
+ );
+
+ return ret;
+}
+
+static __always_inline long kvm_hypercall1(u64 fid, unsigned long arg0)
+{
+ register long ret asm("a0");
+ register unsigned long fun asm("a0") = fid;
+ register unsigned long a1 asm("a1") = arg0;
+
+ __asm__ __volatile__(
+ "hvcl "__stringify(KVM_HCALL_SERVICE)
+ : "=r" (ret)
+ : "r" (fun), "r" (a1)
+ : "memory"
+ );
+
+ return ret;
+}
+
+static __always_inline long kvm_hypercall2(u64 fid,
+ unsigned long arg0, unsigned long arg1)
+{
+ register long ret asm("a0");
+ register unsigned long fun asm("a0") = fid;
+ register unsigned long a1 asm("a1") = arg0;
+ register unsigned long a2 asm("a2") = arg1;
+
+ __asm__ __volatile__(
+ "hvcl "__stringify(KVM_HCALL_SERVICE)
+ : "=r" (ret)
+ : "r" (fun), "r" (a1), "r" (a2)
+ : "memory"
+ );
+
+ return ret;
+}
+
+static __always_inline long kvm_hypercall3(u64 fid,
+ unsigned long arg0, unsigned long arg1, unsigned long arg2)
+{
+ register long ret asm("a0");
+ register unsigned long fun asm("a0") = fid;
+ register unsigned long a1 asm("a1") = arg0;
+ register unsigned long a2 asm("a2") = arg1;
+ register unsigned long a3 asm("a3") = arg2;
+
+ __asm__ __volatile__(
+ "hvcl "__stringify(KVM_HCALL_SERVICE)
+ : "=r" (ret)
+ : "r" (fun), "r" (a1), "r" (a2), "r" (a3)
+ : "memory"
+ );
+
+ return ret;
+}
+
+static __always_inline long kvm_hypercall4(u64 fid,
+ unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3)
+{
+ register long ret asm("a0");
+ register unsigned long fun asm("a0") = fid;
+ register unsigned long a1 asm("a1") = arg0;
+ register unsigned long a2 asm("a2") = arg1;
+ register unsigned long a3 asm("a3") = arg2;
+ register unsigned long a4 asm("a4") = arg3;
+
+ __asm__ __volatile__(
+ "hvcl "__stringify(KVM_HCALL_SERVICE)
+ : "=r" (ret)
+ : "r"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4)
+ : "memory"
+ );
+
+ return ret;
+}
+
+static __always_inline long kvm_hypercall5(u64 fid,
+ unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3, unsigned long arg4)
+{
+ register long ret asm("a0");
+ register unsigned long fun asm("a0") = fid;
+ register unsigned long a1 asm("a1") = arg0;
+ register unsigned long a2 asm("a2") = arg1;
+ register unsigned long a3 asm("a3") = arg2;
+ register unsigned long a4 asm("a4") = arg3;
+ register unsigned long a5 asm("a5") = arg4;
+
+ __asm__ __volatile__(
+ "hvcl "__stringify(KVM_HCALL_SERVICE)
+ : "=r" (ret)
+ : "r"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5)
+ : "memory"
+ );
+
+ return ret;
+}
+
+static inline unsigned int kvm_arch_para_features(void)
+{
+ return 0;
+}
+
+static inline unsigned int kvm_arch_para_hints(void)
+{
+ return 0;
+}
+
+static inline bool kvm_check_and_clear_guest_paused(void)
+{
+ return false;
+}
+
+#endif /* _ASM_LOONGARCH_KVM_PARA_H */
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..c416cb7125c0 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
void kvm_restore_timer(struct kvm_vcpu *vcpu);
int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
/*
* Loongarch KVM guest interrupt handling
@@ -109,4 +110,19 @@ static inline int kvm_queue_exception(struct kvm_vcpu *vcpu,
return -1;
}
+static inline unsigned long kvm_read_reg(struct kvm_vcpu *vcpu, int num)
+{
+ return vcpu->arch.gprs[num];
+}
+
+static inline void kvm_write_reg(struct kvm_vcpu *vcpu, int num, unsigned long val)
+{
+ vcpu->arch.gprs[num] = val;
+}
+
+static inline bool kvm_pvtime_supported(void)
+{
+ return !!sched_info_on();
+}
+
#endif /* __ASM_LOONGARCH_KVM_VCPU_H__ */
diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 46366e783c84..04a78010fc72 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -158,6 +158,19 @@
#define CPUCFG48_VFPU_CG BIT(2)
#define CPUCFG48_RAM_CG BIT(3)
+/*
+ * CPUCFG index area: 0x40000000 -- 0x400000ff
+ * SW emulation for KVM hypervirsor
+ */
+#define CPUCFG_KVM_BASE 0x40000000
+#define CPUCFG_KVM_SIZE 0x100
+
+#define CPUCFG_KVM_SIG (CPUCFG_KVM_BASE + 0)
+#define KVM_SIGNATURE "KVM\0"
+#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4)
+#define KVM_FEATURE_IPI BIT(1)
+#define KVM_FEATURE_STEAL_TIME BIT(2)
+
#ifndef __ASSEMBLY__
/* CSR */
@@ -865,7 +878,7 @@
#define LOONGARCH_CSR_DMWIN2 0x182 /* 64 direct map win2: MEM */
#define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */
-/* Direct Map window 0/1 */
+/* Direct Map window 0/1/2/3 */
#define CSR_DMW0_PLV0 _CONST64_(1 << 0)
#define CSR_DMW0_VSEG _CONST64_(0x8000)
#define CSR_DMW0_BASE (CSR_DMW0_VSEG << DMW_PABITS)
@@ -877,6 +890,14 @@
#define CSR_DMW1_BASE (CSR_DMW1_VSEG << DMW_PABITS)
#define CSR_DMW1_INIT (CSR_DMW1_BASE | CSR_DMW1_MAT | CSR_DMW1_PLV0)
+#define CSR_DMW2_PLV0 _CONST64_(1 << 0)
+#define CSR_DMW2_MAT _CONST64_(2 << 4)
+#define CSR_DMW2_VSEG _CONST64_(0xa000)
+#define CSR_DMW2_BASE (CSR_DMW2_VSEG << DMW_PABITS)
+#define CSR_DMW2_INIT (CSR_DMW2_BASE | CSR_DMW2_MAT | CSR_DMW2_PLV0)
+
+#define CSR_DMW3_INIT 0x0
+
/* Performance Counter registers */
#define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */
#define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */
@@ -1041,11 +1062,14 @@
#define LOONGARCH_IOCSR_NODECNT 0x408
#define LOONGARCH_IOCSR_MISC_FUNC 0x420
+#define IOCSR_MISC_FUNC_SOFT_INT BIT_ULL(10)
#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21)
#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48)
#define LOONGARCH_IOCSR_CPUTEMP 0x428
+#define LOONGARCH_IOCSR_SMCMBX 0x51c
+
/* PerCore CSR, only accessible by local cores */
#define LOONGARCH_IOCSR_IPI_STATUS 0x1000
#define LOONGARCH_IOCSR_IPI_EN 0x1004
diff --git a/arch/loongarch/include/asm/numa.h b/arch/loongarch/include/asm/numa.h
index 27f319b49862..b5f9de9f102e 100644
--- a/arch/loongarch/include/asm/numa.h
+++ b/arch/loongarch/include/asm/numa.h
@@ -56,6 +56,7 @@ extern int early_cpu_to_node(int cpu);
static inline void early_numa_add_cpu(int cpuid, s16 node) { }
static inline void numa_add_cpu(unsigned int cpu) { }
static inline void numa_remove_cpu(unsigned int cpu) { }
+static inline void set_cpuid_to_node(int cpuid, s16 node) { }
static inline int early_cpu_to_node(int cpu)
{
diff --git a/arch/loongarch/include/asm/paravirt.h b/arch/loongarch/include/asm/paravirt.h
new file mode 100644
index 000000000000..dddec49671ae
--- /dev/null
+++ b/arch/loongarch/include/asm/paravirt.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LOONGARCH_PARAVIRT_H
+#define _ASM_LOONGARCH_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT
+
+#include <linux/static_call_types.h>
+struct static_key;
+extern struct static_key paravirt_steal_enabled;
+extern struct static_key paravirt_steal_rq_enabled;
+
+u64 dummy_steal_clock(int cpu);
+DECLARE_STATIC_CALL(pv_steal_clock, dummy_steal_clock);
+
+static inline u64 paravirt_steal_clock(int cpu)
+{
+ return static_call(pv_steal_clock)(cpu);
+}
+
+int __init pv_ipi_init(void);
+int __init pv_time_init(void);
+
+#else
+
+static inline int pv_ipi_init(void)
+{
+ return 0;
+}
+
+static inline int pv_time_init(void)
+{
+ return 0;
+}
+#endif // CONFIG_PARAVIRT
+#endif
diff --git a/arch/loongarch/include/asm/paravirt_api_clock.h b/arch/loongarch/include/asm/paravirt_api_clock.h
new file mode 100644
index 000000000000..65ac7cee0dad
--- /dev/null
+++ b/arch/loongarch/include/asm/paravirt_api_clock.h
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
diff --git a/arch/loongarch/include/asm/perf_event.h b/arch/loongarch/include/asm/perf_event.h
index 52b638059e40..f948a0676daf 100644
--- a/arch/loongarch/include/asm/perf_event.h
+++ b/arch/loongarch/include/asm/perf_event.h
@@ -13,8 +13,7 @@
#define perf_arch_fetch_caller_regs(regs, __ip) { \
(regs)->csr_era = (__ip); \
- (regs)->regs[3] = current_stack_pointer; \
- (regs)->regs[22] = (unsigned long) __builtin_frame_address(0); \
+ (regs)->regs[3] = (unsigned long) __builtin_frame_address(0); \
}
#endif /* __LOONGARCH_PERF_EVENT_H__ */
diff --git a/arch/loongarch/include/asm/pgtable-bits.h b/arch/loongarch/include/asm/pgtable-bits.h
index 21319c1e045c..82cd3a9f094b 100644
--- a/arch/loongarch/include/asm/pgtable-bits.h
+++ b/arch/loongarch/include/asm/pgtable-bits.h
@@ -22,6 +22,7 @@
#define _PAGE_PFN_SHIFT 12
#define _PAGE_SWP_EXCLUSIVE_SHIFT 23
#define _PAGE_PFN_END_SHIFT 48
+#define _PAGE_DEVMAP_SHIFT 59
#define _PAGE_PRESENT_INVALID_SHIFT 60
#define _PAGE_NO_READ_SHIFT 61
#define _PAGE_NO_EXEC_SHIFT 62
@@ -35,6 +36,7 @@
#define _PAGE_MODIFIED (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
#define _PAGE_PROTNONE (_ULCAST_(1) << _PAGE_PROTNONE_SHIFT)
#define _PAGE_SPECIAL (_ULCAST_(1) << _PAGE_SPECIAL_SHIFT)
+#define _PAGE_DEVMAP (_ULCAST_(1) << _PAGE_DEVMAP_SHIFT)
/* We borrow bit 23 to store the exclusive marker in swap PTEs. */
#define _PAGE_SWP_EXCLUSIVE (_ULCAST_(1) << _PAGE_SWP_EXCLUSIVE_SHIFT)
@@ -74,8 +76,8 @@
#define __READABLE (_PAGE_VALID)
#define __WRITEABLE (_PAGE_DIRTY | _PAGE_WRITE)
-#define _PAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV)
-#define _HPAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV | _PAGE_HUGE)
+#define _PAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PAGE_DEVMAP | _PFN_MASK | _CACHE_MASK | _PAGE_PLV)
+#define _HPAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PAGE_DEVMAP | _PFN_MASK | _CACHE_MASK | _PAGE_PLV | _PAGE_HUGE)
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_NO_READ | \
_PAGE_USER | _CACHE_CC)
diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index af3acdf3481a..3fbf1f37c58e 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -424,6 +424,9 @@ static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL;
static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; return pte; }
#endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */
+static inline int pte_devmap(pte_t pte) { return !!(pte_val(pte) & _PAGE_DEVMAP); }
+static inline pte_t pte_mkdevmap(pte_t pte) { pte_val(pte) |= _PAGE_DEVMAP; return pte; }
+
#define pte_accessible pte_accessible
static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
{
@@ -467,8 +470,8 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
#define update_mmu_cache(vma, addr, ptep) \
update_mmu_cache_range(NULL, vma, addr, ptep, 1)
-#define __HAVE_ARCH_UPDATE_MMU_TLB
-#define update_mmu_tlb update_mmu_cache
+#define update_mmu_tlb_range(vma, addr, ptep, nr) \
+ update_mmu_cache_range(NULL, vma, addr, ptep, nr)
static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp)
@@ -558,6 +561,17 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
return pmd;
}
+static inline int pmd_devmap(pmd_t pmd)
+{
+ return !!(pmd_val(pmd) & _PAGE_DEVMAP);
+}
+
+static inline pmd_t pmd_mkdevmap(pmd_t pmd)
+{
+ pmd_val(pmd) |= _PAGE_DEVMAP;
+ return pmd;
+}
+
static inline struct page *pmd_page(pmd_t pmd)
{
if (pmd_trans_huge(pmd))
@@ -613,6 +627,11 @@ static inline long pmd_protnone(pmd_t pmd)
#define pmd_leaf(pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0)
#define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0)
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pud_devmap(pud) (0)
+#define pgd_devmap(pgd) (0)
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
/*
* We provide our own get_unmapped area to cope with the virtual aliasing
* constraints placed on us by the cache architecture.
diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h
index ee52fb1e9963..3c2fb16b11b6 100644
--- a/arch/loongarch/include/asm/setup.h
+++ b/arch/loongarch/include/asm/setup.h
@@ -34,6 +34,11 @@ extern long __la_abs_end;
extern long __rela_dyn_begin;
extern long __rela_dyn_end;
+#ifdef CONFIG_RELR
+extern long __relr_dyn_begin;
+extern long __relr_dyn_end;
+#endif
+
extern unsigned long __init relocate_kernel(void);
#endif
diff --git a/arch/loongarch/include/asm/smp.h b/arch/loongarch/include/asm/smp.h
index f81e5f01d619..50db503f44e3 100644
--- a/arch/loongarch/include/asm/smp.h
+++ b/arch/loongarch/include/asm/smp.h
@@ -6,12 +6,21 @@
#ifndef __ASM_SMP_H
#define __ASM_SMP_H
+#ifdef CONFIG_SMP
+
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/linkage.h>
#include <linux/threads.h>
#include <linux/cpumask.h>
+struct smp_ops {
+ void (*init_ipi)(void);
+ void (*send_ipi_single)(int cpu, unsigned int action);
+ void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
+};
+extern struct smp_ops mp_ops;
+
extern int smp_num_siblings;
extern int num_processors;
extern int disabled_cpus;
@@ -24,8 +33,6 @@ void loongson_prepare_cpus(unsigned int max_cpus);
void loongson_boot_secondary(int cpu, struct task_struct *idle);
void loongson_init_secondary(void);
void loongson_smp_finish(void);
-void loongson_send_ipi_single(int cpu, unsigned int action);
-void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action);
#ifdef CONFIG_HOTPLUG_CPU
int loongson_cpu_disable(void);
void loongson_cpu_die(unsigned int cpu);
@@ -59,9 +66,14 @@ extern int __cpu_logical_map[NR_CPUS];
#define cpu_physical_id(cpu) cpu_logical_map(cpu)
-#define SMP_BOOT_CPU 0x1
-#define SMP_RESCHEDULE 0x2
-#define SMP_CALL_FUNCTION 0x4
+#define ACTION_BOOT_CPU 0
+#define ACTION_RESCHEDULE 1
+#define ACTION_CALL_FUNCTION 2
+#define ACTION_IRQ_WORK 3
+#define SMP_BOOT_CPU BIT(ACTION_BOOT_CPU)
+#define SMP_RESCHEDULE BIT(ACTION_RESCHEDULE)
+#define SMP_CALL_FUNCTION BIT(ACTION_CALL_FUNCTION)
+#define SMP_IRQ_WORK BIT(ACTION_IRQ_WORK)
struct secondary_data {
unsigned long stack;
@@ -81,12 +93,12 @@ extern void show_ipi_list(struct seq_file *p, int prec);
static inline void arch_send_call_function_single_ipi(int cpu)
{
- loongson_send_ipi_single(cpu, SMP_CALL_FUNCTION);
+ mp_ops.send_ipi_single(cpu, ACTION_CALL_FUNCTION);
}
static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
- loongson_send_ipi_mask(mask, SMP_CALL_FUNCTION);
+ mp_ops.send_ipi_mask(mask, ACTION_CALL_FUNCTION);
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -101,4 +113,8 @@ static inline void __cpu_die(unsigned int cpu)
}
#endif
+#else /* !CONFIG_SMP */
+#define cpu_logical_map(cpu) 0
+#endif /* CONFIG_SMP */
+
#endif /* __ASM_SMP_H */
diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h
index 45b507a7b06f..66736837085b 100644
--- a/arch/loongarch/include/asm/stackframe.h
+++ b/arch/loongarch/include/asm/stackframe.h
@@ -38,11 +38,22 @@
cfi_restore \reg \offset \docfi
.endm
+ .macro SETUP_DMWINS temp
+ li.d \temp, CSR_DMW0_INIT # WUC, PLV0, 0x8000 xxxx xxxx xxxx
+ csrwr \temp, LOONGARCH_CSR_DMWIN0
+ li.d \temp, CSR_DMW1_INIT # CAC, PLV0, 0x9000 xxxx xxxx xxxx
+ csrwr \temp, LOONGARCH_CSR_DMWIN1
+ li.d \temp, CSR_DMW2_INIT # WUC, PLV0, 0xa000 xxxx xxxx xxxx
+ csrwr \temp, LOONGARCH_CSR_DMWIN2
+ li.d \temp, CSR_DMW3_INIT # 0x0, unused
+ csrwr \temp, LOONGARCH_CSR_DMWIN3
+ .endm
+
/* Jump to the runtime virtual address. */
.macro JUMP_VIRT_ADDR temp1 temp2
li.d \temp1, CACHE_BASE
pcaddi \temp2, 0
- or \temp1, \temp1, \temp2
+ bstrins.d \temp1, \temp2, (DMW_PABITS - 1), 0
jirl zero, \temp1, 0xc
.endm
diff --git a/arch/loongarch/include/asm/unistd.h b/arch/loongarch/include/asm/unistd.h
index cfddb0116a8c..e2c0f3d86c7b 100644
--- a/arch/loongarch/include/asm/unistd.h
+++ b/arch/loongarch/include/asm/unistd.h
@@ -8,4 +8,7 @@
#include <uapi/asm/unistd.h>
+#define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SYS_CLONE
+
#define NR_syscalls (__NR_syscalls)
diff --git a/arch/loongarch/include/asm/uprobes.h b/arch/loongarch/include/asm/uprobes.h
index c8f59983f702..99a0d198927f 100644
--- a/arch/loongarch/include/asm/uprobes.h
+++ b/arch/loongarch/include/asm/uprobes.h
@@ -9,10 +9,10 @@ typedef u32 uprobe_opcode_t;
#define MAX_UINSN_BYTES 8
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES
-#define UPROBE_SWBP_INSN larch_insn_gen_break(BRK_UPROBE_BP)
+#define UPROBE_SWBP_INSN __emit_break(BRK_UPROBE_BP)
#define UPROBE_SWBP_INSN_SIZE LOONGARCH_INSN_SIZE
-#define UPROBE_XOLBP_INSN larch_insn_gen_break(BRK_UPROBE_XOLBP)
+#define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP)
struct arch_uprobe {
unsigned long resume_era;
diff --git a/arch/loongarch/include/asm/fb.h b/arch/loongarch/include/asm/video.h
index 0b218b10a9ec..9f76845f2d4f 100644
--- a/arch/loongarch/include/asm/fb.h
+++ b/arch/loongarch/include/asm/video.h
@@ -2,8 +2,8 @@
/*
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
*/
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
#include <linux/compiler.h>
#include <linux/string.h>
@@ -26,6 +26,6 @@ static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
}
#define fb_memset fb_memset_io
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/loongarch/include/uapi/asm/Kbuild b/arch/loongarch/include/uapi/asm/Kbuild
index 4aa680ca2e5f..c6d141d7b7d7 100644
--- a/arch/loongarch/include/uapi/asm/Kbuild
+++ b/arch/loongarch/include/uapi/asm/Kbuild
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_64.h
+
generic-y += kvm_para.h
diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
index 109785922cf9..ddc5cab0ffd0 100644
--- a/arch/loongarch/include/uapi/asm/kvm.h
+++ b/arch/loongarch/include/uapi/asm/kvm.h
@@ -17,6 +17,8 @@
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
+#define KVM_GUESTDBG_USE_SW_BP 0x00010000
+
/*
* for KVM_GET_REGS and KVM_SET_REGS
*/
@@ -72,12 +74,18 @@ struct kvm_fpu {
#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1)
#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2)
+/* Debugging: Special instruction for software breakpoint */
+#define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3)
#define LOONGARCH_REG_SHIFT 3
#define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT))
#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
+
+/* Device Control API on vcpu fd */
#define KVM_LOONGARCH_VCPU_CPUCFG 0
+#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1
+#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0
struct kvm_debug_exit_arch {
};
diff --git a/arch/loongarch/include/uapi/asm/unistd.h b/arch/loongarch/include/uapi/asm/unistd.h
index fcb668984f03..1f01980f9c94 100644
--- a/arch/loongarch/include/uapi/asm/unistd.h
+++ b/arch/loongarch/include/uapi/asm/unistd.h
@@ -1,5 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
-#include <asm-generic/unistd.h>
+#include <asm/unistd_64.h>
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index 3a7620b66bc6..c9bfeda89e40 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_MODULES) += module.o module-sections.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PROC_FS) += proc.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o
obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/s390/lib/expoline/Makefile b/arch/loongarch/kernel/Makefile.syscalls
index 854631d9cb03..523bb411a3bc 100644
--- a/arch/s390/lib/expoline/Makefile
+++ b/arch/loongarch/kernel/Makefile.syscalls
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-obj-y += expoline.o
+syscall_abis_64 += newstat
diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c
index 5cf59c617126..929a497c987e 100644
--- a/arch/loongarch/kernel/acpi.c
+++ b/arch/loongarch/kernel/acpi.c
@@ -57,15 +57,22 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
return ioremap_cache(phys, size);
}
+static int cpu_enumerated = 0;
+
#ifdef CONFIG_SMP
static int set_processor_mask(u32 id, u32 flags)
{
-
+ int nr_cpus;
int cpu, cpuid = id;
- if (num_processors >= nr_cpu_ids) {
- pr_warn(PREFIX "nr_cpus/possible_cpus limit of %i reached."
- " processor 0x%x ignored.\n", nr_cpu_ids, cpuid);
+ if (!cpu_enumerated)
+ nr_cpus = NR_CPUS;
+ else
+ nr_cpus = nr_cpu_ids;
+
+ if (num_processors >= nr_cpus) {
+ pr_warn(PREFIX "nr_cpus limit of %i reached."
+ " processor 0x%x ignored.\n", nr_cpus, cpuid);
return -ENODEV;
@@ -73,11 +80,13 @@ static int set_processor_mask(u32 id, u32 flags)
if (cpuid == loongson_sysconf.boot_cpu_id)
cpu = 0;
else
- cpu = cpumask_next_zero(-1, cpu_present_mask);
+ cpu = find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS);
+
+ if (!cpu_enumerated)
+ set_cpu_possible(cpu, true);
if (flags & ACPI_MADT_ENABLED) {
num_processors++;
- set_cpu_possible(cpu, true);
set_cpu_present(cpu, true);
__cpu_number_map[cpuid] = cpu;
__cpu_logical_map[cpu] = cpuid;
@@ -138,6 +147,7 @@ static void __init acpi_process_madt(void)
acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC,
acpi_parse_eio_master, MAX_IO_PICS);
+ cpu_enumerated = 1;
loongson_sysconf.nr_cpus = num_processors;
}
diff --git a/arch/loongarch/kernel/dma.c b/arch/loongarch/kernel/dma.c
index 7a9c6a9dd2d0..429555fb4e13 100644
--- a/arch/loongarch/kernel/dma.c
+++ b/arch/loongarch/kernel/dma.c
@@ -8,17 +8,12 @@
void acpi_arch_dma_setup(struct device *dev)
{
int ret;
- u64 mask, end = 0;
+ u64 mask, end;
const struct bus_dma_region *map = NULL;
ret = acpi_dma_get_range(dev, &map);
if (!ret && map) {
- const struct bus_dma_region *r = map;
-
- for (end = 0; r->size; r++) {
- if (r->dma_start + r->size - 1 > end)
- end = r->dma_start + r->size - 1;
- }
+ end = dma_range_map_max(map);
mask = DMA_BIT_MASK(ilog2(end) + 1);
dev->bus_dma_limit = end;
diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftrace_dyn.c
index 73858c9029cc..bff058317062 100644
--- a/arch/loongarch/kernel/ftrace_dyn.c
+++ b/arch/loongarch/kernel/ftrace_dyn.c
@@ -287,6 +287,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe *p;
struct kprobe_ctlblk *kcb;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index c4f7de2e2805..506a99a5bbc7 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -22,7 +22,7 @@
_head:
.word MZ_MAGIC /* "MZ", MS-DOS header */
.org 0x8
- .dword kernel_entry /* Kernel entry point */
+ .dword _kernel_entry /* Kernel entry point (physical address) */
.dword _kernel_asize /* Kernel image effective size */
.quad PHYS_LINK_KADDR /* Kernel image load offset from start of RAM */
.org 0x38 /* 0x20 ~ 0x37 reserved */
@@ -44,11 +44,7 @@ SYM_DATA(kernel_fsize, .long _kernel_fsize);
SYM_CODE_START(kernel_entry) # kernel entry point
/* Config direct window and set PG */
- li.d t0, CSR_DMW0_INIT # UC, PLV0, 0x8000 xxxx xxxx xxxx
- csrwr t0, LOONGARCH_CSR_DMWIN0
- li.d t0, CSR_DMW1_INIT # CA, PLV0, 0x9000 xxxx xxxx xxxx
- csrwr t0, LOONGARCH_CSR_DMWIN1
-
+ SETUP_DMWINS t0
JUMP_VIRT_ADDR t0, t1
/* Enable PG */
@@ -124,11 +120,8 @@ SYM_CODE_END(kernel_entry)
* function after setting up the stack and tp registers.
*/
SYM_CODE_START(smpboot_entry)
- li.d t0, CSR_DMW0_INIT # UC, PLV0
- csrwr t0, LOONGARCH_CSR_DMWIN0
- li.d t0, CSR_DMW1_INIT # CA, PLV0
- csrwr t0, LOONGARCH_CSR_DMWIN1
+ SETUP_DMWINS t0
JUMP_VIRT_ADDR t0, t1
#ifdef CONFIG_PAGE_SIZE_4KB
diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/hw_breakpoint.c
index fc55c4de2a11..a6e4b605bfa8 100644
--- a/arch/loongarch/kernel/hw_breakpoint.c
+++ b/arch/loongarch/kernel/hw_breakpoint.c
@@ -174,11 +174,21 @@ void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
static int hw_breakpoint_control(struct perf_event *bp,
enum hw_breakpoint_ops ops)
{
- u32 ctrl;
+ u32 ctrl, privilege;
int i, max_slots, enable;
+ struct pt_regs *regs;
struct perf_event **slots;
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ if (arch_check_bp_in_kernelspace(info))
+ privilege = CTRL_PLV0_ENABLE;
+ else
+ privilege = CTRL_PLV3_ENABLE;
+
+ /* Whether bp belongs to a task. */
+ if (bp->hw.target)
+ regs = task_pt_regs(bp->hw.target);
+
if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
/* Breakpoint */
slots = this_cpu_ptr(bp_on_reg);
@@ -197,31 +207,38 @@ static int hw_breakpoint_control(struct perf_event *bp,
switch (ops) {
case HW_BREAKPOINT_INSTALL:
/* Set the FWPnCFG/MWPnCFG 1~4 register. */
- write_wb_reg(CSR_CFG_ADDR, i, 0, info->address);
- write_wb_reg(CSR_CFG_ADDR, i, 1, info->address);
- write_wb_reg(CSR_CFG_MASK, i, 0, info->mask);
- write_wb_reg(CSR_CFG_MASK, i, 1, info->mask);
- write_wb_reg(CSR_CFG_ASID, i, 0, 0);
- write_wb_reg(CSR_CFG_ASID, i, 1, 0);
if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
- write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE);
+ write_wb_reg(CSR_CFG_ADDR, i, 0, info->address);
+ write_wb_reg(CSR_CFG_MASK, i, 0, info->mask);
+ write_wb_reg(CSR_CFG_ASID, i, 0, 0);
+ write_wb_reg(CSR_CFG_CTRL, i, 0, privilege);
} else {
+ write_wb_reg(CSR_CFG_ADDR, i, 1, info->address);
+ write_wb_reg(CSR_CFG_MASK, i, 1, info->mask);
+ write_wb_reg(CSR_CFG_ASID, i, 1, 0);
ctrl = encode_ctrl_reg(info->ctrl);
- write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | CTRL_PLV_ENABLE);
+ write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | privilege);
}
enable = csr_read64(LOONGARCH_CSR_CRMD);
csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD);
+ if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH))
+ regs->csr_prmd |= CSR_PRMD_PWE;
break;
case HW_BREAKPOINT_UNINSTALL:
/* Reset the FWPnCFG/MWPnCFG 1~4 register. */
- write_wb_reg(CSR_CFG_ADDR, i, 0, 0);
- write_wb_reg(CSR_CFG_ADDR, i, 1, 0);
- write_wb_reg(CSR_CFG_MASK, i, 0, 0);
- write_wb_reg(CSR_CFG_MASK, i, 1, 0);
- write_wb_reg(CSR_CFG_CTRL, i, 0, 0);
- write_wb_reg(CSR_CFG_CTRL, i, 1, 0);
- write_wb_reg(CSR_CFG_ASID, i, 0, 0);
- write_wb_reg(CSR_CFG_ASID, i, 1, 0);
+ if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
+ write_wb_reg(CSR_CFG_ADDR, i, 0, 0);
+ write_wb_reg(CSR_CFG_MASK, i, 0, 0);
+ write_wb_reg(CSR_CFG_CTRL, i, 0, 0);
+ write_wb_reg(CSR_CFG_ASID, i, 0, 0);
+ } else {
+ write_wb_reg(CSR_CFG_ADDR, i, 1, 0);
+ write_wb_reg(CSR_CFG_MASK, i, 1, 0);
+ write_wb_reg(CSR_CFG_CTRL, i, 1, 0);
+ write_wb_reg(CSR_CFG_ASID, i, 1, 0);
+ }
+ if (bp->hw.target)
+ regs->csr_prmd &= ~CSR_PRMD_PWE;
break;
}
@@ -283,7 +300,7 @@ int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
* to generic breakpoint descriptions.
*/
int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
- int *gen_len, int *gen_type, int *offset)
+ int *gen_len, int *gen_type)
{
/* Type */
switch (ctrl.type) {
@@ -303,11 +320,6 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
return -EINVAL;
}
- if (!ctrl.len)
- return -EINVAL;
-
- *offset = __ffs(ctrl.len);
-
/* Len */
switch (ctrl.len) {
case LOONGARCH_BREAKPOINT_LEN_1:
@@ -386,21 +398,17 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
struct arch_hw_breakpoint *hw)
{
int ret;
- u64 alignment_mask, offset;
+ u64 alignment_mask;
/* Build the arch_hw_breakpoint. */
ret = arch_build_bp_info(bp, attr, hw);
if (ret)
return ret;
- if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE)
- alignment_mask = 0x7;
- else
+ if (hw->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
alignment_mask = 0x3;
- offset = hw->address & alignment_mask;
-
- hw->address &= ~alignment_mask;
- hw->ctrl.len <<= offset;
+ hw->address &= ~alignment_mask;
+ }
return 0;
}
@@ -471,12 +479,15 @@ void breakpoint_handler(struct pt_regs *regs)
slots = this_cpu_ptr(bp_on_reg);
for (i = 0; i < boot_cpu_data.watch_ireg_count; ++i) {
- bp = slots[i];
- if (bp == NULL)
- continue;
- perf_bp_event(bp, regs);
+ if ((csr_read32(LOONGARCH_CSR_FWPS) & (0x1 << i))) {
+ bp = slots[i];
+ if (bp == NULL)
+ continue;
+ perf_bp_event(bp, regs);
+ csr_write32(0x1 << i, LOONGARCH_CSR_FWPS);
+ update_bp_registers(regs, 0, 0);
+ }
}
- update_bp_registers(regs, 0, 0);
}
NOKPROBE_SYMBOL(breakpoint_handler);
@@ -488,12 +499,15 @@ void watchpoint_handler(struct pt_regs *regs)
slots = this_cpu_ptr(wp_on_reg);
for (i = 0; i < boot_cpu_data.watch_dreg_count; ++i) {
- wp = slots[i];
- if (wp == NULL)
- continue;
- perf_bp_event(wp, regs);
+ if ((csr_read32(LOONGARCH_CSR_MWPS) & (0x1 << i))) {
+ wp = slots[i];
+ if (wp == NULL)
+ continue;
+ perf_bp_event(wp, regs);
+ csr_write32(0x1 << i, LOONGARCH_CSR_MWPS);
+ update_bp_registers(regs, 0, 1);
+ }
}
- update_bp_registers(regs, 0, 1);
}
NOKPROBE_SYMBOL(watchpoint_handler);
diff --git a/arch/loongarch/kernel/irq.c b/arch/loongarch/kernel/irq.c
index 883e5066ae44..f4991c03514f 100644
--- a/arch/loongarch/kernel/irq.c
+++ b/arch/loongarch/kernel/irq.c
@@ -87,23 +87,9 @@ static void __init init_vec_parent_group(void)
acpi_table_parse(ACPI_SIG_MCFG, early_pci_mcfg_parse);
}
-static int __init get_ipi_irq(void)
-{
- struct irq_domain *d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY);
-
- if (d)
- return irq_create_mapping(d, INT_IPI);
-
- return -EINVAL;
-}
-
void __init init_IRQ(void)
{
int i;
-#ifdef CONFIG_SMP
- int r, ipi_irq;
- static int ipi_dummy_dev;
-#endif
unsigned int order = get_order(IRQ_STACK_SIZE);
struct page *page;
@@ -113,13 +99,7 @@ void __init init_IRQ(void)
init_vec_parent_group();
irqchip_init();
#ifdef CONFIG_SMP
- ipi_irq = get_ipi_irq();
- if (ipi_irq < 0)
- panic("IPI IRQ mapping failed\n");
- irq_set_percpu_devid(ipi_irq);
- r = request_percpu_irq(ipi_irq, loongson_ipi_interrupt, "IPI", &ipi_dummy_dev);
- if (r < 0)
- panic("IPI IRQ request failed\n");
+ mp_ops.init_ipi();
#endif
for (i = 0; i < NR_IRQS; i++)
@@ -133,5 +113,5 @@ void __init init_IRQ(void)
per_cpu(irq_stack, i), per_cpu(irq_stack, i) + IRQ_STACK_SIZE);
}
- set_csr_ecfg(ECFGF_IP0 | ECFGF_IP1 | ECFGF_IP2 | ECFGF_IPI | ECFGF_PMC);
+ set_csr_ecfg(ECFGF_SIP0 | ECFGF_IP0 | ECFGF_IP1 | ECFGF_IP2 | ECFGF_IPI | ECFGF_PMC);
}
diff --git a/arch/loongarch/kernel/kprobes.c b/arch/loongarch/kernel/kprobes.c
index 17b040bd6067..8ba391cfabb0 100644
--- a/arch/loongarch/kernel/kprobes.c
+++ b/arch/loongarch/kernel/kprobes.c
@@ -4,8 +4,8 @@
#include <linux/preempt.h>
#include <asm/break.h>
-#define KPROBE_BP_INSN larch_insn_gen_break(BRK_KPROBE_BP)
-#define KPROBE_SSTEPBP_INSN larch_insn_gen_break(BRK_KPROBE_SSTEPBP)
+#define KPROBE_BP_INSN __emit_break(BRK_KPROBE_BP)
+#define KPROBE_SSTEPBP_INSN __emit_break(BRK_KPROBE_SSTEPBP)
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
index 2dcb9e003657..8ae641dc53bb 100644
--- a/arch/loongarch/kernel/machine_kexec.c
+++ b/arch/loongarch/kernel/machine_kexec.c
@@ -225,6 +225,7 @@ void crash_smp_send_stop(void)
void machine_shutdown(void)
{
+#ifdef CONFIG_SMP
int cpu;
/* All CPUs go to reboot_code_buffer */
@@ -232,7 +233,6 @@ void machine_shutdown(void)
if (!cpu_online(cpu))
cpu_device_up(get_cpu_device(cpu));
-#ifdef CONFIG_SMP
smp_call_function(kexec_shutdown_secondary, NULL, 0);
#endif
}
diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
index c7d0338d12c1..36d6d9eeb7c7 100644
--- a/arch/loongarch/kernel/module.c
+++ b/arch/loongarch/kernel/module.c
@@ -490,12 +490,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
return 0;
}
-void *module_alloc(unsigned long size)
-{
- return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, __builtin_return_address(0));
-}
-
static void module_init_ftrace_plt(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *mod)
{
diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
new file mode 100644
index 000000000000..9c9b75b76f62
--- /dev/null
+++ b/arch/loongarch/kernel/paravirt.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq_work.h>
+#include <linux/jump_label.h>
+#include <linux/kvm_para.h>
+#include <linux/reboot.h>
+#include <linux/static_call.h>
+#include <asm/paravirt.h>
+
+static int has_steal_clock;
+struct static_key paravirt_steal_enabled;
+struct static_key paravirt_steal_rq_enabled;
+static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
+
+static u64 native_steal_clock(int cpu)
+{
+ return 0;
+}
+
+DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock);
+
+static bool steal_acc = true;
+
+static int __init parse_no_stealacc(char *arg)
+{
+ steal_acc = false;
+ return 0;
+}
+early_param("no-steal-acc", parse_no_stealacc);
+
+static u64 paravt_steal_clock(int cpu)
+{
+ int version;
+ u64 steal;
+ struct kvm_steal_time *src;
+
+ src = &per_cpu(steal_time, cpu);
+ do {
+
+ version = src->version;
+ virt_rmb(); /* Make sure that the version is read before the steal */
+ steal = src->steal;
+ virt_rmb(); /* Make sure that the steal is read before the next version */
+
+ } while ((version & 1) || (version != src->version));
+
+ return steal;
+}
+
+#ifdef CONFIG_SMP
+static void pv_send_ipi_single(int cpu, unsigned int action)
+{
+ int min, old;
+ irq_cpustat_t *info = &per_cpu(irq_stat, cpu);
+
+ old = atomic_fetch_or(BIT(action), &info->message);
+ if (old)
+ return;
+
+ min = cpu_logical_map(cpu);
+ kvm_hypercall3(KVM_HCALL_FUNC_IPI, 1, 0, min);
+}
+
+#define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG)
+
+static void pv_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ int i, cpu, min = 0, max = 0, old;
+ __uint128_t bitmap = 0;
+ irq_cpustat_t *info;
+
+ if (cpumask_empty(mask))
+ return;
+
+ action = BIT(action);
+ for_each_cpu(i, mask) {
+ info = &per_cpu(irq_stat, i);
+ old = atomic_fetch_or(action, &info->message);
+ if (old)
+ continue;
+
+ cpu = cpu_logical_map(i);
+ if (!bitmap) {
+ min = max = cpu;
+ } else if (cpu < min && cpu > (max - KVM_IPI_CLUSTER_SIZE)) {
+ /* cpu < min, and bitmap still enough */
+ bitmap <<= min - cpu;
+ min = cpu;
+ } else if (cpu > min && cpu < (min + KVM_IPI_CLUSTER_SIZE)) {
+ /* cpu > min, and bitmap still enough */
+ max = cpu > max ? cpu : max;
+ } else {
+ /*
+ * With cpu, bitmap will exceed KVM_IPI_CLUSTER_SIZE,
+ * send IPI here directly and skip the remaining CPUs.
+ */
+ kvm_hypercall3(KVM_HCALL_FUNC_IPI, (unsigned long)bitmap,
+ (unsigned long)(bitmap >> BITS_PER_LONG), min);
+ min = max = cpu;
+ bitmap = 0;
+ }
+ __set_bit(cpu - min, (unsigned long *)&bitmap);
+ }
+
+ if (bitmap)
+ kvm_hypercall3(KVM_HCALL_FUNC_IPI, (unsigned long)bitmap,
+ (unsigned long)(bitmap >> BITS_PER_LONG), min);
+}
+
+static irqreturn_t pv_ipi_interrupt(int irq, void *dev)
+{
+ u32 action;
+ irq_cpustat_t *info;
+
+ /* Clear SWI interrupt */
+ clear_csr_estat(1 << INT_SWI0);
+ info = this_cpu_ptr(&irq_stat);
+ action = atomic_xchg(&info->message, 0);
+
+ if (action & SMP_RESCHEDULE) {
+ scheduler_ipi();
+ info->ipi_irqs[IPI_RESCHEDULE]++;
+ }
+
+ if (action & SMP_CALL_FUNCTION) {
+ generic_smp_call_function_interrupt();
+ info->ipi_irqs[IPI_CALL_FUNCTION]++;
+ }
+
+ if (action & SMP_IRQ_WORK) {
+ irq_work_run();
+ info->ipi_irqs[IPI_IRQ_WORK]++;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void pv_init_ipi(void)
+{
+ int r, swi;
+
+ swi = get_percpu_irq(INT_SWI0);
+ if (swi < 0)
+ panic("SWI0 IRQ mapping failed\n");
+ irq_set_percpu_devid(swi);
+ r = request_percpu_irq(swi, pv_ipi_interrupt, "SWI0-IPI", &irq_stat);
+ if (r < 0)
+ panic("SWI0 IRQ request failed\n");
+}
+#endif
+
+static bool kvm_para_available(void)
+{
+ int config;
+ static int hypervisor_type;
+
+ if (!hypervisor_type) {
+ config = read_cpucfg(CPUCFG_KVM_SIG);
+ if (!memcmp(&config, KVM_SIGNATURE, 4))
+ hypervisor_type = HYPERVISOR_KVM;
+ }
+
+ return hypervisor_type == HYPERVISOR_KVM;
+}
+
+int __init pv_ipi_init(void)
+{
+ int feature;
+
+ if (!cpu_has_hypervisor)
+ return 0;
+ if (!kvm_para_available())
+ return 0;
+
+ feature = read_cpucfg(CPUCFG_KVM_FEATURE);
+ if (!(feature & KVM_FEATURE_IPI))
+ return 0;
+
+#ifdef CONFIG_SMP
+ mp_ops.init_ipi = pv_init_ipi;
+ mp_ops.send_ipi_single = pv_send_ipi_single;
+ mp_ops.send_ipi_mask = pv_send_ipi_mask;
+#endif
+
+ return 0;
+}
+
+static int pv_enable_steal_time(void)
+{
+ int cpu = smp_processor_id();
+ unsigned long addr;
+ struct kvm_steal_time *st;
+
+ if (!has_steal_clock)
+ return -EPERM;
+
+ st = &per_cpu(steal_time, cpu);
+ addr = per_cpu_ptr_to_phys(st);
+
+ /* The whole structure kvm_steal_time should be in one page */
+ if (PFN_DOWN(addr) != PFN_DOWN(addr + sizeof(*st))) {
+ pr_warn("Illegal PV steal time addr %lx\n", addr);
+ return -EFAULT;
+ }
+
+ addr |= KVM_STEAL_PHYS_VALID;
+ kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, KVM_FEATURE_STEAL_TIME, addr);
+
+ return 0;
+}
+
+static void pv_disable_steal_time(void)
+{
+ if (has_steal_clock)
+ kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, KVM_FEATURE_STEAL_TIME, 0);
+}
+
+#ifdef CONFIG_SMP
+static int pv_time_cpu_online(unsigned int cpu)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ pv_enable_steal_time();
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static int pv_time_cpu_down_prepare(unsigned int cpu)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ pv_disable_steal_time();
+ local_irq_restore(flags);
+
+ return 0;
+}
+#endif
+
+static void pv_cpu_reboot(void *unused)
+{
+ pv_disable_steal_time();
+}
+
+static int pv_reboot_notify(struct notifier_block *nb, unsigned long code, void *unused)
+{
+ on_each_cpu(pv_cpu_reboot, NULL, 1);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block pv_reboot_nb = {
+ .notifier_call = pv_reboot_notify,
+};
+
+int __init pv_time_init(void)
+{
+ int r, feature;
+
+ if (!cpu_has_hypervisor)
+ return 0;
+ if (!kvm_para_available())
+ return 0;
+
+ feature = read_cpucfg(CPUCFG_KVM_FEATURE);
+ if (!(feature & KVM_FEATURE_STEAL_TIME))
+ return 0;
+
+ has_steal_clock = 1;
+ r = pv_enable_steal_time();
+ if (r < 0) {
+ has_steal_clock = 0;
+ return 0;
+ }
+ register_reboot_notifier(&pv_reboot_nb);
+
+#ifdef CONFIG_SMP
+ r = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+ "loongarch/pv_time:online",
+ pv_time_cpu_online, pv_time_cpu_down_prepare);
+ if (r < 0) {
+ has_steal_clock = 0;
+ pr_err("Failed to install cpu hotplug callbacks\n");
+ return r;
+ }
+#endif
+
+ static_call_update(pv_steal_clock, paravt_steal_clock);
+
+ static_key_slow_inc(&paravirt_steal_enabled);
+#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
+ if (steal_acc)
+ static_key_slow_inc(&paravirt_steal_rq_enabled);
+#endif
+
+ pr_info("Using paravirt steal-time\n");
+
+ return 0;
+}
diff --git a/arch/loongarch/kernel/perf_event.c b/arch/loongarch/kernel/perf_event.c
index cac7cba81b65..f86a4b838dd7 100644
--- a/arch/loongarch/kernel/perf_event.c
+++ b/arch/loongarch/kernel/perf_event.c
@@ -456,16 +456,6 @@ static void loongarch_pmu_disable(struct pmu *pmu)
static DEFINE_MUTEX(pmu_reserve_mutex);
static atomic_t active_events = ATOMIC_INIT(0);
-static int get_pmc_irq(void)
-{
- struct irq_domain *d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY);
-
- if (d)
- return irq_create_mapping(d, INT_PCOV);
-
- return -EINVAL;
-}
-
static void reset_counters(void *arg);
static int __hw_perf_event_init(struct perf_event *event);
@@ -473,7 +463,7 @@ static void hw_perf_event_destroy(struct perf_event *event)
{
if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) {
on_each_cpu(reset_counters, NULL, 1);
- free_irq(get_pmc_irq(), &loongarch_pmu);
+ free_irq(get_percpu_irq(INT_PCOV), &loongarch_pmu);
mutex_unlock(&pmu_reserve_mutex);
}
}
@@ -562,7 +552,7 @@ static int loongarch_pmu_event_init(struct perf_event *event)
if (event->cpu >= 0 && !cpu_online(event->cpu))
return -ENODEV;
- irq = get_pmc_irq();
+ irq = get_percpu_irq(INT_PCOV);
flags = IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_NO_SUSPEND | IRQF_SHARED;
if (!atomic_inc_not_zero(&active_events)) {
mutex_lock(&pmu_reserve_mutex);
diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c
index c114c5ef1332..19dc6eff45cc 100644
--- a/arch/loongarch/kernel/ptrace.c
+++ b/arch/loongarch/kernel/ptrace.c
@@ -494,28 +494,14 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
struct arch_hw_breakpoint_ctrl ctrl,
struct perf_event_attr *attr)
{
- int err, len, type, offset;
+ int err, len, type;
- err = arch_bp_generic_fields(ctrl, &len, &type, &offset);
+ err = arch_bp_generic_fields(ctrl, &len, &type);
if (err)
return err;
- switch (note_type) {
- case NT_LOONGARCH_HW_BREAK:
- if ((type & HW_BREAKPOINT_X) != type)
- return -EINVAL;
- break;
- case NT_LOONGARCH_HW_WATCH:
- if ((type & HW_BREAKPOINT_RW) != type)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
attr->bp_len = len;
attr->bp_type = type;
- attr->bp_addr += offset;
return 0;
}
@@ -603,16 +589,36 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type,
struct perf_event *bp;
struct perf_event_attr attr;
struct arch_hw_breakpoint_ctrl ctrl;
+ struct thread_info *ti = task_thread_info(tsk);
bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
if (IS_ERR(bp))
return PTR_ERR(bp);
attr = bp->attr;
- decode_ctrl_reg(uctrl, &ctrl);
- err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr);
- if (err)
- return err;
+
+ switch (note_type) {
+ case NT_LOONGARCH_HW_BREAK:
+ ctrl.type = LOONGARCH_BREAKPOINT_EXECUTE;
+ ctrl.len = LOONGARCH_BREAKPOINT_LEN_4;
+ break;
+ case NT_LOONGARCH_HW_WATCH:
+ decode_ctrl_reg(uctrl, &ctrl);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (uctrl & CTRL_PLV_ENABLE) {
+ err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr);
+ if (err)
+ return err;
+ attr.disabled = 0;
+ set_ti_thread_flag(ti, TIF_LOAD_WATCH);
+ } else {
+ attr.disabled = 1;
+ clear_ti_thread_flag(ti, TIF_LOAD_WATCH);
+ }
return modify_user_hw_breakpoint(bp, &attr);
}
@@ -643,6 +649,10 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
struct perf_event *bp;
struct perf_event_attr attr;
+ /* Kernel-space address cannot be monitored by user-space */
+ if ((unsigned long)addr >= XKPRANGE)
+ return -EINVAL;
+
bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
if (IS_ERR(bp))
return PTR_ERR(bp);
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index 1acfa704c8d0..50c469067f3a 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -13,6 +13,7 @@
#include <asm/bootinfo.h>
#include <asm/early_ioremap.h>
#include <asm/inst.h>
+#include <asm/io.h>
#include <asm/sections.h>
#include <asm/setup.h>
@@ -34,11 +35,27 @@ static inline void __init relocate_relative(void)
if (rela->r_info != R_LARCH_RELATIVE)
continue;
- if (relocated_addr >= VMLINUX_LOAD_ADDRESS)
- relocated_addr = (Elf64_Addr)RELOCATED(relocated_addr);
-
+ relocated_addr = (Elf64_Addr)RELOCATED(relocated_addr);
*(Elf64_Addr *)RELOCATED(addr) = relocated_addr;
}
+
+#ifdef CONFIG_RELR
+ u64 *addr = NULL;
+ u64 *relr = (u64 *)&__relr_dyn_begin;
+ u64 *relr_end = (u64 *)&__relr_dyn_end;
+
+ for ( ; relr < relr_end; relr++) {
+ if ((*relr & 1) == 0) {
+ addr = (u64 *)(*relr + reloc_offset);
+ *addr++ += reloc_offset;
+ } else {
+ for (u64 *p = addr, r = *relr >> 1; r; p++, r >>= 1)
+ if (r & 1)
+ *p += reloc_offset;
+ addr += 63;
+ }
+ }
+#endif
}
static inline void __init relocate_absolute(long random_offset)
@@ -123,6 +140,32 @@ static inline __init bool kaslr_disabled(void)
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
return true;
+#ifdef CONFIG_HIBERNATION
+ str = strstr(builtin_cmdline, "nohibernate");
+ if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
+ return false;
+
+ str = strstr(boot_command_line, "nohibernate");
+ if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
+ return false;
+
+ str = strstr(builtin_cmdline, "noresume");
+ if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
+ return false;
+
+ str = strstr(boot_command_line, "noresume");
+ if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
+ return false;
+
+ str = strstr(builtin_cmdline, "resume=");
+ if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
+ return true;
+
+ str = strstr(boot_command_line, "resume=");
+ if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
+ return true;
+#endif
+
return false;
}
@@ -170,7 +213,7 @@ unsigned long __init relocate_kernel(void)
unsigned long kernel_length;
unsigned long random_offset = 0;
void *location_new = _text; /* Default to original kernel start */
- char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
+ char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
@@ -182,6 +225,7 @@ unsigned long __init relocate_kernel(void)
random_offset = (unsigned long)location_new - (unsigned long)(_text);
#endif
reloc_offset = (unsigned long)_text - VMLINUX_LOAD_ADDRESS;
+ early_memunmap(cmdline, COMMAND_LINE_SIZE);
if (random_offset) {
kernel_length = (long)(_end) - (long)(_text);
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index 60e0fe97f61a..0f0740f0be27 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -282,7 +282,7 @@ static void __init fdt_setup(void)
return;
/* Prefer to use built-in dtb, checking its legality first. */
- if (!fdt_check_header(__dtb_start))
+ if (IS_ENABLED(CONFIG_BUILTIN_DTB) && !fdt_check_header(__dtb_start))
fdt_pointer = __dtb_start;
else
fdt_pointer = efi_fdt_pointer(); /* Fallback to firmware dtb */
@@ -351,10 +351,8 @@ void __init platform_init(void)
arch_reserve_vmcore();
arch_reserve_crashkernel();
-#ifdef CONFIG_ACPI_TABLE_UPGRADE
- acpi_table_upgrade();
-#endif
#ifdef CONFIG_ACPI
+ acpi_table_upgrade();
acpi_gbl_use_default_register_widths = false;
acpi_boot_table_init();
#endif
@@ -578,8 +576,10 @@ static void __init prefill_possible_map(void)
for (i = 0; i < possible; i++)
set_cpu_possible(i, true);
- for (; i < NR_CPUS; i++)
+ for (; i < NR_CPUS; i++) {
+ set_cpu_present(i, false);
set_cpu_possible(i, false);
+ }
set_nr_cpu_ids(possible);
}
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index aabee0b280fe..ca405ab86aae 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -13,6 +13,7 @@
#include <linux/cpumask.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq_work.h>
#include <linux/profile.h>
#include <linux/seq_file.h>
#include <linux/smp.h>
@@ -29,6 +30,7 @@
#include <asm/loongson.h>
#include <asm/mmu_context.h>
#include <asm/numa.h>
+#include <asm/paravirt.h>
#include <asm/processor.h>
#include <asm/setup.h>
#include <asm/time.h>
@@ -66,14 +68,10 @@ static cpumask_t cpu_core_setup_map;
struct secondary_data cpuboot_data;
static DEFINE_PER_CPU(int, cpu_state);
-enum ipi_msg_type {
- IPI_RESCHEDULE,
- IPI_CALL_FUNCTION,
-};
-
static const char *ipi_types[NR_IPI] __tracepoint_string = {
[IPI_RESCHEDULE] = "Rescheduling interrupts",
[IPI_CALL_FUNCTION] = "Function call interrupts",
+ [IPI_IRQ_WORK] = "IRQ work interrupts",
};
void show_ipi_list(struct seq_file *p, int prec)
@@ -190,24 +188,19 @@ static u32 ipi_read_clear(int cpu)
static void ipi_write_action(int cpu, u32 action)
{
- unsigned int irq = 0;
-
- while ((irq = ffs(action))) {
- uint32_t val = IOCSR_IPI_SEND_BLOCKING;
+ uint32_t val;
- val |= (irq - 1);
- val |= (cpu << IOCSR_IPI_SEND_CPU_SHIFT);
- iocsr_write32(val, LOONGARCH_IOCSR_IPI_SEND);
- action &= ~BIT(irq - 1);
- }
+ val = IOCSR_IPI_SEND_BLOCKING | action;
+ val |= (cpu << IOCSR_IPI_SEND_CPU_SHIFT);
+ iocsr_write32(val, LOONGARCH_IOCSR_IPI_SEND);
}
-void loongson_send_ipi_single(int cpu, unsigned int action)
+static void loongson_send_ipi_single(int cpu, unsigned int action)
{
ipi_write_action(cpu_logical_map(cpu), (u32)action);
}
-void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+static void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action)
{
unsigned int i;
@@ -222,11 +215,18 @@ void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action)
*/
void arch_smp_send_reschedule(int cpu)
{
- loongson_send_ipi_single(cpu, SMP_RESCHEDULE);
+ mp_ops.send_ipi_single(cpu, ACTION_RESCHEDULE);
}
EXPORT_SYMBOL_GPL(arch_smp_send_reschedule);
-irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+ mp_ops.send_ipi_single(smp_processor_id(), ACTION_IRQ_WORK);
+}
+#endif
+
+static irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
{
unsigned int action;
unsigned int cpu = smp_processor_id();
@@ -243,9 +243,34 @@ irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
per_cpu(irq_stat, cpu).ipi_irqs[IPI_CALL_FUNCTION]++;
}
+ if (action & SMP_IRQ_WORK) {
+ irq_work_run();
+ per_cpu(irq_stat, cpu).ipi_irqs[IPI_IRQ_WORK]++;
+ }
+
return IRQ_HANDLED;
}
+static void loongson_init_ipi(void)
+{
+ int r, ipi_irq;
+
+ ipi_irq = get_percpu_irq(INT_IPI);
+ if (ipi_irq < 0)
+ panic("IPI IRQ mapping failed\n");
+
+ irq_set_percpu_devid(ipi_irq);
+ r = request_percpu_irq(ipi_irq, loongson_ipi_interrupt, "IPI", &irq_stat);
+ if (r < 0)
+ panic("IPI IRQ request failed\n");
+}
+
+struct smp_ops mp_ops = {
+ .init_ipi = loongson_init_ipi,
+ .send_ipi_single = loongson_send_ipi_single,
+ .send_ipi_mask = loongson_send_ipi_mask,
+};
+
static void __init fdt_smp_setup(void)
{
#ifdef CONFIG_OF
@@ -260,18 +285,19 @@ static void __init fdt_smp_setup(void)
if (cpuid >= nr_cpu_ids)
continue;
- if (cpuid == loongson_sysconf.boot_cpu_id) {
+ if (cpuid == loongson_sysconf.boot_cpu_id)
cpu = 0;
- numa_add_cpu(cpu);
- } else {
- cpu = cpumask_next_zero(-1, cpu_present_mask);
- }
+ else
+ cpu = find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS);
num_processors++;
set_cpu_possible(cpu, true);
set_cpu_present(cpu, true);
__cpu_number_map[cpuid] = cpu;
__cpu_logical_map[cpu] = cpuid;
+
+ early_numa_add_cpu(cpu, 0);
+ set_cpuid_to_node(cpuid, 0);
}
loongson_sysconf.nr_cpus = num_processors;
@@ -289,6 +315,7 @@ void __init loongson_smp_setup(void)
cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
+ pv_ipi_init();
iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
pr_info("Detected %i available CPU(s)\n", loongson_sysconf.nr_cpus);
}
@@ -323,7 +350,7 @@ void loongson_boot_secondary(int cpu, struct task_struct *idle)
csr_mail_send(entry, cpu_logical_map(cpu), 0);
- loongson_send_ipi_single(cpu, SMP_BOOT_CPU);
+ loongson_send_ipi_single(cpu, ACTION_BOOT_CPU);
}
/*
@@ -333,7 +360,7 @@ void loongson_init_secondary(void)
{
unsigned int cpu = smp_processor_id();
unsigned int imask = ECFGF_IP0 | ECFGF_IP1 | ECFGF_IP2 |
- ECFGF_IPI | ECFGF_PMC | ECFGF_TIMER;
+ ECFGF_IPI | ECFGF_PMC | ECFGF_TIMER | ECFGF_SIP0;
change_csr_ecfg(ECFG0_IM, imask);
@@ -456,6 +483,7 @@ void smp_prepare_boot_cpu(void)
set_cpu_possible(0, true);
set_cpu_online(0, true);
set_my_cpu_offset(per_cpu_offset(0));
+ numa_add_cpu(0);
rr_node = first_node(node_online_map);
for_each_possible_cpu(cpu) {
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
index b4c5acd7aa3b..ba5d0930a74f 100644
--- a/arch/loongarch/kernel/syscall.c
+++ b/arch/loongarch/kernel/syscall.c
@@ -9,20 +9,24 @@
#include <linux/entry-common.h>
#include <linux/errno.h>
#include <linux/linkage.h>
+#include <linux/objtool.h>
+#include <linux/randomize_kstack.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
#include <asm/asm.h>
#include <asm/exception.h>
+#include <asm/loongarch.h>
#include <asm/signal.h>
#include <asm/switch_to.h>
#include <asm-generic/syscalls.h>
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
- prot, unsigned long, flags, unsigned long, fd, off_t, offset)
+ prot, unsigned long, flags, unsigned long, fd, unsigned long, offset)
{
if (offset & ~PAGE_MASK)
return -EINVAL;
@@ -32,13 +36,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
void *sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table_64.h>
};
typedef long (*sys_call_fn)(unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long, unsigned long);
-void noinstr do_syscall(struct pt_regs *regs)
+void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
{
unsigned long nr;
sys_call_fn syscall_fn;
@@ -54,11 +58,28 @@ void noinstr do_syscall(struct pt_regs *regs)
nr = syscall_enter_from_user_mode(regs, nr);
+ add_random_kstack_offset();
+
if (nr < NR_syscalls) {
syscall_fn = sys_call_table[nr];
regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6],
regs->regs[7], regs->regs[8], regs->regs[9]);
}
+ /*
+ * This value will get limited by KSTACK_OFFSET_MAX(), which is 10
+ * bits. The actual entropy will be further reduced by the compiler
+ * when applying stack alignment constraints: 16-bytes (i.e. 4-bits)
+ * aligned, which will remove the 4 low bits from any entropy chosen
+ * here.
+ *
+ * The resulting 6 bits of entropy is seen in SP[9:4].
+ */
+ choose_random_kstack_offset(drdtime());
+
syscall_exit_to_user_mode(regs);
}
+
+#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
+STACK_FRAME_NON_STANDARD(do_syscall);
+#endif
diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c
index e7015f7b70e3..46d7d40c87e3 100644
--- a/arch/loongarch/kernel/time.c
+++ b/arch/loongarch/kernel/time.c
@@ -15,6 +15,7 @@
#include <asm/cpu-features.h>
#include <asm/loongarch.h>
+#include <asm/paravirt.h>
#include <asm/time.h>
u64 cpu_clock_freq;
@@ -123,16 +124,6 @@ void sync_counter(void)
csr_write64(init_offset, LOONGARCH_CSR_CNTC);
}
-static int get_timer_irq(void)
-{
- struct irq_domain *d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY);
-
- if (d)
- return irq_create_mapping(d, INT_TI);
-
- return -EINVAL;
-}
-
int constant_clockevent_init(void)
{
unsigned int cpu = smp_processor_id();
@@ -142,7 +133,7 @@ int constant_clockevent_init(void)
static int irq = 0, timer_irq_installed = 0;
if (!timer_irq_installed) {
- irq = get_timer_irq();
+ irq = get_percpu_irq(INT_TI);
if (irq < 0)
pr_err("Failed to map irq %d (timer)\n", irq);
}
@@ -224,4 +215,5 @@ void __init time_init(void)
constant_clockevent_init();
constant_clocksource_init();
+ pv_time_init();
}
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index e8e97dbf9ca4..08ea921cdec1 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
#define PAGE_SIZE _PAGE_SIZE
#define RO_EXCEPTION_TABLE_ALIGN 4
+#define PHYSADDR_MASK 0xffffffffffff /* 48-bit */
/*
* Put .bss..swapper_pg_dir as the first thing in .bss. This will
@@ -112,6 +113,14 @@ SECTIONS
__rela_dyn_end = .;
}
+#ifdef CONFIG_RELR
+ .relr.dyn : ALIGN(8) {
+ __relr_dyn_begin = .;
+ *(.relr.dyn)
+ __relr_dyn_end = .;
+ }
+#endif
+
.data.rel : { *(.data.rel*) }
#ifdef CONFIG_RELOCATABLE
@@ -142,10 +151,11 @@ SECTIONS
#ifdef CONFIG_EFI_STUB
/* header symbols */
- _kernel_asize = _end - _text;
- _kernel_fsize = _edata - _text;
- _kernel_vsize = _end - __initdata_begin;
- _kernel_rsize = _edata - __initdata_begin;
+ _kernel_entry = ABSOLUTE(kernel_entry & PHYSADDR_MASK);
+ _kernel_asize = ABSOLUTE(_end - _text);
+ _kernel_fsize = ABSOLUTE(_edata - _text);
+ _kernel_vsize = ABSOLUTE(_end - __initdata_begin);
+ _kernel_rsize = ABSOLUTE(_edata - __initdata_begin);
#endif
.gptab.sdata : {
diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig
index c4ef2b4d9797..248744b4d086 100644
--- a/arch/loongarch/kvm/Kconfig
+++ b/arch/loongarch/kvm/Kconfig
@@ -29,6 +29,7 @@ config KVM
select KVM_MMIO
select HAVE_KVM_READONLY_MEM
select KVM_XFER_TO_GUEST_WORK
+ select SCHED_INFO
help
Support hosting virtualized guest machines using
hardware virtualization extensions. You will need
diff --git a/arch/loongarch/kvm/Makefile b/arch/loongarch/kvm/Makefile
index 244467d7792a..b2f4cbe01ae8 100644
--- a/arch/loongarch/kvm/Makefile
+++ b/arch/loongarch/kvm/Makefile
@@ -3,7 +3,7 @@
# Makefile for LoongArch KVM support
#
-ccflags-y += -I $(srctree)/$(src)
+ccflags-y += -I $(src)
include $(srctree)/virt/kvm/Makefile.kvm
diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
index ed1d89d53e2e..ea73f9dc2cc6 100644
--- a/arch/loongarch/kvm/exit.c
+++ b/arch/loongarch/kvm/exit.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/vmalloc.h>
+#include <trace/events/kvm.h>
#include <asm/fpu.h>
#include <asm/inst.h>
#include <asm/loongarch.h>
@@ -20,6 +21,49 @@
#include <asm/kvm_vcpu.h>
#include "trace.h"
+static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst)
+{
+ int rd, rj;
+ unsigned int index, ret;
+
+ if (inst.reg2_format.opcode != cpucfg_op)
+ return EMULATE_FAIL;
+
+ rd = inst.reg2_format.rd;
+ rj = inst.reg2_format.rj;
+ ++vcpu->stat.cpucfg_exits;
+ index = vcpu->arch.gprs[rj];
+
+ /*
+ * By LoongArch Reference Manual 2.2.10.5
+ * Return value is 0 for undefined CPUCFG index
+ *
+ * Disable preemption since hw gcsr is accessed
+ */
+ preempt_disable();
+ switch (index) {
+ case 0 ... (KVM_MAX_CPUCFG_REGS - 1):
+ vcpu->arch.gprs[rd] = vcpu->arch.cpucfg[index];
+ break;
+ case CPUCFG_KVM_SIG:
+ /* CPUCFG emulation between 0x40000000 -- 0x400000ff */
+ vcpu->arch.gprs[rd] = *(unsigned int *)KVM_SIGNATURE;
+ break;
+ case CPUCFG_KVM_FEATURE:
+ ret = KVM_FEATURE_IPI;
+ if (kvm_pvtime_supported())
+ ret |= KVM_FEATURE_STEAL_TIME;
+ vcpu->arch.gprs[rd] = ret;
+ break;
+ default:
+ vcpu->arch.gprs[rd] = 0;
+ break;
+ }
+ preempt_enable();
+
+ return EMULATE_DONE;
+}
+
static unsigned long kvm_emu_read_csr(struct kvm_vcpu *vcpu, int csrid)
{
unsigned long val = 0;
@@ -208,8 +252,6 @@ int kvm_emu_idle(struct kvm_vcpu *vcpu)
static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu)
{
- int rd, rj;
- unsigned int index;
unsigned long curr_pc;
larch_inst inst;
enum emulation_result er = EMULATE_DONE;
@@ -224,21 +266,7 @@ static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu)
er = EMULATE_FAIL;
switch (((inst.word >> 24) & 0xff)) {
case 0x0: /* CPUCFG GSPR */
- if (inst.reg2_format.opcode == 0x1B) {
- rd = inst.reg2_format.rd;
- rj = inst.reg2_format.rj;
- ++vcpu->stat.cpucfg_exits;
- index = vcpu->arch.gprs[rj];
- er = EMULATE_DONE;
- /*
- * By LoongArch Reference Manual 2.2.10.5
- * return value is 0 for undefined cpucfg index
- */
- if (index < KVM_MAX_CPUCFG_REGS)
- vcpu->arch.gprs[rd] = vcpu->arch.cpucfg[index];
- else
- vcpu->arch.gprs[rd] = 0;
- }
+ er = kvm_emu_cpucfg(vcpu, inst);
break;
case 0x4: /* CSR{RD,WR,XCHG} GSPR */
er = kvm_handle_csr(vcpu, inst);
@@ -417,6 +445,8 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
vcpu->arch.io_gpr = rd;
run->mmio.is_write = 0;
vcpu->mmio_is_write = 0;
+ trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, run->mmio.len,
+ run->mmio.phys_addr, NULL);
} else {
kvm_err("Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
inst.word, vcpu->arch.pc, vcpu->arch.badv);
@@ -463,6 +493,9 @@ int kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
break;
}
+ trace_kvm_mmio(KVM_TRACE_MMIO_READ, run->mmio.len,
+ run->mmio.phys_addr, run->mmio.data);
+
return er;
}
@@ -564,6 +597,8 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)
run->mmio.is_write = 1;
vcpu->mmio_needed = 1;
vcpu->mmio_is_write = 1;
+ trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, run->mmio.len,
+ run->mmio.phys_addr, data);
} else {
vcpu->arch.pc = curr_pc;
kvm_err("Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
@@ -655,6 +690,34 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu)
return RESUME_GUEST;
}
+static long kvm_save_notify(struct kvm_vcpu *vcpu)
+{
+ unsigned long id, data;
+
+ id = kvm_read_reg(vcpu, LOONGARCH_GPR_A1);
+ data = kvm_read_reg(vcpu, LOONGARCH_GPR_A2);
+ switch (id) {
+ case KVM_FEATURE_STEAL_TIME:
+ if (!kvm_pvtime_supported())
+ return KVM_HCALL_INVALID_CODE;
+
+ if (data & ~(KVM_STEAL_PHYS_MASK | KVM_STEAL_PHYS_VALID))
+ return KVM_HCALL_INVALID_PARAMETER;
+
+ vcpu->arch.st.guest_addr = data;
+ if (!(data & KVM_STEAL_PHYS_VALID))
+ break;
+
+ vcpu->arch.st.last_steal = current->sched_info.run_delay;
+ kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
+ break;
+ default:
+ break;
+ };
+
+ return 0;
+};
+
/*
* kvm_handle_lsx_disabled() - Guest used LSX while disabled in root.
* @vcpu: Virtual CPU context.
@@ -685,6 +748,93 @@ static int kvm_handle_lasx_disabled(struct kvm_vcpu *vcpu)
return RESUME_GUEST;
}
+static int kvm_send_pv_ipi(struct kvm_vcpu *vcpu)
+{
+ unsigned int min, cpu, i;
+ unsigned long ipi_bitmap;
+ struct kvm_vcpu *dest;
+
+ min = kvm_read_reg(vcpu, LOONGARCH_GPR_A3);
+ for (i = 0; i < 2; i++, min += BITS_PER_LONG) {
+ ipi_bitmap = kvm_read_reg(vcpu, LOONGARCH_GPR_A1 + i);
+ if (!ipi_bitmap)
+ continue;
+
+ cpu = find_first_bit((void *)&ipi_bitmap, BITS_PER_LONG);
+ while (cpu < BITS_PER_LONG) {
+ dest = kvm_get_vcpu_by_cpuid(vcpu->kvm, cpu + min);
+ cpu = find_next_bit((void *)&ipi_bitmap, BITS_PER_LONG, cpu + 1);
+ if (!dest)
+ continue;
+
+ /* Send SWI0 to dest vcpu to emulate IPI interrupt */
+ kvm_queue_irq(dest, INT_SWI0);
+ kvm_vcpu_kick(dest);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Hypercall emulation always return to guest, Caller should check retval.
+ */
+static void kvm_handle_service(struct kvm_vcpu *vcpu)
+{
+ unsigned long func = kvm_read_reg(vcpu, LOONGARCH_GPR_A0);
+ long ret;
+
+ switch (func) {
+ case KVM_HCALL_FUNC_IPI:
+ kvm_send_pv_ipi(vcpu);
+ ret = KVM_HCALL_SUCCESS;
+ break;
+ case KVM_HCALL_FUNC_NOTIFY:
+ ret = kvm_save_notify(vcpu);
+ break;
+ default:
+ ret = KVM_HCALL_INVALID_CODE;
+ break;
+ }
+
+ kvm_write_reg(vcpu, LOONGARCH_GPR_A0, ret);
+}
+
+static int kvm_handle_hypercall(struct kvm_vcpu *vcpu)
+{
+ int ret;
+ larch_inst inst;
+ unsigned int code;
+
+ inst.word = vcpu->arch.badi;
+ code = inst.reg0i15_format.immediate;
+ ret = RESUME_GUEST;
+
+ switch (code) {
+ case KVM_HCALL_SERVICE:
+ vcpu->stat.hypercall_exits++;
+ kvm_handle_service(vcpu);
+ break;
+ case KVM_HCALL_SWDBG:
+ /* KVM_HCALL_SWDBG only in effective when SW_BP is enabled */
+ if (vcpu->guest_debug & KVM_GUESTDBG_SW_BP_MASK) {
+ vcpu->run->exit_reason = KVM_EXIT_DEBUG;
+ ret = RESUME_HOST;
+ break;
+ }
+ fallthrough;
+ default:
+ /* Treat it as noop intruction, only set return value */
+ kvm_write_reg(vcpu, LOONGARCH_GPR_A0, KVM_HCALL_INVALID_CODE);
+ break;
+ }
+
+ if (ret == RESUME_GUEST)
+ update_pc(&vcpu->arch);
+
+ return ret;
+}
+
/*
* LoongArch KVM callback handling for unimplemented guest exiting
*/
@@ -716,6 +866,7 @@ static exit_handle_fn kvm_fault_tables[EXCCODE_INT_START] = {
[EXCCODE_LSXDIS] = kvm_handle_lsx_disabled,
[EXCCODE_LASXDIS] = kvm_handle_lasx_disabled,
[EXCCODE_GSPR] = kvm_handle_gspr,
+ [EXCCODE_HVC] = kvm_handle_hypercall,
};
int kvm_handle_fault(struct kvm_vcpu *vcpu, int fault)
diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index 86a2f2d0cb27..844736b99d38 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -242,6 +242,7 @@ void kvm_check_vpid(struct kvm_vcpu *vcpu)
kvm_update_vpid(vcpu, cpu);
trace_kvm_vpid_change(vcpu, vcpu->arch.vpid);
vcpu->cpu = cpu;
+ kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
}
/* Restore GSTAT(0x50).vpid */
diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c
index a556cff35740..2634a9e8d82c 100644
--- a/arch/loongarch/kvm/mmu.c
+++ b/arch/loongarch/kvm/mmu.c
@@ -163,6 +163,7 @@ static kvm_pte_t *kvm_populate_gpa(struct kvm *kvm,
child = kvm_mmu_memory_cache_alloc(cache);
_kvm_pte_init(child, ctx.invalid_ptes[ctx.level - 1]);
+ smp_wmb(); /* Make pte visible before pmd */
kvm_set_pte(entry, __pa(child));
} else if (kvm_pte_huge(*entry)) {
return entry;
@@ -444,6 +445,17 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
enum kvm_mr_change change)
{
int needs_flush;
+ u32 old_flags = old ? old->flags : 0;
+ u32 new_flags = new ? new->flags : 0;
+ bool log_dirty_pages = new_flags & KVM_MEM_LOG_DIRTY_PAGES;
+
+ /* Only track memslot flags changed */
+ if (change != KVM_MR_FLAGS_ONLY)
+ return;
+
+ /* Discard dirty page tracking on readonly memslot */
+ if ((old_flags & new_flags) & KVM_MEM_READONLY)
+ return;
/*
* If dirty page logging is enabled, write protect all pages in the slot
@@ -454,9 +466,14 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
* MOVE/DELETE: The old mappings will already have been cleaned up by
* kvm_arch_flush_shadow_memslot()
*/
- if (change == KVM_MR_FLAGS_ONLY &&
- (!(old->flags & KVM_MEM_LOG_DIRTY_PAGES) &&
- new->flags & KVM_MEM_LOG_DIRTY_PAGES)) {
+ if (!(old_flags & KVM_MEM_LOG_DIRTY_PAGES) && log_dirty_pages) {
+ /*
+ * Initially-all-set does not require write protecting any page
+ * because they're all assumed to be dirty.
+ */
+ if (kvm_dirty_log_manual_protect_and_init_set(kvm))
+ return;
+
spin_lock(&kvm->mmu_lock);
/* Write protect GPA page table entries */
needs_flush = kvm_mkclean_gpa_pt(kvm, new->base_gfn,
@@ -494,38 +511,6 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
range->end << PAGE_SHIFT, &ctx);
}
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- unsigned long prot_bits;
- kvm_pte_t *ptep;
- kvm_pfn_t pfn = pte_pfn(range->arg.pte);
- gpa_t gpa = range->start << PAGE_SHIFT;
-
- ptep = kvm_populate_gpa(kvm, NULL, gpa, 0);
- if (!ptep)
- return false;
-
- /* Replacing an absent or old page doesn't need flushes */
- if (!kvm_pte_present(NULL, ptep) || !kvm_pte_young(*ptep)) {
- kvm_set_pte(ptep, 0);
- return false;
- }
-
- /* Fill new pte if write protected or page migrated */
- prot_bits = _PAGE_PRESENT | __READABLE;
- prot_bits |= _CACHE_MASK & pte_val(range->arg.pte);
-
- /*
- * Set _PAGE_WRITE or _PAGE_DIRTY iff old and new pte both support
- * _PAGE_WRITE for map_page_fast if next page write fault
- * _PAGE_DIRTY since gpa has already recorded as dirty page
- */
- prot_bits |= __WRITEABLE & *ptep & pte_val(range->arg.pte);
- kvm_set_pte(ptep, kvm_pfn_pte(pfn, __pgprot(prot_bits)));
-
- return true;
-}
-
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
kvm_ptw_ctx ctx;
@@ -572,6 +557,7 @@ static int kvm_map_page_fast(struct kvm_vcpu *vcpu, unsigned long gpa, bool writ
gfn_t gfn = gpa >> PAGE_SHIFT;
struct kvm *kvm = vcpu->kvm;
struct kvm_memory_slot *slot;
+ struct page *page;
spin_lock(&kvm->mmu_lock);
@@ -583,10 +569,8 @@ static int kvm_map_page_fast(struct kvm_vcpu *vcpu, unsigned long gpa, bool writ
}
/* Track access to pages marked old */
- new = *ptep;
- if (!kvm_pte_young(new))
- new = kvm_pte_mkyoung(new);
- /* call kvm_set_pfn_accessed() after unlock */
+ new = kvm_pte_mkyoung(*ptep);
+ /* call kvm_set_pfn_accessed() after unlock */
if (write && !kvm_pte_dirty(new)) {
if (!kvm_pte_write(new)) {
@@ -614,19 +598,22 @@ static int kvm_map_page_fast(struct kvm_vcpu *vcpu, unsigned long gpa, bool writ
if (changed) {
kvm_set_pte(ptep, new);
pfn = kvm_pte_pfn(new);
+ page = kvm_pfn_to_refcounted_page(pfn);
+ if (page)
+ get_page(page);
}
spin_unlock(&kvm->mmu_lock);
- /*
- * Fixme: pfn may be freed after mmu_lock
- * kvm_try_get_pfn(pfn)/kvm_release_pfn pair to prevent this?
- */
- if (kvm_pte_young(changed))
- kvm_set_pfn_accessed(pfn);
+ if (changed) {
+ if (kvm_pte_young(changed))
+ kvm_set_pfn_accessed(pfn);
- if (kvm_pte_dirty(changed)) {
- mark_page_dirty(kvm, gfn);
- kvm_set_pfn_dirty(pfn);
+ if (kvm_pte_dirty(changed)) {
+ mark_page_dirty(kvm, gfn);
+ kvm_set_pfn_dirty(pfn);
+ }
+ if (page)
+ put_page(page);
}
return ret;
out:
@@ -769,6 +756,7 @@ static kvm_pte_t *kvm_split_huge(struct kvm_vcpu *vcpu, kvm_pte_t *ptep, gfn_t g
val += PAGE_SIZE;
}
+ smp_wmb(); /* Make pte visible before pmd */
/* The later kvm_flush_tlb_gpa() will flush hugepage tlb */
kvm_set_pte(ptep, __pa(child));
@@ -890,11 +878,21 @@ retry:
/* Disable dirty logging on HugePages */
level = 0;
- if (!fault_supports_huge_mapping(memslot, hva, write)) {
- level = 0;
- } else {
+ if (fault_supports_huge_mapping(memslot, hva, write)) {
+ /* Check page level about host mmu*/
level = host_pfn_mapping_level(kvm, gfn, memslot);
if (level == 1) {
+ /*
+ * Check page level about secondary mmu
+ * Disable hugepage if it is normal page on
+ * secondary mmu already
+ */
+ ptep = kvm_populate_gpa(kvm, NULL, gpa, 0);
+ if (ptep && !kvm_pte_huge(*ptep))
+ level = 0;
+ }
+
+ if (level == 1) {
gfn = gfn & ~(PTRS_PER_PTE - 1);
pfn = pfn & ~(PTRS_PER_PTE - 1);
}
@@ -924,7 +922,6 @@ retry:
kvm_set_pfn_dirty(pfn);
}
- kvm_set_pfn_accessed(pfn);
kvm_release_pfn_clean(pfn);
out:
srcu_read_unlock(&kvm->srcu, srcu_idx);
@@ -940,7 +937,8 @@ int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
return ret;
/* Invalidate this entry in the TLB */
- kvm_flush_tlb_gpa(vcpu, gpa);
+ vcpu->arch.flush_gpa = gpa;
+ kvm_make_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
return 0;
}
diff --git a/arch/loongarch/kvm/tlb.c b/arch/loongarch/kvm/tlb.c
index 02535df6b51f..ebdbe9264e9c 100644
--- a/arch/loongarch/kvm/tlb.c
+++ b/arch/loongarch/kvm/tlb.c
@@ -23,10 +23,7 @@ void kvm_flush_tlb_all(void)
void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa)
{
- unsigned long flags;
-
- local_irq_save(flags);
+ lockdep_assert_irqs_disabled();
gpa &= (PAGE_MASK << 1);
invtlb(INVTLB_GID_ADDR, read_csr_gstat() & CSR_GSTAT_GID, gpa);
- local_irq_restore(flags);
}
diff --git a/arch/loongarch/kvm/trace.h b/arch/loongarch/kvm/trace.h
index c2484ad4cffa..1783397b1bc8 100644
--- a/arch/loongarch/kvm/trace.h
+++ b/arch/loongarch/kvm/trace.h
@@ -19,14 +19,16 @@ DECLARE_EVENT_CLASS(kvm_transition,
TP_PROTO(struct kvm_vcpu *vcpu),
TP_ARGS(vcpu),
TP_STRUCT__entry(
+ __field(unsigned int, vcpu_id)
__field(unsigned long, pc)
),
TP_fast_assign(
+ __entry->vcpu_id = vcpu->vcpu_id;
__entry->pc = vcpu->arch.pc;
),
- TP_printk("PC: 0x%08lx", __entry->pc)
+ TP_printk("vcpu %u PC: 0x%08lx", __entry->vcpu_id, __entry->pc)
);
DEFINE_EVENT(kvm_transition, kvm_enter,
@@ -54,19 +56,22 @@ DECLARE_EVENT_CLASS(kvm_exit,
TP_PROTO(struct kvm_vcpu *vcpu, unsigned int reason),
TP_ARGS(vcpu, reason),
TP_STRUCT__entry(
+ __field(unsigned int, vcpu_id)
__field(unsigned long, pc)
__field(unsigned int, reason)
),
TP_fast_assign(
+ __entry->vcpu_id = vcpu->vcpu_id;
__entry->pc = vcpu->arch.pc;
__entry->reason = reason;
),
- TP_printk("[%s]PC: 0x%08lx",
- __print_symbolic(__entry->reason,
- kvm_trace_symbol_exit_types),
- __entry->pc)
+ TP_printk("vcpu %u [%s] PC: 0x%08lx",
+ __entry->vcpu_id,
+ __print_symbolic(__entry->reason,
+ kvm_trace_symbol_exit_types),
+ __entry->pc)
);
DEFINE_EVENT(kvm_exit, kvm_exit_idle,
@@ -85,14 +90,17 @@ TRACE_EVENT(kvm_exit_gspr,
TP_PROTO(struct kvm_vcpu *vcpu, unsigned int inst_word),
TP_ARGS(vcpu, inst_word),
TP_STRUCT__entry(
+ __field(unsigned int, vcpu_id)
__field(unsigned int, inst_word)
),
TP_fast_assign(
+ __entry->vcpu_id = vcpu->vcpu_id;
__entry->inst_word = inst_word;
),
- TP_printk("Inst word: 0x%08x", __entry->inst_word)
+ TP_printk("vcpu %u Inst word: 0x%08x", __entry->vcpu_id,
+ __entry->inst_word)
);
#define KVM_TRACE_AUX_SAVE 0
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..16756ffb55e8 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -19,6 +19,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
STATS_DESC_COUNTER(VCPU, idle_exits),
STATS_DESC_COUNTER(VCPU, cpucfg_exits),
STATS_DESC_COUNTER(VCPU, signal_exits),
+ STATS_DESC_COUNTER(VCPU, hypercall_exits)
};
const struct kvm_stats_header kvm_vcpu_stats_header = {
@@ -30,6 +31,50 @@ const struct kvm_stats_header kvm_vcpu_stats_header = {
sizeof(kvm_vcpu_stats_desc),
};
+static void kvm_update_stolen_time(struct kvm_vcpu *vcpu)
+{
+ u32 version;
+ u64 steal;
+ gpa_t gpa;
+ struct kvm_memslots *slots;
+ struct kvm_steal_time __user *st;
+ struct gfn_to_hva_cache *ghc;
+
+ ghc = &vcpu->arch.st.cache;
+ gpa = vcpu->arch.st.guest_addr;
+ if (!(gpa & KVM_STEAL_PHYS_VALID))
+ return;
+
+ gpa &= KVM_STEAL_PHYS_MASK;
+ slots = kvm_memslots(vcpu->kvm);
+ if (slots->generation != ghc->generation || gpa != ghc->gpa) {
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st))) {
+ ghc->gpa = INVALID_GPA;
+ return;
+ }
+ }
+
+ st = (struct kvm_steal_time __user *)ghc->hva;
+ unsafe_get_user(version, &st->version, out);
+ if (version & 1)
+ version += 1; /* first time write, random junk */
+
+ version += 1;
+ unsafe_put_user(version, &st->version, out);
+ smp_wmb();
+
+ unsafe_get_user(steal, &st->steal, out);
+ steal += current->sched_info.run_delay - vcpu->arch.st.last_steal;
+ vcpu->arch.st.last_steal = current->sched_info.run_delay;
+ unsafe_put_user(steal, &st->steal, out);
+
+ smp_wmb();
+ version += 1;
+ unsafe_put_user(version, &st->version, out);
+out:
+ mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa));
+}
+
/*
* kvm_check_requests - check and handle pending vCPU requests
*
@@ -47,9 +92,22 @@ static int kvm_check_requests(struct kvm_vcpu *vcpu)
if (kvm_dirty_ring_check_request(vcpu))
return RESUME_HOST;
+ if (kvm_check_request(KVM_REQ_STEAL_UPDATE, vcpu))
+ kvm_update_stolen_time(vcpu);
+
return RESUME_GUEST;
}
+static void kvm_late_check_requests(struct kvm_vcpu *vcpu)
+{
+ lockdep_assert_irqs_disabled();
+ if (kvm_check_request(KVM_REQ_TLB_FLUSH_GPA, vcpu))
+ if (vcpu->arch.flush_gpa != INVALID_GPA) {
+ kvm_flush_tlb_gpa(vcpu, vcpu->arch.flush_gpa);
+ vcpu->arch.flush_gpa = INVALID_GPA;
+ }
+}
+
/*
* Check and handle pending signal and vCPU requests etc
* Run with irq enabled and preempt enabled
@@ -100,6 +158,13 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu)
/* Make sure the vcpu mode has been written */
smp_store_mb(vcpu->mode, IN_GUEST_MODE);
kvm_check_vpid(vcpu);
+
+ /*
+ * Called after function kvm_check_vpid()
+ * Since it updates CSR.GSTAT used by kvm_flush_tlb_gpa(),
+ * and it may also clear KVM_REQ_TLB_FLUSH_GPA pending bit
+ */
+ kvm_late_check_requests(vcpu);
vcpu->arch.host_eentry = csr_read64(LOONGARCH_CSR_EENTRY);
/* Clear KVM_LARCH_SWCSR_LATEST as CSR will change when enter guest */
vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST;
@@ -247,7 +312,101 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
{
- return -EINVAL;
+ if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
+ return -EINVAL;
+
+ if (dbg->control & KVM_GUESTDBG_ENABLE)
+ vcpu->guest_debug = dbg->control;
+ else
+ vcpu->guest_debug = 0;
+
+ return 0;
+}
+
+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+ int cpuid;
+ struct kvm_phyid_map *map;
+ struct loongarch_csrs *csr = vcpu->arch.csr;
+
+ if (val >= KVM_MAX_PHYID)
+ return -EINVAL;
+
+ map = vcpu->kvm->arch.phyid_map;
+ cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_CPUID);
+
+ spin_lock(&vcpu->kvm->arch.phyid_map_lock);
+ if ((cpuid < KVM_MAX_PHYID) && map->phys_map[cpuid].enabled) {
+ /* Discard duplicated CPUID set operation */
+ if (cpuid == val) {
+ spin_unlock(&vcpu->kvm->arch.phyid_map_lock);
+ return 0;
+ }
+
+ /*
+ * CPUID is already set before
+ * Forbid changing to a different CPUID at runtime
+ */
+ spin_unlock(&vcpu->kvm->arch.phyid_map_lock);
+ return -EINVAL;
+ }
+
+ if (map->phys_map[val].enabled) {
+ /* Discard duplicated CPUID set operation */
+ if (vcpu == map->phys_map[val].vcpu) {
+ spin_unlock(&vcpu->kvm->arch.phyid_map_lock);
+ return 0;
+ }
+
+ /*
+ * New CPUID is already set with other vcpu
+ * Forbid sharing the same CPUID between different vcpus
+ */
+ spin_unlock(&vcpu->kvm->arch.phyid_map_lock);
+ return -EINVAL;
+ }
+
+ kvm_write_sw_gcsr(csr, LOONGARCH_CSR_CPUID, val);
+ map->phys_map[val].enabled = true;
+ map->phys_map[val].vcpu = vcpu;
+ spin_unlock(&vcpu->kvm->arch.phyid_map_lock);
+
+ return 0;
+}
+
+static inline void kvm_drop_cpuid(struct kvm_vcpu *vcpu)
+{
+ int cpuid;
+ struct kvm_phyid_map *map;
+ struct loongarch_csrs *csr = vcpu->arch.csr;
+
+ map = vcpu->kvm->arch.phyid_map;
+ cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_CPUID);
+
+ if (cpuid >= KVM_MAX_PHYID)
+ return;
+
+ spin_lock(&vcpu->kvm->arch.phyid_map_lock);
+ if (map->phys_map[cpuid].enabled) {
+ map->phys_map[cpuid].vcpu = NULL;
+ map->phys_map[cpuid].enabled = false;
+ kvm_write_sw_gcsr(csr, LOONGARCH_CSR_CPUID, KVM_MAX_PHYID);
+ }
+ spin_unlock(&vcpu->kvm->arch.phyid_map_lock);
+}
+
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid)
+{
+ struct kvm_phyid_map *map;
+
+ if (cpuid >= KVM_MAX_PHYID)
+ return NULL;
+
+ map = kvm->arch.phyid_map;
+ if (!map->phys_map[cpuid].enabled)
+ return NULL;
+
+ return map->phys_map[cpuid].vcpu;
}
static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val)
@@ -259,6 +418,17 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val)
return -EINVAL;
if (id == LOONGARCH_CSR_ESTAT) {
+ preempt_disable();
+ vcpu_load(vcpu);
+ /*
+ * Sync pending interrupts into ESTAT so that interrupt
+ * remains during VM migration stage
+ */
+ kvm_deliver_intr(vcpu);
+ vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST;
+ vcpu_put(vcpu);
+ preempt_enable();
+
/* ESTAT IP0~IP7 get from GINTC */
gintc = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_GINTC) & 0xff;
*val = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT) | (gintc << 2);
@@ -282,6 +452,9 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val)
if (get_gcsr_flag(id) & INVALID_GCSR)
return -EINVAL;
+ if (id == LOONGARCH_CSR_CPUID)
+ return kvm_set_cpuid(vcpu, val);
+
if (id == LOONGARCH_CSR_ESTAT) {
/* ESTAT IP0~IP7 inject through GINTC */
gintc = (val >> 2) & 0xff;
@@ -409,6 +582,9 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
case KVM_REG_LOONGARCH_COUNTER:
*v = drdtime() + vcpu->kvm->arch.time_offset;
break;
+ case KVM_REG_LOONGARCH_DEBUG_INST:
+ *v = INSN_HVCL | KVM_HCALL_SWDBG;
+ break;
default:
ret = -EINVAL;
break;
@@ -561,6 +737,16 @@ static int kvm_loongarch_cpucfg_has_attr(struct kvm_vcpu *vcpu,
return -ENXIO;
}
+static int kvm_loongarch_pvtime_has_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ if (!kvm_pvtime_supported() ||
+ attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
+ return -ENXIO;
+
+ return 0;
+}
+
static int kvm_loongarch_vcpu_has_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
@@ -570,6 +756,9 @@ static int kvm_loongarch_vcpu_has_attr(struct kvm_vcpu *vcpu,
case KVM_LOONGARCH_VCPU_CPUCFG:
ret = kvm_loongarch_cpucfg_has_attr(vcpu, attr);
break;
+ case KVM_LOONGARCH_VCPU_PVTIME_CTRL:
+ ret = kvm_loongarch_pvtime_has_attr(vcpu, attr);
+ break;
default:
break;
}
@@ -577,7 +766,7 @@ static int kvm_loongarch_vcpu_has_attr(struct kvm_vcpu *vcpu,
return ret;
}
-static int kvm_loongarch_get_cpucfg_attr(struct kvm_vcpu *vcpu,
+static int kvm_loongarch_cpucfg_get_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
int ret = 0;
@@ -593,6 +782,23 @@ static int kvm_loongarch_get_cpucfg_attr(struct kvm_vcpu *vcpu,
return ret;
}
+static int kvm_loongarch_pvtime_get_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ u64 gpa;
+ u64 __user *user = (u64 __user *)attr->addr;
+
+ if (!kvm_pvtime_supported() ||
+ attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
+ return -ENXIO;
+
+ gpa = vcpu->arch.st.guest_addr;
+ if (put_user(gpa, user))
+ return -EFAULT;
+
+ return 0;
+}
+
static int kvm_loongarch_vcpu_get_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
@@ -600,7 +806,10 @@ static int kvm_loongarch_vcpu_get_attr(struct kvm_vcpu *vcpu,
switch (attr->group) {
case KVM_LOONGARCH_VCPU_CPUCFG:
- ret = kvm_loongarch_get_cpucfg_attr(vcpu, attr);
+ ret = kvm_loongarch_cpucfg_get_attr(vcpu, attr);
+ break;
+ case KVM_LOONGARCH_VCPU_PVTIME_CTRL:
+ ret = kvm_loongarch_pvtime_get_attr(vcpu, attr);
break;
default:
break;
@@ -615,6 +824,43 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu,
return -ENXIO;
}
+static int kvm_loongarch_pvtime_set_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int idx, ret = 0;
+ u64 gpa, __user *user = (u64 __user *)attr->addr;
+ struct kvm *kvm = vcpu->kvm;
+
+ if (!kvm_pvtime_supported() ||
+ attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
+ return -ENXIO;
+
+ if (get_user(gpa, user))
+ return -EFAULT;
+
+ if (gpa & ~(KVM_STEAL_PHYS_MASK | KVM_STEAL_PHYS_VALID))
+ return -EINVAL;
+
+ if (!(gpa & KVM_STEAL_PHYS_VALID)) {
+ vcpu->arch.st.guest_addr = gpa;
+ return 0;
+ }
+
+ /* Check the address is in a valid memslot */
+ idx = srcu_read_lock(&kvm->srcu);
+ if (kvm_is_error_hva(gfn_to_hva(kvm, gpa >> PAGE_SHIFT)))
+ ret = -EINVAL;
+ srcu_read_unlock(&kvm->srcu, idx);
+
+ if (!ret) {
+ vcpu->arch.st.guest_addr = gpa;
+ vcpu->arch.st.last_steal = current->sched_info.run_delay;
+ kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
+ }
+
+ return ret;
+}
+
static int kvm_loongarch_vcpu_set_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
@@ -624,6 +870,9 @@ static int kvm_loongarch_vcpu_set_attr(struct kvm_vcpu *vcpu,
case KVM_LOONGARCH_VCPU_CPUCFG:
ret = kvm_loongarch_cpucfg_set_attr(vcpu, attr);
break;
+ case KVM_LOONGARCH_VCPU_PVTIME_CTRL:
+ ret = kvm_loongarch_pvtime_set_attr(vcpu, attr);
+ break;
default:
break;
}
@@ -893,6 +1142,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
struct loongarch_csrs *csr;
vcpu->arch.vpid = 0;
+ vcpu->arch.flush_gpa = INVALID_GPA;
hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
vcpu->arch.swtimer.function = kvm_swtimer_wakeup;
@@ -924,6 +1174,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
/* Set cpuid */
kvm_write_sw_gcsr(csr, LOONGARCH_CSR_TMID, vcpu->vcpu_id);
+ kvm_write_sw_gcsr(csr, LOONGARCH_CSR_CPUID, KVM_MAX_PHYID);
/* Start with no pending virtual guest interrupts */
csr->csrs[LOONGARCH_CSR_GINTC] = 0;
@@ -942,6 +1193,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
hrtimer_cancel(&vcpu->arch.swtimer);
kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+ kvm_drop_cpuid(vcpu);
kfree(vcpu->arch.csr);
/*
@@ -981,6 +1233,7 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
/* Control guest page CCA attribute */
change_csr_gcfg(CSR_GCFG_MATC_MASK, CSR_GCFG_MATC_ROOT);
+ kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
/* Don't bother restoring registers multiple times unless necessary */
if (vcpu->arch.aux_inuse & KVM_LARCH_HWCSR_USABLE)
@@ -1163,7 +1416,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_complete_iocsr_read(vcpu, run);
}
- if (run->immediate_exit)
+ if (!vcpu->wants_to_run)
return r;
/* Clear exit_reason */
diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c
index 0a37f6fa8f2d..6b2e4f66ad26 100644
--- a/arch/loongarch/kvm/vm.c
+++ b/arch/loongarch/kvm/vm.c
@@ -30,6 +30,14 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
if (!kvm->arch.pgd)
return -ENOMEM;
+ kvm->arch.phyid_map = kvzalloc(sizeof(struct kvm_phyid_map), GFP_KERNEL_ACCOUNT);
+ if (!kvm->arch.phyid_map) {
+ free_page((unsigned long)kvm->arch.pgd);
+ kvm->arch.pgd = NULL;
+ return -ENOMEM;
+ }
+ spin_lock_init(&kvm->arch.phyid_map_lock);
+
kvm_init_vmcs(kvm);
kvm->arch.gpa_size = BIT(cpu_vabits - 1);
kvm->arch.root_level = CONFIG_PGTABLE_LEVELS - 1;
@@ -52,6 +60,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kvm_destroy_vcpus(kvm);
free_page((unsigned long)kvm->arch.pgd);
kvm->arch.pgd = NULL;
+ kvfree(kvm->arch.phyid_map);
+ kvm->arch.phyid_map = NULL;
}
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
@@ -66,6 +76,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_IMMEDIATE_EXIT:
case KVM_CAP_IOEVENTFD:
case KVM_CAP_MP_STATE:
+ case KVM_CAP_SET_GUEST_DEBUG:
r = 1;
break;
case KVM_CAP_NR_VCPUS:
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index a77bf160bfc4..ccea3bbd4353 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -6,6 +6,8 @@
lib-y += delay.o memset.o memcpy.o memmove.o \
clear_user.o copy_user.o csum.o dump_tlb.o unaligned.o
+obj-$(CONFIG_ARCH_SUPPORTS_INT128) += tishift.o
+
obj-$(CONFIG_CPU_HAS_LSX) += xor_simd.o xor_simd_glue.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/loongarch/lib/tishift.S b/arch/loongarch/lib/tishift.S
new file mode 100644
index 000000000000..fa1d310012bc
--- /dev/null
+++ b/arch/loongarch/lib/tishift.S
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <asm/asmmacro.h>
+#include <linux/export.h>
+#include <linux/linkage.h>
+
+SYM_FUNC_START(__ashlti3)
+ srli.d t2, a0, 1
+ nor t3, zero, a2
+ sll.d t1, a1, a2
+ srl.d t2, t2, t3
+ andi t0, a2, 64
+ sll.d a0, a0, a2
+ or t1, t2, t1
+ maskeqz a1, a0, t0
+ masknez a0, a0, t0
+ masknez t0, t1, t0
+ or a1, t0, a1
+ jr ra
+SYM_FUNC_END(__ashlti3)
+EXPORT_SYMBOL(__ashlti3)
+
+SYM_FUNC_START(__ashrti3)
+ nor t3, zero, a2
+ slli.d t2, a1, 1
+ srl.d t1, a0, a2
+ sll.d t2, t2, t3
+ andi t0, a2, 64
+ or t1, t2, t1
+ sra.d a2, a1, a2
+ srai.d a1, a1, 63
+ maskeqz a0, a2, t0
+ maskeqz a1, a1, t0
+ masknez a2, a2, t0
+ masknez t0, t1, t0
+ or a1, a1, a2
+ or a0, t0, a0
+ jr ra
+SYM_FUNC_END(__ashrti3)
+EXPORT_SYMBOL(__ashrti3)
+
+SYM_FUNC_START(__lshrti3)
+ slli.d t2, a1, 1
+ nor t3, zero, a2
+ srl.d t1, a0, a2
+ sll.d t2, t2, t3
+ andi t0, a2, 64
+ srl.d a1, a1, a2
+ or t1, t2, t1
+ maskeqz a0, a1, t0
+ masknez a1, a1, t0
+ masknez t0, t1, t0
+ or a0, t0, a0
+ jr ra
+SYM_FUNC_END(__lshrti3)
+EXPORT_SYMBOL(__lshrti3)
diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c
index 1e76fcb83093..12222c56cb59 100644
--- a/arch/loongarch/mm/hugetlbpage.c
+++ b/arch/loongarch/mm/hugetlbpage.c
@@ -50,21 +50,11 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
return (pte_t *) pmd;
}
-int pmd_huge(pmd_t pmd)
-{
- return (pmd_val(pmd) & _PAGE_HUGE) != 0;
-}
-
-int pud_huge(pud_t pud)
-{
- return (pud_val(pud) & _PAGE_HUGE) != 0;
-}
-
uint64_t pmd_to_entrylo(unsigned long pmd_val)
{
uint64_t val;
/* PMD as PTE. Must be huge page */
- if (!pmd_huge(__pmd(pmd_val)))
+ if (!pmd_leaf(__pmd(pmd_val)))
panic("%s", __func__);
val = pmd_val ^ _PAGE_HUGE;
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 4dd53427f657..bf789d114c2d 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -24,6 +24,7 @@
#include <linux/gfp.h>
#include <linux/hugetlb.h>
#include <linux/mmzone.h>
+#include <linux/execmem.h>
#include <asm/asm-offsets.h>
#include <asm/bootinfo.h>
@@ -248,3 +249,23 @@ EXPORT_SYMBOL(invalid_pmd_table);
#endif
pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
EXPORT_SYMBOL(invalid_pte_table);
+
+#ifdef CONFIG_EXECMEM
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = MODULES_VADDR,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c
index 89af7c12e8c0..889030985135 100644
--- a/arch/loongarch/mm/mmap.c
+++ b/arch/loongarch/mm/mmap.c
@@ -25,7 +25,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
struct vm_area_struct *vma;
unsigned long addr = addr0;
int do_color_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (unlikely(len > TASK_SIZE))
return -ENOMEM;
@@ -83,7 +83,6 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
*/
}
- info.flags = 0;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
return vm_unmapped_area(&info);
diff --git a/arch/loongarch/mm/tlbex.S b/arch/loongarch/mm/tlbex.S
index a44387b838af..c08682a89c58 100644
--- a/arch/loongarch/mm/tlbex.S
+++ b/arch/loongarch/mm/tlbex.S
@@ -125,6 +125,8 @@ vmalloc_load:
tlb_huge_update_load:
#ifdef CONFIG_SMP
ll.d ra, t1, 0
+#else
+ rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
#endif
andi t0, ra, _PAGE_PRESENT
beqz t0, nopage_tlb_load
@@ -135,7 +137,6 @@ tlb_huge_update_load:
beqz t0, tlb_huge_update_load
ori t0, ra, _PAGE_VALID
#else
- rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
ori t0, ra, _PAGE_VALID
st.d t0, t1, 0
#endif
@@ -281,6 +282,8 @@ vmalloc_store:
tlb_huge_update_store:
#ifdef CONFIG_SMP
ll.d ra, t1, 0
+#else
+ rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
#endif
andi t0, ra, _PAGE_PRESENT | _PAGE_WRITE
xori t0, t0, _PAGE_PRESENT | _PAGE_WRITE
@@ -292,7 +295,6 @@ tlb_huge_update_store:
beqz t0, tlb_huge_update_store
ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
#else
- rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
st.d t0, t1, 0
#endif
@@ -438,6 +440,8 @@ vmalloc_modify:
tlb_huge_update_modify:
#ifdef CONFIG_SMP
ll.d ra, t1, 0
+#else
+ rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
#endif
andi t0, ra, _PAGE_WRITE
beqz t0, nopage_tlb_modify
@@ -448,7 +452,6 @@ tlb_huge_update_modify:
beqz t0, tlb_huge_update_modify
ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
#else
- rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
st.d t0, t1, 0
#endif
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index e73323d759d0..7dbefd4ba210 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -1294,16 +1294,19 @@ skip_init_ctx:
flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx));
if (!prog->is_func || extra_pass) {
+ int err;
+
if (extra_pass && ctx.idx != jit_data->ctx.idx) {
pr_err_once("multi-func JIT bug %d != %d\n",
ctx.idx, jit_data->ctx.idx);
- bpf_jit_binary_free(header);
- prog->bpf_func = NULL;
- prog->jited = 0;
- prog->jited_len = 0;
- goto out_offset;
+ goto out_free;
+ }
+ err = bpf_jit_binary_lock_ro(header);
+ if (err) {
+ pr_err_once("bpf_jit_binary_lock_ro() returned %d\n",
+ err);
+ goto out_free;
}
- bpf_jit_binary_lock_ro(header);
} else {
jit_data->ctx = ctx;
jit_data->image = image_ptr;
@@ -1334,6 +1337,13 @@ out:
out_offset = -1;
return prog;
+
+out_free:
+ bpf_jit_binary_free(header);
+ prog->bpf_func = NULL;
+ prog->jited = 0;
+ prog->jited_len = 0;
+ goto out_offset;
}
/* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
diff --git a/arch/loongarch/power/platform.c b/arch/loongarch/power/platform.c
index 3ea8e07aa225..0909729dc2e1 100644
--- a/arch/loongarch/power/platform.c
+++ b/arch/loongarch/power/platform.c
@@ -34,22 +34,49 @@ void enable_pci_wakeup(void)
acpi_write_bit_register(ACPI_BITREG_PCIEXP_WAKE_DISABLE, 0);
}
+static struct platform_device loongson3_cpufreq_device = {
+ .name = "loongson3_cpufreq",
+ .id = -1,
+};
+
+static int __init loongson_cpufreq_init(void)
+{
+ if (!cpu_has_scalefreq)
+ return -ENODEV;
+
+ return platform_device_register(&loongson3_cpufreq_device);
+}
+
+arch_initcall(loongson_cpufreq_init);
+
+static void default_suspend_addr(void)
+{
+ acpi_enter_sleep_state(ACPI_STATE_S3);
+}
+
static int __init loongson3_acpi_suspend_init(void)
{
#ifdef CONFIG_ACPI
acpi_status status;
uint64_t suspend_addr = 0;
- if (acpi_disabled || acpi_gbl_reduced_hardware)
+ if (acpi_disabled)
+ return 0;
+
+ if (!acpi_gbl_reduced_hardware)
+ acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
+
+ if (!acpi_sleep_state_supported(ACPI_STATE_S3))
return 0;
- acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
status = acpi_evaluate_integer(NULL, "\\SADR", NULL, &suspend_addr);
if (ACPI_FAILURE(status) || !suspend_addr) {
- pr_err("ACPI S3 is not support!\n");
- return -1;
+ pr_info("ACPI S3 supported with hardware register default\n");
+ loongson_sysconf.suspend_addr = (u64)default_suspend_addr;
+ } else {
+ pr_info("ACPI S3 supported with Loongson ACPI SADR extension\n");
+ loongson_sysconf.suspend_addr = (u64)phys_to_virt(PHYSADDR(suspend_addr));
}
- loongson_sysconf.suspend_addr = (u64)phys_to_virt(PHYSADDR(suspend_addr));
#endif
return 0;
}
diff --git a/arch/loongarch/power/suspend.c b/arch/loongarch/power/suspend.c
index 166d9e06a64b..c9e594925c47 100644
--- a/arch/loongarch/power/suspend.c
+++ b/arch/loongarch/power/suspend.c
@@ -24,6 +24,7 @@ struct saved_registers {
u64 kpgd;
u32 pwctl0;
u32 pwctl1;
+ u64 pcpu_base;
};
static struct saved_registers saved_regs;
@@ -36,6 +37,7 @@ void loongarch_common_suspend(void)
saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1);
saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG);
saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN);
+ saved_regs.pcpu_base = csr_read64(PERCPU_BASE_KS);
loongarch_suspend_addr = loongson_sysconf.suspend_addr;
}
@@ -44,7 +46,6 @@ void loongarch_common_resume(void)
{
sync_counter();
local_flush_tlb_all();
- csr_write64(per_cpu_offset(0), PERCPU_BASE_KS);
csr_write64(eentry, LOONGARCH_CSR_EENTRY);
csr_write64(eentry, LOONGARCH_CSR_MERRENTRY);
csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
@@ -55,6 +56,7 @@ void loongarch_common_resume(void)
csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1);
csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG);
csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN);
+ csr_write64(saved_regs.pcpu_base, PERCPU_BASE_KS);
}
int loongarch_acpi_suspend(void)
diff --git a/arch/loongarch/power/suspend_asm.S b/arch/loongarch/power/suspend_asm.S
index e2fc3b4e31f0..9fe28d5a0270 100644
--- a/arch/loongarch/power/suspend_asm.S
+++ b/arch/loongarch/power/suspend_asm.S
@@ -66,18 +66,14 @@ SYM_FUNC_START(loongarch_suspend_enter)
la.pcrel a0, loongarch_wakeup_start
la.pcrel t0, loongarch_suspend_addr
ld.d t0, t0, 0
- jirl a0, t0, 0 /* Call BIOS's STR sleep routine */
+ jirl ra, t0, 0 /* Call BIOS's STR sleep routine */
/*
* This is where we return upon wakeup.
* Reload all of the registers and return.
*/
SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
- li.d t0, CSR_DMW0_INIT # UC, PLV0
- csrwr t0, LOONGARCH_CSR_DMWIN0
- li.d t0, CSR_DMW1_INIT # CA, PLV0
- csrwr t0, LOONGARCH_CSR_DMWIN1
-
+ SETUP_DMWINS t0
JUMP_VIRT_ADDR t0, t1
/* Enable PG */
diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
index 75c6726382c3..d724d46b07c8 100644
--- a/arch/loongarch/vdso/Makefile
+++ b/arch/loongarch/vdso/Makefile
@@ -1,11 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Objects to go into the VDSO.
-KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-OBJECT_FILES_NON_STANDARD := y
-
# Include the generic Makefile to check the built vdso.
include $(srctree)/lib/vdso/Makefile
@@ -39,8 +34,6 @@ ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
$(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared \
--hash-style=sysv --build-id -T
-GCOV_PROFILE := n
-
#
# Shared build commands.
#
@@ -52,7 +45,7 @@ quiet_cmd_vdsoas_o_S = AS $@
cmd_vdsoas_o_S = $(CC) $(a_flags) -c -o $@ $<
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 6ffa29585194..cc26df907bfe 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -3,8 +3,8 @@ config M68K
bool
default y
select ARCH_32BIT_OFF_T
- select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_BINFMT_FLAT
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DMA_PREP_COHERENT if M68K_NONCOHERENT_DMA && !COLDFIRE
@@ -18,7 +18,7 @@ config M68K
select DMA_DIRECT_REMAP if M68K_NONCOHERENT_DMA && !COLDFIRE
select GENERIC_ATOMIC64
select GENERIC_CPU_DEVICES
- select GENERIC_IOMAP
+ select GENERIC_IOMAP if HAS_IOPORT
select GENERIC_IRQ_SHOW
select GENERIC_LIB_ASHLDI3
select GENERIC_LIB_ASHRDI3
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 99718f3dc686..0147130dc34e 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -180,6 +180,15 @@ int __init amiga_parse_bootinfo(const struct bi_record *record)
dev->slotsize = be16_to_cpu(cd->cd_SlotSize);
dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr);
dev->boardsize = be32_to_cpu(cd->cd_BoardSize);
+
+ /* CS-LAB Warp 1260 workaround */
+ if (be16_to_cpu(dev->rom.er_Manufacturer) == ZORRO_MANUF(ZORRO_PROD_CSLAB_WARP_1260) &&
+ dev->rom.er_Product == ZORRO_PROD(ZORRO_PROD_CSLAB_WARP_1260)) {
+
+ /* turn off all interrupts */
+ pr_info("Warp 1260 card detected: applying interrupt storm workaround\n");
+ *(uint32_t *)(dev->boardaddr + 0x1000) = 0xfff;
+ }
} else
pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n");
#endif /* CONFIG_ZORRO */
@@ -836,7 +845,7 @@ static void amiga_get_hardware_list(struct seq_file *m)
seq_printf(m, "\tZorro II%s AutoConfig: %d Expansion "
"Device%s\n",
AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
- zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
+ zorro_num_autocon, str_plural(zorro_num_autocon));
#endif /* CONFIG_ZORRO */
#undef AMIGAHW_ANNOUNCE
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 23256434191c..0465444ceb21 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -301,11 +301,7 @@ void __init atari_init_IRQ(void)
if (ATARIHW_PRESENT(SCU)) {
/* init the SCU if present */
- tt_scu.sys_mask = 0x10; /* enable VBL (for the cursor) and
- * disable HSYNC interrupts (who
- * needs them?) MFP and SCC are
- * enabled in VME mask
- */
+ tt_scu.sys_mask = 0x0; /* disable all interrupts */
tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */
} else {
/* If no SCU and no Hades, the HSYNC interrupt needs to be
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index a6f6607efe79..9a084943a68a 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -26,6 +26,7 @@ CONFIG_AMIGA_BUILTIN_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
@@ -217,7 +218,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -373,6 +373,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -624,8 +625,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 0ca1f9f930bc..58ec725bf392 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -21,6 +21,7 @@ CONFIG_HEARTBEAT=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -213,7 +214,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -353,6 +353,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -581,8 +582,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index be030659d8d7..63ab7e892e59 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -29,6 +29,7 @@ CONFIG_ATARI_ETHERNEC=y
CONFIG_ATARI_DSP56K=m
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_MAC_PARTITION=y
@@ -220,7 +221,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -368,6 +368,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -601,8 +602,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index ad8f81fbb630..ca40744eec60 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -19,6 +19,7 @@ CONFIG_BVME6000=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -210,7 +211,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -351,6 +351,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -573,8 +574,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index ff253b6accec..77bcc6faf468 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -20,6 +20,7 @@ CONFIG_HP300=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -212,7 +213,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -352,6 +352,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -583,8 +584,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index f92b866620a7..e73d4032b659 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -20,6 +20,7 @@ CONFIG_MAC=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -211,7 +212,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -364,6 +364,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -600,8 +601,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index bd813beaa8a7..638df8442c98 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -44,6 +44,7 @@ CONFIG_AMIGA_BUILTIN_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
@@ -231,7 +232,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -407,6 +407,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -686,8 +687,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 2237ee0fe433..2248db426081 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -18,6 +18,7 @@ CONFIG_MVME147=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -209,7 +210,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -350,6 +350,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -572,8 +573,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index afb5aa9c5012..2975b66521f6 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -19,6 +19,7 @@ CONFIG_MVME16x=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -210,7 +211,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -351,6 +351,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -573,8 +574,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index e40f7a308966..0a0e32344033 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -19,6 +19,7 @@ CONFIG_HEARTBEAT=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -211,7 +212,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -357,6 +357,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -590,8 +591,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 4df397c0395f..f16f1a99c2ba 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -16,6 +16,7 @@ CONFIG_SUN3=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -206,7 +207,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -347,6 +347,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -570,8 +571,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index aa7719b3947f..667bd61ae9b3 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -16,6 +16,7 @@ CONFIG_SUN3X=y
CONFIG_PROC_HARDWARE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
@@ -207,7 +208,6 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
@@ -348,6 +348,7 @@ CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
+CONFIG_PFCP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -571,8 +572,6 @@ CONFIG_REED_SOLOMON_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
-CONFIG_STRING_SELFTEST=m
-CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 642fb80c5c4e..83410f8184ec 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -71,7 +71,7 @@ static void nfhd_submit_bio(struct bio *bio)
len = bvec.bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
- page_to_phys(bvec.bv_page) + bvec.bv_offset);
+ bvec_phys(&bvec));
sec += len;
}
bio_endio(bio);
@@ -98,6 +98,7 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
{
struct queue_limits lim = {
.logical_block_size = bsize,
+ .features = BLK_FEAT_ROTATIONAL,
};
struct nfhd_device *dev;
int dev_id = id - NFHD_DEV_OFFSET;
@@ -193,4 +194,5 @@ static void __exit nfhd_exit(void)
module_init(nfhd_init);
module_exit(nfhd_exit);
+MODULE_DESCRIPTION("Atari NatFeat block device driver");
MODULE_LICENSE("GPL");
diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
index 17b2987c2bf5..d41260672e24 100644
--- a/arch/m68k/emu/nfcon.c
+++ b/arch/m68k/emu/nfcon.c
@@ -173,4 +173,5 @@ static void __exit nfcon_exit(void)
module_init(nfcon_init);
module_exit(nfcon_exit);
+MODULE_DESCRIPTION("Atari NatFeat console driver");
MODULE_LICENSE("GPL");
diff --git a/arch/m68k/include/asm/cmpxchg.h b/arch/m68k/include/asm/cmpxchg.h
index d7f3de9c5d6f..4ba14f3535fc 100644
--- a/arch/m68k/include/asm/cmpxchg.h
+++ b/arch/m68k/include/asm/cmpxchg.h
@@ -32,7 +32,7 @@ static inline unsigned long __arch_xchg(unsigned long x, volatile void * ptr, in
x = tmp;
break;
default:
- tmp = __invalid_xchg_size(x, ptr, size);
+ x = __invalid_xchg_size(x, ptr, size);
break;
}
diff --git a/arch/m68k/include/asm/pgtable.h b/arch/m68k/include/asm/pgtable.h
index 27525c6a12fd..49fcfd734860 100644
--- a/arch/m68k/include/asm/pgtable.h
+++ b/arch/m68k/include/asm/pgtable.h
@@ -2,6 +2,8 @@
#ifndef __M68K_PGTABLE_H
#define __M68K_PGTABLE_H
+#include <asm/page.h>
+
#ifdef __uClinux__
#include <asm/pgtable_no.h>
#else
diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h
index 31be2ad999ca..3e31adbddc75 100644
--- a/arch/m68k/include/asm/thread_info.h
+++ b/arch/m68k/include/asm/thread_info.h
@@ -12,14 +12,15 @@
*/
#if PAGE_SHIFT < 13
#ifdef CONFIG_4KSTACKS
-#define THREAD_SIZE 4096
+#define THREAD_SIZE_ORDER 0
#else
-#define THREAD_SIZE 8192
+#define THREAD_SIZE_ORDER 1
#endif
#else
-#define THREAD_SIZE PAGE_SIZE
+#define THREAD_SIZE_ORDER 0
#endif
-#define THREAD_SIZE_ORDER ((THREAD_SIZE / PAGE_SIZE) - 1)
+
+#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#ifndef __ASSEMBLY__
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 4ae52414cd9d..2e0047cf86f8 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -30,6 +30,5 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
-#define __ARCH_WANT_SYS_CLONE3
#endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/video.h
index 9941b7434b69..6cf2194c413d 100644
--- a/arch/m68k/include/asm/fb.h
+++ b/arch/m68k/include/asm/video.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
#include <asm/page.h>
#include <asm/setup.h>
@@ -27,6 +27,6 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
}
#define pgprot_framebuffer pgprot_framebuffer
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/m68k/include/uapi/asm/ptrace.h b/arch/m68k/include/uapi/asm/ptrace.h
index 5b50ea592e00..ebd9fccb3d11 100644
--- a/arch/m68k/include/uapi/asm/ptrace.h
+++ b/arch/m68k/include/uapi/asm/ptrace.h
@@ -39,7 +39,7 @@ struct pt_regs {
long d0;
long orig_d0;
long stkadj;
-#ifdef CONFIG_COLDFIRE
+#ifdef __mcoldfire__
unsigned format : 4; /* frame format specifier */
unsigned vector : 12; /* vector offset */
unsigned short sr;
diff --git a/arch/m68k/install.sh b/arch/m68k/install.sh
index af65e16e5147..b6829b3942b3 100755
--- a/arch/m68k/install.sh
+++ b/arch/m68k/install.sh
@@ -16,6 +16,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
fi
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 3bcdd32a6b36..338b474910f7 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -430,7 +430,9 @@ resume:
movec %a0,%dfc
/* restore status register */
- movew %a1@(TASK_THREAD+THREAD_SR),%sr
+ movew %a1@(TASK_THREAD+THREAD_SR),%d0
+ oriw #0x0700,%d0
+ movew %d0,%sr
rts
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 7fd43fd4c9f2..22a3cbd4c602 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -461,3 +461,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 4c8f8cbfa05f..e7f0f72c1b36 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -453,30 +453,18 @@ void mac_poweroff(void)
void mac_reset(void)
{
- if (macintosh_config->adb_type == MAC_ADB_II &&
- macintosh_config->ident != MAC_MODEL_SE30) {
- /* need ROMBASE in booter */
- /* indeed, plus need to MAP THE ROM !! */
-
- if (mac_bi_data.rombase == 0)
- mac_bi_data.rombase = 0x40800000;
-
- /* works on some */
- rom_reset = (void *) (mac_bi_data.rombase + 0xa);
-
- local_irq_disable();
- rom_reset();
#ifdef CONFIG_ADB_CUDA
- } else if (macintosh_config->adb_type == MAC_ADB_EGRET ||
- macintosh_config->adb_type == MAC_ADB_CUDA) {
+ if (macintosh_config->adb_type == MAC_ADB_EGRET ||
+ macintosh_config->adb_type == MAC_ADB_CUDA) {
cuda_restart();
+ } else
#endif
#ifdef CONFIG_ADB_PMU
- } else if (macintosh_config->adb_type == MAC_ADB_PB2) {
+ if (macintosh_config->adb_type == MAC_ADB_PB2) {
pmu_restart();
+ } else
#endif
- } else if (CPU_IS_030) {
-
+ if (CPU_IS_030) {
/* 030-specific reset routine. The idea is general, but the
* specific registers to reset are '030-specific. Until I
* have a non-030 machine, I can't test anything else.
@@ -524,6 +512,18 @@ void mac_reset(void)
"jmp %/a0@\n\t" /* jump to the reset vector */
".chip 68k"
: : "r" (offset), "a" (rombase) : "a0");
+ } else {
+ /* need ROMBASE in booter */
+ /* indeed, plus need to MAP THE ROM !! */
+
+ if (mac_bi_data.rombase == 0)
+ mac_bi_data.rombase = 0x40800000;
+
+ /* works on some */
+ rom_reset = (void *)(mac_bi_data.rombase + 0xa);
+
+ local_irq_disable();
+ rom_reset();
}
/* should never get here */
diff --git a/arch/microblaze/configs/mmu_defconfig b/arch/microblaze/configs/mmu_defconfig
index 4da7bc4ac4a3..176314f3c9aa 100644
--- a/arch/microblaze/configs/mmu_defconfig
+++ b/arch/microblaze/configs/mmu_defconfig
@@ -4,7 +4,7 @@ CONFIG_AUDIT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_EXPERT=y
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
CONFIG_KALLSYMS_ALL=y
CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index 4393bee64eaf..85c4d29ef43e 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -7,7 +7,6 @@ ifdef CONFIG_FUNCTION_TRACER
# Do not trace early boot code and low level code
CFLAGS_REMOVE_timer.o = -pg
CFLAGS_REMOVE_intc.o = -pg
-CFLAGS_REMOVE_early_printk.o = -pg
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_process.o = -pg
endif
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index 85dbda4a08a8..03da36dc6d9c 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -18,7 +18,7 @@ static const char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
#define err_printk(x) \
- early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n");
+ pr_err("ERROR: Microblaze " x "-different for kernel and DTS\n");
void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
{
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index ed9f34da1a2a..0850b099f300 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -35,7 +35,7 @@
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, fd,
- off_t, pgoff)
+ unsigned long, pgoff)
{
if (pgoff & ~PAGE_MASK)
return -EINVAL;
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index b00ab2cabab9..2b81a6bd78b2 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -467,3 +467,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 5c145b67d3bf..bca37ddf974b 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -8,6 +8,7 @@ platform-$(CONFIG_BCM47XX) += bcm47xx/
platform-$(CONFIG_BCM63XX) += bcm63xx/
platform-$(CONFIG_BMIPS_GENERIC) += bmips/
platform-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon/
+platform-$(CONFIG_EYEQ) += mobileye/
platform-$(CONFIG_MIPS_COBALT) += cobalt/
platform-$(CONFIG_MACH_DECSTATION) += dec/
platform-$(CONFIG_MIPS_GENERIC) += generic/
@@ -17,7 +18,6 @@ platform-$(CONFIG_MACH_LOONGSON2EF) += loongson2ef/
platform-$(CONFIG_MACH_LOONGSON32) += loongson32/
platform-$(CONFIG_MACH_LOONGSON64) += loongson64/
platform-$(CONFIG_MIPS_MALTA) += mti-malta/
-platform-$(CONFIG_MACH_EYEQ5) += mobileye/
platform-$(CONFIG_MACH_NINTENDO64) += n64/
platform-$(CONFIG_PIC32MZDA) += pic32/
platform-$(CONFIG_RALINK) += ralink/
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 516dc7022bd7..60077e576935 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -30,7 +30,7 @@ config MIPS
select BUILDTIME_TABLE_SORT
select CLONE_BACKWARDS
select CPU_NO_EFFICIENT_FFS if (TARGET_ISA_REV < 1)
- select CPU_PM if CPU_IDLE
+ select CPU_PM if CPU_IDLE || SUSPEND
select GENERIC_ATOMIC64 if !64BIT
select GENERIC_CMOS_UPDATE
select GENERIC_CPU_AUTOPROBE
@@ -68,7 +68,7 @@ config MIPS
select HAVE_DYNAMIC_FTRACE
select HAVE_EBPF_JIT if !CPU_MICROMIPS
select HAVE_EXIT_THREAD
- select HAVE_FAST_GUP
+ select HAVE_GUP_FAST
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
@@ -478,6 +478,7 @@ config MACH_LOONGSON64
select BOARD_SCACHE
select CSRC_R4K
select CEVT_R4K
+ select SYNC_R4K
select FORCE_PCI
select ISA
select I8259
@@ -575,8 +576,8 @@ config MACH_PIC32
Microchip PIC32 is a family of general-purpose 32 bit MIPS core
microcontrollers.
-config MACH_EYEQ5
- bool "Mobileye EyeQ5 SoC"
+config EYEQ
+ bool "Mobileye EyeQ SoC"
select MACH_GENERIC_CORE
select ARM_AMBA
select PHYSICAL_START_BOOL
@@ -615,7 +616,7 @@ config MACH_EYEQ5
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select USE_OF
help
- Select this to build a kernel supporting EyeQ5 SoC from Mobileye.
+ Select this to build a kernel supporting EyeQ SoC from Mobileye.
bool
@@ -667,6 +668,7 @@ config MACH_REALTEK_RTL
select BOOT_RAW
select PINCTRL
select USE_OF
+ select REALTEK_OTTO_TIMER
config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
@@ -1021,6 +1023,7 @@ source "arch/mips/generic/Kconfig"
source "arch/mips/ingenic/Kconfig"
source "arch/mips/jazz/Kconfig"
source "arch/mips/lantiq/Kconfig"
+source "arch/mips/mobileye/Kconfig"
source "arch/mips/pic32/Kconfig"
source "arch/mips/ralink/Kconfig"
source "arch/mips/sgi-ip27/Kconfig"
@@ -1083,6 +1086,7 @@ config CSRC_IOASIC
config CSRC_R4K
select CLOCKSOURCE_WATCHDOG if CPU_FREQ
+ select HAVE_UNSTABLE_SCHED_CLOCK if SMP && 64BIT
bool
config CSRC_SB1250
@@ -2924,7 +2928,8 @@ config BUILTIN_DTB
bool
choice
- prompt "Kernel appended dtb support" if USE_OF
+ prompt "Kernel appended dtb support"
+ depends on USE_OF
default MIPS_NO_APPENDED_DTB
config MIPS_NO_APPENDED_DTB
@@ -2965,7 +2970,8 @@ choice
endchoice
choice
- prompt "Kernel command line type" if !CMDLINE_OVERRIDE
+ prompt "Kernel command line type"
+ depends on !CMDLINE_OVERRIDE
default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \
!MACH_LOONGSON64 && !MIPS_MALTA && \
!CAVIUM_OCTEON_SOC
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 80aecba24892..5785a3d5ccfb 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -170,7 +170,7 @@ cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=mips4) \
-Wa,--trap
cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=mips4) \
-Wa,--trap
-cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=mips64r1) \
+cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=mips64) \
-Wa,--trap
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx)
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d)
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index d4ab34b3b404..da74cae6b43a 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -409,8 +409,8 @@ static void __init alchemy_setup_macs(int ctype)
if (alchemy_get_macs(ctype) < 1)
return;
- macres = kmemdup(au1xxx_eth0_resources[ctype],
- sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+ macres = kmemdup_array(au1xxx_eth0_resources[ctype], MAC_RES_COUNT,
+ sizeof(*macres), GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
return;
@@ -430,8 +430,8 @@ static void __init alchemy_setup_macs(int ctype)
if (alchemy_get_macs(ctype) < 2)
return;
- macres = kmemdup(au1xxx_eth1_resources[ctype],
- sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+ macres = kmemdup_array(au1xxx_eth1_resources[ctype], MAC_RES_COUNT,
+ sizeof(*macres), GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
return;
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c
index 7b9f91db227f..6984cd5169b5 100644
--- a/arch/mips/alchemy/devboards/db1000.c
+++ b/arch/mips/alchemy/devboards/db1000.c
@@ -10,15 +10,16 @@
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
+#include <linux/gpio/property.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
-#include <linux/spi/ads7846.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/gpio-au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>
@@ -374,22 +375,20 @@ static struct platform_device db1100_mmc1_dev = {
/******************************************************************************/
-static struct ads7846_platform_data db1100_touch_pd = {
- .model = 7846,
- .vref_mv = 3300,
+static const struct software_node db1100_alchemy2_gpiochip = {
+ .name = "alchemy-gpio2",
};
-static struct spi_gpio_platform_data db1100_spictl_pd = {
- .num_chipselect = 1,
+static const struct property_entry db1100_ads7846_properties[] = {
+ PROPERTY_ENTRY_U16("ti,vref_min", 3300),
+ PROPERTY_ENTRY_GPIO("pendown-gpios",
+ &db1100_alchemy2_gpiochip, 21, GPIO_ACTIVE_LOW),
+ { }
};
-static struct gpiod_lookup_table db1100_touch_gpio_table = {
- .dev_id = "spi0.0",
- .table = {
- GPIO_LOOKUP("alchemy-gpio2", 21,
- "pendown", GPIO_ACTIVE_LOW),
- { }
- },
+static const struct software_node db1100_ads7846_swnode = {
+ .name = "ads7846",
+ .properties = db1100_ads7846_properties,
};
static struct spi_board_info db1100_spi_info[] __initdata = {
@@ -400,37 +399,37 @@ static struct spi_board_info db1100_spi_info[] __initdata = {
.chip_select = 0,
.mode = 0,
.irq = AU1100_GPIO21_INT,
- .platform_data = &db1100_touch_pd,
+ .swnode = &db1100_ads7846_swnode,
},
};
-static struct platform_device db1100_spi_dev = {
- .name = "spi_gpio",
- .id = 0,
- .dev = {
- .platform_data = &db1100_spictl_pd,
- .dma_mask = &au1xxx_all_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
+static const struct spi_gpio_platform_data db1100_spictl_pd __initconst = {
+ .num_chipselect = 1,
};
/*
* Alchemy GPIO 2 has its base at 200 so the GPIO lines
* 207 thru 210 are GPIOs at offset 7 thru 10 at this chip.
*/
-static struct gpiod_lookup_table db1100_spi_gpiod_table = {
- .dev_id = "spi_gpio",
- .table = {
- GPIO_LOOKUP("alchemy-gpio2", 9,
- "sck", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("alchemy-gpio2", 8,
- "mosi", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("alchemy-gpio2", 7,
- "miso", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("alchemy-gpio2", 10,
- "cs", GPIO_ACTIVE_HIGH),
- { },
- },
+static const struct property_entry db1100_spi_dev_properties[] __initconst = {
+ PROPERTY_ENTRY_GPIO("miso-gpios",
+ &db1100_alchemy2_gpiochip, 7, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("mosi-gpios",
+ &db1100_alchemy2_gpiochip, 8, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("sck-gpios",
+ &db1100_alchemy2_gpiochip, 9, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("cs-gpios",
+ &db1100_alchemy2_gpiochip, 10, GPIO_ACTIVE_HIGH),
+ { }
+};
+
+static const struct platform_device_info db1100_spi_dev_info __initconst = {
+ .name = "spi_gpio",
+ .id = 0,
+ .data = &db1100_spictl_pd,
+ .size_data = sizeof(db1100_spictl_pd),
+ .dma_mask = DMA_BIT_MASK(32),
+ .properties = db1100_spi_dev_properties,
};
static struct platform_device *db1x00_devs[] = {
@@ -452,8 +451,10 @@ int __init db1000_dev_setup(void)
{
int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1;
+ int err;
unsigned long pfc;
struct clk *c, *p;
+ struct platform_device *spi_dev;
if (board == BCSR_WHOAMI_DB1500) {
c0 = AU1500_GPIO2_INT;
@@ -480,7 +481,7 @@ int __init db1000_dev_setup(void)
pfc |= (1 << 0); /* SSI0 pins as GPIOs */
alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);
- gpiod_add_lookup_table(&db1100_touch_gpio_table);
+ software_node_register(&db1100_alchemy2_gpiochip);
spi_register_board_info(db1100_spi_info,
ARRAY_SIZE(db1100_spi_info));
@@ -497,8 +498,11 @@ int __init db1000_dev_setup(void)
clk_put(p);
platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
- gpiod_add_lookup_table(&db1100_spi_gpiod_table);
- platform_device_register(&db1100_spi_dev);
+
+ spi_dev = platform_device_register_full(&db1100_spi_dev_info);
+ err = PTR_ERR_OR_ZERO(spi_dev);
+ if (err)
+ pr_err("failed to register SPI controller: %d\n", err);
} else if (board == BCSR_WHOAMI_DB1000) {
c0 = AU1000_GPIO2_INT;
c1 = AU1000_GPIO5_INT;
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index 99a1ba5394e0..66e3ee2b04e6 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -32,9 +32,11 @@
#include <linux/ssb/ssb_driver_chipcommon.h>
#include <linux/ssb/ssb_regs.h>
#include <linux/smp.h>
+#include <asm/bmips.h>
#include <asm/bootinfo.h>
#include <bcm47xx.h>
#include <bcm47xx_board.h>
+#include "bcm47xx_private.h"
static char bcm47xx_system_type[20] = "Broadcom BCM47XX";
@@ -109,6 +111,8 @@ static __init void prom_init_mem(void)
void __init prom_init(void)
{
+ /* Cache CBR addr before CPU/DMA setup */
+ bmips_cbr_addr = BMIPS_GET_CBR();
prom_init_mem();
setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0);
}
@@ -123,7 +127,7 @@ void __init prom_init(void)
/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
* dropped. Calling it at this stage causes a hang.
*/
-void early_tlb_init(void)
+static void early_tlb_init(void)
{
write_c0_pagemask(PM_DEFAULT_MASK);
write_c0_wired(0);
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 94bf839576c1..247be207f293 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -37,6 +37,7 @@
#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_embedded.h>
#include <linux/bcma/bcma_soc.h>
+#include <asm/bmips.h>
#include <asm/bootinfo.h>
#include <asm/idle.h>
#include <asm/prom.h>
@@ -45,6 +46,13 @@
#include <bcm47xx.h>
#include <bcm47xx_board.h>
+/*
+ * CBR addr doesn't change and we can cache it.
+ * For broken SoC/Bootloader CBR addr might also be provided via DT
+ * with "brcm,bmips-cbr-reg" in the "cpus" node.
+ */
+void __iomem *bmips_cbr_addr __read_mostly;
+
union bcm47xx_bus bcm47xx_bus;
EXPORT_SYMBOL(bcm47xx_bus);
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
index c3a2ea62c5c3..f21dd168171a 100644
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -22,6 +22,9 @@ void __init prom_init(void)
{
u32 reg, mask;
+ /* Cache CBR addr before CPU/DMA setup */
+ bmips_cbr_addr = BMIPS_GET_CBR();
+
bcm63xx_cpu_init();
/* stop any running watchdog */
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index c13ddb544a23..81529084bc75 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -12,6 +12,7 @@
#include <linux/memblock.h>
#include <linux/ioport.h>
#include <linux/pm.h>
+#include <asm/bmips.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/reboot.h>
@@ -22,6 +23,13 @@
#include <bcm63xx_io.h>
#include <bcm63xx_gpio.h>
+/*
+ * CBR addr doesn't change and we can cache it.
+ * For broken SoC/Bootloader CBR addr might also be provided via DT
+ * with "brcm,bmips-cbr-reg" in the "cpus" node.
+ */
+void __iomem *bmips_cbr_addr __read_mostly;
+
void bcm63xx_machine_halt(void)
{
pr_info("System halted\n");
diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
index 3779e7855bd7..2bc9c0d4402f 100644
--- a/arch/mips/bmips/dma.c
+++ b/arch/mips/bmips/dma.c
@@ -9,7 +9,7 @@ bool bmips_rac_flush_disable;
void arch_sync_dma_for_cpu_all(void)
{
- void __iomem *cbr = BMIPS_GET_CBR();
+ void __iomem *cbr = bmips_cbr_addr;
u32 cfg;
if (boot_cpu_type() != CPU_BMIPS3300 &&
diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c
index ec180ab92eaa..2572fd49a6e9 100644
--- a/arch/mips/bmips/setup.c
+++ b/arch/mips/bmips/setup.c
@@ -34,6 +34,13 @@
#define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c))
#define BCM6328_TP1_DISABLED BIT(9)
+/*
+ * CBR addr doesn't change and we can cache it.
+ * For broken SoC/Bootloader CBR addr might also be provided via DT
+ * with "brcm,bmips-cbr-reg" in the "cpus" node.
+ */
+void __iomem *bmips_cbr_addr __read_mostly;
+
extern bool bmips_rac_flush_disable;
static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
@@ -110,7 +117,8 @@ static void bcm6358_quirks(void)
* RAC flush causes kernel panics on BCM6358 when booting from TP1
* because the bootloader is not initializing it properly.
*/
- bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31));
+ bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) ||
+ !!bmips_cbr_addr;
}
static void bcm6368_quirks(void)
@@ -143,6 +151,8 @@ static void __init bmips_init_cfe(void)
void __init prom_init(void)
{
+ /* Cache CBR addr before CPU/DMA setup */
+ bmips_cbr_addr = BMIPS_GET_CBR();
bmips_init_cfe();
bmips_cpu_setup();
register_bmips_smp_ops();
@@ -202,13 +212,35 @@ void __init plat_mem_setup(void)
void __init device_tree_init(void)
{
struct device_node *np;
+ u32 addr;
unflatten_and_copy_device_tree();
/* Disable SMP boot unless both CPUs are listed in DT and !disabled */
np = of_find_node_by_name(NULL, "cpus");
- if (np && of_get_available_child_count(np) <= 1)
+ if (!np)
+ return;
+
+ if (of_get_available_child_count(np) <= 1)
bmips_smp_enabled = 0;
+
+ /* Check if DT provide a CBR address */
+ if (of_property_read_u32(np, "brcm,bmips-cbr-reg", &addr))
+ goto exit;
+
+ /* Make sure CBR address is outside DRAM window */
+ if (addr >= (u32)memblock_start_of_DRAM() &&
+ addr < (u32)memblock_end_of_DRAM()) {
+ WARN(1, "DT CBR %x inside DRAM window. Ignoring DT CBR.\n",
+ addr);
+ goto exit;
+ }
+
+ bmips_cbr_addr = (void __iomem *)addr;
+ /* Since CBR is provided by DT, enable RAC flush */
+ bmips_rac_flush_disable = false;
+
+exit:
of_node_put(np);
}
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 6cc28173bee8..e0b8ec9a9516 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -34,12 +34,6 @@ KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
-DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-KCSAN_SANITIZE := n
-
# decompressor objects (linked with vmlinuz)
vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/bswapsi.o
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index efff87cb33a9..e2476b12bb0c 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
subdir-$(CONFIG_BMIPS_GENERIC) += brcm
subdir-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon
+subdir-$(CONFIG_EYEQ) += mobileye
subdir-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += img
subdir-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += img
subdir-$(CONFIG_MACH_INGENIC) += ingenic
@@ -8,7 +9,6 @@ subdir-$(CONFIG_LANTIQ) += lantiq
subdir-$(CONFIG_MACH_LOONGSON64) += loongson
subdir-$(CONFIG_SOC_VCOREIII) += mscc
subdir-$(CONFIG_MIPS_MALTA) += mti
-subdir-$(CONFIG_MACH_EYEQ5) += mobileye
subdir-$(CONFIG_LEGACY_BOARD_SEAD3) += mti
subdir-$(CONFIG_FIT_IMAGE_FDT_NI169445) += ni
subdir-$(CONFIG_MACH_PIC32) += pic32
diff --git a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi
index ee3e2153dd13..cc7747c5f21f 100644
--- a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi
+++ b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi
@@ -23,14 +23,6 @@
};
};
- memory@200000 {
- compatible = "memory";
- device_type = "memory";
- reg = <0x00000000 0x00200000 0x00000000 0x0ee00000>, /* 238 MB at 2 MB */
- <0x00000000 0x20000000 0x00000000 0x1f000000>, /* 496 MB at 512 MB */
- <0x00000001 0x10000000 0x00000001 0xb0000000>; /* 6912 MB at 4352MB */
- };
-
cpu_clk: cpu_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
@@ -52,6 +44,13 @@
0 0x40000000 0 0x40000000 0 0x40000000
0xfe 0x00000000 0xfe 0x00000000 0 0x40000000>;
+ isa@18000000 {
+ compatible = "isa";
+ #size-cells = <1>;
+ #address-cells = <2>;
+ ranges = <1 0x0 0x0 0x18000000 0x4000>;
+ };
+
pm: reset-controller@1fe07000 {
compatible = "loongson,ls2k-pm";
reg = <0 0x1fe07000 0 0x422>;
@@ -100,8 +99,8 @@
rtc0: rtc@1fe07800 {
compatible = "loongson,ls2k1000-rtc";
reg = <0 0x1fe07800 0 0x78>;
- interrupt-parent = <&liointc0>;
- interrupts = <60 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&liointc1>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
};
uart0: serial@1fe00000 {
@@ -109,7 +108,7 @@
reg = <0 0x1fe00000 0 0x8>;
clock-frequency = <125000000>;
interrupt-parent = <&liointc0>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
no-loopback-test;
};
@@ -118,7 +117,6 @@
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
- #interrupt-cells = <2>;
reg = <0 0x1a000000 0 0x02000000>,
<0xfe 0x00000000 0 0x20000000>;
@@ -133,11 +131,12 @@
"pciclass0c03";
reg = <0x1800 0x0 0x0 0x0 0x0>;
- interrupts = <12 IRQ_TYPE_LEVEL_LOW>,
- <13 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH>,
+ <13 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&liointc0>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy1>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
@@ -156,11 +155,12 @@
"loongson, pci-gmac";
reg = <0x1900 0x0 0x0 0x0 0x0>;
- interrupts = <14 IRQ_TYPE_LEVEL_LOW>,
- <15 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>,
+ <15 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&liointc0>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy1>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
@@ -178,7 +178,7 @@
"pciclass0c03";
reg = <0x2100 0x0 0x0 0x0 0x0>;
- interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
};
@@ -189,7 +189,7 @@
"pciclass0c03";
reg = <0x2200 0x0 0x0 0x0 0x0>;
- interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
};
@@ -200,97 +200,121 @@
"pciclass0106";
reg = <0x4000 0x0 0x0 0x0 0x0>;
- interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc0>;
};
- pci_bridge@9,0 {
+ pcie@9,0 {
compatible = "pci0014,7a19.0",
"pci0014,7a19",
"pciclass060400",
"pciclass0604";
reg = <0x4800 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
#interrupt-cells = <1>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &liointc1 0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-map = <0 0 0 0 &liointc1 0 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
external-facing;
};
- pci_bridge@a,0 {
+ pcie@a,0 {
compatible = "pci0014,7a09.0",
"pci0014,7a09",
"pciclass060400",
"pciclass0604";
reg = <0x5000 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
#interrupt-cells = <1>;
- interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &liointc1 1 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-map = <0 0 0 0 &liointc1 1 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
external-facing;
};
- pci_bridge@b,0 {
+ pcie@b,0 {
compatible = "pci0014,7a09.0",
"pci0014,7a09",
"pciclass060400",
"pciclass0604";
reg = <0x5800 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
#interrupt-cells = <1>;
- interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &liointc1 2 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-map = <0 0 0 0 &liointc1 2 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
external-facing;
};
- pci_bridge@c,0 {
+ pcie@c,0 {
compatible = "pci0014,7a09.0",
"pci0014,7a09",
"pciclass060400",
"pciclass0604";
reg = <0x6000 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
#interrupt-cells = <1>;
- interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &liointc1 3 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-map = <0 0 0 0 &liointc1 3 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
external-facing;
};
- pci_bridge@d,0 {
+ pcie@d,0 {
compatible = "pci0014,7a19.0",
"pci0014,7a19",
"pciclass060400",
"pciclass0604";
reg = <0x6800 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
#interrupt-cells = <1>;
- interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &liointc1 4 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-map = <0 0 0 0 &liointc1 4 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
external-facing;
};
- pci_bridge@e,0 {
+ pcie@e,0 {
compatible = "pci0014,7a09.0",
"pci0014,7a09",
"pciclass060400",
"pciclass0604";
reg = <0x7000 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
#interrupt-cells = <1>;
- interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&liointc1>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &liointc1 5 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-map = <0 0 0 0 &liointc1 5 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
external-facing;
};
diff --git a/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts b/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts
index c945f8565d54..fb180cb2b8e2 100644
--- a/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts
+++ b/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts
@@ -33,6 +33,7 @@
compatible = "loongson,pch-msi-1.0";
reg = <0 0x2ff00000 0 0x8>;
interrupt-controller;
+ #interrupt-cells = <1>;
msi-controller;
loongson,msi-base-vec = <64>;
loongson,msi-num-vecs = <192>;
diff --git a/arch/mips/boot/dts/mobileye/Makefile b/arch/mips/boot/dts/mobileye/Makefile
index 01c01c3aad81..7cc89968aaac 100644
--- a/arch/mips/boot/dts/mobileye/Makefile
+++ b/arch/mips/boot/dts/mobileye/Makefile
@@ -2,3 +2,4 @@
# Copyright 2023 Mobileye Vision Technologies Ltd.
dtb-$(CONFIG_MACH_EYEQ5) += eyeq5-epm5.dtb
+dtb-$(CONFIG_MACH_EYEQ6H) += eyeq6h-epm6.dtb
diff --git a/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi b/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi
index 78f5533a95c6..17a342cc744e 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi
@@ -3,42 +3,20 @@
* Copyright 2023 Mobileye Vision Technologies Ltd.
*/
+#include <dt-bindings/clock/mobileye,eyeq5-clk.h>
+
/ {
/* Fixed clock */
- pll_cpu: pll-cpu {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <1500000000>;
- };
-
- pll_vdi: pll-vdi {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <1280000000>;
- };
-
- pll_per: pll-per {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <2000000000>;
- };
-
- pll_ddr0: pll-ddr0 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <1857210000>;
- };
-
- pll_ddr1: pll-ddr1 {
+ xtal: xtal {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <1857210000>;
+ clock-frequency = <30000000>;
};
/* PLL_CPU derivatives */
occ_cpu: occ-cpu {
compatible = "fixed-factor-clock";
- clocks = <&pll_cpu>;
+ clocks = <&olb EQ5C_PLL_CPU>;
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <1>;
@@ -101,7 +79,7 @@
};
occ_isram: occ-isram {
compatible = "fixed-factor-clock";
- clocks = <&pll_cpu>;
+ clocks = <&olb EQ5C_PLL_CPU>;
#clock-cells = <0>;
clock-div = <2>;
clock-mult = <1>;
@@ -115,7 +93,7 @@
};
occ_dbu: occ-dbu {
compatible = "fixed-factor-clock";
- clocks = <&pll_cpu>;
+ clocks = <&olb EQ5C_PLL_CPU>;
#clock-cells = <0>;
clock-div = <10>;
clock-mult = <1>;
@@ -130,7 +108,7 @@
/* PLL_VDI derivatives */
occ_vdi: occ-vdi {
compatible = "fixed-factor-clock";
- clocks = <&pll_vdi>;
+ clocks = <&olb EQ5C_PLL_VDI>;
#clock-cells = <0>;
clock-div = <2>;
clock-mult = <1>;
@@ -144,7 +122,7 @@
};
occ_can_ser: occ-can-ser {
compatible = "fixed-factor-clock";
- clocks = <&pll_vdi>;
+ clocks = <&olb EQ5C_PLL_VDI>;
#clock-cells = <0>;
clock-div = <16>;
clock-mult = <1>;
@@ -158,7 +136,7 @@
};
i2c_ser_clk: i2c-ser-clk {
compatible = "fixed-factor-clock";
- clocks = <&pll_vdi>;
+ clocks = <&olb EQ5C_PLL_VDI>;
#clock-cells = <0>;
clock-div = <20>;
clock-mult = <1>;
@@ -166,7 +144,7 @@
/* PLL_PER derivatives */
occ_periph: occ-periph {
compatible = "fixed-factor-clock";
- clocks = <&pll_per>;
+ clocks = <&olb EQ5C_PLL_PER>;
#clock-cells = <0>;
clock-div = <16>;
clock-mult = <1>;
@@ -225,7 +203,7 @@
};
emmc_sys_clk: emmc-sys-clk {
compatible = "fixed-factor-clock";
- clocks = <&pll_per>;
+ clocks = <&olb EQ5C_PLL_PER>;
#clock-cells = <0>;
clock-div = <10>;
clock-mult = <1>;
@@ -233,7 +211,7 @@
};
ccf_ctrl_clk: ccf-ctrl-clk {
compatible = "fixed-factor-clock";
- clocks = <&pll_per>;
+ clocks = <&olb EQ5C_PLL_PER>;
#clock-cells = <0>;
clock-div = <4>;
clock-mult = <1>;
@@ -241,7 +219,7 @@
};
occ_mjpeg_core: occ-mjpeg-core {
compatible = "fixed-factor-clock";
- clocks = <&pll_per>;
+ clocks = <&olb EQ5C_PLL_PER>;
#clock-cells = <0>;
clock-div = <2>;
clock-mult = <1>;
@@ -265,7 +243,7 @@
};
fcmu_a_clk: fcmu-a-clk {
compatible = "fixed-factor-clock";
- clocks = <&pll_per>;
+ clocks = <&olb EQ5C_PLL_PER>;
#clock-cells = <0>;
clock-div = <20>;
clock-mult = <1>;
@@ -273,7 +251,7 @@
};
occ_pci_sys: occ-pci-sys {
compatible = "fixed-factor-clock";
- clocks = <&pll_per>;
+ clocks = <&olb EQ5C_PLL_PER>;
#clock-cells = <0>;
clock-div = <8>;
clock-mult = <1>;
diff --git a/arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi b/arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi
new file mode 100644
index 000000000000..0b3671013ab4
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+/*
+ * Default pin configuration for Mobileye EyeQ5 boards. We mostly create one
+ * pin configuration node per function.
+ */
+
+&olb {
+ timer0_pins: timer0-pins {
+ function = "timer0";
+ pins = "PA0", "PA1";
+ };
+ timer1_pins: timer1-pins {
+ function = "timer1";
+ pins = "PA2", "PA3";
+ };
+ timer2_pins: timer2-pins {
+ function = "timer2";
+ pins = "PA4", "PA5";
+ };
+ pps0_pins: pps0-pin {
+ function = "timer2";
+ pins = "PA4";
+ };
+ pps1_pins: pps1-pin {
+ function = "timer2";
+ pins = "PA5";
+ };
+ timer5_ext_pins: timer5-ext-pins {
+ function = "timer5";
+ pins = "PA6", "PA7", "PA8", "PA9";
+ };
+ timer5_ext_input_pins: timer5-ext-input-pins {
+ function = "timer5";
+ pins = "PA6", "PA7";
+ };
+ timer5_ext_incap_a_pins: timer5-ext-incap-a-pin {
+ function = "timer5";
+ pins = "PA6";
+ };
+ timer5_ext_incap_b_pins: timer5-ext-incap-b-pin {
+ function = "timer5";
+ pins = "PA7";
+ };
+ can0_pins: can0-pins {
+ function = "can0";
+ pins = "PA14", "PA15";
+ };
+ can1_pins: can1-pins {
+ function = "can1";
+ pins = "PA16", "PA17";
+ };
+ uart0_pins: uart0-pins {
+ function = "uart0";
+ pins = "PA10", "PA11";
+ };
+ uart1_pins: uart1-pins {
+ function = "uart1";
+ pins = "PA12", "PA13";
+ };
+ spi0_pins: spi0-pins {
+ function = "spi0";
+ pins = "PA18", "PA19", "PA20", "PA21", "PA22";
+ };
+ spi1_pins: spi1-pins {
+ function = "spi1";
+ pins = "PA23", "PA24", "PA25", "PA26", "PA27";
+ };
+ spi1_slave_pins: spi1-slave-pins {
+ function = "spi1";
+ pins = "PA24", "PA25", "PA26";
+ };
+ refclk0_pins: refclk0-pin {
+ function = "refclk0";
+ pins = "PA28";
+ };
+ timer3_pins: timer3-pins {
+ function = "timer3";
+ pins = "PB0", "PB1";
+ };
+ timer4_pins: timer4-pins {
+ function = "timer4";
+ pins = "PB2", "PB3";
+ };
+ timer6_ext_pins: timer6-ext-pins {
+ function = "timer6";
+ pins = "PB4", "PB5", "PB6", "PB7";
+ };
+ timer6_ext_input_pins: timer6-ext-input-pins {
+ function = "timer6";
+ pins = "PB4", "PB5";
+ };
+ timer6_ext_incap_a_pins: timer6-ext-incap-a-pin {
+ function = "timer6";
+ pins = "PB4";
+ };
+ timer6_ext_incap_b_pins: timer6-ext-incap-b-pin {
+ function = "timer6";
+ pins = "PB5";
+ };
+ can2_pins: can2-pins {
+ function = "can2";
+ pins = "PB10", "PB11";
+ };
+ uart2_pins: uart2-pins {
+ function = "uart2";
+ pins = "PB8", "PB9";
+ };
+ spi2_pins: spi2-pins {
+ function = "spi2";
+ pins = "PB12", "PB13", "PB14", "PB15", "PB16";
+ };
+ spi3_pins: spi3-pins {
+ function = "spi3";
+ pins = "PB17", "PB18", "PB19", "PB20", "PB21";
+ };
+ spi3_slave_pins: spi3-slave-pins {
+ function = "spi3";
+ pins = "PB18", "PB19", "PB20";
+ };
+ mclk0_pins: mclk0-pin {
+ function = "mclk0";
+ pins = "PB22";
+ };
+};
diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index 6cc5980e2fa1..0708771c193d 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -5,7 +5,7 @@
#include <dt-bindings/interrupt-controller/mips-gic.h>
-#include "eyeq5-fixed-clocks.dtsi"
+#include "eyeq5-clocks.dtsi"
/ {
#address-cells = <2>;
@@ -78,6 +78,9 @@
interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart_clk>, <&occ_periph>;
clock-names = "uartclk", "apb_pclk";
+ resets = <&olb 0 10>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
};
uart1: serial@900000 {
@@ -88,6 +91,9 @@
interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart_clk>, <&occ_periph>;
clock-names = "uartclk", "apb_pclk";
+ resets = <&olb 0 11>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
};
uart2: serial@a00000 {
@@ -98,6 +104,18 @@
interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart_clk>, <&occ_periph>;
clock-names = "uartclk", "apb_pclk";
+ resets = <&olb 0 12>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ };
+
+ olb: system-controller@e00000 {
+ compatible = "mobileye,eyeq5-olb", "syscon";
+ reg = <0 0xe00000 0x0 0x400>;
+ #reset-cells = <2>;
+ #clock-cells = <1>;
+ clocks = <&xtal>;
+ clock-names = "ref";
};
gic: interrupt-controller@140000 {
@@ -122,3 +140,5 @@
};
};
};
+
+#include "eyeq5-pins.dtsi"
diff --git a/arch/mips/boot/dts/mobileye/eyeq6h-epm6.dts b/arch/mips/boot/dts/mobileye/eyeq6h-epm6.dts
new file mode 100644
index 000000000000..ebc0d363fbf8
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq6h-epm6.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright 2024 Mobileye Vision Technologies Ltd.
+ */
+
+/dts-v1/;
+
+#include "eyeq6h.dtsi"
+
+/ {
+ compatible = "mobileye,eyeq6-epm6", "mobileye,eyeq6";
+ model = "Mobile EyeQ6H MP6 Evaluation board";
+
+ chosen {
+ stdout-path = "serial0:921600n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x1 0x00000000 0x1 0x00000000>;
+ };
+};
diff --git a/arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi b/arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi
new file mode 100644
index 000000000000..5fa99e06fde7
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright 2023 Mobileye Vision Technologies Ltd.
+ */
+
+#include <dt-bindings/clock/mobileye,eyeq5-clk.h>
+
+/ {
+ xtal: clock-30000000 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <30000000>;
+ };
+
+ pll_west: clock-2000000000-west {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <2000000000>;
+ };
+
+ pll_cpu: clock-2000000000-cpu {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <2000000000>;
+ };
+
+ /* pll-cpu derivatives */
+ occ_cpu: clock-2000000000-occ-cpu {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_cpu>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+
+ /* pll-west derivatives */
+ occ_periph_w: clock-200000000 {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_west>;
+ #clock-cells = <0>;
+ clock-div = <10>;
+ clock-mult = <1>;
+ };
+ uart_clk: clock-200000000-uart {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph_w>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+
+};
diff --git a/arch/mips/boot/dts/mobileye/eyeq6h-pins.dtsi b/arch/mips/boot/dts/mobileye/eyeq6h-pins.dtsi
new file mode 100644
index 000000000000..a3d1b3684893
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq6h-pins.dtsi
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright 2024 Mobileye Vision Technologies Ltd.
+ */
+
+/*
+ * MUX register structure
+ * bits | field | comment
+ * [0] | MUX_SEL | 0 - GPIO, 1 - alternative func
+ * [4] | SW_LOOPBACK|
+ * [5] | SW_OUT_HZ |
+ * [7] | DBG_IN |
+ * [11:8] | DS | drive strength
+ * [13:12] | PUD | pull-up/pull-down. 0, 3 - no, 1 - PD, 2 - PU
+ * [14] | OD | Open drain
+ * [15] | ST_CFG | Hysteretic input enable (Schmitt trigger)
+ */
+
+&pinctrl_west {
+ // TODO: use pinctrl-single,bias-pullup
+ // TODO: use pinctrl-single,bias-pulldown
+ // TODO: use pinctrl-single,drive-strength
+ // TODO: use pinctrl-single,input-schmitt
+
+ i2c0_pins: i2c0-pins {
+ pinctrl-single,pins = <
+ 0x000 0x200 // I2C0_SCL pin
+ 0x004 0x200 // I2C0_SDA pin
+ >;
+ };
+ i2c1_pins: i2c1-pins {
+ pinctrl-single,pins = <
+ 0x008 0x200 // I2C1_SCL pin
+ 0x00c 0x200 // I2C1_SDA pin
+ >;
+ };
+ eth0_pins: eth0-pins {
+ pinctrl-single,pins = <
+ 0x080 1 // GPIO_C4__SMA0_MDC pin
+ 0x084 1 // GPIO_C5__SMA0_MDIO pin
+ >;
+ };
+ uart0_pins: uart0-pins {
+ pinctrl-single,pins = <0x0a8 1>; // UART0 pin group
+ };
+ uart1_pins: uart1-pins {
+ pinctrl-single,pins = <0x0a0 1>; // UART1 pin group
+ };
+ spi0_pins: spi0-pins {
+ pinctrl-single,pins = <0x0ac 1>; // SPI0 pin group
+ };
+ spi1_pins: spi1-pins {
+ pinctrl-single,pins = <0x0a4 1>; // SPI1 pin group
+ };
+};
+
+&pinctrl_east {
+ i2c2_pins: i2c2-pins {
+ pinctrl-single,pins = <
+ 0x000 0x200 // i2c2_SCL pin
+ 0x004 0x200 // i2c2_SDA pin
+ >;
+ };
+ i2c3_pins: i2c3-pins {
+ pinctrl-single,pins = <
+ 0x008 0x200 // i2c3_SCL pin
+ 0x00c 0x200 // i2c3_SDA pin
+ >;
+ };
+ eth1_pins: eth1-pins {
+ pinctrl-single,pins = <
+ 0x080 1 // GPIO_D4__SMA1_MDC pin
+ 0x084 1 // GPIO_D5__SMA1_MDIO pin
+ >;
+ };
+ uart2_sel_pins: uart2-pins {
+ pinctrl-single,pins = <0x0a4 1>; // UART2 pin group
+ };
+ uart3_pins: uart3-pins {
+ pinctrl-single,pins = <0x09c 1>; // UART3 pin group
+ };
+ spi2_pins: spi2-pins {
+ pinctrl-single,pins = <0x0a8 1>; // SPI2 pin group
+ };
+ spi3_pins: spi3-pins {
+ pinctrl-single,pins = <0x0a0 1>; // SPI3 pin group
+ };
+};
diff --git a/arch/mips/boot/dts/mobileye/eyeq6h.dtsi b/arch/mips/boot/dts/mobileye/eyeq6h.dtsi
new file mode 100644
index 000000000000..1db3c3cda2e3
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq6h.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+/*
+ * Copyright 2024 Mobileye Vision Technologies Ltd.
+ */
+
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+
+#include "eyeq6h-fixed-clocks.dtsi"
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "img,i6500";
+ reg = <0>;
+ clocks = <&occ_cpu>;
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ cpu_intc: interrupt-controller {
+ compatible = "mti,cpu-interrupt-controller";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ uart0: serial@d3331000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0 0xd3331000 0x0 0x1000>;
+ reg-io-width = <4>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&occ_periph_w>, <&occ_periph_w>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pinctrl_west: pinctrl@d3337000 {
+ compatible = "pinctrl-single";
+ reg = <0x0 0xd3337000 0x0 0xb0>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffff>;
+ };
+
+ pinctrl_east: pinctrl@d3357000 {
+ compatible = "pinctrl-single";
+ reg = <0x0 0xd3357000 0x0 0xb0>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffff>;
+ };
+
+ pinctrl_south: pinctrl@d8014000 {
+ compatible = "pinctrl-single";
+ reg = <0x0 0xd8014000 0x0 0xf8>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffff>;
+ };
+
+ gic: interrupt-controller@f0920000 {
+ compatible = "mti,gic";
+ reg = <0x0 0xf0920000 0x0 0x20000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+
+ /*
+ * Declare the interrupt-parent even though the mti,gic
+ * binding doesn't require it, such that the kernel can
+ * figure out that cpu_intc is the root interrupt
+ * controller & should be probed first.
+ */
+ interrupt-parent = <&cpu_intc>;
+
+ timer {
+ compatible = "mti,gic-timer";
+ interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+ clocks = <&occ_cpu>;
+ };
+ };
+ };
+};
+
+#include "eyeq6h-pins.dtsi"
diff --git a/arch/mips/boot/dts/ralink/mt7621.dtsi b/arch/mips/boot/dts/ralink/mt7621.dtsi
index 6e95e6f19a6a..0704eab4a80b 100644
--- a/arch/mips/boot/dts/ralink/mt7621.dtsi
+++ b/arch/mips/boot/dts/ralink/mt7621.dtsi
@@ -5,50 +5,143 @@
#include <dt-bindings/reset/mt7621-reset.h>
/ {
+ compatible = "mediatek,mt7621-soc";
+
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mediatek,mt7621-soc";
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
- device_type = "cpu";
compatible = "mips,mips1004Kc";
reg = <0>;
+ device_type = "cpu";
};
cpu@1 {
- device_type = "cpu";
compatible = "mips,mips1004Kc";
reg = <1>;
+ device_type = "cpu";
};
};
cpuintc: cpuintc {
+ compatible = "mti,cpu-interrupt-controller";
+
#address-cells = <0>;
#interrupt-cells = <1>;
+
interrupt-controller;
- compatible = "mti,cpu-interrupt-controller";
};
mmc_fixed_3v3: regulator-3v3 {
compatible = "regulator-fixed";
- regulator-name = "mmc_power";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+
enable-active-high;
+
regulator-always-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "mmc_power";
};
mmc_fixed_1v8_io: regulator-1v8 {
compatible = "regulator-fixed";
- regulator-name = "mmc_io";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
+
enable-active-high;
+
regulator-always-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "mmc_io";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "ralink,mt7621-pinctrl";
+
+ i2c_pins: i2c0-pins {
+ pinmux {
+ groups = "i2c";
+ function = "i2c";
+ };
+ };
+
+ mdio_pins: mdio0-pins {
+ pinmux {
+ groups = "mdio";
+ function = "mdio";
+ };
+ };
+
+ nand_pins: nand0-pins {
+ sdhci-pinmux {
+ groups = "sdhci";
+ function = "nand2";
+ };
+
+ spi-pinmux {
+ groups = "spi";
+ function = "nand1";
+ };
+ };
+
+ pcie_pins: pcie0-pins {
+ pinmux {
+ groups = "pcie";
+ function = "gpio";
+ };
+ };
+
+ rgmii1_pins: rgmii1-pins {
+ pinmux {
+ groups = "rgmii1";
+ function = "rgmii1";
+ };
+ };
+
+ rgmii2_pins: rgmii2-pins {
+ pinmux {
+ groups = "rgmii2";
+ function = "rgmii2";
+ };
+ };
+
+ sdhci_pins: sdhci0-pins {
+ pinmux {
+ groups = "sdhci";
+ function = "sdhci";
+ };
+ };
+
+ spi_pins: spi0-pins {
+ pinmux {
+ groups = "spi";
+ function = "spi";
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ pinmux {
+ groups = "uart1";
+ function = "uart1";
+ };
+ };
+
+ uart2_pins: uart2-pins {
+ pinmux {
+ groups = "uart2";
+ function = "uart2";
+ };
+ };
+
+ uart3_pins: uart3-pins {
+ pinmux {
+ groups = "uart3";
+ function = "uart3";
+ };
+ };
};
palmbus: palmbus@1e000000 {
@@ -62,12 +155,15 @@
sysc: syscon@0 {
compatible = "mediatek,mt7621-sysc", "syscon";
reg = <0x0 0x100>;
+
#clock-cells = <1>;
#reset-cells = <1>;
- ralink,memctl = <&memc>;
+
clock-output-names = "xtal", "cpu", "bus",
"50m", "125m", "150m",
"250m", "270m";
+
+ ralink,memctl = <&memc>;
};
wdt: watchdog@100 {
@@ -77,13 +173,16 @@
};
gpio: gpio@600 {
+ compatible = "mediatek,mt7621-gpio";
+ reg = <0x600 0x100>;
+
#gpio-cells = <2>;
#interrupt-cells = <2>;
- compatible = "mediatek,mt7621-gpio";
+
gpio-controller;
gpio-ranges = <&pinctrl 0 0 95>;
+
interrupt-controller;
- reg = <0x600 0x100>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 12 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -92,18 +191,19 @@
compatible = "mediatek,mt7621-i2c";
reg = <0x900 0x100>;
- clocks = <&sysc MT7621_CLK_I2C>;
- clock-names = "i2c";
- resets = <&sysc MT7621_RST_I2C>;
- reset-names = "i2c";
-
#address-cells = <1>;
#size-cells = <0>;
- status = "disabled";
+ clocks = <&sysc MT7621_CLK_I2C>;
+ clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c_pins>;
+
+ resets = <&sysc MT7621_RST_I2C>;
+ reset-names = "i2c";
+
+ status = "disabled";
};
memc: memory-controller@5000 {
@@ -170,135 +270,53 @@
};
spi0: spi@b00 {
- status = "disabled";
-
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x100>;
- clocks = <&sysc MT7621_CLK_SPI>;
- clock-names = "spi";
-
- resets = <&sysc MT7621_RST_SPI>;
- reset-names = "spi";
-
#address-cells = <1>;
#size-cells = <0>;
+ clock-names = "spi";
+ clocks = <&sysc MT7621_CLK_SPI>;
+
pinctrl-names = "default";
pinctrl-0 = <&spi_pins>;
- };
- };
-
- pinctrl: pinctrl {
- compatible = "ralink,mt7621-pinctrl";
-
- i2c_pins: i2c0-pins {
- pinmux {
- groups = "i2c";
- function = "i2c";
- };
- };
-
- spi_pins: spi0-pins {
- pinmux {
- groups = "spi";
- function = "spi";
- };
- };
-
- uart1_pins: uart1-pins {
- pinmux {
- groups = "uart1";
- function = "uart1";
- };
- };
-
- uart2_pins: uart2-pins {
- pinmux {
- groups = "uart2";
- function = "uart2";
- };
- };
-
- uart3_pins: uart3-pins {
- pinmux {
- groups = "uart3";
- function = "uart3";
- };
- };
-
- rgmii1_pins: rgmii1-pins {
- pinmux {
- groups = "rgmii1";
- function = "rgmii1";
- };
- };
-
- rgmii2_pins: rgmii2-pins {
- pinmux {
- groups = "rgmii2";
- function = "rgmii2";
- };
- };
-
- mdio_pins: mdio0-pins {
- pinmux {
- groups = "mdio";
- function = "mdio";
- };
- };
-
- pcie_pins: pcie0-pins {
- pinmux {
- groups = "pcie";
- function = "gpio";
- };
- };
-
- nand_pins: nand0-pins {
- spi-pinmux {
- groups = "spi";
- function = "nand1";
- };
- sdhci-pinmux {
- groups = "sdhci";
- function = "nand2";
- };
- };
+ reset-names = "spi";
+ resets = <&sysc MT7621_RST_SPI>;
- sdhci_pins: sdhci0-pins {
- pinmux {
- groups = "sdhci";
- function = "sdhci";
- };
+ status = "disabled";
};
};
mmc: mmc@1e130000 {
- status = "disabled";
-
compatible = "mediatek,mt7620-mmc";
reg = <0x1e130000 0x4000>;
bus-width = <4>;
- max-frequency = <48000000>;
- cap-sd-highspeed;
- cap-mmc-highspeed;
- vmmc-supply = <&mmc_fixed_3v3>;
- vqmmc-supply = <&mmc_fixed_1v8_io>;
- disable-wp;
- pinctrl-names = "default", "state_uhs";
- pinctrl-0 = <&sdhci_pins>;
- pinctrl-1 = <&sdhci_pins>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
clocks = <&sysc MT7621_CLK_SHXC>,
<&sysc MT7621_CLK_50M>;
clock-names = "source", "hclk";
+ disable-wp;
+
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
+
+ max-frequency = <48000000>;
+
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&sdhci_pins>;
+ pinctrl-1 = <&sdhci_pins>;
+
+ vmmc-supply = <&mmc_fixed_3v3>;
+ vqmmc-supply = <&mmc_fixed_1v8_io>;
+
+ status = "disabled";
};
usb: usb@1e1c0000 {
@@ -321,15 +339,15 @@
compatible = "mti,gic";
reg = <0x1fbc0000 0x2000>;
- interrupt-controller;
#interrupt-cells = <3>;
+ interrupt-controller;
mti,reserved-cpu-vectors = <7>;
timer {
compatible = "mti,gic-timer";
- interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
clocks = <&sysc MT7621_CLK_CPU>;
+ interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
};
};
@@ -347,46 +365,22 @@
compatible = "mediatek,mt7621-eth";
reg = <0x1e100000 0x10000>;
- clocks = <&sysc MT7621_CLK_FE>, <&sysc MT7621_CLK_ETH>;
- clock-names = "fe", "ethif";
-
#address-cells = <1>;
#size-cells = <0>;
- resets = <&sysc MT7621_RST_FE>, <&sysc MT7621_RST_ETH>;
- reset-names = "fe", "eth";
+ clock-names = "fe", "ethif";
+ clocks = <&sysc MT7621_CLK_FE>, <&sysc MT7621_CLK_ETH>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
- mediatek,ethsys = <&sysc>;
-
pinctrl-names = "default";
pinctrl-0 = <&mdio_pins>, <&rgmii1_pins>, <&rgmii2_pins>;
- gmac0: mac@0 {
- compatible = "mediatek,eth-mac";
- reg = <0>;
- phy-mode = "trgmii";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- pause;
- };
- };
-
- gmac1: mac@1 {
- compatible = "mediatek,eth-mac";
- reg = <1>;
- phy-mode = "rgmii";
+ reset-names = "fe", "eth";
+ resets = <&sysc MT7621_RST_FE>, <&sysc MT7621_RST_ETH>;
- fixed-link {
- speed = <1000>;
- full-duplex;
- pause;
- };
- };
+ mediatek,ethsys = <&sysc>;
mdio: mdio-bus {
#address-cells = <1>;
@@ -395,73 +389,105 @@
switch0: switch@1f {
compatible = "mediatek,mt7621";
reg = <0x1f>;
- mediatek,mcm;
- resets = <&sysc MT7621_RST_MCM>;
- reset-names = "mcm";
- interrupt-controller;
+
#interrupt-cells = <1>;
+ interrupt-controller;
interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;
+ reset-names = "mcm";
+ resets = <&sysc MT7621_RST_MCM>;
+
+ mediatek,mcm;
+
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
- status = "disabled";
reg = <0>;
label = "swp0";
+ status = "disabled";
};
port@1 {
- status = "disabled";
reg = <1>;
label = "swp1";
+ status = "disabled";
};
port@2 {
- status = "disabled";
reg = <2>;
label = "swp2";
+ status = "disabled";
};
port@3 {
- status = "disabled";
reg = <3>;
label = "swp3";
+ status = "disabled";
};
port@4 {
- status = "disabled";
reg = <4>;
label = "swp4";
+ status = "disabled";
};
port@5 {
reg = <5>;
+
ethernet = <&gmac1>;
phy-mode = "rgmii";
fixed-link {
- speed = <1000>;
full-duplex;
pause;
+ speed = <1000>;
};
};
port@6 {
reg = <6>;
+
ethernet = <&gmac0>;
phy-mode = "trgmii";
fixed-link {
- speed = <1000>;
full-duplex;
pause;
+ speed = <1000>;
};
};
};
};
};
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+
+ phy-mode = "trgmii";
+
+ fixed-link {
+ full-duplex;
+ pause;
+ speed = <1000>;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+
+ phy-mode = "rgmii";
+
+ fixed-link {
+ full-duplex;
+ pause;
+ speed = <1000>;
+ };
+ };
+
};
pcie: pcie@1e140000 {
@@ -470,84 +496,106 @@
<0x1e142000 0x100>, /* pcie port 0 RC control registers */
<0x1e143000 0x100>, /* pcie port 1 RC control registers */
<0x1e144000 0x100>; /* pcie port 2 RC control registers */
+ ranges = <0x02000000 0 0x60000000 0x60000000 0 0x10000000>, /* pci memory */
+ <0x01000000 0 0x00000000 0x1e160000 0 0x00010000>; /* io space */
+
#address-cells = <3>;
+ #interrupt-cells = <1>;
#size-cells = <2>;
- pinctrl-names = "default";
- pinctrl-0 = <&pcie_pins>;
-
device_type = "pci";
- ranges = <0x02000000 0 0x60000000 0x60000000 0 0x10000000>, /* pci memory */
- <0x01000000 0 0x00000000 0x1e160000 0 0x00010000>; /* io space */
-
- #interrupt-cells = <1>;
- interrupt-map-mask = <0xF800 0 0 0>;
- interrupt-map = <0x0000 0 0 0 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>,
+ interrupt-map-mask = <0xf800 0 0 0>;
+ interrupt-map = <0x0000 0 0 0 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>,
<0x0800 0 0 0 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
<0x1000 0 0 0 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pins>;
reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
+ ranges;
+
#address-cells = <3>;
+ #interrupt-cells = <1>;
#size-cells = <2>;
+
+ clocks = <&sysc MT7621_CLK_PCIE0>;
+
device_type = "pci";
- #interrupt-cells = <1>;
+
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&sysc MT7621_RST_PCIE0>;
- clocks = <&sysc MT7621_CLK_PCIE0>;
- phys = <&pcie0_phy 1>;
+
phy-names = "pcie-phy0";
- ranges;
+ phys = <&pcie0_phy 1>;
+
+ resets = <&sysc MT7621_RST_PCIE0>;
};
pcie@1,0 {
reg = <0x0800 0 0 0 0>;
+ ranges;
+
#address-cells = <3>;
+ #interrupt-cells = <1>;
#size-cells = <2>;
+
+ clocks = <&sysc MT7621_CLK_PCIE1>;
+
device_type = "pci";
- #interrupt-cells = <1>;
+
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&sysc MT7621_RST_PCIE1>;
- clocks = <&sysc MT7621_CLK_PCIE1>;
- phys = <&pcie0_phy 1>;
+
phy-names = "pcie-phy1";
- ranges;
+ phys = <&pcie0_phy 1>;
+
+ resets = <&sysc MT7621_RST_PCIE1>;
};
pcie@2,0 {
reg = <0x1000 0 0 0 0>;
+ ranges;
+
#address-cells = <3>;
+ #interrupt-cells = <1>;
#size-cells = <2>;
+
+ clocks = <&sysc MT7621_CLK_PCIE2>;
+
device_type = "pci";
- #interrupt-cells = <1>;
+
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&sysc MT7621_RST_PCIE2>;
- clocks = <&sysc MT7621_CLK_PCIE2>;
- phys = <&pcie2_phy 0>;
+
phy-names = "pcie-phy2";
- ranges;
+ phys = <&pcie2_phy 0>;
+
+ resets = <&sysc MT7621_RST_PCIE2>;
};
};
pcie0_phy: pcie-phy@1e149000 {
compatible = "mediatek,mt7621-pci-phy";
reg = <0x1e149000 0x0700>;
- clocks = <&sysc MT7621_CLK_XTAL>;
+
#phy-cells = <1>;
+
+ clocks = <&sysc MT7621_CLK_XTAL>;
};
pcie2_phy: pcie-phy@1e14a000 {
compatible = "mediatek,mt7621-pci-phy";
reg = <0x1e14a000 0x0700>;
- clocks = <&sysc MT7621_CLK_XTAL>;
+
#phy-cells = <1>;
+
+ clocks = <&sysc MT7621_CLK_XTAL>;
};
};
diff --git a/arch/mips/boot/dts/realtek/Makefile b/arch/mips/boot/dts/realtek/Makefile
index fba4e93187a6..d2709798763f 100644
--- a/arch/mips/boot/dts/realtek/Makefile
+++ b/arch/mips/boot/dts/realtek/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
dtb-y += cisco_sg220-26.dtb
+dtb-y += cameo-rtl9302c-2x-rtl8224-2xge.dtb
diff --git a/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts b/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts
new file mode 100644
index 000000000000..77d2566545f2
--- /dev/null
+++ b/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/dts-v1/;
+
+#include "rtl930x.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ compatible = "cameo,rtl9302c-2x-rtl8224-2xge", "realtek,rtl9302-soc";
+ model = "RTL9302C Development Board";
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x8000000>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "LOADER";
+ reg = <0x0 0xe0000>;
+ read-only;
+ };
+ partition@e0000 {
+ label = "BDINFO";
+ reg = <0xe0000 0x10000>;
+ };
+ partition@f0000 {
+ label = "SYSINFO";
+ reg = <0xf0000 0x10000>;
+ read-only;
+ };
+ partition@100000 {
+ label = "JFFS2 CFG";
+ reg = <0x100000 0x100000>;
+ };
+ partition@200000 {
+ label = "JFFS2 LOG";
+ reg = <0x200000 0x100000>;
+ };
+ partition@300000 {
+ label = "RUNTIME";
+ reg = <0x300000 0xe80000>;
+ };
+ partition@1180000 {
+ label = "RUNTIME2";
+ reg = <0x1180000 0xe80000>;
+ };
+ };
+ };
+};
diff --git a/arch/mips/boot/dts/realtek/rtl838x.dtsi b/arch/mips/boot/dts/realtek/rtl838x.dtsi
index 6cc4ff5c0d19..722106e39194 100644
--- a/arch/mips/boot/dts/realtek/rtl838x.dtsi
+++ b/arch/mips/boot/dts/realtek/rtl838x.dtsi
@@ -6,6 +6,7 @@
#size-cells = <0>;
cpu@0 {
+ device_type = "cpu";
compatible = "mips,mips4KEc";
reg = <0>;
clocks = <&baseclk 0>;
diff --git a/arch/mips/boot/dts/realtek/rtl83xx.dtsi b/arch/mips/boot/dts/realtek/rtl83xx.dtsi
index de65a111b626..03ddc61f7c9e 100644
--- a/arch/mips/boot/dts/realtek/rtl83xx.dtsi
+++ b/arch/mips/boot/dts/realtek/rtl83xx.dtsi
@@ -22,7 +22,7 @@
#size-cells = <1>;
ranges = <0x0 0x18000000 0x10000>;
- uart0: uart@2000 {
+ uart0: serial@2000 {
compatible = "ns16550a";
reg = <0x2000 0x100>;
@@ -39,7 +39,7 @@
status = "disabled";
};
- uart1: uart@2100 {
+ uart1: serial@2100 {
compatible = "ns16550a";
reg = <0x2100 0x100>;
diff --git a/arch/mips/boot/dts/realtek/rtl930x.dtsi b/arch/mips/boot/dts/realtek/rtl930x.dtsi
new file mode 100644
index 000000000000..f271940f82be
--- /dev/null
+++ b/arch/mips/boot/dts/realtek/rtl930x.dtsi
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause
+
+#include "rtl83xx.dtsi"
+
+/ {
+ compatible = "realtek,rtl9302-soc";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "mips,mips34Kc";
+ reg = <0>;
+ clocks = <&baseclk 0>;
+ clock-names = "cpu";
+ };
+ };
+
+ baseclk: clock-800mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <800000000>;
+ };
+
+ lx_clk: clock-175mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <175000000>;
+ };
+};
+
+&soc {
+ intc: interrupt-controller@3000 {
+ compatible = "realtek,rtl9300-intc", "realtek,rtl-intc";
+ reg = <0x3000 0x18>, <0x3018 0x18>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>, <3>, <4>, <5>, <6>, <7>;
+ };
+
+ spi0: spi@1200 {
+ compatible = "realtek,rtl8380-spi";
+ reg = <0x1200 0x100>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ timer0: timer@3200 {
+ compatible = "realtek,rtl9302-timer", "realtek,otto-timer";
+ reg = <0x3200 0x10>, <0x3210 0x10>, <0x3220 0x10>,
+ <0x3230 0x10>, <0x3240 0x10>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <7>, <8>, <9>, <10>, <11>;
+ clocks = <&lx_clk>;
+ };
+};
+
+&uart0 {
+ /delete-property/ clock-frequency;
+ clocks = <&lx_clk>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <30>;
+};
+
+&uart1 {
+ /delete-property/ clock-frequency;
+ clocks = <&lx_clk>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <31>;
+};
+
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
index cdf2a782dee1..90536cab417e 100644
--- a/arch/mips/configs/ci20_defconfig
+++ b/arch/mips/configs/ci20_defconfig
@@ -122,6 +122,7 @@ CONFIG_IR_GPIO_TX=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_DRM=m
CONFIG_DRM_DISPLAY_CONNECTOR=m
+CONFIG_DRM_DW_HDMI=m
CONFIG_DRM_INGENIC=m
CONFIG_DRM_INGENIC_DW_HDMI=m
CONFIG_FB=y
@@ -152,7 +153,6 @@ CONFIG_LEDS_TRIGGER_CAMERA=m
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=y
CONFIG_LEDS_TRIGGER_PATTERN=y
-CONFIG_LEDS_TRIGGER_AUDIO=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_JZ4740=y
CONFIG_DMADEVICES=y
diff --git a/arch/mips/configs/db1xxx_defconfig b/arch/mips/configs/db1xxx_defconfig
index b2d9253ff786..6eff21ff15d5 100644
--- a/arch/mips/configs/db1xxx_defconfig
+++ b/arch/mips/configs/db1xxx_defconfig
@@ -12,7 +12,6 @@ CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
diff --git a/arch/mips/configs/eyeq5_defconfig b/arch/mips/configs/eyeq5_defconfig
index c35c29a4d479..ae9a09b16e40 100644
--- a/arch/mips/configs/eyeq5_defconfig
+++ b/arch/mips/configs/eyeq5_defconfig
@@ -8,7 +8,6 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
@@ -19,6 +18,7 @@ CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
+CONFIG_EYEQ=y
CONFIG_MACH_EYEQ5=y
CONFIG_FIT_IMAGE_FDT_EPM5=y
CONFIG_PAGE_SIZE_16KB=y
diff --git a/arch/mips/configs/eyeq6_defconfig b/arch/mips/configs/eyeq6_defconfig
new file mode 100644
index 000000000000..6597d5e88b33
--- /dev/null
+++ b/arch/mips/configs/eyeq6_defconfig
@@ -0,0 +1,111 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_TASKSTATS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_MEMCG=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_EYEQ=y
+CONFIG_MACH_EYEQ6H=y
+CONFIG_MIPS_CPS=y
+CONFIG_CPU_HAS_MSA=y
+CONFIG_NR_CPUS=16
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_PAGE_SIZE_16KB=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_TRIM_UNUSED_KSYMS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_USERFAULTFD=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NETFILTER=y
+CONFIG_CAN=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_ENDPOINT=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_SCSI=y
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=y
+CONFIG_IPVLAN=y
+CONFIG_MACB=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_CAN_M_CAN=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_PTP_1588_CLOCK is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_ITE=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_REDRAGON=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RESET_CONTROLLER=y
+# CONFIG_NVMEM is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_FS_ENCRYPTION=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CRYPTO_CRC32_MIPS=y
+CONFIG_FRAME_WARN=1024
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_TRACE is not set
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="earlycon"
diff --git a/arch/mips/configs/generic/64r6.config b/arch/mips/configs/generic/64r6.config
index 5dd8e8503e34..63b4e95f303d 100644
--- a/arch/mips/configs/generic/64r6.config
+++ b/arch/mips/configs/generic/64r6.config
@@ -3,4 +3,6 @@ CONFIG_64BIT=y
CONFIG_MIPS32_O32=y
CONFIG_MIPS32_N32=y
+CONFIG_CPU_HAS_MSA=y
CONFIG_CRYPTO_CRC32_MIPS=y
+CONFIG_VIRTUALIZATION=y
diff --git a/arch/mips/configs/generic/board-litex.config b/arch/mips/configs/generic/board-litex.config
new file mode 100644
index 000000000000..f372d0647bfc
--- /dev/null
+++ b/arch/mips/configs/generic/board-litex.config
@@ -0,0 +1,8 @@
+CONFIG_LITEX_LITEETH=y
+CONFIG_SERIAL_LITEUART=y
+CONFIG_SERIAL_LITEUART_CONSOLE=y
+CONFIG_MMC=y
+CONFIG_MMC_LITEX=y
+CONFIG_LITEX_SOC_CONTROLLER=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig
index 071e2205c7ed..fa916407bdd4 100644
--- a/arch/mips/configs/generic_defconfig
+++ b/arch/mips/configs/generic_defconfig
@@ -5,7 +5,6 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
diff --git a/arch/mips/configs/ip30_defconfig b/arch/mips/configs/ip30_defconfig
new file mode 100644
index 000000000000..178d61645cea
--- /dev/null
+++ b/arch/mips/configs/ip30_defconfig
@@ -0,0 +1,183 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_EXPERT=y
+CONFIG_SGI_IP30=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_HZ_1000=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_SGI_PARTITION=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SKBEDIT=m
+# CONFIG_VGA_ARB is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_LIBFC=m
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_BFA_FC=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=y
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+CONFIG_SGI_IOC3_ETH=y
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_SERIO_SGI_IOC3=y
+CONFIG_SERIO_RAW=m
+CONFIG_SERIO_ALTERA_PS2=m
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_IOC3=y
+CONFIG_NOZOMI=m
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+# CONFIG_PTP_1588_CLOCK is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_SGI_MFD_IOC3=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M48T35=y
+CONFIG_UIO=y
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_OMFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_T10DIF=m
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
index 3389e6e885d9..71d6340497c9 100644
--- a/arch/mips/configs/lemote2f_defconfig
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -12,15 +12,14 @@ CONFIG_LOG_BUF_SHIFT=15
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_PROFILING=y
+CONFIG_KEXEC=y
CONFIG_MACH_LOONGSON2EF=y
CONFIG_LEMOTE_MACH2F=y
-CONFIG_KEXEC=y
-# CONFIG_SECCOMP is not set
-CONFIG_PCI=y
CONFIG_MIPS32_O32=y
CONFIG_MIPS32_N32=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION="/dev/hda3"
+# CONFIG_SECCOMP is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
@@ -68,10 +67,10 @@ CONFIG_BT_HIDP=m
CONFIG_BT_HCIBTUSB=m
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIVHCI=m
-CONFIG_CFG80211=m
-CONFIG_MAC80211=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
CONFIG_MAC80211_LEDS=y
-CONFIG_RFKILL=m
+CONFIG_RFKILL=y
CONFIG_RFKILL_INPUT=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
@@ -83,13 +82,10 @@ CONFIG_ATA=y
CONFIG_PATA_AMD=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_DEBUG=y
CONFIG_DM_CRYPT=m
@@ -112,6 +108,10 @@ CONFIG_8139TOO=y
CONFIG_R8169=y
CONFIG_USB_USBNET=m
CONFIG_USB_NET_CDC_EEM=m
+CONFIG_RTL8180=m
+CONFIG_RTL8187=y
+CONFIG_RTL_CARDS=m
+CONFIG_RTL8XXXU=m
CONFIG_INPUT_EVDEV=y
# CONFIG_MOUSE_PS2_ALPS is not set
# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
@@ -119,27 +119,27 @@ CONFIG_INPUT_EVDEV=y
CONFIG_MOUSE_APPLETOUCH=m
# CONFIG_SERIO_SERPORT is not set
CONFIG_LEGACY_PTY_COUNT=16
-CONFIG_SERIAL_NONSTANDARD=y
CONFIG_SERIAL_8250=m
# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_NR_UARTS=16
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_FOURPORT=y
+CONFIG_SERIAL_NONSTANDARD=y
CONFIG_HW_RANDOM=y
CONFIG_GPIO_LOONGSON=y
CONFIG_THERMAL=y
CONFIG_MEDIA_SUPPORT=m
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
CONFIG_FB_SIS=y
CONFIG_FB_SIS_300=y
CONFIG_FB_SIS_315=y
-# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_FB_SIMPLE=y
+CONFIG_FB_SM712=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_LOGO=y
@@ -238,7 +238,6 @@ CONFIG_BTRFS_FS=m
CONFIG_QUOTA=y
CONFIG_QFMT_V2=m
CONFIG_AUTOFS_FS=m
-CONFIG_NETFS_SUPPORT=m
CONFIG_FSCACHE=y
CONFIG_CACHEFILES=m
CONFIG_ISO9660_FS=m
@@ -247,7 +246,6 @@ CONFIG_ZISOFS=y
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_CRAMFS=m
@@ -299,29 +297,23 @@ CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=y
CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_LZO=m
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_6x11=y
diff --git a/arch/mips/configs/rs90_defconfig b/arch/mips/configs/rs90_defconfig
index 4b9e36d6400e..a53dd66e9b86 100644
--- a/arch/mips/configs/rs90_defconfig
+++ b/arch/mips/configs/rs90_defconfig
@@ -9,7 +9,7 @@ CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
# CONFIG_SGETMASK_SYSCALL is not set
# CONFIG_SYSFS_SYSCALL is not set
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_TIMERFD is not set
# CONFIG_AIO is not set
# CONFIG_IO_URING is not set
diff --git a/arch/mips/crypto/poly1305-glue.c b/arch/mips/crypto/poly1305-glue.c
index bc6110fb98e0..867728ee535a 100644
--- a/arch/mips/crypto/poly1305-glue.c
+++ b/arch/mips/crypto/poly1305-glue.c
@@ -186,6 +186,7 @@ static void __exit mips_poly1305_mod_exit(void)
module_init(mips_poly1305_mod_init);
module_exit(mips_poly1305_mod_exit);
+MODULE_DESCRIPTION("Poly1305 transform (MIPS accelerated");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("poly1305");
MODULE_ALIAS_CRYPTO("poly1305-mips");
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 6c3704f51d0d..87f0a1436bf9 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -756,7 +756,7 @@ void __init arch_init_irq(void)
NULL))
pr_err("Failed to register fpu interrupt\n");
desc_fpu = irq_to_desc(irq_fpu);
- fpu_kstat_irq = this_cpu_ptr(desc_fpu->kstat_irqs);
+ fpu_kstat_irq = this_cpu_ptr(&desc_fpu->kstat_irqs->cnt);
}
if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) {
if (request_irq(dec_interrupt[DEC_IRQ_CASCADE], no_action,
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index 56011d738441..ea0e4ad5e600 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -13,3 +13,4 @@ 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
+obj-$(CONFIG_MACH_REALTEK_RTL) += board-realtek.o
diff --git a/arch/mips/generic/board-realtek.c b/arch/mips/generic/board-realtek.c
new file mode 100644
index 000000000000..9cce6103d24e
--- /dev/null
+++ b/arch/mips/generic/board-realtek.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Allied Telesis
+ */
+
+#include <linux/errno.h>
+#include <linux/libfdt.h>
+#include <linux/printk.h>
+#include <linux/types.h>
+
+#include <asm/fw/fw.h>
+#include <asm/machine.h>
+
+static __init int realtek_add_initrd(void *fdt)
+{
+ int node, err;
+ u32 start, size;
+
+ node = fdt_path_offset(fdt, "/chosen");
+ if (node < 0) {
+ pr_err("/chosen node not found\n");
+ return -ENOENT;
+ }
+
+ start = fw_getenvl("initrd_start");
+ size = fw_getenvl("initrd_size");
+
+ if (start == 0 && size == 0)
+ return 0;
+
+ pr_info("Adding initrd info from environment\n");
+
+ err = fdt_setprop_u32(fdt, node, "linux,initrd-start", start);
+ if (err) {
+ pr_err("unable to set initrd-start: %d\n", err);
+ return err;
+ }
+
+ err = fdt_setprop_u32(fdt, node, "linux,initrd-end", start + size);
+ if (err) {
+ pr_err("unable to set initrd-end: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct mips_fdt_fixup realtek_fdt_fixups[] __initconst = {
+ { realtek_add_initrd, "add initrd" },
+ {},
+};
+
+static __init const void *realtek_fixup_fdt(const void *fdt, const void *match_data)
+{
+ static unsigned char fdt_buf[16 << 10] __initdata;
+ int err;
+
+ if (fdt_check_header(fdt))
+ panic("Corrupt DT");
+
+ fw_init_cmdline();
+
+ err = apply_mips_fdt_fixups(fdt_buf, sizeof(fdt_buf), fdt, realtek_fdt_fixups);
+ if (err)
+ panic("Unable to fixup FDT: %d", err);
+
+ return fdt_buf;
+
+}
+
+static const struct of_device_id realtek_of_match[] __initconst = {
+ { .compatible = "realtek,rtl9302-soc" },
+ {}
+};
+
+MIPS_MACHINE(realtek) = {
+ .matches = realtek_of_match,
+ .fixup_fdt = realtek_fixup_fdt,
+};
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h
index 2e99450f4228..87ff609b53fe 100644
--- a/arch/mips/include/asm/asm.h
+++ b/arch/mips/include/asm/asm.h
@@ -37,6 +37,7 @@
#define CFI_SECTIONS
#endif
+#ifdef __ASSEMBLY__
/*
* LEAF - declare leaf routine
*/
@@ -122,6 +123,8 @@ symbol = value
#define ASM_PRINT(string)
#endif
+#endif /* __ASSEMBLY__ */
+
/*
* Stack alignment
*/
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
index 581a6a3c66e4..3a1cdfddb987 100644
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -81,6 +81,7 @@ extern char bmips_smp_movevec[];
extern char bmips_smp_int_vec[];
extern char bmips_smp_int_vec_end[];
+extern void __iomem *bmips_cbr_addr;
extern int bmips_smp_enabled;
extern int bmips_cpu_offset;
extern cpumask_t bmips_booted_mask;
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index 86310d6e1035..bc5ac9887d09 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -129,6 +129,18 @@ static inline int __own_fpu(void)
if (ret)
return ret;
+ if (current->thread.fpu.fcr31 & FPU_CSR_NAN2008) {
+ if (!cpu_has_nan_2008) {
+ ret = SIGFPE;
+ goto failed;
+ }
+ } else {
+ if (!cpu_has_nan_legacy) {
+ ret = SIGFPE;
+ goto failed;
+ }
+ }
+
KSTK_STATUS(current) |= ST0_CU1;
if (mode == FPU_64BIT || mode == FPU_HYBRID)
KSTK_STATUS(current) |= ST0_FR;
@@ -137,6 +149,9 @@ static inline int __own_fpu(void)
set_thread_flag(TIF_USEDFPU);
return 0;
+failed:
+ __disable_fpu();
+ return ret;
}
static inline int own_fpu_inatomic(int restore)
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 179f320cc231..6743a57c1ab4 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -890,7 +890,6 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
static inline void kvm_arch_free_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot) {}
static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index e007edd6b60a..9218b3ae3383 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -42,12 +42,14 @@ enum loongson_cpu_type {
Legacy_1B = 0x5,
Legacy_2G = 0x6,
Legacy_2H = 0x7,
+ Legacy_2K = 0x8,
Loongson_1A = 0x100,
Loongson_1B = 0x101,
Loongson_2E = 0x200,
Loongson_2F = 0x201,
Loongson_2G = 0x202,
Loongson_2H = 0x203,
+ Loongson_2K = 0x204,
Loongson_3A = 0x300,
Loongson_3B = 0x301
};
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index c2930a75b7e4..1e782275850a 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -240,6 +240,10 @@ GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
#define CM_GCR_CPC_STATUS_EX BIT(0)
+/* GCR_ACCESS - Controls core/IOCU access to GCRs */
+GCR_ACCESSOR_RW(32, 0x120, access_cm3)
+#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0)
+
/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
GCR_ACCESSOR_RW(32, 0x130, l2_config)
#define CM_GCR_L2_CONFIG_BYPASS BIT(20)
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index c077e8d100f5..917009b80e69 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -8,6 +8,7 @@
#define __MIPS_ASM_MIPS_CPS_H__
#include <linux/bitfield.h>
+#include <linux/cpumask.h>
#include <linux/io.h>
#include <linux/types.h>
@@ -228,4 +229,42 @@ static inline unsigned int mips_cps_numvps(unsigned int cluster, unsigned int co
return FIELD_GET(CM_GCR_Cx_CONFIG_PVPE, cfg + 1);
}
+/**
+ * mips_cps_multicluster_cpus() - Detect whether CPUs are in multiple clusters
+ *
+ * Determine whether the system includes CPUs in multiple clusters - ie.
+ * whether we can treat the system as single or multi-cluster as far as CPUs
+ * are concerned. Note that this is slightly different to simply checking
+ * whether multiple clusters are present - it is possible for there to be
+ * clusters which contain no CPUs, which this function will effectively ignore.
+ *
+ * Returns true if CPUs are spread across multiple clusters, else false.
+ */
+static inline bool mips_cps_multicluster_cpus(void)
+{
+ unsigned int first_cl, last_cl;
+
+ /*
+ * CPUs are numbered sequentially by cluster - ie. CPUs 0..X will be in
+ * cluster 0, CPUs X+1..Y in cluster 1, CPUs Y+1..Z in cluster 2 etc.
+ *
+ * Thus we can detect multiple clusters trivially by checking whether
+ * the first & last CPUs belong to the same cluster.
+ */
+ first_cl = cpu_cluster(&boot_cpu_data);
+ last_cl = cpu_cluster(&cpu_data[nr_cpu_ids - 1]);
+ return first_cl != last_cl;
+}
+
+/**
+ * mips_cps_first_online_in_cluster() - Detect if CPU is first online in cluster
+ *
+ * Determine whether the local CPU is the first to be brought online in its
+ * cluster - that is, whether there are any other online CPUs in the local
+ * cluster.
+ *
+ * Returns true if this CPU is first online, else false.
+ */
+extern unsigned int mips_cps_first_online_in_cluster(void);
+
#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
index 084cac1c5ea2..fd9da5e3beaa 100644
--- a/arch/mips/include/asm/mips-gic.h
+++ b/arch/mips/include/asm/mips-gic.h
@@ -28,11 +28,13 @@ extern void __iomem *mips_gic_base;
/* For read-only shared registers */
#define GIC_ACCESSOR_RO(sz, off, name) \
- CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
+ CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name) \
+ CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, redir_##name)
/* For read-write shared registers */
#define GIC_ACCESSOR_RW(sz, off, name) \
- CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
+ CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name) \
+ CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, redir_##name)
/* For read-only local registers */
#define GIC_VX_ACCESSOR_RO(sz, off, name) \
@@ -45,7 +47,7 @@ extern void __iomem *mips_gic_base;
CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
/* For read-only shared per-interrupt registers */
-#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
+#define _GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
static inline void __iomem *addr_gic_##name(unsigned int intr) \
{ \
return mips_gic_base + (off) + (intr * (stride)); \
@@ -58,8 +60,8 @@ static inline unsigned int read_gic_##name(unsigned int intr) \
}
/* For read-write shared per-interrupt registers */
-#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
- GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
+#define _GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
+ _GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
\
static inline void write_gic_##name(unsigned int intr, \
unsigned int val) \
@@ -68,22 +70,30 @@ static inline void write_gic_##name(unsigned int intr, \
__raw_writel(val, addr_gic_##name(intr)); \
}
+#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
+ _GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
+ _GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, stride, redir_##name)
+
+#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
+ _GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
+ _GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, stride, redir_##name)
+
/* For read-only local per-interrupt registers */
#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
- GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \
+ _GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \
stride, vl_##name) \
- GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \
+ _GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \
stride, vo_##name)
/* For read-write local per-interrupt registers */
#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
- GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \
+ _GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \
stride, vl_##name) \
- GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \
+ _GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \
stride, vo_##name)
/* For read-only shared bit-per-interrupt registers */
-#define GIC_ACCESSOR_RO_INTR_BIT(off, name) \
+#define _GIC_ACCESSOR_RO_INTR_BIT(off, name) \
static inline void __iomem *addr_gic_##name(void) \
{ \
return mips_gic_base + (off); \
@@ -106,8 +116,8 @@ static inline unsigned int read_gic_##name(unsigned int intr) \
}
/* For read-write shared bit-per-interrupt registers */
-#define GIC_ACCESSOR_RW_INTR_BIT(off, name) \
- GIC_ACCESSOR_RO_INTR_BIT(off, name) \
+#define _GIC_ACCESSOR_RW_INTR_BIT(off, name) \
+ _GIC_ACCESSOR_RO_INTR_BIT(off, name) \
\
static inline void write_gic_##name(unsigned int intr) \
{ \
@@ -146,6 +156,14 @@ static inline void change_gic_##name(unsigned int intr, \
} \
}
+#define GIC_ACCESSOR_RO_INTR_BIT(off, name) \
+ _GIC_ACCESSOR_RO_INTR_BIT(off, name) \
+ _GIC_ACCESSOR_RO_INTR_BIT(MIPS_GIC_REDIR_OFS + off, redir_##name)
+
+#define GIC_ACCESSOR_RW_INTR_BIT(off, name) \
+ _GIC_ACCESSOR_RW_INTR_BIT(off, name) \
+ _GIC_ACCESSOR_RW_INTR_BIT(MIPS_GIC_REDIR_OFS + off, redir_##name)
+
/* For read-only local bit-per-interrupt registers */
#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name) \
GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \
@@ -155,10 +173,10 @@ static inline void change_gic_##name(unsigned int intr, \
/* For read-write local bit-per-interrupt registers */
#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name) \
- GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \
- vl_##name) \
- GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \
- vo_##name)
+ _GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \
+ vl_##name) \
+ _GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \
+ vo_##name)
/* GIC_SH_CONFIG - Information about the GIC configuration */
GIC_ACCESSOR_RW(32, 0x000, config)
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
index 30e86861c206..b1ee3c48e84b 100644
--- a/arch/mips/include/asm/mipsmtregs.h
+++ b/arch/mips/include/asm/mipsmtregs.h
@@ -322,7 +322,7 @@ static inline void ehb(void)
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
_ASM_SET_MFTC0 \
- " mftc0 $1, " #rt ", " #sel " \n" \
+ " mftc0 %0, " #rt ", " #sel " \n" \
_ASM_UNSET_MFTC0 \
" .set pop \n" \
: "=r" (__res)); \
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index 0e196650f4f4..92b7591aac2a 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -129,7 +129,7 @@ static inline int pmd_none(pmd_t pmd)
static inline int pmd_bad(pmd_t pmd)
{
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
- /* pmd_huge(pmd) but inline */
+ /* pmd_leaf(pmd) but inline */
if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
return 0;
#endif
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 20ca48c1b606..401c1d9e4409 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -147,8 +147,8 @@
#if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
VMALLOC_START != CKSSEG
/* Load modules into 32bit-compatible segment. */
-#define MODULE_START CKSSEG
-#define MODULE_END (FIXADDR_START-2*PAGE_SIZE)
+#define MODULES_VADDR CKSSEG
+#define MODULES_END (FIXADDR_START-2*PAGE_SIZE)
#endif
#define pte_ERROR(e) \
@@ -245,7 +245,7 @@ static inline int pmd_none(pmd_t pmd)
static inline int pmd_bad(pmd_t pmd)
{
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
- /* pmd_huge(pmd) but inline */
+ /* pmd_leaf(pmd) but inline */
if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
return 0;
#endif
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index e27a4c83c548..c29a551eb0ca 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -594,8 +594,8 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
#define update_mmu_cache(vma, address, ptep) \
update_mmu_cache_range(NULL, vma, address, ptep, 1)
-#define __HAVE_ARCH_UPDATE_MMU_TLB
-#define update_mmu_tlb update_mmu_cache
+#define update_mmu_tlb_range(vma, address, ptep, nr) \
+ update_mmu_cache_range(NULL, vma, address, ptep, nr)
static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp)
diff --git a/arch/mips/include/asm/pm.h b/arch/mips/include/asm/pm.h
index 10bb7b640738..7ecd4dfe3846 100644
--- a/arch/mips/include/asm/pm.h
+++ b/arch/mips/include/asm/pm.h
@@ -17,7 +17,7 @@
/* Save CPU state to stack for suspend to RAM */
.macro SUSPEND_SAVE_REGS
- subu sp, PT_SIZE
+ PTR_SUBU sp, PT_SIZE
/* Call preserved GPRs */
LONG_S $16, PT_R16(sp)
LONG_S $17, PT_R17(sp)
@@ -56,13 +56,13 @@
LONG_L $31, PT_R31(sp)
/* Pop and return */
jr ra
- addiu sp, PT_SIZE
+ PTR_ADDIU sp, PT_SIZE
.set pop
.endm
/* Get address of static suspend state into t1 */
.macro LA_STATIC_SUSPEND
- la t1, mips_static_suspend_state
+ PTR_LA t1, mips_static_suspend_state
.endm
/* Save important CPU state for early restoration to global data */
@@ -72,11 +72,11 @@
* Segment configuration is saved in global data where it can be easily
* reloaded without depending on the segment configuration.
*/
- mfc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
+ mfc0 k0, CP0_SEGCTL0
LONG_S k0, SSS_SEGCTL0(t1)
- mfc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
+ mfc0 k0, CP0_SEGCTL1
LONG_S k0, SSS_SEGCTL1(t1)
- mfc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
+ mfc0 k0, CP0_SEGCTL2
LONG_S k0, SSS_SEGCTL2(t1)
#endif
/* save stack pointer (pointing to GPRs) */
@@ -92,11 +92,11 @@
* segments.
*/
LONG_L k0, SSS_SEGCTL0(t1)
- mtc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
+ mtc0 k0, CP0_SEGCTL0
LONG_L k0, SSS_SEGCTL1(t1)
- mtc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
+ mtc0 k0, CP0_SEGCTL1
LONG_L k0, SSS_SEGCTL2(t1)
- mtc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
+ mtc0 k0, CP0_SEGCTL2
tlbw_use_hazard
#endif
/* restore stack pointer (pointing to GPRs) */
@@ -105,10 +105,10 @@
/* flush caches to make sure context has reached memory */
.macro SUSPEND_CACHE_FLUSH
- .extern __wback_cache_all
+ .extern __flush_cache_all
.set push
.set noreorder
- la t1, __wback_cache_all
+ PTR_LA t1, __flush_cache_all
LONG_L t0, 0(t1)
jalr t0
nop
diff --git a/arch/mips/include/asm/r4k-timer.h b/arch/mips/include/asm/r4k-timer.h
index 6e7361629348..432e61dd5204 100644
--- a/arch/mips/include/asm/r4k-timer.h
+++ b/arch/mips/include/asm/r4k-timer.h
@@ -12,15 +12,10 @@
#ifdef CONFIG_SYNC_R4K
-extern void synchronise_count_master(int cpu);
extern void synchronise_count_slave(int cpu);
#else
-static inline void synchronise_count_master(int cpu)
-{
-}
-
static inline void synchronise_count_slave(int cpu)
{
}
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h
index 4dce41138bad..d8077136372c 100644
--- a/arch/mips/include/asm/setup.h
+++ b/arch/mips/include/asm/setup.h
@@ -2,6 +2,7 @@
#ifndef _MIPS_SETUP_H
#define _MIPS_SETUP_H
+#include <linux/init.h>
#include <linux/types.h>
#include <uapi/asm/setup.h>
@@ -29,4 +30,9 @@ extern void per_cpu_trap_init(bool);
extern void cpu_cache_init(void);
extern void tlb_init(void);
+#ifdef CONFIG_RELOCATABLE
+extern void * __init relocate_kernel(void);
+extern int plat_post_relocation(long);
+#endif
+
#endif /* __SETUP_H */
diff --git a/arch/mips/include/asm/sgi/ip22.h b/arch/mips/include/asm/sgi/ip22.h
index 87ec9eaa04e3..57942afb5c86 100644
--- a/arch/mips/include/asm/sgi/ip22.h
+++ b/arch/mips/include/asm/sgi/ip22.h
@@ -76,5 +76,8 @@
extern unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg);
extern unsigned short ip22_nvram_read(int reg);
+extern void ip22_be_interrupt(int irq);
+extern void ip22_be_init(void) __init;
+extern void indy_8254timer_irq(void);
#endif
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index bc2c240f414b..2427d76f953f 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -50,7 +50,6 @@ extern int __cpu_logical_map[NR_CPUS];
#define SMP_CALL_FUNCTION 0x2
/* Octeon - Tell another core to flush its icache */
#define SMP_ICACHE_FLUSH 0x4
-#define SMP_ASK_C0COUNT 0x8
/* Mask of CPUs which are currently definitely operating coherently */
extern cpumask_t cpu_coherent_mask;
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index a8705aef47e1..a13431379073 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -308,17 +308,12 @@
jal octeon_mult_restore
#endif
#ifdef CONFIG_CPU_HAS_SMARTMIPS
- LONG_L $24, PT_ACX(sp)
- mtlhx $24
- LONG_L $24, PT_HI(sp)
- mtlhx $24
+ LONG_L $14, PT_ACX(sp)
LONG_L $24, PT_LO(sp)
- mtlhx $24
+ LONG_L $15, PT_HI(sp)
#elif !defined(CONFIG_CPU_MIPSR6)
LONG_L $24, PT_LO(sp)
- mtlo $24
- LONG_L $24, PT_HI(sp)
- mthi $24
+ LONG_L $15, PT_HI(sp)
#endif
#ifdef CONFIG_32BIT
cfi_ld $8, PT_R8, \docfi
@@ -327,6 +322,14 @@
cfi_ld $10, PT_R10, \docfi
cfi_ld $11, PT_R11, \docfi
cfi_ld $12, PT_R12, \docfi
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ mtlhx $14
+ mtlhx $15
+ mtlhx $24
+#elif !defined(CONFIG_CPU_MIPSR6)
+ mtlo $24
+ mthi $15
+#endif
cfi_ld $13, PT_R13, \docfi
cfi_ld $14, PT_R14, \docfi
cfi_ld $15, PT_R15, \docfi
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index 25a5253db7f4..ba83d3fb0a84 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -58,7 +58,6 @@
# endif
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
/* whitelists for checksyscalls */
#define __IGNORE_fadvise64_64
diff --git a/arch/mips/include/asm/fb.h b/arch/mips/include/asm/video.h
index d98d6681d64e..007c106d980f 100644
--- a/arch/mips/include/asm/fb.h
+++ b/arch/mips/include/asm/video.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
#include <asm/page.h>
@@ -13,8 +13,8 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
/*
* MIPS doesn't define __raw_ I/O macros, so the helpers
- * in <asm-generic/fb.h> don't generate fb_readq() and
- * fb_write(). We have to provide them here.
+ * in <asm-generic/video.h> don't generate fb_readq() and
+ * fb_writeq(). We have to provide them here.
*
* TODO: Convert MIPS to generic I/O. The helpers below can
* then be removed.
@@ -33,6 +33,6 @@ static inline void fb_writeq(u64 b, volatile void __iomem *addr)
#define fb_writeq fb_writeq
#endif
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index eabddb89d221..c97b089b9902 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -617,7 +617,7 @@ const struct dma_map_ops jazz_dma_ops = {
.sync_sg_for_device = jazz_dma_sync_sg_for_device,
.mmap = dma_common_mmap,
.get_sgtable = dma_common_get_sgtable,
- .alloc_pages = dma_common_alloc_pages,
+ .alloc_pages_op = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
};
EXPORT_SYMBOL(jazz_dma_ops);
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
index edc4afc080fa..bdb1fa8931f4 100644
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -21,7 +21,9 @@ static struct clocksource clocksource_mips = {
.name = "MIPS",
.read = c0_hpt_read,
.mask = CLOCKSOURCE_MASK(32),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
+ CLOCK_SOURCE_MUST_VERIFY |
+ CLOCK_SOURCE_VERIFY_PERCPU,
};
static u64 __maybe_unused notrace r4k_read_sched_clock(void)
@@ -66,6 +68,18 @@ static bool rdhwr_count_usable(void)
return false;
}
+static inline __init bool count_can_be_sched_clock(void)
+{
+ if (IS_ENABLED(CONFIG_CPU_FREQ))
+ return false;
+
+ if (num_possible_cpus() > 1 &&
+ !IS_ENABLED(CONFIG_HAVE_UNSTABLE_SCHED_CLOCK))
+ return false;
+
+ return true;
+}
+
#ifdef CONFIG_CPU_FREQ
static bool __read_mostly r4k_clock_unstable;
@@ -111,7 +125,8 @@ int __init init_r4k_clocksource(void)
return -ENXIO;
/* Calculate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+ clocksource_mips.rating = 200;
+ clocksource_mips.rating += clamp(mips_hpt_frequency / 10000000, 0, 99);
/*
* R2 onwards makes the count accessible to user mode so it can be used
@@ -122,9 +137,8 @@ int __init init_r4k_clocksource(void)
clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
-#ifndef CONFIG_CPU_FREQ
- sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
-#endif
+ if (count_can_be_sched_clock())
+ sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
return 0;
}
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index 7aa2c2360ff6..f0e7fe85a42a 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -318,6 +318,10 @@ void mips_set_personality_nan(struct arch_elf_state *state)
t->thread.fpu.fcr31 = c->fpu_csr31;
switch (state->nan_2008) {
case 0:
+ if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
+ t->thread.fpu.fcr31 &= ~FPU_CSR_NAN2008;
+ if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
+ t->thread.fpu.fcr31 &= ~FPU_CSR_ABS2008;
break;
case 1:
if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
diff --git a/arch/mips/kernel/fpu-probe.c b/arch/mips/kernel/fpu-probe.c
index e689d6a83234..6bf3f19b1c33 100644
--- a/arch/mips/kernel/fpu-probe.c
+++ b/arch/mips/kernel/fpu-probe.c
@@ -144,7 +144,7 @@ static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
* 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;
+static enum { STRICT, EMULATED, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
/*
* Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
@@ -160,6 +160,7 @@ static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
switch (ieee754) {
case STRICT:
+ case EMULATED:
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 |
@@ -204,6 +205,10 @@ static void cpu_set_nan_2008(struct cpuinfo_mips *c)
mips_use_nan_legacy = !cpu_has_nan_2008;
mips_use_nan_2008 = !!cpu_has_nan_2008;
break;
+ case EMULATED:
+ /* Pretend ABS2008/NAN2008 options are dynamic */
+ c->fpu_msk31 &= ~(FPU_CSR_NAN2008 | FPU_CSR_ABS2008);
+ fallthrough;
case RELAXED:
mips_use_nan_legacy = true;
mips_use_nan_2008 = true;
@@ -226,6 +231,8 @@ static int __init ieee754_setup(char *s)
return -1;
else if (!strcmp(s, "strict"))
ieee754 = STRICT;
+ else if (!strcmp(s, "emulated"))
+ ieee754 = EMULATED;
else if (!strcmp(s, "legacy"))
ieee754 = LEGACY;
else if (!strcmp(s, "2008"))
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 3a115fab5573..3eb2cfb893e1 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -512,3 +512,40 @@ void mips_cm_error_report(void)
/* reprime cause register */
write_gcr_error_cause(cm_error);
}
+
+unsigned int mips_cps_first_online_in_cluster(void)
+{
+ unsigned int local_cl;
+ int i;
+
+ local_cl = cpu_cluster(&current_cpu_data);
+
+ /*
+ * We rely upon knowledge that CPUs are numbered sequentially by
+ * cluster - ie. CPUs 0..X will be in cluster 0, CPUs X+1..Y in cluster
+ * 1, CPUs Y+1..Z in cluster 2 etc. This means that CPUs in the same
+ * cluster will immediately precede or follow one another.
+ *
+ * First we scan backwards, until we find an online CPU in the cluster
+ * or we move on to another cluster.
+ */
+ for (i = smp_processor_id() - 1; i >= 0; i--) {
+ if (cpu_cluster(&cpu_data[i]) != local_cl)
+ break;
+ if (!cpu_online(i))
+ continue;
+ return false;
+ }
+
+ /* Then do the same for higher numbered CPUs */
+ for (i = smp_processor_id() + 1; i < nr_cpu_ids; i++) {
+ if (cpu_cluster(&cpu_data[i]) != local_cl)
+ break;
+ if (!cpu_online(i))
+ continue;
+ return false;
+ }
+
+ /* We found no online CPUs in the local cluster */
+ return true;
+}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 7b2fbaa9cac5..ba0f62d8eff5 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -13,7 +13,6 @@
#include <linux/elf.h>
#include <linux/mm.h>
#include <linux/numa.h>
-#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/string.h>
@@ -31,15 +30,6 @@ struct mips_hi16 {
static LIST_HEAD(dbe_list);
static DEFINE_SPINLOCK(dbe_lock);
-#ifdef MODULE_START
-void *module_alloc(unsigned long size)
-{
- return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
- GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-#endif
-
static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v)
{
*location = base + v;
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index b3dbf9ecb0d6..35b8d810833c 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -518,7 +518,7 @@ static void bmips_set_reset_vec(int cpu, u32 val)
info.val = val;
bmips_set_reset_vec_remote(&info);
} else {
- void __iomem *cbr = BMIPS_GET_CBR();
+ void __iomem *cbr = bmips_cbr_addr;
if (cpu == 0)
__raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
@@ -591,7 +591,8 @@ asmlinkage void __weak plat_wired_tlb_setup(void)
void bmips_cpu_setup(void)
{
- void __iomem __maybe_unused *cbr = BMIPS_GET_CBR();
+ void __iomem __maybe_unused *cbr = bmips_cbr_addr;
+ u32 __maybe_unused rac_addr;
u32 __maybe_unused cfg;
switch (current_cpu_type()) {
@@ -620,6 +621,23 @@ void bmips_cpu_setup(void)
__raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE);
break;
+ case CPU_BMIPS4350:
+ rac_addr = BMIPS_RAC_CONFIG_1;
+
+ if (!(read_c0_brcm_cmt_local() & (1 << 31)))
+ rac_addr = BMIPS_RAC_CONFIG;
+
+ /* Enable data RAC */
+ cfg = __raw_readl(cbr + rac_addr);
+ __raw_writel(cfg | 0xf, cbr + rac_addr);
+ __raw_readl(cbr + rac_addr);
+
+ /* Flush stale data out of the readahead cache */
+ cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
+ __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
+ __raw_readl(cbr + BMIPS_RAC_CONFIG);
+ break;
+
case CPU_BMIPS4380:
/* CBG workaround for early BMIPS4380 CPUs */
switch (read_c0_prid()) {
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 9cc087dd1c19..395622c37325 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -317,7 +317,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
/* Ensure the core can access the GCRs */
- set_gcr_access(1 << core);
+ if (mips_cm_revision() < CM_REV_CM3)
+ set_gcr_access(1 << core);
+ else
+ set_gcr_access_cm3(1 << core);
if (mips_cpc_present()) {
/* Reset the core */
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 0b53d35a116e..0362fc5df7b0 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -462,8 +462,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
return -EIO;
}
- synchronise_count_master(cpu);
-
/* Wait for CPU to finish startup & mark itself online before return */
wait_for_completion(&cpu_running);
return 0;
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
index abdd7aaa3311..39156592582e 100644
--- a/arch/mips/kernel/sync-r4k.c
+++ b/arch/mips/kernel/sync-r4k.c
@@ -2,121 +2,244 @@
/*
* Count register synchronisation.
*
- * All CPUs will have their count registers synchronised to the CPU0 next time
- * value. This can cause a small timewarp for CPU0. All other CPU's should
- * not have done anything significant (but they may have had interrupts
- * enabled briefly - prom_smp_finish() should not be responsible for enabling
- * interrupts...)
+ * Derived from arch/x86/kernel/tsc_sync.c
+ * Copyright (C) 2006, Red Hat, Inc., Ingo Molnar
*/
#include <linux/kernel.h>
#include <linux/irqflags.h>
#include <linux/cpumask.h>
+#include <linux/atomic.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
#include <asm/r4k-timer.h>
-#include <linux/atomic.h>
-#include <asm/barrier.h>
#include <asm/mipsregs.h>
+#include <asm/time.h>
-static unsigned int initcount = 0;
-static atomic_t count_count_start = ATOMIC_INIT(0);
-static atomic_t count_count_stop = ATOMIC_INIT(0);
-
-#define COUNTON 100
-#define NR_LOOPS 3
-
-void synchronise_count_master(int cpu)
-{
- int i;
- unsigned long flags;
-
- pr_info("Synchronize counters for CPU %u: ", cpu);
+#define COUNTON 100
+#define NR_LOOPS 3
+#define LOOP_TIMEOUT 20
- local_irq_save(flags);
+/*
+ * Entry/exit counters that make sure that both CPUs
+ * run the measurement code at once:
+ */
+static atomic_t start_count;
+static atomic_t stop_count;
+static atomic_t test_runs;
- /*
- * We loop a few times to get a primed instruction cache,
- * then the last pass is more or less synchronised and
- * the master and slaves each set their cycle counters to a known
- * value all at once. This reduces the chance of having random offsets
- * between the processors, and guarantees that the maximum
- * delay between the cycle counters is never bigger than
- * the latency of information-passing (cachelines) between
- * two CPUs.
- */
+/*
+ * We use a raw spinlock in this exceptional case, because
+ * we want to have the fastest, inlined, non-debug version
+ * of a critical section, to be able to prove counter time-warps:
+ */
+static arch_spinlock_t sync_lock = __ARCH_SPIN_LOCK_UNLOCKED;
- for (i = 0; i < NR_LOOPS; i++) {
- /* slaves loop on '!= 2' */
- while (atomic_read(&count_count_start) != 1)
- mb();
- atomic_set(&count_count_stop, 0);
- smp_wmb();
+static uint32_t last_counter;
+static uint32_t max_warp;
+static int nr_warps;
+static int random_warps;
- /* Let the slave writes its count register */
- atomic_inc(&count_count_start);
+/*
+ * Counter warp measurement loop running on both CPUs.
+ */
+static uint32_t check_counter_warp(void)
+{
+ uint32_t start, now, prev, end, cur_max_warp = 0;
+ int i, cur_warps = 0;
- /* Count will be initialised to current timer */
- if (i == 1)
- initcount = read_c0_count();
+ start = read_c0_count();
+ end = start + (uint32_t) mips_hpt_frequency / 1000 * LOOP_TIMEOUT;
+ for (i = 0; ; i++) {
/*
- * Everyone initialises count in the last loop:
+ * We take the global lock, measure counter, save the
+ * previous counter that was measured (possibly on
+ * another CPU) and update the previous counter timestamp.
*/
- if (i == NR_LOOPS-1)
- write_c0_count(initcount);
+ arch_spin_lock(&sync_lock);
+ prev = last_counter;
+ now = read_c0_count();
+ last_counter = now;
+ arch_spin_unlock(&sync_lock);
/*
- * Wait for slave to leave the synchronization point:
+ * Be nice every now and then (and also check whether
+ * measurement is done [we also insert a 10 million
+ * loops safety exit, so we dont lock up in case the
+ * counter is totally broken]):
*/
- while (atomic_read(&count_count_stop) != 1)
- mb();
- atomic_set(&count_count_start, 0);
- smp_wmb();
- atomic_inc(&count_count_stop);
+ if (unlikely(!(i & 7))) {
+ if (now > end || i > 10000000)
+ break;
+ cpu_relax();
+ touch_nmi_watchdog();
+ }
+ /*
+ * Outside the critical section we can now see whether
+ * we saw a time-warp of the counter going backwards:
+ */
+ if (unlikely(prev > now)) {
+ arch_spin_lock(&sync_lock);
+ max_warp = max(max_warp, prev - now);
+ cur_max_warp = max_warp;
+ /*
+ * Check whether this bounces back and forth. Only
+ * one CPU should observe time going backwards.
+ */
+ if (cur_warps != nr_warps)
+ random_warps++;
+ nr_warps++;
+ cur_warps = nr_warps;
+ arch_spin_unlock(&sync_lock);
+ }
+ }
+ WARN(!(now-start),
+ "Warning: zero counter calibration delta: %d [max: %d]\n",
+ now-start, end-start);
+ return cur_max_warp;
+}
+
+/*
+ * The freshly booted CPU initiates this via an async SMP function call.
+ */
+static void check_counter_sync_source(void *__cpu)
+{
+ unsigned int cpu = (unsigned long)__cpu;
+ int cpus = 2;
+
+ atomic_set(&test_runs, NR_LOOPS);
+retry:
+ /* Wait for the target to start. */
+ while (atomic_read(&start_count) != cpus - 1)
+ cpu_relax();
+
+ /*
+ * Trigger the target to continue into the measurement too:
+ */
+ atomic_inc(&start_count);
+
+ check_counter_warp();
+
+ while (atomic_read(&stop_count) != cpus-1)
+ cpu_relax();
+
+ /*
+ * If the test was successful set the number of runs to zero and
+ * stop. If not, decrement the number of runs an check if we can
+ * retry. In case of random warps no retry is attempted.
+ */
+ if (!nr_warps) {
+ atomic_set(&test_runs, 0);
+
+ pr_info("Counter synchronization [CPU#%d -> CPU#%u]: passed\n",
+ smp_processor_id(), cpu);
+ } else if (atomic_dec_and_test(&test_runs) || random_warps) {
+ /* Force it to 0 if random warps brought us here */
+ atomic_set(&test_runs, 0);
+
+ pr_info("Counter synchronization [CPU#%d -> CPU#%u]:\n",
+ smp_processor_id(), cpu);
+ pr_info("Measured %d cycles counter warp between CPUs", max_warp);
+ if (random_warps)
+ pr_warn("Counter warped randomly between CPUs\n");
}
- /* Arrange for an interrupt in a short while */
- write_c0_compare(read_c0_count() + COUNTON);
- local_irq_restore(flags);
+ /*
+ * Reset it - just in case we boot another CPU later:
+ */
+ atomic_set(&start_count, 0);
+ random_warps = 0;
+ nr_warps = 0;
+ max_warp = 0;
+ last_counter = 0;
+
+ /*
+ * Let the target continue with the bootup:
+ */
+ atomic_inc(&stop_count);
/*
- * i386 code reported the skew here, but the
- * count registers were almost certainly out of sync
- * so no point in alarming people
+ * Retry, if there is a chance to do so.
*/
- pr_cont("done.\n");
+ if (atomic_read(&test_runs) > 0)
+ goto retry;
}
+/*
+ * Freshly booted CPUs call into this:
+ */
void synchronise_count_slave(int cpu)
{
- int i;
- unsigned long flags;
+ uint32_t cur_max_warp, gbl_max_warp, count;
+ int cpus = 2;
- local_irq_save(flags);
+ if (!cpu_has_counter || !mips_hpt_frequency)
+ return;
+ /* Kick the control CPU into the counter synchronization function */
+ smp_call_function_single(cpumask_first(cpu_online_mask),
+ check_counter_sync_source,
+ (unsigned long *)(unsigned long)cpu, 0);
+retry:
/*
- * Not every cpu is online at the time this gets called,
- * so we first wait for the master to say everyone is ready
+ * Register this CPU's participation and wait for the
+ * source CPU to start the measurement:
*/
+ atomic_inc(&start_count);
+ while (atomic_read(&start_count) != cpus)
+ cpu_relax();
- for (i = 0; i < NR_LOOPS; i++) {
- atomic_inc(&count_count_start);
- while (atomic_read(&count_count_start) != 2)
- mb();
+ cur_max_warp = check_counter_warp();
- /*
- * Everyone initialises count in the last loop:
- */
- if (i == NR_LOOPS-1)
- write_c0_count(initcount);
+ /*
+ * Store the maximum observed warp value for a potential retry:
+ */
+ gbl_max_warp = max_warp;
+
+ /*
+ * Ok, we are done:
+ */
+ atomic_inc(&stop_count);
+
+ /*
+ * Wait for the source CPU to print stuff:
+ */
+ while (atomic_read(&stop_count) != cpus)
+ cpu_relax();
- atomic_inc(&count_count_stop);
- while (atomic_read(&count_count_stop) != 2)
- mb();
+ /*
+ * Reset it for the next sync test:
+ */
+ atomic_set(&stop_count, 0);
+
+ /*
+ * Check the number of remaining test runs. If not zero, the test
+ * failed and a retry with adjusted counter is possible. If zero the
+ * test was either successful or failed terminally.
+ */
+ if (!atomic_read(&test_runs)) {
+ /* Arrange for an interrupt in a short while */
+ write_c0_compare(read_c0_count() + COUNTON);
+ return;
}
- /* Arrange for an interrupt in a short while */
- write_c0_compare(read_c0_count() + COUNTON);
- local_irq_restore(flags);
+ /*
+ * If the warp value of this CPU is 0, then the other CPU
+ * observed time going backwards so this counter was ahead and
+ * needs to move backwards.
+ */
+ if (!cur_max_warp)
+ cur_max_warp = -gbl_max_warp;
+
+ count = read_c0_count();
+ count += cur_max_warp;
+ write_c0_count(count);
+
+ pr_debug("Counter compensate: CPU%u observed %d warp\n", cpu, cur_max_warp);
+
+ goto retry;
+
}
-#undef NR_LOOPS
diff --git a/arch/mips/kernel/syscalls/Makefile b/arch/mips/kernel/syscalls/Makefile
index e6b21de65cca..56f6f093bb88 100644
--- a/arch/mips/kernel/syscalls/Makefile
+++ b/arch/mips/kernel/syscalls/Makefile
@@ -5,7 +5,7 @@ uapi := arch/$(SRCARCH)/include/generated/uapi/asm
$(shell mkdir -p $(uapi) $(kapi))
syshdr := $(srctree)/scripts/syscallhdr.sh
-sysnr := $(srctree)/$(src)/syscallnr.sh
+sysnr := $(src)/syscallnr.sh
systbl := $(srctree)/scripts/syscalltbl.sh
quiet_cmd_syshdr = SYSHDR $@
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 83cfc9eb6b88..953f5b7dc723 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -354,7 +354,7 @@
412 n32 utimensat_time64 sys_utimensat
413 n32 pselect6_time64 compat_sys_pselect6_time64
414 n32 ppoll_time64 compat_sys_ppoll_time64
-416 n32 io_pgetevents_time64 sys_io_pgetevents
+416 n32 io_pgetevents_time64 compat_sys_io_pgetevents_time64
417 n32 recvmmsg_time64 compat_sys_recvmmsg_time64
418 n32 mq_timedsend_time64 sys_mq_timedsend
419 n32 mq_timedreceive_time64 sys_mq_timedreceive
@@ -400,3 +400,4 @@
459 n32 lsm_get_self_attr sys_lsm_get_self_attr
460 n32 lsm_set_self_attr sys_lsm_set_self_attr
461 n32 lsm_list_modules sys_lsm_list_modules
+462 n32 mseal sys_mseal
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 532b855df589..1464c6be6eb3 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -376,3 +376,4 @@
459 n64 lsm_get_self_attr sys_lsm_get_self_attr
460 n64 lsm_set_self_attr sys_lsm_set_self_attr
461 n64 lsm_list_modules sys_lsm_list_modules
+462 n64 mseal sys_mseal
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index f45c9530ea93..2439a2491cff 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -27,7 +27,7 @@
17 o32 break sys_ni_syscall
# 18 was sys_stat
18 o32 unused18 sys_ni_syscall
-19 o32 lseek sys_lseek
+19 o32 lseek sys_lseek compat_sys_lseek
20 o32 getpid sys_getpid
21 o32 mount sys_mount
22 o32 umount sys_oldumount
@@ -403,7 +403,7 @@
412 o32 utimensat_time64 sys_utimensat sys_utimensat
413 o32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
414 o32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64
-416 o32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents
+416 o32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64
417 o32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
418 o32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend
419 o32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive
@@ -449,3 +449,4 @@
459 o32 lsm_get_self_attr sys_lsm_get_self_attr
460 o32 lsm_set_self_attr sys_lsm_set_self_attr
461 o32 lsm_list_modules sys_lsm_list_modules
+462 o32 mseal sys_mseal
diff --git a/arch/mips/kvm/interrupt.h b/arch/mips/kvm/interrupt.h
index e529ea2bb34b..07bc0160bc94 100644
--- a/arch/mips/kvm/interrupt.h
+++ b/arch/mips/kvm/interrupt.h
@@ -37,3 +37,7 @@ u32 kvm_irq_to_priority(u32 irq);
int kvm_mips_pending_timer(struct kvm_vcpu *vcpu);
void kvm_mips_deliver_interrupts(struct kvm_vcpu *vcpu, u32 cause);
+
+#ifdef CONFIG_CPU_LOONGSON64
+extern void kvm_init_loongson_ipi(struct kvm *kvm);
+#endif
diff --git a/arch/mips/kvm/loongson_ipi.c b/arch/mips/kvm/loongson_ipi.c
index 5d53f32d837c..6ac83a31148c 100644
--- a/arch/mips/kvm/loongson_ipi.c
+++ b/arch/mips/kvm/loongson_ipi.c
@@ -10,6 +10,8 @@
#include <linux/kvm_host.h>
+#include "interrupt.h"
+
#define IPI_BASE 0x3ff01000ULL
#define CORE0_STATUS_OFF 0x000
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 231ac052b506..b5de770b092e 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -135,8 +135,6 @@ void kvm_arch_hardware_disable(void)
kvm_mips_callbacks->hardware_disable();
}
-extern void kvm_init_loongson_ipi(struct kvm *kvm);
-
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
{
switch (type) {
@@ -436,7 +434,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
vcpu->mmio_needed = 0;
}
- if (vcpu->run->immediate_exit)
+ if (!vcpu->wants_to_run)
goto out;
lose_fpu(1);
diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c
index 467ee6b95ae1..c17157e700c0 100644
--- a/arch/mips/kvm/mmu.c
+++ b/arch/mips/kvm/mmu.c
@@ -444,36 +444,6 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
return true;
}
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- gpa_t gpa = range->start << PAGE_SHIFT;
- pte_t hva_pte = range->arg.pte;
- pte_t *gpa_pte = kvm_mips_pte_for_gpa(kvm, NULL, gpa);
- pte_t old_pte;
-
- if (!gpa_pte)
- return false;
-
- /* Mapping may need adjusting depending on memslot flags */
- old_pte = *gpa_pte;
- if (range->slot->flags & KVM_MEM_LOG_DIRTY_PAGES && !pte_dirty(old_pte))
- hva_pte = pte_mkclean(hva_pte);
- else if (range->slot->flags & KVM_MEM_READONLY)
- hva_pte = pte_wrprotect(hva_pte);
-
- set_pte(gpa_pte, hva_pte);
-
- /* Replacing an absent or old page doesn't need flushes */
- if (!pte_present(old_pte) || !pte_young(old_pte))
- return false;
-
- /* Pages swapped, aged, moved, or cleaned require flushes */
- return !pte_present(hva_pte) ||
- !pte_young(hva_pte) ||
- pte_pfn(old_pte) != pte_pfn(hva_pte) ||
- (pte_dirty(old_pte) && !pte_dirty(hva_pte));
-}
-
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
return kvm_mips_mkold_gpa_pt(kvm, range->start, range->end);
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 3ed078225222..5a75283d17f1 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -247,6 +247,25 @@ static void pmu_disable(struct clk *clk)
pr_warn("deactivating PMU module failed!");
}
+static void usb_set_clock(void)
+{
+ unsigned int val = ltq_cgu_r32(ifccr);
+
+ if (of_machine_is_compatible("lantiq,ar10") ||
+ of_machine_is_compatible("lantiq,grx390")) {
+ val &= ~0x03; /* XTAL divided by 3 */
+ } else if (of_machine_is_compatible("lantiq,ar9") ||
+ of_machine_is_compatible("lantiq,vr9")) {
+ /* TODO: this depends on the XTAL frequency */
+ val |= 0x03; /* XTAL divided by 3 */
+ } else if (of_machine_is_compatible("lantiq,ase")) {
+ val |= 0x20; /* from XTAL */
+ } else if (of_machine_is_compatible("lantiq,danube")) {
+ val |= 0x30; /* 12 MHz, generated from 36 MHz */
+ }
+ ltq_cgu_w32(val, ifccr);
+}
+
/* the pci enable helper */
static int pci_enable(struct clk *clk)
{
@@ -588,4 +607,5 @@ void __init ltq_soc_init(void)
clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
}
+ usb_set_clock();
}
diff --git a/arch/mips/loongson64/Makefile b/arch/mips/loongson64/Makefile
index e806280bbb85..cbba30dfddf5 100644
--- a/arch/mips/loongson64/Makefile
+++ b/arch/mips/loongson64/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_MACH_LOONGSON64) += cop2-ex.o dma.o \
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_RS780_HPET) += hpet.o
-obj-$(CONFIG_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += pm.o sleeper.o
obj-$(CONFIG_PCI_QUIRKS) += vbios_quirk.o
obj-$(CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION) += cpucfg-emul.o
obj-$(CONFIG_SYSFS) += boardinfo.o
diff --git a/arch/mips/loongson64/dma.c b/arch/mips/loongson64/dma.c
index 8220a1bc0db6..52801442ea86 100644
--- a/arch/mips/loongson64/dma.c
+++ b/arch/mips/loongson64/dma.c
@@ -2,6 +2,7 @@
#include <linux/dma-direct.h>
#include <linux/init.h>
#include <linux/swiotlb.h>
+#include <asm/bootinfo.h>
#include <boot_param.h>
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c
index ef3750a6ffac..09ff05269861 100644
--- a/arch/mips/loongson64/env.c
+++ b/arch/mips/loongson64/env.c
@@ -88,6 +88,12 @@ void __init prom_lefi_init_env(void)
cpu_clock_freq = ecpu->cpu_clock_freq;
loongson_sysconf.cputype = ecpu->cputype;
switch (ecpu->cputype) {
+ case Legacy_2K:
+ case Loongson_2K:
+ smp_group[0] = 0x900000001fe11000;
+ loongson_sysconf.cores_per_node = 2;
+ loongson_sysconf.cores_per_package = 2;
+ break;
case Legacy_3A:
case Loongson_3A:
loongson_sysconf.cores_per_node = 4;
@@ -221,6 +227,8 @@ void __init prom_lefi_init_env(void)
default:
break;
}
+ } else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64R) {
+ loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
} else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G) {
if (loongson_sysconf.bridgetype == LS7A)
loongson_fdt_blob = __dtb_loongson64g_4core_ls7a_begin;
diff --git a/arch/mips/loongson64/pm.c b/arch/mips/loongson64/pm.c
index 7c8556f09781..5f0604af8f13 100644
--- a/arch/mips/loongson64/pm.c
+++ b/arch/mips/loongson64/pm.c
@@ -6,98 +6,46 @@
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#include <linux/suspend.h>
-#include <linux/interrupt.h>
#include <linux/pm.h>
-#include <asm/i8259.h>
#include <asm/mipsregs.h>
#include <loongson.h>
-static unsigned int __maybe_unused cached_master_mask; /* i8259A */
-static unsigned int __maybe_unused cached_slave_mask;
-static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */
+asmlinkage void loongson_lefi_sleep(unsigned long sleep_addr);
-void arch_suspend_disable_irqs(void)
+static int lefi_pm_enter(suspend_state_t state)
{
- /* disable all mips events */
- local_irq_disable();
-
-#ifdef CONFIG_I8259
- /* disable all events of i8259A */
- cached_slave_mask = inb(PIC_SLAVE_IMR);
- cached_master_mask = inb(PIC_MASTER_IMR);
-
- outb(0xff, PIC_SLAVE_IMR);
- inb(PIC_SLAVE_IMR);
- outb(0xff, PIC_MASTER_IMR);
- inb(PIC_MASTER_IMR);
-#endif
- /* disable all events of bonito */
- cached_bonito_irq_mask = LOONGSON_INTEN;
- LOONGSON_INTENCLR = 0xffff;
- (void)LOONGSON_INTENCLR;
-}
-
-void arch_suspend_enable_irqs(void)
-{
- /* enable all mips events */
- local_irq_enable();
-#ifdef CONFIG_I8259
- /* only enable the cached events of i8259A */
- outb(cached_slave_mask, PIC_SLAVE_IMR);
- outb(cached_master_mask, PIC_MASTER_IMR);
-#endif
- /* enable all cached events of bonito */
- LOONGSON_INTENSET = cached_bonito_irq_mask;
- (void)LOONGSON_INTENSET;
-}
-
-/*
- * Setup the board-specific events for waking up loongson from wait mode
- */
-void __weak setup_wakeup_events(void)
-{
-}
-
-void __weak mach_suspend(void)
-{
-}
-
-void __weak mach_resume(void)
-{
-}
-
-static int loongson_pm_enter(suspend_state_t state)
-{
- mach_suspend();
-
- mach_resume();
-
- return 0;
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ pm_set_suspend_via_firmware();
+ loongson_lefi_sleep(loongson_sysconf.suspend_addr);
+ pm_set_resume_via_firmware();
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
-static int loongson_pm_valid_state(suspend_state_t state)
+static int lefi_pm_valid_state(suspend_state_t state)
{
switch (state) {
- case PM_SUSPEND_ON:
- case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM:
- return 1;
-
+ return !!loongson_sysconf.suspend_addr;
default:
return 0;
}
}
-static const struct platform_suspend_ops loongson_pm_ops = {
- .valid = loongson_pm_valid_state,
- .enter = loongson_pm_enter,
+static const struct platform_suspend_ops lefi_pm_ops = {
+ .valid = lefi_pm_valid_state,
+ .enter = lefi_pm_enter,
};
static int __init loongson_pm_init(void)
{
- suspend_set_ops(&loongson_pm_ops);
+ if (loongson_sysconf.fw_interface == LOONGSON_LEFI)
+ suspend_set_ops(&lefi_pm_ops);
return 0;
}
diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c
index e01c8d4a805a..3e20ade0503a 100644
--- a/arch/mips/loongson64/reset.c
+++ b/arch/mips/loongson64/reset.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/kexec.h>
#include <linux/pm.h>
+#include <linux/reboot.h>
#include <linux/slab.h>
#include <asm/bootinfo.h>
@@ -21,36 +22,21 @@
#include <loongson.h>
#include <boot_param.h>
-static void loongson_restart(char *command)
+static int firmware_restart(struct sys_off_data *unusedd)
{
void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr;
fw_restart();
- while (1) {
- if (cpu_wait)
- cpu_wait();
- }
+ return NOTIFY_DONE;
}
-static void loongson_poweroff(void)
+static int firmware_poweroff(struct sys_off_data *unused)
{
void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr;
fw_poweroff();
- while (1) {
- if (cpu_wait)
- cpu_wait();
- }
-}
-
-static void loongson_halt(void)
-{
- pr_notice("\n\n** You can safely turn off the power now **\n\n");
- while (1) {
- if (cpu_wait)
- cpu_wait();
- }
+ return NOTIFY_DONE;
}
#ifdef CONFIG_KEXEC_CORE
@@ -154,9 +140,17 @@ static void loongson_crash_shutdown(struct pt_regs *regs)
static int __init mips_reboot_setup(void)
{
- _machine_restart = loongson_restart;
- _machine_halt = loongson_halt;
- pm_power_off = loongson_poweroff;
+ if (loongson_sysconf.restart_addr) {
+ register_sys_off_handler(SYS_OFF_MODE_RESTART,
+ SYS_OFF_PRIO_FIRMWARE,
+ firmware_restart, NULL);
+ }
+
+ if (loongson_sysconf.poweroff_addr) {
+ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+ SYS_OFF_PRIO_FIRMWARE,
+ firmware_poweroff, NULL);
+ }
#ifdef CONFIG_KEXEC_CORE
kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
diff --git a/arch/mips/loongson64/sleeper.S b/arch/mips/loongson64/sleeper.S
new file mode 100644
index 000000000000..cf16877409e2
--- /dev/null
+++ b/arch/mips/loongson64/sleeper.S
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024, Jiaxun Yang <jiaxun.yang@flygoat.com>
+ * Loongson EFI firmware sleeper routine
+ */
+
+#include <asm/asm.h>
+#include <asm/pm.h>
+
+#include <kernel-entry-init.h>
+
+LEAF(loongson_lefi_sleep)
+ SUSPEND_SAVE
+ move t9, a0
+ PTR_LA a0, wake
+ move a1, sp
+ jalr t9
+wake:
+ smp_slave_setup
+ RESUME_RESTORE_REGS_RETURN
+END(loongson_lefi_sleep)
diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c
index 5a990cdef91a..147acd972a07 100644
--- a/arch/mips/loongson64/smp.c
+++ b/arch/mips/loongson64/smp.c
@@ -33,7 +33,6 @@ static void __iomem *ipi_clear0_regs[16];
static void __iomem *ipi_status0_regs[16];
static void __iomem *ipi_en0_regs[16];
static void __iomem *ipi_mailbox_buf[16];
-static uint32_t core0_c0count[NR_CPUS];
static u32 (*ipi_read_clear)(int cpu);
static void (*ipi_write_action)(int cpu, u32 action);
@@ -382,11 +381,10 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
ipi_write_action(cpu_logical_map(i), (u32)action);
}
-
static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
{
- int i, cpu = smp_processor_id();
- unsigned int action, c0count;
+ int cpu = smp_processor_id();
+ unsigned int action;
action = ipi_read_clear(cpu);
@@ -399,26 +397,14 @@ static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
irq_exit();
}
- if (action & SMP_ASK_C0COUNT) {
- BUG_ON(cpu != 0);
- c0count = read_c0_count();
- c0count = c0count ? c0count : 1;
- for (i = 1; i < nr_cpu_ids; i++)
- core0_c0count[i] = c0count;
- nudge_writes(); /* Let others see the result ASAP */
- }
-
return IRQ_HANDLED;
}
-#define MAX_LOOPS 800
/*
* SMP init and finish on secondary CPUs
*/
static void loongson3_init_secondary(void)
{
- int i;
- uint32_t initcount;
unsigned int cpu = smp_processor_id();
unsigned int imask = STATUSF_IP7 | STATUSF_IP6 |
STATUSF_IP3 | STATUSF_IP2;
@@ -432,23 +418,6 @@ static void loongson3_init_secondary(void)
cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
cpu_data[cpu].package =
cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
-
- i = 0;
- core0_c0count[cpu] = 0;
- loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
- while (!core0_c0count[cpu]) {
- i++;
- cpu_relax();
- }
-
- if (i > MAX_LOOPS)
- i = MAX_LOOPS;
- if (cpu_data[cpu].package)
- initcount = core0_c0count[cpu] + i;
- else /* Local access is faster for loops */
- initcount = core0_c0count[cpu] + i/2;
-
- write_c0_count(initcount);
}
static void loongson3_smp_finish(void)
@@ -466,12 +435,25 @@ static void loongson3_smp_finish(void)
static void __init loongson3_smp_setup(void)
{
int i = 0, num = 0; /* i: physical id, num: logical id */
+ int max_cpus = 0;
init_cpu_possible(cpu_none_mask);
+ for (i = 0; i < ARRAY_SIZE(smp_group); i++) {
+ if (!smp_group[i])
+ break;
+ max_cpus += loongson_sysconf.cores_per_node;
+ }
+
+ if (max_cpus < loongson_sysconf.nr_cpus) {
+ pr_err("SMP Groups are less than the number of CPUs\n");
+ loongson_sysconf.nr_cpus = max_cpus ? max_cpus : 1;
+ }
+
/* For unified kernel, NR_CPUS is the maximum possible value,
* loongson_sysconf.nr_cpus is the really present value
*/
+ i = 0;
while (i < loongson_sysconf.nr_cpus) {
if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
/* Reserved physical CPU cores */
@@ -492,14 +474,14 @@ static void __init loongson3_smp_setup(void)
__cpu_logical_map[num] = -1;
num++;
}
-
csr_ipi_probe();
ipi_set0_regs_init();
ipi_clear0_regs_init();
ipi_status0_regs_init();
ipi_en0_regs_init();
ipi_mailbox_buf_init();
- ipi_write_enable(0);
+ if (smp_group[0])
+ ipi_write_enable(0);
cpu_set_core(&cpu_data[0],
cpu_logical_map(0) % loongson_sysconf.cores_per_package);
@@ -818,6 +800,9 @@ static int loongson3_disable_clock(unsigned int cpu)
uint64_t core_id = cpu_core(&cpu_data[cpu]);
uint64_t package_id = cpu_data[cpu].package;
+ if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id])
+ return 0;
+
if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
} else {
@@ -832,6 +817,9 @@ static int loongson3_enable_clock(unsigned int cpu)
uint64_t core_id = cpu_core(&cpu_data[cpu]);
uint64_t package_id = cpu_data[cpu].package;
+ if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id])
+ return 0;
+
if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
} else {
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index df1ced4fc3b5..bf9a37c60e9f 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -112,7 +112,7 @@ void __flush_dcache_pages(struct page *page, unsigned int nr)
}
/*
- * We could delay the flush for the !page_mapping case too. But that
+ * We could delay the flush for the !folio_mapping case too. But that
* case is for exec env/arg pages and those are %99 certainly going to
* get faulted into the tlb (and thus flushed) anyways.
*/
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 0f3cec663a12..ab4f2a75a7d0 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -137,8 +137,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
#endif
#ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
{
dev->dma_coherent = coherent;
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index aaa9a242ebba..37fedeaca2e9 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -83,8 +83,8 @@ static void __do_page_fault(struct pt_regs *regs, unsigned long write,
if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
goto VMALLOC_FAULT_TARGET;
-#ifdef MODULE_START
- if (unlikely(address >= MODULE_START && address < MODULE_END))
+#ifdef MODULES_VADDR
+ if (unlikely(address >= MODULES_VADDR && address < MODULES_END))
goto VMALLOC_FAULT_TARGET;
#endif
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c
index 7eaff5b07873..0b9e15555b59 100644
--- a/arch/mips/mm/hugetlbpage.c
+++ b/arch/mips/mm/hugetlbpage.c
@@ -57,13 +57,3 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
}
return (pte_t *) pmd;
}
-
-int pmd_huge(pmd_t pmd)
-{
- return (pmd_val(pmd) & _PAGE_HUGE) != 0;
-}
-
-int pud_huge(pud_t pud)
-{
- return (pud_val(pud) & _PAGE_HUGE) != 0;
-}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 39f129205b0c..4583d1a2a73e 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -31,6 +31,7 @@
#include <linux/gfp.h>
#include <linux/kcore.h>
#include <linux/initrd.h>
+#include <linux/execmem.h>
#include <asm/bootinfo.h>
#include <asm/cachectl.h>
@@ -576,3 +577,25 @@ EXPORT_SYMBOL_GPL(invalid_pmd_table);
#endif
pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
EXPORT_SYMBOL(invalid_pte_table);
+
+#ifdef CONFIG_EXECMEM
+#ifdef MODULES_VADDR
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = MODULES_VADDR,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 00fe90c6db3e..7e11d7b58761 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -34,7 +34,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
struct vm_area_struct *vma;
unsigned long addr = addr0;
int do_color_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (unlikely(len > TASK_SIZE))
return -ENOMEM;
@@ -92,7 +92,6 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
*/
}
- info.flags = 0;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
return vm_unmapped_area(&info);
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 4106084e57d7..76f3b9c0a9f0 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -326,7 +326,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
idx = read_c0_index();
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
/* this could be a huge page */
- if (pmd_huge(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
unsigned long lo;
write_c0_pagemask(PM_HUGE_MASK);
ptep = (pte_t *)pmdp;
diff --git a/arch/mips/mobileye/Kconfig b/arch/mips/mobileye/Kconfig
new file mode 100644
index 000000000000..f9abb2d6e178
--- /dev/null
+++ b/arch/mips/mobileye/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0
+if EYEQ
+
+choice
+ prompt "Mobileye EyeQ SoC selection"
+ default MACH_EYEQ5
+ help
+ Select Mobileye EyeQ MIPS SoC type.
+
+ config MACH_EYEQ5
+ bool "Mobileye EyeQ5 SoC"
+
+ config MACH_EYEQ6H
+ bool "Mobileye EyeQ6H SoC"
+endchoice
+
+config FIT_IMAGE_FDT_EPM5
+ bool "Include FDT for Mobileye EyeQ5 development platforms"
+ depends on MACH_EYEQ5
+ default n
+ help
+ Enable this to include the FDT for the EyeQ5 development platforms
+ from Mobileye in the FIT kernel image.
+ This requires u-boot on the platform.
+
+endif
diff --git a/arch/mips/mobileye/Platform b/arch/mips/mobileye/Platform
index c69f811dd13a..69f775bbbb1e 100644
--- a/arch/mips/mobileye/Platform
+++ b/arch/mips/mobileye/Platform
@@ -9,6 +9,7 @@
#
load-$(CONFIG_MACH_EYEQ5) = 0xa800000808000000
+load-$(CONFIG_MACH_EYEQ6H) = 0xa800000100800000
all-$(CONFIG_MACH_EYEQ5) += vmlinux.gz.itb
its-y := vmlinux.its.S
diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c
index a40d926b6513..e355dfca4400 100644
--- a/arch/mips/net/bpf_jit_comp.c
+++ b/arch/mips/net/bpf_jit_comp.c
@@ -1012,7 +1012,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]);
/* Set as read-only exec and flush instruction cache */
- bpf_jit_binary_lock_ro(header);
+ if (bpf_jit_binary_lock_ro(header))
+ goto out_err;
flush_icache_range((unsigned long)header,
(unsigned long)&ctx.target[ctx.jit_index]);
diff --git a/arch/mips/pci/ops-rc32434.c b/arch/mips/pci/ops-rc32434.c
index 874ed6df9768..34b9323bdabb 100644
--- a/arch/mips/pci/ops-rc32434.c
+++ b/arch/mips/pci/ops-rc32434.c
@@ -112,8 +112,8 @@ retry:
* gives them time to settle
*/
if (where == PCI_VENDOR_ID) {
- if (ret == 0xffffffff || ret == 0x00000000 ||
- ret == 0x0000ffff || ret == 0xffff0000) {
+ if (*val == 0xffffffff || *val == 0x00000000 ||
+ *val == 0x0000ffff || *val == 0xffff0000) {
if (delay > 4)
return 0;
delay *= 2;
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
index 2583e318e8c6..b080c7c6cc46 100644
--- a/arch/mips/pci/pcie-octeon.c
+++ b/arch/mips/pci/pcie-octeon.c
@@ -230,12 +230,18 @@ static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus,
{
union cvmx_pcie_address pcie_addr;
union cvmx_pciercx_cfg006 pciercx_cfg006;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
pciercx_cfg006.u32 =
cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
return 0;
+ pciercx_cfg032.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1))
+ return 0;
+
pcie_addr.u64 = 0;
pcie_addr.config.upper = 2;
pcie_addr.config.io = 1;
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index 29c21b9d42da..ea6ebfea4a67 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -197,7 +197,7 @@ void rb532_gpio_set_func(unsigned gpio)
}
EXPORT_SYMBOL(rb532_gpio_set_func);
-int __init rb532_gpio_init(void)
+static int __init rb532_gpio_init(void)
{
struct resource *r;
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
index b11693715547..b88e89ec5894 100644
--- a/arch/mips/rb532/prom.c
+++ b/arch/mips/rb532/prom.c
@@ -46,7 +46,7 @@ static inline unsigned long tag2ul(char *arg, const char *tag)
return simple_strtoul(num, 0, 10);
}
-void __init prom_setup_cmdline(void)
+static void __init prom_setup_cmdline(void)
{
static char cmd_line[COMMAND_LINE_SIZE] __initdata;
char *cp, *board;
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c
index a3cdcb289941..2738325e98dd 100644
--- a/arch/mips/sgi-ip22/ip22-gio.c
+++ b/arch/mips/sgi-ip22/ip22-gio.c
@@ -246,7 +246,7 @@ void gio_set_master(struct gio_device *dev)
}
EXPORT_SYMBOL_GPL(gio_set_master);
-void ip22_gio_set_64bit(int slotno)
+static void ip22_gio_set_64bit(int slotno)
{
u32 tmp = sgimc->giopar;
@@ -395,7 +395,7 @@ static struct resource gio_bus_resource = {
.flags = IORESOURCE_MEM,
};
-int __init ip22_gio_init(void)
+static int __init ip22_gio_init(void)
{
unsigned int pbdma __maybe_unused;
int ret;
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index 96798a4ab2de..11f8adc98cb5 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -165,8 +165,6 @@ static void __irq_entry indy_buserror_irq(void)
#define SGI_INTERRUPTS SGINT_LOCAL3
#endif
-extern void indy_8254timer_irq(void);
-
/*
* IRQs on the INDY look basically (barring software IRQs which we don't use
* at all) like:
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index b69daa02401b..e06a818fe792 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -26,8 +26,6 @@
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
-extern void ip22_be_init(void) __init;
-
void __init plat_mem_setup(void)
{
char *ctype;
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 8f5299b269e7..00e63e9ef61d 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -277,7 +277,6 @@ void __init arch_init_irq(void)
{
struct irq_domain *domain;
struct fwnode_handle *fn;
- int i;
mips_cpu_irq_init();
@@ -286,20 +285,16 @@ void __init arch_init_irq(void)
* Mark these as reserved right away so they won't be used accidentally
* later.
*/
- for (i = 0; i <= CPU_CALL_B_IRQ; i++)
- set_bit(i, hub_irq_map);
-
- for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++)
- set_bit(i, hub_irq_map);
+ bitmap_set(hub_irq_map, 0, CPU_CALL_B_IRQ + 1);
+ bitmap_set(hub_irq_map, NI_BRDCAST_ERR_A, MSC_PANIC_INTR - NI_BRDCAST_ERR_A + 1);
fn = irq_domain_alloc_named_fwnode("HUB");
- WARN_ON(fn == NULL);
- if (!fn)
+ if (WARN_ON(fn == NULL))
return;
+
domain = irq_domain_create_linear(fn, IP27_HUB_IRQ_COUNT,
&hub_domain_ops, NULL);
- WARN_ON(domain == NULL);
- if (!domain)
+ if (WARN_ON(domain == NULL))
return;
irq_set_default_host(domain);
diff --git a/arch/mips/sgi-ip30/ip30-console.c b/arch/mips/sgi-ip30/ip30-console.c
index 7c6dcf6e73f7..a5f10097b985 100644
--- a/arch/mips/sgi-ip30/ip30-console.c
+++ b/arch/mips/sgi-ip30/ip30-console.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/io.h>
+#include <linux/processor.h>
#include <asm/sn/ioc3.h>
#include <asm/setup.h>
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index af5333986900..149a9151bc0b 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -589,4 +589,5 @@ module_exit(sbprof_tb_cleanup);
MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR);
MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_DESCRIPTION("Support for ZBbus profiling");
MODULE_LICENSE("GPL");
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index eb56581f6d73..b289b2c1b294 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -1,9 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Objects to go into the VDSO.
-# Sanitizer runtimes are unavailable and cannot be linked here.
- KCSAN_SANITIZE := n
-
# Include the generic Makefile to check the built vdso.
include $(srctree)/lib/vdso/Makefile
@@ -43,8 +40,8 @@ CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
# config-n32-o32-env.c prepares the environment to build a 32bit vDSO
# library on a 64bit kernel.
# Note: Needs to be included before than the generic library.
-CFLAGS_vgettimeofday-o32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
-CFLAGS_vgettimeofday-n32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-o32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-n32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
endif
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
@@ -60,10 +57,6 @@ ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
CFLAGS_REMOVE_vdso.o = $(CC_FLAGS_FTRACE)
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-
# Check that we don't have PIC 'jalr t9' calls left
quiet_cmd_vdso_mips_check = VDSOCHK $@
cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | grep -E -h "jalr.*t9" > /dev/null; \
diff --git a/arch/nios2/boot/dts/Makefile b/arch/nios2/boot/dts/Makefile
index e9e31bb40df8..1a2e8996bec7 100644
--- a/arch/nios2/boot/dts/Makefile
+++ b/arch/nios2/boot/dts/Makefile
@@ -2,5 +2,4 @@
obj-y := $(patsubst %.dts,%.dtb.o,$(CONFIG_NIOS2_DTB_SOURCE))
-dtstree := $(srctree)/$(src)
-dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts))
diff --git a/arch/nios2/boot/install.sh b/arch/nios2/boot/install.sh
index 34a2feec42c8..1161f2bf59ec 100755
--- a/arch/nios2/boot/install.sh
+++ b/arch/nios2/boot/install.sh
@@ -16,6 +16,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
fi
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index 7fe7437555fb..0d09829ed144 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
+
generic-y += cmpxchg.h
generic-y += extable.h
generic-y += kvm_para.h
diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h
index d052dfcbe8d3..eab87c6beacb 100644
--- a/arch/nios2/include/asm/pgtable.h
+++ b/arch/nios2/include/asm/pgtable.h
@@ -25,7 +25,10 @@
#include <asm-generic/pgtable-nopmd.h>
#define VMALLOC_START CONFIG_NIOS2_KERNEL_MMU_REGION_BASE
-#define VMALLOC_END (CONFIG_NIOS2_KERNEL_REGION_BASE - 1)
+#define VMALLOC_END (CONFIG_NIOS2_KERNEL_REGION_BASE - SZ_32M - 1)
+
+#define MODULES_VADDR (CONFIG_NIOS2_KERNEL_REGION_BASE - SZ_32M)
+#define MODULES_END (CONFIG_NIOS2_KERNEL_REGION_BASE - 1)
struct mm_struct;
diff --git a/arch/nios2/include/asm/unistd.h b/arch/nios2/include/asm/unistd.h
new file mode 100644
index 000000000000..1146e56473c5
--- /dev/null
+++ b/arch/nios2/include/asm/unistd.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_UNISTD_H
+#define __ASM_UNISTD_H
+
+#include <uapi/asm/unistd.h>
+
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SET_GET_RLIMIT
+
+#define __ARCH_BROKEN_SYS_CLONE3
+
+#endif
diff --git a/arch/nios2/include/uapi/asm/Kbuild b/arch/nios2/include/uapi/asm/Kbuild
index e78470141932..2501e82a1a0a 100644
--- a/arch/nios2/include/uapi/asm/Kbuild
+++ b/arch/nios2/include/uapi/asm/Kbuild
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
+
generic-y += ucontext.h
diff --git a/arch/nios2/include/uapi/asm/unistd.h b/arch/nios2/include/uapi/asm/unistd.h
index 0b4bb1d41b28..1f0e0f5538d9 100644
--- a/arch/nios2/include/uapi/asm/unistd.h
+++ b/arch/nios2/include/uapi/asm/unistd.h
@@ -16,16 +16,4 @@
*
*/
- #define sys_mmap2 sys_mmap_pgoff
-
-#define __ARCH_WANT_RENAMEAT
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_TIME32_SYSCALLS
-
-/* Use the standard ABI for syscalls */
-#include <asm-generic/unistd.h>
-
-/* Additional Nios II specific syscalls. */
-#define __NR_cacheflush (__NR_arch_specific_syscall)
-__SYSCALL(__NR_cacheflush, sys_cacheflush)
+#include <asm/unistd_32.h>
diff --git a/arch/nios2/kernel/Makefile.syscalls b/arch/nios2/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..579a9daec272
--- /dev/null
+++ b/arch/nios2/kernel/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += nios2 time32 stat64 renameat rlimit
diff --git a/arch/nios2/kernel/module.c b/arch/nios2/kernel/module.c
index 76e0a42d6e36..f4483243578d 100644
--- a/arch/nios2/kernel/module.c
+++ b/arch/nios2/kernel/module.c
@@ -13,7 +13,6 @@
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/mm.h>
-#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/string.h>
@@ -21,25 +20,6 @@
#include <asm/cacheflush.h>
-/*
- * Modules should NOT be allocated with kmalloc for (obvious) reasons.
- * But we do it for now to avoid relocation issues. CALL26/PCREL26 cannot reach
- * from 0x80000000 (vmalloc area) to 0xc00000000 (kernel) (kmalloc returns
- * addresses in 0xc0000000)
- */
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
- return kmalloc(size, GFP_KERNEL);
-}
-
-/* Free memory returned from module_alloc */
-void module_memfree(void *module_region)
-{
- kfree(module_region);
-}
-
int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
unsigned int symindex, unsigned int relsec,
struct module *mod)
diff --git a/arch/nios2/kernel/syscall_table.c b/arch/nios2/kernel/syscall_table.c
index c2875a6dd5a4..434694067d8f 100644
--- a/arch/nios2/kernel/syscall_table.c
+++ b/arch/nios2/kernel/syscall_table.c
@@ -9,10 +9,12 @@
#include <asm/syscalls.h>
-#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+
+#define sys_mmap2 sys_mmap_pgoff
void *sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls-1] = sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index 7bc82ee889c9..3459df28afee 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -26,6 +26,7 @@
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/binfmts.h>
+#include <linux/execmem.h>
#include <asm/setup.h>
#include <asm/page.h>
@@ -143,3 +144,23 @@ static const pgprot_t protection_map[16] = {
[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = MKP(1, 1, 1)
};
DECLARE_VM_GET_PAGE_PROT
+
+#ifdef CONFIG_EXECMEM
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = MODULES_VADDR,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL_EXEC,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 3586cda55bde..69c0258700b2 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -188,6 +188,15 @@ config SMP
If you don't know what to do here, say N.
+config FPU
+ bool "FPU support"
+ default y
+ help
+ Say N here if you want to disable all floating-point related procedures
+ in the kernel and reduce binary size.
+
+ If you don't know what to do here, say Y.
+
source "kernel/Kconfig.hz"
config OPENRISC_NO_SPR_SR_DSX
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index c8c99b554ca4..cef49d60d74c 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
+
generic-y += extable.h
generic-y += kvm_para.h
generic-y += parport.h
diff --git a/arch/openrisc/include/asm/fpu.h b/arch/openrisc/include/asm/fpu.h
new file mode 100644
index 000000000000..57bc44d80d53
--- /dev/null
+++ b/arch/openrisc/include/asm/fpu.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_OPENRISC_FPU_H
+#define __ASM_OPENRISC_FPU_H
+
+struct task_struct;
+
+#ifdef CONFIG_FPU
+static inline void save_fpu(struct task_struct *task)
+{
+ task->thread.fpcsr = mfspr(SPR_FPCSR);
+}
+
+static inline void restore_fpu(struct task_struct *task)
+{
+ mtspr(SPR_FPCSR, task->thread.fpcsr);
+}
+#else
+#define save_fpu(tsk) do { } while (0)
+#define restore_fpu(tsk) do { } while (0)
+#endif
+
+#endif /* __ASM_OPENRISC_FPU_H */
diff --git a/arch/openrisc/include/asm/processor.h b/arch/openrisc/include/asm/processor.h
index 3b736e74e6ed..e05d1b59e24e 100644
--- a/arch/openrisc/include/asm/processor.h
+++ b/arch/openrisc/include/asm/processor.h
@@ -44,6 +44,7 @@
struct task_struct;
struct thread_struct {
+ long fpcsr; /* Floating point control status register. */
};
/*
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
index 375147ff71fc..1da3e66292e2 100644
--- a/arch/openrisc/include/asm/ptrace.h
+++ b/arch/openrisc/include/asm/ptrace.h
@@ -59,7 +59,7 @@ struct pt_regs {
* -1 for all other exceptions.
*/
long orig_gpr11; /* For restarting system calls */
- long fpcsr; /* Floating point control status register. */
+ long dummy; /* Cheap alignment fix */
long dummy2; /* Cheap alignment fix */
};
@@ -115,6 +115,5 @@ static inline long regs_return_value(struct pt_regs *regs)
#define PT_GPR31 124
#define PT_PC 128
#define PT_ORIG_GPR11 132
-#define PT_FPCSR 136
#endif /* __ASM_OPENRISC_PTRACE_H */
diff --git a/arch/openrisc/include/asm/syscalls.h b/arch/openrisc/include/asm/syscalls.h
index aa1c7e98722e..9f4c47961bea 100644
--- a/arch/openrisc/include/asm/syscalls.h
+++ b/arch/openrisc/include/asm/syscalls.h
@@ -25,8 +25,4 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage long __sys_clone3(struct clone_args __user *uargs, size_t size);
asmlinkage long __sys_fork(void);
-#define sys_clone __sys_clone
-#define sys_clone3 __sys_clone3
-#define sys_fork __sys_fork
-
#endif /* __ASM_OPENRISC_SYSCALLS_H */
diff --git a/arch/openrisc/include/asm/unistd.h b/arch/openrisc/include/asm/unistd.h
new file mode 100644
index 000000000000..c73f65e18d3b
--- /dev/null
+++ b/arch/openrisc/include/asm/unistd.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_TIME32_SYSCALLS
+
+#include <uapi/asm/unistd.h>
diff --git a/arch/openrisc/include/uapi/asm/Kbuild b/arch/openrisc/include/uapi/asm/Kbuild
index e78470141932..2501e82a1a0a 100644
--- a/arch/openrisc/include/uapi/asm/Kbuild
+++ b/arch/openrisc/include/uapi/asm/Kbuild
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
+
generic-y += ucontext.h
diff --git a/arch/openrisc/include/uapi/asm/elf.h b/arch/openrisc/include/uapi/asm/elf.h
index 6868f81c281e..441e343f8268 100644
--- a/arch/openrisc/include/uapi/asm/elf.h
+++ b/arch/openrisc/include/uapi/asm/elf.h
@@ -34,15 +34,72 @@
#include <asm/ptrace.h>
/* The OR1K relocation types... not all relevant for module loader */
-#define R_OR32_NONE 0
-#define R_OR32_32 1
-#define R_OR32_16 2
-#define R_OR32_8 3
-#define R_OR32_CONST 4
-#define R_OR32_CONSTH 5
-#define R_OR32_JUMPTARG 6
-#define R_OR32_VTINHERIT 7
-#define R_OR32_VTENTRY 8
+#define R_OR1K_NONE 0
+#define R_OR1K_32 1
+#define R_OR1K_16 2
+#define R_OR1K_8 3
+#define R_OR1K_LO_16_IN_INSN 4
+#define R_OR1K_HI_16_IN_INSN 5
+#define R_OR1K_INSN_REL_26 6
+#define R_OR1K_GNU_VTENTRY 7
+#define R_OR1K_GNU_VTINHERIT 8
+#define R_OR1K_32_PCREL 9
+#define R_OR1K_16_PCREL 10
+#define R_OR1K_8_PCREL 11
+#define R_OR1K_GOTPC_HI16 12
+#define R_OR1K_GOTPC_LO16 13
+#define R_OR1K_GOT16 14
+#define R_OR1K_PLT26 15
+#define R_OR1K_GOTOFF_HI16 16
+#define R_OR1K_GOTOFF_LO16 17
+#define R_OR1K_COPY 18
+#define R_OR1K_GLOB_DAT 19
+#define R_OR1K_JMP_SLOT 20
+#define R_OR1K_RELATIVE 21
+#define R_OR1K_TLS_GD_HI16 22
+#define R_OR1K_TLS_GD_LO16 23
+#define R_OR1K_TLS_LDM_HI16 24
+#define R_OR1K_TLS_LDM_LO16 25
+#define R_OR1K_TLS_LDO_HI16 26
+#define R_OR1K_TLS_LDO_LO16 27
+#define R_OR1K_TLS_IE_HI16 28
+#define R_OR1K_TLS_IE_LO16 29
+#define R_OR1K_TLS_LE_HI16 30
+#define R_OR1K_TLS_LE_LO16 31
+#define R_OR1K_TLS_TPOFF 32
+#define R_OR1K_TLS_DTPOFF 33
+#define R_OR1K_TLS_DTPMOD 34
+#define R_OR1K_AHI16 35
+#define R_OR1K_GOTOFF_AHI16 36
+#define R_OR1K_TLS_IE_AHI16 37
+#define R_OR1K_TLS_LE_AHI16 38
+#define R_OR1K_SLO16 39
+#define R_OR1K_GOTOFF_SLO16 40
+#define R_OR1K_TLS_LE_SLO16 41
+#define R_OR1K_PCREL_PG21 42
+#define R_OR1K_GOT_PG21 43
+#define R_OR1K_TLS_GD_PG21 44
+#define R_OR1K_TLS_LDM_PG21 45
+#define R_OR1K_TLS_IE_PG21 46
+#define R_OR1K_LO13 47
+#define R_OR1K_GOT_LO13 48
+#define R_OR1K_TLS_GD_LO13 49
+#define R_OR1K_TLS_LDM_LO13 50
+#define R_OR1K_TLS_IE_LO13 51
+#define R_OR1K_SLO13 52
+#define R_OR1K_PLTA26 53
+#define R_OR1K_GOT_AHI16 54
+
+/* Old relocation names */
+#define R_OR32_NONE R_OR1K_NONE
+#define R_OR32_32 R_OR1K_32
+#define R_OR32_16 R_OR1K_16
+#define R_OR32_8 R_OR1K_8
+#define R_OR32_CONST R_OR1K_LO_16_IN_INSN
+#define R_OR32_CONSTH R_OR1K_HI_16_IN_INSN
+#define R_OR32_JUMPTARG R_OR1K_INSN_REL_26
+#define R_OR32_VTENTRY R_OR1K_GNU_VTENTRY
+#define R_OR32_VTINHERIT R_OR1K_GNU_VTINHERIT
typedef unsigned long elf_greg_t;
diff --git a/arch/openrisc/include/uapi/asm/unistd.h b/arch/openrisc/include/uapi/asm/unistd.h
index fae34c60fa88..46b94d454efd 100644
--- a/arch/openrisc/include/uapi/asm/unistd.h
+++ b/arch/openrisc/include/uapi/asm/unistd.h
@@ -17,17 +17,4 @@
* (at your option) any later version.
*/
-#define sys_mmap2 sys_mmap_pgoff
-
-#define __ARCH_WANT_RENAMEAT
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_SYS_FORK
-#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_TIME32_SYSCALLS
-
-#include <asm-generic/unistd.h>
-
-#define __NR_or1k_atomic __NR_arch_specific_syscall
-__SYSCALL(__NR_or1k_atomic, sys_or1k_atomic)
+#include <asm/unistd_32.h>
diff --git a/arch/openrisc/kernel/Makefile.syscalls b/arch/openrisc/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..525a1e7e7fc9
--- /dev/null
+++ b/arch/openrisc/kernel/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += or1k time32 stat64 rlimit renameat
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index c9f48e750b72..440711d7bf40 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -106,8 +106,6 @@
l.mtspr r0,r3,SPR_EPCR_BASE ;\
l.lwz r3,PT_SR(r1) ;\
l.mtspr r0,r3,SPR_ESR_BASE ;\
- l.lwz r3,PT_FPCSR(r1) ;\
- l.mtspr r0,r3,SPR_FPCSR ;\
l.lwz r2,PT_GPR2(r1) ;\
l.lwz r3,PT_GPR3(r1) ;\
l.lwz r4,PT_GPR4(r1) ;\
@@ -177,8 +175,6 @@ handler: ;\
/* r30 already save */ ;\
l.sw PT_GPR31(r1),r31 ;\
TRACE_IRQS_OFF_ENTRY ;\
- l.mfspr r30,r0,SPR_FPCSR ;\
- l.sw PT_FPCSR(r1),r30 ;\
/* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
l.addi r30,r0,-1 ;\
l.sw PT_ORIG_GPR11(r1),r30
@@ -219,8 +215,6 @@ handler: ;\
/* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
l.addi r30,r0,-1 ;\
l.sw PT_ORIG_GPR11(r1),r30 ;\
- l.mfspr r30,r0,SPR_FPCSR ;\
- l.sw PT_FPCSR(r1),r30 ;\
l.addi r3,r1,0 ;\
/* r4 is exception EA */ ;\
l.addi r5,r0,vector ;\
@@ -852,6 +846,7 @@ _syscall_badsys:
EXCEPTION_ENTRY(_fpe_trap_handler)
CLEAR_LWA_FLAG(r3)
+
/* r4: EA of fault (set by EXCEPTION_HANDLE) */
l.jal do_fpe_trap
l.addi r3,r1,0 /* pt_regs */
@@ -1100,10 +1095,6 @@ ENTRY(_switch)
l.sw PT_GPR28(r1),r28
l.sw PT_GPR30(r1),r30
- /* Store the old FPU state to new pt_regs */
- l.mfspr r29,r0,SPR_FPCSR
- l.sw PT_FPCSR(r1),r29
-
l.addi r11,r10,0 /* Save old 'current' to 'last' return value*/
/* We use thread_info->ksp for storing the address of the above
@@ -1126,10 +1117,6 @@ ENTRY(_switch)
l.lwz r29,PT_SP(r1)
l.sw TI_KSP(r10),r29
- /* Restore the old value of FPCSR */
- l.lwz r29,PT_FPCSR(r1)
- l.mtspr r0,r29,SPR_FPCSR
-
/* ...and restore the registers, except r11 because the return value
* has already been set above.
*/
diff --git a/arch/openrisc/kernel/module.c b/arch/openrisc/kernel/module.c
index 532013f523ac..c9ff4c4a0b29 100644
--- a/arch/openrisc/kernel/module.c
+++ b/arch/openrisc/kernel/module.c
@@ -39,22 +39,32 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
value = sym->st_value + rel[i].r_addend;
switch (ELF32_R_TYPE(rel[i].r_info)) {
- case R_OR32_32:
+ case R_OR1K_32:
*location = value;
break;
- case R_OR32_CONST:
+ case R_OR1K_LO_16_IN_INSN:
*((uint16_t *)location + 1) = value;
break;
- case R_OR32_CONSTH:
+ case R_OR1K_HI_16_IN_INSN:
*((uint16_t *)location + 1) = value >> 16;
break;
- case R_OR32_JUMPTARG:
+ case R_OR1K_INSN_REL_26:
value -= (uint32_t)location;
value >>= 2;
value &= 0x03ffffff;
value |= *location & 0xfc000000;
*location = value;
break;
+ case R_OR1K_AHI16:
+ /* Adjust the operand to match with a signed LO16. */
+ value += 0x8000;
+ *((uint16_t *)location + 1) = value >> 16;
+ break;
+ case R_OR1K_SLO16:
+ /* Split value lower 16-bits. */
+ value = ((value & 0xf800) << 10) | (value & 0x7ff);
+ *location = (*location & ~0x3e007ff) | value;
+ break;
default:
pr_err("module %s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info));
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index 86e02929f3ac..eef99fee2110 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -36,6 +36,7 @@
#include <linux/reboot.h>
#include <linux/uaccess.h>
+#include <asm/fpu.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/spr_defs.h>
@@ -65,7 +66,7 @@ void machine_restart(char *cmd)
}
/*
- * This is used if pm_power_off has not been set by a power management
+ * This is used if a sys-off handler was not set by a power management
* driver, in this case we can assume we are on a simulator. On
* OpenRISC simulators l.nop 1 will trigger the simulator exit.
*/
@@ -89,10 +90,8 @@ void machine_halt(void)
void machine_power_off(void)
{
printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
- if (pm_power_off != NULL)
- pm_power_off();
- else
- default_power_off();
+ do_kernel_power_off();
+ default_power_off();
}
/*
@@ -246,6 +245,8 @@ struct task_struct *__switch_to(struct task_struct *old,
local_irq_save(flags);
+ save_fpu(current);
+
/* current_set is an array of saved current pointers
* (one for each cpu). we need them at user->kernel transition,
* while we save them at kernel->user transition
@@ -258,6 +259,8 @@ struct task_struct *__switch_to(struct task_struct *old,
current_thread_info_set[smp_processor_id()] = new_ti;
last = (_switch(old_ti, new_ti))->task;
+ restore_fpu(current);
+
local_irq_restore(flags);
return last;
diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c
index 1eeac3b62e9d..5091b18eab4c 100644
--- a/arch/openrisc/kernel/ptrace.c
+++ b/arch/openrisc/kernel/ptrace.c
@@ -88,6 +88,7 @@ static int genregs_set(struct task_struct *target,
return ret;
}
+#ifdef CONFIG_FPU
/*
* As OpenRISC shares GPRs and floating point registers we don't need to export
* the floating point registers again. So here we only export the fpcsr special
@@ -97,9 +98,7 @@ static int fpregs_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
{
- const struct pt_regs *regs = task_pt_regs(target);
-
- return membuf_store(&to, regs->fpcsr);
+ return membuf_store(&to, target->thread.fpcsr);
}
static int fpregs_set(struct task_struct *target,
@@ -107,21 +106,20 @@ static int fpregs_set(struct task_struct *target,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
- struct pt_regs *regs = task_pt_regs(target);
- int ret;
-
/* FPCSR */
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &regs->fpcsr, 0, 4);
- return ret;
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpcsr, 0, 4);
}
+#endif
/*
* Define the register sets available on OpenRISC under Linux
*/
enum or1k_regset {
REGSET_GENERAL,
+#ifdef CONFIG_FPU
REGSET_FPU,
+#endif
};
static const struct user_regset or1k_regsets[] = {
@@ -133,6 +131,7 @@ static const struct user_regset or1k_regsets[] = {
.regset_get = genregs_get,
.set = genregs_set,
},
+#ifdef CONFIG_FPU
[REGSET_FPU] = {
.core_note_type = NT_PRFPREG,
.n = sizeof(struct __or1k_fpu_state) / sizeof(long),
@@ -141,6 +140,7 @@ static const struct user_regset or1k_regsets[] = {
.regset_get = fpregs_get,
.set = fpregs_set,
},
+#endif
};
static const struct user_regset_view user_or1k_native_view = {
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index e2f21a5d8ad9..c7ab42e2cb7a 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -23,6 +23,7 @@
#include <linux/stddef.h>
#include <linux/resume_user_mode.h>
+#include <asm/fpu.h>
#include <asm/processor.h>
#include <asm/syscall.h>
#include <asm/ucontext.h>
@@ -39,6 +40,37 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs);
asmlinkage int do_work_pending(struct pt_regs *regs, unsigned int thread_flags,
int syscall);
+#ifdef CONFIG_FPU
+static long restore_fp_state(struct sigcontext __user *sc)
+{
+ long err;
+
+ err = __copy_from_user(&current->thread.fpcsr, &sc->fpcsr, sizeof(unsigned long));
+ if (unlikely(err))
+ return err;
+
+ /* Restore the FPU state */
+ restore_fpu(current);
+
+ return 0;
+}
+
+static long save_fp_state(struct sigcontext __user *sc)
+{
+ long err;
+
+ /* Sync the user FPU state so we can copy to sigcontext */
+ save_fpu(current);
+
+ err = __copy_to_user(&sc->fpcsr, &current->thread.fpcsr, sizeof(unsigned long));
+
+ return err;
+}
+#else
+#define save_fp_state(sc) (0)
+#define restore_fp_state(sc) (0)
+#endif
+
static int restore_sigcontext(struct pt_regs *regs,
struct sigcontext __user *sc)
{
@@ -55,7 +87,7 @@ static int restore_sigcontext(struct pt_regs *regs,
err |= __copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long));
err |= __copy_from_user(&regs->pc, &sc->regs.pc, sizeof(unsigned long));
err |= __copy_from_user(&regs->sr, &sc->regs.sr, sizeof(unsigned long));
- err |= __copy_from_user(&regs->fpcsr, &sc->fpcsr, sizeof(unsigned long));
+ err |= restore_fp_state(sc);
/* make sure the SM-bit is cleared so user-mode cannot fool us */
regs->sr &= ~SPR_SR_SM;
@@ -118,7 +150,7 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
err |= __copy_to_user(&sc->regs.pc, &regs->pc, sizeof(unsigned long));
err |= __copy_to_user(&sc->regs.sr, &regs->sr, sizeof(unsigned long));
- err |= __copy_to_user(&sc->fpcsr, &regs->fpcsr, sizeof(unsigned long));
+ err |= save_fp_state(sc);
return err;
}
diff --git a/arch/openrisc/kernel/sys_call_table.c b/arch/openrisc/kernel/sys_call_table.c
index 3d18008310e4..b2f57e2538f7 100644
--- a/arch/openrisc/kernel/sys_call_table.c
+++ b/arch/openrisc/kernel/sys_call_table.c
@@ -16,9 +16,14 @@
#include <asm/syscalls.h>
-#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+
+#define sys_mmap2 sys_mmap_pgoff
+#define sys_clone __sys_clone
+#define sys_clone3 __sys_clone3
+#define sys_fork __sys_fork
void *sys_call_table[__NR_syscalls] = {
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 9370888c9a7e..c195be9cc9fc 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -31,6 +31,7 @@
#include <linux/uaccess.h>
#include <asm/bug.h>
+#include <asm/fpu.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/unwinder.h>
@@ -51,16 +52,16 @@ static void print_trace(void *data, unsigned long addr, int reliable)
{
const char *loglvl = data;
- printk("%s[<%p>] %s%pS\n", loglvl, (void *) addr, reliable ? "" : "? ",
- (void *) addr);
+ pr_info("%s[<%p>] %s%pS\n", loglvl, (void *) addr, reliable ? "" : "? ",
+ (void *) addr);
}
static void print_data(unsigned long base_addr, unsigned long word, int i)
{
if (i == 0)
- printk("(%08lx:)\t%08lx", base_addr + (i * 4), word);
+ pr_info("(%08lx:)\t%08lx", base_addr + (i * 4), word);
else
- printk(" %08lx:\t%08lx", base_addr + (i * 4), word);
+ pr_info(" %08lx:\t%08lx", base_addr + (i * 4), word);
}
/* displays a short stack trace */
@@ -69,7 +70,7 @@ void show_stack(struct task_struct *task, unsigned long *esp, const char *loglvl
if (esp == NULL)
esp = (unsigned long *)&esp;
- printk("%sCall trace:\n", loglvl);
+ pr_info("%sCall trace:\n", loglvl);
unwind_stack((void *)loglvl, esp, print_trace);
}
@@ -83,57 +84,56 @@ void show_registers(struct pt_regs *regs)
if (user_mode(regs))
in_kernel = 0;
- printk("CPU #: %d\n"
- " PC: %08lx SR: %08lx SP: %08lx FPCSR: %08lx\n",
- smp_processor_id(), regs->pc, regs->sr, regs->sp,
- regs->fpcsr);
- printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
- 0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]);
- printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
- regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7]);
- printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n",
- regs->gpr[8], regs->gpr[9], regs->gpr[10], regs->gpr[11]);
- printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n",
- regs->gpr[12], regs->gpr[13], regs->gpr[14], regs->gpr[15]);
- printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n",
- regs->gpr[16], regs->gpr[17], regs->gpr[18], regs->gpr[19]);
- printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n",
- regs->gpr[20], regs->gpr[21], regs->gpr[22], regs->gpr[23]);
- printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n",
- regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]);
- printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n",
- regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]);
- printk(" RES: %08lx oGPR11: %08lx\n",
- regs->gpr[11], regs->orig_gpr11);
-
- printk("Process %s (pid: %d, stackpage=%08lx)\n",
- current->comm, current->pid, (unsigned long)current);
+ pr_info("CPU #: %d\n"
+ " PC: %08lx SR: %08lx SP: %08lx\n",
+ smp_processor_id(), regs->pc, regs->sr, regs->sp);
+ pr_info("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
+ 0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]);
+ pr_info("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
+ regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7]);
+ pr_info("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n",
+ regs->gpr[8], regs->gpr[9], regs->gpr[10], regs->gpr[11]);
+ pr_info("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n",
+ regs->gpr[12], regs->gpr[13], regs->gpr[14], regs->gpr[15]);
+ pr_info("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n",
+ regs->gpr[16], regs->gpr[17], regs->gpr[18], regs->gpr[19]);
+ pr_info("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n",
+ regs->gpr[20], regs->gpr[21], regs->gpr[22], regs->gpr[23]);
+ pr_info("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n",
+ regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]);
+ pr_info("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n",
+ regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]);
+ pr_info(" RES: %08lx oGPR11: %08lx\n",
+ regs->gpr[11], regs->orig_gpr11);
+
+ pr_info("Process %s (pid: %d, stackpage=%08lx)\n",
+ current->comm, current->pid, (unsigned long)current);
/*
* When in-kernel, we also print out the stack and code at the
* time of the fault..
*/
if (in_kernel) {
- printk("\nStack: ");
+ pr_info("\nStack: ");
show_stack(NULL, (unsigned long *)esp, KERN_EMERG);
if (esp < PAGE_OFFSET)
goto bad_stack;
- printk("\n");
+ pr_info("\n");
for (i = -8; i < 24; i += 1) {
unsigned long word;
if (__get_user(word, &((unsigned long *)esp)[i])) {
bad_stack:
- printk(" Bad Stack value.");
+ pr_info(" Bad Stack value.");
break;
}
print_data(esp, word, i);
}
- printk("\nCode: ");
+ pr_info("\nCode: ");
if (regs->pc < PAGE_OFFSET)
goto bad;
@@ -142,14 +142,14 @@ bad_stack:
if (__get_user(word, &((unsigned long *)regs->pc)[i])) {
bad:
- printk(" Bad PC value.");
+ pr_info(" Bad PC value.");
break;
}
print_data(regs->pc, word, i);
}
}
- printk("\n");
+ pr_info("\n");
}
/* This is normally the 'Oops' routine */
@@ -157,10 +157,10 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
{
console_verbose();
- printk("\n%s#: %04lx\n", str, err & 0xffff);
+ pr_emerg("\n%s#: %04lx\n", str, err & 0xffff);
show_registers(regs);
#ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION
- printk("\n\nUNHANDLED_EXCEPTION: entering infinite loop\n");
+ pr_emerg("\n\nUNHANDLED_EXCEPTION: entering infinite loop\n");
/* shut down interrupts */
local_irq_disable();
@@ -173,36 +173,51 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
asmlinkage void unhandled_exception(struct pt_regs *regs, int ea, int vector)
{
- printk("Unable to handle exception at EA =0x%x, vector 0x%x",
- ea, vector);
+ pr_emerg("Unable to handle exception at EA =0x%x, vector 0x%x",
+ ea, vector);
die("Oops", regs, 9);
}
asmlinkage void do_fpe_trap(struct pt_regs *regs, unsigned long address)
{
- int code = FPE_FLTUNK;
- unsigned long fpcsr = regs->fpcsr;
-
- if (fpcsr & SPR_FPCSR_IVF)
- code = FPE_FLTINV;
- else if (fpcsr & SPR_FPCSR_OVF)
- code = FPE_FLTOVF;
- else if (fpcsr & SPR_FPCSR_UNF)
- code = FPE_FLTUND;
- else if (fpcsr & SPR_FPCSR_DZF)
- code = FPE_FLTDIV;
- else if (fpcsr & SPR_FPCSR_IXF)
- code = FPE_FLTRES;
-
- /* Clear all flags */
- regs->fpcsr &= ~SPR_FPCSR_ALLF;
-
- force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
+ if (user_mode(regs)) {
+ int code = FPE_FLTUNK;
+#ifdef CONFIG_FPU
+ unsigned long fpcsr;
+
+ save_fpu(current);
+ fpcsr = current->thread.fpcsr;
+
+ if (fpcsr & SPR_FPCSR_IVF)
+ code = FPE_FLTINV;
+ else if (fpcsr & SPR_FPCSR_OVF)
+ code = FPE_FLTOVF;
+ else if (fpcsr & SPR_FPCSR_UNF)
+ code = FPE_FLTUND;
+ else if (fpcsr & SPR_FPCSR_DZF)
+ code = FPE_FLTDIV;
+ else if (fpcsr & SPR_FPCSR_IXF)
+ code = FPE_FLTRES;
+
+ /* Clear all flags */
+ current->thread.fpcsr &= ~SPR_FPCSR_ALLF;
+ restore_fpu(current);
+#endif
+ force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
+ } else {
+ pr_emerg("KERNEL: Illegal fpe exception 0x%.8lx\n", regs->pc);
+ die("Die:", regs, SIGFPE);
+ }
}
asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
{
- force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
+ if (user_mode(regs)) {
+ force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
+ } else {
+ pr_emerg("KERNEL: Illegal trap exception 0x%.8lx\n", regs->pc);
+ die("Die:", regs, SIGILL);
+ }
}
asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
@@ -211,8 +226,7 @@ asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
/* Send a SIGBUS */
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)address);
} else {
- printk("KERNEL: Unaligned Access 0x%.8lx\n", address);
- show_registers(regs);
+ pr_emerg("KERNEL: Unaligned Access 0x%.8lx\n", address);
die("Die:", regs, address);
}
@@ -224,8 +238,7 @@ asmlinkage void do_bus_fault(struct pt_regs *regs, unsigned long address)
/* Send a SIGBUS */
force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address);
} else { /* Kernel mode */
- printk("KERNEL: Bus error (SIGBUS) 0x%.8lx\n", address);
- show_registers(regs);
+ pr_emerg("KERNEL: Bus error (SIGBUS) 0x%.8lx\n", address);
die("Die:", regs, address);
}
}
@@ -419,9 +432,8 @@ asmlinkage void do_illegal_instruction(struct pt_regs *regs,
/* Send a SIGILL */
force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)address);
} else { /* Kernel mode */
- printk("KERNEL: Illegal instruction (SIGILL) 0x%.8lx\n",
- address);
- show_registers(regs);
+ pr_emerg("KERNEL: Illegal instruction (SIGILL) 0x%.8lx\n",
+ address);
die("Die:", regs, address);
}
}
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index daafeb20f993..5d650e02cbf4 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -16,6 +16,7 @@ config PARISC
select ARCH_HAS_UBSAN
select ARCH_HAS_PTE_SPECIAL
select ARCH_NO_SG_CHAIN
+ select ARCH_SPLIT_ARG64 if !64BIT
select ARCH_SUPPORTS_HUGETLBFS if PA20
select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_STACKWALK
@@ -45,6 +46,7 @@ config PARISC
select GENERIC_CPU_DEVICES if !SMP
select GENERIC_LIB_DEVMEM_IS_ALLOWED
select SYSCTL_ARCH_UNALIGN_ALLOW
+ select SYSCTL_ARCH_UNALIGN_NO_WARN
select SYSCTL_EXCEPTION_TRACE
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
@@ -85,6 +87,7 @@ config PARISC
select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
select TRACE_IRQFLAGS_SUPPORT
select HAVE_FUNCTION_DESCRIPTORS if 64BIT
+ select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 316f84f1d15c..21b8166a6883 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -119,7 +119,7 @@ export LIBGCC
libs-y += arch/parisc/lib/ $(LIBGCC)
-drivers-y += arch/parisc/video/
+drivers-$(CONFIG_VIDEO) += arch/parisc/video/
boot := arch/parisc/boot
diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile
index a294a1b58ee7..92227fa813dc 100644
--- a/arch/parisc/boot/compressed/Makefile
+++ b/arch/parisc/boot/compressed/Makefile
@@ -5,10 +5,6 @@
# create a compressed self-extracting vmlinux image from the original vmlinux
#
-KCOV_INSTRUMENT := n
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-
OBJECTS := head.o real2.o firmware.o misc.o piggy.o
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig
index ee4febb30386..5ce258f3fffa 100644
--- a/arch/parisc/configs/generic-32bit_defconfig
+++ b/arch/parisc/configs/generic-32bit_defconfig
@@ -131,7 +131,7 @@ CONFIG_PPDEV=m
CONFIG_I2C=y
CONFIG_HWMON=m
CONFIG_DRM=m
-CONFIG_DRM_DP_CEC=y
+CONFIG_DRM_DISPLAY_DP_AUX_CEC=y
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
CONFIG_DRM_RADEON=m
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index ba4c05bc24d6..8394718870e1 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -31,18 +31,17 @@ void flush_cache_all_local(void);
void flush_cache_all(void);
void flush_cache_mm(struct mm_struct *mm);
-void flush_kernel_dcache_page_addr(const void *addr);
-
#define flush_kernel_dcache_range(start,size) \
flush_kernel_dcache_range_asm((start), (start)+(size));
+/* The only way to flush a vmap range is to flush whole cache */
#define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
void flush_kernel_vmap_range(void *vaddr, int size);
void invalidate_kernel_vmap_range(void *vaddr, int size);
-#define flush_cache_vmap(start, end) flush_cache_all()
+void flush_cache_vmap(unsigned long start, unsigned long end);
#define flush_cache_vmap_early(start, end) do { } while (0)
-#define flush_cache_vunmap(start, end) flush_cache_all()
+void flush_cache_vunmap(unsigned long start, unsigned long end);
void flush_dcache_folio(struct folio *folio);
#define flush_dcache_folio flush_dcache_folio
@@ -77,17 +76,11 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
-/* defined in pacache.S exported in cache.c used by flush_anon_page */
-void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
-
#define ARCH_HAS_FLUSH_ANON_PAGE
void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr);
#define ARCH_HAS_FLUSH_ON_KUNMAP
-static inline void kunmap_flush_on_unmap(const void *addr)
-{
- flush_kernel_dcache_page_addr(addr);
-}
+void kunmap_flush_on_unmap(const void *addr);
#endif /* _PARISC_CACHEFLUSH_H */
diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h
index c1d776bb16b4..bf0a0f1189eb 100644
--- a/arch/parisc/include/asm/cmpxchg.h
+++ b/arch/parisc/include/asm/cmpxchg.h
@@ -56,26 +56,24 @@ __arch_xchg(unsigned long x, volatile void *ptr, int size)
/* bug catcher for when unsupported size is used - won't link */
extern void __cmpxchg_called_with_bad_pointer(void);
-/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */
-extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old,
- unsigned int new_);
-extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_);
+/* __cmpxchg_u... defined in arch/parisc/lib/bitops.c */
extern u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new_);
+extern u16 __cmpxchg_u16(volatile u16 *ptr, u16 old, u16 new_);
+extern u32 __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_);
/* don't worry...optimizer will get rid of most of this */
static inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
{
- switch (size) {
+ return
#ifdef CONFIG_64BIT
- case 8: return __cmpxchg_u64((u64 *)ptr, old, new_);
+ size == 8 ? __cmpxchg_u64(ptr, old, new_) :
#endif
- case 4: return __cmpxchg_u32((unsigned int *)ptr,
- (unsigned int)old, (unsigned int)new_);
- case 1: return __cmpxchg_u8((u8 *)ptr, old & 0xff, new_ & 0xff);
- }
- __cmpxchg_called_with_bad_pointer();
- return old;
+ size == 4 ? __cmpxchg_u32(ptr, old, new_) :
+ size == 2 ? __cmpxchg_u16(ptr, old, new_) :
+ size == 1 ? __cmpxchg_u8(ptr, old, new_) :
+ (__cmpxchg_called_with_bad_pointer(), old);
}
#define arch_cmpxchg(ptr, o, n) \
diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/fb.h
deleted file mode 100644
index 658a8a7dc531..000000000000
--- a/arch/parisc/include/asm/fb.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-struct fb_info;
-
-#if defined(CONFIG_STI_CORE)
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
-#endif
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index ad4e15d12ed1..4bea2e95798f 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -8,6 +8,7 @@
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#ifndef __ASSEMBLY__
diff --git a/arch/parisc/include/asm/parisc-device.h b/arch/parisc/include/asm/parisc-device.h
index 7ddd7f433367..9e74cef4d774 100644
--- a/arch/parisc/include/asm/parisc-device.h
+++ b/arch/parisc/include/asm/parisc-device.h
@@ -41,7 +41,7 @@ struct parisc_driver {
#define to_parisc_device(d) container_of(d, struct parisc_device, dev)
-#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv)
+#define to_parisc_driver(d) container_of_const(d, struct parisc_driver, drv)
#define parisc_parent(d) to_parisc_device(d->dev.parent)
static inline const char *parisc_pathname(struct parisc_device *d)
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 974accac05cd..babf65751e81 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -448,14 +448,17 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
return pte;
}
+static inline pte_t ptep_get(pte_t *ptep)
+{
+ return READ_ONCE(*ptep);
+}
+#define ptep_get ptep_get
+
static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
{
pte_t pte;
- if (!pte_young(*ptep))
- return 0;
-
- pte = *ptep;
+ pte = ptep_get(ptep);
if (!pte_young(pte)) {
return 0;
}
@@ -463,17 +466,10 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
return 1;
}
-struct mm_struct;
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
- pte_t old_pte;
-
- old_pte = *ptep;
- set_pte(ptep, __pte(0));
-
- return old_pte;
-}
+int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
+pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
+struct mm_struct;
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
set_pte(ptep, pte_wrprotect(*ptep));
@@ -511,7 +507,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
#define __HAVE_ARCH_PTE_SAME
diff --git a/arch/parisc/include/asm/signal.h b/arch/parisc/include/asm/signal.h
index 715c96ba2ec8..e84883c6b4c7 100644
--- a/arch/parisc/include/asm/signal.h
+++ b/arch/parisc/include/asm/signal.h
@@ -4,23 +4,11 @@
#include <uapi/asm/signal.h>
-#define _NSIG 64
-/* bits-per-word, where word apparently means 'long' not 'int' */
-#define _NSIG_BPW BITS_PER_LONG
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
# ifndef __ASSEMBLY__
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- /* next_signal() assumes this is a long - no choice */
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
#include <asm/sigcontext.h>
#endif /* !__ASSEMBLY */
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index e38f9a90ac15..a97c0fd55f91 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -20,7 +20,7 @@
* sysdeps/unix/sysv/linux/hppa/sysdep.h
*/
-#ifdef PIC
+#ifndef DONT_USE_PIC
/* WARNING: CANNOT BE USED IN A NOP! */
# define K_STW_ASM_PIC " copy %%r19, %%r4\n"
# define K_LDW_ASM_PIC " copy %%r4, %%r19\n"
@@ -43,7 +43,7 @@
across the syscall. */
#define K_CALL_CLOB_REGS "%r1", "%r2", K_USING_GR4 \
- "%r20", "%r29", "%r31"
+ "%r20", "%r29", "%r31"
#undef K_INLINE_SYSCALL
#define K_INLINE_SYSCALL(name, nr, args...) ({ \
@@ -58,7 +58,7 @@
" ldi %1, %%r20\n" \
K_LDW_ASM_PIC \
: "=r" (__res) \
- : "i" (SYS_ify(name)) K_ASM_ARGS_##nr \
+ : "i" (name) K_ASM_ARGS_##nr \
: "memory", K_CALL_CLOB_REGS K_CLOB_ARGS_##nr \
); \
__sys_res = (long)__res; \
@@ -104,42 +104,18 @@
#define K_CLOB_ARGS_1 K_CLOB_ARGS_2, "%r25"
#define K_CLOB_ARGS_0 K_CLOB_ARGS_1, "%r26"
-#define _syscall0(type,name) \
-type name(void) \
-{ \
- return K_INLINE_SYSCALL(name, 0); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
- return K_INLINE_SYSCALL(name, 1, arg1); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1, type2 arg2) \
-{ \
- return K_INLINE_SYSCALL(name, 2, arg1, arg2); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1, type2 arg2, type3 arg3) \
-{ \
- return K_INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
- return K_INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
-}
-
-/* select takes 5 arguments */
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
-{ \
- return K_INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
-}
+#define syscall0(name) \
+ K_INLINE_SYSCALL(name, 0)
+#define syscall1(name, arg1) \
+ K_INLINE_SYSCALL(name, 1, arg1)
+#define syscall2(name, arg1, arg2) \
+ K_INLINE_SYSCALL(name, 2, arg1, arg2)
+#define syscall3(name, arg1, arg2, arg3) \
+ K_INLINE_SYSCALL(name, 3, arg1, arg2, arg3)
+#define syscall4(name, arg1, arg2, arg3, arg4) \
+ K_INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)
+#define syscall5(name, arg1, arg2, arg3, arg4, arg5) \
+ K_INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)
#define __ARCH_WANT_NEW_STAT
#define __ARCH_WANT_STAT64
@@ -160,7 +136,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#define __ARCH_WANT_COMPAT_STAT
diff --git a/arch/parisc/include/asm/vdso.h b/arch/parisc/include/asm/vdso.h
index ef8206193f82..2a2dc11b5545 100644
--- a/arch/parisc/include/asm/vdso.h
+++ b/arch/parisc/include/asm/vdso.h
@@ -19,6 +19,6 @@ extern struct vdso_data *vdso_data;
/* Default link addresses for the vDSOs */
#define VDSO_LBASE 0
-#define VDSO_VERSION_STRING LINUX_5.18
+#define VDSO_VERSION_STRING LINUX_6.11
#endif /* __PARISC_VDSO_H__ */
diff --git a/arch/parisc/include/asm/video.h b/arch/parisc/include/asm/video.h
new file mode 100644
index 000000000000..c5dff3223194
--- /dev/null
+++ b/arch/parisc/include/asm/video.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
+
+#include <linux/types.h>
+
+struct device;
+
+#if defined(CONFIG_STI_CORE)
+bool video_is_primary_device(struct device *dev);
+#define video_is_primary_device video_is_primary_device
+#endif
+
+#include <asm-generic/video.h>
+
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h
index 8e4895c5ea5d..40d7a574c5dd 100644
--- a/arch/parisc/include/uapi/asm/signal.h
+++ b/arch/parisc/include/uapi/asm/signal.h
@@ -57,10 +57,20 @@
#include <asm-generic/signal-defs.h>
+#define _NSIG 64
+#define _NSIG_BPW (sizeof(unsigned long) * 8)
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
# ifndef __ASSEMBLY__
# include <linux/types.h>
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
/* Avoid too many header ordering problems. */
struct siginfo;
diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh
index 933d031c249a..664c2d77f776 100755
--- a/arch/parisc/install.sh
+++ b/arch/parisc/install.sh
@@ -16,6 +16,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ "$(basename $2)" = "vmlinuz" ]; then
# Compressed install
echo "Installing compressed kernel"
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 422f3e1e6d9c..db531e58d70e 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -20,6 +20,7 @@
#include <linux/sched.h>
#include <linux/sched/mm.h>
#include <linux/syscalls.h>
+#include <linux/vmalloc.h>
#include <asm/pdc.h>
#include <asm/cache.h>
#include <asm/cacheflush.h>
@@ -31,20 +32,31 @@
#include <asm/mmu_context.h>
#include <asm/cachectl.h>
+#define PTR_PAGE_ALIGN_DOWN(addr) PTR_ALIGN_DOWN(addr, PAGE_SIZE)
+
+/*
+ * When nonzero, use _PAGE_ACCESSED bit to try to reduce the number
+ * of page flushes done flush_cache_page_if_present. There are some
+ * pros and cons in using this option. It may increase the risk of
+ * random segmentation faults.
+ */
+#define CONFIG_FLUSH_PAGE_ACCESSED 0
+
int split_tlb __ro_after_init;
int dcache_stride __ro_after_init;
int icache_stride __ro_after_init;
EXPORT_SYMBOL(dcache_stride);
+/* Internal implementation in arch/parisc/kernel/pacache.S */
void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
EXPORT_SYMBOL(flush_dcache_page_asm);
void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
-
-/* Internal implementation in arch/parisc/kernel/pacache.S */
void flush_data_cache_local(void *); /* flushes local data-cache only */
void flush_instruction_cache_local(void); /* flushes local code-cache only */
+static void flush_kernel_dcache_page_addr(const void *addr);
+
/* On some machines (i.e., ones with the Merced bus), there can be
* only a single PxTLB broadcast at a time; this must be guaranteed
* by software. We need a spinlock around all TLB flushes to ensure
@@ -321,6 +333,18 @@ __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
{
if (!static_branch_likely(&parisc_has_cache))
return;
+
+ /*
+ * The TLB is the engine of coherence on parisc. The CPU is
+ * entitled to speculate any page with a TLB mapping, so here
+ * we kill the mapping then flush the page along a special flush
+ * only alias mapping. This guarantees that the page is no-longer
+ * in the cache for any process and nor may it be speculatively
+ * read in (until the user or kernel specifically accesses it,
+ * of course).
+ */
+ flush_tlb_page(vma, vmaddr);
+
preempt_disable();
flush_dcache_page_asm(physaddr, vmaddr);
if (vma->vm_flags & VM_EXEC)
@@ -328,46 +352,44 @@ __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
preempt_enable();
}
-static void flush_user_cache_page(struct vm_area_struct *vma, unsigned long vmaddr)
+static void flush_kernel_dcache_page_addr(const void *addr)
{
- unsigned long flags, space, pgd, prot;
-#ifdef CONFIG_TLB_PTLOCK
- unsigned long pgd_lock;
-#endif
+ unsigned long vaddr = (unsigned long)addr;
+ unsigned long flags;
- vmaddr &= PAGE_MASK;
+ /* Purge TLB entry to remove translation on all CPUs */
+ purge_tlb_start(flags);
+ pdtlb(SR_KERNEL, addr);
+ purge_tlb_end(flags);
+ /* Use tmpalias flush to prevent data cache move-in */
preempt_disable();
+ flush_dcache_page_asm(__pa(vaddr), vaddr);
+ preempt_enable();
+}
- /* Set context for flush */
- local_irq_save(flags);
- prot = mfctl(8);
- space = mfsp(SR_USER);
- pgd = mfctl(25);
-#ifdef CONFIG_TLB_PTLOCK
- pgd_lock = mfctl(28);
-#endif
- switch_mm_irqs_off(NULL, vma->vm_mm, NULL);
- local_irq_restore(flags);
-
- flush_user_dcache_range_asm(vmaddr, vmaddr + PAGE_SIZE);
- if (vma->vm_flags & VM_EXEC)
- flush_user_icache_range_asm(vmaddr, vmaddr + PAGE_SIZE);
- flush_tlb_page(vma, vmaddr);
+static void flush_kernel_icache_page_addr(const void *addr)
+{
+ unsigned long vaddr = (unsigned long)addr;
+ unsigned long flags;
- /* Restore previous context */
- local_irq_save(flags);
-#ifdef CONFIG_TLB_PTLOCK
- mtctl(pgd_lock, 28);
-#endif
- mtctl(pgd, 25);
- mtsp(space, SR_USER);
- mtctl(prot, 8);
- local_irq_restore(flags);
+ /* Purge TLB entry to remove translation on all CPUs */
+ purge_tlb_start(flags);
+ pdtlb(SR_KERNEL, addr);
+ purge_tlb_end(flags);
+ /* Use tmpalias flush to prevent instruction cache move-in */
+ preempt_disable();
+ flush_icache_page_asm(__pa(vaddr), vaddr);
preempt_enable();
}
+void kunmap_flush_on_unmap(const void *addr)
+{
+ flush_kernel_dcache_page_addr(addr);
+}
+EXPORT_SYMBOL(kunmap_flush_on_unmap);
+
void flush_icache_pages(struct vm_area_struct *vma, struct page *page,
unsigned int nr)
{
@@ -375,13 +397,16 @@ void flush_icache_pages(struct vm_area_struct *vma, struct page *page,
for (;;) {
flush_kernel_dcache_page_addr(kaddr);
- flush_kernel_icache_page(kaddr);
+ flush_kernel_icache_page_addr(kaddr);
if (--nr == 0)
break;
kaddr += PAGE_SIZE;
}
}
+/*
+ * Walk page directory for MM to find PTEP pointer for address ADDR.
+ */
static inline pte_t *get_ptep(struct mm_struct *mm, unsigned long addr)
{
pte_t *ptep = NULL;
@@ -410,6 +435,41 @@ static inline bool pte_needs_flush(pte_t pte)
== (_PAGE_PRESENT | _PAGE_ACCESSED);
}
+/*
+ * Return user physical address. Returns 0 if page is not present.
+ */
+static inline unsigned long get_upa(struct mm_struct *mm, unsigned long addr)
+{
+ unsigned long flags, space, pgd, prot, pa;
+#ifdef CONFIG_TLB_PTLOCK
+ unsigned long pgd_lock;
+#endif
+
+ /* Save context */
+ local_irq_save(flags);
+ prot = mfctl(8);
+ space = mfsp(SR_USER);
+ pgd = mfctl(25);
+#ifdef CONFIG_TLB_PTLOCK
+ pgd_lock = mfctl(28);
+#endif
+
+ /* Set context for lpa_user */
+ switch_mm_irqs_off(NULL, mm, NULL);
+ pa = lpa_user(addr);
+
+ /* Restore previous context */
+#ifdef CONFIG_TLB_PTLOCK
+ mtctl(pgd_lock, 28);
+#endif
+ mtctl(pgd, 25);
+ mtsp(space, SR_USER);
+ mtctl(prot, 8);
+ local_irq_restore(flags);
+
+ return pa;
+}
+
void flush_dcache_folio(struct folio *folio)
{
struct address_space *mapping = folio_flush_mapping(folio);
@@ -458,50 +518,23 @@ void flush_dcache_folio(struct folio *folio)
if (addr + nr * PAGE_SIZE > vma->vm_end)
nr = (vma->vm_end - addr) / PAGE_SIZE;
- if (parisc_requires_coherency()) {
- for (i = 0; i < nr; i++) {
- pte_t *ptep = get_ptep(vma->vm_mm,
- addr + i * PAGE_SIZE);
- if (!ptep)
- continue;
- if (pte_needs_flush(*ptep))
- flush_user_cache_page(vma,
- addr + i * PAGE_SIZE);
- /* Optimise accesses to the same table? */
- pte_unmap(ptep);
- }
- } else {
+ if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
+ != (addr & (SHM_COLOUR - 1))) {
+ for (i = 0; i < nr; i++)
+ __flush_cache_page(vma,
+ addr + i * PAGE_SIZE,
+ (pfn + i) * PAGE_SIZE);
/*
- * The TLB is the engine of coherence on parisc:
- * The CPU is entitled to speculate any page
- * with a TLB mapping, so here we kill the
- * mapping then flush the page along a special
- * flush only alias mapping. This guarantees that
- * the page is no-longer in the cache for any
- * process and nor may it be speculatively read
- * in (until the user or kernel specifically
- * accesses it, of course)
+ * Software is allowed to have any number
+ * of private mappings to a page.
*/
- for (i = 0; i < nr; i++)
- flush_tlb_page(vma, addr + i * PAGE_SIZE);
- if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
- != (addr & (SHM_COLOUR - 1))) {
- for (i = 0; i < nr; i++)
- __flush_cache_page(vma,
- addr + i * PAGE_SIZE,
- (pfn + i) * PAGE_SIZE);
- /*
- * Software is allowed to have any number
- * of private mappings to a page.
- */
- if (!(vma->vm_flags & VM_SHARED))
- continue;
- if (old_addr)
- pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n",
- old_addr, addr, vma->vm_file);
- if (nr == folio_nr_pages(folio))
- old_addr = addr;
- }
+ if (!(vma->vm_flags & VM_SHARED))
+ continue;
+ if (old_addr)
+ pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n",
+ old_addr, addr, vma->vm_file);
+ if (nr == folio_nr_pages(folio))
+ old_addr = addr;
}
WARN_ON(++count == 4096);
}
@@ -578,11 +611,7 @@ void __init parisc_setup_cache_timing(void)
threshold/1024);
set_tlb_threshold:
- if (threshold > FLUSH_TLB_THRESHOLD)
- parisc_tlb_flush_threshold = threshold;
- else
- parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD;
-
+ parisc_tlb_flush_threshold = max(threshold, FLUSH_TLB_THRESHOLD);
printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
parisc_tlb_flush_threshold/1024);
}
@@ -591,35 +620,28 @@ extern void purge_kernel_dcache_page_asm(unsigned long);
extern void clear_user_page_asm(void *, unsigned long);
extern void copy_user_page_asm(void *, void *, unsigned long);
-void flush_kernel_dcache_page_addr(const void *addr)
-{
- unsigned long flags;
-
- flush_kernel_dcache_page_asm(addr);
- purge_tlb_start(flags);
- pdtlb(SR_KERNEL, addr);
- purge_tlb_end(flags);
-}
-EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
-
static void flush_cache_page_if_present(struct vm_area_struct *vma,
- unsigned long vmaddr, unsigned long pfn)
+ unsigned long vmaddr)
{
+#if CONFIG_FLUSH_PAGE_ACCESSED
bool needs_flush = false;
- pte_t *ptep;
+ pte_t *ptep, pte;
- /*
- * The pte check is racy and sometimes the flush will trigger
- * a non-access TLB miss. Hopefully, the page has already been
- * flushed.
- */
ptep = get_ptep(vma->vm_mm, vmaddr);
if (ptep) {
- needs_flush = pte_needs_flush(*ptep);
+ pte = ptep_get(ptep);
+ needs_flush = pte_needs_flush(pte);
pte_unmap(ptep);
}
if (needs_flush)
- flush_cache_page(vma, vmaddr, pfn);
+ __flush_cache_page(vma, vmaddr, PFN_PHYS(pte_pfn(pte)));
+#else
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long physaddr = get_upa(mm, vmaddr);
+
+ if (physaddr)
+ __flush_cache_page(vma, vmaddr, PAGE_ALIGN_DOWN(physaddr));
+#endif
}
void copy_user_highpage(struct page *to, struct page *from,
@@ -629,7 +651,7 @@ void copy_user_highpage(struct page *to, struct page *from,
kfrom = kmap_local_page(from);
kto = kmap_local_page(to);
- flush_cache_page_if_present(vma, vaddr, page_to_pfn(from));
+ __flush_cache_page(vma, vaddr, PFN_PHYS(page_to_pfn(from)));
copy_page_asm(kto, kfrom);
kunmap_local(kto);
kunmap_local(kfrom);
@@ -638,16 +660,17 @@ void copy_user_highpage(struct page *to, struct page *from,
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long user_vaddr, void *dst, void *src, int len)
{
- flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page));
+ __flush_cache_page(vma, user_vaddr, PFN_PHYS(page_to_pfn(page)));
memcpy(dst, src, len);
- flush_kernel_dcache_range_asm((unsigned long)dst, (unsigned long)dst + len);
+ flush_kernel_dcache_page_addr(PTR_PAGE_ALIGN_DOWN(dst));
}
void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long user_vaddr, void *dst, void *src, int len)
{
- flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page));
+ __flush_cache_page(vma, user_vaddr, PFN_PHYS(page_to_pfn(page)));
memcpy(dst, src, len);
+ flush_kernel_dcache_page_addr(PTR_PAGE_ALIGN_DOWN(src));
}
/* __flush_tlb_range()
@@ -681,32 +704,10 @@ int __flush_tlb_range(unsigned long sid, unsigned long start,
static void flush_cache_pages(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{
- unsigned long addr, pfn;
- pte_t *ptep;
-
- for (addr = start; addr < end; addr += PAGE_SIZE) {
- bool needs_flush = false;
- /*
- * The vma can contain pages that aren't present. Although
- * the pte search is expensive, we need the pte to find the
- * page pfn and to check whether the page should be flushed.
- */
- ptep = get_ptep(vma->vm_mm, addr);
- if (ptep) {
- needs_flush = pte_needs_flush(*ptep);
- pfn = pte_pfn(*ptep);
- pte_unmap(ptep);
- }
- if (needs_flush) {
- if (parisc_requires_coherency()) {
- flush_user_cache_page(vma, addr);
- } else {
- if (WARN_ON(!pfn_valid(pfn)))
- return;
- __flush_cache_page(vma, addr, PFN_PHYS(pfn));
- }
- }
- }
+ unsigned long addr;
+
+ for (addr = start; addr < end; addr += PAGE_SIZE)
+ flush_cache_page_if_present(vma, addr);
}
static inline unsigned long mm_total_size(struct mm_struct *mm)
@@ -757,21 +758,19 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled()))
return;
flush_tlb_range(vma, start, end);
- flush_cache_all();
+ if (vma->vm_flags & VM_EXEC)
+ flush_cache_all();
+ else
+ flush_data_cache();
return;
}
- flush_cache_pages(vma, start, end);
+ flush_cache_pages(vma, start & PAGE_MASK, end);
}
void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
{
- if (WARN_ON(!pfn_valid(pfn)))
- return;
- if (parisc_requires_coherency())
- flush_user_cache_page(vma, vmaddr);
- else
- __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
+ __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
}
void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
@@ -779,34 +778,133 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned lon
if (!PageAnon(page))
return;
- if (parisc_requires_coherency()) {
- if (vma->vm_flags & VM_SHARED)
- flush_data_cache();
- else
- flush_user_cache_page(vma, vmaddr);
+ __flush_cache_page(vma, vmaddr, PFN_PHYS(page_to_pfn(page)));
+}
+
+int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr,
+ pte_t *ptep)
+{
+ pte_t pte = ptep_get(ptep);
+
+ if (!pte_young(pte))
+ return 0;
+ set_pte(ptep, pte_mkold(pte));
+#if CONFIG_FLUSH_PAGE_ACCESSED
+ __flush_cache_page(vma, addr, PFN_PHYS(pte_pfn(pte)));
+#endif
+ return 1;
+}
+
+/*
+ * After a PTE is cleared, we have no way to flush the cache for
+ * the physical page. On PA8800 and PA8900 processors, these lines
+ * can cause random cache corruption. Thus, we must flush the cache
+ * as well as the TLB when clearing a PTE that's valid.
+ */
+pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr,
+ pte_t *ptep)
+{
+ struct mm_struct *mm = (vma)->vm_mm;
+ pte_t pte = ptep_get_and_clear(mm, addr, ptep);
+ unsigned long pfn = pte_pfn(pte);
+
+ if (pfn_valid(pfn))
+ __flush_cache_page(vma, addr, PFN_PHYS(pfn));
+ else if (pte_accessible(mm, pte))
+ flush_tlb_page(vma, addr);
+
+ return pte;
+}
+
+/*
+ * The physical address for pages in the ioremap case can be obtained
+ * from the vm_struct struct. I wasn't able to successfully handle the
+ * vmalloc and vmap cases. We have an array of struct page pointers in
+ * the uninitialized vmalloc case but the flush failed using page_to_pfn.
+ */
+void flush_cache_vmap(unsigned long start, unsigned long end)
+{
+ unsigned long addr, physaddr;
+ struct vm_struct *vm;
+
+ /* Prevent cache move-in */
+ flush_tlb_kernel_range(start, end);
+
+ if (end - start >= parisc_cache_flush_threshold) {
+ flush_cache_all();
return;
}
- flush_tlb_page(vma, vmaddr);
- preempt_disable();
- flush_dcache_page_asm(page_to_phys(page), vmaddr);
- preempt_enable();
+ if (WARN_ON_ONCE(!is_vmalloc_addr((void *)start))) {
+ flush_cache_all();
+ return;
+ }
+
+ vm = find_vm_area((void *)start);
+ if (WARN_ON_ONCE(!vm)) {
+ flush_cache_all();
+ return;
+ }
+
+ /* The physical addresses of IOREMAP regions are contiguous */
+ if (vm->flags & VM_IOREMAP) {
+ physaddr = vm->phys_addr;
+ for (addr = start; addr < end; addr += PAGE_SIZE) {
+ preempt_disable();
+ flush_dcache_page_asm(physaddr, start);
+ flush_icache_page_asm(physaddr, start);
+ preempt_enable();
+ physaddr += PAGE_SIZE;
+ }
+ return;
+ }
+
+ flush_cache_all();
}
+EXPORT_SYMBOL(flush_cache_vmap);
+/*
+ * The vm_struct has been retired and the page table is set up. The
+ * last page in the range is a guard page. Its physical address can't
+ * be determined using lpa, so there is no way to flush the range
+ * using flush_dcache_page_asm.
+ */
+void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+ /* Prevent cache move-in */
+ flush_tlb_kernel_range(start, end);
+ flush_data_cache();
+}
+EXPORT_SYMBOL(flush_cache_vunmap);
+
+/*
+ * On systems with PA8800/PA8900 processors, there is no way to flush
+ * a vmap range other than using the architected loop to flush the
+ * entire cache. The page directory is not set up, so we can't use
+ * fdc, etc. FDCE/FICE don't work to flush a portion of the cache.
+ * L2 is physically indexed but FDCE/FICE instructions in virtual
+ * mode output their virtual address on the core bus, not their
+ * real address. As a result, the L2 cache index formed from the
+ * virtual address will most likely not be the same as the L2 index
+ * formed from the real address.
+ */
void flush_kernel_vmap_range(void *vaddr, int size)
{
unsigned long start = (unsigned long)vaddr;
unsigned long end = start + size;
- if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
- (unsigned long)size >= parisc_cache_flush_threshold) {
- flush_tlb_kernel_range(start, end);
- flush_data_cache();
+ flush_tlb_kernel_range(start, end);
+
+ if (!static_branch_likely(&parisc_has_dcache))
+ return;
+
+ /* If interrupts are disabled, we can only do local flush */
+ if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) {
+ flush_data_cache_local(NULL);
return;
}
- flush_kernel_dcache_range_asm(start, end);
- flush_tlb_kernel_range(start, end);
+ flush_data_cache();
}
EXPORT_SYMBOL(flush_kernel_vmap_range);
@@ -818,15 +916,18 @@ void invalidate_kernel_vmap_range(void *vaddr, int size)
/* Ensure DMA is complete */
asm_syncdma();
- if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
- (unsigned long)size >= parisc_cache_flush_threshold) {
- flush_tlb_kernel_range(start, end);
- flush_data_cache();
+ flush_tlb_kernel_range(start, end);
+
+ if (!static_branch_likely(&parisc_has_dcache))
+ return;
+
+ /* If interrupts are disabled, we can only do local flush */
+ if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) {
+ flush_data_cache_local(NULL);
return;
}
- purge_kernel_dcache_range_asm(start, end);
- flush_tlb_kernel_range(start, end);
+ flush_data_cache();
}
EXPORT_SYMBOL(invalidate_kernel_vmap_range);
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index ac19d685e4a5..1e793f770f71 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -97,7 +97,7 @@ static int for_each_padev(int (*fn)(struct device *, void *), void * data)
* @driver: the PA-RISC driver to try
* @dev: the PA-RISC device to try
*/
-static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
+static int match_device(const struct parisc_driver *driver, struct parisc_device *dev)
{
const struct parisc_device_id *ids;
@@ -548,7 +548,7 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
return dev;
}
-static int parisc_generic_match(struct device *dev, struct device_driver *drv)
+static int parisc_generic_match(struct device *dev, const struct device_driver *drv)
{
return match_device(to_parisc_driver(drv), to_parisc_device(dev));
}
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index 621a4b386ae4..c91f9c2e61ed 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -206,6 +206,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe *p;
int bit;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index d214bbe3c2af..4e5d991b2b65 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -41,7 +41,6 @@
#include <linux/moduleloader.h>
#include <linux/elf.h>
-#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/ftrace.h>
#include <linux/string.h>
@@ -173,17 +172,6 @@ static inline int reassemble_22(int as22)
((as22 & 0x0003ff) << 3));
}
-void *module_alloc(unsigned long size)
-{
- /* using RWX means less protection for modules, but it's
- * easier than trying to map the text, data, init_text and
- * init_data correctly */
- return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
- GFP_KERNEL,
- PAGE_KERNEL_RWX, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-
#ifndef CONFIG_64BIT
static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
{
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 6f0c92e8149d..c1587aa35beb 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -22,6 +22,8 @@ EXPORT_SYMBOL(memset);
#include <linux/atomic.h>
EXPORT_SYMBOL(__xchg8);
EXPORT_SYMBOL(__xchg32);
+EXPORT_SYMBOL(__cmpxchg_u8);
+EXPORT_SYMBOL(__cmpxchg_u16);
EXPORT_SYMBOL(__cmpxchg_u32);
EXPORT_SYMBOL(__cmpxchg_u64);
#ifdef CONFIG_SMP
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 444154271f23..800eb64e91ad 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -344,7 +344,7 @@ static int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
struct irq_desc *desc = irq_to_desc(i);
if (desc && desc->kstat_irqs)
- *per_cpu_ptr(desc->kstat_irqs, cpuid) = 0;
+ *per_cpu_ptr(desc->kstat_irqs, cpuid) = (struct irqstat) { };
}
#endif
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 98af719d5f85..f7722451276e 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -104,7 +104,9 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
struct vm_area_struct *vma, *prev;
unsigned long filp_pgoff;
int do_color_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {
+ .length = len
+ };
if (unlikely(len > TASK_SIZE))
return -ENOMEM;
@@ -139,7 +141,6 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
return addr;
}
- info.length = len;
info.align_mask = do_color_align ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(filp_pgoff, pgoff);
@@ -160,7 +161,6 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
*/
}
- info.flags = 0;
info.low_limit = mm->mmap_base;
info.high_limit = mmap_upper_limit(NULL);
return vm_unmapped_area(&info);
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 2a12a547b447..826c8e51b585 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
current->comm, current->pid, r20);
return -ENOSYS;
}
-
-asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags,
- compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
- const char __user * pathname)
-{
- return sys_fanotify_mark(fanotify_fd, flags,
- ((__u64)mask1 << 32) | mask0,
- dfd, pathname);
-}
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index b236a84c4e12..66dc406b12e4 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -108,7 +108,7 @@
95 common fchown sys_fchown
96 common getpriority sys_getpriority
97 common setpriority sys_setpriority
-98 common recv sys_recv
+98 common recv sys_recv compat_sys_recv
99 common statfs sys_statfs compat_sys_statfs
100 common fstatfs sys_fstatfs compat_sys_fstatfs
101 common stat64 sys_stat64
@@ -135,7 +135,7 @@
120 common clone sys_clone_wrapper
121 common setdomainname sys_setdomainname
122 common sendfile sys_sendfile compat_sys_sendfile
-123 common recvfrom sys_recvfrom
+123 common recvfrom sys_recvfrom compat_sys_recvfrom
124 32 adjtimex sys_adjtimex_time32
124 64 adjtimex sys_adjtimex
125 common mprotect sys_mprotect
@@ -364,7 +364,7 @@
320 common accept4 sys_accept4
321 common prlimit64 sys_prlimit64
322 common fanotify_init sys_fanotify_init
-323 common fanotify_mark sys_fanotify_mark sys32_fanotify_mark
+323 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark
324 32 clock_adjtime sys_clock_adjtime32
324 64 clock_adjtime sys_clock_adjtime
325 common name_to_handle_at sys_name_to_handle_at
@@ -460,3 +460,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 71e596ca5a86..3e79e40e361d 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -104,6 +104,7 @@
#define ERR_NOTHANDLED -1
int unaligned_enabled __read_mostly = 1;
+int no_unaligned_warning __read_mostly;
static int emulate_ldh(struct pt_regs *regs, int toreg)
{
@@ -399,6 +400,7 @@ void handle_unaligned(struct pt_regs *regs)
} else {
static DEFINE_RATELIMIT_STATE(kernel_ratelimit, 5 * HZ, 5);
if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
+ !no_unaligned_warning &&
__ratelimit(&kernel_ratelimit))
pr_warn("Kernel: unaligned access to " RFMT " in %pS "
"(iir " RFMT ")\n",
diff --git a/arch/parisc/kernel/vdso32/Makefile b/arch/parisc/kernel/vdso32/Makefile
index 4459a48d2303..2b36d25ada6e 100644
--- a/arch/parisc/kernel/vdso32/Makefile
+++ b/arch/parisc/kernel/vdso32/Makefile
@@ -1,11 +1,25 @@
-# List of files in the vdso, has to be asm only for now
+# Include the generic Makefile to check the built vdso.
+include $(srctree)/lib/vdso/Makefile
+
+KCOV_INSTRUMENT := n
+
+# Disable gcov profiling, ubsan and kasan for VDSO code
+GCOV_PROFILE := n
+UBSAN_SANITIZE := n
+KASAN_SANITIZE := n
+KCSAN_SANITIZE := n
obj-vdso32 = note.o sigtramp.o restart_syscall.o
+obj-cvdso32 = vdso32_generic.o
# Build rules
-targets := $(obj-vdso32) vdso32.so
+targets := $(obj-vdso32) $(obj-cvdso32) vdso32.so
obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
+obj-cvdso32 := $(addprefix $(obj)/, $(obj-cvdso32))
+
+VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_vdso32_generic.o = $(VDSO_CFLAGS_REMOVE)
ccflags-y := -shared -fno-common -fbuiltin -mno-fast-indirect-calls -O2 -mno-long-calls
# -march=1.1 -mschedule=7100LC
@@ -26,13 +40,12 @@ $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so FORCE
# Force dependency (incbin is bad)
# link rule for the .so file, .lds has to be first
-$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) FORCE
+$(obj)/vdso32.so: $(obj)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) FORCE
$(call if_changed,vdso32ld)
# assembly rules for the .S files
$(obj-vdso32): %.o: %.S FORCE
$(call if_changed_dep,vdso32as)
-
$(obj-cvdso32): %.o: %.c FORCE
$(call if_changed_dep,vdso32cc)
@@ -42,10 +55,10 @@ quiet_cmd_vdso32ld = VDSO32L $@
quiet_cmd_vdso32as = VDSO32A $@
cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
quiet_cmd_vdso32cc = VDSO32C $@
- cmd_vdso32cc = $(CROSS32CC) $(c_flags) -c -fPIC -mno-fast-indirect-calls -o $@ $<
+ cmd_vdso32cc = $(CROSS32CC) $(c_flags) -c -o $@ $<
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/parisc/kernel/vdso32/vdso32.lds.S b/arch/parisc/kernel/vdso32/vdso32.lds.S
index d4aff3af5262..4273baa26b65 100644
--- a/arch/parisc/kernel/vdso32/vdso32.lds.S
+++ b/arch/parisc/kernel/vdso32/vdso32.lds.S
@@ -106,6 +106,9 @@ VERSION
global:
__kernel_sigtramp_rt32;
__kernel_restart_syscall32;
+ __vdso_gettimeofday;
+ __vdso_clock_gettime;
+ __vdso_clock_gettime64;
local: *;
};
}
diff --git a/arch/parisc/kernel/vdso32/vdso32_generic.c b/arch/parisc/kernel/vdso32/vdso32_generic.c
new file mode 100644
index 000000000000..8d5bd59e8646
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/vdso32_generic.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "asm/unistd.h"
+#include <linux/types.h>
+#include <uapi/asm/unistd_32.h>
+
+struct timezone;
+struct old_timespec32;
+struct __kernel_timespec;
+struct __kernel_old_timeval;
+
+/* forward declarations */
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
+int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts);
+int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts);
+
+
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
+{
+ return syscall2(__NR_gettimeofday, (long)tv, (long)tz);
+}
+
+int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
+{
+ return syscall2(__NR_clock_gettime, (long)clock, (long)ts);
+}
+
+int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts)
+{
+ return syscall2(__NR_clock_gettime64, (long)clock, (long)ts);
+}
diff --git a/arch/parisc/kernel/vdso64/Makefile b/arch/parisc/kernel/vdso64/Makefile
index f3d6045793f4..bd87bd6a6659 100644
--- a/arch/parisc/kernel/vdso64/Makefile
+++ b/arch/parisc/kernel/vdso64/Makefile
@@ -1,12 +1,25 @@
-# List of files in the vdso, has to be asm only for now
+# Include the generic Makefile to check the built vdso.
+include $(srctree)/lib/vdso/Makefile
+
+KCOV_INSTRUMENT := n
+
+# Disable gcov profiling, ubsan and kasan for VDSO code
+GCOV_PROFILE := n
+UBSAN_SANITIZE := n
+KASAN_SANITIZE := n
+KCSAN_SANITIZE := n
obj-vdso64 = note.o sigtramp.o restart_syscall.o
+obj-cvdso64 = vdso64_generic.o
# Build rules
-targets := $(obj-vdso64) vdso64.so
-obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
+targets := $(obj-vdso64) $(obj-cvdso64) vdso64.so
+obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
+obj-cvdso64 := $(addprefix $(obj)/, $(obj-cvdso64))
+VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE)
ccflags-y := -shared -fno-common -fno-builtin
ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
@@ -26,21 +39,25 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so FORCE
# Force dependency (incbin is bad)
# link rule for the .so file, .lds has to be first
-$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC) FORCE
+$(obj)/vdso64.so: $(obj)/vdso64.lds $(obj-vdso64) $(obj-cvdso64) $(VDSO_LIBGCC) FORCE
$(call if_changed,vdso64ld)
# assembly rules for the .S files
$(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_vdso64ld = VDSO64L $@
cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
quiet_cmd_vdso64as = VDSO64A $@
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
+quiet_cmd_vdso64cc = VDSO64C $@
+ cmd_vdso64cc = $(CC) $(c_flags) -c -o $@ $<
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/parisc/kernel/vdso64/vdso64.lds.S b/arch/parisc/kernel/vdso64/vdso64.lds.S
index de1fb4b19286..10f25e4e1554 100644
--- a/arch/parisc/kernel/vdso64/vdso64.lds.S
+++ b/arch/parisc/kernel/vdso64/vdso64.lds.S
@@ -104,6 +104,8 @@ VERSION
global:
__kernel_sigtramp_rt64;
__kernel_restart_syscall64;
+ __vdso_gettimeofday;
+ __vdso_clock_gettime;
local: *;
};
}
diff --git a/arch/parisc/kernel/vdso64/vdso64_generic.c b/arch/parisc/kernel/vdso64/vdso64_generic.c
new file mode 100644
index 000000000000..fc6836a0075b
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/vdso64_generic.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "asm/unistd.h"
+#include <linux/types.h>
+
+struct timezone;
+struct __kernel_timespec;
+struct __kernel_old_timeval;
+
+/* forward declarations */
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
+int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
+
+
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
+{
+ return syscall2(__NR_gettimeofday, (long)tv, (long)tz);
+}
+
+int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
+{
+ return syscall2(__NR_clock_gettime, (long)clock, (long)ts);
+}
diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c
index 36a314199074..9df810050642 100644
--- a/arch/parisc/lib/bitops.c
+++ b/arch/parisc/lib/bitops.c
@@ -56,38 +56,20 @@ unsigned long notrace __xchg8(char x, volatile char *ptr)
}
-u64 notrace __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new)
-{
- unsigned long flags;
- u64 prev;
-
- _atomic_spin_lock_irqsave(ptr, flags);
- if ((prev = *ptr) == old)
- *ptr = new;
- _atomic_spin_unlock_irqrestore(ptr, flags);
- return prev;
-}
-
-unsigned long notrace __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new)
-{
- unsigned long flags;
- unsigned int prev;
-
- _atomic_spin_lock_irqsave(ptr, flags);
- if ((prev = *ptr) == old)
- *ptr = new;
- _atomic_spin_unlock_irqrestore(ptr, flags);
- return (unsigned long)prev;
-}
-
-u8 notrace __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new)
-{
- unsigned long flags;
- u8 prev;
-
- _atomic_spin_lock_irqsave(ptr, flags);
- if ((prev = *ptr) == old)
- *ptr = new;
- _atomic_spin_unlock_irqrestore(ptr, flags);
- return prev;
-}
+#define CMPXCHG(T) \
+ T notrace __cmpxchg_##T(volatile T *ptr, T old, T new) \
+ { \
+ unsigned long flags; \
+ T prev; \
+ \
+ _atomic_spin_lock_irqsave(ptr, flags); \
+ if ((prev = *ptr) == old) \
+ *ptr = new; \
+ _atomic_spin_unlock_irqrestore(ptr, flags); \
+ return prev; \
+ }
+
+CMPXCHG(u64)
+CMPXCHG(u32)
+CMPXCHG(u16)
+CMPXCHG(u8)
diff --git a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c
index 6ce427b58836..34495446e051 100644
--- a/arch/parisc/math-emu/driver.c
+++ b/arch/parisc/math-emu/driver.c
@@ -26,12 +26,6 @@
#define FPUDEBUG 0
-/* Format of the floating-point exception registers. */
-struct exc_reg {
- unsigned int exception : 6;
- unsigned int ei : 26;
-};
-
/* Macros for grabbing bits of the instruction format from the 'ei'
field above. */
/* Major opcode 0c and 0e */
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index a9f7e21f6656..0356199bd9e7 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -180,14 +180,3 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
}
return changed;
}
-
-
-int pmd_huge(pmd_t pmd)
-{
- return 0;
-}
-
-int pud_huge(pud_t pud)
-{
- return 0;
-}
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index f876af56e13f..34d91cb8b259 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -24,6 +24,7 @@
#include <linux/nodemask.h> /* for node_online_map */
#include <linux/pagemap.h> /* for release_pages */
#include <linux/compat.h>
+#include <linux/execmem.h>
#include <asm/pgalloc.h>
#include <asm/tlb.h>
@@ -481,7 +482,7 @@ void free_initmem(void)
/* finally dump all the instructions which were cached, since the
* pages are no-longer executable */
flush_icache_range(init_begin, init_end);
-
+
free_initmem_default(POISON_FREE_INITMEM);
/* set up a new led state on systems shipped LED State panel */
@@ -992,3 +993,23 @@ static const pgprot_t protection_map[16] = {
[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_RWX
};
DECLARE_VM_GET_PAGE_PROT
+
+#ifdef CONFIG_EXECMEM
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = VMALLOC_START,
+ .end = VMALLOC_END,
+ .pgprot = PAGE_KERNEL_RWX,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c
index d6ee2fd45550..979f45d4d1fb 100644
--- a/arch/parisc/net/bpf_jit_core.c
+++ b/arch/parisc/net/bpf_jit_core.c
@@ -167,7 +167,13 @@ skip_init_ctx:
bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns);
if (!prog->is_func || extra_pass) {
- bpf_jit_binary_lock_ro(jit_data->header);
+ if (bpf_jit_binary_lock_ro(jit_data->header)) {
+ bpf_jit_binary_free(jit_data->header);
+ prog->bpf_func = NULL;
+ prog->jited = 0;
+ prog->jited_len = 0;
+ goto out_offset;
+ }
prologue_len = ctx->epilogue_offset - ctx->body_len;
for (i = 0; i < prog->len; i++)
ctx->offset[i] += prologue_len;
diff --git a/arch/parisc/video/Makefile b/arch/parisc/video/Makefile
index 16a73cce4661..b5db5b42880f 100644
--- a/arch/parisc/video/Makefile
+++ b/arch/parisc/video/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_STI_CORE) += fbdev.o
+obj-$(CONFIG_STI_CORE) += video-sti.o
diff --git a/arch/parisc/video/fbdev.c b/arch/parisc/video/video-sti.c
index e4f8ac99fc9e..564661e87093 100644
--- a/arch/parisc/video/fbdev.c
+++ b/arch/parisc/video/video-sti.c
@@ -5,12 +5,13 @@
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*/
-#include <linux/fb.h>
#include <linux/module.h>
#include <video/sticore.h>
-int fb_is_primary_device(struct fb_info *info)
+#include <asm/video.h>
+
+bool video_is_primary_device(struct device *dev)
{
struct sti_struct *sti;
@@ -21,6 +22,6 @@ int fb_is_primary_device(struct fb_info *info)
return true;
/* return true if it's the default built-in framebuffer driver */
- return (sti->dev == info->device);
+ return (sti->dev == dev);
}
-EXPORT_SYMBOL(fb_is_primary_device);
+EXPORT_SYMBOL(video_is_primary_device);
diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 22cd0d55a892..571f260b0842 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror -Wa,--fatal-warnings
+subdir-asflags-$(CONFIG_PPC_WERROR) := -Wa,--fatal-warnings
obj-y += kernel/
obj-y += mm/
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1c4be3373686..d7b09b064a8a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,8 +135,8 @@ config PPC
select ARCH_HAS_DMA_MAP_DIRECT if PPC_PSERIES
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
- select ARCH_HAS_HUGEPD if HUGETLB_PAGE
select ARCH_HAS_KCOV
+ select ARCH_HAS_KERNEL_FPU_SUPPORT if PPC64 && PPC_FPU
select ARCH_HAS_MEMBARRIER_CALLBACKS
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_MEMREMAP_COMPAT_ALIGN if PPC_64S_HASH_MMU
@@ -148,7 +148,7 @@ config PPC
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
select ARCH_HAS_SET_MEMORY
- select ARCH_HAS_STRICT_KERNEL_RWX if (PPC_BOOK3S || PPC_8xx || 40x) && !HIBERNATION
+ select ARCH_HAS_STRICT_KERNEL_RWX if (PPC_BOOK3S || PPC_8xx) && !HIBERNATION
select ARCH_HAS_STRICT_KERNEL_RWX if PPC_85xx && !HIBERNATION && !RANDOMIZE_BASE
select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_SYSCALL_WRAPPER if !SPU_BASE && !COMPAT
@@ -156,6 +156,7 @@ config PPC
select ARCH_HAS_UACCESS_FLUSHCACHE
select ARCH_HAS_UBSAN
select ARCH_HAVE_NMI_SAFE_CMPXCHG
+ select ARCH_HAVE_EXTRA_ELF_NOTES if SPU_BASE
select ARCH_KEEP_MEMBLOCK
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if PPC_RADIX_MMU
select ARCH_MIGHT_HAVE_PC_PARPORT
@@ -165,7 +166,7 @@ config PPC
select ARCH_SPLIT_ARG64 if PPC32
select ARCH_STACKWALK
select ARCH_SUPPORTS_ATOMIC_RMW
- select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx || 40x
+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF if PPC64
select ARCH_USE_MEMTEST
@@ -236,7 +237,7 @@ config PPC
select HAVE_DYNAMIC_FTRACE_WITH_REGS if ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
select HAVE_EBPF_JIT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
- select HAVE_FAST_GUP
+ select HAVE_GUP_FAST
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_ARG_ACCESS_API
select HAVE_FUNCTION_DESCRIPTORS if PPC64_ELF_ABI_V1
@@ -285,7 +286,7 @@ config PPC
select IOMMU_HELPER if PPC64
select IRQ_DOMAIN
select IRQ_FORCED_THREADING
- select KASAN_VMALLOC if KASAN && MODULES
+ select KASAN_VMALLOC if KASAN && EXECMEM
select LOCK_MM_AND_FIND_VMA
select MMU_GATHER_PAGE_SIZE
select MMU_GATHER_RCU_TABLE_FREE
@@ -387,7 +388,7 @@ config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
(PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \
- || 44x || 40x
+ || 44x
config ARCH_SUSPEND_NONZERO_CPU
def_bool y
@@ -441,7 +442,7 @@ config ARCH_SUPPORTS_UPROBES
config PPC_ADV_DEBUG_REGS
bool
- depends on 40x || BOOKE
+ depends on BOOKE
default y
config PPC_ADV_DEBUG_IACS
@@ -488,7 +489,7 @@ source "kernel/Kconfig.hz"
config MATH_EMULATION
bool "Math emulation"
- depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE || PPC_MICROWATT
+ depends on 44x || PPC_8xx || PPC_MPC832x || BOOKE || PPC_MICROWATT
select PPC_FPU_REGS
help
Some PowerPC chips designed for embedded applications do not have
@@ -686,6 +687,10 @@ config ARCH_SELECTS_CRASH_DUMP
depends on CRASH_DUMP
select RELOCATABLE if PPC64 || 44x || PPC_85xx
+config ARCH_SUPPORTS_CRASH_HOTPLUG
+ def_bool y
+ depends on PPC64
+
config FA_DUMP
bool "Firmware-assisted dump"
depends on CRASH_DUMP && PPC64 && (PPC_RTAS || PPC_POWERNV)
@@ -959,7 +964,8 @@ config CMDLINE
most cases you will need to specify the root device here.
choice
- prompt "Kernel command line type" if CMDLINE != ""
+ prompt "Kernel command line type"
+ depends on CMDLINE != ""
default CMDLINE_FROM_BOOTLOADER
config CMDLINE_FROM_BOOTLOADER
@@ -1071,7 +1077,7 @@ config GENERIC_ISA_DMA
config PPC_INDIRECT_PCI
bool
depends on PCI
- default y if 40x || 44x
+ default y if 44x
config SBUS
bool
@@ -1096,15 +1102,12 @@ config FSL_PMC
config PPC4xx_CPM
bool
default y
- depends on SUSPEND && (44x || 40x)
+ depends on SUSPEND && 44x
help
PPC4xx Clock Power Management (CPM) support (suspend/resume).
It also enables support for two different idle states (idle-wait
and idle-doze).
-config 4xx_SOC
- bool
-
config FSL_LBC
bool "Freescale Local Bus support"
help
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 8c80b154e814..3799ceceb04a 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -244,14 +244,6 @@ config PPC_EARLY_DEBUG_44x
inbuilt serial port. If you enable this, ensure you set
PPC_EARLY_DEBUG_44x_PHYSLOW below to suit your target board.
-config PPC_EARLY_DEBUG_40x
- bool "Early serial debugging for IBM/AMCC 40x CPUs"
- depends on 40x
- help
- Select this to enable early debugging for IBM 40x chips via the
- inbuilt serial port. This works on chips with a 16550 compatible
- UART.
-
config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports"
depends on SERIAL_CPM=y
@@ -356,11 +348,6 @@ config PPC_EARLY_DEBUG_44x_PHYSHIGH
depends on PPC_EARLY_DEBUG_44x
default "0x1"
-config PPC_EARLY_DEBUG_40x_PHYSADDR
- hex "Early debug UART physical address"
- depends on PPC_EARLY_DEBUG_40x
- default "0xef600300"
-
config PPC_EARLY_DEBUG_CPM_ADDR
hex "CPM UART early debug transmit descriptor address"
depends on PPC_EARLY_DEBUG_CPM
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 65261cbe5bfd..bbfe4a1f06ef 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -114,7 +114,6 @@ LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y)
ifdef CONFIG_PPC64
ifndef CONFIG_PPC_KERNEL_PCREL
-ifeq ($(call cc-option-yn,-mcmodel=medium),y)
# -mcmodel=medium breaks modules because it uses 32bit offsets from
# the TOC pointer to create pointers where possible. Pointers into the
# percpu data area are created by this method.
@@ -124,9 +123,6 @@ ifeq ($(call cc-option-yn,-mcmodel=medium),y)
# kernel percpu data space (starting with 0xc...). We need a full
# 64bit relocation for this to work, hence -mcmodel=large.
KBUILD_CFLAGS_MODULE += -mcmodel=large
-else
- export NO_MINIMAL_TOC := -mno-minimal-toc
-endif
endif
endif
@@ -139,7 +135,7 @@ CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc)
endif
endif
-CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc))
+CFLAGS-$(CONFIG_PPC64) += -mcmodel=medium
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mlong-double-128)
@@ -153,6 +149,9 @@ CFLAGS-$(CONFIG_PPC32) += $(call cc-option, $(MULTIPLEWORD))
CFLAGS-$(CONFIG_PPC32) += $(call cc-option,-mno-readonly-in-sdata)
+CC_FLAGS_FPU := $(call cc-option,-mhard-float)
+CC_FLAGS_NO_FPU := $(call cc-option,-msoft-float)
+
ifdef CONFIG_FUNCTION_TRACER
ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY
KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
@@ -174,7 +173,7 @@ asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1)
KBUILD_CPPFLAGS += -I $(srctree)/arch/powerpc $(asinstr)
KBUILD_AFLAGS += $(AFLAGS-y)
-KBUILD_CFLAGS += $(call cc-option,-msoft-float)
+KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU)
KBUILD_CFLAGS += $(CFLAGS-y)
CPP = $(CC) -E $(KBUILD_CFLAGS)
@@ -302,11 +301,6 @@ ppc32_allmodconfig:
$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/book3s_32.config \
-f $(srctree)/Makefile allmodconfig
-generated_configs += ppc40x_allmodconfig
-ppc40x_allmodconfig:
- $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/40x.config \
- -f $(srctree)/Makefile allmodconfig
-
generated_configs += ppc44x_allmodconfig
ppc44x_allmodconfig:
$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/44x.config \
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 00c4d843a023..682ca3827892 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -253,7 +253,6 @@ void ibm4xx_denali_fixup_memsize(void)
dt_fixup_memory(0, memsize);
}
-#define SPRN_DBCR0_40X 0x3F2
#define SPRN_DBCR0_44X 0x134
#define DBCR0_RST_SYSTEM 0x30000000
@@ -270,18 +269,6 @@ void ibm44x_dbcr_reset(void)
}
-void ibm40x_dbcr_reset(void)
-{
- unsigned long tmp;
-
- asm volatile (
- "mfspr %0,%1\n"
- "oris %0,%0,%2@h\n"
- "mtspr %1,%0"
- : "=&r"(tmp) : "i"(SPRN_DBCR0_40X), "i"(DBCR0_RST_SYSTEM)
- );
-}
-
#define EMAC_RESET 0x20000000
void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
{
@@ -544,256 +531,3 @@ void ibm440spe_fixup_clocks(unsigned int sys_clk,
eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk);
eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk);
}
-
-void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
-{
- u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
- u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
- u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
- u32 psr = mfdcr(DCRN_405_CPC0_PSR);
- u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
- u32 fwdv, fwdvb, fbdv, cbdv, opdv, epdv, ppdv, udiv;
-
- fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
- fbdv = (pllmr & 0x1e000000) >> 25;
- if (fbdv == 0)
- fbdv = 16;
- cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */
- opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */
- ppdv = ((pllmr & 0x00006000) >> 13) + 1; /* PLB:PCI */
- epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */
- udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
-
- /* check for 405GPr */
- if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) {
- fwdvb = 8 - (pllmr & 0x00000007);
- if (!(psr & 0x00001000)) /* PCI async mode enable == 0 */
- if (psr & 0x00000020) /* New mode enable */
- m = fwdvb * 2 * ppdv;
- else
- m = fwdvb * cbdv * ppdv;
- else if (psr & 0x00000020) /* New mode enable */
- if (psr & 0x00000800) /* PerClk synch mode */
- m = fwdvb * 2 * epdv;
- else
- m = fbdv * fwdv;
- else if (epdv == fbdv)
- m = fbdv * cbdv * epdv;
- else
- m = fbdv * fwdvb * cbdv;
-
- cpu = sys_clk * m / fwdv;
- plb = sys_clk * m / (fwdvb * cbdv);
- } else {
- m = fwdv * fbdv * cbdv;
- cpu = sys_clk * m / fwdv;
- plb = cpu / cbdv;
- }
- opb = plb / opdv;
- ebc = plb / epdv;
-
- if (cpc0_cr0 & 0x80)
- /* uart0 uses the external clock */
- uart0 = ser_clk;
- else
- uart0 = cpu / udiv;
-
- if (cpc0_cr0 & 0x40)
- /* uart1 uses the external clock */
- uart1 = ser_clk;
- else
- uart1 = cpu / udiv;
-
- /* setup the timebase clock to tick at the cpu frequency */
- cpc0_cr1 = cpc0_cr1 & ~0x00800000;
- mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
- tb = cpu;
-
- dt_fixup_cpu_clocks(cpu, tb, 0);
- dt_fixup_clock("/plb", plb);
- dt_fixup_clock("/plb/opb", opb);
- dt_fixup_clock("/plb/ebc", ebc);
- dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
- dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
-}
-
-
-void ibm405ep_fixup_clocks(unsigned int sys_clk)
-{
- u32 pllmr0 = mfdcr(DCRN_CPC0_PLLMR0);
- u32 pllmr1 = mfdcr(DCRN_CPC0_PLLMR1);
- u32 cpc0_ucr = mfdcr(DCRN_CPC0_UCR);
- u32 cpu, plb, opb, ebc, uart0, uart1;
- u32 fwdva, fwdvb, fbdv, cbdv, opdv, epdv;
- u32 pllmr0_ccdv, tb, m;
-
- fwdva = 8 - ((pllmr1 & 0x00070000) >> 16);
- fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12);
- fbdv = (pllmr1 & 0x00f00000) >> 20;
- if (fbdv == 0)
- fbdv = 16;
-
- cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */
- epdv = ((pllmr0 & 0x00000300) >> 8) + 2; /* PLB:EBC */
- opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */
-
- m = fbdv * fwdvb;
-
- pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1;
- if (pllmr1 & 0x80000000)
- cpu = sys_clk * m / (fwdva * pllmr0_ccdv);
- else
- cpu = sys_clk / pllmr0_ccdv;
-
- plb = cpu / cbdv;
- opb = plb / opdv;
- ebc = plb / epdv;
- tb = cpu;
- uart0 = cpu / (cpc0_ucr & 0x0000007f);
- uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8);
-
- dt_fixup_cpu_clocks(cpu, tb, 0);
- dt_fixup_clock("/plb", plb);
- dt_fixup_clock("/plb/opb", opb);
- dt_fixup_clock("/plb/ebc", ebc);
- dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
- dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
-}
-
-static u8 ibm405ex_fwdv_multi_bits[] = {
- /* values for: 1 - 16 */
- 0x01, 0x02, 0x0e, 0x09, 0x04, 0x0b, 0x10, 0x0d, 0x0c, 0x05,
- 0x06, 0x0f, 0x0a, 0x07, 0x08, 0x03
-};
-
-u32 ibm405ex_get_fwdva(unsigned long cpr_fwdv)
-{
- u32 index;
-
- for (index = 0; index < ARRAY_SIZE(ibm405ex_fwdv_multi_bits); index++)
- if (cpr_fwdv == (u32)ibm405ex_fwdv_multi_bits[index])
- return index + 1;
-
- return 0;
-}
-
-static u8 ibm405ex_fbdv_multi_bits[] = {
- /* values for: 1 - 100 */
- 0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4,
- 0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb,
- 0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96,
- 0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde,
- 0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb,
- 0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91,
- 0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b,
- 0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95,
- 0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4,
- 0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc,
- /* values for: 101 - 200 */
- 0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3,
- 0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90,
- 0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe,
- 0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6,
- 0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd,
- 0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1,
- 0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6,
- 0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9,
- 0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e,
- 0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf,
- /* values for: 201 - 255 */
- 0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae,
- 0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2,
- 0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2,
- 0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98,
- 0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81,
- 0x03, 0x87, 0x0f, 0x9f, 0x3f /* END */
-};
-
-u32 ibm405ex_get_fbdv(unsigned long cpr_fbdv)
-{
- u32 index;
-
- for (index = 0; index < ARRAY_SIZE(ibm405ex_fbdv_multi_bits); index++)
- if (cpr_fbdv == (u32)ibm405ex_fbdv_multi_bits[index])
- return index + 1;
-
- return 0;
-}
-
-void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk)
-{
- /* PLL config */
- u32 pllc = CPR0_READ(DCRN_CPR0_PLLC);
- u32 plld = CPR0_READ(DCRN_CPR0_PLLD);
- u32 cpud = CPR0_READ(DCRN_CPR0_PRIMAD);
- u32 plbd = CPR0_READ(DCRN_CPR0_PRIMBD);
- u32 opbd = CPR0_READ(DCRN_CPR0_OPBD);
- u32 perd = CPR0_READ(DCRN_CPR0_PERD);
-
- /* Dividers */
- u32 fbdv = ibm405ex_get_fbdv(__fix_zero((plld >> 24) & 0xff, 1));
-
- u32 fwdva = ibm405ex_get_fwdva(__fix_zero((plld >> 16) & 0x0f, 1));
-
- u32 cpudv0 = __fix_zero((cpud >> 24) & 7, 8);
-
- /* PLBDV0 is hardwared to 010. */
- u32 plbdv0 = 2;
- u32 plb2xdv0 = __fix_zero((plbd >> 16) & 7, 8);
-
- u32 opbdv0 = __fix_zero((opbd >> 24) & 3, 4);
-
- u32 perdv0 = __fix_zero((perd >> 24) & 3, 4);
-
- /* Resulting clocks */
- u32 cpu, plb, opb, ebc, vco, tb, uart0, uart1;
-
- /* PLL's VCO is the source for primary forward ? */
- if (pllc & 0x40000000) {
- u32 m;
-
- /* Feedback path */
- switch ((pllc >> 24) & 7) {
- case 0:
- /* PLLOUTx */
- m = fbdv;
- break;
- case 1:
- /* CPU */
- m = fbdv * fwdva * cpudv0;
- break;
- case 5:
- /* PERClk */
- m = fbdv * fwdva * plb2xdv0 * plbdv0 * opbdv0 * perdv0;
- break;
- default:
- printf("WARNING ! Invalid PLL feedback source !\n");
- goto bypass;
- }
-
- vco = (unsigned int)(sys_clk * m);
- } else {
-bypass:
- /* Bypass system PLL */
- vco = 0;
- }
-
- /* CPU = VCO / ( FWDVA x CPUDV0) */
- cpu = vco / (fwdva * cpudv0);
- /* PLB = VCO / ( FWDVA x PLB2XDV0 x PLBDV0) */
- plb = vco / (fwdva * plb2xdv0 * plbdv0);
- /* OPB = PLB / OPBDV0 */
- opb = plb / opbdv0;
- /* EBC = OPB / PERDV0 */
- ebc = opb / perdv0;
-
- tb = cpu;
- uart0 = uart1 = uart_clk;
-
- dt_fixup_cpu_clocks(cpu, tb, 0);
- dt_fixup_clock("/plb", plb);
- dt_fixup_clock("/plb/opb", opb);
- dt_fixup_clock("/plb/opb/ebc", ebc);
- dt_fixup_clock("/plb/opb/serial@ef600200", uart0);
- dt_fixup_clock("/plb/opb/serial@ef600300", uart1);
-}
diff --git a/arch/powerpc/boot/4xx.h b/arch/powerpc/boot/4xx.h
index 77f15d124c81..62df496b7ba6 100644
--- a/arch/powerpc/boot/4xx.h
+++ b/arch/powerpc/boot/4xx.h
@@ -12,13 +12,9 @@ void ibm4xx_sdram_fixup_memsize(void);
void ibm440spe_fixup_memsize(void);
void ibm4xx_denali_fixup_memsize(void);
void ibm44x_dbcr_reset(void);
-void ibm40x_dbcr_reset(void);
void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1);
void ibm4xx_fixup_ebc_ranges(const char *ebc);
-void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
-void ibm405ep_fixup_clocks(unsigned int sys_clk);
-void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk);
void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
unsigned int tmr_clk);
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 968aee2025b8..fa8518067d38 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -54,10 +54,8 @@ endif
$(obj)/4xx.o: BOOTTARGETFLAGS += -mcpu=405
$(obj)/ebony.o: BOOTTARGETFLAGS += -mcpu=440
-$(obj)/cuboot-hotfoot.o: BOOTTARGETFLAGS += -mcpu=405
$(obj)/cuboot-taishan.o: BOOTTARGETFLAGS += -mcpu=440
$(obj)/cuboot-katmai.o: BOOTTARGETFLAGS += -mcpu=440
-$(obj)/cuboot-acadia.o: BOOTTARGETFLAGS += -mcpu=405
$(obj)/treeboot-iss4xx.o: BOOTTARGETFLAGS += -mcpu=405
$(obj)/treeboot-currituck.o: BOOTTARGETFLAGS += -mcpu=405
$(obj)/treeboot-akebono.o: BOOTTARGETFLAGS += -mcpu=405
@@ -108,8 +106,8 @@ DTC_FLAGS ?= -p 1024
# these files into the build dir, fix up any includes and ensure that dependent
# files are copied in the right order.
-# these need to be seperate variables because they are copied out of different
-# directories in the kernel tree. Sure you COULd merge them, but it's a
+# these need to be separate variables because they are copied out of different
+# directories in the kernel tree. Sure you COULD merge them, but it's a
# cure-is-worse-than-disease situation.
zlib-decomp-$(CONFIG_KERNEL_GZIP) := decompress_inflate.c
zlib-$(CONFIG_KERNEL_GZIP) := inffast.c inflate.c inftrees.c
@@ -146,7 +144,6 @@ src-wlib-$(CONFIG_PPC_POWERNV) += opal-calls.S opal.c
ifndef CONFIG_PPC64_BOOT_WRAPPER
src-wlib-y += crtsavres.S
endif
-src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c
src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
@@ -154,9 +151,6 @@ src-wlib-$(CONFIG_EMBEDDED6xx) += ugecon.c fsl-soc.c
src-wlib-$(CONFIG_CPM) += cpm-serial.c
src-plat-y := of.c epapr.c
-src-plat-$(CONFIG_40x) += fixed-head.S cuboot-hotfoot.c \
- cuboot-acadia.c \
- cuboot-kilauea.c simpleboot.c
src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \
cuboot-bamboo.c cuboot-sam440ep.c \
cuboot-sequoia.c cuboot-rainier.c \
@@ -218,7 +212,7 @@ $(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc
$(obj)/empty.c:
$(Q)touch $@
-$(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
+$(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(src)/%.S
$(Q)cp $< $@
clean-files := $(zlib-) $(zlibheader-) $(zliblinuxheader-) \
@@ -252,9 +246,9 @@ targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) zImage.lds
extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
-dtstree := $(srctree)/$(src)/dts
+dtstree := $(src)/dts
-wrapper :=$(srctree)/$(src)/wrapper
+wrapper := $(src)/wrapper
wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
$(wrapper) FORCE
@@ -300,11 +294,6 @@ image-$(CONFIG_EPAPR_BOOT) += zImage.epapr
# Boards with newish u-boot firmware can use the uImage target above
#
-# Board ports in arch/powerpc/platform/40x/Kconfig
-image-$(CONFIG_HOTFOOT) += cuImage.hotfoot
-image-$(CONFIG_ACADIA) += cuImage.acadia
-image-$(CONFIG_OBS600) += uImage.obs600
-
# Board ports in arch/powerpc/platform/44x/Kconfig
image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony
image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo
diff --git a/arch/powerpc/boot/cuboot-acadia.c b/arch/powerpc/boot/cuboot-acadia.c
deleted file mode 100644
index 46e96756cfe1..000000000000
--- a/arch/powerpc/boot/cuboot-acadia.c
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Old U-boot compatibility for Acadia
- *
- * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com>
- *
- * Copyright 2008 IBM Corporation
- */
-
-#include "ops.h"
-#include "io.h"
-#include "dcr.h"
-#include "stdio.h"
-#include "4xx.h"
-#include "44x.h"
-#include "cuboot.h"
-
-#define TARGET_4xx
-#include "ppcboot.h"
-
-static bd_t bd;
-
-#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */
-
-#define PLLC_SRC_MASK 0x20000000 /* PLL feedback source */
-
-#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */
-#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */
-#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */
-
-#define PRIMAD_CPUDV_MASK 0x0F000000 /* CPU Clock Divisor Mask */
-#define PRIMAD_PLBDV_MASK 0x000F0000 /* PLB Clock Divisor Mask */
-#define PRIMAD_OPBDV_MASK 0x00000F00 /* OPB Clock Divisor Mask */
-#define PRIMAD_EBCDV_MASK 0x0000000F /* EBC Clock Divisor Mask */
-
-#define PERD0_PWMDV_MASK 0xFF000000 /* PWM Divider Mask */
-#define PERD0_SPIDV_MASK 0x000F0000 /* SPI Divider Mask */
-#define PERD0_U0DV_MASK 0x0000FF00 /* UART 0 Divider Mask */
-#define PERD0_U1DV_MASK 0x000000FF /* UART 1 Divider Mask */
-
-static void get_clocks(void)
-{
- unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i;
- unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv;
- unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB;
- unsigned long div; /* total divisor udiv * bdiv */
- unsigned long umin; /* minimum udiv */
- unsigned short diff; /* smallest diff */
- unsigned long udiv; /* best udiv */
- unsigned short idiff; /* current diff */
- unsigned short ibdiv; /* current bdiv */
- unsigned long est; /* current estimate */
- unsigned long baud;
- void *np;
-
- /* read the sysclk value from the CPLD */
- sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000;
-
- /*
- * Read PLL Mode registers
- */
- cpr_plld = CPR0_READ(DCRN_CPR0_PLLD);
- cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC);
-
- /*
- * Determine forward divider A
- */
- pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
-
- /*
- * Determine forward divider B
- */
- pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
- if (pllFwdDivB == 0)
- pllFwdDivB = 8;
-
- /*
- * Determine FBK_DIV.
- */
- pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
- if (pllFbkDiv == 0)
- pllFbkDiv = 256;
-
- /*
- * Read CPR_PRIMAD register
- */
- cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD);
-
- /*
- * Determine PLB_DIV.
- */
- pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
- if (pllPlbDiv == 0)
- pllPlbDiv = 16;
-
- /*
- * Determine EXTBUS_DIV.
- */
- pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
- if (pllExtBusDiv == 0)
- pllExtBusDiv = 16;
-
- /*
- * Determine OPB_DIV.
- */
- pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
- if (pllOpbDiv == 0)
- pllOpbDiv = 16;
-
- /* There is a bug in U-Boot that prevents us from using
- * bd.bi_opbfreq because U-Boot doesn't populate it for
- * 405EZ. We get to calculate it, yay!
- */
- freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv;
-
- freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv;
-
- plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ?
- pllFwdDivB : pllFwdDiv) *
- pllFbkDiv) / pllFwdDivB);
-
- np = find_node_by_alias("serial0");
- if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud))
- fatal("no current-speed property\n\r");
-
- udiv = 256; /* Assume lowest possible serial clk */
- div = plloutb / (16 * baud); /* total divisor */
- umin = (plloutb / freqOPB) << 1; /* 2 x OPB divisor */
- diff = 256; /* highest possible */
-
- /* i is the test udiv value -- start with the largest
- * possible (256) to minimize serial clock and constrain
- * search to umin.
- */
- for (i = 256; i > umin; i--) {
- ibdiv = div / i;
- est = i * ibdiv;
- idiff = (est > div) ? (est-div) : (div-est);
- if (idiff == 0) {
- udiv = i;
- break; /* can't do better */
- } else if (idiff < diff) {
- udiv = i; /* best so far */
- diff = idiff; /* update lowest diff*/
- }
- }
- freqUART = plloutb / udiv;
-
- dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq);
- dt_fixup_clock("/plb/ebc", freqEBC);
- dt_fixup_clock("/plb/opb", freqOPB);
- dt_fixup_clock("/plb/opb/serial@ef600300", freqUART);
- dt_fixup_clock("/plb/opb/serial@ef600400", freqUART);
-}
-
-static void acadia_fixups(void)
-{
- dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
- get_clocks();
- dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
-}
-
-void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
- CUBOOT_INIT();
- platform_ops.fixups = acadia_fixups;
- platform_ops.exit = ibm40x_dbcr_reset;
- fdt_init(_dtb_start);
- serial_console_init();
-}
diff --git a/arch/powerpc/boot/cuboot-hotfoot.c b/arch/powerpc/boot/cuboot-hotfoot.c
deleted file mode 100644
index 0e5532f855d6..000000000000
--- a/arch/powerpc/boot/cuboot-hotfoot.c
+++ /dev/null
@@ -1,139 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Old U-boot compatibility for Esteem 195E Hotfoot CPU Board
- *
- * Author: Solomon Peachy <solomon@linux-wlan.com>
- */
-
-#include "ops.h"
-#include "stdio.h"
-#include "reg.h"
-#include "dcr.h"
-#include "4xx.h"
-#include "cuboot.h"
-
-#define TARGET_4xx
-#define TARGET_HOTFOOT
-
-#include "ppcboot-hotfoot.h"
-
-static bd_t bd;
-
-#define NUM_REGS 3
-
-static void hotfoot_fixups(void)
-{
- u32 uart = mfdcr(DCRN_CPC0_UCR) & 0x7f;
-
- dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
-
- dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_procfreq, 0);
- dt_fixup_clock("/plb", bd.bi_plb_busfreq);
- dt_fixup_clock("/plb/opb", bd.bi_opbfreq);
- dt_fixup_clock("/plb/ebc", bd.bi_pci_busfreq);
- dt_fixup_clock("/plb/opb/serial@ef600300", bd.bi_procfreq / uart);
- dt_fixup_clock("/plb/opb/serial@ef600400", bd.bi_procfreq / uart);
-
- dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
- dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
-
- /* Is this a single eth/serial board? */
- if ((bd.bi_enet1addr[0] == 0) &&
- (bd.bi_enet1addr[1] == 0) &&
- (bd.bi_enet1addr[2] == 0) &&
- (bd.bi_enet1addr[3] == 0) &&
- (bd.bi_enet1addr[4] == 0) &&
- (bd.bi_enet1addr[5] == 0)) {
- void *devp;
-
- printf("Trimming devtree for single serial/eth board\n");
-
- devp = finddevice("/plb/opb/serial@ef600300");
- if (!devp)
- fatal("Can't find node for /plb/opb/serial@ef600300");
- del_node(devp);
-
- devp = finddevice("/plb/opb/ethernet@ef600900");
- if (!devp)
- fatal("Can't find node for /plb/opb/ethernet@ef600900");
- del_node(devp);
- }
-
- ibm4xx_quiesce_eth((u32 *)0xef600800, (u32 *)0xef600900);
-
- /* Fix up flash size in fdt for 4M boards. */
- if (bd.bi_flashsize < 0x800000) {
- u32 regs[NUM_REGS];
- void *devp = finddevice("/plb/ebc/nor_flash@0");
- if (!devp)
- fatal("Can't find FDT node for nor_flash!??");
-
- printf("Fixing devtree for 4M Flash\n");
-
- /* First fix up the base address */
- getprop(devp, "reg", regs, sizeof(regs));
- regs[0] = 0;
- regs[1] = 0xffc00000;
- regs[2] = 0x00400000;
- setprop(devp, "reg", regs, sizeof(regs));
-
- /* Then the offsets */
- devp = finddevice("/plb/ebc/nor_flash@0/partition@0");
- if (!devp)
- fatal("Can't find FDT node for partition@0");
- getprop(devp, "reg", regs, 2*sizeof(u32));
- regs[0] -= 0x400000;
- setprop(devp, "reg", regs, 2*sizeof(u32));
-
- devp = finddevice("/plb/ebc/nor_flash@0/partition@1");
- if (!devp)
- fatal("Can't find FDT node for partition@1");
- getprop(devp, "reg", regs, 2*sizeof(u32));
- regs[0] -= 0x400000;
- setprop(devp, "reg", regs, 2*sizeof(u32));
-
- devp = finddevice("/plb/ebc/nor_flash@0/partition@2");
- if (!devp)
- fatal("Can't find FDT node for partition@2");
- getprop(devp, "reg", regs, 2*sizeof(u32));
- regs[0] -= 0x400000;
- setprop(devp, "reg", regs, 2*sizeof(u32));
-
- devp = finddevice("/plb/ebc/nor_flash@0/partition@3");
- if (!devp)
- fatal("Can't find FDT node for partition@3");
- getprop(devp, "reg", regs, 2*sizeof(u32));
- regs[0] -= 0x400000;
- setprop(devp, "reg", regs, 2*sizeof(u32));
-
- devp = finddevice("/plb/ebc/nor_flash@0/partition@4");
- if (!devp)
- fatal("Can't find FDT node for partition@4");
- getprop(devp, "reg", regs, 2*sizeof(u32));
- regs[0] -= 0x400000;
- setprop(devp, "reg", regs, 2*sizeof(u32));
-
- devp = finddevice("/plb/ebc/nor_flash@0/partition@6");
- if (!devp)
- fatal("Can't find FDT node for partition@6");
- getprop(devp, "reg", regs, 2*sizeof(u32));
- regs[0] -= 0x400000;
- setprop(devp, "reg", regs, 2*sizeof(u32));
-
- /* Delete the FeatFS node */
- devp = finddevice("/plb/ebc/nor_flash@0/partition@5");
- if (!devp)
- fatal("Can't find FDT node for partition@5");
- del_node(devp);
- }
-}
-
-void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
- CUBOOT_INIT();
- platform_ops.fixups = hotfoot_fixups;
- platform_ops.exit = ibm40x_dbcr_reset;
- fdt_init(_dtb_start);
- serial_console_init();
-}
diff --git a/arch/powerpc/boot/cuboot-kilauea.c b/arch/powerpc/boot/cuboot-kilauea.c
deleted file mode 100644
index fda182f518a2..000000000000
--- a/arch/powerpc/boot/cuboot-kilauea.c
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Old U-boot compatibility for PPC405EX. This image is already included
- * a dtb.
- *
- * Author: Tiejun Chen <tiejun.chen@windriver.com>
- *
- * Copyright (C) 2009 Wind River Systems, Inc.
- */
-
-#include "ops.h"
-#include "io.h"
-#include "dcr.h"
-#include "stdio.h"
-#include "4xx.h"
-#include "44x.h"
-#include "cuboot.h"
-
-#define TARGET_4xx
-#define TARGET_44x
-#include "ppcboot.h"
-
-#define KILAUEA_SYS_EXT_SERIAL_CLOCK 11059200 /* ext. 11.059MHz clk */
-
-static bd_t bd;
-
-static void kilauea_fixups(void)
-{
- unsigned long sysclk = 33333333;
-
- ibm405ex_fixup_clocks(sysclk, KILAUEA_SYS_EXT_SERIAL_CLOCK);
- dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
- ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
- dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
- dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
-}
-
-void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
- CUBOOT_INIT();
- platform_ops.fixups = kilauea_fixups;
- platform_ops.exit = ibm40x_dbcr_reset;
- fdt_init(_dtb_start);
- serial_console_init();
-}
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
index 334ab8b5a668..91dc3a302cc8 100644
--- a/arch/powerpc/boot/dcr.h
+++ b/arch/powerpc/boot/dcr.h
@@ -153,17 +153,6 @@ static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR,
#define CPR0_SCPID 0x120
#define CPR0_PLLC0 0x40
-/* 405GP Clocking/Power Management/Chip Control regs */
-#define DCRN_CPC0_PLLMR 0xb0
-#define DCRN_405_CPC0_CR0 0xb1
-#define DCRN_405_CPC0_CR1 0xb2
-#define DCRN_405_CPC0_PSR 0xb4
-
-/* 405EP Clocking/Power Management/Chip Control regs */
-#define DCRN_CPC0_PLLMR0 0xf0
-#define DCRN_CPC0_PLLMR1 0xf4
-#define DCRN_CPC0_UCR 0xf5
-
/* 440GX/405EX Clock Control reg */
#define DCRN_CPR0_CLKUPD 0x020
#define DCRN_CPR0_PLLC 0x040
diff --git a/arch/powerpc/boot/decompress.c b/arch/powerpc/boot/decompress.c
index 977eb15a6d17..6835cb53f034 100644
--- a/arch/powerpc/boot/decompress.c
+++ b/arch/powerpc/boot/decompress.c
@@ -101,7 +101,7 @@ static void print_err(char *s)
* @input_size: length of the input buffer
* @outbuf: output buffer
* @output_size: length of the output buffer
- * @skip number of output bytes to ignore
+ * @_skip: number of output bytes to ignore
*
* This function takes compressed data from inbuf, decompresses and write it to
* outbuf. Once output_size bytes are written to the output buffer, or the
diff --git a/arch/powerpc/boot/dts/Makefile b/arch/powerpc/boot/dts/Makefile
index fb335d05aae8..0cd0d8558b47 100644
--- a/arch/powerpc/boot/dts/Makefile
+++ b/arch/powerpc/boot/dts/Makefile
@@ -2,5 +2,4 @@
subdir-y += fsl
-dtstree := $(srctree)/$(src)
-dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts))
diff --git a/arch/powerpc/boot/dts/acadia.dts b/arch/powerpc/boot/dts/acadia.dts
deleted file mode 100644
index deb52e41ab84..000000000000
--- a/arch/powerpc/boot/dts/acadia.dts
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Device Tree Source for AMCC Acadia (405EZ)
- *
- * Copyright IBM Corp. 2008
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "amcc,acadia";
- compatible = "amcc,acadia";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- serial0 = &UART0;
- serial1 = &UART1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,405EZ";
- reg = <0x0>;
- clock-frequency = <0>; /* Filled in by wrapper */
- timebase-frequency = <0>; /* Filled in by wrapper */
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <16384>;
- d-cache-size = <16384>;
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x0>; /* Filled in by wrapper */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic-405ez", "ibm,uic";
- interrupt-controller;
- dcr-reg = <0x0c0 0x009>;
- cell-index = <0>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- plb {
- compatible = "ibm,plb-405ez", "ibm,plb3";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by wrapper */
-
- MAL0: mcmal {
- compatible = "ibm,mcmal-405ez", "ibm,mcmal";
- dcr-reg = <0x380 0x62>;
- num-tx-chans = <1>;
- num-rx-chans = <1>;
- interrupt-parent = <&UIC0>;
- /* 405EZ has only 3 interrupts to the UIC, as
- * SERR, TXDE, and RXDE are or'd together into
- * one UIC bit
- */
- interrupts = <
- 0x13 0x4 /* TXEOB */
- 0x15 0x4 /* RXEOB */
- 0x12 0x4 /* SERR, TXDE, RXDE */>;
- };
-
- POB0: opb {
- compatible = "ibm,opb-405ez", "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- dcr-reg = <0x0a 0x05>;
- clock-frequency = <0>; /* Filled in by wrapper */
-
- UART0: serial@ef600300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600300 0x8>;
- virtual-reg = <0xef600300>;
- clock-frequency = <0>; /* Filled in by wrapper */
- current-speed = <115200>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x5 0x4>;
- };
-
- UART1: serial@ef600400 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600400 0x8>;
- clock-frequency = <0>; /* Filled in by wrapper */
- current-speed = <115200>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x6 0x4>;
- };
-
- IIC: i2c@ef600500 {
- compatible = "ibm,iic-405ez", "ibm,iic";
- reg = <0xef600500 0x11>;
- interrupt-parent = <&UIC0>;
- interrupts = <0xa 0x4>;
- };
-
- GPIO0: gpio@ef600700 {
- compatible = "ibm,gpio-405ez";
- reg = <0xef600700 0x20>;
- };
-
- GPIO1: gpio@ef600800 {
- compatible = "ibm,gpio-405ez";
- reg = <0xef600800 0x20>;
- };
-
- EMAC0: ethernet@ef600900 {
- device_type = "network";
- compatible = "ibm,emac-405ez", "ibm,emac";
- interrupt-parent = <&UIC0>;
- interrupts = <
- 0x10 0x4 /* Ethernet */
- 0x11 0x4 /* Ethernet Wake up */>;
- local-mac-address = [000000000000]; /* Filled in by wrapper */
- reg = <0xef600900 0x70>;
- mal-device = <&MAL0>;
- mal-tx-channel = <0>;
- mal-rx-channel = <0>;
- cell-index = <0>;
- max-frame-size = <1500>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- phy-mode = "mii";
- phy-map = <0x0>;
- };
-
- CAN0: can@ef601000 {
- compatible = "amcc,can-405ez";
- reg = <0xef601000 0x620>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x7 0x4>;
- };
-
- CAN1: can@ef601800 {
- compatible = "amcc,can-405ez";
- reg = <0xef601800 0x620>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x8 0x4>;
- };
-
- cameleon@ef602000 {
- compatible = "amcc,cameleon-405ez";
- reg = <0xef602000 0x800>;
- interrupt-parent = <&UIC0>;
- interrupts = <0xb 0x4 0xc 0x4>;
- };
-
- ieee1588@ef602800 {
- compatible = "amcc,ieee1588-405ez";
- reg = <0xef602800 0x60>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x4 0x4>;
- /* This thing is a bit weird. It has it's own UIC
- * that it uses to generate snapshot triggers. We
- * don't really support this device yet, and it needs
- * work to figure this out.
- */
- dcr-reg = <0xe0 0x9>;
- };
-
- usb@ef603000 {
- compatible = "ohci-be";
- reg = <0xef603000 0x80>;
- interrupt-parent = <&UIC0>;
- interrupts = <0xd 0x4 0xe 0x4>;
- };
-
- dac@ef603300 {
- compatible = "amcc,dac-405ez";
- reg = <0xef603300 0x40>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x18 0x4>;
- };
-
- adc@ef603400 {
- compatible = "amcc,adc-405ez";
- reg = <0xef603400 0x40>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x17 0x4>;
- };
-
- spi@ef603500 {
- compatible = "amcc,spi-405ez";
- reg = <0xef603500 0x100>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x9 0x4>;
- };
- };
-
- EBC0: ebc {
- compatible = "ibm,ebc-405ez", "ibm,ebc";
- dcr-reg = <0x12 0x2>;
- #address-cells = <2>;
- #size-cells = <1>;
- clock-frequency = <0>; /* Filled in by wrapper */
- };
- };
-
- chosen {
- stdout-path = "/plb/opb/serial@ef600300";
- };
-};
diff --git a/arch/powerpc/boot/dts/fsl/Makefile b/arch/powerpc/boot/dts/fsl/Makefile
index 3bae982641e9..d3ecdf14bc42 100644
--- a/arch/powerpc/boot/dts/fsl/Makefile
+++ b/arch/powerpc/boot/dts/fsl/Makefile
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-dtstree := $(srctree)/$(src)
-dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts))
diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
index 4f044b41a776..fb3200b006ad 100644
--- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
@@ -50,7 +50,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <25 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts
index 8da984251abc..0ba86a6dce1b 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts
@@ -15,7 +15,7 @@
device_type = "memory";
};
- board_ifc: ifc: ifc@ff71e000 {
+ board_ifc: ifc: memory-controller@ff71e000 {
/* NAND Flash on board */
ranges = <0x0 0x0 0x0 0xff800000 0x00004000>;
reg = <0x0 0xff71e000 0x0 0x2000>;
diff --git a/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi
index 2a677fd323eb..5c53cee8755f 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi
@@ -35,7 +35,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <16 2 0 0 20 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dts b/arch/powerpc/boot/dts/fsl/bsc9132qds.dts
index 7cb2158dfe58..ce642e879a1b 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9132qds.dts
+++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dts
@@ -15,7 +15,7 @@
device_type = "memory";
};
- ifc: ifc@ff71e000 {
+ ifc: memory-controller@ff71e000 {
/* NOR, NAND Flash on board */
ranges = <0x0 0x0 0x0 0x88000000 0x08000000
0x1 0x0 0x0 0xff800000 0x00010000>;
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi
index b8e0edd1ac69..4da451e000d9 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi
@@ -35,7 +35,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
/* FIXME: Test whether interrupts are split */
interrupts = <16 2 0 0 20 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/c293pcie.dts b/arch/powerpc/boot/dts/fsl/c293pcie.dts
index 5e905e0857cf..e2fdac2ed420 100644
--- a/arch/powerpc/boot/dts/fsl/c293pcie.dts
+++ b/arch/powerpc/boot/dts/fsl/c293pcie.dts
@@ -42,7 +42,7 @@
device_type = "memory";
};
- ifc: ifc@fffe1e000 {
+ ifc: memory-controller@fffe1e000 {
reg = <0xf 0xffe1e000 0 0x2000>;
ranges = <0x0 0x0 0xf 0xec000000 0x04000000
0x1 0x0 0xf 0xff800000 0x00010000
diff --git a/arch/powerpc/boot/dts/fsl/c293si-post.dtsi b/arch/powerpc/boot/dts/fsl/c293si-post.dtsi
index f208fb8f64b3..2d443d519274 100644
--- a/arch/powerpc/boot/dts/fsl/c293si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/c293si-post.dtsi
@@ -35,7 +35,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <19 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
index 41935709ebe8..fba40a1bccc0 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
@@ -199,6 +199,10 @@
/include/ "pq3-dma-0.dtsi"
/include/ "pq3-etsec1-0.dtsi"
+ enet0: ethernet@24000 {
+ fsl,wake-on-filer;
+ fsl,pmc-handle = <&etsec1_clk>;
+ };
/include/ "pq3-etsec1-timer-0.dtsi"
usb@22000 {
@@ -222,9 +226,10 @@
};
/include/ "pq3-etsec1-2.dtsi"
-
- ethernet@26000 {
+ enet2: ethernet@26000 {
cell-index = <1>;
+ fsl,wake-on-filer;
+ fsl,pmc-handle = <&etsec3_clk>;
};
usb@2b000 {
@@ -249,4 +254,9 @@
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
+ power@e0070 {
+ compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc";
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi
index b68eb119faef..ea7416af7ee3 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi
@@ -188,4 +188,6 @@
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi
index 579d76cb8e32..dddb7374508d 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi
@@ -156,4 +156,6 @@
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
index 49294cf36b4e..40a6cff77032 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
@@ -193,4 +193,6 @@
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
};
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts b/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts
index 3a94acbb3c03..ce3346d77858 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts
@@ -29,3 +29,19 @@
};
/include/ "p1010si-post.dtsi"
+
+&pci0 {
+ pcie@0 {
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ /*
+ *irq[4:5] are active-high
+ *irq[6:7] are active-low
+ */
+ 0000 0x0 0x0 0x1 &mpic 0x4 0x2 0x0 0x0
+ 0000 0x0 0x0 0x2 &mpic 0x5 0x2 0x0 0x0
+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0
+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0
+ >;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts b/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts
index 4cf255fedc96..83590354f9a0 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts
@@ -56,3 +56,19 @@
};
/include/ "p1010si-post.dtsi"
+
+&pci0 {
+ pcie@0 {
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ /*
+ *irq[4:5] are active-high
+ *irq[6:7] are active-low
+ */
+ 0000 0x0 0x0 0x1 &mpic 0x4 0x2 0x0 0x0
+ 0000 0x0 0x0 0x2 &mpic 0x5 0x2 0x0 0x0
+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0
+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0
+ >;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
index 2ca9cee2ddeb..ef49a7d6c69d 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
@@ -215,19 +215,3 @@
phy-connection-type = "sgmii";
};
};
-
-&pci0 {
- pcie@0 {
- interrupt-map = <
- /* IDSEL 0x0 */
- /*
- *irq[4:5] are active-high
- *irq[6:7] are active-low
- */
- 0000 0x0 0x0 0x1 &mpic 0x4 0x2 0x0 0x0
- 0000 0x0 0x0 0x2 &mpic 0x5 0x2 0x0 0x0
- 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0
- 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0
- >;
- };
-};
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi
index fdc19aab2f70..583a6cd05079 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi
@@ -36,7 +36,7 @@ memory {
device_type = "memory";
};
-board_ifc: ifc: ifc@ffe1e000 {
+board_ifc: ifc: memory-controller@ffe1e000 {
/* NOR, NAND Flashes and CPLD on board */
ranges = <0x0 0x0 0x0 0xee000000 0x02000000
0x1 0x0 0x0 0xff800000 0x00010000
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi
index de2fceed4f79..4d41efe0038f 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi
@@ -36,7 +36,7 @@ memory {
device_type = "memory";
};
-board_ifc: ifc: ifc@fffe1e000 {
+board_ifc: ifc: memory-controller@fffe1e000 {
/* NOR, NAND Flashes and CPLD on board */
ranges = <0x0 0x0 0xf 0xee000000 0x02000000
0x1 0x0 0xf 0xff800000 0x00010000
diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
index ccda0a91abf0..2d2550729dcc 100644
--- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
@@ -35,7 +35,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <16 2 0 0 19 2 0 0>;
};
@@ -183,9 +183,23 @@
/include/ "pq3-etsec2-1.dtsi"
/include/ "pq3-etsec2-2.dtsi"
+ enet0: ethernet@b0000 {
+ fsl,pmc-handle = <&etsec1_clk>;
+ };
+
+ enet1: ethernet@b1000 {
+ fsl,pmc-handle = <&etsec2_clk>;
+ };
+
+ enet2: ethernet@b2000 {
+ fsl,pmc-handle = <&etsec3_clk>;
+ };
+
global-utilities@e0000 {
compatible = "fsl,p1010-guts";
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
};
diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
index 642dc3a83d0e..cc4c7461003b 100644
--- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
@@ -163,14 +163,17 @@
/include/ "pq3-etsec2-0.dtsi"
enet0: enet0_grp2: ethernet@b0000 {
+ fsl,pmc-handle = <&etsec1_clk>;
};
/include/ "pq3-etsec2-1.dtsi"
enet1: enet1_grp2: ethernet@b1000 {
+ fsl,pmc-handle = <&etsec2_clk>;
};
/include/ "pq3-etsec2-2.dtsi"
enet2: enet2_grp2: ethernet@b2000 {
+ fsl,pmc-handle = <&etsec3_clk>;
};
global-utilities@e0000 {
@@ -178,6 +181,8 @@
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
};
/include/ "pq3-etsec2-grp2-0.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi
index 407cb5fd0f5b..378195db9fca 100644
--- a/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi
@@ -159,14 +159,17 @@
/include/ "pq3-etsec2-0.dtsi"
enet0: enet0_grp2: ethernet@b0000 {
+ fsl,pmc-handle = <&etsec1_clk>;
};
/include/ "pq3-etsec2-1.dtsi"
enet1: enet1_grp2: ethernet@b1000 {
+ fsl,pmc-handle = <&etsec2_clk>;
};
/include/ "pq3-etsec2-2.dtsi"
enet2: enet2_grp2: ethernet@b2000 {
+ fsl,pmc-handle = <&etsec3_clk>;
};
global-utilities@e0000 {
@@ -174,6 +177,8 @@
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
+
+/include/ "pq3-power.dtsi"
};
&qe {
diff --git a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
index 093e4e3ed368..6ac21e81344a 100644
--- a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
@@ -225,11 +225,13 @@
/include/ "pq3-etsec2-0.dtsi"
enet0: enet0_grp2: ethernet@b0000 {
fsl,wake-on-filer;
+ fsl,pmc-handle = <&etsec1_clk>;
};
/include/ "pq3-etsec2-1.dtsi"
enet1: enet1_grp2: ethernet@b1000 {
fsl,wake-on-filer;
+ fsl,pmc-handle = <&etsec2_clk>;
};
global-utilities@e0000 {
@@ -238,9 +240,10 @@
fsl,has-rstcr;
};
+/include/ "pq3-power.dtsi"
power@e0070 {
- compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc";
- reg = <0xe0070 0x20>;
+ compatible = "fsl,p1022-pmc", "fsl,mpc8536-pmc",
+ "fsl,mpc8548-pmc";
};
};
diff --git a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
index 81b9ab2119be..d410082d21c0 100644
--- a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
@@ -178,6 +178,10 @@
compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr";
};
/include/ "pq3-etsec1-0.dtsi"
+ enet0: ethernet@24000 {
+ fsl,pmc-handle = <&etsec1_clk>;
+
+ };
/include/ "pq3-etsec1-timer-0.dtsi"
ptp_clock@24e00 {
@@ -186,7 +190,15 @@
/include/ "pq3-etsec1-1.dtsi"
+ enet1: ethernet@25000 {
+ fsl,pmc-handle = <&etsec2_clk>;
+ };
+
/include/ "pq3-etsec1-2.dtsi"
+ enet2: ethernet@26000 {
+ fsl,pmc-handle = <&etsec3_clk>;
+ };
+
/include/ "pq3-esdhc-0.dtsi"
sdhc@2e000 {
compatible = "fsl,p2020-esdhc", "fsl,esdhc";
@@ -202,8 +214,5 @@
fsl,has-rstcr;
};
- pmc: power@e0070 {
- compatible = "fsl,mpc8548-pmc";
- reg = <0xe0070 0x20>;
- };
+/include/ "pq3-power.dtsi"
};
diff --git a/arch/powerpc/boot/dts/fsl/pq3-power.dtsi b/arch/powerpc/boot/dts/fsl/pq3-power.dtsi
new file mode 100644
index 000000000000..6af12401004d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/pq3-power.dtsi
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+/*
+ * Copyright 2024 NXP
+ */
+
+power@e0070 {
+ compatible = "fsl,mpc8548-pmc";
+ reg = <0xe0070 0x20>;
+
+ etsec1_clk: soc-clk@24 {
+ fsl,pmcdr-mask = <0x00000080>;
+ };
+ etsec2_clk: soc-clk@25 {
+ fsl,pmcdr-mask = <0x00000040>;
+ };
+ etsec3_clk: soc-clk@26 {
+ fsl,pmcdr-mask = <0x00000020>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
index aa5152ca8120..8ef0c020206b 100644
--- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
@@ -52,7 +52,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <25 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts
index 270aaf631f2a..7d003e07a9fb 100644
--- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts
@@ -91,7 +91,7 @@
board-control@2,0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "fsl,t1024-cpld";
+ compatible = "fsl,t1024-cpld", "fsl,deepsleep-cpld";
reg = <3 0 0x300>;
ranges = <0 3 0 0x300>;
bank-width = <1>;
diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
index dd3aab81e9de..4347924e9aa7 100644
--- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
@@ -104,7 +104,7 @@
ifc: localbus@ffe124000 {
cpld@3,0 {
- compatible = "fsl,t1040rdb-cpld";
+ compatible = "fsl,t104xrdb-cpld", "fsl,deepsleep-cpld";
};
};
};
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 776788623204..c9542b73bd7f 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -52,7 +52,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <25 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
index 3ebb712224cb..099764322b33 100644
--- a/arch/powerpc/boot/dts/fsl/t1042rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
@@ -68,7 +68,7 @@
ifc: localbus@ffe124000 {
cpld@3,0 {
- compatible = "fsl,t1042rdb-cpld";
+ compatible = "fsl,t104xrdb-cpld", "fsl,deepsleep-cpld";
};
};
};
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
index 8ec3ff45e6fc..b10cab1a347b 100644
--- a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
@@ -41,7 +41,7 @@
ifc: localbus@ffe124000 {
cpld@3,0 {
- compatible = "fsl,t1042rdb_pi-cpld";
+ compatible = "fsl,t104xrdb-cpld", "fsl,deepsleep-cpld";
};
};
diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
index 27714dc2f04a..6bb95878d39d 100644
--- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -50,7 +50,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <25 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index fcac73486d48..65f3e17c0d41 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -50,7 +50,7 @@
&ifc {
#address-cells = <2>;
#size-cells = <1>;
- compatible = "fsl,ifc", "simple-bus";
+ compatible = "fsl,ifc";
interrupts = <25 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
deleted file mode 100644
index f81ce8786d59..000000000000
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Device Tree Source for AMCC Haleakala (405EXr)
- *
- * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without
- * any warranty of any kind, whether express or implied.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "amcc,haleakala";
- compatible = "amcc,haleakala", "amcc,kilauea";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- serial0 = &UART0;
- serial1 = &UART1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,405EXr";
- reg = <0x00000000>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- timebase-frequency = <0>; /* Filled in by U-Boot */
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <16384>; /* 16 kB */
- d-cache-size = <16384>; /* 16 kB */
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic-405exr", "ibm,uic";
- interrupt-controller;
- cell-index = <0>;
- dcr-reg = <0x0c0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- UIC1: interrupt-controller1 {
- compatible = "ibm,uic-405exr","ibm,uic";
- interrupt-controller;
- cell-index = <1>;
- dcr-reg = <0x0d0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- UIC2: interrupt-controller2 {
- compatible = "ibm,uic-405exr","ibm,uic";
- interrupt-controller;
- cell-index = <2>;
- dcr-reg = <0x0e0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- plb {
- compatible = "ibm,plb-405exr", "ibm,plb4";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- SDRAM0: memory-controller {
- compatible = "ibm,sdram-405exr", "ibm,sdram-4xx-ddr2";
- dcr-reg = <0x010 0x002>;
- interrupt-parent = <&UIC2>;
- interrupts = <0x5 0x4 /* ECC DED Error */
- 0x6 0x4>; /* ECC SEC Error */
- };
-
- MAL0: mcmal {
- compatible = "ibm,mcmal-405exr", "ibm,mcmal2";
- dcr-reg = <0x180 0x062>;
- num-tx-chans = <2>;
- num-rx-chans = <2>;
- interrupt-parent = <&MAL0>;
- interrupts = <0x0 0x1 0x2 0x3 0x4>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*TXEOB*/ 0x0 &UIC0 0xa 0x4
- /*RXEOB*/ 0x1 &UIC0 0xb 0x4
- /*SERR*/ 0x2 &UIC1 0x0 0x4
- /*TXDE*/ 0x3 &UIC1 0x1 0x4
- /*RXDE*/ 0x4 &UIC1 0x2 0x4>;
- interrupt-map-mask = <0xffffffff>;
- };
-
- POB0: opb {
- compatible = "ibm,opb-405exr", "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x80000000 0x80000000 0x10000000
- 0xef600000 0xef600000 0x00a00000
- 0xf0000000 0xf0000000 0x10000000>;
- dcr-reg = <0x0a0 0x005>;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- EBC0: ebc {
- compatible = "ibm,ebc-405exr", "ibm,ebc";
- dcr-reg = <0x012 0x002>;
- #address-cells = <2>;
- #size-cells = <1>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- /* ranges property is supplied by U-Boot */
- interrupts = <0x5 0x1>;
- interrupt-parent = <&UIC1>;
-
- nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
- bank-width = <2>;
- reg = <0x00000000 0x00000000 0x04000000>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0x00000000 0x00200000>;
- };
- partition@200000 {
- label = "root";
- reg = <0x00200000 0x00200000>;
- };
- partition@400000 {
- label = "user";
- reg = <0x00400000 0x03b60000>;
- };
- partition@3f60000 {
- label = "env";
- reg = <0x03f60000 0x00040000>;
- };
- partition@3fa0000 {
- label = "u-boot";
- reg = <0x03fa0000 0x00060000>;
- };
- };
- };
-
- UART0: serial@ef600200 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600200 0x00000008>;
- virtual-reg = <0xef600200>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1a 0x4>;
- };
-
- UART1: serial@ef600300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600300 0x00000008>;
- virtual-reg = <0xef600300>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1 0x4>;
- };
-
- IIC0: i2c@ef600400 {
- compatible = "ibm,iic-405exr", "ibm,iic";
- reg = <0xef600400 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x2 0x4>;
- };
-
- IIC1: i2c@ef600500 {
- compatible = "ibm,iic-405exr", "ibm,iic";
- reg = <0xef600500 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x7 0x4>;
- };
-
-
- RGMII0: emac-rgmii@ef600b00 {
- compatible = "ibm,rgmii-405exr", "ibm,rgmii";
- reg = <0xef600b00 0x00000104>;
- has-mdio;
- };
-
- EMAC0: ethernet@ef600900 {
- linux,network-index = <0x0>;
- device_type = "network";
- compatible = "ibm,emac-405exr", "ibm,emac4sync";
- interrupt-parent = <&EMAC0>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x18 0x4
- /*Wake*/ 0x1 &UIC1 0x1d 0x4>;
- reg = <0xef600900 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <0>;
- mal-rx-channel = <0>;
- cell-index = <0>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <0>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
- };
-
- PCIE0: pcie@a0000000 {
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
- primary;
- port = <0x0>; /* port number */
- reg = <0xa0000000 0x20000000 /* Config space access */
- 0xef000000 0x00001000>; /* Registers */
- dcr-reg = <0x040 0x020>;
- sdr-base = <0x400>;
-
- /* Outbound ranges, one memory and one IO,
- * later cannot be changed
- */
- ranges = <0x02000000 0x00000000 0x80000000 0x90000000 0x00000000 0x08000000
- 0x01000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00010000>;
-
- /* Inbound 2GB range starting at 0 */
- dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
-
- /* This drives busses 0x00 to 0x3f */
- bus-range = <0x0 0x3f>;
-
- /* Legacy interrupts (note the weird polarity, the bridge seems
- * to invert PCIe legacy interrupts).
- * We are de-swizzling here because the numbers are actually for
- * port of the root complex virtual P2P bridge. But I want
- * to avoid putting a node for it in the tree, so the numbers
- * below are basically de-swizzled numbers.
- * The real slot is on idsel 0, so the swizzling is 1:1
- */
- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0 0x0 0x0 0x1 &UIC2 0x0 0x4 /* swizzled int A */
- 0x0 0x0 0x0 0x2 &UIC2 0x1 0x4 /* swizzled int B */
- 0x0 0x0 0x0 0x3 &UIC2 0x2 0x4 /* swizzled int C */
- 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/hotfoot.dts b/arch/powerpc/boot/dts/hotfoot.dts
deleted file mode 100644
index b93bf2d9dd5b..000000000000
--- a/arch/powerpc/boot/dts/hotfoot.dts
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Device Tree Source for ESTeem 195E Hotfoot
- *
- * Copyright 2009 AbsoluteValue Systems <solomon@linux-wlan.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 kind, whether express or implied.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "est,hotfoot";
- compatible = "est,hotfoot";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- ethernet1 = &EMAC1;
- serial0 = &UART0;
- serial1 = &UART1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,405EP";
- reg = <0x00000000>;
- clock-frequency = <0>; /* Filled in by zImage */
- timebase-frequency = <0>; /* Filled in by zImage */
- i-cache-line-size = <0x20>;
- d-cache-line-size = <0x20>;
- i-cache-size = <0x4000>;
- d-cache-size = <0x4000>;
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x00000000>; /* Filled in by zImage */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic";
- interrupt-controller;
- cell-index = <0>;
- dcr-reg = <0x0c0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- plb {
- compatible = "ibm,plb3";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by zImage */
-
- SDRAM0: memory-controller {
- compatible = "ibm,sdram-405ep";
- dcr-reg = <0x010 0x002>;
- };
-
- MAL: mcmal {
- compatible = "ibm,mcmal-405ep", "ibm,mcmal";
- dcr-reg = <0x180 0x062>;
- num-tx-chans = <4>;
- num-rx-chans = <2>;
- interrupt-parent = <&UIC0>;
- interrupts = <
- 0xb 0x4 /* TXEOB */
- 0xc 0x4 /* RXEOB */
- 0xa 0x4 /* SERR */
- 0xd 0x4 /* TXDE */
- 0xe 0x4 /* RXDE */>;
- };
-
- POB0: opb {
- compatible = "ibm,opb-405ep", "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xef600000 0xef600000 0x00a00000>;
- dcr-reg = <0x0a0 0x005>;
- clock-frequency = <0>; /* Filled in by zImage */
-
- /* Hotfoot has UART0/UART1 swapped */
-
- UART0: serial@ef600400 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600400 0x00000008>;
- virtual-reg = <0xef600400>;
- clock-frequency = <0>; /* Filled in by zImage */
- current-speed = <0x9600>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1 0x4>;
- };
-
- UART1: serial@ef600300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600300 0x00000008>;
- virtual-reg = <0xef600300>;
- clock-frequency = <0>; /* Filled in by zImage */
- current-speed = <0x9600>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x0 0x4>;
- };
-
- IIC: i2c@ef600500 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "ibm,iic-405ep", "ibm,iic";
- reg = <0xef600500 0x00000011>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x2 0x4>;
-
- rtc@68 {
- /* Actually a DS1339 */
- compatible = "dallas,ds1307";
- reg = <0x68>;
- };
-
- temp@4a {
- /* Not present on all boards */
- compatible = "national,lm75";
- reg = <0x4a>;
- };
- };
-
- GPIO: gpio@ef600700 {
- #gpio-cells = <2>;
- compatible = "ibm,ppc4xx-gpio";
- reg = <0xef600700 0x00000020>;
- gpio-controller;
- };
-
- gpio-leds {
- compatible = "gpio-leds";
- status {
- label = "Status";
- gpios = <&GPIO 1 0>;
- };
- radiorx {
- label = "Rx";
- gpios = <&GPIO 0xe 0>;
- };
- };
-
- EMAC0: ethernet@ef600800 {
- linux,network-index = <0x0>;
- device_type = "network";
- compatible = "ibm,emac-405ep", "ibm,emac";
- interrupt-parent = <&UIC0>;
- interrupts = <
- 0xf 0x4 /* Ethernet */
- 0x9 0x4 /* Ethernet Wake Up */>;
- local-mac-address = [000000000000]; /* Filled in by zImage */
- reg = <0xef600800 0x00000070>;
- mal-device = <&MAL>;
- mal-tx-channel = <0>;
- mal-rx-channel = <0>;
- cell-index = <0>;
- max-frame-size = <0x5dc>;
- rx-fifo-size = <0x1000>;
- tx-fifo-size = <0x800>;
- phy-mode = "mii";
- phy-map = <0x00000000>;
- };
-
- EMAC1: ethernet@ef600900 {
- linux,network-index = <0x1>;
- device_type = "network";
- compatible = "ibm,emac-405ep", "ibm,emac";
- interrupt-parent = <&UIC0>;
- interrupts = <
- 0x11 0x4 /* Ethernet */
- 0x9 0x4 /* Ethernet Wake Up */>;
- local-mac-address = [000000000000]; /* Filled in by zImage */
- reg = <0xef600900 0x00000070>;
- mal-device = <&MAL>;
- mal-tx-channel = <2>;
- mal-rx-channel = <1>;
- cell-index = <1>;
- max-frame-size = <0x5dc>;
- rx-fifo-size = <0x1000>;
- tx-fifo-size = <0x800>;
- mdio-device = <&EMAC0>;
- phy-mode = "mii";
- phy-map = <0x0000001>;
- };
- };
-
- EBC0: ebc {
- compatible = "ibm,ebc-405ep", "ibm,ebc";
- dcr-reg = <0x012 0x002>;
- #address-cells = <2>;
- #size-cells = <1>;
-
- /* The ranges property is supplied by the bootwrapper
- * and is based on the firmware's configuration of the
- * EBC bridge
- */
- clock-frequency = <0>; /* Filled in by zImage */
-
- nor_flash@0 {
- compatible = "cfi-flash";
- bank-width = <2>;
- reg = <0x0 0xff800000 0x00800000>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- /* This mapping is for the 8M flash
- 4M flash has all ofssets -= 4M,
- and FeatFS partition is not present */
- partition@0 {
- label = "Bootloader";
- reg = <0x7c0000 0x40000>;
- /* read-only; */
- };
- partition@1 {
- label = "Env_and_Config_Primary";
- reg = <0x400000 0x10000>;
- };
- partition@2 {
- label = "Kernel";
- reg = <0x420000 0x100000>;
- };
- partition@3 {
- label = "Filesystem";
- reg = <0x520000 0x2a0000>;
- };
- partition@4 {
- label = "Env_and_Config_Secondary";
- reg = <0x410000 0x10000>;
- };
- partition@5 {
- label = "FeatFS";
- reg = <0x000000 0x400000>;
- };
- partition@6 {
- label = "Bootloader_Env";
- reg = <0x7d0000 0x10000>;
- };
- };
- };
-
- PCI0: pci@ec000000 {
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "ibm,plb405ep-pci", "ibm,plb-pci";
- primary;
- reg = <0xeec00000 0x00000008 /* Config space access */
- 0xeed80000 0x00000004 /* IACK */
- 0xeed80000 0x00000004 /* Special cycle */
- 0xef480000 0x00000040>; /* Internal registers */
-
- /* Outbound ranges, one memory and one IO,
- * later cannot be changed. Chip supports a second
- * IO range but we don't use it for now
- */
- ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000
- 0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
-
- /* Inbound 2GB range starting at 0 */
- dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
-
- interrupt-parent = <&UIC0>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- /* IDSEL 3 -- slot1 (optional) 27/29 A/B IRQ2/4 */
- 0x1800 0x0 0x0 0x1 &UIC0 0x1b 0x8
- 0x1800 0x0 0x0 0x2 &UIC0 0x1d 0x8
-
- /* IDSEL 4 -- slot0, 26/28 A/B IRQ1/3 */
- 0x2000 0x0 0x0 0x1 &UIC0 0x1a 0x8
- 0x2000 0x0 0x0 0x2 &UIC0 0x1c 0x8
- >;
- };
- };
-
- chosen {
- stdout-path = &UART0;
- };
-};
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
deleted file mode 100644
index c07a7525a72c..000000000000
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Device Tree Source for AMCC Kilauea (405EX)
- *
- * Copyright 2007-2009 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without
- * any warranty of any kind, whether express or implied.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "amcc,kilauea";
- compatible = "amcc,kilauea";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- ethernet1 = &EMAC1;
- serial0 = &UART0;
- serial1 = &UART1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,405EX";
- reg = <0x00000000>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- timebase-frequency = <0>; /* Filled in by U-Boot */
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <16384>; /* 16 kB */
- d-cache-size = <16384>; /* 16 kB */
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic-405ex", "ibm,uic";
- interrupt-controller;
- cell-index = <0>;
- dcr-reg = <0x0c0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- UIC1: interrupt-controller1 {
- compatible = "ibm,uic-405ex","ibm,uic";
- interrupt-controller;
- cell-index = <1>;
- dcr-reg = <0x0d0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- UIC2: interrupt-controller2 {
- compatible = "ibm,uic-405ex","ibm,uic";
- interrupt-controller;
- cell-index = <2>;
- dcr-reg = <0x0e0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- CPM0: cpm {
- compatible = "ibm,cpm";
- dcr-access-method = "native";
- dcr-reg = <0x0b0 0x003>;
- unused-units = <0x00000000>;
- idle-doze = <0x02000000>;
- standby = <0xe3e74800>;
- };
-
- plb {
- compatible = "ibm,plb-405ex", "ibm,plb4";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- SDRAM0: memory-controller {
- compatible = "ibm,sdram-405ex", "ibm,sdram-4xx-ddr2";
- dcr-reg = <0x010 0x002>;
- interrupt-parent = <&UIC2>;
- interrupts = <0x5 0x4 /* ECC DED Error */
- 0x6 0x4>; /* ECC SEC Error */
- };
-
- CRYPTO: crypto@ef700000 {
- compatible = "amcc,ppc405ex-crypto", "amcc,ppc4xx-crypto";
- reg = <0xef700000 0x80400>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x17 0x2>;
- };
-
- MAL0: mcmal {
- compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
- dcr-reg = <0x180 0x062>;
- num-tx-chans = <2>;
- num-rx-chans = <2>;
- interrupt-parent = <&MAL0>;
- interrupts = <0x0 0x1 0x2 0x3 0x4>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*TXEOB*/ 0x0 &UIC0 0xa 0x4
- /*RXEOB*/ 0x1 &UIC0 0xb 0x4
- /*SERR*/ 0x2 &UIC1 0x0 0x4
- /*TXDE*/ 0x3 &UIC1 0x1 0x4
- /*RXDE*/ 0x4 &UIC1 0x2 0x4>;
- interrupt-map-mask = <0xffffffff>;
- };
-
- POB0: opb {
- compatible = "ibm,opb-405ex", "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x80000000 0x80000000 0x10000000
- 0xef600000 0xef600000 0x00a00000
- 0xf0000000 0xf0000000 0x10000000>;
- dcr-reg = <0x0a0 0x005>;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- EBC0: ebc {
- compatible = "ibm,ebc-405ex", "ibm,ebc";
- dcr-reg = <0x012 0x002>;
- #address-cells = <2>;
- #size-cells = <1>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- /* ranges property is supplied by U-Boot */
- interrupts = <0x5 0x1>;
- interrupt-parent = <&UIC1>;
-
- nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
- bank-width = <2>;
- reg = <0x00000000 0x00000000 0x04000000>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0x00000000 0x001e0000>;
- };
- partition@1e0000 {
- label = "dtb";
- reg = <0x001e0000 0x00020000>;
- };
- partition@200000 {
- label = "root";
- reg = <0x00200000 0x00200000>;
- };
- partition@400000 {
- label = "user";
- reg = <0x00400000 0x03b60000>;
- };
- partition@3f60000 {
- label = "env";
- reg = <0x03f60000 0x00040000>;
- };
- partition@3fa0000 {
- label = "u-boot";
- reg = <0x03fa0000 0x00060000>;
- };
- };
-
- ndfc@1,0 {
- compatible = "ibm,ndfc";
- reg = <0x00000001 0x00000000 0x00002000>;
- ccr = <0x00001000>;
- bank-settings = <0x80002222>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- nand {
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- };
- partition@100000 {
- label = "user";
- reg = <0x00000000 0x03f00000>;
- };
- };
- };
- };
-
- UART0: serial@ef600200 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600200 0x00000008>;
- virtual-reg = <0xef600200>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1a 0x4>;
- };
-
- UART1: serial@ef600300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600300 0x00000008>;
- virtual-reg = <0xef600300>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1 0x4>;
- };
-
- IIC0: i2c@ef600400 {
- compatible = "ibm,iic-405ex", "ibm,iic";
- reg = <0xef600400 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x2 0x4>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- rtc@68 {
- compatible = "dallas,ds1338";
- reg = <0x68>;
- };
-
- dtt@48 {
- compatible = "dallas,ds1775";
- reg = <0x48>;
- };
- };
-
- IIC1: i2c@ef600500 {
- compatible = "ibm,iic-405ex", "ibm,iic";
- reg = <0xef600500 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x7 0x4>;
- };
-
- RGMII0: emac-rgmii@ef600b00 {
- compatible = "ibm,rgmii-405ex", "ibm,rgmii";
- reg = <0xef600b00 0x00000104>;
- has-mdio;
- };
-
- EMAC0: ethernet@ef600900 {
- linux,network-index = <0x0>;
- device_type = "network";
- compatible = "ibm,emac-405ex", "ibm,emac4sync";
- interrupt-parent = <&EMAC0>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x18 0x4
- /*Wake*/ 0x1 &UIC1 0x1d 0x4>;
- reg = <0xef600900 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <0>;
- mal-rx-channel = <0>;
- cell-index = <0>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <0>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
-
- EMAC1: ethernet@ef600a00 {
- linux,network-index = <0x1>;
- device_type = "network";
- compatible = "ibm,emac-405ex", "ibm,emac4sync";
- interrupt-parent = <&EMAC1>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x19 0x4
- /*Wake*/ 0x1 &UIC1 0x1f 0x4>;
- reg = <0xef600a00 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <1>;
- mal-rx-channel = <1>;
- cell-index = <1>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <1>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
- };
-
- PCIE0: pcie@a0000000 {
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
- primary;
- port = <0x0>; /* port number */
- reg = <0xa0000000 0x20000000 /* Config space access */
- 0xef000000 0x00001000>; /* Registers */
- dcr-reg = <0x040 0x020>;
- sdr-base = <0x400>;
-
- /* Outbound ranges, one memory and one IO,
- * later cannot be changed
- */
- ranges = <0x02000000 0x00000000 0x80000000 0x90000000 0x00000000 0x08000000
- 0x01000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00010000>;
-
- /* Inbound 2GB range starting at 0 */
- dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
-
- /* This drives busses 0x00 to 0x3f */
- bus-range = <0x0 0x3f>;
-
- /* Legacy interrupts (note the weird polarity, the bridge seems
- * to invert PCIe legacy interrupts).
- * We are de-swizzling here because the numbers are actually for
- * port of the root complex virtual P2P bridge. But I want
- * to avoid putting a node for it in the tree, so the numbers
- * below are basically de-swizzled numbers.
- * The real slot is on idsel 0, so the swizzling is 1:1
- */
- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0 0x0 0x0 0x1 &UIC2 0x0 0x4 /* swizzled int A */
- 0x0 0x0 0x0 0x2 &UIC2 0x1 0x4 /* swizzled int B */
- 0x0 0x0 0x0 0x3 &UIC2 0x2 0x4 /* swizzled int C */
- 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>;
- };
-
- PCIE1: pcie@c0000000 {
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
- primary;
- port = <0x1>; /* port number */
- reg = <0xc0000000 0x20000000 /* Config space access */
- 0xef001000 0x00001000>; /* Registers */
- dcr-reg = <0x060 0x020>;
- sdr-base = <0x440>;
-
- /* Outbound ranges, one memory and one IO,
- * later cannot be changed
- */
- ranges = <0x02000000 0x00000000 0x80000000 0x98000000 0x00000000 0x08000000
- 0x01000000 0x00000000 0x00000000 0xe0010000 0x00000000 0x00010000>;
-
- /* Inbound 2GB range starting at 0 */
- dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
-
- /* This drives busses 0x40 to 0x7f */
- bus-range = <0x40 0x7f>;
-
- /* Legacy interrupts (note the weird polarity, the bridge seems
- * to invert PCIe legacy interrupts).
- * We are de-swizzling here because the numbers are actually for
- * port of the root complex virtual P2P bridge. But I want
- * to avoid putting a node for it in the tree, so the numbers
- * below are basically de-swizzled numbers.
- * The real slot is on idsel 0, so the swizzling is 1:1
- */
- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0 0x0 0x0 0x1 &UIC2 0xb 0x4 /* swizzled int A */
- 0x0 0x0 0x0 0x2 &UIC2 0xc 0x4 /* swizzled int B */
- 0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */
- 0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/klondike.dts b/arch/powerpc/boot/dts/klondike.dts
deleted file mode 100644
index 97432177892a..000000000000
--- a/arch/powerpc/boot/dts/klondike.dts
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Device Tree for Klondike (APM8018X) board.
- *
- * Copyright (c) 2010, Applied Micro Circuits Corporation
- * Author: Tanmay Inamdar <tinamdar@apm.com>
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "apm,klondike";
- compatible = "apm,klondike";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- ethernet1 = &EMAC1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,apm8018x";
- reg = <0x00000000>;
- clock-frequency = <300000000>; /* Filled in by U-Boot */
- timebase-frequency = <300000000>; /* Filled in by U-Boot */
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <16384>; /* 16 kB */
- d-cache-size = <16384>; /* 16 kB */
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x20000000>; /* Filled in by U-Boot */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic";
- interrupt-controller;
- cell-index = <0>;
- dcr-reg = <0x0c0 0x010>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- UIC1: interrupt-controller1 {
- compatible = "ibm,uic";
- interrupt-controller;
- cell-index = <1>;
- dcr-reg = <0x0d0 0x010>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- UIC2: interrupt-controller2 {
- compatible = "ibm,uic";
- interrupt-controller;
- cell-index = <2>;
- dcr-reg = <0x0e0 0x010>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x0a 0x4 0x0b 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- UIC3: interrupt-controller3 {
- compatible = "ibm,uic";
- interrupt-controller;
- cell-index = <3>;
- dcr-reg = <0x0f0 0x010>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- plb {
- compatible = "ibm,plb4";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- SDRAM0: memory-controller {
- compatible = "ibm,sdram-apm8018x";
- dcr-reg = <0x010 0x002>;
- };
-
- MAL0: mcmal {
- compatible = "ibm,mcmal2";
- dcr-reg = <0x180 0x062>;
- num-tx-chans = <2>;
- num-rx-chans = <16>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-parent = <&UIC1>;
- interrupts = </*TXEOB*/ 0x6 0x4
- /*RXEOB*/ 0x7 0x4
- /*SERR*/ 0x1 0x4
- /*TXDE*/ 0x2 0x4
- /*RXDE*/ 0x3 0x4>;
- };
-
- POB0: opb {
- compatible = "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x20000000 0x20000000 0x30000000
- 0x50000000 0x50000000 0x10000000
- 0x60000000 0x60000000 0x10000000
- 0xFE000000 0xFE000000 0x00010000>;
- dcr-reg = <0x100 0x020>;
- clock-frequency = <300000000>; /* Filled in by U-Boot */
-
- RGMII0: emac-rgmii@400a2000 {
- compatible = "ibm,rgmii";
- reg = <0x400a2000 0x00000010>;
- has-mdio;
- };
-
- TAH0: emac-tah@400a3000 {
- compatible = "ibm,tah";
- reg = <0x400a3000 0x100>;
- };
-
- TAH1: emac-tah@400a4000 {
- compatible = "ibm,tah";
- reg = <0x400a4000 0x100>;
- };
-
- EMAC0: ethernet@400a0000 {
- compatible = "ibm,emac4", "ibm-emac4sync";
- interrupt-parent = <&EMAC0>;
- interrupts = <0x0>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x13 0x4>;
- reg = <0x400a0000 0x00000100>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <0x0>;
- mal-rx-channel = <0x0>;
- cell-index = <0>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- phy-mode = "rgmii";
- phy-address = <0x2>;
- turbo = "no";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <0>;
- tah-device = <&TAH0>;
- tah-channel = <0>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
-
- EMAC1: ethernet@400a1000 {
- compatible = "ibm,emac4", "ibm-emac4sync";
- status = "disabled";
- interrupt-parent = <&EMAC1>;
- interrupts = <0x0>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x14 0x4>;
- reg = <0x400a1000 0x00000100>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <1>;
- mal-rx-channel = <8>;
- cell-index = <1>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- phy-mode = "rgmii";
- phy-address = <0x3>;
- turbo = "no";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <1>;
- tah-device = <&TAH1>;
- tah-channel = <0>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- mdio-device = <&EMAC0>;
- };
- };
- };
-
- chosen {
- stdout-path = "/plb/opb/serial@50001000";
- };
-};
diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts
deleted file mode 100644
index c473cd911bca..000000000000
--- a/arch/powerpc/boot/dts/makalu.dts
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Device Tree Source for AMCC Makalu (405EX)
- *
- * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without
- * any warranty of any kind, whether express or implied.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "amcc,makalu";
- compatible = "amcc,makalu";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- ethernet1 = &EMAC1;
- serial0 = &UART0;
- serial1 = &UART1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,405EX";
- reg = <0x00000000>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- timebase-frequency = <0>; /* Filled in by U-Boot */
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <16384>; /* 16 kB */
- d-cache-size = <16384>; /* 16 kB */
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic-405ex", "ibm,uic";
- interrupt-controller;
- cell-index = <0>;
- dcr-reg = <0x0c0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- UIC1: interrupt-controller1 {
- compatible = "ibm,uic-405ex","ibm,uic";
- interrupt-controller;
- cell-index = <1>;
- dcr-reg = <0x0d0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- UIC2: interrupt-controller2 {
- compatible = "ibm,uic-405ex","ibm,uic";
- interrupt-controller;
- cell-index = <2>;
- dcr-reg = <0x0e0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- plb {
- compatible = "ibm,plb-405ex", "ibm,plb4";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- SDRAM0: memory-controller {
- compatible = "ibm,sdram-405ex", "ibm,sdram-4xx-ddr2";
- dcr-reg = <0x010 0x002>;
- interrupt-parent = <&UIC2>;
- interrupts = <0x5 0x4 /* ECC DED Error */
- 0x6 0x4 /* ECC SEC Error */ >;
- };
-
- MAL0: mcmal {
- compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
- dcr-reg = <0x180 0x062>;
- num-tx-chans = <2>;
- num-rx-chans = <2>;
- interrupt-parent = <&MAL0>;
- interrupts = <0x0 0x1 0x2 0x3 0x4>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*TXEOB*/ 0x0 &UIC0 0xa 0x4
- /*RXEOB*/ 0x1 &UIC0 0xb 0x4
- /*SERR*/ 0x2 &UIC1 0x0 0x4
- /*TXDE*/ 0x3 &UIC1 0x1 0x4
- /*RXDE*/ 0x4 &UIC1 0x2 0x4>;
- interrupt-map-mask = <0xffffffff>;
- };
-
- POB0: opb {
- compatible = "ibm,opb-405ex", "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x80000000 0x80000000 0x10000000
- 0xef600000 0xef600000 0x00a00000
- 0xf0000000 0xf0000000 0x10000000>;
- dcr-reg = <0x0a0 0x005>;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- EBC0: ebc {
- compatible = "ibm,ebc-405ex", "ibm,ebc";
- dcr-reg = <0x012 0x002>;
- #address-cells = <2>;
- #size-cells = <1>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- /* ranges property is supplied by U-Boot */
- interrupts = <0x5 0x1>;
- interrupt-parent = <&UIC1>;
-
- nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
- bank-width = <2>;
- reg = <0x00000000 0x00000000 0x04000000>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0x00000000 0x00200000>;
- };
- partition@200000 {
- label = "root";
- reg = <0x00200000 0x00200000>;
- };
- partition@400000 {
- label = "user";
- reg = <0x00400000 0x03b60000>;
- };
- partition@3f60000 {
- label = "env";
- reg = <0x03f60000 0x00040000>;
- };
- partition@3fa0000 {
- label = "u-boot";
- reg = <0x03fa0000 0x00060000>;
- };
- };
- };
-
- UART0: serial@ef600200 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600200 0x00000008>;
- virtual-reg = <0xef600200>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1a 0x4>;
- };
-
- UART1: serial@ef600300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600300 0x00000008>;
- virtual-reg = <0xef600300>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1 0x4>;
- };
-
- IIC0: i2c@ef600400 {
- compatible = "ibm,iic-405ex", "ibm,iic";
- reg = <0xef600400 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x2 0x4>;
- };
-
- IIC1: i2c@ef600500 {
- compatible = "ibm,iic-405ex", "ibm,iic";
- reg = <0xef600500 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x7 0x4>;
- };
-
-
- RGMII0: emac-rgmii@ef600b00 {
- compatible = "ibm,rgmii-405ex", "ibm,rgmii";
- reg = <0xef600b00 0x00000104>;
- has-mdio;
- };
-
- EMAC0: ethernet@ef600900 {
- linux,network-index = <0x0>;
- device_type = "network";
- compatible = "ibm,emac-405ex", "ibm,emac4sync";
- interrupt-parent = <&EMAC0>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x18 0x4
- /*Wake*/ 0x1 &UIC1 0x1d 0x4>;
- reg = <0xef600900 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <0>;
- mal-rx-channel = <0>;
- cell-index = <0>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x0000003f>; /* Start at 6 */
- rgmii-device = <&RGMII0>;
- rgmii-channel = <0>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
-
- EMAC1: ethernet@ef600a00 {
- linux,network-index = <0x1>;
- device_type = "network";
- compatible = "ibm,emac-405ex", "ibm,emac4sync";
- interrupt-parent = <&EMAC1>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x19 0x4
- /*Wake*/ 0x1 &UIC1 0x1f 0x4>;
- reg = <0xef600a00 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <1>;
- mal-rx-channel = <1>;
- cell-index = <1>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <1>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
- };
-
- PCIE0: pcie@a0000000 {
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
- primary;
- port = <0x0>; /* port number */
- reg = <0xa0000000 0x20000000 /* Config space access */
- 0xef000000 0x00001000>; /* Registers */
- dcr-reg = <0x040 0x020>;
- sdr-base = <0x400>;
-
- /* Outbound ranges, one memory and one IO,
- * later cannot be changed
- */
- ranges = <0x02000000 0x00000000 0x80000000 0x90000000 0x00000000 0x08000000
- 0x01000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00010000>;
-
- /* Inbound 2GB range starting at 0 */
- dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
-
- /* This drives busses 0x00 to 0x3f */
- bus-range = <0x0 0x3f>;
-
- /* Legacy interrupts (note the weird polarity, the bridge seems
- * to invert PCIe legacy interrupts).
- * We are de-swizzling here because the numbers are actually for
- * port of the root complex virtual P2P bridge. But I want
- * to avoid putting a node for it in the tree, so the numbers
- * below are basically de-swizzled numbers.
- * The real slot is on idsel 0, so the swizzling is 1:1
- */
- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0 0x0 0x0 0x1 &UIC2 0x0 0x4 /* swizzled int A */
- 0x0 0x0 0x0 0x2 &UIC2 0x1 0x4 /* swizzled int B */
- 0x0 0x0 0x0 0x3 &UIC2 0x2 0x4 /* swizzled int C */
- 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>;
- };
-
- PCIE1: pcie@c0000000 {
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
- primary;
- port = <0x1>; /* port number */
- reg = <0xc0000000 0x20000000 /* Config space access */
- 0xef001000 0x00001000>; /* Registers */
- dcr-reg = <0x060 0x020>;
- sdr-base = <0x440>;
-
- /* Outbound ranges, one memory and one IO,
- * later cannot be changed
- */
- ranges = <0x02000000 0x00000000 0x80000000 0x98000000 0x00000000 0x08000000
- 0x01000000 0x00000000 0x00000000 0xe0010000 0x00000000 0x00010000>;
-
- /* Inbound 2GB range starting at 0 */
- dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
-
- /* This drives busses 0x40 to 0x7f */
- bus-range = <0x40 0x7f>;
-
- /* Legacy interrupts (note the weird polarity, the bridge seems
- * to invert PCIe legacy interrupts).
- * We are de-swizzling here because the numbers are actually for
- * port of the root complex virtual P2P bridge. But I want
- * to avoid putting a node for it in the tree, so the numbers
- * below are basically de-swizzled numbers.
- * The real slot is on idsel 0, so the swizzling is 1:1
- */
- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0 0x0 0x0 0x1 &UIC2 0xb 0x4 /* swizzled int A */
- 0x0 0x0 0x0 0x2 &UIC2 0xc 0x4 /* swizzled int B */
- 0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */
- 0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/obs600.dts b/arch/powerpc/boot/dts/obs600.dts
deleted file mode 100644
index d10b0411809b..000000000000
--- a/arch/powerpc/boot/dts/obs600.dts
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Device Tree Source for PlatHome OpenBlockS 600 (405EX)
- *
- * Copyright 2011 Ben Herrenschmidt, IBM Corp.
- *
- * Based on Kilauea by:
- *
- * Copyright 2007-2009 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without
- * any warranty of any kind, whether express or implied.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "PlatHome,OpenBlockS 600";
- compatible = "plathome,obs600";
- dcr-parent = <&{/cpus/cpu@0}>;
-
- aliases {
- ethernet0 = &EMAC0;
- ethernet1 = &EMAC1;
- serial0 = &UART0;
- serial1 = &UART1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- model = "PowerPC,405EX";
- reg = <0x00000000>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- timebase-frequency = <0>; /* Filled in by U-Boot */
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <16384>; /* 16 kB */
- d-cache-size = <16384>; /* 16 kB */
- dcr-controller;
- dcr-access-method = "native";
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */
- };
-
- UIC0: interrupt-controller {
- compatible = "ibm,uic-405ex", "ibm,uic";
- interrupt-controller;
- cell-index = <0>;
- dcr-reg = <0x0c0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- };
-
- UIC1: interrupt-controller1 {
- compatible = "ibm,uic-405ex","ibm,uic";
- interrupt-controller;
- cell-index = <1>;
- dcr-reg = <0x0d0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- UIC2: interrupt-controller2 {
- compatible = "ibm,uic-405ex","ibm,uic";
- interrupt-controller;
- cell-index = <2>;
- dcr-reg = <0x0e0 0x009>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */
- interrupt-parent = <&UIC0>;
- };
-
- CPM0: cpm {
- compatible = "ibm,cpm";
- dcr-access-method = "native";
- dcr-reg = <0x0b0 0x003>;
- unused-units = <0x00000000>;
- idle-doze = <0x02000000>;
- standby = <0xe3e74800>;
- };
-
- plb {
- compatible = "ibm,plb-405ex", "ibm,plb4";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- SDRAM0: memory-controller {
- compatible = "ibm,sdram-405ex", "ibm,sdram-4xx-ddr2";
- dcr-reg = <0x010 0x002>;
- interrupt-parent = <&UIC2>;
- interrupts = <0x5 0x4 /* ECC DED Error */
- 0x6 0x4>; /* ECC SEC Error */
- };
-
- CRYPTO: crypto@ef700000 {
- compatible = "amcc,ppc405ex-crypto", "amcc,ppc4xx-crypto";
- reg = <0xef700000 0x80400>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x17 0x2>;
- };
-
- MAL0: mcmal {
- compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
- dcr-reg = <0x180 0x062>;
- num-tx-chans = <2>;
- num-rx-chans = <2>;
- interrupt-parent = <&MAL0>;
- interrupts = <0x0 0x1 0x2 0x3 0x4>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*TXEOB*/ 0x0 &UIC0 0xa 0x4
- /*RXEOB*/ 0x1 &UIC0 0xb 0x4
- /*SERR*/ 0x2 &UIC1 0x0 0x4
- /*TXDE*/ 0x3 &UIC1 0x1 0x4
- /*RXDE*/ 0x4 &UIC1 0x2 0x4>;
- interrupt-map-mask = <0xffffffff>;
- };
-
- POB0: opb {
- compatible = "ibm,opb-405ex", "ibm,opb";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x80000000 0x80000000 0x10000000
- 0xef600000 0xef600000 0x00a00000
- 0xf0000000 0xf0000000 0x10000000>;
- dcr-reg = <0x0a0 0x005>;
- clock-frequency = <0>; /* Filled in by U-Boot */
-
- EBC0: ebc {
- compatible = "ibm,ebc-405ex", "ibm,ebc";
- dcr-reg = <0x012 0x002>;
- #address-cells = <2>;
- #size-cells = <1>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- /* ranges property is supplied by U-Boot */
- interrupts = <0x5 0x1>;
- interrupt-parent = <&UIC1>;
-
- nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
- bank-width = <2>;
- reg = <0x00000000 0x00000000 0x08000000>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "kernel + initrd";
- reg = <0x00000000 0x03de0000>;
- };
- partition@3de0000 {
- label = "user config area";
- reg = <0x03de0000 0x00080000>;
- };
- partition@3e60000 {
- label = "user program area";
- reg = <0x03e60000 0x04000000>;
- };
- partition@7e60000 {
- label = "flat device tree";
- reg = <0x07e60000 0x00080000>;
- };
- partition@7ee0000 {
- label = "test program";
- reg = <0x07ee0000 0x00080000>;
- };
- partition@7f60000 {
- label = "u-boot env";
- reg = <0x07f60000 0x00040000>;
- };
- partition@7fa0000 {
- label = "u-boot";
- reg = <0x07fa0000 0x00060000>;
- };
- };
- };
-
- UART0: serial@ef600200 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600200 0x00000008>;
- virtual-reg = <0xef600200>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1a 0x4>;
- };
-
- UART1: serial@ef600300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600300 0x00000008>;
- virtual-reg = <0xef600300>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x1 0x4>;
- };
-
- IIC0: i2c@ef600400 {
- compatible = "ibm,iic-405ex", "ibm,iic";
- reg = <0xef600400 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x2 0x4>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- rtc@68 {
- compatible = "dallas,ds1340";
- reg = <0x68>;
- };
- };
-
- IIC1: i2c@ef600500 {
- compatible = "ibm,iic-405ex", "ibm,iic";
- reg = <0xef600500 0x00000014>;
- interrupt-parent = <&UIC0>;
- interrupts = <0x7 0x4>;
- };
-
- RGMII0: emac-rgmii@ef600b00 {
- compatible = "ibm,rgmii-405ex", "ibm,rgmii";
- reg = <0xef600b00 0x00000104>;
- has-mdio;
- };
-
- EMAC0: ethernet@ef600900 {
- linux,network-index = <0x0>;
- device_type = "network";
- compatible = "ibm,emac-405ex", "ibm,emac4sync";
- interrupt-parent = <&EMAC0>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x18 0x4
- /*Wake*/ 0x1 &UIC1 0x1d 0x4>;
- reg = <0xef600900 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <0>;
- mal-rx-channel = <0>;
- cell-index = <0>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <0>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
-
- EMAC1: ethernet@ef600a00 {
- linux,network-index = <0x1>;
- device_type = "network";
- compatible = "ibm,emac-405ex", "ibm,emac4sync";
- interrupt-parent = <&EMAC1>;
- interrupts = <0x0 0x1>;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = </*Status*/ 0x0 &UIC0 0x19 0x4
- /*Wake*/ 0x1 &UIC1 0x1f 0x4>;
- reg = <0xef600a00 0x000000c4>;
- local-mac-address = [000000000000]; /* Filled in by U-Boot */
- mal-device = <&MAL0>;
- mal-tx-channel = <1>;
- mal-rx-channel = <1>;
- cell-index = <1>;
- max-frame-size = <9000>;
- rx-fifo-size = <4096>;
- tx-fifo-size = <2048>;
- rx-fifo-size-gige = <16384>;
- tx-fifo-size-gige = <16384>;
- phy-mode = "rgmii";
- phy-map = <0x00000000>;
- rgmii-device = <&RGMII0>;
- rgmii-channel = <1>;
- has-inverted-stacr-oc;
- has-new-stacr-staopc;
- };
-
- GPIO: gpio@ef600800 {
- device_type = "gpio";
- compatible = "ibm,gpio-405ex", "ibm,ppc4xx-gpio";
- reg = <0xef600800 0x50>;
- };
- };
- };
- chosen {
- stdout-path = "/plb/opb/serial@ef600200";
- };
-};
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index cae31a6e8f02..2c0e2a1cab01 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -188,7 +188,7 @@ static inline void prep_esm_blob(struct addr_range vmlinux, void *chosen) { }
/* A buffer that may be edited by tools operating on a zImage binary so as to
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
- * The buffer is put in it's own section so that tools may locate it easier.
+ * The buffer is put in its own section so that tools may locate it easier.
*/
static char cmdline[BOOT_COMMAND_LINE_SIZE]
__attribute__((__section__("__builtin_cmdline")));
diff --git a/arch/powerpc/boot/ppcboot-hotfoot.h b/arch/powerpc/boot/ppcboot-hotfoot.h
deleted file mode 100644
index 4728db95f58a..000000000000
--- a/arch/powerpc/boot/ppcboot-hotfoot.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * This interface is used for compatibility with old U-boots *ONLY*.
- * Please do not imitate or extend this.
- */
-
-/*
- * Unfortunately, the ESTeem Hotfoot board uses a mangled version of
- * ppcboot.h for historical reasons, and in the interest of having a
- * mainline kernel boot on the production board+bootloader, this was the
- * least-offensive solution. Please direct all flames to:
- *
- * Solomon Peachy <solomon@linux-wlan.com>
- *
- * (This header is identical to ppcboot.h except for the
- * TARGET_HOTFOOT bits)
- */
-
-/*
- * (C) Copyright 2000, 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#ifndef __PPCBOOT_H__
-#define __PPCBOOT_H__
-
-/*
- * Board information passed to kernel from PPCBoot
- *
- * include/asm-ppc/ppcboot.h
- */
-
-#include "types.h"
-
-typedef struct bd_info {
- unsigned long bi_memstart; /* start of DRAM memory */
- unsigned long bi_memsize; /* size of DRAM memory in bytes */
- unsigned long bi_flashstart; /* start of FLASH memory */
- unsigned long bi_flashsize; /* size of FLASH memory */
- unsigned long bi_flashoffset; /* reserved area for startup monitor */
- unsigned long bi_sramstart; /* start of SRAM memory */
- unsigned long bi_sramsize; /* size of SRAM memory */
-#if defined(TARGET_8xx) || defined(TARGET_CPM2) || defined(TARGET_85xx) ||\
- defined(TARGET_83xx)
- unsigned long bi_immr_base; /* base of IMMR register */
-#endif
-#if defined(TARGET_PPC_MPC52xx)
- unsigned long bi_mbar_base; /* base of internal registers */
-#endif
- unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
- unsigned long bi_ip_addr; /* IP Address */
- unsigned char bi_enetaddr[6]; /* Ethernet address */
-#if defined(TARGET_HOTFOOT)
- /* second onboard ethernet port */
- unsigned char bi_enet1addr[6];
-#define HAVE_ENET1ADDR
-#endif /* TARGET_HOOTFOOT */
- unsigned short bi_ethspeed; /* Ethernet speed in Mbps */
- unsigned long bi_intfreq; /* Internal Freq, in MHz */
- unsigned long bi_busfreq; /* Bus Freq, in MHz */
-#if defined(TARGET_CPM2)
- unsigned long bi_cpmfreq; /* CPM_CLK Freq, in MHz */
- unsigned long bi_brgfreq; /* BRG_CLK Freq, in MHz */
- unsigned long bi_sccfreq; /* SCC_CLK Freq, in MHz */
- unsigned long bi_vco; /* VCO Out from PLL, in MHz */
-#endif
-#if defined(TARGET_PPC_MPC52xx)
- unsigned long bi_ipbfreq; /* IPB Bus Freq, in MHz */
- unsigned long bi_pcifreq; /* PCI Bus Freq, in MHz */
-#endif
- unsigned long bi_baudrate; /* Console Baudrate */
-#if defined(TARGET_4xx)
- unsigned char bi_s_version[4]; /* Version of this structure */
- unsigned char bi_r_version[32]; /* Version of the ROM (IBM) */
- unsigned int bi_procfreq; /* CPU (Internal) Freq, in Hz */
- unsigned int bi_plb_busfreq; /* PLB Bus speed, in Hz */
- unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
- unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
-#endif
-#if defined(TARGET_HOTFOOT)
- unsigned int bi_pllouta_freq; /* PLL OUTA speed, in Hz */
-#endif
-#if defined(TARGET_HYMOD)
- hymod_conf_t bi_hymod_conf; /* hymod configuration information */
-#endif
-#if defined(TARGET_EVB64260) || defined(TARGET_405EP) || defined(TARGET_44x) || \
- defined(TARGET_85xx) || defined(TARGET_83xx) || defined(TARGET_HAS_ETH1)
- /* second onboard ethernet port */
- unsigned char bi_enet1addr[6];
-#define HAVE_ENET1ADDR
-#endif
-#if defined(TARGET_EVB64260) || defined(TARGET_440GX) || \
- defined(TARGET_85xx) || defined(TARGET_HAS_ETH2)
- /* third onboard ethernet ports */
- unsigned char bi_enet2addr[6];
-#define HAVE_ENET2ADDR
-#endif
-#if defined(TARGET_440GX) || defined(TARGET_HAS_ETH3)
- /* fourth onboard ethernet ports */
- unsigned char bi_enet3addr[6];
-#define HAVE_ENET3ADDR
-#endif
-#if defined(TARGET_HOTFOOT)
- int bi_phynum[2]; /* Determines phy mapping */
- int bi_phymode[2]; /* Determines phy mode */
-#endif
-#if defined(TARGET_4xx)
- unsigned int bi_opbfreq; /* OB clock in Hz */
- int bi_iic_fast[2]; /* Use fast i2c mode */
-#endif
-#if defined(TARGET_440GX)
- int bi_phynum[4]; /* phy mapping */
- int bi_phymode[4]; /* phy mode */
-#endif
-} bd_t;
-
-#define bi_tbfreq bi_intfreq
-
-#endif /* __PPCBOOT_H__ */
diff --git a/arch/powerpc/boot/ppcboot.h b/arch/powerpc/boot/ppcboot.h
index a78b0b257698..90c8f452fe6e 100644
--- a/arch/powerpc/boot/ppcboot.h
+++ b/arch/powerpc/boot/ppcboot.h
@@ -63,7 +63,7 @@ typedef struct bd_info {
#if defined(TARGET_HYMOD)
hymod_conf_t bi_hymod_conf; /* hymod configuration information */
#endif
-#if defined(TARGET_EVB64260) || defined(TARGET_405EP) || defined(TARGET_44x) || \
+#if defined(TARGET_EVB64260) || defined(TARGET_44x) || \
defined(TARGET_85xx) || defined(TARGET_83xx) || defined(TARGET_HAS_ETH1)
/* second onboard ethernet port */
unsigned char bi_enet1addr[6];
diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c
index f157717ae814..89ff46b8b225 100644
--- a/arch/powerpc/boot/ps3.c
+++ b/arch/powerpc/boot/ps3.c
@@ -25,7 +25,7 @@ BSS_STACK(4096);
/* A buffer that may be edited by tools operating on a zImage binary so as to
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
- * The buffer is put in it's own section so that tools may locate it easier.
+ * The buffer is put in its own section so that tools may locate it easier.
*/
static char cmdline[BOOT_COMMAND_LINE_SIZE]
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 352d7de24018..b1f5549a3c9c 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -337,7 +337,7 @@ ps3)
make_space=n
pie=
;;
-ep88xc|ep405|ep8248e)
+ep88xc|ep8248e)
platformo="$object/fixed-head.o $object/$platform.o"
binary=y
;;
@@ -468,26 +468,6 @@ uboot)
fi
exit 0
;;
-uboot-obs600)
- rm -f "$ofile"
- # obs600 wants a multi image with an initrd, so we need to put a fake
- # one in even when building a "normal" image.
- if [ -n "$initrd" ]; then
- real_rd="$initrd"
- else
- real_rd=`mktemp`
- echo "\0" >>"$real_rd"
- fi
- ${MKIMAGE} -A ppc -O linux -T multi -C gzip -a $membase -e $membase \
- $uboot_version -d "$vmz":"$real_rd":"$dtb" "$ofile"
- if [ -z "$initrd" ]; then
- rm -f "$real_rd"
- fi
- if [ -z "$cacheit" ]; then
- rm -f "$vmz"
- fi
- exit 0
- ;;
esac
addsec() {
diff --git a/arch/powerpc/configs/40x.config b/arch/powerpc/configs/40x.config
deleted file mode 100644
index 82a9d58ddb81..000000000000
--- a/arch/powerpc/configs/40x.config
+++ /dev/null
@@ -1,2 +0,0 @@
-CONFIG_PPC64=n
-CONFIG_40x=y
diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig
deleted file mode 100644
index 25eed86ec528..000000000000
--- a/arch/powerpc/configs/40x/acadia_defconfig
+++ /dev/null
@@ -1,61 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ACADIA=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_IBM_EMAC=y
-CONFIG_IBM_EMAC_RXB=256
-CONFIG_IBM_EMAC_TXB=256
-CONFIG_IBM_EMAC_DEBUG=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig
deleted file mode 100644
index 3549c9e950e8..000000000000
--- a/arch/powerpc/configs/40x/kilauea_defconfig
+++ /dev/null
@@ -1,69 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_KILAUEA=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_NAND_NDFC=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_IBM_EMAC=y
-CONFIG_IBM_EMAC_RXB=256
-CONFIG_IBM_EMAC_TXB=256
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_IBM_IIC=y
-CONFIG_SENSORS_LM75=y
-CONFIG_THERMAL=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_EXT2_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/configs/40x/klondike_defconfig
deleted file mode 100644
index a974d1e945cc..000000000000
--- a/arch/powerpc/configs/40x/klondike_defconfig
+++ /dev/null
@@ -1,43 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_APM8018X=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_MATH_EMULATION=y
-# CONFIG_SUSPEND is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_SAS_ATTRS=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_FTRACE is not set
diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig
deleted file mode 100644
index 4563f88acf0c..000000000000
--- a/arch/powerpc/configs/40x/makalu_defconfig
+++ /dev/null
@@ -1,59 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_MAKALU=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_IBM_EMAC=y
-CONFIG_IBM_EMAC_RXB=256
-CONFIG_IBM_EMAC_TXB=256
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/40x/obs600_defconfig b/arch/powerpc/configs/40x/obs600_defconfig
deleted file mode 100644
index 2a2bb3f46847..000000000000
--- a/arch/powerpc/configs/40x/obs600_defconfig
+++ /dev/null
@@ -1,69 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_OBS600=y
-CONFIG_MATH_EMULATION=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_NAND_NDFC=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_IBM_EMAC=y
-CONFIG_IBM_EMAC_RXB=256
-CONFIG_IBM_EMAC_TXB=256
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_IBM_IIC=y
-CONFIG_SENSORS_LM75=y
-CONFIG_THERMAL=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_EXT2_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig
deleted file mode 100644
index 9eaaf1a1d2c6..000000000000
--- a/arch/powerpc/configs/40x/walnut_defconfig
+++ /dev/null
@@ -1,55 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-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_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_IBM_EMAC=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-CONFIG_EXT2_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config
index 524db76f47b7..8aff83217397 100644
--- a/arch/powerpc/configs/85xx-hw.config
+++ b/arch/powerpc/configs/85xx-hw.config
@@ -24,6 +24,7 @@ CONFIG_FS_ENET=y
CONFIG_FSL_CORENET_CF=y
CONFIG_FSL_DMA=y
CONFIG_FSL_HV_MANAGER=y
+CONFIG_FSL_IFC=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_FSL_RIO=y
CONFIG_FSL_XGMAC_MDIO=y
@@ -58,6 +59,7 @@ CONFIG_INPUT_FF_MEMLESS=m
CONFIG_MARVELL_PHY=y
CONFIG_MDIO_BUS_MUX_GPIO=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
+CONFIG_MEMORY=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI=y
diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig
index 7f35d5bc1229..97f4d4851735 100644
--- a/arch/powerpc/configs/adder875_defconfig
+++ b/arch/powerpc/configs/adder875_defconfig
@@ -4,7 +4,7 @@ CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig
index a98ef6a4abef..50cc59eb36cf 100644
--- a/arch/powerpc/configs/ep88xc_defconfig
+++ b/arch/powerpc/configs/ep88xc_defconfig
@@ -6,7 +6,7 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig
index 5c56d36cdfc5..6f449411abf7 100644
--- a/arch/powerpc/configs/mpc866_ads_defconfig
+++ b/arch/powerpc/configs/mpc866_ads_defconfig
@@ -6,7 +6,7 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXPERT=y
# CONFIG_BUG is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_EPOLL is not set
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig
index 56b876e418e9..77306be62e9e 100644
--- a/arch/powerpc/configs/mpc885_ads_defconfig
+++ b/arch/powerpc/configs/mpc885_ads_defconfig
@@ -7,7 +7,7 @@ CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig
deleted file mode 100644
index 7e48693775f4..000000000000
--- a/arch/powerpc/configs/ppc40x_defconfig
+++ /dev/null
@@ -1,74 +0,0 @@
-CONFIG_40x=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PPC4xx_GPIO=y
-CONFIG_ACADIA=y
-CONFIG_HOTFOOT=y
-CONFIG_KILAUEA=y
-CONFIG_MAKALU=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_UBI=m
-CONFIG_MTD_UBI_GLUEBI=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_IBM_EMAC=y
-# CONFIG_INPUT is not set
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-CONFIG_I2C_IBM_IIC=m
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-CONFIG_FB=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT4_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=m
-CONFIG_UBIFS_FS=m
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 66c7b28d7450..c06344db0eb3 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -12,7 +12,6 @@ CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_USER_NS=y
diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig
index 083c2e57520a..383c0966e92f 100644
--- a/arch/powerpc/configs/tqm8xx_defconfig
+++ b/arch/powerpc/configs/tqm8xx_defconfig
@@ -6,7 +6,7 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_MODULES=y
diff --git a/arch/powerpc/crypto/.gitignore b/arch/powerpc/crypto/.gitignore
index e1094f08f713..e9fe73aac8b6 100644
--- a/arch/powerpc/crypto/.gitignore
+++ b/arch/powerpc/crypto/.gitignore
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
aesp10-ppc.S
+aesp8-ppc.S
ghashp10-ppc.S
+ghashp8-ppc.S
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig
index 1e201b7ae2fc..09ebcbdfb34f 100644
--- a/arch/powerpc/crypto/Kconfig
+++ b/arch/powerpc/crypto/Kconfig
@@ -2,6 +2,17 @@
menu "Accelerated Cryptographic Algorithms for CPU (powerpc)"
+config CRYPTO_CURVE25519_PPC64
+ tristate "Public key crypto: Curve25519 (PowerPC64)"
+ depends on PPC64 && CPU_LITTLE_ENDIAN
+ select CRYPTO_LIB_CURVE25519_GENERIC
+ select CRYPTO_ARCH_HAVE_LIB_CURVE25519
+ help
+ Curve25519 algorithm
+
+ Architecture: PowerPC64
+ - Little-endian
+
config CRYPTO_CRC32C_VPMSUM
tristate "CRC32c"
depends on PPC64 && ALTIVEC
diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
index fca0e9739869..59808592f0a1 100644
--- a/arch/powerpc/crypto/Makefile
+++ b/arch/powerpc/crypto/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
obj-$(CONFIG_CRYPTO_CHACHA20_P10) += chacha-p10-crypto.o
obj-$(CONFIG_CRYPTO_POLY1305_P10) += poly1305-p10-crypto.o
obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
+obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o
md5-ppc-y := md5-asm.o md5-glue.o
@@ -29,6 +30,7 @@ aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-p
chacha-p10-crypto-y := chacha-p10-glue.o chacha-p10le-8x.o
poly1305-p10-crypto-y := poly1305-p10-glue.o poly1305-p10le_64.o
vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
+curve25519-ppc64le-y := curve25519-ppc64le-core.o curve25519-ppc64le_asm.o
ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
override flavour := linux-ppc64le
diff --git a/arch/powerpc/crypto/curve25519-ppc64le-core.c b/arch/powerpc/crypto/curve25519-ppc64le-core.c
new file mode 100644
index 000000000000..4e3e44ea4484
--- /dev/null
+++ b/arch/powerpc/crypto/curve25519-ppc64le-core.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024- IBM Corp.
+ *
+ * X25519 scalar multiplication with 51 bits limbs for PPC64le.
+ * Based on RFC7748 and AArch64 optimized implementation for X25519
+ * - Algorithm 1 Scalar multiplication of a variable point
+ */
+
+#include <crypto/curve25519.h>
+#include <crypto/internal/kpp.h>
+
+#include <linux/types.h>
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+
+#include <linux/cpufeature.h>
+#include <linux/processor.h>
+
+typedef uint64_t fe51[5];
+
+asmlinkage void x25519_fe51_mul(fe51 h, const fe51 f, const fe51 g);
+asmlinkage void x25519_fe51_sqr(fe51 h, const fe51 f);
+asmlinkage void x25519_fe51_mul121666(fe51 h, fe51 f);
+asmlinkage void x25519_fe51_sqr_times(fe51 h, const fe51 f, int n);
+asmlinkage void x25519_fe51_frombytes(fe51 h, const uint8_t *s);
+asmlinkage void x25519_fe51_tobytes(uint8_t *s, const fe51 h);
+asmlinkage void x25519_cswap(fe51 p, fe51 q, unsigned int bit);
+
+#define fmul x25519_fe51_mul
+#define fsqr x25519_fe51_sqr
+#define fmul121666 x25519_fe51_mul121666
+#define fe51_tobytes x25519_fe51_tobytes
+
+static void fadd(fe51 h, const fe51 f, const fe51 g)
+{
+ h[0] = f[0] + g[0];
+ h[1] = f[1] + g[1];
+ h[2] = f[2] + g[2];
+ h[3] = f[3] + g[3];
+ h[4] = f[4] + g[4];
+}
+
+/*
+ * Prime = 2 ** 255 - 19, 255 bits
+ * (0x7fffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffed)
+ *
+ * Prime in 5 51-bit limbs
+ */
+static fe51 prime51 = { 0x7ffffffffffed, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff};
+
+static void fsub(fe51 h, const fe51 f, const fe51 g)
+{
+ h[0] = (f[0] + ((prime51[0] * 2))) - g[0];
+ h[1] = (f[1] + ((prime51[1] * 2))) - g[1];
+ h[2] = (f[2] + ((prime51[2] * 2))) - g[2];
+ h[3] = (f[3] + ((prime51[3] * 2))) - g[3];
+ h[4] = (f[4] + ((prime51[4] * 2))) - g[4];
+}
+
+static void fe51_frombytes(fe51 h, const uint8_t *s)
+{
+ /*
+ * Make sure 64-bit aligned.
+ */
+ unsigned char sbuf[32+8];
+ unsigned char *sb = PTR_ALIGN((void *)sbuf, 8);
+
+ memcpy(sb, s, 32);
+ x25519_fe51_frombytes(h, sb);
+}
+
+static void finv(fe51 o, const fe51 i)
+{
+ fe51 a0, b, c, t00;
+
+ fsqr(a0, i);
+ x25519_fe51_sqr_times(t00, a0, 2);
+
+ fmul(b, t00, i);
+ fmul(a0, b, a0);
+
+ fsqr(t00, a0);
+
+ fmul(b, t00, b);
+ x25519_fe51_sqr_times(t00, b, 5);
+
+ fmul(b, t00, b);
+ x25519_fe51_sqr_times(t00, b, 10);
+
+ fmul(c, t00, b);
+ x25519_fe51_sqr_times(t00, c, 20);
+
+ fmul(t00, t00, c);
+ x25519_fe51_sqr_times(t00, t00, 10);
+
+ fmul(b, t00, b);
+ x25519_fe51_sqr_times(t00, b, 50);
+
+ fmul(c, t00, b);
+ x25519_fe51_sqr_times(t00, c, 100);
+
+ fmul(t00, t00, c);
+ x25519_fe51_sqr_times(t00, t00, 50);
+
+ fmul(t00, t00, b);
+ x25519_fe51_sqr_times(t00, t00, 5);
+
+ fmul(o, t00, a0);
+}
+
+static void curve25519_fe51(uint8_t out[32], const uint8_t scalar[32],
+ const uint8_t point[32])
+{
+ fe51 x1, x2, z2, x3, z3;
+ uint8_t s[32];
+ unsigned int swap = 0;
+ int i;
+
+ memcpy(s, scalar, 32);
+ s[0] &= 0xf8;
+ s[31] &= 0x7f;
+ s[31] |= 0x40;
+ fe51_frombytes(x1, point);
+
+ z2[0] = z2[1] = z2[2] = z2[3] = z2[4] = 0;
+ x3[0] = x1[0];
+ x3[1] = x1[1];
+ x3[2] = x1[2];
+ x3[3] = x1[3];
+ x3[4] = x1[4];
+
+ x2[0] = z3[0] = 1;
+ x2[1] = z3[1] = 0;
+ x2[2] = z3[2] = 0;
+ x2[3] = z3[3] = 0;
+ x2[4] = z3[4] = 0;
+
+ for (i = 254; i >= 0; --i) {
+ unsigned int k_t = 1 & (s[i / 8] >> (i & 7));
+ fe51 a, b, c, d, e;
+ fe51 da, cb, aa, bb;
+ fe51 dacb_p, dacb_m;
+
+ swap ^= k_t;
+ x25519_cswap(x2, x3, swap);
+ x25519_cswap(z2, z3, swap);
+ swap = k_t;
+
+ fsub(b, x2, z2); // B = x_2 - z_2
+ fadd(a, x2, z2); // A = x_2 + z_2
+ fsub(d, x3, z3); // D = x_3 - z_3
+ fadd(c, x3, z3); // C = x_3 + z_3
+
+ fsqr(bb, b); // BB = B^2
+ fsqr(aa, a); // AA = A^2
+ fmul(da, d, a); // DA = D * A
+ fmul(cb, c, b); // CB = C * B
+
+ fsub(e, aa, bb); // E = AA - BB
+ fmul(x2, aa, bb); // x2 = AA * BB
+ fadd(dacb_p, da, cb); // DA + CB
+ fsub(dacb_m, da, cb); // DA - CB
+
+ fmul121666(z3, e); // 121666 * E
+ fsqr(z2, dacb_m); // (DA - CB)^2
+ fsqr(x3, dacb_p); // x3 = (DA + CB)^2
+ fadd(b, bb, z3); // BB + 121666 * E
+ fmul(z3, x1, z2); // z3 = x1 * (DA - CB)^2
+ fmul(z2, e, b); // z2 = e * (BB + (DA + CB)^2)
+ }
+
+ finv(z2, z2);
+ fmul(x2, x2, z2);
+ fe51_tobytes(out, x2);
+}
+
+void curve25519_arch(u8 mypublic[CURVE25519_KEY_SIZE],
+ const u8 secret[CURVE25519_KEY_SIZE],
+ const u8 basepoint[CURVE25519_KEY_SIZE])
+{
+ curve25519_fe51(mypublic, secret, basepoint);
+}
+EXPORT_SYMBOL(curve25519_arch);
+
+void curve25519_base_arch(u8 pub[CURVE25519_KEY_SIZE],
+ const u8 secret[CURVE25519_KEY_SIZE])
+{
+ curve25519_fe51(pub, secret, curve25519_base_point);
+}
+EXPORT_SYMBOL(curve25519_base_arch);
+
+static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
+ unsigned int len)
+{
+ u8 *secret = kpp_tfm_ctx(tfm);
+
+ if (!len)
+ curve25519_generate_secret(secret);
+ else if (len == CURVE25519_KEY_SIZE &&
+ crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
+ memcpy(secret, buf, CURVE25519_KEY_SIZE);
+ else
+ return -EINVAL;
+ return 0;
+}
+
+static int curve25519_generate_public_key(struct kpp_request *req)
+{
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+ const u8 *secret = kpp_tfm_ctx(tfm);
+ u8 buf[CURVE25519_KEY_SIZE];
+ int copied, nbytes;
+
+ if (req->src)
+ return -EINVAL;
+
+ curve25519_base_arch(buf, secret);
+
+ /* might want less than we've got */
+ nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
+ copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
+ nbytes),
+ buf, nbytes);
+ if (copied != nbytes)
+ return -EINVAL;
+ return 0;
+}
+
+static int curve25519_compute_shared_secret(struct kpp_request *req)
+{
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+ const u8 *secret = kpp_tfm_ctx(tfm);
+ u8 public_key[CURVE25519_KEY_SIZE];
+ u8 buf[CURVE25519_KEY_SIZE];
+ int copied, nbytes;
+
+ if (!req->src)
+ return -EINVAL;
+
+ copied = sg_copy_to_buffer(req->src,
+ sg_nents_for_len(req->src,
+ CURVE25519_KEY_SIZE),
+ public_key, CURVE25519_KEY_SIZE);
+ if (copied != CURVE25519_KEY_SIZE)
+ return -EINVAL;
+
+ curve25519_arch(buf, secret, public_key);
+
+ /* might want less than we've got */
+ nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
+ copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
+ nbytes),
+ buf, nbytes);
+ if (copied != nbytes)
+ return -EINVAL;
+ return 0;
+}
+
+static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
+{
+ return CURVE25519_KEY_SIZE;
+}
+
+static struct kpp_alg curve25519_alg = {
+ .base.cra_name = "curve25519",
+ .base.cra_driver_name = "curve25519-ppc64le",
+ .base.cra_priority = 200,
+ .base.cra_module = THIS_MODULE,
+ .base.cra_ctxsize = CURVE25519_KEY_SIZE,
+
+ .set_secret = curve25519_set_secret,
+ .generate_public_key = curve25519_generate_public_key,
+ .compute_shared_secret = curve25519_compute_shared_secret,
+ .max_size = curve25519_max_size,
+};
+
+
+static int __init curve25519_mod_init(void)
+{
+ return IS_REACHABLE(CONFIG_CRYPTO_KPP) ?
+ crypto_register_kpp(&curve25519_alg) : 0;
+}
+
+static void __exit curve25519_mod_exit(void)
+{
+ if (IS_REACHABLE(CONFIG_CRYPTO_KPP))
+ crypto_unregister_kpp(&curve25519_alg);
+}
+
+module_init(curve25519_mod_init);
+module_exit(curve25519_mod_exit);
+
+MODULE_ALIAS_CRYPTO("curve25519");
+MODULE_ALIAS_CRYPTO("curve25519-ppc64le");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Danny Tsen <dtsen@us.ibm.com>");
diff --git a/arch/powerpc/crypto/curve25519-ppc64le_asm.S b/arch/powerpc/crypto/curve25519-ppc64le_asm.S
new file mode 100644
index 000000000000..06c1febe24b9
--- /dev/null
+++ b/arch/powerpc/crypto/curve25519-ppc64le_asm.S
@@ -0,0 +1,671 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#
+# This code is taken from CRYPTOGAMs[1] and is included here using the option
+# in the license to distribute the code under the GPL. Therefore this program
+# is free software; you can redistribute it and/or modify it under the terms of
+# the GNU General Public License version 2 as published by the Free Software
+# Foundation.
+#
+# [1] https://github.com/dot-asm/cryptogams/
+
+# Copyright (c) 2006-2017, CRYPTOGAMS by <appro@openssl.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain copyright notices,
+# this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# * Neither the name of the CRYPTOGAMS nor the names of its
+# copyright holder and contributors may be used to endorse or
+# promote products derived from this software without specific
+# prior written permission.
+#
+# ALTERNATIVELY, provided that this notice is retained in full, this
+# product may be distributed under the terms of the GNU General Public
+# License (GPL), in which case the provisions of the GPL apply INSTEAD OF
+# those given above.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see https://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+#
+# ====================================================================
+# Written and Modified by Danny Tsen <dtsen@us.ibm.com>
+# - Added x25519_fe51_sqr_times, x25519_fe51_frombytes, x25519_fe51_tobytes
+# and x25519_cswap
+#
+# Copyright 2024- IBM Corp.
+#
+# X25519 lower-level primitives for PPC64.
+#
+
+#include <linux/linkage.h>
+
+.text
+
+.align 5
+SYM_FUNC_START(x25519_fe51_mul)
+
+ stdu 1,-144(1)
+ std 21,56(1)
+ std 22,64(1)
+ std 23,72(1)
+ std 24,80(1)
+ std 25,88(1)
+ std 26,96(1)
+ std 27,104(1)
+ std 28,112(1)
+ std 29,120(1)
+ std 30,128(1)
+ std 31,136(1)
+
+ ld 6,0(5)
+ ld 7,0(4)
+ ld 8,8(4)
+ ld 9,16(4)
+ ld 10,24(4)
+ ld 11,32(4)
+
+ mulld 22,7,6
+ mulhdu 23,7,6
+
+ mulld 24,8,6
+ mulhdu 25,8,6
+
+ mulld 30,11,6
+ mulhdu 31,11,6
+ ld 4,8(5)
+ mulli 11,11,19
+
+ mulld 26,9,6
+ mulhdu 27,9,6
+
+ mulld 28,10,6
+ mulhdu 29,10,6
+ mulld 12,11,4
+ mulhdu 21,11,4
+ addc 22,22,12
+ adde 23,23,21
+
+ mulld 12,7,4
+ mulhdu 21,7,4
+ addc 24,24,12
+ adde 25,25,21
+
+ mulld 12,10,4
+ mulhdu 21,10,4
+ ld 6,16(5)
+ mulli 10,10,19
+ addc 30,30,12
+ adde 31,31,21
+
+ mulld 12,8,4
+ mulhdu 21,8,4
+ addc 26,26,12
+ adde 27,27,21
+
+ mulld 12,9,4
+ mulhdu 21,9,4
+ addc 28,28,12
+ adde 29,29,21
+ mulld 12,10,6
+ mulhdu 21,10,6
+ addc 22,22,12
+ adde 23,23,21
+
+ mulld 12,11,6
+ mulhdu 21,11,6
+ addc 24,24,12
+ adde 25,25,21
+
+ mulld 12,9,6
+ mulhdu 21,9,6
+ ld 4,24(5)
+ mulli 9,9,19
+ addc 30,30,12
+ adde 31,31,21
+
+ mulld 12,7,6
+ mulhdu 21,7,6
+ addc 26,26,12
+ adde 27,27,21
+
+ mulld 12,8,6
+ mulhdu 21,8,6
+ addc 28,28,12
+ adde 29,29,21
+ mulld 12,9,4
+ mulhdu 21,9,4
+ addc 22,22,12
+ adde 23,23,21
+
+ mulld 12,10,4
+ mulhdu 21,10,4
+ addc 24,24,12
+ adde 25,25,21
+
+ mulld 12,8,4
+ mulhdu 21,8,4
+ ld 6,32(5)
+ mulli 8,8,19
+ addc 30,30,12
+ adde 31,31,21
+
+ mulld 12,11,4
+ mulhdu 21,11,4
+ addc 26,26,12
+ adde 27,27,21
+
+ mulld 12,7,4
+ mulhdu 21,7,4
+ addc 28,28,12
+ adde 29,29,21
+ mulld 12,8,6
+ mulhdu 21,8,6
+ addc 22,22,12
+ adde 23,23,21
+
+ mulld 12,9,6
+ mulhdu 21,9,6
+ addc 24,24,12
+ adde 25,25,21
+
+ mulld 12,10,6
+ mulhdu 21,10,6
+ addc 26,26,12
+ adde 27,27,21
+
+ mulld 12,11,6
+ mulhdu 21,11,6
+ addc 28,28,12
+ adde 29,29,21
+
+ mulld 12,7,6
+ mulhdu 21,7,6
+ addc 30,30,12
+ adde 31,31,21
+
+.Lfe51_reduce:
+ li 0,-1
+ srdi 0,0,13
+
+ srdi 12,26,51
+ and 9,26,0
+ insrdi 12,27,51,0
+ srdi 21,22,51
+ and 7,22,0
+ insrdi 21,23,51,0
+ addc 28,28,12
+ addze 29,29
+ addc 24,24,21
+ addze 25,25
+
+ srdi 12,28,51
+ and 10,28,0
+ insrdi 12,29,51,0
+ srdi 21,24,51
+ and 8,24,0
+ insrdi 21,25,51,0
+ addc 30,30,12
+ addze 31,31
+ add 9,9,21
+
+ srdi 12,30,51
+ and 11,30,0
+ insrdi 12,31,51,0
+ mulli 12,12,19
+
+ add 7,7,12
+
+ srdi 21,9,51
+ and 9,9,0
+ add 10,10,21
+
+ srdi 12,7,51
+ and 7,7,0
+ add 8,8,12
+
+ std 9,16(3)
+ std 10,24(3)
+ std 11,32(3)
+ std 7,0(3)
+ std 8,8(3)
+
+ ld 21,56(1)
+ ld 22,64(1)
+ ld 23,72(1)
+ ld 24,80(1)
+ ld 25,88(1)
+ ld 26,96(1)
+ ld 27,104(1)
+ ld 28,112(1)
+ ld 29,120(1)
+ ld 30,128(1)
+ ld 31,136(1)
+ addi 1,1,144
+ blr
+SYM_FUNC_END(x25519_fe51_mul)
+
+.align 5
+SYM_FUNC_START(x25519_fe51_sqr)
+
+ stdu 1,-144(1)
+ std 21,56(1)
+ std 22,64(1)
+ std 23,72(1)
+ std 24,80(1)
+ std 25,88(1)
+ std 26,96(1)
+ std 27,104(1)
+ std 28,112(1)
+ std 29,120(1)
+ std 30,128(1)
+ std 31,136(1)
+
+ ld 7,0(4)
+ ld 8,8(4)
+ ld 9,16(4)
+ ld 10,24(4)
+ ld 11,32(4)
+
+ add 6,7,7
+ mulli 21,11,19
+
+ mulld 22,7,7
+ mulhdu 23,7,7
+ mulld 24,8,6
+ mulhdu 25,8,6
+ mulld 26,9,6
+ mulhdu 27,9,6
+ mulld 28,10,6
+ mulhdu 29,10,6
+ mulld 30,11,6
+ mulhdu 31,11,6
+ add 6,8,8
+ mulld 12,11,21
+ mulhdu 11,11,21
+ addc 28,28,12
+ adde 29,29,11
+
+ mulli 5,10,19
+
+ mulld 12,8,8
+ mulhdu 11,8,8
+ addc 26,26,12
+ adde 27,27,11
+ mulld 12,9,6
+ mulhdu 11,9,6
+ addc 28,28,12
+ adde 29,29,11
+ mulld 12,10,6
+ mulhdu 11,10,6
+ addc 30,30,12
+ adde 31,31,11
+ mulld 12,21,6
+ mulhdu 11,21,6
+ add 6,10,10
+ addc 22,22,12
+ adde 23,23,11
+ mulld 12,10,5
+ mulhdu 10,10,5
+ addc 24,24,12
+ adde 25,25,10
+ mulld 12,6,21
+ mulhdu 10,6,21
+ add 6,9,9
+ addc 26,26,12
+ adde 27,27,10
+
+ mulld 12,9,9
+ mulhdu 10,9,9
+ addc 30,30,12
+ adde 31,31,10
+ mulld 12,5,6
+ mulhdu 10,5,6
+ addc 22,22,12
+ adde 23,23,10
+ mulld 12,21,6
+ mulhdu 10,21,6
+ addc 24,24,12
+ adde 25,25,10
+
+ b .Lfe51_reduce
+SYM_FUNC_END(x25519_fe51_sqr)
+
+.align 5
+SYM_FUNC_START(x25519_fe51_mul121666)
+
+ stdu 1,-144(1)
+ std 21,56(1)
+ std 22,64(1)
+ std 23,72(1)
+ std 24,80(1)
+ std 25,88(1)
+ std 26,96(1)
+ std 27,104(1)
+ std 28,112(1)
+ std 29,120(1)
+ std 30,128(1)
+ std 31,136(1)
+
+ lis 6,1
+ ori 6,6,56130
+ ld 7,0(4)
+ ld 8,8(4)
+ ld 9,16(4)
+ ld 10,24(4)
+ ld 11,32(4)
+
+ mulld 22,7,6
+ mulhdu 23,7,6
+ mulld 24,8,6
+ mulhdu 25,8,6
+ mulld 26,9,6
+ mulhdu 27,9,6
+ mulld 28,10,6
+ mulhdu 29,10,6
+ mulld 30,11,6
+ mulhdu 31,11,6
+
+ b .Lfe51_reduce
+SYM_FUNC_END(x25519_fe51_mul121666)
+
+.align 5
+SYM_FUNC_START(x25519_fe51_sqr_times)
+
+ stdu 1,-144(1)
+ std 21,56(1)
+ std 22,64(1)
+ std 23,72(1)
+ std 24,80(1)
+ std 25,88(1)
+ std 26,96(1)
+ std 27,104(1)
+ std 28,112(1)
+ std 29,120(1)
+ std 30,128(1)
+ std 31,136(1)
+
+ ld 7,0(4)
+ ld 8,8(4)
+ ld 9,16(4)
+ ld 10,24(4)
+ ld 11,32(4)
+
+ mtctr 5
+
+.Lsqr_times_loop:
+ add 6,7,7
+ mulli 21,11,19
+
+ mulld 22,7,7
+ mulhdu 23,7,7
+ mulld 24,8,6
+ mulhdu 25,8,6
+ mulld 26,9,6
+ mulhdu 27,9,6
+ mulld 28,10,6
+ mulhdu 29,10,6
+ mulld 30,11,6
+ mulhdu 31,11,6
+ add 6,8,8
+ mulld 12,11,21
+ mulhdu 11,11,21
+ addc 28,28,12
+ adde 29,29,11
+
+ mulli 5,10,19
+
+ mulld 12,8,8
+ mulhdu 11,8,8
+ addc 26,26,12
+ adde 27,27,11
+ mulld 12,9,6
+ mulhdu 11,9,6
+ addc 28,28,12
+ adde 29,29,11
+ mulld 12,10,6
+ mulhdu 11,10,6
+ addc 30,30,12
+ adde 31,31,11
+ mulld 12,21,6
+ mulhdu 11,21,6
+ add 6,10,10
+ addc 22,22,12
+ adde 23,23,11
+ mulld 12,10,5
+ mulhdu 10,10,5
+ addc 24,24,12
+ adde 25,25,10
+ mulld 12,6,21
+ mulhdu 10,6,21
+ add 6,9,9
+ addc 26,26,12
+ adde 27,27,10
+
+ mulld 12,9,9
+ mulhdu 10,9,9
+ addc 30,30,12
+ adde 31,31,10
+ mulld 12,5,6
+ mulhdu 10,5,6
+ addc 22,22,12
+ adde 23,23,10
+ mulld 12,21,6
+ mulhdu 10,21,6
+ addc 24,24,12
+ adde 25,25,10
+
+ # fe51_reduce
+ li 0,-1
+ srdi 0,0,13
+
+ srdi 12,26,51
+ and 9,26,0
+ insrdi 12,27,51,0
+ srdi 21,22,51
+ and 7,22,0
+ insrdi 21,23,51,0
+ addc 28,28,12
+ addze 29,29
+ addc 24,24,21
+ addze 25,25
+
+ srdi 12,28,51
+ and 10,28,0
+ insrdi 12,29,51,0
+ srdi 21,24,51
+ and 8,24,0
+ insrdi 21,25,51,0
+ addc 30,30,12
+ addze 31,31
+ add 9,9,21
+
+ srdi 12,30,51
+ and 11,30,0
+ insrdi 12,31,51,0
+ mulli 12,12,19
+
+ add 7,7,12
+
+ srdi 21,9,51
+ and 9,9,0
+ add 10,10,21
+
+ srdi 12,7,51
+ and 7,7,0
+ add 8,8,12
+
+ bdnz .Lsqr_times_loop
+
+ std 9,16(3)
+ std 10,24(3)
+ std 11,32(3)
+ std 7,0(3)
+ std 8,8(3)
+
+ ld 21,56(1)
+ ld 22,64(1)
+ ld 23,72(1)
+ ld 24,80(1)
+ ld 25,88(1)
+ ld 26,96(1)
+ ld 27,104(1)
+ ld 28,112(1)
+ ld 29,120(1)
+ ld 30,128(1)
+ ld 31,136(1)
+ addi 1,1,144
+ blr
+SYM_FUNC_END(x25519_fe51_sqr_times)
+
+.align 5
+SYM_FUNC_START(x25519_fe51_frombytes)
+
+ li 12, -1
+ srdi 12, 12, 13 # 0x7ffffffffffff
+
+ ld 5, 0(4)
+ ld 6, 8(4)
+ ld 7, 16(4)
+ ld 8, 24(4)
+
+ srdi 10, 5, 51
+ and 5, 5, 12 # h0
+
+ sldi 11, 6, 13
+ or 11, 10, 11 # h1t
+ srdi 10, 6, 38
+ and 6, 11, 12 # h1
+
+ sldi 11, 7, 26
+ or 10, 10, 11 # h2t
+
+ srdi 11, 7, 25
+ and 7, 10, 12 # h2
+ sldi 10, 8, 39
+ or 11, 11, 10 # h3t
+
+ srdi 9, 8, 12
+ and 8, 11, 12 # h3
+ and 9, 9, 12 # h4
+
+ std 5, 0(3)
+ std 6, 8(3)
+ std 7, 16(3)
+ std 8, 24(3)
+ std 9, 32(3)
+
+ blr
+SYM_FUNC_END(x25519_fe51_frombytes)
+
+.align 5
+SYM_FUNC_START(x25519_fe51_tobytes)
+
+ ld 5, 0(4)
+ ld 6, 8(4)
+ ld 7, 16(4)
+ ld 8, 24(4)
+ ld 9, 32(4)
+
+ li 12, -1
+ srdi 12, 12, 13 # 0x7ffffffffffff
+
+ # Full reducuction
+ addi 10, 5, 19
+ srdi 10, 10, 51
+ add 10, 10, 6
+ srdi 10, 10, 51
+ add 10, 10, 7
+ srdi 10, 10, 51
+ add 10, 10, 8
+ srdi 10, 10, 51
+ add 10, 10, 9
+ srdi 10, 10, 51
+
+ mulli 10, 10, 19
+ add 5, 5, 10
+ srdi 11, 5, 51
+ add 6, 6, 11
+ srdi 11, 6, 51
+ add 7, 7, 11
+ srdi 11, 7, 51
+ add 8, 8, 11
+ srdi 11, 8, 51
+ add 9, 9, 11
+
+ and 5, 5, 12
+ and 6, 6, 12
+ and 7, 7, 12
+ and 8, 8, 12
+ and 9, 9, 12
+
+ sldi 10, 6, 51
+ or 5, 5, 10 # s0
+
+ srdi 11, 6, 13
+ sldi 10, 7, 38
+ or 6, 11, 10 # s1
+
+ srdi 11, 7, 26
+ sldi 10, 8, 25
+ or 7, 11, 10 # s2
+
+ srdi 11, 8, 39
+ sldi 10, 9, 12
+ or 8, 11, 10 # s4
+
+ std 5, 0(3)
+ std 6, 8(3)
+ std 7, 16(3)
+ std 8, 24(3)
+
+ blr
+SYM_FUNC_END(x25519_fe51_tobytes)
+
+.align 5
+SYM_FUNC_START(x25519_cswap)
+
+ li 7, 5
+ neg 6, 5
+ mtctr 7
+
+.Lswap_loop:
+ ld 8, 0(3)
+ ld 9, 0(4)
+ xor 10, 8, 9
+ and 10, 10, 6
+ xor 11, 8, 10
+ xor 12, 9, 10
+ std 11, 0(3)
+ addi 3, 3, 8
+ std 12, 0(4)
+ addi 4, 4, 8
+ bdnz .Lswap_loop
+
+ blr
+SYM_FUNC_END(x25519_cswap)
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index 61a8d5555cd7..e5fdc336c9b2 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -6,5 +6,4 @@ generic-y += agp.h
generic-y += kvm_types.h
generic-y += mcs_spinlock.h
generic-y += qrwlock.h
-generic-y += vtime.h
generic-y += early_ioremap.h
diff --git a/arch/powerpc/include/asm/book3s/32/pgalloc.h b/arch/powerpc/include/asm/book3s/32/pgalloc.h
index dc5c039eb28e..dd4eb3063175 100644
--- a/arch/powerpc/include/asm/book3s/32/pgalloc.h
+++ b/arch/powerpc/include/asm/book3s/32/pgalloc.h
@@ -47,8 +47,6 @@ static inline void pgtable_free(void *table, unsigned index_size)
}
}
-#define get_hugepd_cache_index(x) (x)
-
static inline void pgtable_free_tlb(struct mmu_gather *tlb,
void *table, int shift)
{
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index 6472b08fa1b0..c654c376ef8b 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -74,21 +74,6 @@
#define remap_4k_pfn(vma, addr, pfn, prot) \
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
-#ifdef CONFIG_HUGETLB_PAGE
-static inline int hash__hugepd_ok(hugepd_t hpd)
-{
- unsigned long hpdval = hpd_val(hpd);
- /*
- * if it is not a pte and have hugepd shift mask
- * set, then it is a hugepd directory pointer
- */
- if (!(hpdval & _PAGE_PTE) && (hpdval & _PAGE_PRESENT) &&
- ((hpdval & HUGEPD_SHIFT_MASK) != 0))
- return true;
- return false;
-}
-#endif
-
/*
* 4K PTE format is different from 64K PTE format. Saving the hash_slot is just
* a matter of returning the PTE bits that need to be modified. On 64K PTE,
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index faf3e3b4e4b2..0755f2567021 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -4,6 +4,7 @@
#ifdef __KERNEL__
#include <asm/asm-const.h>
+#include <asm/book3s/64/slice.h>
/*
* Common bits between 4K and 64K pages in a linux-style PTE.
@@ -161,14 +162,10 @@ extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long pte, int huge);
unsigned long htab_convert_pte_flags(unsigned long pteflags, unsigned long flags);
/* Atomic PTE updates */
-static inline unsigned long hash__pte_update(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, unsigned long clr,
- unsigned long set,
- int huge)
+static inline unsigned long hash__pte_update_one(pte_t *ptep, unsigned long clr,
+ unsigned long set)
{
__be64 old_be, tmp_be;
- unsigned long old;
__asm__ __volatile__(
"1: ldarx %0,0,%3 # pte_update\n\
@@ -182,11 +179,40 @@ static inline unsigned long hash__pte_update(struct mm_struct *mm,
: "r" (ptep), "r" (cpu_to_be64(clr)), "m" (*ptep),
"r" (cpu_to_be64(H_PAGE_BUSY)), "r" (cpu_to_be64(set))
: "cc" );
+
+ return be64_to_cpu(old_be);
+}
+
+static inline unsigned long hash__pte_update(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, unsigned long clr,
+ unsigned long set,
+ int huge)
+{
+ unsigned long old;
+
+ old = hash__pte_update_one(ptep, clr, set);
+
+ if (IS_ENABLED(CONFIG_PPC_4K_PAGES) && huge) {
+ unsigned int psize = get_slice_psize(mm, addr);
+ int nb, i;
+
+ if (psize == MMU_PAGE_16M)
+ nb = SZ_16M / PMD_SIZE;
+ else if (psize == MMU_PAGE_16G)
+ nb = SZ_16G / PUD_SIZE;
+ else
+ nb = 1;
+
+ WARN_ON_ONCE(nb == 1); /* Should never happen */
+
+ for (i = 1; i < nb; i++)
+ hash__pte_update_one(ptep + i, clr, set);
+ }
/* huge pages use the old page table lock */
if (!huge)
assert_pte_locked(mm, addr);
- old = be64_to_cpu(old_be);
if (old & H_PAGE_HASHPTE)
hpte_need_flush(mm, addr, ptep, old, huge);
diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index aa1c67c8bfc8..f0bba9c5f9c3 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -49,9 +49,6 @@ static inline bool gigantic_page_runtime_supported(void)
return true;
}
-/* hugepd entry valid bit */
-#define HUGEPD_VAL_BITS (0x8000000000000000UL)
-
#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep);
@@ -60,29 +57,7 @@ extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
extern void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t old_pte, pte_t new_pte);
-/*
- * This should work for other subarchs too. But right now we use the
- * new format only for 64bit book3s
- */
-static inline pte_t *hugepd_page(hugepd_t hpd)
-{
- BUG_ON(!hugepd_ok(hpd));
- /*
- * We have only four bits to encode, MMU page size
- */
- BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
- return __va(hpd_val(hpd) & HUGEPD_ADDR_MASK);
-}
-
-static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
-{
- return (hpd_val(hpd) & HUGEPD_SHIFT_MASK) >> 2;
-}
-static inline unsigned int hugepd_shift(hugepd_t hpd)
-{
- return mmu_psize_to_shift(hugepd_mmu_psize(hpd));
-}
static inline void flush_hugetlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
@@ -90,19 +65,6 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
return radix__flush_hugetlb_page(vma, vmaddr);
}
-static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
- unsigned int pdshift)
-{
- unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd);
-
- return hugepd_page(hpd) + idx;
-}
-
-static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
-{
- *hpdp = __hugepd(__pa(new) | HUGEPD_VAL_BITS | (shift_to_mmu_psize(pshift) << 2));
-}
-
void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
static inline int check_and_get_huge_psize(int shift)
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-4k.h b/arch/powerpc/include/asm/book3s/64/pgtable-4k.h
deleted file mode 100644
index 48f21820afe2..000000000000
--- a/arch/powerpc/include/asm/book3s/64/pgtable-4k.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_4K_H
-#define _ASM_POWERPC_BOOK3S_64_PGTABLE_4K_H
-/*
- * hash 4k can't share hugetlb and also doesn't support THP
- */
-#ifndef __ASSEMBLY__
-#ifdef CONFIG_HUGETLB_PAGE
-static inline int pmd_huge(pmd_t pmd)
-{
- /*
- * leaf pte for huge page
- */
- if (radix_enabled())
- return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
- return 0;
-}
-
-static inline int pud_huge(pud_t pud)
-{
- /*
- * leaf pte for huge page
- */
- if (radix_enabled())
- return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
- return 0;
-}
-
-/*
- * With radix , we have hugepage ptes in the pud and pmd entries. We don't
- * need to setup hugepage directory for them. Our pte and page directory format
- * enable us to have this enabled.
- */
-static inline int hugepd_ok(hugepd_t hpd)
-{
- if (radix_enabled())
- return 0;
- return hash__hugepd_ok(hpd);
-}
-#define is_hugepd(hpd) (hugepd_ok(hpd))
-
-/*
- * 16M and 16G huge page directory tables are allocated from slab cache
- *
- */
-#define H_16M_CACHE_INDEX (PAGE_SHIFT + H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE - 24)
-#define H_16G_CACHE_INDEX \
- (PAGE_SHIFT + H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE + H_PUD_INDEX_SIZE - 34)
-
-static inline int get_hugepd_cache_index(int index)
-{
- switch (index) {
- case H_16M_CACHE_INDEX:
- return HTLB_16M_INDEX;
- case H_16G_CACHE_INDEX:
- return HTLB_16G_INDEX;
- default:
- BUG();
- }
- /* should not reach */
-}
-
-#endif /* CONFIG_HUGETLB_PAGE */
-
-#endif /* __ASSEMBLY__ */
-
-#endif /*_ASM_POWERPC_BOOK3S_64_PGTABLE_4K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h
index ced7ee8b42fc..4d8d7b4ea16b 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h
@@ -4,51 +4,6 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_HUGETLB_PAGE
-/*
- * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have
- * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD;
- *
- * Defined in such a way that we can optimize away code block at build time
- * if CONFIG_HUGETLB_PAGE=n.
- *
- * returns true for pmd migration entries, THP, devmap, hugetlb
- * But compile time dependent on CONFIG_HUGETLB_PAGE
- */
-static inline int pmd_huge(pmd_t pmd)
-{
- /*
- * leaf pte for huge page
- */
- return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
-}
-
-static inline int pud_huge(pud_t pud)
-{
- /*
- * leaf pte for huge page
- */
- return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
-}
-
-/*
- * With 64k page size, we have hugepage ptes in the pgd and pmd entries. We don't
- * need to setup hugepage directory for them. Our pte and page directory format
- * enable us to have this enabled.
- */
-static inline int hugepd_ok(hugepd_t hpd)
-{
- return 0;
-}
-
-#define is_hugepd(pdep) 0
-
-/*
- * This should never get called
- */
-static __always_inline int get_hugepd_cache_index(int index)
-{
- BUILD_BUG();
-}
#endif /* CONFIG_HUGETLB_PAGE */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index fac5615e6bc5..519b1743a0f4 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -262,6 +262,36 @@ extern unsigned long __kernel_io_end;
extern struct page *vmemmap;
extern unsigned long pci_io_base;
+
+#define pmd_leaf pmd_leaf
+static inline bool pmd_leaf(pmd_t pmd)
+{
+ return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
+}
+
+#define pud_leaf pud_leaf
+static inline bool pud_leaf(pud_t pud)
+{
+ return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
+}
+
+#define pmd_leaf_size pmd_leaf_size
+static inline unsigned long pmd_leaf_size(pmd_t pmd)
+{
+ if (IS_ENABLED(CONFIG_PPC_4K_PAGES) && !radix_enabled())
+ return SZ_16M;
+ else
+ return PMD_SIZE;
+}
+
+#define pud_leaf_size pud_leaf_size
+static inline unsigned long pud_leaf_size(pud_t pud)
+{
+ if (IS_ENABLED(CONFIG_PPC_4K_PAGES) && !radix_enabled())
+ return SZ_16G;
+ else
+ return PUD_SIZE;
+}
#endif /* __ASSEMBLY__ */
#include <asm/book3s/64/hash.h>
@@ -273,11 +303,9 @@ extern unsigned long pci_io_base;
#define MAX_PHYSMEM_BITS R_MAX_PHYSMEM_BITS
#endif
-
+/* hash 4k can't share hugetlb and also doesn't support THP */
#ifdef CONFIG_PPC_64K_PAGES
#include <asm/book3s/64/pgtable-64k.h>
-#else
-#include <asm/book3s/64/pgtable-4k.h>
#endif
#include <asm/barrier.h>
@@ -1426,20 +1454,5 @@ static inline bool is_pte_rw_upgrade(unsigned long old_val, unsigned long new_va
return false;
}
-/*
- * Like pmd_huge(), but works regardless of config options
- */
-#define pmd_leaf pmd_leaf
-static inline bool pmd_leaf(pmd_t pmd)
-{
- return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
-}
-
-#define pud_leaf pud_leaf
-static inline bool pud_leaf(pud_t pud)
-{
- return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
-}
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h
index ef7d2de33b89..f2656774aaa9 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -121,7 +121,7 @@ static inline void invalidate_dcache_range(unsigned long start,
mb(); /* sync */
}
-#ifdef CONFIG_4xx
+#ifdef CONFIG_44x
static inline void flush_instruction_cache(void)
{
iccci((void *)KERNELBASE);
diff --git a/arch/powerpc/include/asm/cpu_has_feature.h b/arch/powerpc/include/asm/cpu_has_feature.h
index 727d4b321937..bf8a228229fa 100644
--- a/arch/powerpc/include/asm/cpu_has_feature.h
+++ b/arch/powerpc/include/asm/cpu_has_feature.h
@@ -24,12 +24,11 @@ static __always_inline bool cpu_has_feature(unsigned long feature)
{
int i;
-#ifndef __clang__ /* clang can't cope with this */
BUILD_BUG_ON(!__builtin_constant_p(feature));
-#endif
+ BUILD_BUG_ON(__builtin_popcountl(feature) > 1);
#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
- if (!static_key_initialized) {
+ if (!static_key_feature_checks_initialized) {
printk("Warning! cpu_has_feature() used prior to jump label init!\n");
dump_stack();
return early_cpu_has_feature(feature);
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 07a204d21034..201218faed61 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -353,7 +353,6 @@ static inline void cpu_feature_keys_init(void) { }
CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON)
#define CPU_FTRS_8XX (CPU_FTR_NOEXECUTE)
-#define CPU_FTRS_40X (CPU_FTR_NOEXECUTE)
#define CPU_FTRS_44X (CPU_FTR_NOEXECUTE)
#define CPU_FTRS_440x6 (CPU_FTR_NOEXECUTE | \
CPU_FTR_INDEXED_DCR)
@@ -507,9 +506,6 @@ enum {
#ifdef CONFIG_PPC_8xx
CPU_FTRS_8XX |
#endif
-#ifdef CONFIG_40x
- CPU_FTRS_40X |
-#endif
#ifdef CONFIG_PPC_47x
CPU_FTRS_47X | CPU_FTR_476_DD2 |
#elif defined(CONFIG_44x)
@@ -582,9 +578,6 @@ enum {
#ifdef CONFIG_PPC_8xx
CPU_FTRS_8XX &
#endif
-#ifdef CONFIG_40x
- CPU_FTRS_40X &
-#endif
#ifdef CONFIG_PPC_47x
CPU_FTRS_47X &
#elif defined(CONFIG_44x)
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index 4961fb38e438..aff858ca99c0 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -32,23 +32,10 @@
#ifdef CONFIG_PPC64
#define get_accounting(tsk) (&get_paca()->accounting)
#define raw_get_accounting(tsk) (&local_paca->accounting)
-static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
#else
#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
#define raw_get_accounting(tsk) get_accounting(tsk)
-/*
- * Called from the context switch with interrupts disabled, to charge all
- * accumulated times to the current process, and to prepare accounting on
- * the next process.
- */
-static inline void arch_vtime_task_switch(struct task_struct *prev)
-{
- struct cpu_accounting_data *acct = get_accounting(current);
- struct cpu_accounting_data *acct0 = get_accounting(prev);
-
- acct->starttime = acct0->starttime;
-}
#endif
/*
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 514dd056c2c8..91a9fd53254f 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -82,7 +82,7 @@ struct eeh_pe {
int false_positives; /* Times of reported #ff's */
atomic_t pass_dev_cnt; /* Count of passed through devs */
struct eeh_pe *parent; /* Parent PE */
- void *data; /* PE auxillary data */
+ void *data; /* PE auxiliary data */
struct list_head child_list; /* List of PEs below this PE */
struct list_head child; /* Memb. child_list/eeh_phb_pe */
struct list_head edevs; /* List of eeh_dev in this PE */
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 79f1c480b5eb..bb4b94444d3e 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -127,8 +127,6 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
/* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
#define NT_SPU 1
-#define ARCH_HAVE_EXTRA_ELF_NOTES
-
#endif /* CONFIG_SPU_BASE */
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h
index 27f9e11eda28..e83869a4eb6a 100644
--- a/arch/powerpc/include/asm/fadump-internal.h
+++ b/arch/powerpc/include/asm/fadump-internal.h
@@ -42,13 +42,38 @@ static inline u64 fadump_str_to_u64(const char *str)
#define FADUMP_CPU_UNKNOWN (~((u32)0))
-#define FADUMP_CRASH_INFO_MAGIC fadump_str_to_u64("FADMPINF")
+/*
+ * The introduction of new fields in the fadump crash info header has
+ * led to a change in the magic key from `FADMPINF` to `FADMPSIG` for
+ * identifying a kernel crash from an old kernel.
+ *
+ * To prevent the need for further changes to the magic number in the
+ * event of future modifications to the fadump crash info header, a
+ * version field has been introduced to track the fadump crash info
+ * header version.
+ *
+ * Consider a few points before adding new members to the fadump crash info
+ * header structure:
+ *
+ * - Append new members; avoid adding them in between.
+ * - Non-primitive members should have a size member as well.
+ * - For every change in the fadump header, increment the
+ * fadump header version. This helps the updated kernel decide how to
+ * handle kernel dumps from older kernels.
+ */
+#define FADUMP_CRASH_INFO_MAGIC_OLD fadump_str_to_u64("FADMPINF")
+#define FADUMP_CRASH_INFO_MAGIC fadump_str_to_u64("FADMPSIG")
+#define FADUMP_HEADER_VERSION 1
/* fadump crash info structure */
struct fadump_crash_info_header {
u64 magic_number;
- u64 elfcorehdr_addr;
+ u32 version;
u32 crashing_cpu;
+ u64 vmcoreinfo_raddr;
+ u64 vmcoreinfo_size;
+ u32 pt_regs_sz;
+ u32 cpu_mask_sz;
struct pt_regs regs;
struct cpumask cpu_mask;
};
@@ -94,9 +119,13 @@ struct fw_dump {
u64 boot_mem_regs_cnt;
unsigned long fadumphdr_addr;
+ u64 elfcorehdr_addr;
+ u64 elfcorehdr_size;
unsigned long cpu_notes_buf_vaddr;
unsigned long cpu_notes_buf_size;
+ unsigned long param_area;
+
/*
* Maximum size supported by firmware to copy from source to
* destination address per entry.
@@ -111,6 +140,7 @@ struct fw_dump {
unsigned long dump_active:1;
unsigned long dump_registered:1;
unsigned long nocma:1;
+ unsigned long param_area_supported:1;
struct fadump_ops *ops;
};
@@ -129,6 +159,7 @@ struct fadump_ops {
struct seq_file *m);
void (*fadump_trigger)(struct fadump_crash_info_header *fdh,
const char *msg);
+ int (*fadump_max_boot_mem_rgns)(void);
};
/* Helper functions */
@@ -136,7 +167,6 @@ s32 __init fadump_setup_cpu_notes_buf(u32 num_cpus);
void fadump_free_cpu_notes_buf(void);
u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs);
void __init fadump_update_elfcore_header(char *bufp);
-bool is_fadump_boot_mem_contiguous(void);
bool is_fadump_reserved_mem_contiguous(void);
#else /* !CONFIG_PRESERVE_FA_DUMP */
diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
index 526a6a647312..ef40c9b6972a 100644
--- a/arch/powerpc/include/asm/fadump.h
+++ b/arch/powerpc/include/asm/fadump.h
@@ -19,12 +19,14 @@ extern int is_fadump_active(void);
extern int should_fadump_crash(void);
extern void crash_fadump(struct pt_regs *, const char *);
extern void fadump_cleanup(void);
+extern void fadump_append_bootargs(void);
#else /* CONFIG_FA_DUMP */
static inline int is_fadump_active(void) { return 0; }
static inline int should_fadump_crash(void) { return 0; }
static inline void crash_fadump(struct pt_regs *regs, const char *str) { }
static inline void fadump_cleanup(void) { }
+static inline void fadump_append_bootargs(void) { }
#endif /* !CONFIG_FA_DUMP */
#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP)
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
index 77824bd289a3..17d168dd8b49 100644
--- a/arch/powerpc/include/asm/feature-fixups.h
+++ b/arch/powerpc/include/asm/feature-fixups.h
@@ -291,6 +291,8 @@ extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;
+extern bool static_key_feature_checks_initialized;
+
void apply_feature_fixups(void);
void update_mmu_feature_fixups(unsigned long mask);
void setup_feature_keys(void);
diff --git a/arch/powerpc/include/asm/fpu.h b/arch/powerpc/include/asm/fpu.h
new file mode 100644
index 000000000000..ca584e4bc40f
--- /dev/null
+++ b/arch/powerpc/include/asm/fpu.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 SiFive
+ */
+
+#ifndef _ASM_POWERPC_FPU_H
+#define _ASM_POWERPC_FPU_H
+
+#include <linux/preempt.h>
+
+#include <asm/cpu_has_feature.h>
+#include <asm/switch_to.h>
+
+#define kernel_fpu_available() (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE))
+
+static inline void kernel_fpu_begin(void)
+{
+ preempt_disable();
+ enable_kernel_fp();
+}
+
+static inline void kernel_fpu_end(void)
+{
+ disable_kernel_fp();
+ preempt_enable();
+}
+
+#endif /* ! _ASM_POWERPC_FPU_H */
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
index 107fc5a48456..559560286e6d 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -8,8 +8,6 @@
#define MCOUNT_ADDR ((unsigned long)(_mcount))
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
-
/* Ignore unused weak functions which will have larger offsets */
#if defined(CONFIG_MPROFILE_KERNEL) || defined(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)
#define FTRACE_MCOUNT_MAX_OFFSET 16
diff --git a/arch/powerpc/include/asm/guest-state-buffer.h b/arch/powerpc/include/asm/guest-state-buffer.h
index 808149f31576..d107abe1468f 100644
--- a/arch/powerpc/include/asm/guest-state-buffer.h
+++ b/arch/powerpc/include/asm/guest-state-buffer.h
@@ -81,6 +81,7 @@
#define KVMPPC_GSID_HASHKEYR 0x1050
#define KVMPPC_GSID_HASHPKEYR 0x1051
#define KVMPPC_GSID_CTRL 0x1052
+#define KVMPPC_GSID_DPDES 0x1053
#define KVMPPC_GSID_CR 0x2000
#define KVMPPC_GSID_PIDR 0x2001
@@ -110,7 +111,7 @@
#define KVMPPC_GSE_META_COUNT (KVMPPC_GSE_META_END - KVMPPC_GSE_META_START + 1)
#define KVMPPC_GSE_DW_REGS_START KVMPPC_GSID_GPR(0)
-#define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_CTRL
+#define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_DPDES
#define KVMPPC_GSE_DW_REGS_COUNT \
(KVMPPC_GSE_DW_REGS_END - KVMPPC_GSE_DW_REGS_START + 1)
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index ea71f7245a63..18a3028ac3b6 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -30,10 +30,9 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
}
#define is_hugepage_only_range is_hugepage_only_range
-#define __HAVE_ARCH_HUGETLB_FREE_PGD_RANGE
-void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
- unsigned long end, unsigned long floor,
- unsigned long ceiling);
+#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte, unsigned long sz);
#define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
@@ -67,14 +66,6 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
{
}
-#define hugepd_shift(x) 0
-static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
- unsigned pdshift)
-{
- return NULL;
-}
-
-
static inline void __init gigantic_hugetlb_cma_reserve(void)
{
}
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index a41e542ba94d..7a8495660c2f 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -524,7 +524,7 @@ long plpar_hcall_norets_notrace(unsigned long opcode, ...);
* Used for all but the craziest of phyp interfaces (see plpar_hcall9)
*/
#define PLPAR_HCALL_BUFSIZE 4
-long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...);
/**
* plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats
@@ -538,7 +538,7 @@ long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
* plpar_hcall, but plpar_hcall_raw works in real mode and does not
* calculate hypervisor call statistics.
*/
-long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...);
/**
* plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments
@@ -549,8 +549,8 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
* PLPAR_HCALL9_BUFSIZE to size the return argument buffer.
*/
#define PLPAR_HCALL9_BUFSIZE 9
-long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
-long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...);
+long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...);
/* pseries hcall tracing */
extern struct static_key hcall_tracepoint_key;
@@ -570,7 +570,7 @@ struct hvcall_mpp_data {
unsigned long backing_mem;
};
-int h_get_mpp(struct hvcall_mpp_data *);
+long h_get_mpp(struct hvcall_mpp_data *mpp_data);
struct hvcall_mpp_x_data {
unsigned long coalesced_bytes;
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 317659fdeacf..569ac1165b06 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -63,7 +63,7 @@
static inline void __hard_irq_enable(void)
{
- if (IS_ENABLED(CONFIG_BOOKE_OR_40x))
+ if (IS_ENABLED(CONFIG_BOOKE))
wrtee(MSR_EE);
else if (IS_ENABLED(CONFIG_PPC_8xx))
wrtspr(SPRN_EIE);
@@ -75,7 +75,7 @@ static inline void __hard_irq_enable(void)
static inline void __hard_irq_disable(void)
{
- if (IS_ENABLED(CONFIG_BOOKE_OR_40x))
+ if (IS_ENABLED(CONFIG_BOOKE))
wrtee(0);
else if (IS_ENABLED(CONFIG_PPC_8xx))
wrtspr(SPRN_EID);
@@ -87,7 +87,7 @@ static inline void __hard_irq_disable(void)
static inline void __hard_EE_RI_disable(void)
{
- if (IS_ENABLED(CONFIG_BOOKE_OR_40x))
+ if (IS_ENABLED(CONFIG_BOOKE))
wrtee(0);
else if (IS_ENABLED(CONFIG_PPC_8xx))
wrtspr(SPRN_NRI);
@@ -99,7 +99,7 @@ static inline void __hard_EE_RI_disable(void)
static inline void __hard_RI_enable(void)
{
- if (IS_ENABLED(CONFIG_BOOKE_OR_40x))
+ if (IS_ENABLED(CONFIG_BOOKE))
return;
if (IS_ENABLED(CONFIG_PPC_8xx))
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index 7b610864b364..2d6c886b40f4 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -336,6 +336,14 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte
if (IS_ENABLED(CONFIG_KASAN))
return;
+ /*
+ * Likewise, do not use it in real mode if percpu first chunk is not
+ * embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled there
+ * are chances where percpu allocation can come from vmalloc area.
+ */
+ if (percpu_first_chunk_is_paged)
+ return;
+
/* Otherwise, it should be safe to call it */
nmi_enter();
}
@@ -351,6 +359,8 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter
// no nmi_exit for a pseries hash guest taking a real mode exception
} else if (IS_ENABLED(CONFIG_KASAN)) {
// no nmi_exit for KASAN in real mode
+ } else if (percpu_first_chunk_is_paged) {
+ // no nmi_exit if percpu first chunk is not embedded
} else {
nmi_exit();
}
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 08c550ed49be..52e1b1d15ff6 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -37,7 +37,7 @@ extern struct pci_dev *isa_bridge_pcidev;
* define properly based on the platform
*/
#ifndef CONFIG_PCI
-#define _IO_BASE 0
+#define _IO_BASE POISON_POINTER_DELTA
#define _ISA_MEM_BASE 0
#define PCI_DRAM_OFFSET 0
#elif defined(CONFIG_PPC32)
@@ -585,12 +585,12 @@ __do_out_asm(_rec_outl, "stwbrx")
#define __do_inw(port) _rec_inw(port)
#define __do_inl(port) _rec_inl(port)
#else /* CONFIG_PPC32 */
-#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port);
-#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port);
-#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port);
-#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port);
-#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port);
-#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port);
+#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)(_IO_BASE+port));
+#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)(_IO_BASE+port));
+#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)(_IO_BASE+port));
+#define __do_inb(port) readb((PCI_IO_ADDR)(_IO_BASE + port));
+#define __do_inw(port) readw((PCI_IO_ADDR)(_IO_BASE + port));
+#define __do_inl(port) readl((PCI_IO_ADDR)(_IO_BASE + port));
#endif /* !CONFIG_PPC32 */
#ifdef CONFIG_EEH
@@ -606,12 +606,12 @@ __do_out_asm(_rec_outl, "stwbrx")
#define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n))
#define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n))
-#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
-#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
-#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
-#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
-#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
-#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
+#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
+#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
+#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
+#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
+#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
+#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
#define __do_memset_io(addr, c, n) \
_memset_io(PCI_FIX_ADDR(addr), c, n)
@@ -982,7 +982,7 @@ static inline phys_addr_t page_to_phys(struct page *page)
}
/*
- * 32 bits still uses virt_to_bus() for it's implementation of DMA
+ * 32 bits still uses virt_to_bus() for its implementation of DMA
* mappings se we have to keep it defined here. We also have some old
* drivers (shame shame shame) that use bus_to_virt() and haven't been
* fixed yet so I need to define it here.
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 026695943550..04072b5f8962 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -31,6 +31,8 @@
#define DIRECT64_PROPNAME "linux,direct64-ddr-window-info"
#define DMA64_PROPNAME "linux,dma64-ddr-window-info"
+#define MIN_DDW_VPMEM_DMA_WINDOW SZ_2G
+
/* Boot time flags */
extern int iommu_is_off;
extern int iommu_force_on;
@@ -156,6 +158,9 @@ extern int iommu_tce_table_put(struct iommu_table *tbl);
extern struct iommu_table *iommu_init_table(struct iommu_table *tbl,
int nid, unsigned long res_start, unsigned long res_end);
bool iommu_table_in_use(struct iommu_table *tbl);
+extern void iommu_table_reserve_pages(struct iommu_table *tbl,
+ unsigned long res_start, unsigned long res_end);
+extern void iommu_table_clear(struct iommu_table *tbl);
#define IOMMU_TABLE_GROUP_MAX_TABLES 2
@@ -178,9 +183,9 @@ struct iommu_table_group_ops {
long (*unset_window)(struct iommu_table_group *table_group,
int num);
/* Switch ownership from platform code to external user (e.g. VFIO) */
- long (*take_ownership)(struct iommu_table_group *table_group);
+ long (*take_ownership)(struct iommu_table_group *table_group, struct device *dev);
/* Switch ownership from external user (e.g. VFIO) back to core */
- void (*release_ownership)(struct iommu_table_group *table_group);
+ void (*release_ownership)(struct iommu_table_group *table_group, struct device *dev);
};
struct iommu_table_group_link {
@@ -217,8 +222,8 @@ extern long iommu_tce_xchg_no_kill(struct mm_struct *mm,
enum dma_data_direction *direction);
extern void iommu_tce_kill(struct iommu_table *tbl,
unsigned long entry, unsigned long pages);
+int dev_has_iommu_table(struct device *dev, void *data);
-extern struct iommu_table_group_ops spapr_tce_table_group_ops;
#else
static inline void iommu_register_group(struct iommu_table_group *table_group,
int pci_domain_number,
@@ -231,6 +236,11 @@ static inline int iommu_add_device(struct iommu_table_group *table_group,
{
return 0;
}
+
+static inline int dev_has_iommu_table(struct device *dev, void *data)
+{
+ return 0;
+}
#endif /* !CONFIG_IOMMU_API */
u64 dma_iommu_get_required_mask(struct device *dev);
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index ba1a5974e714..aa3751960ffd 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -33,7 +33,7 @@ extern int distribute_irqs;
struct pt_regs;
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
/*
* Per-cpu stacks for handling critical, debug and machine check
* level interrupts.
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
index 365d2720097c..b5bbb94c51f6 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -19,7 +19,7 @@
#define KASAN_SHADOW_SCALE_SHIFT 3
-#if defined(CONFIG_MODULES) && defined(CONFIG_PPC32)
+#if defined(CONFIG_EXECMEM) && defined(CONFIG_PPC32)
#define KASAN_KERN_START ALIGN_DOWN(PAGE_OFFSET - SZ_256M, SZ_256M)
#else
#define KASAN_KERN_START PAGE_OFFSET
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index fdb90e24dc74..270ee93a0f7d 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -103,10 +103,8 @@ int load_crashdump_segments_ppc64(struct kimage *image,
int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr);
-unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image);
-int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
- unsigned long initrd_load_addr,
- unsigned long initrd_len, const char *cmdline);
+unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image, struct crash_mem *rmem);
+int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, struct crash_mem *rmem);
#endif /* CONFIG_PPC64 */
#endif /* CONFIG_KEXEC_FILE */
@@ -135,6 +133,17 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
ppc_save_regs(newregs);
}
+#ifdef CONFIG_CRASH_HOTPLUG
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
+#define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
+
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
+#define arch_crash_hotplug_support arch_crash_hotplug_support
+
+unsigned int arch_crash_get_elfcorehdr_size(void);
+#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
+#endif /* CONFIG_CRASH_HOTPLUG */
+
extern int crashing_cpu;
extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
extern void crash_ipi_callback(struct pt_regs *regs);
@@ -185,6 +194,10 @@ static inline void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
#endif /* CONFIG_CRASH_DUMP */
+#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
+int update_cpus_node(void *fdt);
+#endif
+
#ifdef CONFIG_PPC_BOOK3S_64
#include <asm/book3s/64/kexec.h>
#endif
diff --git a/arch/powerpc/include/asm/kexec_ranges.h b/arch/powerpc/include/asm/kexec_ranges.h
index f83866a19e87..14055896cbcb 100644
--- a/arch/powerpc/include/asm/kexec_ranges.h
+++ b/arch/powerpc/include/asm/kexec_ranges.h
@@ -7,19 +7,9 @@
void sort_memory_ranges(struct crash_mem *mrngs, bool merge);
struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
-int add_tce_mem_ranges(struct crash_mem **mem_ranges);
-int add_initrd_mem_range(struct crash_mem **mem_ranges);
-#ifdef CONFIG_PPC_64S_HASH_MMU
-int add_htab_mem_range(struct crash_mem **mem_ranges);
-#else
-static inline int add_htab_mem_range(struct crash_mem **mem_ranges)
-{
- return 0;
-}
-#endif
-int add_kernel_mem_range(struct crash_mem **mem_ranges);
-int add_rtas_mem_range(struct crash_mem **mem_ranges);
-int add_opal_mem_range(struct crash_mem **mem_ranges);
-int add_reserved_mem_ranges(struct crash_mem **mem_ranges);
-
+int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
+int get_exclude_memory_ranges(struct crash_mem **mem_ranges);
+int get_reserved_memory_ranges(struct crash_mem **mem_ranges);
+int get_crash_memory_ranges(struct crash_mem **mem_ranges);
+int get_usable_memory_ranges(struct crash_mem **mem_ranges);
#endif /* _ASM_POWERPC_KEXEC_RANGES_H */
diff --git a/arch/powerpc/include/asm/kfence.h b/arch/powerpc/include/asm/kfence.h
index 424ceef82ae6..fab124ada1c7 100644
--- a/arch/powerpc/include/asm/kfence.h
+++ b/arch/powerpc/include/asm/kfence.h
@@ -15,10 +15,19 @@
#define ARCH_FUNC_PREFIX "."
#endif
+#ifdef CONFIG_KFENCE
+extern bool kfence_disabled;
+
+static inline void disable_kfence(void)
+{
+ kfence_disabled = true;
+}
+
static inline bool arch_kfence_init_pool(void)
{
- return true;
+ return !kfence_disabled;
}
+#endif
#ifdef CONFIG_PPC64
static inline bool kfence_protect_page(unsigned long addr, bool protect)
diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h
index ad7e8c5aec3f..2bb03d941e3e 100644
--- a/arch/powerpc/include/asm/kup.h
+++ b/arch/powerpc/include/asm/kup.h
@@ -20,7 +20,7 @@ static __always_inline bool kuap_is_disabled(void);
#include <asm/nohash/32/kup-8xx.h>
#endif
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
#include <asm/nohash/kup-booke.h>
#endif
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 3e1e2a698c9e..10618622d7ef 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -594,6 +594,7 @@ static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \
KVMPPC_BOOK3S_VCORE_ACCESSOR(vtb, 64, KVMPPC_GSID_VTB)
+KVMPPC_BOOK3S_VCORE_ACCESSOR(dpdes, 64, KVMPPC_GSID_DPDES)
KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(arch_compat, 32, KVMPPC_GSID_LOGICAL_PVR)
KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(lpcr, 64, KVMPPC_GSID_LPCR)
KVMPPC_BOOK3S_VCORE_ACCESSOR_SET(tb_offset, 64, KVMPPC_GSID_TB_OFFSET)
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index d8729ec81ca0..2ef9a5f4e5d1 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -684,6 +684,11 @@ int kvmhv_nestedv2_set_ptbl_entry(unsigned long lpid, u64 dw0, u64 dw1);
int kvmhv_nestedv2_parse_output(struct kvm_vcpu *vcpu);
int kvmhv_nestedv2_set_vpa(struct kvm_vcpu *vcpu, unsigned long vpa);
+int kmvhv_counters_tracepoint_regfunc(void);
+void kmvhv_counters_tracepoint_unregfunc(void);
+int kvmhv_get_l2_counters_status(void);
+void kvmhv_set_l2_counters_status(int cpu, bool status);
+
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
#endif /* __ASM_KVM_BOOK3S_64_H__ */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 8abac532146e..37e581c5b201 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -599,6 +599,9 @@ struct kvm_vcpu_arch {
ulong dawrx0;
ulong dawr1;
ulong dawrx1;
+ ulong dexcr;
+ ulong hashkeyr;
+ ulong hashpkeyr;
ulong ciabr;
ulong cfar;
ulong ppr;
@@ -897,7 +900,6 @@ struct kvm_vcpu_arch {
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {}
static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 3281215097cc..ca3829d47ab7 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -287,7 +287,6 @@ struct kvmppc_ops {
bool (*unmap_gfn_range)(struct kvm *kvm, struct kvm_gfn_range *range);
bool (*age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
bool (*test_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
- bool (*set_spte_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
void (*free_memslot)(struct kvm_memory_slot *slot);
int (*init_vm)(struct kvm *kvm);
void (*destroy_vm)(struct kvm *kvm);
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 61ec2447dabf..f40a646bee3c 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -62,7 +62,8 @@ struct lppaca {
u8 donate_dedicated_cpu; /* Donate dedicated CPU cycles */
u8 fpregs_in_use;
u8 pmcregs_in_use;
- u8 reserved8[28];
+ u8 l2_counters_enable; /* Enable usage of counters for KVM guest */
+ u8 reserved8[27];
__be64 wait_state_cycles; /* Wait cycles for this proc */
u8 reserved9[28];
__be16 slb_count; /* # of SLBs to maintain */
@@ -92,9 +93,13 @@ struct lppaca {
/* cacheline 4-5 */
__be32 page_ins; /* CMO Hint - # page ins by OS */
- u8 reserved12[148];
+ u8 reserved12[28];
+ volatile __be64 l1_to_l2_cs_tb;
+ volatile __be64 l2_to_l1_cs_tb;
+ volatile __be64 l2_runtime_tb;
+ u8 reserved13[96];
volatile __be64 dtl_idx; /* Dispatch Trace Log head index */
- u8 reserved13[96];
+ u8 reserved14[96];
} ____cacheline_aligned;
#define lppaca_of(cpu) (*paca_ptrs[cpu]->lppaca_ptr)
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 3b72c7ed24cf..4182d68d9cd1 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -16,7 +16,6 @@
*/
#define MMU_FTR_HPTE_TABLE ASM_CONST(0x00000001)
#define MMU_FTR_TYPE_8xx ASM_CONST(0x00000002)
-#define MMU_FTR_TYPE_40x ASM_CONST(0x00000004)
#define MMU_FTR_TYPE_44x ASM_CONST(0x00000008)
#define MMU_FTR_TYPE_FSL_E ASM_CONST(0x00000010)
#define MMU_FTR_TYPE_47x ASM_CONST(0x00000020)
@@ -153,9 +152,6 @@ enum {
#ifdef CONFIG_PPC_8xx
MMU_FTR_TYPE_8xx |
#endif
-#ifdef CONFIG_40x
- MMU_FTR_TYPE_40x |
-#endif
#ifdef CONFIG_PPC_47x
MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL |
#elif defined(CONFIG_44x)
@@ -202,9 +198,6 @@ enum {
#ifdef CONFIG_PPC_8xx
#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_8xx
#endif
-#ifdef CONFIG_40x
-#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_40x
-#endif
#ifdef CONFIG_PPC_47x
#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_47x
#elif defined(CONFIG_44x)
@@ -246,12 +239,11 @@ static __always_inline bool mmu_has_feature(unsigned long feature)
{
int i;
-#ifndef __clang__ /* clang can't cope with this */
BUILD_BUG_ON(!__builtin_constant_p(feature));
-#endif
+ BUILD_BUG_ON(__builtin_popcountl(feature) > 1);
#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
- if (!static_key_initialized) {
+ if (!static_key_feature_checks_initialized) {
printk("Warning! mmu_has_feature() used prior to jump label init!\n");
dump_stack();
return early_mmu_has_feature(feature);
@@ -406,9 +398,5 @@ extern void *abatron_pteptrs[2];
#include <asm/nohash/mmu.h>
#endif
-#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP)
-#define __HAVE_ARCH_RESERVED_KERNEL_PAGES
-#endif
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_MMU_H_ */
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index a8e2e8339fb7..300c777cc307 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -48,11 +48,6 @@ struct mod_arch_specific {
unsigned long tramp;
unsigned long tramp_regs;
#endif
-
- /* List of BUG addresses, source line numbers and filenames */
- struct list_head bug_list;
- struct bug_entry *bug_table;
- unsigned int num_bugs;
};
/*
diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
index 92df40c6cc6b..014799557f60 100644
--- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -4,42 +4,12 @@
#define PAGE_SHIFT_8M 23
-static inline pte_t *hugepd_page(hugepd_t hpd)
-{
- BUG_ON(!hugepd_ok(hpd));
-
- return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
-}
-
-static inline unsigned int hugepd_shift(hugepd_t hpd)
-{
- return PAGE_SHIFT_8M;
-}
-
-static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
- unsigned int pdshift)
-{
- unsigned long idx = (addr & (SZ_4M - 1)) >> PAGE_SHIFT;
-
- return hugepd_page(hpd) + idx;
-}
-
static inline void flush_hugetlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
flush_tlb_page(vma, vmaddr);
}
-static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
-{
- *hpdp = __hugepd(__pa(new) | _PMD_USER | _PMD_PRESENT | _PMD_PAGE_8M);
-}
-
-static inline void hugepd_populate_kernel(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
-{
- *hpdp = __hugepd(__pa(new) | _PMD_PRESENT | _PMD_PAGE_8M);
-}
-
static inline int check_and_get_huge_psize(int shift)
{
return shift_to_mmu_psize(shift);
@@ -49,6 +19,14 @@ static inline int check_and_get_huge_psize(int shift)
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
pte_t pte, unsigned long sz);
+#define __HAVE_ARCH_HUGE_PTEP_GET
+static inline pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ if (ptep_is_8m_pmdp(mm, addr, ptep))
+ ptep = pte_offset_kernel((pmd_t *)ptep, ALIGN_DOWN(addr, SZ_8M));
+ return ptep_get(ptep);
+}
+
#define __HAVE_ARCH_HUGE_PTE_CLEAR
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long sz)
diff --git a/arch/powerpc/include/asm/nohash/32/mmu-40x.h b/arch/powerpc/include/asm/nohash/32/mmu-40x.h
deleted file mode 100644
index 8a8f13a22cf4..000000000000
--- a/arch/powerpc/include/asm/nohash/32/mmu-40x.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_POWERPC_MMU_40X_H_
-#define _ASM_POWERPC_MMU_40X_H_
-
-/*
- * PPC40x support
- */
-
-#define PPC40X_TLB_SIZE 64
-
-/*
- * TLB entries are defined by a "high" tag portion and a "low" data
- * portion. On all architectures, the data portion is 32-bits.
- *
- * TLB entries are managed entirely under software control by reading,
- * writing, and searchoing using the 4xx-specific tlbre, tlbwr, and tlbsx
- * instructions.
- */
-
-#define TLB_LO 1
-#define TLB_HI 0
-
-#define TLB_DATA TLB_LO
-#define TLB_TAG TLB_HI
-
-/* Tag portion */
-
-#define TLB_EPN_MASK 0xFFFFFC00 /* Effective Page Number */
-#define TLB_PAGESZ_MASK 0x00000380
-#define TLB_PAGESZ(x) (((x) & 0x7) << 7)
-#define PAGESZ_1K 0
-#define PAGESZ_4K 1
-#define PAGESZ_16K 2
-#define PAGESZ_64K 3
-#define PAGESZ_256K 4
-#define PAGESZ_1M 5
-#define PAGESZ_4M 6
-#define PAGESZ_16M 7
-#define TLB_VALID 0x00000040 /* Entry is valid */
-
-/* Data portion */
-
-#define TLB_RPN_MASK 0xFFFFFC00 /* Real Page Number */
-#define TLB_PERM_MASK 0x00000300
-#define TLB_EX 0x00000200 /* Instruction execution allowed */
-#define TLB_WR 0x00000100 /* Writes permitted */
-#define TLB_ZSEL_MASK 0x000000F0
-#define TLB_ZSEL(x) (((x) & 0xF) << 4)
-#define TLB_ATTR_MASK 0x0000000F
-#define TLB_W 0x00000008 /* Caching is write-through */
-#define TLB_I 0x00000004 /* Caching is inhibited */
-#define TLB_M 0x00000002 /* Memory is coherent */
-#define TLB_G 0x00000001 /* Memory is guarded from prefetch */
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned int id;
- unsigned int active;
- void __user *vdso;
-} mm_context_t;
-
-#endif /* !__ASSEMBLY__ */
-
-#define mmu_virtual_psize MMU_PAGE_4K
-#define mmu_linear_psize MMU_PAGE_256M
-
-#endif /* _ASM_POWERPC_MMU_40X_H_ */
diff --git a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
index 141d82e249a8..a756a1e59c54 100644
--- a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
@@ -189,19 +189,14 @@ typedef struct {
#define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
-/* Page size definitions, common between 32 and 64-bit
+/*
+ * Page size definitions for 8xx
*
* shift : is the "PAGE_SHIFT" value for that page size
- * penc : is the pte encoding mask
*
*/
struct mmu_psize_def {
unsigned int shift; /* number of bits */
- unsigned int enc; /* PTE encoding */
- unsigned int ind; /* Corresponding indirect page size shift */
- unsigned int flags;
-#define MMU_PAGE_SIZE_DIRECT 0x1 /* Supported as a direct size */
-#define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */
};
extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 9164a9e41b02..9508399dd036 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -118,9 +118,7 @@
* (hardware-defined) PowerPC PTE as closely as possible.
*/
-#if defined(CONFIG_40x)
-#include <asm/nohash/32/pte-40x.h>
-#elif defined(CONFIG_44x)
+#if defined(CONFIG_44x)
#include <asm/nohash/32/pte-44x.h>
#elif defined(CONFIG_PPC_85xx) && defined(CONFIG_PTE_64BIT)
#include <asm/nohash/pte-e500.h>
diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h
deleted file mode 100644
index d759cfd74754..000000000000
--- a/arch/powerpc/include/asm/nohash/32/pte-40x.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_POWERPC_NOHASH_32_PTE_40x_H
-#define _ASM_POWERPC_NOHASH_32_PTE_40x_H
-#ifdef __KERNEL__
-
-/*
- * At present, all PowerPC 400-class processors share a similar TLB
- * architecture. The instruction and data sides share a unified,
- * 64-entry, fully-associative TLB which is maintained totally under
- * software control. In addition, the instruction side has a
- * hardware-managed, 4-entry, fully-associative TLB which serves as a
- * first level to the shared TLB. These two TLBs are known as the UTLB
- * and ITLB, respectively (see "mmu.h" for definitions).
- *
- * There are several potential gotchas here. The 40x hardware TLBLO
- * field looks like this:
- *
- * 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- * RPN..................... 0 0 EX WR ZSEL....... W I M G
- *
- * Where possible we make the Linux PTE bits match up with this
- *
- * - bits 20 and 21 must be cleared, because we use 4k pages (40x can
- * support down to 1k pages), this is done in the TLBMiss exception
- * handler.
- * - We use only zones 0 (for kernel pages) and 1 (for user pages)
- * of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
- * miss handler. Bit 27 is PAGE_USER, thus selecting the correct
- * zone.
- * - PRESENT *must* be in the bottom two bits because swap PTEs
- * use the top 30 bits. Because 40x doesn't support SMP anyway, M is
- * irrelevant so we borrow it for PAGE_PRESENT. Bit 30
- * is cleared in the TLB miss handler before the TLB entry is loaded.
- * - All other bits of the PTE are loaded into TLBLO without
- * modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
- * software PTE bits. We actually use bits 21, 24, 25, and
- * 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
- * PRESENT.
- */
-
-#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
-#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
-#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
-#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
-#define _PAGE_READ 0x010 /* software: read permission */
-#define _PAGE_SPECIAL 0x020 /* software: Special page */
-#define _PAGE_DIRTY 0x080 /* software: dirty page */
-#define _PAGE_WRITE 0x100 /* hardware: WR, anded with dirty in exception */
-#define _PAGE_EXEC 0x200 /* hardware: EX permission */
-#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
-
-/* No page size encoding in the linux PTE */
-#define _PAGE_PSIZE 0
-
-/* cache related flags non existing on 40x */
-#define _PAGE_COHERENT 0
-
-#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
-#define _PMD_PRESENT_MASK _PMD_PRESENT
-#define _PMD_BAD 0x802
-#define _PMD_SIZE_4M 0x0c0
-#define _PMD_SIZE_16M 0x0e0
-#define _PMD_USER 0
-
-#define _PTE_NONE_MASK 0
-
-#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED)
-#define _PAGE_BASE (_PAGE_BASE_NC)
-
-#include <asm/pgtable-masks.h>
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_NOHASH_32_PTE_40x_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-44x.h b/arch/powerpc/include/asm/nohash/32/pte-44x.h
index 851813725237..da0469928273 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-44x.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-44x.h
@@ -75,9 +75,6 @@
#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
-/* No page size encoding in the linux PTE */
-#define _PAGE_PSIZE 0
-
/* TODO: Add large page lowmem mapping support */
#define _PMD_PRESENT 0
#define _PMD_PRESENT_MASK (PAGE_MASK)
diff --git a/arch/powerpc/include/asm/nohash/32/pte-85xx.h b/arch/powerpc/include/asm/nohash/32/pte-85xx.h
index 653a342d3b25..14d64b4f3f14 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-85xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-85xx.h
@@ -31,9 +31,6 @@
#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
#define _PAGE_SPECIAL 0x00800 /* S: Special page */
-/* No page size encoding in the linux PTE */
-#define _PAGE_PSIZE 0
-
#define _PMD_PRESENT 0
#define _PMD_PRESENT_MASK (PAGE_MASK)
#define _PMD_BAD (~PAGE_MASK)
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index 137dc3c84e45..54ebb91dbdcf 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -74,12 +74,11 @@
#define _PTE_NONE_MASK 0
#ifdef CONFIG_PPC_16K_PAGES
-#define _PAGE_PSIZE _PAGE_SPS
+#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SPS)
#else
-#define _PAGE_PSIZE 0
+#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED)
#endif
-#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
#define _PAGE_BASE (_PAGE_BASE_NC)
#include <asm/pgtable-masks.h>
@@ -120,7 +119,7 @@ static inline pte_t pte_mkhuge(pte_t pte)
#define pte_mkhuge pte_mkhuge
-static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
+static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
unsigned long clr, unsigned long set, int huge);
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
@@ -142,19 +141,12 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma, pte_t *pt
}
#define __ptep_set_access_flags __ptep_set_access_flags
-static inline unsigned long pgd_leaf_size(pgd_t pgd)
-{
- if (pgd_val(pgd) & _PMD_PAGE_8M)
- return SZ_8M;
- return SZ_4M;
-}
-
-#define pgd_leaf_size pgd_leaf_size
-
-static inline unsigned long pte_leaf_size(pte_t pte)
+static inline unsigned long __pte_leaf_size(pmd_t pmd, pte_t pte)
{
pte_basic_t val = pte_val(pte);
+ if (pmd_val(pmd) & _PMD_PAGE_8M)
+ return SZ_8M;
if (val & _PAGE_HUGE)
return SZ_512K;
if (val & _PAGE_SPS)
@@ -162,31 +154,38 @@ static inline unsigned long pte_leaf_size(pte_t pte)
return SZ_4K;
}
-#define pte_leaf_size pte_leaf_size
+#define __pte_leaf_size __pte_leaf_size
/*
* On the 8xx, the page tables are a bit special. For 16k pages, we have
* 4 identical entries. For 512k pages, we have 128 entries as if it was
* 4k pages, but they are flagged as 512k pages for the hardware.
- * For other page sizes, we have a single entry in the table.
+ * For 8M pages, we have 1024 entries as if it was 4M pages (PMD_SIZE)
+ * but they are flagged as 8M pages for the hardware.
+ * For 4k pages, we have a single entry in the table.
*/
static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr);
-static int hugepd_ok(hugepd_t hpd);
+static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address);
+
+static inline bool ptep_is_8m_pmdp(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ return (pmd_t *)ptep == pmd_off(mm, ALIGN_DOWN(addr, SZ_8M));
+}
static inline 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 ((pmd_val(*pmd) & _PMD_PAGE_MASK) == _PMD_PAGE_8M)
+ return SZ_4M / SZ_4K;
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)
+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)
{
pte_basic_t *entry = (pte_basic_t *)p;
pte_basic_t old = pte_val(*p);
@@ -198,7 +197,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
for (i = 0; i < num; i += PAGE_SIZE / SZ_4K, new += PAGE_SIZE) {
*entry++ = new;
- if (IS_ENABLED(CONFIG_PPC_16K_PAGES) && num != 1) {
+ if (IS_ENABLED(CONFIG_PPC_16K_PAGES)) {
*entry++ = new;
*entry++ = new;
*entry++ = new;
@@ -208,6 +207,21 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
return old;
}
+static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ unsigned long clr, unsigned long set, int huge)
+{
+ pte_basic_t old;
+
+ if (huge && ptep_is_8m_pmdp(mm, addr, ptep)) {
+ pmd_t *pmdp = (pmd_t *)ptep;
+
+ old = __pte_update(mm, addr, pte_offset_kernel(pmdp, 0), clr, set, huge);
+ __pte_update(mm, addr, pte_offset_kernel(pmdp + 1, 0), clr, set, huge);
+ } else {
+ old = __pte_update(mm, addr, ptep, clr, set, huge);
+ }
+ return old;
+}
#define pte_update pte_update
#ifdef CONFIG_PPC_16K_PAGES
diff --git a/arch/powerpc/include/asm/nohash/hugetlb-e500.h b/arch/powerpc/include/asm/nohash/hugetlb-e500.h
index 8f04ad20e040..cab0e1f1eea0 100644
--- a/arch/powerpc/include/asm/nohash/hugetlb-e500.h
+++ b/arch/powerpc/include/asm/nohash/hugetlb-e500.h
@@ -2,38 +2,8 @@
#ifndef _ASM_POWERPC_NOHASH_HUGETLB_E500_H
#define _ASM_POWERPC_NOHASH_HUGETLB_E500_H
-static inline pte_t *hugepd_page(hugepd_t hpd)
-{
- if (WARN_ON(!hugepd_ok(hpd)))
- return NULL;
-
- return (pte_t *)((hpd_val(hpd) & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
-}
-
-static inline unsigned int hugepd_shift(hugepd_t hpd)
-{
- return hpd_val(hpd) & HUGEPD_SHIFT_MASK;
-}
-
-static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
- unsigned int pdshift)
-{
- /*
- * On FSL BookE, we have multiple higher-level table entries that
- * point to the same hugepte. Just use the first one since they're all
- * identical. So for that case, idx=0.
- */
- return hugepd_page(hpd);
-}
-
void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
-static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
-{
- /* We use the old format for PPC_E500 */
- *hpdp = __hugepd(((unsigned long)new & ~PD_HUGE) | pshift);
-}
-
static inline int check_and_get_huge_psize(int shift)
{
if (shift & 1) /* Not a power of 4 */
@@ -42,4 +12,13 @@ static inline int check_and_get_huge_psize(int shift)
return shift_to_mmu_psize(shift);
}
+static inline pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
+{
+ unsigned int tsize = shift - _PAGE_PSIZE_SHIFT_OFFSET;
+ pte_basic_t val = (tsize << _PAGE_PSIZE_SHIFT) & _PAGE_PSIZE_MSK;
+
+ return __pte((pte_val(entry) & ~(pte_basic_t)_PAGE_PSIZE_MSK) | val);
+}
+#define arch_make_huge_pte arch_make_huge_pte
+
#endif /* _ASM_POWERPC_NOHASH_HUGETLB_E500_H */
diff --git a/arch/powerpc/include/asm/nohash/mmu-e500.h b/arch/powerpc/include/asm/nohash/mmu-e500.h
index 6ddced0415cb..b281d9eeaf1e 100644
--- a/arch/powerpc/include/asm/nohash/mmu-e500.h
+++ b/arch/powerpc/include/asm/nohash/mmu-e500.h
@@ -244,14 +244,11 @@ typedef struct {
/* Page size definitions, common between 32 and 64-bit
*
* shift : is the "PAGE_SHIFT" value for that page size
- * penc : is the pte encoding mask
*
*/
struct mmu_psize_def
{
unsigned int shift; /* number of bits */
- unsigned int enc; /* PTE encoding */
- unsigned int ind; /* Corresponding indirect page size shift */
unsigned int flags;
#define MMU_PAGE_SIZE_DIRECT 0x1 /* Supported as a direct size */
#define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */
@@ -303,8 +300,7 @@ extern unsigned long linear_map_top;
extern int book3e_htw_mode;
#define PPC_HTW_NONE 0
-#define PPC_HTW_IBM 1
-#define PPC_HTW_E6500 2
+#define PPC_HTW_E6500 1
/*
* 64-bit booke platforms don't load the tlb in the tlb miss handler code.
diff --git a/arch/powerpc/include/asm/nohash/mmu.h b/arch/powerpc/include/asm/nohash/mmu.h
index e264be219fdb..4cc795044103 100644
--- a/arch/powerpc/include/asm/nohash/mmu.h
+++ b/arch/powerpc/include/asm/nohash/mmu.h
@@ -2,10 +2,7 @@
#ifndef _ASM_POWERPC_NOHASH_MMU_H_
#define _ASM_POWERPC_NOHASH_MMU_H_
-#if defined(CONFIG_40x)
-/* 40x-style software loaded TLB */
-#include <asm/nohash/32/mmu-40x.h>
-#elif defined(CONFIG_44x)
+#if defined(CONFIG_44x)
/* 44x-style software loaded TLB */
#include <asm/nohash/32/mmu-44x.h>
#elif defined(CONFIG_PPC_E500)
diff --git a/arch/powerpc/include/asm/nohash/pgalloc.h b/arch/powerpc/include/asm/nohash/pgalloc.h
index 4b62376318e1..d06efac6d7aa 100644
--- a/arch/powerpc/include/asm/nohash/pgalloc.h
+++ b/arch/powerpc/include/asm/nohash/pgalloc.h
@@ -44,8 +44,6 @@ static inline void pgtable_free(void *table, int shift)
}
}
-#define get_hugepd_cache_index(x) (x)
-
static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
{
unsigned long pgf = (unsigned long)table;
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h
index 427db14292c9..8d1f0b7062eb 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -31,6 +31,13 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
extern int icache_44x_need_flush;
+#ifndef pte_huge_size
+static inline unsigned long pte_huge_size(pte_t pte)
+{
+ return PAGE_SIZE;
+}
+#endif
+
/*
* PTE updates. This function is called whenever an existing
* valid PTE is updated. This does -not- include set_pte_at()
@@ -52,11 +59,34 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
{
pte_basic_t old = pte_val(*p);
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
+ unsigned long sz;
+ unsigned long pdsize;
+ int i;
if (new == old)
return old;
- *p = __pte(new);
+ if (huge)
+ sz = pte_huge_size(__pte(old));
+ else
+ sz = PAGE_SIZE;
+
+ if (sz < PMD_SIZE)
+ pdsize = PAGE_SIZE;
+ else if (sz < PUD_SIZE)
+ pdsize = PMD_SIZE;
+ else if (sz < P4D_SIZE)
+ pdsize = PUD_SIZE;
+ else if (sz < PGDIR_SIZE)
+ pdsize = P4D_SIZE;
+ else
+ pdsize = PGDIR_SIZE;
+
+ for (i = 0; i < sz / pdsize; i++, p++) {
+ *p = __pte(new);
+ if (new)
+ new += (unsigned long long)(pdsize / PAGE_SIZE) << PTE_RPN_SHIFT;
+ }
if (IS_ENABLED(CONFIG_44x) && !is_kernel_addr(addr) && (old & _PAGE_EXEC))
icache_44x_need_flush = 1;
@@ -340,30 +370,6 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
#define pgprot_writecombine pgprot_noncached_wc
-#ifdef CONFIG_HUGETLB_PAGE
-static inline int hugepd_ok(hugepd_t hpd)
-{
-#ifdef CONFIG_PPC_8xx
- return ((hpd_val(hpd) & _PMD_PAGE_MASK) == _PMD_PAGE_8M);
-#else
- /* We clear the top bit to indicate hugepd */
- return (hpd_val(hpd) && (hpd_val(hpd) & PD_HUGE) == 0);
-#endif
-}
-
-static inline int pmd_huge(pmd_t pmd)
-{
- return 0;
-}
-
-static inline int pud_huge(pud_t pud)
-{
- return 0;
-}
-
-#define is_hugepd(hpd) (hugepd_ok(hpd))
-#endif
-
int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
void unmap_kernel_page(unsigned long va);
diff --git a/arch/powerpc/include/asm/nohash/pte-e500.h b/arch/powerpc/include/asm/nohash/pte-e500.h
index f516f0b5b7a8..cb78392494da 100644
--- a/arch/powerpc/include/asm/nohash/pte-e500.h
+++ b/arch/powerpc/include/asm/nohash/pte-e500.h
@@ -19,20 +19,7 @@
#define _PAGE_BAP_SX 0x000040
#define _PAGE_BAP_UX 0x000080
#define _PAGE_PSIZE_MSK 0x000f00
-#define _PAGE_PSIZE_4K 0x000200
-#define _PAGE_PSIZE_8K 0x000300
-#define _PAGE_PSIZE_16K 0x000400
-#define _PAGE_PSIZE_32K 0x000500
-#define _PAGE_PSIZE_64K 0x000600
-#define _PAGE_PSIZE_128K 0x000700
-#define _PAGE_PSIZE_256K 0x000800
-#define _PAGE_PSIZE_512K 0x000900
-#define _PAGE_PSIZE_1M 0x000a00
-#define _PAGE_PSIZE_2M 0x000b00
-#define _PAGE_PSIZE_4M 0x000c00
-#define _PAGE_PSIZE_8M 0x000d00
-#define _PAGE_PSIZE_16M 0x000e00
-#define _PAGE_PSIZE_32M 0x000f00
+#define _PAGE_TSIZE_4K 0x000100
#define _PAGE_DIRTY 0x001000 /* C: page changed */
#define _PAGE_SW0 0x002000
#define _PAGE_U3 0x004000
@@ -46,6 +33,9 @@
#define _PAGE_NO_CACHE 0x400000 /* I: cache inhibit */
#define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
+#define _PAGE_PSIZE_SHIFT 7
+#define _PAGE_PSIZE_SHIFT_OFFSET 10
+
/* "Higher level" linux bit combinations */
#define _PAGE_EXEC (_PAGE_BAP_SX | _PAGE_BAP_UX) /* .. and was cache cleaned */
#define _PAGE_READ (_PAGE_BAP_SR | _PAGE_BAP_UR) /* User read permission */
@@ -65,8 +55,6 @@
#define _PAGE_SPECIAL _PAGE_SW0
-/* Base page size */
-#define _PAGE_PSIZE _PAGE_PSIZE_4K
#define PTE_RPN_SHIFT (24)
#define PTE_WIMGE_SHIFT (19)
@@ -89,7 +77,7 @@
* pages. We always set _PAGE_COHERENT when SMP is enabled or
* the processor might need it for DMA coherency.
*/
-#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
+#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_TSIZE_4K)
#if defined(CONFIG_SMP)
#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT)
#else
@@ -105,6 +93,47 @@ static inline pte_t pte_mkexec(pte_t pte)
}
#define pte_mkexec pte_mkexec
+static inline unsigned long pte_huge_size(pte_t pte)
+{
+ pte_basic_t val = pte_val(pte);
+
+ return 1UL << (((val & _PAGE_PSIZE_MSK) >> _PAGE_PSIZE_SHIFT) + _PAGE_PSIZE_SHIFT_OFFSET);
+}
+#define pte_huge_size pte_huge_size
+
+static inline int pmd_leaf(pmd_t pmd)
+{
+ if (IS_ENABLED(CONFIG_PPC64))
+ return (long)pmd_val(pmd) > 0;
+ else
+ return pmd_val(pmd) & _PAGE_PSIZE_MSK;
+}
+#define pmd_leaf pmd_leaf
+
+static inline unsigned long pmd_leaf_size(pmd_t pmd)
+{
+ return pte_huge_size(__pte(pmd_val(pmd)));
+}
+#define pmd_leaf_size pmd_leaf_size
+
+#ifdef CONFIG_PPC64
+static inline int pud_leaf(pud_t pud)
+{
+ if (IS_ENABLED(CONFIG_PPC64))
+ return (long)pud_val(pud) > 0;
+ else
+ return pud_val(pud) & _PAGE_PSIZE_MSK;
+}
+#define pud_leaf pud_leaf
+
+static inline unsigned long pud_leaf_size(pud_t pud)
+{
+ return pte_huge_size(__pte(pud_val(pud)));
+}
+#define pud_leaf_size pud_leaf_size
+
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index a2bc4b95e703..8c9d4b26bf57 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -1027,10 +1027,10 @@ struct opal_i2c_request {
* The host will pass on OPAL, a buffer of length OPAL_SYSEPOW_MAX
* with individual elements being 16 bits wide to fetch the system
* wide EPOW status. Each element in the buffer will contain the
- * EPOW status in it's bit representation for a particular EPOW sub
+ * EPOW status in its bit representation for a particular EPOW sub
* class as defined here. So multiple detailed EPOW status bits
* specific for any sub class can be represented in a single buffer
- * element as it's bit representation.
+ * element as its bit representation.
*/
/* System EPOW type */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index e411e5a70ea3..83d0a4fc5f75 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -269,38 +269,6 @@ static inline const void *pfn_to_kaddr(unsigned long pfn)
#define is_kernel_addr(x) ((x) >= TASK_SIZE)
#endif
-#ifndef CONFIG_PPC_BOOK3S_64
-/*
- * Use the top bit of the higher-level page table entries to indicate whether
- * the entries we point to contain hugepages. This works because we know that
- * the page tables live in kernel space. If we ever decide to support having
- * page tables at arbitrary addresses, this breaks and will have to change.
- */
-#ifdef CONFIG_PPC64
-#define PD_HUGE 0x8000000000000000UL
-#else
-#define PD_HUGE 0x80000000
-#endif
-
-#else /* CONFIG_PPC_BOOK3S_64 */
-/*
- * Book3S 64 stores real addresses in the hugepd entries to
- * avoid overlaps with _PAGE_PRESENT and _PAGE_PTE.
- */
-#define HUGEPD_ADDR_MASK (0x0ffffffffffffffful & ~HUGEPD_SHIFT_MASK)
-#endif /* CONFIG_PPC_BOOK3S_64 */
-
-/*
- * Some number of bits at the level of the page table that points to
- * a hugepte are used to encode the size. This masks those bits.
- * On 8xx, HW assistance requires 4k alignment for the hugepte.
- */
-#ifdef CONFIG_PPC_8xx
-#define HUGEPD_SHIFT_MASK 0xfff
-#else
-#define HUGEPD_SHIFT_MASK 0x3f
-#endif
-
#ifndef __ASSEMBLY__
#ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/include/asm/percpu.h b/arch/powerpc/include/asm/percpu.h
index 8e5b7d0b851c..634970ce13c6 100644
--- a/arch/powerpc/include/asm/percpu.h
+++ b/arch/powerpc/include/asm/percpu.h
@@ -15,6 +15,16 @@
#endif /* CONFIG_SMP */
#endif /* __powerpc64__ */
+#if defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK) && defined(CONFIG_SMP)
+#include <linux/jump_label.h>
+DECLARE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged);
+
+#define percpu_first_chunk_is_paged \
+ (static_key_enabled(&__percpu_first_chunk_is_paged.key))
+#else
+#define percpu_first_chunk_is_paged false
+#endif /* CONFIG_PPC64 && CONFIG_SMP */
+
#include <asm-generic/percpu.h>
#include <asm/paca.h>
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index e2221d29fdf9..5995614e9062 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -89,7 +89,8 @@ struct power_pmu {
#define PPMU_NO_SIAR 0x00000100 /* Do not use SIAR */
#define PPMU_ARCH_31 0x00000200 /* Has MMCR3, SIER2 and SIER3 */
#define PPMU_P10_DD1 0x00000400 /* Is power10 DD1 processor version */
-#define PPMU_HAS_ATTR_CONFIG1 0x00000800 /* Using config1 attribute */
+#define PPMU_P10 0x00000800 /* For power10 pmu */
+#define PPMU_HAS_ATTR_CONFIG1 0x00001000 /* Using config1 attribute */
/*
* Values for flags to get_alternatives()
diff --git a/arch/powerpc/include/asm/pgtable-be-types.h b/arch/powerpc/include/asm/pgtable-be-types.h
index 82633200b500..6bd8f89b25dc 100644
--- a/arch/powerpc/include/asm/pgtable-be-types.h
+++ b/arch/powerpc/include/asm/pgtable-be-types.h
@@ -101,14 +101,4 @@ static inline bool pmd_xchg(pmd_t *pmdp, pmd_t old, pmd_t new)
return pmd_raw(old) == prev;
}
-#ifdef CONFIG_ARCH_HAS_HUGEPD
-typedef struct { __be64 pdbe; } hugepd_t;
-#define __hugepd(x) ((hugepd_t) { cpu_to_be64(x) })
-
-static inline unsigned long hpd_val(hugepd_t x)
-{
- return be64_to_cpu(x.pdbe);
-}
-#endif
-
#endif /* _ASM_POWERPC_PGTABLE_BE_TYPES_H */
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
index 082c85cc09b1..7b3d4c592a10 100644
--- a/arch/powerpc/include/asm/pgtable-types.h
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -49,7 +49,11 @@ static inline unsigned long pud_val(pud_t x)
#endif /* CONFIG_PPC64 */
/* PGD level */
+#if defined(CONFIG_PPC_E500) && defined(CONFIG_PTE_64BIT)
+typedef struct { unsigned long long pgd; } pgd_t;
+#else
typedef struct { unsigned long pgd; } pgd_t;
+#endif
#define __pgd(x) ((pgd_t) { (x) })
static inline unsigned long pgd_val(pgd_t x)
{
@@ -83,13 +87,4 @@ static inline bool pte_xchg(pte_t *ptep, pte_t old, pte_t new)
}
#endif
-#ifdef CONFIG_ARCH_HAS_HUGEPD
-typedef struct { unsigned long pd; } hugepd_t;
-#define __hugepd(x) ((hugepd_t) { (x) })
-static inline unsigned long hpd_val(hugepd_t x)
-{
- return x.pd;
-}
-#endif
-
#endif /* _ASM_POWERPC_PGTABLE_TYPES_H */
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 239709a2f68e..264a6c09517a 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -106,6 +106,9 @@ unsigned long vmalloc_to_phys(void *vmalloc_addr);
void pgtable_cache_add(unsigned int shift);
+#ifdef CONFIG_PPC32
+void __init *early_alloc_pgtable(unsigned long size);
+#endif
pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va);
#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_PPC32)
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h
index b3ee44a40c2f..71648c126970 100644
--- a/arch/powerpc/include/asm/plpar_wrappers.h
+++ b/arch/powerpc/include/asm/plpar_wrappers.h
@@ -18,16 +18,6 @@ static inline long poll_pending(void)
return plpar_hcall_norets(H_POLL_PENDING);
}
-static inline u8 get_cede_latency_hint(void)
-{
- return get_lppaca()->cede_latency_hint;
-}
-
-static inline void set_cede_latency_hint(u8 latency_hint)
-{
- get_lppaca()->cede_latency_hint = latency_hint;
-}
-
static inline long cede_processor(void)
{
/*
@@ -37,24 +27,6 @@ static inline long cede_processor(void)
return plpar_hcall_norets_notrace(H_CEDE);
}
-static inline long extended_cede_processor(unsigned long latency_hint)
-{
- long rc;
- u8 old_latency_hint = get_cede_latency_hint();
-
- set_cede_latency_hint(latency_hint);
-
- rc = cede_processor();
-
- /* Ensure that H_CEDE returns with IRQs on */
- if (WARN_ON(IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && !(mfmsr() & MSR_EE)))
- __hard_irq_enable();
-
- set_cede_latency_hint(old_latency_hint);
-
- return rc;
-}
-
static inline long vpa_call(unsigned long flags, unsigned long cpu,
unsigned long vpa)
{
diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h
index 2495866f2e97..420e2878ae67 100644
--- a/arch/powerpc/include/asm/pmac_feature.h
+++ b/arch/powerpc/include/asm/pmac_feature.h
@@ -192,7 +192,7 @@ static inline long pmac_call_feature(int selector, struct device_node* node,
/* PMAC_FTR_BMAC_ENABLE (struct device_node* node, 0, int value)
* enable/disable the bmac (ethernet) cell of a mac-io ASIC, also drive
- * it's reset line
+ * its reset line
*/
#define PMAC_FTR_BMAC_ENABLE PMAC_FTR_DEF(6)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 005601243dda..b98a9e982c03 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -471,6 +471,7 @@
#define PPC_RAW_VCMPEQUB_RC(vrt, vra, vrb) \
(0x10000006 | ___PPC_RT(vrt) | ___PPC_RA(vra) | ___PPC_RB(vrb) | __PPC_RC21)
#define PPC_RAW_LD(r, base, i) (0xe8000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_DS(i))
+#define PPC_RAW_LWA(r, base, i) (0xe8000002 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_DS(i))
#define PPC_RAW_LWZ(r, base, i) (0x80000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LWZX(t, a, b) (0x7c00002e | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_STD(r, base, i) (0xf8000000 | ___PPC_RS(r) | ___PPC_RA(base) | IMM_DS(i))
@@ -510,6 +511,7 @@
#define PPC_RAW_STB(r, base, i) (0x98000000 | ___PPC_RS(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LBZ(r, base, i) (0x88000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_LHA(r, base, i) (0xa8000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
@@ -532,7 +534,9 @@
#define PPC_RAW_MULW(d, a, b) (0x7c0001d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_MULHWU(d, a, b) (0x7c000016 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_MULI(d, a, i) (0x1c000000 | ___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_DIVW(d, a, b) (0x7c0003d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_DIVWU(d, a, b) (0x7c000396 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_DIVD(d, a, b) (0x7c0003d2 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_DIVDU(d, a, b) (0x7c000392 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_DIVDE(t, a, b) (0x7c000352 | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_DIVDE_DOT(t, a, b) (0x7c000352 | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b) | 0x1)
@@ -550,6 +554,8 @@
#define PPC_RAW_XOR(d, a, b) (0x7c000278 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(b))
#define PPC_RAW_XORI(d, a, i) (0x68000000 | ___PPC_RA(d) | ___PPC_RS(a) | IMM_L(i))
#define PPC_RAW_XORIS(d, a, i) (0x6c000000 | ___PPC_RA(d) | ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_EXTSB(d, a) (0x7c000774 | ___PPC_RA(d) | ___PPC_RS(a))
+#define PPC_RAW_EXTSH(d, a) (0x7c000734 | ___PPC_RA(d) | ___PPC_RS(a))
#define PPC_RAW_EXTSW(d, a) (0x7c0007b4 | ___PPC_RA(d) | ___PPC_RS(a))
#define PPC_RAW_SLW(d, a, s) (0x7c000030 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(s))
#define PPC_RAW_SLD(d, a, s) (0x7c000036 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(s))
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 1d1018c1e482..02897f4b0dbf 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -482,7 +482,7 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
* and they must be used.
*/
-#if !defined(CONFIG_4xx) && !defined(CONFIG_PPC_8xx)
+#if !defined(CONFIG_44x) && !defined(CONFIG_PPC_8xx)
#define tlbia \
li r4,1024; \
mtctr r4; \
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index b2c51d337e60..6b94de17201c 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -159,7 +159,7 @@ struct thread_struct {
unsigned long sr0;
#endif
#endif /* CONFIG_PPC32 */
-#if defined(CONFIG_BOOKE_OR_40x) && defined(CONFIG_PPC_KUAP)
+#if defined(CONFIG_BOOKE) && defined(CONFIG_PPC_KUAP)
unsigned long pid; /* value written in PID reg. at interrupt exit */
#endif
/* Debug Registers */
@@ -260,7 +260,8 @@ struct thread_struct {
unsigned long sier2;
unsigned long sier3;
unsigned long hashkeyr;
-
+ unsigned long dexcr;
+ unsigned long dexcr_onexec; /* Reset value to load on exec */
#endif
};
@@ -333,6 +334,16 @@ extern int set_endian(struct task_struct *tsk, unsigned int val);
extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
+#ifdef CONFIG_PPC_BOOK3S_64
+
+#define PPC_GET_DEXCR_ASPECT(tsk, asp) get_dexcr_prctl((tsk), (asp))
+#define PPC_SET_DEXCR_ASPECT(tsk, asp, val) set_dexcr_prctl((tsk), (asp), (val))
+
+int get_dexcr_prctl(struct task_struct *tsk, unsigned long asp);
+int set_dexcr_prctl(struct task_struct *tsk, unsigned long asp, unsigned long val);
+
+#endif
+
extern void load_fp_state(struct thread_fp_state *fp);
extern void store_fp_state(struct thread_fp_state *fp);
extern void load_vr_state(struct thread_vr_state *vr);
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index d13d8fdc3411..987e23a2bd28 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -390,11 +390,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev);
int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv);
void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv);
-static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv(
- struct device_driver *_drv)
-{
- return container_of(_drv, struct ps3_system_bus_driver, core);
-}
+#define ps3_drv_to_system_bus_drv(_drv) container_of_const(_drv, struct ps3_system_bus_driver, core)
static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev(
const struct device *_dev)
{
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index ea8f91fbc62f..7b9350756875 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -310,7 +310,7 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
static inline bool cpu_has_msr_ri(void)
{
- return !IS_ENABLED(CONFIG_BOOKE_OR_40x);
+ return !IS_ENABLED(CONFIG_BOOKE);
}
static inline bool regs_is_unrecoverable(struct pt_regs *regs)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d3d1aea009b4..0228c90bbcc7 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -18,7 +18,7 @@
#include <asm/feature-fixups.h>
/* Pickup Book E specific registers. */
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
#include <asm/reg_booke.h>
#endif
@@ -233,14 +233,10 @@
/* Special Purpose Registers (SPRNs)*/
-#ifdef CONFIG_40x
-#define SPRN_PID 0x3B1 /* Process ID */
-#else
#define SPRN_PID 0x030 /* Process ID */
#ifdef CONFIG_BOOKE
#define SPRN_PID0 SPRN_PID/* Process ID Register 0 */
#endif
-#endif
#define SPRN_CTR 0x009 /* Count Register */
#define SPRN_DSCR 0x11
@@ -527,7 +523,7 @@
#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_PIT 0x3DB /* Programmable Interval Timer (BOOKE) */
#define SPRN_DER 0x095 /* Debug Enable Register */
#define DER_RSTE 0x40000000 /* Reset Interrupt */
@@ -615,7 +611,7 @@
#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */
#define HID1_PS (1<<16) /* 750FX PLL selection */
#endif
-#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
+#define SPRN_HID2_750FX 0x3F8 /* IBM 750FX HID2 Register */
#define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */
#define SPRN_HID2_G2_LE 0x3F3 /* G2_LE HID2 Register */
#define HID2_G2_LE_HBE (1<<18) /* High BAT Enable (G2_LE) */
@@ -1116,15 +1112,6 @@
* - SPRG2 indicator that we are in RTAS
* - SPRG4 (603 only) pseudo TLB LRU data
*
- * 32-bit 40x:
- * - SPRG0 scratch for exception vectors
- * - SPRG1 scratch for exception vectors
- * - SPRG2 scratch for exception vectors
- * - SPRG4 scratch for exception vectors (not 403)
- * - SPRG5 scratch for exception vectors (not 403)
- * - SPRG6 scratch for exception vectors (not 403)
- * - SPRG7 scratch for exception vectors (not 403)
- *
* 32-bit 440 and FSL BookE:
* - SPRG0 scratch for exception vectors
* - SPRG1 scratch for exception vectors (*)
@@ -1216,16 +1203,6 @@
#define SPRN_SPRG_603_LRU SPRN_SPRG4
#endif
-#ifdef CONFIG_40x
-#define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
-#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
-#define SPRN_SPRG_SCRATCH2 SPRN_SPRG2
-#define SPRN_SPRG_SCRATCH3 SPRN_SPRG4
-#define SPRN_SPRG_SCRATCH4 SPRN_SPRG5
-#define SPRN_SPRG_SCRATCH5 SPRN_SPRG6
-#define SPRN_SPRG_SCRATCH6 SPRN_SPRG7
-#endif
-
#ifdef CONFIG_BOOKE
#define SPRN_SPRG_RSCRATCH0 SPRN_SPRG0
#define SPRN_SPRG_WSCRATCH0 SPRN_SPRG0
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index af56980b6cdb..656bfaf91526 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -1,10 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Contains register definitions common to the Book E PowerPC
- * specification. Notice that while the IBM-40x series of CPUs
- * are not true Book E PowerPCs, they borrowed a number of features
- * before Book E was finalized, and are included here as well. Unfortunately,
- * they sometimes used different locations than true Book E CPUs did.
+ * specification.
*
* Copyright 2009-2010 Freescale Semiconductor, Inc.
*/
@@ -42,9 +39,6 @@
#define MSR_KERNEL (MSR_ | MSR_64BIT)
#define MSR_USER32 (MSR_ | MSR_PR | MSR_EE)
#define MSR_USER64 (MSR_USER32 | MSR_64BIT)
-#elif defined (CONFIG_40x)
-#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
-#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
#else
#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_CE)
#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
@@ -157,7 +151,6 @@
#define SPRN_TLB3CFG 0x2B3 /* TLB 3 Config Register */
#define SPRN_EPR 0x2BE /* External Proxy Register */
#define SPRN_CCR1 0x378 /* Core Configuration Register 1 */
-#define SPRN_ZPR 0x3B0 /* Zone Protection Register (40x) */
#define SPRN_MAS7 0x3B0 /* MMU Assist Register 7 */
#define SPRN_MMUCR 0x3B2 /* MMU Control Register */
#define SPRN_CCR0 0x3B3 /* Core Configuration Register 0 */
@@ -166,7 +159,6 @@
#define SPRN_SGR 0x3B9 /* Storage Guarded Register */
#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */
#define SPRN_SLER 0x3BB /* Little-endian real mode */
-#define SPRN_SU0R 0x3BC /* "User 0" real mode (40x) */
#define SPRN_DCMP 0x3D1 /* Data TLB Compare Register */
#define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */
#define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */
@@ -183,10 +175,8 @@
#define SPRN_SVR 0x3FF /* System Version Register */
/*
- * SPRs which have conflicting definitions on true Book E versus classic,
- * or IBM 40x.
+ * SPRs which have conflicting definitions on true Book E versus classic.
*/
-#ifdef CONFIG_BOOKE
#define SPRN_CSRR0 0x03A /* Critical Save and Restore Register 0 */
#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */
#define SPRN_DEAR 0x03D /* Data Error Address Register */
@@ -201,22 +191,6 @@
#define SPRN_DAC2 0x13D /* Data Address Compare 2 */
#define SPRN_TSR 0x150 /* Timer Status Register */
#define SPRN_TCR 0x154 /* Timer Control Register */
-#endif /* Book E */
-#ifdef CONFIG_40x
-#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */
-#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */
-#define SPRN_DEAR 0x3D5 /* Data Error Address Register */
-#define SPRN_TSR 0x3D8 /* Timer Status Register */
-#define SPRN_TCR 0x3DA /* Timer Control Register */
-#define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */
-#define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */
-#define SPRN_DBSR 0x3F0 /* Debug Status Register */
-#define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */
-#define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */
-#define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */
-#define SPRN_CSRR0 SPRN_SRR2 /* Critical Save and Restore Register 0 */
-#define SPRN_CSRR1 SPRN_SRR3 /* Critical Save and Restore Register 1 */
-#endif
#define SPRN_HACOP 0x15F /* Hypervisor Available Coprocessor Register */
/* Bit definitions for CCR1. */
@@ -296,10 +270,6 @@
#endif
/* Bit definitions for the DBSR. */
-/*
- * DBSR bits which have conflicting definitions on true Book E versus IBM 40x.
- */
-#ifdef CONFIG_BOOKE
#define DBSR_IDE 0x80000000 /* Imprecise Debug Event */
#define DBSR_MRR 0x30000000 /* Most Recent Reset */
#define DBSR_IC 0x08000000 /* Instruction Completion */
@@ -319,21 +289,6 @@
#define DBSR_CRET 0x00000020 /* Critical Return Debug Event */
#define DBSR_IAC12ATS 0x00000002 /* Instr Address Compare 1/2 Toggle */
#define DBSR_IAC34ATS 0x00000001 /* Instr Address Compare 3/4 Toggle */
-#endif
-#ifdef CONFIG_40x
-#define DBSR_IC 0x80000000 /* Instruction Completion */
-#define DBSR_BT 0x40000000 /* Branch taken */
-#define DBSR_IRPT 0x20000000 /* Exception Debug Event */
-#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */
-#define DBSR_IAC1 0x04000000 /* Instruction Address Compare 1 Event */
-#define DBSR_IAC2 0x02000000 /* Instruction Address Compare 2 Event */
-#define DBSR_IAC3 0x00080000 /* Instruction Address Compare 3 Event */
-#define DBSR_IAC4 0x00040000 /* Instruction Address Compare 4 Event */
-#define DBSR_DAC1R 0x01000000 /* Data Address Compare 1 Read Event */
-#define DBSR_DAC1W 0x00800000 /* Data Address Compare 1 Write Event */
-#define DBSR_DAC2R 0x00400000 /* Data Address Compare 2 Read Event */
-#define DBSR_DAC2W 0x00200000 /* Data Address Compare 2 Write Event */
-#endif
/* Bit definitions related to the ESR. */
#define ESR_MCI 0x80000000 /* Machine Check - Instruction */
@@ -355,69 +310,6 @@
#define ESR_SPV 0x00000080 /* Signal Processing operation */
/* Bit definitions related to the DBCR0. */
-#if defined(CONFIG_40x)
-#define DBCR0_EDM 0x80000000 /* External Debug Mode */
-#define DBCR0_IDM 0x40000000 /* Internal Debug Mode */
-#define DBCR0_RST 0x30000000 /* all the bits in the RST field */
-#define DBCR0_RST_SYSTEM 0x30000000 /* System Reset */
-#define DBCR0_RST_CHIP 0x20000000 /* Chip Reset */
-#define DBCR0_RST_CORE 0x10000000 /* Core Reset */
-#define DBCR0_RST_NONE 0x00000000 /* No Reset */
-#define DBCR0_IC 0x08000000 /* Instruction Completion */
-#define DBCR0_ICMP DBCR0_IC
-#define DBCR0_BT 0x04000000 /* Branch Taken */
-#define DBCR0_BRT DBCR0_BT
-#define DBCR0_EDE 0x02000000 /* Exception Debug Event */
-#define DBCR0_IRPT DBCR0_EDE
-#define DBCR0_TDE 0x01000000 /* TRAP Debug Event */
-#define DBCR0_IA1 0x00800000 /* Instr Addr compare 1 enable */
-#define DBCR0_IAC1 DBCR0_IA1
-#define DBCR0_IA2 0x00400000 /* Instr Addr compare 2 enable */
-#define DBCR0_IAC2 DBCR0_IA2
-#define DBCR0_IA12 0x00200000 /* Instr Addr 1-2 range enable */
-#define DBCR0_IA12X 0x00100000 /* Instr Addr 1-2 range eXclusive */
-#define DBCR0_IA3 0x00080000 /* Instr Addr compare 3 enable */
-#define DBCR0_IAC3 DBCR0_IA3
-#define DBCR0_IA4 0x00040000 /* Instr Addr compare 4 enable */
-#define DBCR0_IAC4 DBCR0_IA4
-#define DBCR0_IA34 0x00020000 /* Instr Addr 3-4 range Enable */
-#define DBCR0_IA34X 0x00010000 /* Instr Addr 3-4 range eXclusive */
-#define DBCR0_IA12T 0x00008000 /* Instr Addr 1-2 range Toggle */
-#define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */
-#define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */
-
-#define dbcr_iac_range(task) ((task)->thread.debug.dbcr0)
-#define DBCR_IAC12I DBCR0_IA12 /* Range Inclusive */
-#define DBCR_IAC12X (DBCR0_IA12 | DBCR0_IA12X) /* Range Exclusive */
-#define DBCR_IAC12MODE (DBCR0_IA12 | DBCR0_IA12X) /* IAC 1-2 Mode Bits */
-#define DBCR_IAC34I DBCR0_IA34 /* Range Inclusive */
-#define DBCR_IAC34X (DBCR0_IA34 | DBCR0_IA34X) /* Range Exclusive */
-#define DBCR_IAC34MODE (DBCR0_IA34 | DBCR0_IA34X) /* IAC 3-4 Mode Bits */
-
-/* Bit definitions related to the DBCR1. */
-#define DBCR1_DAC1R 0x80000000 /* DAC1 Read Debug Event */
-#define DBCR1_DAC2R 0x40000000 /* DAC2 Read Debug Event */
-#define DBCR1_DAC1W 0x20000000 /* DAC1 Write Debug Event */
-#define DBCR1_DAC2W 0x10000000 /* DAC2 Write Debug Event */
-
-#define dbcr_dac(task) ((task)->thread.debug.dbcr1)
-#define DBCR_DAC1R DBCR1_DAC1R
-#define DBCR_DAC1W DBCR1_DAC1W
-#define DBCR_DAC2R DBCR1_DAC2R
-#define DBCR_DAC2W DBCR1_DAC2W
-
-/*
- * Are there any active Debug Events represented in the
- * Debug Control Registers?
- */
-#define DBCR0_ACTIVE_EVENTS (DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
- DBCR0_IAC3 | DBCR0_IAC4)
-#define DBCR1_ACTIVE_EVENTS (DBCR1_DAC1R | DBCR1_DAC2R | \
- DBCR1_DAC1W | DBCR1_DAC2W)
-#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1) (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
- ((dbcr1) & DBCR1_ACTIVE_EVENTS))
-
-#elif defined(CONFIG_BOOKE)
#define DBCR0_EDM 0x80000000 /* External Debug Mode */
#define DBCR0_IDM 0x40000000 /* Internal Debug Mode */
#define DBCR0_RST 0x30000000 /* all the bits in the RST field */
@@ -518,7 +410,6 @@
#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1) (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
((dbcr1) & DBCR1_ACTIVE_EVENTS))
-#endif /* #elif defined(CONFIG_BOOKE) */
/* Bit definitions related to the TCR. */
#define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 9f50766c4623..221c8f8ff89b 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -58,9 +58,6 @@ static inline u64 get_vtb(void)
*/
static inline u64 get_dec(void)
{
- if (IS_ENABLED(CONFIG_40x))
- return mfspr(SPRN_PIT);
-
return mfspr(SPRN_DEC);
}
@@ -71,9 +68,7 @@ static inline u64 get_dec(void)
*/
static inline void set_dec(u64 val)
{
- if (IS_ENABLED(CONFIG_40x))
- mtspr(SPRN_PIT, (u32)val);
- else if (IS_ENABLED(CONFIG_BOOKE))
+ if (IS_ENABLED(CONFIG_BOOKE))
mtspr(SPRN_DEC, val);
else
mtspr(SPRN_DEC, val - 1);
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index d9ac3a4f46e1..a7b69b25296b 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -137,7 +137,7 @@ TRACE_EVENT(rtas_input,
TP_fast_assign(
__entry->nargs = be32_to_cpu(rtas_args->nargs);
- __assign_str(name, name);
+ __assign_str(name);
be32_to_cpu_array(__get_dynamic_array(inputs), rtas_args->args, __entry->nargs);
),
@@ -162,7 +162,7 @@ TRACE_EVENT(rtas_output,
TP_fast_assign(
__entry->nr_other = be32_to_cpu(rtas_args->nret) - 1;
__entry->status = be32_to_cpu(rtas_args->rets[0]);
- __assign_str(name, name);
+ __assign_str(name);
be32_to_cpu_array(__get_dynamic_array(other_outputs),
&rtas_args->rets[1], __entry->nr_other);
),
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index de10437fd206..fd594bf6c6a9 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -92,9 +92,25 @@ __pu_failed: \
: label)
#endif
+#ifdef CONFIG_CC_IS_CLANG
+#define DS_FORM_CONSTRAINT "Z<>"
+#else
+#define DS_FORM_CONSTRAINT "YZ<>"
+#endif
+
#ifdef __powerpc64__
+#ifdef CONFIG_PPC_KERNEL_PREFIXED
#define __put_user_asm2_goto(x, ptr, label) \
__put_user_asm_goto(x, ptr, label, "std")
+#else
+#define __put_user_asm2_goto(x, addr, label) \
+ asm goto ("1: std%U1%X1 %0,%1 # put_user\n" \
+ EX_TABLE(1b, %l2) \
+ : \
+ : "r" (x), DS_FORM_CONSTRAINT (*addr) \
+ : \
+ : label)
+#endif // CONFIG_PPC_KERNEL_PREFIXED
#else /* __powerpc64__ */
#define __put_user_asm2_goto(x, addr, label) \
asm goto( \
@@ -165,8 +181,19 @@ do { \
#endif
#ifdef __powerpc64__
+#ifdef CONFIG_PPC_KERNEL_PREFIXED
#define __get_user_asm2_goto(x, addr, label) \
__get_user_asm_goto(x, addr, label, "ld")
+#else
+#define __get_user_asm2_goto(x, addr, label) \
+ asm_goto_output( \
+ "1: ld%U1%X1 %0, %1 # get_user\n" \
+ EX_TABLE(1b, %l2) \
+ : "=r" (x) \
+ : DS_FORM_CONSTRAINT (*addr) \
+ : \
+ : label)
+#endif // CONFIG_PPC_KERNEL_PREFIXED
#else /* __powerpc64__ */
#define __get_user_asm2_goto(x, addr, label) \
asm_goto_output( \
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index b1f094728b35..289023f7a656 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -44,7 +44,6 @@ void __init udbg_init_rtas_panel(void);
void __init udbg_init_rtas_console(void);
void __init udbg_init_btext(void);
void __init udbg_init_44x_as1(void);
-void __init udbg_init_40x_realmode(void);
void __init udbg_init_cpm(void);
void __init udbg_init_usbgecko(void);
void __init udbg_init_memcons(void);
diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h
index e278299b9b37..6949b5daa37d 100644
--- a/arch/powerpc/include/asm/uninorth.h
+++ b/arch/powerpc/include/asm/uninorth.h
@@ -144,7 +144,7 @@
#define UNI_N_HWINIT_STATE_SLEEPING 0x01
#define UNI_N_HWINIT_STATE_RUNNING 0x02
/* This last bit appear to be used by the bootROM to know the second
- * CPU has started and will enter it's sleep loop with IP=0
+ * CPU has started and will enter its sleep loop with IP=0
*/
#define UNI_N_HWINIT_STATE_CPU1_FLAG 0x10000000
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 659a996c75aa..027ef94a12fb 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -51,7 +51,6 @@
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
index 78302f6c2580..c6390890a60c 100644
--- a/arch/powerpc/include/asm/vdso/gettimeofday.h
+++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
@@ -13,6 +13,17 @@
#define VDSO_HAS_TIME 1
+/*
+ * powerpc specific delta calculation.
+ *
+ * This variant removes the masking of the subtraction because the
+ * clocksource mask of all VDSO capable clocksources on powerpc is U64_MAX
+ * which would result in a pointless operation. The compiler cannot
+ * optimize it away as the mask comes from the vdso data and is not compile
+ * time constant.
+ */
+#define VDSO_DELTA_NOMASK 1
+
static __always_inline int do_syscall_2(const unsigned long _r0, const unsigned long _r3,
const unsigned long _r4)
{
@@ -104,21 +115,6 @@ static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
}
#define vdso_clocksource_ok vdso_clocksource_ok
-/*
- * powerpc specific delta calculation.
- *
- * This variant removes the masking of the subtraction because the
- * clocksource mask of all VDSO capable clocksources on powerpc is U64_MAX
- * which would result in a pointless operation. The compiler cannot
- * optimize it away as the mask comes from the vdso data and is not compile
- * time constant.
- */
-static __always_inline u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
-{
- return (cycles - last) * mult;
-}
-#define vdso_calc_delta vdso_calc_delta
-
#ifndef __powerpc64__
static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift)
{
diff --git a/arch/powerpc/include/asm/fb.h b/arch/powerpc/include/asm/video.h
index c0c5d1df7ad1..e1770114ffc3 100644
--- a/arch/powerpc/include/asm/fb.h
+++ b/arch/powerpc/include/asm/video.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
#include <asm/page.h>
@@ -12,6 +12,6 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
}
#define pgprot_framebuffer pgprot_framebuffer
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/powerpc/include/asm/vio.h b/arch/powerpc/include/asm/vio.h
index 6faf2a931755..7c444150c5ad 100644
--- a/arch/powerpc/include/asm/vio.h
+++ b/arch/powerpc/include/asm/vio.h
@@ -156,11 +156,7 @@ static inline int vio_enable_interrupts(struct vio_dev *dev)
}
#endif
-static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
-{
- return container_of(drv, struct vio_driver, driver);
-}
-
+#define to_vio_driver(__drv) container_of_const(__drv, struct vio_driver, driver)
#define to_vio_dev(__dev) container_of_const(__dev, struct vio_dev, dev)
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/uapi/asm/bootx.h b/arch/powerpc/include/uapi/asm/bootx.h
index 6728c7e24e58..1b8c121071d9 100644
--- a/arch/powerpc/include/uapi/asm/bootx.h
+++ b/arch/powerpc/include/uapi/asm/bootx.h
@@ -108,7 +108,7 @@ typedef struct boot_infos
/* ALL BELOW NEW (vers. 4) */
/* This defines the physical memory. Valid with BOOT_ARCH_NUBUS flag
- (non-PCI) only. On PCI, memory is contiguous and it's size is in the
+ (non-PCI) only. On PCI, memory is contiguous and its size is in the
device-tree. */
boot_info_map_entry_t
physMemoryMap[MAX_MEM_MAP_SIZE]; /* Where the phys memory is */
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 1691297a766a..eaeda001784e 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -645,6 +645,9 @@ struct kvm_ppc_cpu_char {
#define KVM_REG_PPC_SIER3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3)
#define KVM_REG_PPC_DAWR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc4)
#define KVM_REG_PPC_DAWRX1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc5)
+#define KVM_REG_PPC_DEXCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc6)
+#define KVM_REG_PPC_HASHKEYR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc7)
+#define KVM_REG_PPC_HASHPKEYR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc8)
/* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs
diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
deleted file mode 100644
index 17439925045c..000000000000
--- a/arch/powerpc/include/uapi/asm/papr_pdsm.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * PAPR nvDimm Specific Methods (PDSM) and structs for libndctl
- *
- * (C) Copyright IBM 2020
- *
- * Author: Vaibhav Jain <vaibhav at linux.ibm.com>
- */
-
-#ifndef _UAPI_ASM_POWERPC_PAPR_PDSM_H_
-#define _UAPI_ASM_POWERPC_PAPR_PDSM_H_
-
-#include <linux/types.h>
-#include <linux/ndctl.h>
-
-/*
- * PDSM Envelope:
- *
- * The ioctl ND_CMD_CALL exchange data between user-space and kernel via
- * envelope which consists of 2 headers sections and payload sections as
- * illustrated below:
- * +-----------------+---------------+---------------------------+
- * | 64-Bytes | 8-Bytes | Max 184-Bytes |
- * +-----------------+---------------+---------------------------+
- * | ND-HEADER | PDSM-HEADER | PDSM-PAYLOAD |
- * +-----------------+---------------+---------------------------+
- * | nd_family | | |
- * | nd_size_out | cmd_status | |
- * | nd_size_in | reserved | nd_pdsm_payload |
- * | nd_command | payload --> | |
- * | nd_fw_size | | |
- * | nd_payload ---> | | |
- * +---------------+-----------------+---------------------------+
- *
- * ND Header:
- * This is the generic libnvdimm header described as 'struct nd_cmd_pkg'
- * which is interpreted by libnvdimm before passed on to papr_scm. Important
- * member fields used are:
- * 'nd_family' : (In) NVDIMM_FAMILY_PAPR_SCM
- * 'nd_size_in' : (In) PDSM-HEADER + PDSM-IN-PAYLOAD (usually 0)
- * 'nd_size_out' : (In) PDSM-HEADER + PDSM-RETURN-PAYLOAD
- * 'nd_command' : (In) One of PAPR_PDSM_XXX
- * 'nd_fw_size' : (Out) PDSM-HEADER + size of actual payload returned
- *
- * PDSM Header:
- * This is papr-scm specific header that precedes the payload. This is defined
- * as nd_cmd_pdsm_pkg. Following fields aare available in this header:
- *
- * 'cmd_status' : (Out) Errors if any encountered while servicing PDSM.
- * 'reserved' : Not used, reserved for future and should be set to 0.
- * 'payload' : A union of all the possible payload structs
- *
- * PDSM Payload:
- *
- * The layout of the PDSM Payload is defined by various structs shared between
- * papr_scm and libndctl so that contents of payload can be interpreted. As such
- * its defined as a union of all possible payload structs as
- * 'union nd_pdsm_payload'. Based on the value of 'nd_cmd_pkg.nd_command'
- * appropriate member of the union is accessed.
- */
-
-/* Max payload size that we can handle */
-#define ND_PDSM_PAYLOAD_MAX_SIZE 184
-
-/* Max payload size that we can handle */
-#define ND_PDSM_HDR_SIZE \
- (sizeof(struct nd_pkg_pdsm) - ND_PDSM_PAYLOAD_MAX_SIZE)
-
-/* Various nvdimm health indicators */
-#define PAPR_PDSM_DIMM_HEALTHY 0
-#define PAPR_PDSM_DIMM_UNHEALTHY 1
-#define PAPR_PDSM_DIMM_CRITICAL 2
-#define PAPR_PDSM_DIMM_FATAL 3
-
-/* struct nd_papr_pdsm_health.extension_flags field flags */
-
-/* Indicate that the 'dimm_fuel_gauge' field is valid */
-#define PDSM_DIMM_HEALTH_RUN_GAUGE_VALID 1
-
-/* Indicate that the 'dimm_dsc' field is valid */
-#define PDSM_DIMM_DSC_VALID 2
-
-/*
- * Struct exchanged between kernel & ndctl in for PAPR_PDSM_HEALTH
- * Various flags indicate the health status of the dimm.
- *
- * extension_flags : Any extension fields present in the struct.
- * dimm_unarmed : Dimm not armed. So contents wont persist.
- * dimm_bad_shutdown : Previous shutdown did not persist contents.
- * dimm_bad_restore : Contents from previous shutdown werent restored.
- * dimm_scrubbed : Contents of the dimm have been scrubbed.
- * dimm_locked : Contents of the dimm cant be modified until CEC reboot
- * dimm_encrypted : Contents of dimm are encrypted.
- * dimm_health : Dimm health indicator. One of PAPR_PDSM_DIMM_XXXX
- * dimm_fuel_gauge : Life remaining of DIMM as a percentage from 0-100
- */
-struct nd_papr_pdsm_health {
- union {
- struct {
- __u32 extension_flags;
- __u8 dimm_unarmed;
- __u8 dimm_bad_shutdown;
- __u8 dimm_bad_restore;
- __u8 dimm_scrubbed;
- __u8 dimm_locked;
- __u8 dimm_encrypted;
- __u16 dimm_health;
-
- /* Extension flag PDSM_DIMM_HEALTH_RUN_GAUGE_VALID */
- __u16 dimm_fuel_gauge;
-
- /* Extension flag PDSM_DIMM_DSC_VALID */
- __u64 dimm_dsc;
- };
- __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
- };
-};
-
-/* Flags for injecting specific smart errors */
-#define PDSM_SMART_INJECT_HEALTH_FATAL (1 << 0)
-#define PDSM_SMART_INJECT_BAD_SHUTDOWN (1 << 1)
-
-struct nd_papr_pdsm_smart_inject {
- union {
- struct {
- /* One or more of PDSM_SMART_INJECT_ */
- __u32 flags;
- __u8 fatal_enable;
- __u8 unsafe_shutdown_enable;
- };
- __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
- };
-};
-
-/*
- * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
- * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
- */
-enum papr_pdsm {
- PAPR_PDSM_MIN = 0x0,
- PAPR_PDSM_HEALTH,
- PAPR_PDSM_SMART_INJECT,
- PAPR_PDSM_MAX,
-};
-
-/* Maximal union that can hold all possible payload types */
-union nd_pdsm_payload {
- struct nd_papr_pdsm_health health;
- struct nd_papr_pdsm_smart_inject smart_inject;
- __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
-} __packed;
-
-/*
- * PDSM-header + payload expected with ND_CMD_CALL ioctl from libnvdimm
- * Valid member of union 'payload' is identified via 'nd_cmd_pkg.nd_command'
- * that should always precede this struct when sent to papr_scm via CMD_CALL
- * interface.
- */
-struct nd_pkg_pdsm {
- __s32 cmd_status; /* Out: Sub-cmd status returned back */
- __u16 reserved[2]; /* Ignored and to be set as '0' */
- union nd_pdsm_payload payload;
-} __packed;
-
-#endif /* _UAPI_ASM_POWERPC_PAPR_PDSM_H_ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index d3282fbea4f2..1784b6a6ca1d 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -3,9 +3,6 @@
# Makefile for the linux kernel.
#
-ifdef CONFIG_PPC64
-CFLAGS_prom_init.o += $(NO_MINIMAL_TOC)
-endif
ifdef CONFIG_PPC32
CFLAGS_prom_init.o += -fPIC
CFLAGS_btext.o += -fPIC
@@ -87,6 +84,7 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_PPC_DAWR) += dawr.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o
+obj-$(CONFIG_PPC_BOOK3S_64) += dexcr.o
obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o
obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_64e.o
obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o
@@ -125,7 +123,6 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_PPC64) += head_64.o
obj-$(CONFIG_PPC_BOOK3S_32) += head_book3s_32.o
-obj-$(CONFIG_40x) += head_40x.o
obj-$(CONFIG_44x) += head_44x.o
obj-$(CONFIG_PPC_8xx) += head_8xx.o
obj-$(CONFIG_PPC_85xx) += head_85xx.o
@@ -190,9 +187,6 @@ GCOV_PROFILE_kprobes-ftrace.o := n
KCOV_INSTRUMENT_kprobes-ftrace.o := n
KCSAN_SANITIZE_kprobes-ftrace.o := n
UBSAN_SANITIZE_kprobes-ftrace.o := n
-GCOV_PROFILE_syscall_64.o := n
-KCOV_INSTRUMENT_syscall_64.o := n
-UBSAN_SANITIZE_syscall_64.o := n
UBSAN_SANITIZE_vdso.o := n
# Necessary for booting with kcov enabled on book3e machines
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index f029755f9e69..23733282de4d 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -54,7 +54,7 @@
#endif
#ifdef CONFIG_PPC32
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
#include "head_booke.h"
#endif
#endif
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index bfd3f442e5eb..ab3ca74e6730 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -401,7 +401,7 @@ _GLOBAL(__save_cpu_setup)
andi. r3,r3,0xff00
cmpwi cr0,r3,0x0200
bne 1f
- mfspr r4,SPRN_HID2
+ mfspr r4,SPRN_HID2_750FX
stw r4,CS_HID2(r5)
1:
mtcr r7
@@ -496,7 +496,7 @@ _GLOBAL(__restore_cpu_setup)
bne 4f
lwz r4,CS_HID2(r5)
rlwinm r4,r4,0,19,17
- mtspr SPRN_HID2,r4
+ mtspr SPRN_HID2_750FX,r4
sync
4:
lwz r4,CS_HID1(r5)
diff --git a/arch/powerpc/kernel/cpu_specs.h b/arch/powerpc/kernel/cpu_specs.h
index 85ded3f77204..5ea14605bb41 100644
--- a/arch/powerpc/kernel/cpu_specs.h
+++ b/arch/powerpc/kernel/cpu_specs.h
@@ -1,9 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifdef CONFIG_40x
-#include "cpu_specs_40x.h"
-#endif
-
#ifdef CONFIG_PPC_47x
#include "cpu_specs_47x.h"
#elif defined(CONFIG_44x)
diff --git a/arch/powerpc/kernel/cpu_specs_40x.h b/arch/powerpc/kernel/cpu_specs_40x.h
deleted file mode 100644
index a1362a75b8c8..000000000000
--- a/arch/powerpc/kernel/cpu_specs_40x.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
- */
-
-static struct cpu_spec cpu_specs[] __initdata = {
- { /* STB 04xxx */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x41810000,
- .cpu_name = "STB04xxx",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* NP405L */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x41610000,
- .cpu_name = "NP405L",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* NP4GS3 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x40B10000,
- .cpu_name = "NP4GS3",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* NP405H */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x41410000,
- .cpu_name = "NP405H",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405GPr */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x50910000,
- .cpu_name = "405GPr",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* STBx25xx */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x51510000,
- .cpu_name = "STBx25xx",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405LP */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x41F10000,
- .cpu_name = "405LP",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EP */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x51210000,
- .cpu_name = "405EP",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EX Rev. A/B with Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910007,
- .cpu_name = "405EX Rev. A/B",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EX Rev. C without Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x1291000d,
- .cpu_name = "405EX Rev. C",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EX Rev. C with Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x1291000f,
- .cpu_name = "405EX Rev. C",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EX Rev. D without Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910003,
- .cpu_name = "405EX Rev. D",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EX Rev. D with Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910005,
- .cpu_name = "405EX Rev. D",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EXr Rev. A/B without Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910001,
- .cpu_name = "405EXr Rev. A/B",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EXr Rev. C without Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910009,
- .cpu_name = "405EXr Rev. C",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EXr Rev. C with Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x1291000b,
- .cpu_name = "405EXr Rev. C",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EXr Rev. D without Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910000,
- .cpu_name = "405EXr Rev. D",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* 405EXr Rev. D with Security */
- .pvr_mask = 0xffff000f,
- .pvr_value = 0x12910002,
- .cpu_name = "405EXr Rev. D",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- {
- /* 405EZ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x41510000,
- .cpu_name = "405EZ",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* APM8018X */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x7ff11432,
- .cpu_name = "APM8018X",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- },
- { /* default match */
- .pvr_mask = 0x00000000,
- .pvr_value = 0x00000000,
- .cpu_name = "(generic 40x PPC)",
- .cpu_features = CPU_FTRS_40X,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU |
- PPC_FEATURE_HAS_4xxMAC,
- .mmu_features = MMU_FTR_TYPE_40x,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc405",
- }
-};
diff --git a/arch/powerpc/kernel/dexcr.c b/arch/powerpc/kernel/dexcr.c
new file mode 100644
index 000000000000..3a0358e91c60
--- /dev/null
+++ b/arch/powerpc/kernel/dexcr.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/capability.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/prctl.h>
+#include <linux/sched.h>
+
+#include <asm/cpu_has_feature.h>
+#include <asm/cputable.h>
+#include <asm/processor.h>
+#include <asm/reg.h>
+
+static int __init init_task_dexcr(void)
+{
+ if (!early_cpu_has_feature(CPU_FTR_ARCH_31))
+ return 0;
+
+ current->thread.dexcr_onexec = mfspr(SPRN_DEXCR);
+
+ return 0;
+}
+early_initcall(init_task_dexcr)
+
+/* Allow thread local configuration of these by default */
+#define DEXCR_PRCTL_EDITABLE ( \
+ DEXCR_PR_IBRTPD | \
+ DEXCR_PR_SRAPD | \
+ DEXCR_PR_NPHIE)
+
+static int prctl_to_aspect(unsigned long which, unsigned int *aspect)
+{
+ switch (which) {
+ case PR_PPC_DEXCR_SBHE:
+ *aspect = DEXCR_PR_SBHE;
+ break;
+ case PR_PPC_DEXCR_IBRTPD:
+ *aspect = DEXCR_PR_IBRTPD;
+ break;
+ case PR_PPC_DEXCR_SRAPD:
+ *aspect = DEXCR_PR_SRAPD;
+ break;
+ case PR_PPC_DEXCR_NPHIE:
+ *aspect = DEXCR_PR_NPHIE;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+int get_dexcr_prctl(struct task_struct *task, unsigned long which)
+{
+ unsigned int aspect;
+ int ret;
+
+ ret = prctl_to_aspect(which, &aspect);
+ if (ret)
+ return ret;
+
+ if (aspect & DEXCR_PRCTL_EDITABLE)
+ ret |= PR_PPC_DEXCR_CTRL_EDITABLE;
+
+ if (aspect & mfspr(SPRN_DEXCR))
+ ret |= PR_PPC_DEXCR_CTRL_SET;
+ else
+ ret |= PR_PPC_DEXCR_CTRL_CLEAR;
+
+ if (aspect & task->thread.dexcr_onexec)
+ ret |= PR_PPC_DEXCR_CTRL_SET_ONEXEC;
+ else
+ ret |= PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC;
+
+ return ret;
+}
+
+int set_dexcr_prctl(struct task_struct *task, unsigned long which, unsigned long ctrl)
+{
+ unsigned long dexcr;
+ unsigned int aspect;
+ int err = 0;
+
+ err = prctl_to_aspect(which, &aspect);
+ if (err)
+ return err;
+
+ if (!(aspect & DEXCR_PRCTL_EDITABLE))
+ return -EPERM;
+
+ if (ctrl & ~PR_PPC_DEXCR_CTRL_MASK)
+ return -EINVAL;
+
+ if (ctrl & PR_PPC_DEXCR_CTRL_SET && ctrl & PR_PPC_DEXCR_CTRL_CLEAR)
+ return -EINVAL;
+
+ if (ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC && ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC)
+ return -EINVAL;
+
+ /*
+ * We do not want an unprivileged process being able to disable
+ * a setuid process's hash check instructions
+ */
+ if (aspect == DEXCR_PR_NPHIE &&
+ ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC &&
+ !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ dexcr = mfspr(SPRN_DEXCR);
+
+ if (ctrl & PR_PPC_DEXCR_CTRL_SET)
+ dexcr |= aspect;
+ else if (ctrl & PR_PPC_DEXCR_CTRL_CLEAR)
+ dexcr &= ~aspect;
+
+ if (ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC)
+ task->thread.dexcr_onexec |= aspect;
+ else if (ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC)
+ task->thread.dexcr_onexec &= ~aspect;
+
+ mtspr(SPRN_DEXCR, dexcr);
+
+ return 0;
+}
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 8920862ffd79..f0ae39e77e37 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -216,6 +216,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,
+ .alloc_pages_op = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
};
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index ab316e155ea9..d03f17987fca 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -506,9 +506,18 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
* We will punt with the following conditions: Failure to get
* PE's state, EEH not support and Permanently unavailable
* state, PE is in good state.
+ *
+ * On the pSeries, after reaching the threshold, get_state might
+ * return EEH_STATE_NOT_SUPPORT. However, it's possible that the
+ * device state remains uncleared if the device is not marked
+ * pci_channel_io_perm_failure. Therefore, consider logging the
+ * event to let device removal happen.
+ *
*/
if ((ret < 0) ||
- (ret == EEH_STATE_NOT_SUPPORT) || eeh_state_active(ret)) {
+ (ret == EEH_STATE_NOT_SUPPORT &&
+ dev->error_state == pci_channel_io_perm_failure) ||
+ eeh_state_active(ret)) {
eeh_stats.false_positives++;
pe->false_positives++;
rc = 0;
@@ -1264,22 +1273,6 @@ EXPORT_SYMBOL(eeh_dev_release);
#ifdef CONFIG_IOMMU_API
-static int dev_has_iommu_table(struct device *dev, void *data)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct pci_dev **ppdev = data;
-
- if (!dev)
- return 0;
-
- if (device_iommu_mapped(dev)) {
- *ppdev = pdev;
- return 1;
- }
-
- return 0;
-}
-
/**
* eeh_iommu_group_to_pe - Convert IOMMU group to EEH PE
* @group: IOMMU group
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 48773d2d9be3..7efe04c68f0f 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -865,9 +865,18 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
devices++;
if (!devices) {
- pr_debug("EEH: Frozen PHB#%x-PE#%x is empty!\n",
+ pr_warn("EEH: Frozen PHB#%x-PE#%x is empty!\n",
pe->phb->global_number, pe->addr);
- goto out; /* nothing to recover */
+ /*
+ * The device is removed, tear down its state, on powernv
+ * hotplug driver would take care of it but not on pseries,
+ * permanently disable the card as it is hot removed.
+ *
+ * In the case of powernv, note that the removal of device
+ * is covered by pci rescan lock, so no problem even if hotplug
+ * driver attempts to remove the device.
+ */
+ goto recover_failed;
}
/* Log the event */
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index e0ce81279624..d283d281d28e 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -24,10 +24,10 @@ static int eeh_pe_aux_size = 0;
static LIST_HEAD(eeh_phb_pe);
/**
- * eeh_set_pe_aux_size - Set PE auxillary data size
- * @size: PE auxillary data size
+ * eeh_set_pe_aux_size - Set PE auxiliary data size
+ * @size: PE auxiliary data size in bytes
*
- * Set PE auxillary data size
+ * Set PE auxiliary data size.
*/
void eeh_set_pe_aux_size(int size)
{
@@ -527,7 +527,7 @@ EXPORT_SYMBOL_GPL(eeh_pe_state_mark);
* eeh_pe_mark_isolated
* @pe: EEH PE
*
- * Record that a PE has been isolated by marking the PE and it's children as
+ * Record that a PE has been isolated by marking the PE and its children as
* EEH_PE_ISOLATED (and EEH_PE_CFG_BLOCKED, if required) and their PCI devices
* as pci_channel_io_frozen.
*/
@@ -849,6 +849,7 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
{
struct eeh_dev *edev;
struct pci_dev *pdev;
+ struct pci_bus *bus = NULL;
if (pe->type & EEH_PE_PHB)
return pe->phb->bus;
@@ -859,9 +860,11 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
/* Retrieve the parent PCI bus of first (top) PCI device */
edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, entry);
+ pci_lock_rescan_remove();
pdev = eeh_dev_to_pci_dev(edev);
if (pdev)
- return pdev->bus;
+ bus = pdev->bus;
+ pci_unlock_rescan_remove();
- return NULL;
+ return bus;
}
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 7eda33a24bb4..f4a8c9877249 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -108,7 +108,7 @@ transfer_to_syscall:
stw r11, 0(r1)
mflr r12
stw r12, _LINK(r1)
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
#endif
lis r12,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
@@ -158,9 +158,6 @@ syscall_exit_finish:
1: REST_GPR(2, r1)
REST_GPR(1, r1)
rfi
-#ifdef CONFIG_40x
- b . /* Prevent prefetch past rfi */
-#endif
3: mtcr r5
lwz r4,_CTR(r1)
@@ -214,7 +211,7 @@ start_kernel_thread:
.globl fast_exception_return
fast_exception_return:
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#ifndef CONFIG_BOOKE
andi. r10,r9,MSR_RI /* check for recoverable interrupt */
beq 3f /* if not, we've got problems */
#endif
@@ -237,9 +234,6 @@ fast_exception_return:
REST_GPR(12, r11)
REST_GPR(11, r11)
rfi
-#ifdef CONFIG_40x
- b . /* Prevent prefetch past rfi */
-#endif
_ASM_NOKPROBE_SYMBOL(fast_exception_return)
/* aargh, a nonrecoverable interrupt, panic */
@@ -296,9 +290,6 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
REST_GPR(0, r1)
REST_GPR(1, r1)
rfi
-#ifdef CONFIG_40x
- b . /* Prevent prefetch past rfi */
-#endif
.Lrestore_nvgprs:
REST_NVGPRS(r1)
@@ -346,9 +337,6 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
REST_GPR(0, r1)
REST_GPR(1, r1)
rfi
-#ifdef CONFIG_40x
- b . /* Prevent prefetch past rfi */
-#endif
1: /*
* Emulate stack store with update. New r1 value was already calculated
@@ -375,12 +363,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
mfspr r9, SPRN_SPRG_SCRATCH0
#endif
rfi
-#ifdef CONFIG_40x
- b . /* Prevent prefetch past rfi */
-#endif
_ASM_NOKPROBE_SYMBOL(interrupt_return)
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_BOOKE
/*
* Returning from a critical interrupt in user mode doesn't need
@@ -395,17 +380,6 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return)
* time of the critical interrupt.
*
*/
-#ifdef CONFIG_40x
-#define PPC_40x_TURN_OFF_MSR_DR \
- /* avoid any possible TLB misses here by turning off MSR.DR, we \
- * assume the instructions here are mapped by a pinned TLB entry */ \
- li r10,MSR_IR; \
- mtmsr r10; \
- isync; \
- tophys(r1, r1);
-#else
-#define PPC_40x_TURN_OFF_MSR_DR
-#endif
#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \
REST_NVGPRS(r1); \
@@ -423,7 +397,6 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return)
mtlr r11; \
lwz r10,_CCR(r1); \
mtcrf 0xff,r10; \
- PPC_40x_TURN_OFF_MSR_DR; \
lwz r9,_DEAR(r1); \
lwz r10,_ESR(r1); \
mtspr SPRN_DEAR,r9; \
@@ -471,20 +444,6 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return)
#define RESTORE_MMU_REGS
#endif
-#ifdef CONFIG_40x
- .globl ret_from_crit_exc
-ret_from_crit_exc:
- lis r9,crit_srr0@ha;
- lwz r9,crit_srr0@l(r9);
- lis r10,crit_srr1@ha;
- lwz r10,crit_srr1@l(r10);
- mtspr SPRN_SRR0,r9;
- mtspr SPRN_SRR1,r10;
- RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
-_ASM_NOKPROBE_SYMBOL(ret_from_crit_exc)
-#endif /* CONFIG_40x */
-
-#ifdef CONFIG_BOOKE
.globl ret_from_crit_exc
ret_from_crit_exc:
RESTORE_xSRR(SRR0,SRR1);
@@ -509,4 +468,3 @@ ret_from_mcheck_exc:
RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI)
_ASM_NOKPROBE_SYMBOL(ret_from_mcheck_exc)
#endif /* CONFIG_BOOKE */
-#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S
index 1a9b5ae8ccb2..6a414ed5a411 100644
--- a/arch/powerpc/kernel/epapr_hcalls.S
+++ b/arch/powerpc/kernel/epapr_hcalls.S
@@ -21,7 +21,7 @@ _GLOBAL(epapr_ev_idle)
ori r4, r4,_TLF_NAPPING /* so when we take an exception */
PPC_STL r4, TI_LOCAL_FLAGS(r2) /* it will return to our caller */
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
wrteei 1
#else
mfmsr r4
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index dcf0591ad3c2..63f6b9f513a4 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -485,8 +485,8 @@ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x160, decrementer) /* 0x0900 */
EXCEPTION_STUB(0x180, fixed_interval) /* 0x0980 */
EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */
- EXCEPTION_STUB(0x1c0, data_tlb_miss)
- EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
+ EXCEPTION_STUB(0x1c0, data_tlb_miss_bolted)
+ EXCEPTION_STUB(0x1e0, instruction_tlb_miss_bolted)
EXCEPTION_STUB(0x200, altivec_unavailable)
EXCEPTION_STUB(0x220, altivec_assist)
EXCEPTION_STUB(0x260, perfmon)
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index d14eda1e8589..a612e7513a4f 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -53,8 +53,6 @@ static struct kobject *fadump_kobj;
static atomic_t cpus_in_fadump;
static DEFINE_MUTEX(fadump_mutex);
-static struct fadump_mrange_info crash_mrange_info = { "crash", NULL, 0, 0, 0, false };
-
#define RESERVED_RNGS_SZ 16384 /* 16K - 128 entries */
#define RESERVED_RNGS_CNT (RESERVED_RNGS_SZ / \
sizeof(struct fadump_memory_range))
@@ -133,6 +131,41 @@ static int __init fadump_cma_init(void)
static int __init fadump_cma_init(void) { return 1; }
#endif /* CONFIG_CMA */
+/*
+ * Additional parameters meant for capture kernel are placed in a dedicated area.
+ * If this is capture kernel boot, append these parameters to bootargs.
+ */
+void __init fadump_append_bootargs(void)
+{
+ char *append_args;
+ size_t len;
+
+ if (!fw_dump.dump_active || !fw_dump.param_area_supported || !fw_dump.param_area)
+ return;
+
+ if (fw_dump.param_area >= fw_dump.boot_mem_top) {
+ if (memblock_reserve(fw_dump.param_area, COMMAND_LINE_SIZE)) {
+ pr_warn("WARNING: Can't use additional parameters area!\n");
+ fw_dump.param_area = 0;
+ return;
+ }
+ }
+
+ append_args = (char *)fw_dump.param_area;
+ len = strlen(boot_command_line);
+
+ /*
+ * Too late to fail even if cmdline size exceeds. Truncate additional parameters
+ * to cmdline size and proceed anyway.
+ */
+ if (len + strlen(append_args) >= COMMAND_LINE_SIZE - 1)
+ pr_warn("WARNING: Appending parameters exceeds cmdline size. Truncating!\n");
+
+ pr_debug("Cmdline: %s\n", boot_command_line);
+ snprintf(boot_command_line + len, COMMAND_LINE_SIZE - len, " %s", append_args);
+ pr_info("Updated cmdline: %s\n", boot_command_line);
+}
+
/* Scan the Firmware Assisted dump configuration details. */
int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
int depth, void *data)
@@ -223,28 +256,6 @@ static bool is_fadump_mem_area_contiguous(u64 d_start, u64 d_end)
}
/*
- * Returns true, if there are no holes in boot memory area,
- * false otherwise.
- */
-bool is_fadump_boot_mem_contiguous(void)
-{
- unsigned long d_start, d_end;
- bool ret = false;
- int i;
-
- for (i = 0; i < fw_dump.boot_mem_regs_cnt; i++) {
- d_start = fw_dump.boot_mem_addr[i];
- d_end = d_start + fw_dump.boot_mem_sz[i];
-
- ret = is_fadump_mem_area_contiguous(d_start, d_end);
- if (!ret)
- break;
- }
-
- return ret;
-}
-
-/*
* Returns true, if there are no holes in reserved memory area,
* false otherwise.
*/
@@ -373,12 +384,6 @@ static unsigned long __init get_fadump_area_size(void)
size = PAGE_ALIGN(size);
size += fw_dump.boot_memory_size;
size += sizeof(struct fadump_crash_info_header);
- size += sizeof(struct elfhdr); /* ELF core header.*/
- size += sizeof(struct elf_phdr); /* place holder for cpu notes */
- /* Program headers for crash memory regions. */
- size += sizeof(struct elf_phdr) * (memblock_num_regions(memory) + 2);
-
- size = PAGE_ALIGN(size);
/* This is to hold kernel metadata on platforms that support it */
size += (fw_dump.ops->fadump_get_metadata_size ?
@@ -389,10 +394,11 @@ static unsigned long __init get_fadump_area_size(void)
static int __init add_boot_mem_region(unsigned long rstart,
unsigned long rsize)
{
+ int max_boot_mem_rgns = fw_dump.ops->fadump_max_boot_mem_rgns();
int i = fw_dump.boot_mem_regs_cnt++;
- if (fw_dump.boot_mem_regs_cnt > FADUMP_MAX_MEM_REGS) {
- fw_dump.boot_mem_regs_cnt = FADUMP_MAX_MEM_REGS;
+ if (fw_dump.boot_mem_regs_cnt > max_boot_mem_rgns) {
+ fw_dump.boot_mem_regs_cnt = max_boot_mem_rgns;
return 0;
}
@@ -573,22 +579,6 @@ int __init fadump_reserve_mem(void)
}
}
- /*
- * Calculate the memory boundary.
- * If memory_limit is less than actual memory boundary then reserve
- * the memory for fadump beyond the memory_limit and adjust the
- * memory_limit accordingly, so that the running kernel can run with
- * specified memory_limit.
- */
- if (memory_limit && memory_limit < memblock_end_of_DRAM()) {
- size = get_fadump_area_size();
- if ((memory_limit + size) < memblock_end_of_DRAM())
- memory_limit += size;
- else
- memory_limit = memblock_end_of_DRAM();
- printk(KERN_INFO "Adjusted memory_limit for firmware-assisted"
- " dump, now %#016llx\n", memory_limit);
- }
if (memory_limit)
mem_boundary = memory_limit;
else
@@ -705,7 +695,7 @@ void crash_fadump(struct pt_regs *regs, const char *str)
* old_cpu == -1 means this is the first CPU which has come here,
* go ahead and trigger fadump.
*
- * old_cpu != -1 means some other CPU has already on it's way
+ * old_cpu != -1 means some other CPU has already on its way
* to trigger fadump, just keep looping here.
*/
this_cpu = smp_processor_id();
@@ -931,36 +921,6 @@ static inline int fadump_add_mem_range(struct fadump_mrange_info *mrange_info,
return 0;
}
-static int fadump_exclude_reserved_area(u64 start, u64 end)
-{
- u64 ra_start, ra_end;
- int ret = 0;
-
- ra_start = fw_dump.reserve_dump_area_start;
- ra_end = ra_start + fw_dump.reserve_dump_area_size;
-
- if ((ra_start < end) && (ra_end > start)) {
- if ((start < ra_start) && (end > ra_end)) {
- ret = fadump_add_mem_range(&crash_mrange_info,
- start, ra_start);
- if (ret)
- return ret;
-
- ret = fadump_add_mem_range(&crash_mrange_info,
- ra_end, end);
- } else if (start < ra_start) {
- ret = fadump_add_mem_range(&crash_mrange_info,
- start, ra_start);
- } else if (ra_end < end) {
- ret = fadump_add_mem_range(&crash_mrange_info,
- ra_end, end);
- }
- } else
- ret = fadump_add_mem_range(&crash_mrange_info, start, end);
-
- return ret;
-}
-
static int fadump_init_elfcore_header(char *bufp)
{
struct elfhdr *elf;
@@ -998,52 +958,6 @@ static int fadump_init_elfcore_header(char *bufp)
}
/*
- * Traverse through memblock structure and setup crash memory ranges. These
- * ranges will be used create PT_LOAD program headers in elfcore header.
- */
-static int fadump_setup_crash_memory_ranges(void)
-{
- u64 i, start, end;
- int ret;
-
- pr_debug("Setup crash memory ranges.\n");
- crash_mrange_info.mem_range_cnt = 0;
-
- /*
- * Boot memory region(s) registered with firmware are moved to
- * different location at the time of crash. Create separate program
- * header(s) for this memory chunk(s) with the correct offset.
- */
- for (i = 0; i < fw_dump.boot_mem_regs_cnt; i++) {
- start = fw_dump.boot_mem_addr[i];
- end = start + fw_dump.boot_mem_sz[i];
- ret = fadump_add_mem_range(&crash_mrange_info, start, end);
- if (ret)
- return ret;
- }
-
- for_each_mem_range(i, &start, &end) {
- /*
- * skip the memory chunk that is already added
- * (0 through boot_memory_top).
- */
- if (start < fw_dump.boot_mem_top) {
- if (end > fw_dump.boot_mem_top)
- start = fw_dump.boot_mem_top;
- else
- continue;
- }
-
- /* add this range excluding the reserved dump area. */
- ret = fadump_exclude_reserved_area(start, end);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/*
* If the given physical address falls within the boot memory region then
* return the relocated address that points to the dump region reserved
* for saving initial boot memory contents.
@@ -1073,36 +987,50 @@ static inline unsigned long fadump_relocate(unsigned long paddr)
return raddr;
}
-static int fadump_create_elfcore_headers(char *bufp)
+static void __init populate_elf_pt_load(struct elf_phdr *phdr, u64 start,
+ u64 size, unsigned long long offset)
{
- unsigned long long raddr, offset;
- struct elf_phdr *phdr;
+ phdr->p_align = 0;
+ phdr->p_memsz = size;
+ phdr->p_filesz = size;
+ phdr->p_paddr = start;
+ phdr->p_offset = offset;
+ phdr->p_type = PT_LOAD;
+ phdr->p_flags = PF_R|PF_W|PF_X;
+ phdr->p_vaddr = (unsigned long)__va(start);
+}
+
+static void __init fadump_populate_elfcorehdr(struct fadump_crash_info_header *fdh)
+{
+ char *bufp;
struct elfhdr *elf;
- int i, j;
+ struct elf_phdr *phdr;
+ u64 boot_mem_dest_offset;
+ unsigned long long i, ra_start, ra_end, ra_size, mstart, mend;
+ bufp = (char *) fw_dump.elfcorehdr_addr;
fadump_init_elfcore_header(bufp);
elf = (struct elfhdr *)bufp;
bufp += sizeof(struct elfhdr);
/*
- * setup ELF PT_NOTE, place holder for cpu notes info. The notes info
- * will be populated during second kernel boot after crash. Hence
- * this PT_NOTE will always be the first elf note.
+ * Set up ELF PT_NOTE, a placeholder for CPU notes information.
+ * The notes info will be populated later by platform-specific code.
+ * Hence, this PT_NOTE will always be the first ELF note.
*
* NOTE: Any new ELF note addition should be placed after this note.
*/
phdr = (struct elf_phdr *)bufp;
bufp += sizeof(struct elf_phdr);
phdr->p_type = PT_NOTE;
- phdr->p_flags = 0;
- phdr->p_vaddr = 0;
- phdr->p_align = 0;
-
- phdr->p_offset = 0;
- phdr->p_paddr = 0;
- phdr->p_filesz = 0;
- phdr->p_memsz = 0;
-
+ phdr->p_flags = 0;
+ phdr->p_vaddr = 0;
+ phdr->p_align = 0;
+ phdr->p_offset = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = 0;
+ phdr->p_memsz = 0;
+ /* Increment number of program headers. */
(elf->e_phnum)++;
/* setup ELF PT_NOTE for vmcoreinfo */
@@ -1112,55 +1040,66 @@ static int fadump_create_elfcore_headers(char *bufp)
phdr->p_flags = 0;
phdr->p_vaddr = 0;
phdr->p_align = 0;
-
- phdr->p_paddr = fadump_relocate(paddr_vmcoreinfo_note());
- phdr->p_offset = phdr->p_paddr;
- phdr->p_memsz = phdr->p_filesz = VMCOREINFO_NOTE_SIZE;
-
+ phdr->p_paddr = phdr->p_offset = fdh->vmcoreinfo_raddr;
+ phdr->p_memsz = phdr->p_filesz = fdh->vmcoreinfo_size;
/* Increment number of program headers. */
(elf->e_phnum)++;
- /* setup PT_LOAD sections. */
- j = 0;
- offset = 0;
- raddr = fw_dump.boot_mem_addr[0];
- for (i = 0; i < crash_mrange_info.mem_range_cnt; i++) {
- u64 mbase, msize;
-
- mbase = crash_mrange_info.mem_ranges[i].base;
- msize = crash_mrange_info.mem_ranges[i].size;
- if (!msize)
- continue;
-
+ /*
+ * Setup PT_LOAD sections. first include boot memory regions
+ * and then add rest of the memory regions.
+ */
+ boot_mem_dest_offset = fw_dump.boot_mem_dest_addr;
+ for (i = 0; i < fw_dump.boot_mem_regs_cnt; i++) {
phdr = (struct elf_phdr *)bufp;
bufp += sizeof(struct elf_phdr);
- phdr->p_type = PT_LOAD;
- phdr->p_flags = PF_R|PF_W|PF_X;
- phdr->p_offset = mbase;
-
- if (mbase == raddr) {
- /*
- * The entire real memory region will be moved by
- * firmware to the specified destination_address.
- * Hence set the correct offset.
- */
- phdr->p_offset = fw_dump.boot_mem_dest_addr + offset;
- if (j < (fw_dump.boot_mem_regs_cnt - 1)) {
- offset += fw_dump.boot_mem_sz[j];
- raddr = fw_dump.boot_mem_addr[++j];
- }
+ populate_elf_pt_load(phdr, fw_dump.boot_mem_addr[i],
+ fw_dump.boot_mem_sz[i],
+ boot_mem_dest_offset);
+ /* Increment number of program headers. */
+ (elf->e_phnum)++;
+ boot_mem_dest_offset += fw_dump.boot_mem_sz[i];
+ }
+
+ /* Memory reserved for fadump in first kernel */
+ ra_start = fw_dump.reserve_dump_area_start;
+ ra_size = get_fadump_area_size();
+ ra_end = ra_start + ra_size;
+
+ phdr = (struct elf_phdr *)bufp;
+ for_each_mem_range(i, &mstart, &mend) {
+ /* Boot memory regions already added, skip them now */
+ if (mstart < fw_dump.boot_mem_top) {
+ if (mend > fw_dump.boot_mem_top)
+ mstart = fw_dump.boot_mem_top;
+ else
+ continue;
}
- phdr->p_paddr = mbase;
- phdr->p_vaddr = (unsigned long)__va(mbase);
- phdr->p_filesz = msize;
- phdr->p_memsz = msize;
- phdr->p_align = 0;
+ /* Handle memblock regions overlaps with fadump reserved area */
+ if ((ra_start < mend) && (ra_end > mstart)) {
+ if ((mstart < ra_start) && (mend > ra_end)) {
+ populate_elf_pt_load(phdr, mstart, ra_start - mstart, mstart);
+ /* Increment number of program headers. */
+ (elf->e_phnum)++;
+ bufp += sizeof(struct elf_phdr);
+ phdr = (struct elf_phdr *)bufp;
+ populate_elf_pt_load(phdr, ra_end, mend - ra_end, ra_end);
+ } else if (mstart < ra_start) {
+ populate_elf_pt_load(phdr, mstart, ra_start - mstart, mstart);
+ } else if (ra_end < mend) {
+ populate_elf_pt_load(phdr, ra_end, mend - ra_end, ra_end);
+ }
+ } else {
+ /* No overlap with fadump reserved memory region */
+ populate_elf_pt_load(phdr, mstart, mend - mstart, mstart);
+ }
/* Increment number of program headers. */
(elf->e_phnum)++;
+ bufp += sizeof(struct elf_phdr);
+ phdr = (struct elf_phdr *) bufp;
}
- return 0;
}
static unsigned long init_fadump_header(unsigned long addr)
@@ -1175,14 +1114,25 @@ static unsigned long init_fadump_header(unsigned long addr)
memset(fdh, 0, sizeof(struct fadump_crash_info_header));
fdh->magic_number = FADUMP_CRASH_INFO_MAGIC;
- fdh->elfcorehdr_addr = addr;
+ fdh->version = FADUMP_HEADER_VERSION;
/* We will set the crashing cpu id in crash_fadump() during crash. */
fdh->crashing_cpu = FADUMP_CPU_UNKNOWN;
+
+ /*
+ * The physical address and size of vmcoreinfo are required in the
+ * second kernel to prepare elfcorehdr.
+ */
+ fdh->vmcoreinfo_raddr = fadump_relocate(paddr_vmcoreinfo_note());
+ fdh->vmcoreinfo_size = VMCOREINFO_NOTE_SIZE;
+
+
+ fdh->pt_regs_sz = sizeof(struct pt_regs);
/*
* When LPAR is terminated by PYHP, ensure all possible CPUs'
* register data is processed while exporting the vmcore.
*/
fdh->cpu_mask = *cpu_possible_mask;
+ fdh->cpu_mask_sz = sizeof(struct cpumask);
return addr;
}
@@ -1190,8 +1140,6 @@ static unsigned long init_fadump_header(unsigned long addr)
static int register_fadump(void)
{
unsigned long addr;
- void *vaddr;
- int ret;
/*
* If no memory is reserved then we can not register for firmware-
@@ -1200,18 +1148,10 @@ static int register_fadump(void)
if (!fw_dump.reserve_dump_area_size)
return -ENODEV;
- ret = fadump_setup_crash_memory_ranges();
- if (ret)
- return ret;
-
addr = fw_dump.fadumphdr_addr;
/* Initialize fadump crash info header. */
addr = init_fadump_header(addr);
- vaddr = __va(addr);
-
- pr_debug("Creating ELF core headers at %#016lx\n", addr);
- fadump_create_elfcore_headers(vaddr);
/* register the future kernel dump with firmware. */
pr_debug("Registering for firmware-assisted kernel dump...\n");
@@ -1230,7 +1170,6 @@ void fadump_cleanup(void)
} else if (fw_dump.dump_registered) {
/* Un-register Firmware-assisted dump if it was registered. */
fw_dump.ops->fadump_unregister(&fw_dump);
- fadump_free_mem_ranges(&crash_mrange_info);
}
if (fw_dump.ops->fadump_cleanup)
@@ -1416,6 +1355,22 @@ static void fadump_release_memory(u64 begin, u64 end)
fadump_release_reserved_area(tstart, end);
}
+static void fadump_free_elfcorehdr_buf(void)
+{
+ if (fw_dump.elfcorehdr_addr == 0 || fw_dump.elfcorehdr_size == 0)
+ return;
+
+ /*
+ * Before freeing the memory of `elfcorehdr`, reset the global
+ * `elfcorehdr_addr` to prevent modules like `vmcore` from accessing
+ * invalid memory.
+ */
+ elfcorehdr_addr = ELFCORE_ADDR_ERR;
+ fadump_free_buffer(fw_dump.elfcorehdr_addr, fw_dump.elfcorehdr_size);
+ fw_dump.elfcorehdr_addr = 0;
+ fw_dump.elfcorehdr_size = 0;
+}
+
static void fadump_invalidate_release_mem(void)
{
mutex_lock(&fadump_mutex);
@@ -1427,6 +1382,7 @@ static void fadump_invalidate_release_mem(void)
fadump_cleanup();
mutex_unlock(&fadump_mutex);
+ fadump_free_elfcorehdr_buf();
fadump_release_memory(fw_dump.boot_mem_top, memblock_end_of_DRAM());
fadump_free_cpu_notes_buf();
@@ -1484,6 +1440,18 @@ static ssize_t enabled_show(struct kobject *kobj,
return sprintf(buf, "%d\n", fw_dump.fadump_enabled);
}
+/*
+ * /sys/kernel/fadump/hotplug_ready sysfs node returns 1, which inidcates
+ * to usersapce that fadump re-registration is not required on memory
+ * hotplug events.
+ */
+static ssize_t hotplug_ready_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", 1);
+}
+
static ssize_t mem_reserved_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
@@ -1498,6 +1466,43 @@ static ssize_t registered_show(struct kobject *kobj,
return sprintf(buf, "%d\n", fw_dump.dump_registered);
}
+static ssize_t bootargs_append_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", (char *)__va(fw_dump.param_area));
+}
+
+static ssize_t bootargs_append_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ char *params;
+
+ if (!fw_dump.fadump_enabled || fw_dump.dump_active)
+ return -EPERM;
+
+ if (count >= COMMAND_LINE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Fail here instead of handling this scenario with
+ * some silly workaround in capture kernel.
+ */
+ if (saved_command_line_len + count >= COMMAND_LINE_SIZE) {
+ pr_err("Appending parameters exceeds cmdline size!\n");
+ return -ENOSPC;
+ }
+
+ params = __va(fw_dump.param_area);
+ strscpy_pad(params, buf, COMMAND_LINE_SIZE);
+ /* Remove newline character at the end. */
+ if (params[count-1] == '\n')
+ params[count-1] = '\0';
+
+ return count;
+}
+
static ssize_t registered_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
@@ -1556,11 +1561,14 @@ static struct kobj_attribute release_attr = __ATTR_WO(release_mem);
static struct kobj_attribute enable_attr = __ATTR_RO(enabled);
static struct kobj_attribute register_attr = __ATTR_RW(registered);
static struct kobj_attribute mem_reserved_attr = __ATTR_RO(mem_reserved);
+static struct kobj_attribute hotplug_ready_attr = __ATTR_RO(hotplug_ready);
+static struct kobj_attribute bootargs_append_attr = __ATTR_RW(bootargs_append);
static struct attribute *fadump_attrs[] = {
&enable_attr.attr,
&register_attr.attr,
&mem_reserved_attr.attr,
+ &hotplug_ready_attr.attr,
NULL,
};
@@ -1632,6 +1640,150 @@ static void __init fadump_init_files(void)
return;
}
+static int __init fadump_setup_elfcorehdr_buf(void)
+{
+ int elf_phdr_cnt;
+ unsigned long elfcorehdr_size;
+
+ /*
+ * Program header for CPU notes comes first, followed by one for
+ * vmcoreinfo, and the remaining program headers correspond to
+ * memory regions.
+ */
+ elf_phdr_cnt = 2 + fw_dump.boot_mem_regs_cnt + memblock_num_regions(memory);
+ elfcorehdr_size = sizeof(struct elfhdr) + (elf_phdr_cnt * sizeof(struct elf_phdr));
+ elfcorehdr_size = PAGE_ALIGN(elfcorehdr_size);
+
+ fw_dump.elfcorehdr_addr = (u64)fadump_alloc_buffer(elfcorehdr_size);
+ if (!fw_dump.elfcorehdr_addr) {
+ pr_err("Failed to allocate %lu bytes for elfcorehdr\n",
+ elfcorehdr_size);
+ return -ENOMEM;
+ }
+ fw_dump.elfcorehdr_size = elfcorehdr_size;
+ return 0;
+}
+
+/*
+ * Check if the fadump header of crashed kernel is compatible with fadump kernel.
+ *
+ * It checks the magic number, endianness, and size of non-primitive type
+ * members of fadump header to ensure safe dump collection.
+ */
+static bool __init is_fadump_header_compatible(struct fadump_crash_info_header *fdh)
+{
+ if (fdh->magic_number == FADUMP_CRASH_INFO_MAGIC_OLD) {
+ pr_err("Old magic number, can't process the dump.\n");
+ return false;
+ }
+
+ if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
+ if (fdh->magic_number == swab64(FADUMP_CRASH_INFO_MAGIC))
+ pr_err("Endianness mismatch between the crashed and fadump kernels.\n");
+ else
+ pr_err("Fadump header is corrupted.\n");
+
+ return false;
+ }
+
+ /*
+ * Dump collection is not safe if the size of non-primitive type members
+ * of the fadump header do not match between crashed and fadump kernel.
+ */
+ if (fdh->pt_regs_sz != sizeof(struct pt_regs) ||
+ fdh->cpu_mask_sz != sizeof(struct cpumask)) {
+ pr_err("Fadump header size mismatch.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void __init fadump_process(void)
+{
+ struct fadump_crash_info_header *fdh;
+
+ fdh = (struct fadump_crash_info_header *) __va(fw_dump.fadumphdr_addr);
+ if (!fdh) {
+ pr_err("Crash info header is empty.\n");
+ goto err_out;
+ }
+
+ /* Avoid processing the dump if fadump header isn't compatible */
+ if (!is_fadump_header_compatible(fdh))
+ goto err_out;
+
+ /* Allocate buffer for elfcorehdr */
+ if (fadump_setup_elfcorehdr_buf())
+ goto err_out;
+
+ fadump_populate_elfcorehdr(fdh);
+
+ /* Let platform update the CPU notes in elfcorehdr */
+ if (fw_dump.ops->fadump_process(&fw_dump) < 0)
+ goto err_out;
+
+ /*
+ * elfcorehdr is now ready to be exported.
+ *
+ * set elfcorehdr_addr so that vmcore module will export the
+ * elfcorehdr through '/proc/vmcore'.
+ */
+ elfcorehdr_addr = virt_to_phys((void *)fw_dump.elfcorehdr_addr);
+ return;
+
+err_out:
+ fadump_invalidate_release_mem();
+}
+
+/*
+ * Reserve memory to store additional parameters to be passed
+ * for fadump/capture kernel.
+ */
+static void __init fadump_setup_param_area(void)
+{
+ phys_addr_t range_start, range_end;
+
+ if (!fw_dump.param_area_supported || fw_dump.dump_active)
+ return;
+
+ /* This memory can't be used by PFW or bootloader as it is shared across kernels */
+ if (radix_enabled()) {
+ /*
+ * Anywhere in the upper half should be good enough as all memory
+ * is accessible in real mode.
+ */
+ range_start = memblock_end_of_DRAM() / 2;
+ range_end = memblock_end_of_DRAM();
+ } else {
+ /*
+ * Passing additional parameters is supported for hash MMU only
+ * if the first memory block size is 768MB or higher.
+ */
+ if (ppc64_rma_size < 0x30000000)
+ return;
+
+ /*
+ * 640 MB to 768 MB is not used by PFW/bootloader. So, try reserving
+ * memory for passing additional parameters in this range to avoid
+ * being stomped on by PFW/bootloader.
+ */
+ range_start = 0x2A000000;
+ range_end = range_start + 0x4000000;
+ }
+
+ fw_dump.param_area = memblock_phys_alloc_range(COMMAND_LINE_SIZE,
+ COMMAND_LINE_SIZE,
+ range_start,
+ range_end);
+ if (!fw_dump.param_area || sysfs_create_file(fadump_kobj, &bootargs_append_attr.attr)) {
+ pr_warn("WARNING: Could not setup area to pass additional parameters!\n");
+ return;
+ }
+
+ memset(phys_to_virt(fw_dump.param_area), 0, COMMAND_LINE_SIZE);
+}
+
/*
* Prepare for firmware-assisted dump.
*/
@@ -1651,15 +1803,11 @@ int __init setup_fadump(void)
* saving it to the disk.
*/
if (fw_dump.dump_active) {
- /*
- * if dump process fails then invalidate the registration
- * and release memory before proceeding for re-registration.
- */
- if (fw_dump.ops->fadump_process(&fw_dump) < 0)
- fadump_invalidate_release_mem();
+ fadump_process();
}
/* Initialize the kernel dump memory structure and register with f/w */
else if (fw_dump.reserve_dump_area_size) {
+ fadump_setup_param_area();
fw_dump.ops->fadump_init_mem_struct(&fw_dump);
register_fadump();
}
@@ -1735,8 +1883,3 @@ static void __init fadump_reserve_crash_area(u64 base)
memblock_reserve(mstart, msize);
}
}
-
-unsigned long __init arch_reserved_kernel_pages(void)
-{
- return memblock_reserved_size() / PAGE_SIZE;
-}
diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h
index f8e2911478a7..9cba7dbf58dd 100644
--- a/arch/powerpc/kernel/head_32.h
+++ b/arch/powerpc/kernel/head_32.h
@@ -21,17 +21,9 @@
mtspr SPRN_SPRG_SCRATCH1,r11
mfspr r10, SPRN_SPRG_THREAD
.if \handle_dar_dsisr
-#ifdef CONFIG_40x
- mfspr r11, SPRN_DEAR
-#else
mfspr r11, SPRN_DAR
-#endif
stw r11, DAR(r10)
-#ifdef CONFIG_40x
- mfspr r11, SPRN_ESR
-#else
mfspr r11, SPRN_DSISR
-#endif
stw r11, DSISR(r10)
.endif
mfspr r11, SPRN_SRR0
@@ -96,9 +88,7 @@
.endif
lwz r9, SRR1(r12)
lwz r12, SRR0(r12)
-#ifdef CONFIG_40x
- rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
-#elif defined(CONFIG_PPC_8xx)
+#ifdef CONFIG_PPC_8xx
mtspr SPRN_EID, r2 /* Set MSR_RI */
#else
li r10, MSR_KERNEL /* can take exceptions */
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
deleted file mode 100644
index 9fc90410b385..000000000000
--- a/arch/powerpc/kernel/head_40x.S
+++ /dev/null
@@ -1,721 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
- * Initial PowerPC version.
- * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
- * Rewritten for PReP
- * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
- * Low-level exception handers, MMU support, and rewrite.
- * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
- * PowerPC 8xx modifications.
- * Copyright (c) 1998-1999 TiVo, Inc.
- * PowerPC 403GCX modifications.
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- * PowerPC 403GCX/405GP modifications.
- * Copyright 2000 MontaVista Software Inc.
- * PPC405 modifications
- * PowerPC 403GCX/405GP modifications.
- * Author: MontaVista Software, Inc.
- * frank_rowand@mvista.com or source@mvista.com
- * debbie_chu@mvista.com
- *
- * Module name: head_4xx.S
- *
- * Description:
- * Kernel execution entry point code.
- */
-
-#include <linux/init.h>
-#include <linux/pgtable.h>
-#include <linux/sizes.h>
-#include <linux/linkage.h>
-
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/mmu.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/ptrace.h>
-
-#include "head_32.h"
-
-/* As with the other PowerPC ports, it is expected that when code
- * execution begins here, the following registers contain valid, yet
- * optional, information:
- *
- * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
- * r4 - Starting address of the init RAM disk
- * r5 - Ending address of the init RAM disk
- * r6 - Start of kernel command line string (e.g. "mem=96m")
- * r7 - End of kernel command line string
- *
- * This is all going to change RSN when we add bi_recs....... -- Dan
- */
- __HEAD
-_GLOBAL(_stext);
-_GLOBAL(_start);
-
- mr r31,r3 /* save device tree ptr */
-
- /* We have to turn on the MMU right away so we get cache modes
- * set correctly.
- */
- bl initial_mmu
-
-/* We now have the lower 16 Meg mapped into TLB entries, and the caches
- * ready to work.
- */
-turn_on_mmu:
- lis r0,MSR_KERNEL@h
- ori r0,r0,MSR_KERNEL@l
- mtspr SPRN_SRR1,r0
- lis r0,start_here@h
- ori r0,r0,start_here@l
- mtspr SPRN_SRR0,r0
- rfi /* enables MMU */
- b . /* prevent prefetch past rfi */
-
-/*
- * This area is used for temporarily saving registers during the
- * critical exception prolog.
- */
- . = 0xc0
-crit_save:
-_GLOBAL(crit_r10)
- .space 4
-_GLOBAL(crit_r11)
- .space 4
-_GLOBAL(crit_srr0)
- .space 4
-_GLOBAL(crit_srr1)
- .space 4
-_GLOBAL(crit_r1)
- .space 4
-_GLOBAL(crit_dear)
- .space 4
-_GLOBAL(crit_esr)
- .space 4
-
-/*
- * Exception prolog for critical exceptions. This is a little different
- * from the normal exception prolog above since a critical exception
- * can potentially occur at any point during normal exception processing.
- * Thus we cannot use the same SPRG registers as the normal prolog above.
- * Instead we use a couple of words of memory at low physical addresses.
- * This is OK since we don't support SMP on these processors.
- */
-.macro CRITICAL_EXCEPTION_PROLOG trapno name
- stw r10,crit_r10@l(0) /* save two registers to work with */
- stw r11,crit_r11@l(0)
- mfspr r10,SPRN_SRR0
- mfspr r11,SPRN_SRR1
- stw r10,crit_srr0@l(0)
- stw r11,crit_srr1@l(0)
- mfspr r10,SPRN_DEAR
- mfspr r11,SPRN_ESR
- stw r10,crit_dear@l(0)
- stw r11,crit_esr@l(0)
- mfcr r10 /* save CR in r10 for now */
- mfspr r11,SPRN_SRR3 /* check whether user or kernel */
- andi. r11,r11,MSR_PR
- lis r11,(critirq_ctx-PAGE_OFFSET)@ha
- lwz r11,(critirq_ctx-PAGE_OFFSET)@l(r11)
- beq 1f
- /* COMING FROM USER MODE */
- mfspr r11,SPRN_SPRG_THREAD /* if from user, start at top of */
- lwz r11,TASK_STACK-THREAD(r11) /* this thread's kernel stack */
-1: stw r1,crit_r1@l(0)
- addi r1,r11,THREAD_SIZE-INT_FRAME_SIZE /* Alloc an excpt frm */
- LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)) /* re-enable MMU */
- mtspr SPRN_SRR1, r11
- lis r11, 1f@h
- ori r11, r11, 1f@l
- mtspr SPRN_SRR0, r11
- rfi
-
- .text
-1:
-\name\()_virt:
- lwz r11,crit_r1@l(0)
- stw r11,GPR1(r1)
- stw r11,0(r1)
- mr r11,r1
- stw r10,_CCR(r11) /* save various registers */
- stw r12,GPR12(r11)
- stw r9,GPR9(r11)
- mflr r10
- stw r10,_LINK(r11)
- lis r9,PAGE_OFFSET@ha
- lwz r10,crit_r10@l(r9)
- lwz r12,crit_r11@l(r9)
- stw r10,GPR10(r11)
- stw r12,GPR11(r11)
- lwz r12,crit_dear@l(r9)
- lwz r9,crit_esr@l(r9)
- stw r12,_DEAR(r11) /* since they may have had stuff */
- stw r9,_ESR(r11) /* exception was taken */
- mfspr r12,SPRN_SRR2
- mfspr r9,SPRN_SRR3
- rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
- COMMON_EXCEPTION_PROLOG_END \trapno + 2
-_ASM_NOKPROBE_SYMBOL(\name\()_virt)
-.endm
-
- /*
- * State at this point:
- * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
- * r10 saved in crit_r10 and in stack frame, trashed
- * r11 saved in crit_r11 and in stack frame,
- * now phys stack/exception frame pointer
- * r12 saved in stack frame, now saved SRR2
- * CR saved in stack frame, CR0.EQ = !SRR3.PR
- * LR, DEAR, ESR in stack frame
- * r1 saved in stack frame, now virt stack/excframe pointer
- * r0, r3-r8 saved in stack frame
- */
-
-/*
- * Exception vectors.
- */
-#define CRITICAL_EXCEPTION(n, label, hdlr) \
- START_EXCEPTION(n, label); \
- CRITICAL_EXCEPTION_PROLOG n label; \
- prepare_transfer_to_handler; \
- bl hdlr; \
- b ret_from_crit_exc
-
-/*
- * 0x0100 - Critical Interrupt Exception
- */
- CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
-
-/*
- * 0x0200 - Machine Check Exception
- */
- CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
-
-/*
- * 0x0300 - Data Storage Exception
- * This happens for just a few reasons. U0 set (but we don't do that),
- * or zone protection fault (user violation, write to protected page).
- * The other Data TLB exceptions bail out to this point
- * if they can't resolve the lightweight TLB fault.
- */
- START_EXCEPTION(0x0300, DataStorage)
- EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1
- prepare_transfer_to_handler
- bl do_page_fault
- b interrupt_return
-
-/*
- * 0x0400 - Instruction Storage Exception
- * This is caused by a fetch from non-execute or guarded pages.
- */
- START_EXCEPTION(0x0400, InstructionAccess)
- EXCEPTION_PROLOG 0x400 InstructionAccess
- li r5,0
- stw r5, _ESR(r11) /* Zero ESR */
- stw r12, _DEAR(r11) /* SRR0 as DEAR */
- prepare_transfer_to_handler
- bl do_page_fault
- b interrupt_return
-
-/* 0x0500 - External Interrupt Exception */
- EXCEPTION(0x0500, HardwareInterrupt, do_IRQ)
-
-/* 0x0600 - Alignment Exception */
- START_EXCEPTION(0x0600, Alignment)
- EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1
- prepare_transfer_to_handler
- bl alignment_exception
- REST_NVGPRS(r1)
- b interrupt_return
-
-/* 0x0700 - Program Exception */
- START_EXCEPTION(0x0700, ProgramCheck)
- EXCEPTION_PROLOG 0x700 ProgramCheck handle_dar_dsisr=1
- prepare_transfer_to_handler
- bl program_check_exception
- REST_NVGPRS(r1)
- b interrupt_return
-
- EXCEPTION(0x0800, Trap_08, unknown_exception)
- EXCEPTION(0x0900, Trap_09, unknown_exception)
- EXCEPTION(0x0A00, Trap_0A, unknown_exception)
- EXCEPTION(0x0B00, Trap_0B, unknown_exception)
-
-/* 0x0C00 - System Call Exception */
- START_EXCEPTION(0x0C00, SystemCall)
- SYSCALL_ENTRY 0xc00
-/* Trap_0D is commented out to get more space for system call exception */
-
-/* EXCEPTION(0x0D00, Trap_0D, unknown_exception) */
- EXCEPTION(0x0E00, Trap_0E, unknown_exception)
- EXCEPTION(0x0F00, Trap_0F, unknown_exception)
-
-/* 0x1000 - Programmable Interval Timer (PIT) Exception */
- START_EXCEPTION(0x1000, DecrementerTrap)
- b Decrementer
-
-/* 0x1010 - Fixed Interval Timer (FIT) Exception */
- START_EXCEPTION(0x1010, FITExceptionTrap)
- b FITException
-
-/* 0x1020 - Watchdog Timer (WDT) Exception */
- START_EXCEPTION(0x1020, WDTExceptionTrap)
- b WDTException
-
-/* 0x1100 - Data TLB Miss Exception
- * As the name implies, translation is not in the MMU, so search the
- * page tables and fix it. The only purpose of this function is to
- * load TLB entries from the page table if they exist.
- */
- START_EXCEPTION(0x1100, DTLBMiss)
- mtspr SPRN_SPRG_SCRATCH5, r10 /* Save some working registers */
- mtspr SPRN_SPRG_SCRATCH6, r11
- mtspr SPRN_SPRG_SCRATCH3, r12
- mtspr SPRN_SPRG_SCRATCH4, r9
- mfcr r12
- mfspr r9, SPRN_PID
- rlwimi r12, r9, 0, 0xff
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, PAGE_OFFSET@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- li r9, 0
- mtspr SPRN_PID, r9 /* TLB will have 0 TID */
- b 4f
-
- /* Get the PGD for the current thread.
- */
-3:
- mfspr r11,SPRN_SPRG_THREAD
- lwz r11,PGDIR(r11)
-#ifdef CONFIG_PPC_KUAP
- rlwinm. r9, r9, 0, 0xff
- beq 5f /* Kuap fault */
-#endif
-4:
- tophys(r11, r11)
- rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
- lwz r11, 0(r11) /* Get L1 entry */
- andi. r9, r11, _PMD_PRESENT /* Check if it points to a PTE page */
- beq 2f /* Bail if no table */
-
- rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
- lwz r11, 0(r11) /* Get Linux PTE */
- li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_READ
- andc. r9, r9, r11 /* Check permission */
- bne 5f
-
- rlwinm r9, r11, 1, _PAGE_WRITE /* dirty => w */
- and r9, r9, r11 /* hwwrite = dirty & w */
- rlwimi r11, r9, 0, _PAGE_WRITE /* replace w by hwwrite */
-
- /* Create TLB tag. This is the faulting address plus a static
- * set of bits. These are size, valid, E, U0.
- */
- li r9, 0x00c0
- rlwimi r10, r9, 0, 20, 31
-
- b finish_tlb_load
-
-2: /* Check for possible large-page pmd entry */
- rlwinm. r9, r11, 2, 22, 24
- beq 5f
-
- /* Create TLB tag. This is the faulting address, plus a static
- * set of bits (valid, E, U0) plus the size from the PMD.
- */
- ori r9, r9, 0x40
- rlwimi r10, r9, 0, 20, 31
-
- b finish_tlb_load
-
-5:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mtspr SPRN_PID, r12
- mtcrf 0x80, r12
- mfspr r9, SPRN_SPRG_SCRATCH4
- mfspr r12, SPRN_SPRG_SCRATCH3
- mfspr r11, SPRN_SPRG_SCRATCH6
- mfspr r10, SPRN_SPRG_SCRATCH5
- b DataStorage
-
-/* 0x1200 - Instruction TLB Miss Exception
- * Nearly the same as above, except we get our information from different
- * registers and bailout to a different point.
- */
- START_EXCEPTION(0x1200, ITLBMiss)
- mtspr SPRN_SPRG_SCRATCH5, r10 /* Save some working registers */
- mtspr SPRN_SPRG_SCRATCH6, r11
- mtspr SPRN_SPRG_SCRATCH3, r12
- mtspr SPRN_SPRG_SCRATCH4, r9
- mfcr r12
- mfspr r9, SPRN_PID
- rlwimi r12, r9, 0, 0xff
- mfspr r10, SPRN_SRR0 /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, PAGE_OFFSET@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- li r9, 0
- mtspr SPRN_PID, r9 /* TLB will have 0 TID */
- b 4f
-
- /* Get the PGD for the current thread.
- */
-3:
- mfspr r11,SPRN_SPRG_THREAD
- lwz r11,PGDIR(r11)
-#ifdef CONFIG_PPC_KUAP
- rlwinm. r9, r9, 0, 0xff
- beq 5f /* Kuap fault */
-#endif
-4:
- tophys(r11, r11)
- rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
- lwz r11, 0(r11) /* Get L1 entry */
- andi. r9, r11, _PMD_PRESENT /* Check if it points to a PTE page */
- beq 2f /* Bail if no table */
-
- rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
- lwz r11, 0(r11) /* Get Linux PTE */
- li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
- andc. r9, r9, r11 /* Check permission */
- bne 5f
-
- rlwinm r9, r11, 1, _PAGE_WRITE /* dirty => w */
- and r9, r9, r11 /* hwwrite = dirty & w */
- rlwimi r11, r9, 0, _PAGE_WRITE /* replace w by hwwrite */
-
- /* Create TLB tag. This is the faulting address plus a static
- * set of bits. These are size, valid, E, U0.
- */
- li r9, 0x00c0
- rlwimi r10, r9, 0, 20, 31
-
- b finish_tlb_load
-
-2: /* Check for possible large-page pmd entry */
- rlwinm. r9, r11, 2, 22, 24
- beq 5f
-
- /* Create TLB tag. This is the faulting address, plus a static
- * set of bits (valid, E, U0) plus the size from the PMD.
- */
- ori r9, r9, 0x40
- rlwimi r10, r9, 0, 20, 31
-
- b finish_tlb_load
-
-5:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mtspr SPRN_PID, r12
- mtcrf 0x80, r12
- mfspr r9, SPRN_SPRG_SCRATCH4
- mfspr r12, SPRN_SPRG_SCRATCH3
- mfspr r11, SPRN_SPRG_SCRATCH6
- mfspr r10, SPRN_SPRG_SCRATCH5
- b InstructionAccess
-
- EXCEPTION(0x1300, Trap_13, unknown_exception)
- EXCEPTION(0x1400, Trap_14, unknown_exception)
- EXCEPTION(0x1500, Trap_15, unknown_exception)
- EXCEPTION(0x1600, Trap_16, unknown_exception)
- EXCEPTION(0x1700, Trap_17, unknown_exception)
- EXCEPTION(0x1800, Trap_18, unknown_exception)
- EXCEPTION(0x1900, Trap_19, unknown_exception)
- EXCEPTION(0x1A00, Trap_1A, unknown_exception)
- EXCEPTION(0x1B00, Trap_1B, unknown_exception)
- EXCEPTION(0x1C00, Trap_1C, unknown_exception)
- EXCEPTION(0x1D00, Trap_1D, unknown_exception)
- EXCEPTION(0x1E00, Trap_1E, unknown_exception)
- EXCEPTION(0x1F00, Trap_1F, unknown_exception)
-
-/* Check for a single step debug exception while in an exception
- * handler before state has been saved. This is to catch the case
- * where an instruction that we are trying to single step causes
- * an exception (eg ITLB/DTLB miss) and thus the first instruction of
- * the exception handler generates a single step debug exception.
- *
- * If we get a debug trap on the first instruction of an exception handler,
- * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
- * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
- * The exception handler was handling a non-critical interrupt, so it will
- * save (and later restore) the MSR via SPRN_SRR1, which will still have
- * the MSR_DE bit set.
- */
- /* 0x2000 - Debug Exception */
- START_EXCEPTION(0x2000, DebugTrap)
- CRITICAL_EXCEPTION_PROLOG 0x2000 DebugTrap
-
- /*
- * If this is a single step or branch-taken exception in an
- * exception entry sequence, it was probably meant to apply to
- * the code where the exception occurred (since exception entry
- * doesn't turn off DE automatically). We simulate the effect
- * of turning off DE on entry to an exception handler by turning
- * off DE in the SRR3 value and clearing the debug status.
- */
- mfspr r10,SPRN_DBSR /* check single-step/branch taken */
- andis. r10,r10,DBSR_IC@h
- beq+ 2f
-
- andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */
- beq 1f /* branch and fix it up */
-
- mfspr r10,SPRN_SRR2 /* Faulting instruction address */
- cmplwi r10,0x2100
- bgt+ 2f /* address above exception vectors */
-
- /* here it looks like we got an inappropriate debug exception. */
-1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */
- lis r10,DBSR_IC@h /* clear the IC event */
- mtspr SPRN_DBSR,r10
- /* restore state and get out */
- lwz r10,_CCR(r11)
- lwz r0,GPR0(r11)
- lwz r1,GPR1(r11)
- mtcrf 0x80,r10
- mtspr SPRN_SRR2,r12
- mtspr SPRN_SRR3,r9
- lwz r9,GPR9(r11)
- lwz r12,GPR12(r11)
- lwz r10,crit_r10@l(0)
- lwz r11,crit_r11@l(0)
- rfci
- b .
-
- /* continue normal handling for a critical exception... */
-2: mfspr r4,SPRN_DBSR
- stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */
- prepare_transfer_to_handler
- bl DebugException
- b ret_from_crit_exc
-
- /* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
- __HEAD
-Decrementer:
- EXCEPTION_PROLOG 0x1000 Decrementer
- lis r0,TSR_PIS@h
- mtspr SPRN_TSR,r0 /* Clear the PIT exception */
- prepare_transfer_to_handler
- bl timer_interrupt
- b interrupt_return
-
- /* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
- __HEAD
-FITException:
- EXCEPTION_PROLOG 0x1010 FITException
- prepare_transfer_to_handler
- bl unknown_exception
- b interrupt_return
-
- /* Watchdog Timer (WDT) Exception. (from 0x1020) */
- __HEAD
-WDTException:
- CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
- prepare_transfer_to_handler
- bl WatchdogException
- b ret_from_crit_exc
-
-/* Other PowerPC processors, namely those derived from the 6xx-series
- * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
- * However, for the 4xx-series processors these are neither defined nor
- * reserved.
- */
-
- __HEAD
- /* Damn, I came up one instruction too many to fit into the
- * exception space :-). Both the instruction and data TLB
- * miss get to this point to load the TLB.
- * r10 - TLB_TAG value
- * r11 - Linux PTE
- * r9 - available to use
- * PID - loaded with proper value when we get here
- * Upon exit, we reload everything and RFI.
- * Actually, it will fit now, but oh well.....a common place
- * to load the TLB.
- */
-tlb_4xx_index:
- .long 0
-finish_tlb_load:
- /*
- * Clear out the software-only bits in the PTE to generate the
- * TLB_DATA value. These are the bottom 2 bits of the RPM, the
- * 4 bits of the zone field, and M.
- */
- li r9, 0x0cf2
- andc r11, r11, r9
- rlwimi r11, r10, 8, 24, 27 /* Copy 4 upper address bit into zone */
-
- /* load the next available TLB index. */
- lwz r9, tlb_4xx_index@l(0)
- addi r9, r9, 1
- andi. r9, r9, PPC40X_TLB_SIZE - 1
- stw r9, tlb_4xx_index@l(0)
-
- tlbwe r11, r9, TLB_DATA /* Load TLB LO */
- tlbwe r10, r9, TLB_TAG /* Load TLB HI */
-
- /* Done...restore registers and get out of here.
- */
- mtspr SPRN_PID, r12
- mtcrf 0x80, r12
- mfspr r9, SPRN_SPRG_SCRATCH4
- mfspr r12, SPRN_SPRG_SCRATCH3
- mfspr r11, SPRN_SPRG_SCRATCH6
- mfspr r10, SPRN_SPRG_SCRATCH5
- rfi /* Should sync shadow TLBs */
- b . /* prevent prefetch past rfi */
-
-/* This is where the main kernel code starts.
- */
-start_here:
-
- /* ptr to current */
- lis r2,init_task@h
- ori r2,r2,init_task@l
-
- /* ptr to phys current thread */
- tophys(r4,r2)
- addi r4,r4,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG_THREAD,r4
-
- /* stack */
- lis r1,init_thread_union@ha
- addi r1,r1,init_thread_union@l
- li r0,0
- stwu r0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
-
- bl early_init /* We have to do this with MMU on */
-
-/*
- * Decide what sort of machine this is and initialize the MMU.
- */
-#ifdef CONFIG_KASAN
- bl kasan_early_init
-#endif
- li r3,0
- mr r4,r31
- bl machine_init
- bl MMU_init
-
-/* Go back to running unmapped so we can load up new values
- * and change to using our exception vectors.
- * On the 4xx, all we have to do is invalidate the TLB to clear
- * the old 16M byte TLB mappings.
- */
- lis r4,2f@h
- ori r4,r4,2f@l
- tophys(r4,r4)
- lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
- ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- rfi
- b . /* prevent prefetch past rfi */
-
-/* Load up the kernel context */
-2:
- sync /* Flush to memory before changing TLB */
- tlbia
- isync /* Flush shadow TLBs */
-
- /* set up the PTE pointers for the Abatron bdiGDB.
- */
- lis r6, swapper_pg_dir@h
- ori r6, r6, swapper_pg_dir@l
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- stw r5, 0xf0(0) /* Must match your Abatron config file */
- tophys(r5,r5)
- stw r6, 0(r5)
-
-/* Now turn on the MMU for real! */
- lis r4,MSR_KERNEL@h
- ori r4,r4,MSR_KERNEL@l
- lis r3,start_kernel@h
- ori r3,r3,start_kernel@l
- mtspr SPRN_SRR0,r3
- mtspr SPRN_SRR1,r4
- rfi /* enable MMU and jump to start_kernel */
- b . /* prevent prefetch past rfi */
-
-/* Set up the initial MMU state so we can do the first level of
- * kernel initialization. This maps the first 32 MBytes of memory 1:1
- * virtual to physical and more importantly sets the cache mode.
- */
-SYM_FUNC_START_LOCAL(initial_mmu)
- tlbia /* Invalidate all TLB entries */
- isync
-
- /* We should still be executing code at physical address 0x0000xxxx
- * at this point. However, start_here is at virtual address
- * 0xC000xxxx. So, set up a TLB mapping to cover this once
- * translation is enabled.
- */
-
- lis r3,KERNELBASE@h /* Load the kernel virtual address */
- ori r3,r3,KERNELBASE@l
- tophys(r4,r3) /* Load the kernel physical address */
-
- iccci r0,r3 /* Invalidate the i-cache before use */
-
- /* Load the kernel PID.
- */
- li r0,0
- mtspr SPRN_PID,r0
- sync
-
- /* Configure and load one entry into TLB slots 63 */
- clrrwi r4,r4,10 /* Mask off the real page number */
- ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
-
- clrrwi r3,r3,10 /* Mask off the effective page number */
- ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
-
- li r0,63 /* TLB slot 63 */
-
- tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
- tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
-
- li r0,62 /* TLB slot 62 */
- addis r4,r4,SZ_16M@h
- addis r3,r3,SZ_16M@h
- tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
- tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
-
- isync
-
- /* Establish the exception vector base
- */
- lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */
- tophys(r0,r4) /* Use the physical address */
- mtspr SPRN_EVPR,r0
-
- blr
-SYM_FUNC_END(initial_mmu)
-
-_GLOBAL(abort)
- mfspr r13,SPRN_DBCR0
- oris r13,r13,DBCR0_RST_SYSTEM@h
- mtspr SPRN_DBCR0,r13
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 4690c219bfa4..63432a33ec49 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -647,8 +647,9 @@ __after_prom_start:
* Note: This process overwrites the OF exception vectors.
*/
LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET)
- mr. r4,r26 /* In some cases the loader may */
- beq 9f /* have already put us at zero */
+ mr r4,r26 /* Load the virtual source address into r4 */
+ cmpld r3,r4 /* Check if source == dest */
+ beq 9f /* If so skip the copy */
li r6,0x100 /* Start offset, the first 0x100 */
/* bytes were copied earlier. */
diff --git a/arch/powerpc/kernel/head_85xx.S b/arch/powerpc/kernel/head_85xx.S
index 39724ff5ae1f..f9a73fae6464 100644
--- a/arch/powerpc/kernel/head_85xx.S
+++ b/arch/powerpc/kernel/head_85xx.S
@@ -294,9 +294,10 @@ set_ivor:
/* Macros to hide the PTE size differences
*
* FIND_PTE -- walks the page tables given EA & pgdir pointer
- * r10 -- EA of fault
+ * r10 -- free
* r11 -- PGDIR pointer
* r12 -- free
+ * r13 -- EA of fault
* label 2: is the bailout case
*
* if we find the pte (fall through):
@@ -307,34 +308,34 @@ set_ivor:
#ifdef CONFIG_PTE_64BIT
#ifdef CONFIG_HUGETLB_PAGE
#define FIND_PTE \
- rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
- lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
+ rlwinm r12, r13, 14, 18, 28; /* Compute pgdir/pmd offset */ \
+ add r12, r11, r12; \
+ lwz r11, 4(r12); /* Get pgd/pmd entry */ \
+ rlwinm. r10, r11, 32 - _PAGE_PSIZE_SHIFT, 0x1e; /* get tsize*/ \
+ bne 1000f; /* Huge page (leaf entry) */ \
rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \
- blt 1000f; /* Normal non-huge page */ \
beq 2f; /* Bail if no table */ \
- oris r11, r11, PD_HUGE@h; /* Put back address bit */ \
- andi. r10, r11, HUGEPD_SHIFT_MASK@l; /* extract size field */ \
- xor r12, r10, r11; /* drop size bits from pointer */ \
- b 1001f; \
-1000: rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
+ rlwimi r12, r13, 23, 20, 28; /* Compute pte address */ \
li r10, 0; /* clear r10 */ \
-1001: lwz r11, 4(r12); /* Get pte entry */
+ lwz r11, 4(r12); /* Get pte entry */ \
+1000:
#else
#define FIND_PTE \
- rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
- lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
+ rlwinm r12, r13, 14, 18, 28; /* Compute pgdir/pmd offset */ \
+ add r12, r11, r12; \
+ lwz r11, 4(r12); /* Get pgd/pmd entry */ \
rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \
beq 2f; /* Bail if no table */ \
- rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
+ rlwimi r12, r13, 23, 20, 28; /* Compute pte address */ \
lwz r11, 4(r12); /* Get pte entry */
#endif /* HUGEPAGE */
#else /* !PTE_64BIT */
#define FIND_PTE \
- rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \
+ rlwimi r11, r13, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \
lwz r11, 0(r11); /* Get L1 entry */ \
rlwinm. r12, r11, 0, 0, 19; /* Extract L2 (pte) base address */ \
beq 2f; /* Bail if no table */ \
- rlwimi r12, r10, 22, 20, 29; /* Compute PTE address */ \
+ rlwimi r12, r13, 22, 20, 29; /* Compute PTE address */ \
lwz r11, 0(r12); /* Get Linux PTE */
#endif
@@ -441,13 +442,13 @@ START_BTB_FLUSH_SECTION
BTB_FLUSH(r10)
1:
END_BTB_FLUSH_SECTION
- mfspr r10, SPRN_DEAR /* Get faulting address */
+ mfspr r13, SPRN_DEAR /* Get faulting address */
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
lis r11, PAGE_OFFSET@h
- cmplw 5, r10, r11
+ cmplw 5, r13, r11
blt 5, 3f
lis r11, swapper_pg_dir@h
ori r11, r11, swapper_pg_dir@l
@@ -470,29 +471,14 @@ END_BTB_FLUSH_SECTION
#endif
4:
- /* Mask of required permission bits. Note that while we
- * do copy ESR:ST to _PAGE_WRITE position as trying to write
- * to an RO page is pretty common, we don't do it with
- * _PAGE_DIRTY. We could do it, but it's a fairly rare
- * event so I'd rather take the overhead when it happens
- * rather than adding an instruction here. We should measure
- * whether the whole thing is worth it in the first place
- * as we could avoid loading SPRN_ESR completely in the first
- * place...
- *
- * TODO: Is it worth doing that mfspr & rlwimi in the first
- * place or can we save a couple of instructions here ?
- */
- mfspr r12,SPRN_ESR
+ FIND_PTE
+
#ifdef CONFIG_PTE_64BIT
li r13,_PAGE_PRESENT|_PAGE_BAP_SR
oris r13,r13,_PAGE_ACCESSED@h
#else
li r13,_PAGE_PRESENT|_PAGE_READ|_PAGE_ACCESSED
#endif
- rlwimi r13,r12,11,29,29
-
- FIND_PTE
andc. r13,r13,r11 /* Check permission */
#ifdef CONFIG_PTE_64BIT
@@ -549,13 +535,13 @@ START_BTB_FLUSH_SECTION
1:
END_BTB_FLUSH_SECTION
- mfspr r10, SPRN_SRR0 /* Get faulting address */
+ mfspr r13, SPRN_SRR0 /* Get faulting address */
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
lis r11, PAGE_OFFSET@h
- cmplw 5, r10, r11
+ cmplw 5, r13, r11
blt 5, 3f
lis r11, swapper_pg_dir@h
ori r11, r11, swapper_pg_dir@l
@@ -564,6 +550,7 @@ END_BTB_FLUSH_SECTION
rlwinm r12,r12,0,16,1
mtspr SPRN_MAS1,r12
+ FIND_PTE
/* Make up the required permissions for kernel code */
#ifdef CONFIG_PTE_64BIT
li r13,_PAGE_PRESENT | _PAGE_BAP_SX
@@ -584,6 +571,7 @@ END_BTB_FLUSH_SECTION
beq 2f /* KUAP fault */
#endif
+ FIND_PTE
/* Make up the required permissions for user code */
#ifdef CONFIG_PTE_64BIT
li r13,_PAGE_PRESENT | _PAGE_BAP_UX
@@ -593,7 +581,6 @@ END_BTB_FLUSH_SECTION
#endif
4:
- FIND_PTE
andc. r13,r13,r11 /* Check permission */
#ifdef CONFIG_PTE_64BIT
@@ -746,17 +733,12 @@ finish_tlb_load:
lwz r15, 0(r14)
100: stw r15, 0(r17)
- /*
- * Calc MAS1_TSIZE from r10 (which has pshift encoded)
- * tlb_enc = (pshift - 10).
- */
- subi r15, r10, 10
mfspr r16, SPRN_MAS1
- rlwimi r16, r15, 7, 20, 24
+ rlwimi r16, r10, MAS1_TSIZE_SHIFT, MAS1_TSIZE_MASK
mtspr SPRN_MAS1, r16
/* copy the pshift for use later */
- mr r14, r10
+ addi r14, r10, _PAGE_PSIZE_SHIFT_OFFSET
/* fall through */
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 647b0b445e89..ac74321b1192 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -199,12 +199,12 @@ instruction_counter:
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
INVALIDATE_ADJACENT_PAGES_CPU15(r10, r11)
mtspr SPRN_MD_EPN, r10
-#ifdef CONFIG_MODULES
+#ifdef CONFIG_EXECMEM
mfcr r11
compare_to_kernel_boundary r10, r10
#endif
mfspr r10, SPRN_M_TWB /* Get level 1 table */
-#ifdef CONFIG_MODULES
+#ifdef CONFIG_EXECMEM
blt+ 3f
rlwinm r10, r10, 0, 20, 31
oris r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha
@@ -415,14 +415,13 @@ FixupDAR:/* Entry point for dcbx workaround. */
oris r11, r11, (swapper_pg_dir - PAGE_OFFSET)@ha
3:
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
+ rlwinm r11, r11, 0, ~_PMD_PAGE_8M
mtspr SPRN_MD_TWC, r11
- mtcrf 0x01, r11
mfspr r11, SPRN_MD_TWC
lwz r11, 0(r11) /* Get the pte */
- bt 28,200f /* bit 28 = Large page (8M) */
/* concat physical page address(r11) and page offset(r10) */
rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31
-201: lwz r11,0(r11)
+ lwz r11,0(r11)
/* Check if it really is a dcbx instruction. */
/* dcbt and dcbtst does not generate DTLB Misses/Errors,
* no need to include them here */
@@ -441,11 +440,6 @@ FixupDAR:/* Entry point for dcbx workaround. */
141: mfspr r10,SPRN_M_TW
b DARFixed /* Nope, go back to normal TLB processing */
-200:
- /* concat physical page address(r11) and page offset(r10) */
- rlwimi r11, r10, 0, 32 - PAGE_SHIFT_8M, 31
- b 201b
-
144: mfspr r10, SPRN_DSISR
rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
mtspr SPRN_DSISR, r10
diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S
index c1d89764dd22..57196883a00e 100644
--- a/arch/powerpc/kernel/head_book3s_32.S
+++ b/arch/powerpc/kernel/head_book3s_32.S
@@ -419,14 +419,14 @@ InstructionTLBMiss:
*/
/* Get PTE (linux-style) and check access */
mfspr r3,SPRN_IMISS
-#ifdef CONFIG_MODULES
+#ifdef CONFIG_EXECMEM
lis r1, TASK_SIZE@h /* check if kernel address */
cmplw 0,r1,r3
#endif
mfspr r2, SPRN_SDR1
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
rlwinm r2, r2, 28, 0xfffff000
-#ifdef CONFIG_MODULES
+#ifdef CONFIG_EXECMEM
li r0, 3
bgt- 112f
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
@@ -442,7 +442,7 @@ InstructionTLBMiss:
andc. r1,r1,r2 /* check access & ~permission */
bne- InstructionAddressInvalid /* return if access not permitted */
/* Convert linux-style PTE to low word of PPC-style PTE */
-#ifdef CONFIG_MODULES
+#ifdef CONFIG_EXECMEM
rlwimi r2, r0, 0, 31, 31 /* userspace ? -> PP lsb */
#endif
ori r1, r1, 0xe06 /* clear out reserved bits */
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index b6b5b01a173c..0b5c1993809e 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -145,10 +145,9 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
b transfer_to_syscall /* jump to handler */
.endm
-/* To handle the additional exception priority levels on 40x and Book-E
+/* To handle the additional exception priority levels on Book-E
* processors we allocate a stack per additional priority level.
*
- * On 40x critical is the only additional level
* On 44x/e500 we have critical and machine check
*
* Additionally we reserve a SPRG for each priority level so we can free up a
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 29a8c8e18585..76381e14e800 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -26,6 +26,7 @@
#include <linux/iommu.h>
#include <linux/sched.h>
#include <linux/debugfs.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
@@ -642,7 +643,7 @@ void ppc_iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
tbl->it_ops->flush(tbl);
}
-static void iommu_table_clear(struct iommu_table *tbl)
+void iommu_table_clear(struct iommu_table *tbl)
{
/*
* In case of firmware assisted dump system goes through clean
@@ -683,7 +684,7 @@ static void iommu_table_clear(struct iommu_table *tbl)
#endif
}
-static void iommu_table_reserve_pages(struct iommu_table *tbl,
+void iommu_table_reserve_pages(struct iommu_table *tbl,
unsigned long res_start, unsigned long res_end)
{
int i;
@@ -987,6 +988,23 @@ unsigned long iommu_direction_to_tce_perm(enum dma_data_direction dir)
EXPORT_SYMBOL_GPL(iommu_direction_to_tce_perm);
#ifdef CONFIG_IOMMU_API
+
+int dev_has_iommu_table(struct device *dev, void *data)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_dev **ppdev = data;
+
+ if (!dev)
+ return 0;
+
+ if (device_iommu_mapped(dev)) {
+ *ppdev = pdev;
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* SPAPR TCE API
*/
@@ -1101,59 +1119,6 @@ void iommu_tce_kill(struct iommu_table *tbl,
}
EXPORT_SYMBOL_GPL(iommu_tce_kill);
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
-static int iommu_take_ownership(struct iommu_table *tbl)
-{
- unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;
- int ret = 0;
-
- /*
- * VFIO does not control TCE entries allocation and the guest
- * can write new TCEs on top of existing ones so iommu_tce_build()
- * must be able to release old pages. This functionality
- * requires exchange() callback defined so if it is not
- * implemented, we disallow taking ownership over the table.
- */
- if (!tbl->it_ops->xchg_no_kill)
- return -EINVAL;
-
- spin_lock_irqsave(&tbl->large_pool.lock, flags);
- for (i = 0; i < tbl->nr_pools; i++)
- spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock);
-
- if (iommu_table_in_use(tbl)) {
- pr_err("iommu_tce: it_map is not empty");
- ret = -EBUSY;
- } else {
- memset(tbl->it_map, 0xff, sz);
- }
-
- for (i = 0; i < tbl->nr_pools; i++)
- spin_unlock(&tbl->pools[i].lock);
- spin_unlock_irqrestore(&tbl->large_pool.lock, flags);
-
- return ret;
-}
-
-static void iommu_release_ownership(struct iommu_table *tbl)
-{
- unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;
-
- spin_lock_irqsave(&tbl->large_pool.lock, flags);
- for (i = 0; i < tbl->nr_pools; i++)
- spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock);
-
- memset(tbl->it_map, 0, sz);
-
- iommu_table_reserve_pages(tbl, tbl->it_reserved_start,
- tbl->it_reserved_end);
-
- for (i = 0; i < tbl->nr_pools; i++)
- spin_unlock(&tbl->pools[i].lock);
- spin_unlock_irqrestore(&tbl->large_pool.lock, flags);
-}
-#endif
-
int iommu_add_device(struct iommu_table_group *table_group, struct device *dev)
{
/*
@@ -1186,98 +1151,6 @@ EXPORT_SYMBOL_GPL(iommu_add_device);
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
/*
- * A simple iommu_table_group_ops which only allows reusing the existing
- * iommu_table. This handles VFIO for POWER7 or the nested KVM.
- * The ops does not allow creating windows and only allows reusing the existing
- * one if it matches table_group->tce32_start/tce32_size/page_shift.
- */
-static unsigned long spapr_tce_get_table_size(__u32 page_shift,
- __u64 window_size, __u32 levels)
-{
- unsigned long size;
-
- if (levels > 1)
- return ~0U;
- size = window_size >> (page_shift - 3);
- return size;
-}
-
-static long spapr_tce_create_table(struct iommu_table_group *table_group, int num,
- __u32 page_shift, __u64 window_size, __u32 levels,
- struct iommu_table **ptbl)
-{
- struct iommu_table *tbl = table_group->tables[0];
-
- if (num > 0)
- return -EPERM;
-
- if (tbl->it_page_shift != page_shift ||
- tbl->it_size != (window_size >> page_shift) ||
- tbl->it_indirect_levels != levels - 1)
- return -EINVAL;
-
- *ptbl = iommu_tce_table_get(tbl);
- return 0;
-}
-
-static long spapr_tce_set_window(struct iommu_table_group *table_group,
- int num, struct iommu_table *tbl)
-{
- return tbl == table_group->tables[num] ? 0 : -EPERM;
-}
-
-static long spapr_tce_unset_window(struct iommu_table_group *table_group, int num)
-{
- return 0;
-}
-
-static long spapr_tce_take_ownership(struct iommu_table_group *table_group)
-{
- int i, j, rc = 0;
-
- for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
- struct iommu_table *tbl = table_group->tables[i];
-
- if (!tbl || !tbl->it_map)
- continue;
-
- rc = iommu_take_ownership(tbl);
- if (!rc)
- continue;
-
- for (j = 0; j < i; ++j)
- iommu_release_ownership(table_group->tables[j]);
- return rc;
- }
- return 0;
-}
-
-static void spapr_tce_release_ownership(struct iommu_table_group *table_group)
-{
- int i;
-
- for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
- struct iommu_table *tbl = table_group->tables[i];
-
- if (!tbl)
- continue;
-
- iommu_table_clear(tbl);
- if (tbl->it_map)
- iommu_release_ownership(tbl);
- }
-}
-
-struct iommu_table_group_ops spapr_tce_table_group_ops = {
- .get_table_size = spapr_tce_get_table_size,
- .create_table = spapr_tce_create_table,
- .set_window = spapr_tce_set_window,
- .unset_window = spapr_tce_unset_window,
- .take_ownership = spapr_tce_take_ownership,
- .release_ownership = spapr_tce_release_ownership,
-};
-
-/*
* A simple iommu_ops to allow less cruft in generic VFIO code.
*/
static int
@@ -1298,7 +1171,7 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
* The domain being set to PLATFORM from earlier
* BLOCKED. The table_group ownership has to be released.
*/
- table_group->ops->release_ownership(table_group);
+ table_group->ops->release_ownership(table_group, dev);
iommu_group_put(grp);
return 0;
@@ -1326,7 +1199,7 @@ spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain,
* also sets the dma_api ops
*/
table_group = iommu_group_get_iommudata(grp);
- ret = table_group->ops->take_ownership(table_group);
+ ret = table_group->ops->take_ownership(table_group, dev);
iommu_group_put(grp);
return ret;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 7504ceec5c58..2e1600a8bbbb 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -333,7 +333,7 @@ void __init init_IRQ(void)
static_call_update(ppc_get_irq, ppc_md.get_irq);
}
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
void *critirq_ctx[NR_CPUS] __read_mostly;
void *dbgirq_ctx[NR_CPUS] __read_mostly;
void *mcheckirq_ctx[NR_CPUS] __read_mostly;
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index ebe4d1645ca1..7a8bc03a00af 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -45,7 +45,7 @@ static struct hard_trap_info
{ 0x0800, 0x08 /* SIGFPE */ }, /* fp unavailable */
{ 0x0900, 0x0e /* SIGALRM */ }, /* decrementer */
{ 0x0c00, 0x14 /* SIGCHLD */ }, /* system call */
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
{ 0x2002, 0x05 /* SIGTRAP */ }, /* debug */
#if defined(CONFIG_PPC_85xx)
{ 0x2010, 0x08 /* SIGFPE */ }, /* spe unavailable */
@@ -64,7 +64,7 @@ static struct hard_trap_info
{ 0x2010, 0x08 /* SIGFPE */ }, /* fp unavailable */
{ 0x2020, 0x08 /* SIGFPE */ }, /* ap unavailable */
#endif
-#else /* !CONFIG_BOOKE_OR_40x */
+#else /* !CONFIG_BOOKE */
{ 0x0d00, 0x05 /* SIGTRAP */ }, /* single-step */
#if defined(CONFIG_PPC_8xx)
{ 0x1000, 0x04 /* SIGILL */ }, /* software emulation */
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c b/arch/powerpc/kernel/kprobes-ftrace.c
index 072ebe7f290b..f8208c027148 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
struct pt_regs *regs;
int bit;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(nip, parent_nip);
if (bit < 0)
return;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index bbca90a5e2ec..14c5ddec3056 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -19,8 +19,8 @@
#include <linux/extable.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
-#include <linux/moduleloader.h>
#include <linux/set_memory.h>
+#include <linux/execmem.h>
#include <asm/code-patching.h>
#include <asm/cacheflush.h>
#include <asm/sstep.h>
@@ -126,26 +126,6 @@ kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offse
return (kprobe_opcode_t *)(addr + offset);
}
-void *alloc_insn_page(void)
-{
- void *page;
-
- page = module_alloc(PAGE_SIZE);
- if (!page)
- return NULL;
-
- if (strict_module_rwx_enabled()) {
- int err = set_memory_rox((unsigned long)page, 1);
-
- if (err)
- goto error;
- }
- return page;
-error:
- module_memfree(page);
- return NULL;
-}
-
int arch_prepare_kprobe(struct kprobe *p)
{
int ret = 0;
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 2eabb15687a6..033cd00aa0fc 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -176,46 +176,6 @@ _GLOBAL(low_choose_7447a_dfs)
#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_PPC_BOOK3S_32 */
-#ifdef CONFIG_40x
-
-/*
- * Do an IO access in real mode
- */
-_GLOBAL(real_readb)
- mfmsr r7
- rlwinm r0,r7,0,~MSR_DR
- sync
- mtmsr r0
- sync
- isync
- lbz r3,0(r3)
- sync
- mtmsr r7
- sync
- isync
- blr
-_ASM_NOKPROBE_SYMBOL(real_readb)
-
- /*
- * Do an IO access in real mode
- */
-_GLOBAL(real_writeb)
- mfmsr r7
- rlwinm r0,r7,0,~MSR_DR
- sync
- mtmsr r0
- sync
- isync
- stb r3,0(r4)
- sync
- mtmsr r7
- sync
- isync
- blr
-_ASM_NOKPROBE_SYMBOL(real_writeb)
-
-#endif /* CONFIG_40x */
-
/*
* 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 1a8cdafd68e8..91123e102db4 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -192,7 +192,7 @@ _GLOBAL(scom970_read)
xori r0,r0,MSR_EE
mtmsrd r0,1
- /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
+ /* rotate 24 bits SCOM address 8 bits left and mask out its low 8 bits
* (including parity). On current CPUs they must be 0'd,
* and finally or in RW bit
*/
@@ -226,7 +226,7 @@ _GLOBAL(scom970_write)
xori r0,r0,MSR_EE
mtmsrd r0,1
- /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
+ /* rotate 24 bits SCOM address 8 bits left and mask out its low 8 bits
* (including parity). On current CPUs they must be 0'd.
*/
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index f6d6ae0a1692..baeb24c102c8 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -7,7 +7,6 @@
#include <linux/elf.h>
#include <linux/moduleloader.h>
#include <linux/err.h>
-#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/bug.h>
#include <asm/module.h>
@@ -17,8 +16,6 @@
#include <asm/setup.h>
#include <asm/sections.h>
-static LIST_HEAD(module_bug_list);
-
static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
const char *name)
@@ -88,40 +85,3 @@ int module_finalize(const Elf_Ehdr *hdr,
return 0;
}
-
-static __always_inline void *
-__module_alloc(unsigned long size, unsigned long start, unsigned long end, bool nowarn)
-{
- pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC;
- gfp_t gfp = GFP_KERNEL | (nowarn ? __GFP_NOWARN : 0);
-
- /*
- * Don't do huge page allocations for modules yet until more testing
- * is done. STRICT_MODULE_RWX may require extra work to support this
- * too.
- */
- return __vmalloc_node_range(size, 1, start, end, gfp, prot,
- VM_FLUSH_RESET_PERMS,
- NUMA_NO_NODE, __builtin_return_address(0));
-}
-
-void *module_alloc(unsigned long size)
-{
-#ifdef MODULES_VADDR
- unsigned long limit = (unsigned long)_etext - SZ_32M;
- void *ptr = NULL;
-
- BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
-
- /* First try within 32M limit from _etext to avoid branch trampolines */
- if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit)
- ptr = __module_alloc(size, limit, MODULES_END, true);
-
- if (!ptr)
- ptr = __module_alloc(size, MODULES_VADDR, MODULES_END, false);
-
- return ptr;
-#else
- return __module_alloc(size, VMALLOC_START, VMALLOC_END, false);
-#endif
-}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index d95a48eff412..eac84d687b53 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -517,7 +517,7 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma)
}
/*
- * This one is used by /dev/mem and fbdev who have no clue about the
+ * This one is used by /dev/mem and video who have no clue about the
* PCI device, it tries to find the PCI device first and calls the
* above routine
*/
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 0fe251c6ac2c..9ea74973d78d 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -93,6 +93,36 @@ void pci_hp_remove_devices(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
+static void traverse_siblings_and_scan_slot(struct device_node *start, struct pci_bus *bus)
+{
+ struct device_node *dn;
+ int slotno;
+
+ u32 class = 0;
+
+ if (!of_property_read_u32(start->child, "class-code", &class)) {
+ /* Call of pci_scan_slot for non-bridge/EP case */
+ if (!((class >> 8) == PCI_CLASS_BRIDGE_PCI)) {
+ slotno = PCI_SLOT(PCI_DN(start->child)->devfn);
+ pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ return;
+ }
+ }
+
+ /* Iterate all siblings */
+ for_each_child_of_node(start, dn) {
+ class = 0;
+
+ if (!of_property_read_u32(start->child, "class-code", &class)) {
+ /* Call of pci_scan_slot on each sibling-nodes/bridge-ports */
+ if ((class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ slotno = PCI_SLOT(PCI_DN(dn)->devfn);
+ pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ }
+ }
+ }
+}
+
/**
* pci_hp_add_devices - adds new pci devices to bus
* @bus: the indicated PCI bus
@@ -106,7 +136,7 @@ EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
*/
void pci_hp_add_devices(struct pci_bus *bus)
{
- int slotno, mode, max;
+ int mode, max;
struct pci_dev *dev;
struct pci_controller *phb;
struct device_node *dn = pci_bus_to_OF_node(bus);
@@ -129,8 +159,7 @@ void pci_hp_add_devices(struct pci_bus *bus)
* order for fully rescan all the way down to pick them up.
* They can have been removed during partial hotplug.
*/
- slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
- pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ traverse_siblings_and_scan_slot(dn, bus);
max = bus->busn_res.start;
/*
* Scan bridges that are already configured. We don't touch
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 9452a54d356c..3b506d4c55f3 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1185,6 +1185,9 @@ static inline void save_sprs(struct thread_struct *t)
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE))
t->hashkeyr = mfspr(SPRN_HASHKEYR);
+
+ if (cpu_has_feature(CPU_FTR_ARCH_31))
+ t->dexcr = mfspr(SPRN_DEXCR);
#endif
}
@@ -1267,6 +1270,10 @@ static inline void restore_sprs(struct thread_struct *old_thread,
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) &&
old_thread->hashkeyr != new_thread->hashkeyr)
mtspr(SPRN_HASHKEYR, new_thread->hashkeyr);
+
+ if (cpu_has_feature(CPU_FTR_ARCH_31) &&
+ old_thread->dexcr != new_thread->dexcr)
+ mtspr(SPRN_DEXCR, new_thread->dexcr);
#endif
}
@@ -1566,7 +1573,7 @@ static void __show_regs(struct pt_regs *regs)
if (trap == INTERRUPT_MACHINE_CHECK ||
trap == INTERRUPT_DATA_STORAGE ||
trap == INTERRUPT_ALIGNMENT) {
- if (IS_ENABLED(CONFIG_4xx) || IS_ENABLED(CONFIG_BOOKE))
+ if (IS_ENABLED(CONFIG_BOOKE))
pr_cont("DEAR: "REG" ESR: "REG" ", regs->dear, regs->esr);
else
pr_cont("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr);
@@ -1634,6 +1641,13 @@ void arch_setup_new_exec(void)
current->thread.regs->amr = default_amr;
current->thread.regs->iamr = default_iamr;
#endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+ if (cpu_has_feature(CPU_FTR_ARCH_31)) {
+ current->thread.dexcr = current->thread.dexcr_onexec;
+ mtspr(SPRN_DEXCR, current->thread.dexcr);
+ }
+#endif /* CONFIG_PPC_BOOK3S_64 */
}
#ifdef CONFIG_PPC64
@@ -1647,7 +1661,7 @@ void arch_setup_new_exec(void)
* cases will happen:
*
* 1. The correct thread is running, the wrong thread is not
- * In this situation, the correct thread is woken and proceeds to pass it's
+ * In this situation, the correct thread is woken and proceeds to pass its
* condition check.
*
* 2. Neither threads are running
@@ -1657,15 +1671,15 @@ void arch_setup_new_exec(void)
* for the wrong thread, or they will execute the condition check immediately.
*
* 3. The wrong thread is running, the correct thread is not
- * The wrong thread will be woken, but will fail it's condition check and
+ * The wrong thread will be woken, but will fail its condition check and
* re-execute wait. The correct thread, when scheduled, will execute either
- * it's condition check (which will pass), or wait, which returns immediately
- * when called the first time after the thread is scheduled, followed by it's
+ * its condition check (which will pass), or wait, which returns immediately
+ * when called the first time after the thread is scheduled, followed by its
* condition check (which will pass).
*
* 4. Both threads are running
- * Both threads will be woken. The wrong thread will fail it's condition check
- * and execute another wait, while the correct thread will pass it's condition
+ * Both threads will be woken. The wrong thread will fail its condition check
+ * and execute another wait, while the correct thread will pass its condition
* check.
*
* @t: the task to set the thread ID for
@@ -1861,7 +1875,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
#if defined(CONFIG_PPC_BOOK3S_32) && defined(CONFIG_PPC_KUAP)
p->thread.kuap = KUAP_NONE;
#endif
-#if defined(CONFIG_BOOKE_OR_40x) && defined(CONFIG_PPC_KUAP)
+#if defined(CONFIG_BOOKE) && defined(CONFIG_PPC_KUAP)
p->thread.pid = MMU_NO_CONTEXT;
#endif
@@ -1878,6 +1892,9 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
#ifdef CONFIG_PPC_BOOK3S_64
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE))
p->thread.hashkeyr = current->thread.hashkeyr;
+
+ if (cpu_has_feature(CPU_FTR_ARCH_31))
+ p->thread.dexcr = mfspr(SPRN_DEXCR);
#endif
return 0;
}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index cd8d8883de90..0be07ed407c7 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -331,6 +331,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
void *data)
{
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ const __be32 *cpu_version = NULL;
const __be32 *prop;
const __be32 *intserv;
int i, nthreads;
@@ -420,7 +421,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000) {
identify_cpu(0, be32_to_cpup(prop));
- seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(prop));
+ cpu_version = prop;
}
check_cpu_feature_properties(node);
@@ -431,6 +432,12 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
}
identical_pvr_fixup(node);
+
+ // We can now add the CPU name & PVR to the hardware description
+ seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR));
+ if (cpu_version)
+ seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(cpu_version));
+
init_mmu_slb_size(node);
#ifdef CONFIG_PPC64
@@ -779,7 +786,7 @@ static inline void save_fscr_to_task(void) {}
void __init early_init_devtree(void *params)
{
- phys_addr_t limit;
+ phys_addr_t int_vector_size;
DBG(" -> early_init_devtree(%px)\n", params);
@@ -813,6 +820,9 @@ void __init early_init_devtree(void *params)
*/
of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line);
+ /* Append additional parameters passed for fadump capture kernel */
+ fadump_append_bootargs();
+
/* Scan memory nodes and rebuild MEMBLOCKs */
early_init_dt_scan_root();
early_init_dt_scan_memory_ppc();
@@ -832,9 +842,16 @@ void __init early_init_devtree(void *params)
setup_initial_memory_limit(memstart_addr, first_memblock_size);
/* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
memblock_reserve(PHYSICAL_START, __pa(_end) - PHYSICAL_START);
+#ifdef CONFIG_PPC64
+ /* If relocatable, reserve at least 32k for interrupt vectors etc. */
+ int_vector_size = __end_interrupts - _stext;
+ int_vector_size = max_t(phys_addr_t, SZ_32K, int_vector_size);
+#else
/* If relocatable, reserve first 32k for interrupt vectors etc. */
+ int_vector_size = SZ_32K;
+#endif
if (PHYSICAL_START > MEMORY_START)
- memblock_reserve(MEMORY_START, 0x8000);
+ memblock_reserve(MEMORY_START, int_vector_size);
reserve_kdump_trampoline();
#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP)
/*
@@ -846,9 +863,12 @@ void __init early_init_devtree(void *params)
reserve_crashkernel();
early_reserve_mem();
- /* Ensure that total memory size is page-aligned. */
- limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE);
- memblock_enforce_memory_limit(limit);
+ if (memory_limit > memblock_phys_mem_size())
+ memory_limit = 0;
+
+ /* Align down to 16 MB which is large page size with hash page translation */
+ memory_limit = ALIGN_DOWN(memory_limit ?: memblock_phys_mem_size(), SZ_16M);
+ memblock_enforce_memory_limit(memory_limit);
#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_4K_PAGES)
if (!early_radix_enabled())
@@ -868,9 +888,6 @@ void __init early_init_devtree(void *params)
dt_cpu_ftrs_scan();
- // We can now add the CPU name & PVR to the hardware description
- seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR));
-
/* Retrieve CPU related informations from the flat tree
* (altivec support, boot CPU ID, ...)
*/
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 0ef358285337..fbb68fc28ed3 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -817,8 +817,8 @@ static void __init early_cmdline_parse(void)
opt += 4;
prom_memory_limit = prom_memparse(opt, (const char **)&opt);
#ifdef CONFIG_PPC64
- /* Align to 16 MB == size of ppc64 large page */
- prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
+ /* Align down to 16 MB which is large page size with hash page translation */
+ prom_memory_limit = ALIGN_DOWN(prom_memory_limit, SZ_16M);
#endif
}
diff --git a/arch/powerpc/kernel/ptrace/ptrace-tm.c b/arch/powerpc/kernel/ptrace/ptrace-tm.c
index 210ea834e603..447bff87fd21 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-tm.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-tm.c
@@ -12,7 +12,7 @@ void flush_tmregs_to_thread(struct task_struct *tsk)
{
/*
* If task is not current, it will have been flushed already to
- * it's thread_struct during __switch_to().
+ * its thread_struct during __switch_to().
*
* A reclaim flushes ALL the state or if not in TM save TM SPRs
* in the appropriate thread structures from live.
diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c
index 584cf5c3df50..c1819e0a6684 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -469,12 +469,7 @@ static int dexcr_get(struct task_struct *target, const struct user_regset *regse
if (!cpu_has_feature(CPU_FTR_ARCH_31))
return -ENODEV;
- /*
- * The DEXCR is currently static across all CPUs, so we don't
- * store the target's value anywhere, but the static value
- * will also be correct.
- */
- membuf_store(&to, (u64)lower_32_bits(DEXCR_INIT));
+ membuf_store(&to, (u64)lower_32_bits(target->thread.dexcr));
/*
* Technically the HDEXCR is per-cpu, but a hypervisor can't reasonably
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8064d9c3de86..f7e86e09c49f 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -19,6 +19,7 @@
#include <linux/lockdep.h>
#include <linux/memblock.h>
#include <linux/mutex.h>
+#include <linux/nospec.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/reboot.h>
@@ -1916,6 +1917,9 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
|| nargs + nret > ARRAY_SIZE(args.args))
return -EINVAL;
+ nargs = array_index_nospec(nargs, ARRAY_SIZE(args.args));
+ nret = array_index_nospec(nret, ARRAY_SIZE(args.args) - nargs);
+
/* Copy in args. */
if (copy_from_user(args.args, uargs->args,
nargs * sizeof(rtas_arg_t)) != 0)
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 359577ec1680..5407024881e5 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -773,4 +773,5 @@ static void __exit rtas_flash_cleanup(void)
module_init(rtas_flash_init);
module_exit(rtas_flash_cleanup);
+MODULE_DESCRIPTION("PPC procfs firmware flash interface");
MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 01ed1263e1a9..4bd2f87616ba 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -405,7 +405,7 @@ static void __init cpu_init_thread_core_maps(int tpc)
cpumask_set_cpu(i, &threads_core_mask);
printk(KERN_INFO "CPU maps initialized for %d thread%s per core\n",
- tpc, tpc > 1 ? "s" : "");
+ tpc, str_plural(tpc));
printk(KERN_DEBUG " (thread shift is %d)\n", threads_shift);
}
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
index 7912bb50a7cb..385a00a2e2ca 100644
--- a/arch/powerpc/kernel/setup.h
+++ b/arch/powerpc/kernel/setup.h
@@ -29,7 +29,7 @@ void setup_tlb_core_data(void);
static inline void setup_tlb_core_data(void) { }
#endif
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
void exc_lvl_early_init(void);
#else
static inline void exc_lvl_early_init(void) { }
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index b761cc1a403c..e515c1f7d8d3 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -176,7 +176,7 @@ void __init emergency_stack_init(void)
}
#endif
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
void __init exc_lvl_early_init(void)
{
unsigned int i, hw_cpu;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2f19d5e94485..22f83fbbc762 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -696,11 +696,7 @@ __init u64 ppc64_bolted_size(void)
{
#ifdef CONFIG_PPC_BOOK3E_64
/* Freescale BookE bolts the entire linear mapping */
- /* XXX: BookE ppc64_rma_limit setup seems to disagree? */
- if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E))
- return linear_map_top;
- /* Other BookE, we assume the first GB is bolted */
- return 1ul << 30;
+ return linear_map_top;
#else
/* BookS radix, does not take faults on linear mapping */
if (early_radix_enabled())
@@ -834,6 +830,7 @@ static __init int pcpu_cpu_to_node(int cpu)
unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(__per_cpu_offset);
+DEFINE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged);
void __init setup_per_cpu_areas(void)
{
@@ -876,6 +873,7 @@ void __init setup_per_cpu_areas(void)
if (rc < 0)
panic("cannot initialize percpu area (err=%d)", rc);
+ static_key_enable(&__percpu_first_chunk_is_paged.key);
delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
for_each_possible_cpu(cpu) {
__per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 12e53b3d7923..46e6d2cd7a2d 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -1567,7 +1567,7 @@ static void add_cpu_to_masks(int cpu)
/*
* This CPU will not be in the online mask yet so we need to manually
- * add it to it's own thread sibling mask.
+ * add it to its own thread sibling mask.
*/
map_cpu_to_node(cpu, cpu_to_node(cpu));
cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 17173b82ca21..ebae8415dfbb 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -230,8 +230,10 @@
178 nospu rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
179 32 pread64 sys_ppc_pread64 compat_sys_ppc_pread64
179 64 pread64 sys_pread64
+179 spu pread64 sys_pread64
180 32 pwrite64 sys_ppc_pwrite64 compat_sys_ppc_pwrite64
180 64 pwrite64 sys_pwrite64
+180 spu pwrite64 sys_pwrite64
181 common chown sys_chown
182 common getcwd sys_getcwd
183 common capget sys_capget
@@ -246,6 +248,7 @@
190 common ugetrlimit sys_getrlimit compat_sys_getrlimit
191 32 readahead sys_ppc_readahead compat_sys_ppc_readahead
191 64 readahead sys_readahead
+191 spu readahead sys_readahead
192 32 mmap2 sys_mmap2 compat_sys_mmap2
193 32 truncate64 sys_ppc_truncate64 compat_sys_ppc_truncate64
194 32 ftruncate64 sys_ppc_ftruncate64 compat_sys_ppc_ftruncate64
@@ -293,6 +296,7 @@
232 nospu set_tid_address sys_set_tid_address
233 32 fadvise64 sys_ppc32_fadvise64 compat_sys_ppc32_fadvise64
233 64 fadvise64 sys_fadvise64
+233 spu fadvise64 sys_fadvise64
234 nospu exit_group sys_exit_group
235 nospu lookup_dcookie sys_ni_syscall
236 common epoll_create sys_epoll_create
@@ -502,7 +506,7 @@
412 32 utimensat_time64 sys_utimensat sys_utimensat
413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64
-416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents
+416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64
417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend
419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive
@@ -548,3 +552,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 0f39a6b84132..b842c83ab497 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -139,7 +139,7 @@ static unsigned long dscr_default;
* @val: Returned cpu specific DSCR default value
*
* This function returns the per cpu DSCR default value
- * for any cpu which is contained in it's PACA structure.
+ * for any cpu which is contained in its PACA structure.
*/
static void read_dscr(void *val)
{
@@ -152,7 +152,7 @@ static void read_dscr(void *val)
* @val: New cpu specific DSCR default value to update
*
* This function updates the per cpu DSCR default value
- * for any cpu which is contained in it's PACA structure.
+ * for any cpu which is contained in its PACA structure.
*/
static void write_dscr(void *val)
{
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index df20cf201f74..0ff9f038e800 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -354,6 +354,28 @@ void vtime_flush(struct task_struct *tsk)
acct->hardirq_time = 0;
acct->softirq_time = 0;
}
+
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void vtime_task_switch(struct task_struct *prev)
+{
+ if (is_idle_task(prev))
+ vtime_account_idle(prev);
+ else
+ vtime_account_kernel(prev);
+
+ vtime_flush(prev);
+
+ if (!IS_ENABLED(CONFIG_PPC64)) {
+ struct cpu_accounting_data *acct = get_accounting(current);
+ struct cpu_accounting_data *acct0 = get_accounting(prev);
+
+ acct->starttime = acct0->starttime;
+ }
+}
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
void __no_kcsan __delay(unsigned long loops)
@@ -673,7 +695,7 @@ static int __init get_freq(char *name, int cells, unsigned long *val)
static void start_cpu_decrementer(void)
{
-#ifdef CONFIG_BOOKE_OR_40x
+#ifdef CONFIG_BOOKE
unsigned int tcr;
/* Clear any pending timer interrupts */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f23430adb68a..28d6472c380a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -2244,7 +2244,7 @@ void __noreturn unrecoverable_exception(struct pt_regs *regs)
;
}
-#if defined(CONFIG_BOOKE_WDT) || defined(CONFIG_40x)
+#ifdef CONFIG_BOOKE_WDT
DEFINE_INTERRUPT_HANDLER_NMI(WatchdogException)
{
printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 92b3fc258d11..4b99208f5adc 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -49,9 +49,6 @@ void __init udbg_early_init(void)
#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
/* PPC44x debug */
udbg_init_44x_as1();
-#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
- /* PPC40x debug */
- udbg_init_40x_realmode();
#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
udbg_init_cpm();
#elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index a0467e528b70..313802aff571 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -274,29 +274,6 @@ void __init udbg_init_44x_as1(void)
#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
-#ifdef CONFIG_PPC_EARLY_DEBUG_40x
-
-static u8 udbg_uart_in_40x(unsigned int reg)
-{
- return real_readb((void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR
- + reg);
-}
-
-static void udbg_uart_out_40x(unsigned int reg, u8 val)
-{
- real_writeb(val, (void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR
- + reg);
-}
-
-void __init udbg_init_40x_realmode(void)
-{
- udbg_uart_in = udbg_uart_in_40x;
- udbg_uart_out = udbg_uart_out_40x;
- udbg_use_uart();
-}
-
-#endif /* CONFIG_PPC_EARLY_DEBUG_40x */
-
#ifdef CONFIG_PPC_EARLY_DEBUG_16550
static void __iomem *udbg_uart_early_addr;
diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
index 1b93655c2857..1425b6edc66b 100644
--- a/arch/powerpc/kernel/vdso/Makefile
+++ b/arch/powerpc/kernel/vdso/Makefile
@@ -47,12 +47,6 @@ obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
targets += $(obj-vdso64) vdso64.so.dbg vgettimeofday-64.o
obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
-GCOV_PROFILE := n
-KCOV_INSTRUMENT := n
-UBSAN_SANITIZE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-
ccflags-y := -fno-common -fno-builtin
ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
ldflags-$(CONFIG_LD_IS_LLD) += $(call cc-option,--ld-path=$(LD),-fuse-ld=lld)
@@ -74,9 +68,9 @@ targets += vdso64.lds
CPPFLAGS_vdso64.lds += -P -C
# link rule for the .so file, .lds has to be first
-$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday-32.o FORCE
+$(obj)/vdso32.so.dbg: $(obj)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday-32.o FORCE
$(call if_changed,vdso32ld_and_check)
-$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday-64.o FORCE
+$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday-64.o FORCE
$(call if_changed,vdso64ld_and_check)
# assembly rules for the .S files
@@ -90,10 +84,10 @@ $(obj)/vgettimeofday-64.o: %-64.o: %.c FORCE
$(call if_changed_dep,cc_o_c)
# Generate VDSO offsets using helper script
-gen-vdso32sym := $(srctree)/$(src)/gen_vdso32_offsets.sh
+gen-vdso32sym := $(src)/gen_vdso32_offsets.sh
quiet_cmd_vdso32sym = VDSO32SYM $@
cmd_vdso32sym = $(NM) $< | $(gen-vdso32sym) | LC_ALL=C sort > $@
-gen-vdso64sym := $(srctree)/$(src)/gen_vdso64_offsets.sh
+gen-vdso64sym := $(src)/gen_vdso64_offsets.sh
quiet_cmd_vdso64sym = VDSO64SYM $@
cmd_vdso64sym = $(NM) $< | $(gen-vdso64sym) | LC_ALL=C sort > $@
@@ -114,5 +108,3 @@ quiet_cmd_vdso64ld_and_check = VDSO64L $@
cmd_vdso64ld_and_check = $(VDSOCC) $(ldflags-y) $(LD64FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check)
quiet_cmd_vdso64as = VDSO64A $@
cmd_vdso64as = $(VDSOCC) $(a_flags) $(AS64FLAGS) -c -o $@ $<
-
-OBJECT_FILES_NON_STANDARD := y
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index f420df7888a7..7ab4e2fb28b1 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -123,8 +123,6 @@ SECTIONS
*/
*(.sfpr);
*(.text.asan.* .text.tsan.*)
- MEM_KEEP(init.text)
- MEM_KEEP(exit.text)
} :text
. = ALIGN(PAGE_SIZE);
diff --git a/arch/powerpc/kexec/Makefile b/arch/powerpc/kexec/Makefile
index 8e469c4da3f8..470eb0453e17 100644
--- a/arch/powerpc/kexec/Makefile
+++ b/arch/powerpc/kexec/Makefile
@@ -3,11 +3,11 @@
# Makefile for the linux kernel.
#
-obj-y += core.o core_$(BITS).o
+obj-y += core.o core_$(BITS).o ranges.o
obj-$(CONFIG_PPC32) += relocate_32.o
-obj-$(CONFIG_KEXEC_FILE) += file_load.o ranges.o file_load_$(BITS).o elf_$(BITS).o
+obj-$(CONFIG_KEXEC_FILE) += file_load.o file_load_$(BITS).o elf_$(BITS).o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_CRASH_DUMP) += crash.o
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 762e4d09aacf..222aa326dace 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -17,6 +17,7 @@
#include <linux/cpu.h>
#include <linux/hardirq.h>
#include <linux/of.h>
+#include <linux/libfdt.h>
#include <asm/page.h>
#include <asm/current.h>
@@ -26,10 +27,12 @@
#include <asm/paca.h>
#include <asm/mmu.h>
#include <asm/sections.h> /* _end */
+#include <asm/setup.h>
#include <asm/smp.h>
#include <asm/hw_breakpoint.h>
#include <asm/svm.h>
#include <asm/ultravisor.h>
+#include <asm/crashdump-ppc64.h>
int machine_kexec_prepare(struct kimage *image)
{
@@ -315,6 +318,16 @@ void default_machine_kexec(struct kimage *image)
if (!kdump_in_progress())
kexec_prepare_cpus();
+#ifdef CONFIG_PPC_PSERIES
+ /*
+ * This must be done after other CPUs have shut down, otherwise they
+ * could execute the 'scv' instruction, which is not supported with
+ * reloc disabled (see configure_exceptions()).
+ */
+ if (firmware_has_feature(FW_FEATURE_SET_MODE))
+ pseries_disable_reloc_on_exc();
+#endif
+
printk("kexec: Starting switchover sequence.\n");
/* switch to a staticly allocated stack. Based on irq stack code.
@@ -419,3 +432,113 @@ static int __init export_htab_values(void)
}
late_initcall(export_htab_values);
#endif /* CONFIG_PPC_64S_HASH_MMU */
+
+#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
+/**
+ * add_node_props - Reads node properties from device node structure and add
+ * them to fdt.
+ * @fdt: Flattened device tree of the kernel
+ * @node_offset: offset of the node to add a property at
+ * @dn: device node pointer
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int add_node_props(void *fdt, int node_offset, const struct device_node *dn)
+{
+ int ret = 0;
+ struct property *pp;
+
+ if (!dn)
+ return -EINVAL;
+
+ for_each_property_of_node(dn, pp) {
+ ret = fdt_setprop(fdt, node_offset, pp->name, pp->value, pp->length);
+ if (ret < 0) {
+ pr_err("Unable to add %s property: %s\n", pp->name, fdt_strerror(ret));
+ return ret;
+ }
+ }
+ return ret;
+}
+
+/**
+ * update_cpus_node - Update cpus node of flattened device tree using of_root
+ * device node.
+ * @fdt: Flattened device tree of the kernel.
+ *
+ * Returns 0 on success, negative errno on error.
+ *
+ * Note: expecting no subnodes under /cpus/<node> with device_type == "cpu".
+ * If this changes, update this function to include them.
+ */
+int update_cpus_node(void *fdt)
+{
+ int prev_node_offset;
+ const char *device_type;
+ const struct fdt_property *prop;
+ struct device_node *cpus_node, *dn;
+ int cpus_offset, cpus_subnode_offset, ret = 0;
+
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0 && cpus_offset != -FDT_ERR_NOTFOUND) {
+ pr_err("Malformed device tree: error reading /cpus node: %s\n",
+ fdt_strerror(cpus_offset));
+ return cpus_offset;
+ }
+
+ prev_node_offset = cpus_offset;
+ /* Delete sub-nodes of /cpus node with device_type == "cpu" */
+ for (cpus_subnode_offset = fdt_first_subnode(fdt, cpus_offset); cpus_subnode_offset >= 0;) {
+ /* Ignore nodes that do not have a device_type property or device_type != "cpu" */
+ prop = fdt_get_property(fdt, cpus_subnode_offset, "device_type", NULL);
+ if (!prop || strcmp(prop->data, "cpu")) {
+ prev_node_offset = cpus_subnode_offset;
+ goto next_node;
+ }
+
+ ret = fdt_del_node(fdt, cpus_subnode_offset);
+ if (ret < 0) {
+ pr_err("Failed to delete a cpus sub-node: %s\n", fdt_strerror(ret));
+ return ret;
+ }
+next_node:
+ if (prev_node_offset == cpus_offset)
+ cpus_subnode_offset = fdt_first_subnode(fdt, cpus_offset);
+ else
+ cpus_subnode_offset = fdt_next_subnode(fdt, prev_node_offset);
+ }
+
+ cpus_node = of_find_node_by_path("/cpus");
+ /* Fail here to avoid kexec/kdump kernel boot hung */
+ if (!cpus_node) {
+ pr_err("No /cpus node found\n");
+ return -EINVAL;
+ }
+
+ /* Add all /cpus sub-nodes of device_type == "cpu" to FDT */
+ for_each_child_of_node(cpus_node, dn) {
+ /* Ignore device nodes that do not have a device_type property
+ * or device_type != "cpu".
+ */
+ device_type = of_get_property(dn, "device_type", NULL);
+ if (!device_type || strcmp(device_type, "cpu"))
+ continue;
+
+ cpus_subnode_offset = fdt_add_subnode(fdt, cpus_offset, dn->full_name);
+ if (cpus_subnode_offset < 0) {
+ pr_err("Unable to add %s subnode: %s\n", dn->full_name,
+ fdt_strerror(cpus_subnode_offset));
+ ret = cpus_subnode_offset;
+ goto out;
+ }
+
+ ret = add_node_props(fdt, cpus_subnode_offset, dn);
+ if (ret < 0)
+ goto out;
+ }
+out:
+ of_node_put(cpus_node);
+ of_node_put(dn);
+ return ret;
+}
+#endif /* CONFIG_KEXEC_FILE || CONFIG_CRASH_DUMP */
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index ef5c2d25ec39..9ac3266e4965 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -16,6 +16,8 @@
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/types.h>
+#include <linux/libfdt.h>
+#include <linux/memory.h>
#include <asm/processor.h>
#include <asm/machdep.h>
@@ -24,6 +26,7 @@
#include <asm/setjmp.h>
#include <asm/debug.h>
#include <asm/interrupt.h>
+#include <asm/kexec_ranges.h>
/*
* The primary CPU waits a while for all secondary CPUs to enter. This is to
@@ -392,3 +395,195 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(1, 0);
}
+
+#ifdef CONFIG_CRASH_HOTPLUG
+#undef pr_fmt
+#define pr_fmt(fmt) "crash hp: " fmt
+
+/*
+ * Advertise preferred elfcorehdr size to userspace via
+ * /sys/kernel/crash_elfcorehdr_size sysfs interface.
+ */
+unsigned int arch_crash_get_elfcorehdr_size(void)
+{
+ unsigned long phdr_cnt;
+
+ /* A program header for possible CPUs + vmcoreinfo */
+ phdr_cnt = num_possible_cpus() + 1;
+ if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
+ phdr_cnt += CONFIG_CRASH_MAX_MEMORY_RANGES;
+
+ return sizeof(struct elfhdr) + (phdr_cnt * sizeof(Elf64_Phdr));
+}
+
+/**
+ * update_crash_elfcorehdr() - Recreate the elfcorehdr and replace it with old
+ * elfcorehdr in the kexec segment array.
+ * @image: the active struct kimage
+ * @mn: struct memory_notify data handler
+ */
+static void update_crash_elfcorehdr(struct kimage *image, struct memory_notify *mn)
+{
+ int ret;
+ struct crash_mem *cmem = NULL;
+ struct kexec_segment *ksegment;
+ void *ptr, *mem, *elfbuf = NULL;
+ unsigned long elfsz, memsz, base_addr, size;
+
+ ksegment = &image->segment[image->elfcorehdr_index];
+ mem = (void *) ksegment->mem;
+ memsz = ksegment->memsz;
+
+ ret = get_crash_memory_ranges(&cmem);
+ if (ret) {
+ pr_err("Failed to get crash mem range\n");
+ return;
+ }
+
+ /*
+ * The hot unplugged memory is part of crash memory ranges,
+ * remove it here.
+ */
+ if (image->hp_action == KEXEC_CRASH_HP_REMOVE_MEMORY) {
+ base_addr = PFN_PHYS(mn->start_pfn);
+ size = mn->nr_pages * PAGE_SIZE;
+ ret = remove_mem_range(&cmem, base_addr, size);
+ if (ret) {
+ pr_err("Failed to remove hot-unplugged memory from crash memory ranges\n");
+ goto out;
+ }
+ }
+
+ ret = crash_prepare_elf64_headers(cmem, false, &elfbuf, &elfsz);
+ if (ret) {
+ pr_err("Failed to prepare elf header\n");
+ goto out;
+ }
+
+ /*
+ * It is unlikely that kernel hit this because elfcorehdr kexec
+ * segment (memsz) is built with addition space to accommodate growing
+ * number of crash memory ranges while loading the kdump kernel. It is
+ * Just to avoid any unforeseen case.
+ */
+ if (elfsz > memsz) {
+ pr_err("Updated crash elfcorehdr elfsz %lu > memsz %lu", elfsz, memsz);
+ goto out;
+ }
+
+ ptr = __va(mem);
+ if (ptr) {
+ /* Temporarily invalidate the crash image while it is replaced */
+ xchg(&kexec_crash_image, NULL);
+
+ /* Replace the old elfcorehdr with newly prepared elfcorehdr */
+ memcpy((void *)ptr, elfbuf, elfsz);
+
+ /* The crash image is now valid once again */
+ xchg(&kexec_crash_image, image);
+ }
+out:
+ kvfree(cmem);
+ kvfree(elfbuf);
+}
+
+/**
+ * get_fdt_index - Loop through the kexec segment array and find
+ * the index of the FDT segment.
+ * @image: a pointer to kexec_crash_image
+ *
+ * Returns the index of FDT segment in the kexec segment array
+ * if found; otherwise -1.
+ */
+static int get_fdt_index(struct kimage *image)
+{
+ void *ptr;
+ unsigned long mem;
+ int i, fdt_index = -1;
+
+ /* Find the FDT segment index in kexec segment array. */
+ for (i = 0; i < image->nr_segments; i++) {
+ mem = image->segment[i].mem;
+ ptr = __va(mem);
+
+ if (ptr && fdt_magic(ptr) == FDT_MAGIC) {
+ fdt_index = i;
+ break;
+ }
+ }
+
+ return fdt_index;
+}
+
+/**
+ * update_crash_fdt - updates the cpus node of the crash FDT.
+ *
+ * @image: a pointer to kexec_crash_image
+ */
+static void update_crash_fdt(struct kimage *image)
+{
+ void *fdt;
+ int fdt_index;
+
+ fdt_index = get_fdt_index(image);
+ if (fdt_index < 0) {
+ pr_err("Unable to locate FDT segment.\n");
+ return;
+ }
+
+ fdt = __va((void *)image->segment[fdt_index].mem);
+
+ /* Temporarily invalidate the crash image while it is replaced */
+ xchg(&kexec_crash_image, NULL);
+
+ /* update FDT to reflect changes in CPU resources */
+ if (update_cpus_node(fdt))
+ pr_err("Failed to update crash FDT");
+
+ /* The crash image is now valid once again */
+ xchg(&kexec_crash_image, image);
+}
+
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
+{
+#ifdef CONFIG_KEXEC_FILE
+ if (image->file_mode)
+ return 1;
+#endif
+ return kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT;
+}
+
+/**
+ * arch_crash_handle_hotplug_event - Handle crash CPU/Memory hotplug events to update the
+ * necessary kexec segments based on the hotplug event.
+ * @image: a pointer to kexec_crash_image
+ * @arg: struct memory_notify handler for memory hotplug case and NULL for CPU hotplug case.
+ *
+ * Update the kdump image based on the type of hotplug event, represented by image->hp_action.
+ * CPU add: Update the FDT segment to include the newly added CPU.
+ * CPU remove: No action is needed, with the assumption that it's okay to have offline CPUs
+ * part of the FDT.
+ * Memory add/remove: No action is taken as this is not yet supported.
+ */
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
+{
+ struct memory_notify *mn;
+
+ switch (image->hp_action) {
+ case KEXEC_CRASH_HP_REMOVE_CPU:
+ return;
+
+ case KEXEC_CRASH_HP_ADD_CPU:
+ update_crash_fdt(image);
+ break;
+
+ case KEXEC_CRASH_HP_REMOVE_MEMORY:
+ case KEXEC_CRASH_HP_ADD_MEMORY:
+ mn = (struct memory_notify *)arg;
+ update_crash_elfcorehdr(image, mn);
+ return;
+ default:
+ pr_warn_once("Unknown hotplug action\n");
+ }
+}
+#endif /* CONFIG_CRASH_HOTPLUG */
diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index 6d8951e8e966..5d6d616404cf 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -23,6 +23,7 @@
#include <linux/of_fdt.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <asm/kexec_ranges.h>
static void *elf64_load(struct kimage *image, char *kernel_buf,
unsigned long kernel_len, char *initrd,
@@ -36,6 +37,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
const void *slave_code;
struct elfhdr ehdr;
char *modified_cmdline = NULL;
+ struct crash_mem *rmem = NULL;
struct kexec_elf_info elf_info;
struct kexec_buf kbuf = { .image = image, .buf_min = 0,
.buf_max = ppc64_rma_size };
@@ -102,21 +104,25 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
kexec_dprintk("Loaded initrd at 0x%lx\n", initrd_load_addr);
}
+ ret = get_reserved_memory_ranges(&rmem);
+ if (ret)
+ goto out;
+
fdt = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
initrd_len, cmdline,
- kexec_extra_fdt_size_ppc64(image));
+ kexec_extra_fdt_size_ppc64(image, rmem));
if (!fdt) {
pr_err("Error setting up the new device tree.\n");
ret = -EINVAL;
goto out;
}
- ret = setup_new_fdt_ppc64(image, fdt, initrd_load_addr,
- initrd_len, cmdline);
+ ret = setup_new_fdt_ppc64(image, fdt, rmem);
if (ret)
goto out_free_fdt;
- fdt_pack(fdt);
+ if (!IS_ENABLED(CONFIG_CRASH_HOTPLUG) || image->type != KEXEC_TYPE_CRASH)
+ fdt_pack(fdt);
kbuf.buffer = fdt;
kbuf.bufsz = kbuf.memsz = fdt_totalsize(fdt);
@@ -145,6 +151,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
out_free_fdt:
kvfree(fdt);
out:
+ kfree(rmem);
kfree(modified_cmdline);
kexec_free_elf_info(&elf_info);
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index 1bc65de6174f..9738adabeb1f 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -18,6 +18,7 @@
#include <linux/of_fdt.h>
#include <linux/libfdt.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -30,6 +31,7 @@
#include <asm/iommu.h>
#include <asm/prom.h>
#include <asm/plpks.h>
+#include <asm/cputhreads.h>
struct umem_info {
__be64 *buf; /* data buffer for usable-memory property */
@@ -48,83 +50,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
};
/**
- * get_exclude_memory_ranges - Get exclude memory ranges. This list includes
- * regions like opal/rtas, tce-table, initrd,
- * kernel, htab which should be avoided while
- * setting up kexec load segments.
- * @mem_ranges: Range list to add the memory ranges to.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int get_exclude_memory_ranges(struct crash_mem **mem_ranges)
-{
- int ret;
-
- ret = add_tce_mem_ranges(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_initrd_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_htab_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_kernel_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_rtas_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_opal_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_reserved_mem_ranges(mem_ranges);
- if (ret)
- goto out;
-
- /* exclude memory ranges should be sorted for easy lookup */
- sort_memory_ranges(*mem_ranges, true);
-out:
- if (ret)
- pr_err("Failed to setup exclude memory ranges\n");
- return ret;
-}
-
-/**
- * get_reserved_memory_ranges - Get reserve memory ranges. This list includes
- * memory regions that should be added to the
- * memory reserve map to ensure the region is
- * protected from any mischief.
- * @mem_ranges: Range list to add the memory ranges to.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int get_reserved_memory_ranges(struct crash_mem **mem_ranges)
-{
- int ret;
-
- ret = add_rtas_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_tce_mem_ranges(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_reserved_mem_ranges(mem_ranges);
-out:
- if (ret)
- pr_err("Failed to setup reserved memory ranges\n");
- return ret;
-}
-
-/**
* __locate_mem_hole_top_down - Looks top down for a large enough memory hole
* in the memory regions between buf_min & buf_max
* for the buffer. If found, sets kbuf->mem.
@@ -323,119 +248,6 @@ static int locate_mem_hole_bottom_up_ppc64(struct kexec_buf *kbuf,
#ifdef CONFIG_CRASH_DUMP
/**
- * get_usable_memory_ranges - Get usable memory ranges. This list includes
- * regions like crashkernel, opal/rtas & tce-table,
- * that kdump kernel could use.
- * @mem_ranges: Range list to add the memory ranges to.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int get_usable_memory_ranges(struct crash_mem **mem_ranges)
-{
- int ret;
-
- /*
- * Early boot failure observed on guests when low memory (first memory
- * block?) is not added to usable memory. So, add [0, crashk_res.end]
- * instead of [crashk_res.start, crashk_res.end] to workaround it.
- * Also, crashed kernel's memory must be added to reserve map to
- * avoid kdump kernel from using it.
- */
- ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
- if (ret)
- goto out;
-
- ret = add_rtas_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_opal_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_tce_mem_ranges(mem_ranges);
-out:
- if (ret)
- pr_err("Failed to setup usable memory ranges\n");
- return ret;
-}
-
-/**
- * get_crash_memory_ranges - Get crash memory ranges. This list includes
- * first/crashing kernel's memory regions that
- * would be exported via an elfcore.
- * @mem_ranges: Range list to add the memory ranges to.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int get_crash_memory_ranges(struct crash_mem **mem_ranges)
-{
- phys_addr_t base, end;
- struct crash_mem *tmem;
- u64 i;
- int ret;
-
- 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) {
- if (size > BACKUP_SRC_SIZE) {
- base = BACKUP_SRC_END + 1;
- size -= BACKUP_SRC_SIZE;
- } else
- continue;
- }
-
- ret = add_mem_range(mem_ranges, base, size);
- if (ret)
- goto out;
-
- /* Try merging adjacent ranges before reallocation attempt */
- if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges)
- sort_memory_ranges(*mem_ranges, true);
- }
-
- /* Reallocate memory ranges if there is no space to split ranges */
- tmem = *mem_ranges;
- if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
- tmem = realloc_mem_ranges(mem_ranges);
- if (!tmem)
- goto out;
- }
-
- /* Exclude crashkernel region */
- ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
- if (ret)
- goto out;
-
- /*
- * FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
- * regions are exported to save their context at the time of
- * crash, they should actually be backed up just like the
- * first 64K bytes of memory.
- */
- ret = add_rtas_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- ret = add_opal_mem_range(mem_ranges);
- if (ret)
- goto out;
-
- /* create a separate program header for the backup region */
- ret = add_mem_range(mem_ranges, BACKUP_SRC_START, BACKUP_SRC_SIZE);
- if (ret)
- goto out;
-
- sort_memory_ranges(*mem_ranges, false);
-out:
- if (ret)
- pr_err("Failed to setup crash memory ranges\n");
- return ret;
-}
-
-/**
* check_realloc_usable_mem - Reallocate buffer if it can't accommodate entries
* @um_info: Usable memory buffer and ranges info.
* @cnt: No. of entries to accommodate.
@@ -565,11 +377,10 @@ static int kdump_setup_usable_lmb(struct drmem_lmb *lmb, const __be32 **usm,
static int add_usable_mem_property(void *fdt, struct device_node *dn,
struct umem_info *um_info)
{
- int n_mem_addr_cells, n_mem_size_cells, node;
+ int node;
char path[NODE_PATH_LEN];
- int i, len, ranges, ret;
- const __be32 *prop;
- u64 base, end;
+ int i, ret;
+ u64 base, size;
of_node_get(dn);
@@ -588,41 +399,30 @@ static int add_usable_mem_property(void *fdt, struct device_node *dn,
goto out;
}
- /* Get the address & size cells */
- n_mem_addr_cells = of_n_addr_cells(dn);
- n_mem_size_cells = of_n_size_cells(dn);
- kexec_dprintk("address cells: %d, size cells: %d\n", n_mem_addr_cells,
- n_mem_size_cells);
-
um_info->idx = 0;
if (!check_realloc_usable_mem(um_info, 2)) {
ret = -ENOMEM;
goto out;
}
- prop = of_get_property(dn, "reg", &len);
- if (!prop || len <= 0) {
- ret = 0;
- goto out;
- }
-
/*
* "reg" property represents sequence of (addr,size) tuples
* each representing a memory range.
*/
- ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
-
- for (i = 0; i < ranges; i++) {
- base = of_read_number(prop, n_mem_addr_cells);
- prop += n_mem_addr_cells;
- end = base + of_read_number(prop, n_mem_size_cells) - 1;
- prop += n_mem_size_cells;
+ for (i = 0; ; i++) {
+ ret = of_property_read_reg(dn, i, &base, &size);
+ if (ret)
+ break;
- ret = add_usable_mem(um_info, base, end);
+ ret = add_usable_mem(um_info, base, base + size - 1);
if (ret)
goto out;
}
+ // No reg or empty reg? Skip this node.
+ if (i == 0)
+ goto out;
+
/*
* No kdump kernel usable memory found in this memory node.
* Write (0,0) tuple in linux,usable-memory property for
@@ -784,6 +584,23 @@ static void update_backup_region_phdr(struct kimage *image, Elf64_Ehdr *ehdr)
}
}
+static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem)
+{
+#if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG)
+ unsigned int extra_sz = 0;
+
+ if (CONFIG_CRASH_MAX_MEMORY_RANGES > (unsigned int)PN_XNUM)
+ pr_warn("Number of Phdrs %u exceeds max\n", CONFIG_CRASH_MAX_MEMORY_RANGES);
+ else if (cmem->nr_ranges >= CONFIG_CRASH_MAX_MEMORY_RANGES)
+ pr_warn("Configured crash mem ranges may not be enough\n");
+ else
+ extra_sz = (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr);
+
+ return extra_sz;
+#endif
+ return 0;
+}
+
/**
* load_elfcorehdr_segment - Setup crash memory ranges and initialize elfcorehdr
* segment needed to load kdump kernel.
@@ -815,7 +632,8 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
kbuf->buffer = headers;
kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf->bufsz = kbuf->memsz = headers_sz;
+ kbuf->bufsz = headers_sz;
+ kbuf->memsz = headers_sz + kdump_extra_elfcorehdr_size(cmem);
kbuf->top_down = false;
ret = kexec_add_buffer(kbuf);
@@ -974,11 +792,13 @@ static unsigned int cpu_node_size(void)
return size;
}
-static unsigned int kdump_extra_fdt_size_ppc64(struct kimage *image)
+static unsigned int kdump_extra_fdt_size_ppc64(struct kimage *image, unsigned int cpu_nodes)
{
- unsigned int cpu_nodes, extra_size = 0;
- struct device_node *dn;
+ unsigned int extra_size = 0;
u64 usm_entries;
+#ifdef CONFIG_CRASH_HOTPLUG
+ unsigned int possible_cpu_nodes;
+#endif
if (!IS_ENABLED(CONFIG_CRASH_DUMP) || image->type != KEXEC_TYPE_CRASH)
return 0;
@@ -994,17 +814,18 @@ static unsigned int kdump_extra_fdt_size_ppc64(struct kimage *image)
extra_size += (unsigned int)(usm_entries * sizeof(u64));
}
+#ifdef CONFIG_CRASH_HOTPLUG
/*
- * Get the number of CPU nodes in the current DT. This allows to
- * reserve places for CPU nodes added since the boot time.
+ * Make sure enough space is reserved to accommodate possible CPU nodes
+ * in the crash FDT. This allows packing possible CPU nodes which are
+ * not yet present in the system without regenerating the entire FDT.
*/
- cpu_nodes = 0;
- for_each_node_by_type(dn, "cpu") {
- cpu_nodes++;
+ if (image->type == KEXEC_TYPE_CRASH) {
+ possible_cpu_nodes = num_possible_cpus() / threads_per_core;
+ if (possible_cpu_nodes > cpu_nodes)
+ extra_size += (possible_cpu_nodes - cpu_nodes) * cpu_node_size();
}
-
- if (cpu_nodes > boot_cpu_node_count)
- extra_size += (cpu_nodes - boot_cpu_node_count) * cpu_node_size();
+#endif
return extra_size;
}
@@ -1016,103 +837,30 @@ static unsigned int kdump_extra_fdt_size_ppc64(struct kimage *image)
*
* Returns the estimated extra size needed for kexec/kdump kernel FDT.
*/
-unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
+unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image, struct crash_mem *rmem)
{
- unsigned int extra_size = 0;
+ struct device_node *dn;
+ unsigned int cpu_nodes = 0, extra_size = 0;
// Budget some space for the password blob. There's already extra space
// for the key name
if (plpks_is_available())
extra_size += (unsigned int)plpks_get_passwordlen();
- return extra_size + kdump_extra_fdt_size_ppc64(image);
-}
-
-/**
- * add_node_props - Reads node properties from device node structure and add
- * them to fdt.
- * @fdt: Flattened device tree of the kernel
- * @node_offset: offset of the node to add a property at
- * @dn: device node pointer
- *
- * Returns 0 on success, negative errno on error.
- */
-static int add_node_props(void *fdt, int node_offset, const struct device_node *dn)
-{
- int ret = 0;
- struct property *pp;
-
- if (!dn)
- return -EINVAL;
-
- for_each_property_of_node(dn, pp) {
- ret = fdt_setprop(fdt, node_offset, pp->name, pp->value, pp->length);
- if (ret < 0) {
- pr_err("Unable to add %s property: %s\n", pp->name, fdt_strerror(ret));
- return ret;
- }
- }
- return ret;
-}
-
-/**
- * update_cpus_node - Update cpus node of flattened device tree using of_root
- * device node.
- * @fdt: Flattened device tree of the kernel.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int update_cpus_node(void *fdt)
-{
- struct device_node *cpus_node, *dn;
- int cpus_offset, cpus_subnode_offset, ret = 0;
-
- cpus_offset = fdt_path_offset(fdt, "/cpus");
- if (cpus_offset < 0 && cpus_offset != -FDT_ERR_NOTFOUND) {
- pr_err("Malformed device tree: error reading /cpus node: %s\n",
- fdt_strerror(cpus_offset));
- return cpus_offset;
- }
-
- if (cpus_offset > 0) {
- ret = fdt_del_node(fdt, cpus_offset);
- if (ret < 0) {
- pr_err("Error deleting /cpus node: %s\n", fdt_strerror(ret));
- return -EINVAL;
- }
+ /* Get the number of CPU nodes in the current device tree */
+ for_each_node_by_type(dn, "cpu") {
+ cpu_nodes++;
}
- /* Add cpus node to fdt */
- cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "cpus");
- if (cpus_offset < 0) {
- pr_err("Error creating /cpus node: %s\n", fdt_strerror(cpus_offset));
- return -EINVAL;
- }
+ /* Consider extra space for CPU nodes added since the boot time */
+ if (cpu_nodes > boot_cpu_node_count)
+ extra_size += (cpu_nodes - boot_cpu_node_count) * cpu_node_size();
- /* Add cpus node properties */
- cpus_node = of_find_node_by_path("/cpus");
- ret = add_node_props(fdt, cpus_offset, cpus_node);
- of_node_put(cpus_node);
- if (ret < 0)
- return ret;
+ /* Consider extra space for reserved memory ranges if any */
+ if (rmem->nr_ranges > 0)
+ extra_size += sizeof(struct fdt_reserve_entry) * rmem->nr_ranges;
- /* Loop through all subnodes of cpus and add them to fdt */
- for_each_node_by_type(dn, "cpu") {
- cpus_subnode_offset = fdt_add_subnode(fdt, cpus_offset, dn->full_name);
- if (cpus_subnode_offset < 0) {
- pr_err("Unable to add %s subnode: %s\n", dn->full_name,
- fdt_strerror(cpus_subnode_offset));
- ret = cpus_subnode_offset;
- goto out;
- }
-
- ret = add_node_props(fdt, cpus_subnode_offset, dn);
- if (ret < 0)
- goto out;
- }
-out:
- of_node_put(dn);
- return ret;
+ return extra_size + kdump_extra_fdt_size_ppc64(image, cpu_nodes);
}
static int copy_property(void *fdt, int node_offset, const struct device_node *dn,
@@ -1166,18 +914,13 @@ static int update_pci_dma_nodes(void *fdt, const char *dmapropname)
* being loaded.
* @image: kexec image being loaded.
* @fdt: Flattened device tree for the next kernel.
- * @initrd_load_addr: Address where the next initrd will be loaded.
- * @initrd_len: Size of the next initrd, or 0 if there will be none.
- * @cmdline: Command line for the next kernel, or NULL if there will
- * be none.
+ * @rmem: Reserved memory ranges.
*
* Returns 0 on success, negative errno on error.
*/
-int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
- unsigned long initrd_load_addr,
- unsigned long initrd_len, const char *cmdline)
+int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, struct crash_mem *rmem)
{
- struct crash_mem *umem = NULL, *rmem = NULL;
+ struct crash_mem *umem = NULL;
int i, nr_ranges, ret;
#ifdef CONFIG_CRASH_DUMP
@@ -1233,10 +976,6 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
goto out;
/* Update memory reserve map */
- ret = get_reserved_memory_ranges(&rmem);
- if (ret)
- goto out;
-
nr_ranges = rmem ? rmem->nr_ranges : 0;
for (i = 0; i < nr_ranges; i++) {
u64 base, size;
@@ -1256,7 +995,6 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
ret = plpks_populate_fdt(fdt);
out:
- kfree(rmem);
kfree(umem);
return ret;
}
diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c
index 33b780049aaf..3702b0bdab14 100644
--- a/arch/powerpc/kexec/ranges.c
+++ b/arch/powerpc/kexec/ranges.c
@@ -20,9 +20,13 @@
#include <linux/kexec.h>
#include <linux/of.h>
#include <linux/slab.h>
+#include <linux/memblock.h>
+#include <linux/crash_core.h>
#include <asm/sections.h>
#include <asm/kexec_ranges.h>
+#include <asm/crashdump-ppc64.h>
+#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
/**
* get_max_nr_ranges - Get the max no. of ranges crash_mem structure
* could hold, given the size allocated for it.
@@ -234,13 +238,16 @@ int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size)
return __add_mem_range(mem_ranges, base, size);
}
+#endif /* CONFIG_KEXEC_FILE || CONFIG_CRASH_DUMP */
+
+#ifdef CONFIG_KEXEC_FILE
/**
* add_tce_mem_ranges - Adds tce-table range to the given memory ranges list.
* @mem_ranges: Range list to add the memory range(s) to.
*
* Returns 0 on success, negative errno on error.
*/
-int add_tce_mem_ranges(struct crash_mem **mem_ranges)
+static int add_tce_mem_ranges(struct crash_mem **mem_ranges)
{
struct device_node *dn = NULL;
int ret = 0;
@@ -279,7 +286,7 @@ int add_tce_mem_ranges(struct crash_mem **mem_ranges)
*
* Returns 0 on success, negative errno on error.
*/
-int add_initrd_mem_range(struct crash_mem **mem_ranges)
+static int add_initrd_mem_range(struct crash_mem **mem_ranges)
{
u64 base, end;
int ret;
@@ -296,7 +303,6 @@ int add_initrd_mem_range(struct crash_mem **mem_ranges)
return ret;
}
-#ifdef CONFIG_PPC_64S_HASH_MMU
/**
* add_htab_mem_range - Adds htab range to the given memory ranges list,
* if it exists
@@ -304,14 +310,18 @@ int add_initrd_mem_range(struct crash_mem **mem_ranges)
*
* Returns 0 on success, negative errno on error.
*/
-int add_htab_mem_range(struct crash_mem **mem_ranges)
+static int add_htab_mem_range(struct crash_mem **mem_ranges)
{
+
+#ifdef CONFIG_PPC_64S_HASH_MMU
if (!htab_address)
return 0;
return add_mem_range(mem_ranges, __pa(htab_address), htab_size_bytes);
-}
+#else
+ return 0;
#endif
+}
/**
* add_kernel_mem_range - Adds kernel text region to the given
@@ -320,18 +330,20 @@ int add_htab_mem_range(struct crash_mem **mem_ranges)
*
* Returns 0 on success, negative errno on error.
*/
-int add_kernel_mem_range(struct crash_mem **mem_ranges)
+static int add_kernel_mem_range(struct crash_mem **mem_ranges)
{
return add_mem_range(mem_ranges, 0, __pa(_end));
}
+#endif /* CONFIG_KEXEC_FILE */
+#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
/**
* add_rtas_mem_range - Adds RTAS region to the given memory ranges list.
* @mem_ranges: Range list to add the memory range to.
*
* Returns 0 on success, negative errno on error.
*/
-int add_rtas_mem_range(struct crash_mem **mem_ranges)
+static int add_rtas_mem_range(struct crash_mem **mem_ranges)
{
struct device_node *dn;
u32 base, size;
@@ -356,7 +368,7 @@ int add_rtas_mem_range(struct crash_mem **mem_ranges)
*
* Returns 0 on success, negative errno on error.
*/
-int add_opal_mem_range(struct crash_mem **mem_ranges)
+static int add_opal_mem_range(struct crash_mem **mem_ranges)
{
struct device_node *dn;
u64 base, size;
@@ -374,7 +386,9 @@ int add_opal_mem_range(struct crash_mem **mem_ranges)
of_node_put(dn);
return ret;
}
+#endif /* CONFIG_KEXEC_FILE || CONFIG_CRASH_DUMP */
+#ifdef CONFIG_KEXEC_FILE
/**
* add_reserved_mem_ranges - Adds "/reserved-ranges" regions exported by f/w
* to the given memory ranges list.
@@ -382,7 +396,7 @@ int add_opal_mem_range(struct crash_mem **mem_ranges)
*
* Returns 0 on success, negative errno on error.
*/
-int add_reserved_mem_ranges(struct crash_mem **mem_ranges)
+static int add_reserved_mem_ranges(struct crash_mem **mem_ranges)
{
int n_mem_addr_cells, n_mem_size_cells, i, len, cells, ret = 0;
struct device_node *root = of_find_node_by_path("/");
@@ -412,3 +426,283 @@ int add_reserved_mem_ranges(struct crash_mem **mem_ranges)
return ret;
}
+
+/**
+ * get_reserved_memory_ranges - Get reserve memory ranges. This list includes
+ * memory regions that should be added to the
+ * memory reserve map to ensure the region is
+ * protected from any mischief.
+ * @mem_ranges: Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int get_reserved_memory_ranges(struct crash_mem **mem_ranges)
+{
+ int ret;
+
+ ret = add_rtas_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_tce_mem_ranges(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_reserved_mem_ranges(mem_ranges);
+out:
+ if (ret)
+ pr_err("Failed to setup reserved memory ranges\n");
+ return ret;
+}
+
+/**
+ * get_exclude_memory_ranges - Get exclude memory ranges. This list includes
+ * regions like opal/rtas, tce-table, initrd,
+ * kernel, htab which should be avoided while
+ * setting up kexec load segments.
+ * @mem_ranges: Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int get_exclude_memory_ranges(struct crash_mem **mem_ranges)
+{
+ int ret;
+
+ ret = add_tce_mem_ranges(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_initrd_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_htab_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_kernel_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_rtas_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_opal_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_reserved_mem_ranges(mem_ranges);
+ if (ret)
+ goto out;
+
+ /* exclude memory ranges should be sorted for easy lookup */
+ sort_memory_ranges(*mem_ranges, true);
+out:
+ if (ret)
+ pr_err("Failed to setup exclude memory ranges\n");
+ return ret;
+}
+
+#ifdef CONFIG_CRASH_DUMP
+/**
+ * get_usable_memory_ranges - Get usable memory ranges. This list includes
+ * regions like crashkernel, opal/rtas & tce-table,
+ * that kdump kernel could use.
+ * @mem_ranges: Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int get_usable_memory_ranges(struct crash_mem **mem_ranges)
+{
+ int ret;
+
+ /*
+ * Early boot failure observed on guests when low memory (first memory
+ * block?) is not added to usable memory. So, add [0, crashk_res.end]
+ * instead of [crashk_res.start, crashk_res.end] to workaround it.
+ * Also, crashed kernel's memory must be added to reserve map to
+ * avoid kdump kernel from using it.
+ */
+ ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
+ if (ret)
+ goto out;
+
+ ret = add_rtas_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_opal_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_tce_mem_ranges(mem_ranges);
+out:
+ if (ret)
+ pr_err("Failed to setup usable memory ranges\n");
+ return ret;
+}
+#endif /* CONFIG_CRASH_DUMP */
+#endif /* CONFIG_KEXEC_FILE */
+
+#ifdef CONFIG_CRASH_DUMP
+/**
+ * get_crash_memory_ranges - Get crash memory ranges. This list includes
+ * first/crashing kernel's memory regions that
+ * would be exported via an elfcore.
+ * @mem_ranges: Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int get_crash_memory_ranges(struct crash_mem **mem_ranges)
+{
+ phys_addr_t base, end;
+ struct crash_mem *tmem;
+ u64 i;
+ int ret;
+
+ 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) {
+ if (size > BACKUP_SRC_SIZE) {
+ base = BACKUP_SRC_END + 1;
+ size -= BACKUP_SRC_SIZE;
+ } else
+ continue;
+ }
+
+ ret = add_mem_range(mem_ranges, base, size);
+ if (ret)
+ goto out;
+
+ /* Try merging adjacent ranges before reallocation attempt */
+ if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges)
+ sort_memory_ranges(*mem_ranges, true);
+ }
+
+ /* Reallocate memory ranges if there is no space to split ranges */
+ tmem = *mem_ranges;
+ if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
+ tmem = realloc_mem_ranges(mem_ranges);
+ if (!tmem)
+ goto out;
+ }
+
+ /* Exclude crashkernel region */
+ ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
+ if (ret)
+ goto out;
+
+ /*
+ * FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
+ * regions are exported to save their context at the time of
+ * crash, they should actually be backed up just like the
+ * first 64K bytes of memory.
+ */
+ ret = add_rtas_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_opal_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ /* create a separate program header for the backup region */
+ ret = add_mem_range(mem_ranges, BACKUP_SRC_START, BACKUP_SRC_SIZE);
+ if (ret)
+ goto out;
+
+ sort_memory_ranges(*mem_ranges, false);
+out:
+ if (ret)
+ pr_err("Failed to setup crash memory ranges\n");
+ return ret;
+}
+
+/**
+ * remove_mem_range - Removes the given memory range from the range list.
+ * @mem_ranges: Range list to remove the memory range to.
+ * @base: Base address of the range to remove.
+ * @size: Size of the memory range to remove.
+ *
+ * (Re)allocates memory, if needed.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size)
+{
+ u64 end;
+ int ret = 0;
+ unsigned int i;
+ u64 mstart, mend;
+ struct crash_mem *mem_rngs = *mem_ranges;
+
+ if (!size)
+ return 0;
+
+ /*
+ * Memory range are stored as start and end address, use
+ * the same format to do remove operation.
+ */
+ end = base + size - 1;
+
+ for (i = 0; i < mem_rngs->nr_ranges; i++) {
+ mstart = mem_rngs->ranges[i].start;
+ mend = mem_rngs->ranges[i].end;
+
+ /*
+ * Memory range to remove is not part of this range entry
+ * in the memory range list
+ */
+ if (!(base >= mstart && end <= mend))
+ continue;
+
+ /*
+ * Memory range to remove is equivalent to this entry in the
+ * memory range list. Remove the range entry from the list.
+ */
+ if (base == mstart && end == mend) {
+ for (; i < mem_rngs->nr_ranges - 1; i++) {
+ mem_rngs->ranges[i].start = mem_rngs->ranges[i+1].start;
+ mem_rngs->ranges[i].end = mem_rngs->ranges[i+1].end;
+ }
+ mem_rngs->nr_ranges--;
+ goto out;
+ }
+ /*
+ * Start address of the memory range to remove and the
+ * current memory range entry in the list is same. Just
+ * move the start address of the current memory range
+ * entry in the list to end + 1.
+ */
+ else if (base == mstart) {
+ mem_rngs->ranges[i].start = end + 1;
+ goto out;
+ }
+ /*
+ * End address of the memory range to remove and the
+ * current memory range entry in the list is same.
+ * Just move the end address of the current memory
+ * range entry in the list to base - 1.
+ */
+ else if (end == mend) {
+ mem_rngs->ranges[i].end = base - 1;
+ goto out;
+ }
+ /*
+ * Memory range to remove is not at the edge of current
+ * memory range entry. Split the current memory entry into
+ * two half.
+ */
+ else {
+ mem_rngs->ranges[i].end = base - 1;
+ size = mem_rngs->ranges[i].end - end;
+ ret = add_mem_range(mem_ranges, end + 1, size);
+ }
+ }
+out:
+ return ret;
+}
+#endif /* CONFIG_CRASH_DUMP */
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 8acec144120e..ff6c38373957 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -360,10 +360,6 @@ static int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu,
break;
}
-#if 0
- printk(KERN_INFO "Deliver interrupt 0x%x? %x\n", vec, deliver);
-#endif
-
if (deliver)
kvmppc_inject_interrupt(vcpu, vec, 0);
@@ -899,11 +895,6 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
return kvm->arch.kvm_ops->test_age_gfn(kvm, range);
}
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- return kvm->arch.kvm_ops->set_spte_gfn(kvm, range);
-}
-
int kvmppc_core_init_vm(struct kvm *kvm)
{
diff --git a/arch/powerpc/kvm/book3s.h b/arch/powerpc/kvm/book3s.h
index 58391b4b32ed..4aa2ab89afbc 100644
--- a/arch/powerpc/kvm/book3s.h
+++ b/arch/powerpc/kvm/book3s.h
@@ -12,7 +12,6 @@ extern void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
extern bool kvm_unmap_gfn_range_hv(struct kvm *kvm, struct kvm_gfn_range *range);
extern bool kvm_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
extern bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
-extern bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
extern int kvmppc_mmu_init_pr(struct kvm_vcpu *vcpu);
extern void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 2b1f0cdd8c18..1b51b1c4713b 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -1010,18 +1010,6 @@ bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
return kvm_test_age_rmapp(kvm, range->slot, range->start);
}
-bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- WARN_ON(range->start + 1 != range->end);
-
- if (kvm_is_radix(kvm))
- kvm_unmap_radix(kvm, range->slot, range->start);
- else
- kvm_unmap_rmapp(kvm, range->slot, range->start);
-
- return false;
-}
-
static int vcpus_running(struct kvm *kvm)
{
return atomic_read(&kvm->arch.vcpus_running) != 0;
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index b569ebaa590e..3ff3de9a52ac 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -130,14 +130,16 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
}
rcu_read_unlock();
- fdput(f);
-
- if (!found)
+ if (!found) {
+ fdput(f);
return -EINVAL;
+ }
table_group = iommu_group_get_iommudata(grp);
- if (WARN_ON(!table_group))
+ if (WARN_ON(!table_group)) {
+ fdput(f);
return -EFAULT;
+ }
for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
struct iommu_table *tbltmp = table_group->tables[i];
@@ -158,8 +160,10 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
break;
}
}
- if (!tbl)
+ if (!tbl) {
+ fdput(f);
return -EINVAL;
+ }
rcu_read_lock();
list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
@@ -170,6 +174,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
/* stit is being destroyed */
iommu_tce_table_put(tbl);
rcu_read_unlock();
+ fdput(f);
return -ENOTTY;
}
/*
@@ -177,6 +182,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
* its KVM reference counter and can return.
*/
rcu_read_unlock();
+ fdput(f);
return 0;
}
rcu_read_unlock();
@@ -184,6 +190,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
stit = kzalloc(sizeof(*stit), GFP_KERNEL);
if (!stit) {
iommu_tce_table_put(tbl);
+ fdput(f);
return -ENOMEM;
}
@@ -192,6 +199,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
list_add_rcu(&stit->next, &stt->iommu_tables);
+ fdput(f);
return 0;
}
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 5bbfb2eed127..de126d153328 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -714,7 +714,7 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
case SPRN_HID1:
to_book3s(vcpu)->hid[1] = spr_val;
break;
- case SPRN_HID2:
+ case SPRN_HID2_750FX:
to_book3s(vcpu)->hid[2] = spr_val;
break;
case SPRN_HID2_GEKKO:
@@ -900,7 +900,7 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
case SPRN_HID1:
*spr_val = to_book3s(vcpu)->hid[1];
break;
- case SPRN_HID2:
+ case SPRN_HID2_750FX:
case SPRN_HID2_GEKKO:
*spr_val = to_book3s(vcpu)->hid[2];
break;
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 8e86eb577eb8..8f7d7e37bc8c 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2305,7 +2305,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
*val = get_reg_val(id, kvmppc_get_siar_hv(vcpu));
break;
case KVM_REG_PPC_SDAR:
- *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu));
+ *val = get_reg_val(id, kvmppc_get_sdar_hv(vcpu));
break;
case KVM_REG_PPC_SIER:
*val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 0));
@@ -2349,6 +2349,15 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_DAWRX1:
*val = get_reg_val(id, kvmppc_get_dawrx1_hv(vcpu));
break;
+ case KVM_REG_PPC_DEXCR:
+ *val = get_reg_val(id, kvmppc_get_dexcr_hv(vcpu));
+ break;
+ case KVM_REG_PPC_HASHKEYR:
+ *val = get_reg_val(id, kvmppc_get_hashkeyr_hv(vcpu));
+ break;
+ case KVM_REG_PPC_HASHPKEYR:
+ *val = get_reg_val(id, kvmppc_get_hashpkeyr_hv(vcpu));
+ break;
case KVM_REG_PPC_CIABR:
*val = get_reg_val(id, kvmppc_get_ciabr_hv(vcpu));
break;
@@ -2540,7 +2549,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
vcpu->arch.mmcrs = set_reg_val(id, *val);
break;
case KVM_REG_PPC_MMCR3:
- *val = get_reg_val(id, vcpu->arch.mmcr[3]);
+ kvmppc_set_mmcr_hv(vcpu, 3, set_reg_val(id, *val));
break;
case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8:
i = id - KVM_REG_PPC_PMC1;
@@ -2592,6 +2601,15 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_DAWRX1:
kvmppc_set_dawrx1_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP);
break;
+ case KVM_REG_PPC_DEXCR:
+ kvmppc_set_dexcr_hv(vcpu, set_reg_val(id, *val));
+ break;
+ case KVM_REG_PPC_HASHKEYR:
+ kvmppc_set_hashkeyr_hv(vcpu, set_reg_val(id, *val));
+ break;
+ case KVM_REG_PPC_HASHPKEYR:
+ kvmppc_set_hashpkeyr_hv(vcpu, set_reg_val(id, *val));
+ break;
case KVM_REG_PPC_CIABR:
kvmppc_set_ciabr_hv(vcpu, set_reg_val(id, *val));
/* Don't allow setting breakpoints in hypervisor code */
@@ -4108,6 +4126,77 @@ static void vcpu_vpa_increment_dispatch(struct kvm_vcpu *vcpu)
}
}
+/* Helper functions for reading L2's stats from L1's VPA */
+#ifdef CONFIG_PPC_PSERIES
+static DEFINE_PER_CPU(u64, l1_to_l2_cs);
+static DEFINE_PER_CPU(u64, l2_to_l1_cs);
+static DEFINE_PER_CPU(u64, l2_runtime_agg);
+
+int kvmhv_get_l2_counters_status(void)
+{
+ return firmware_has_feature(FW_FEATURE_LPAR) &&
+ get_lppaca()->l2_counters_enable;
+}
+
+void kvmhv_set_l2_counters_status(int cpu, bool status)
+{
+ if (!firmware_has_feature(FW_FEATURE_LPAR))
+ return;
+ if (status)
+ lppaca_of(cpu).l2_counters_enable = 1;
+ else
+ lppaca_of(cpu).l2_counters_enable = 0;
+}
+
+int kmvhv_counters_tracepoint_regfunc(void)
+{
+ int cpu;
+
+ for_each_present_cpu(cpu) {
+ kvmhv_set_l2_counters_status(cpu, true);
+ }
+ return 0;
+}
+
+void kmvhv_counters_tracepoint_unregfunc(void)
+{
+ int cpu;
+
+ for_each_present_cpu(cpu) {
+ kvmhv_set_l2_counters_status(cpu, false);
+ }
+}
+
+static void do_trace_nested_cs_time(struct kvm_vcpu *vcpu)
+{
+ struct lppaca *lp = get_lppaca();
+ u64 l1_to_l2_ns, l2_to_l1_ns, l2_runtime_ns;
+ u64 *l1_to_l2_cs_ptr = this_cpu_ptr(&l1_to_l2_cs);
+ u64 *l2_to_l1_cs_ptr = this_cpu_ptr(&l2_to_l1_cs);
+ u64 *l2_runtime_agg_ptr = this_cpu_ptr(&l2_runtime_agg);
+
+ l1_to_l2_ns = tb_to_ns(be64_to_cpu(lp->l1_to_l2_cs_tb));
+ l2_to_l1_ns = tb_to_ns(be64_to_cpu(lp->l2_to_l1_cs_tb));
+ l2_runtime_ns = tb_to_ns(be64_to_cpu(lp->l2_runtime_tb));
+ trace_kvmppc_vcpu_stats(vcpu, l1_to_l2_ns - *l1_to_l2_cs_ptr,
+ l2_to_l1_ns - *l2_to_l1_cs_ptr,
+ l2_runtime_ns - *l2_runtime_agg_ptr);
+ *l1_to_l2_cs_ptr = l1_to_l2_ns;
+ *l2_to_l1_cs_ptr = l2_to_l1_ns;
+ *l2_runtime_agg_ptr = l2_runtime_ns;
+}
+
+#else
+int kvmhv_get_l2_counters_status(void)
+{
+ return 0;
+}
+
+static void do_trace_nested_cs_time(struct kvm_vcpu *vcpu)
+{
+}
+#endif
+
static int kvmhv_vcpu_entry_nestedv2(struct kvm_vcpu *vcpu, u64 time_limit,
unsigned long lpcr, u64 *tb)
{
@@ -4116,6 +4205,11 @@ static int kvmhv_vcpu_entry_nestedv2(struct kvm_vcpu *vcpu, u64 time_limit,
int trap;
long rc;
+ if (vcpu->arch.doorbell_request) {
+ vcpu->arch.doorbell_request = 0;
+ kvmppc_set_dpdes(vcpu, 1);
+ }
+
io = &vcpu->arch.nestedv2_io;
msr = mfmsr();
@@ -4156,6 +4250,10 @@ static int kvmhv_vcpu_entry_nestedv2(struct kvm_vcpu *vcpu, u64 time_limit,
timer_rearm_host_dec(*tb);
+ /* Record context switch and guest_run_time data */
+ if (kvmhv_get_l2_counters_status())
+ do_trace_nested_cs_time(vcpu);
+
return trap;
}
@@ -4857,7 +4955,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
* entering a nested guest in which case the decrementer is now owned
* by L2 and the L1 decrementer is provided in hdec_expires
*/
- if (!kvmhv_is_nestedv2() && kvmppc_core_pending_dec(vcpu) &&
+ if (kvmppc_core_pending_dec(vcpu) &&
((tb < kvmppc_dec_expires_host_tb(vcpu)) ||
(trap == BOOK3S_INTERRUPT_SYSCALL &&
kvmppc_get_gpr(vcpu, 3) == H_ENTER_NESTED)))
@@ -6364,7 +6462,6 @@ static struct kvmppc_ops kvm_ops_hv = {
.unmap_gfn_range = kvm_unmap_gfn_range_hv,
.age_gfn = kvm_age_gfn_hv,
.test_age_gfn = kvm_test_age_gfn_hv,
- .set_spte_gfn = kvm_set_spte_gfn_hv,
.free_memslot = kvmppc_core_free_memslot_hv,
.init_vm = kvmppc_core_init_vm_hv,
.destroy_vm = kvmppc_core_destroy_vm_hv,
@@ -6520,6 +6617,7 @@ static void kvmppc_book3s_exit_hv(void)
module_init(kvmppc_book3s_init_hv);
module_exit(kvmppc_book3s_exit_hv);
+MODULE_DESCRIPTION("KVM on Book3S (POWER8 and later) in hypervisor mode");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(KVM_MINOR);
MODULE_ALIAS("devname:kvm");
diff --git a/arch/powerpc/kvm/book3s_hv.h b/arch/powerpc/kvm/book3s_hv.h
index 47b2c815641e..a404c9b221c1 100644
--- a/arch/powerpc/kvm/book3s_hv.h
+++ b/arch/powerpc/kvm/book3s_hv.h
@@ -116,6 +116,9 @@ KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr0, 64, KVMPPC_GSID_DAWR0)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr1, 64, KVMPPC_GSID_DAWR1)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx0, 64, KVMPPC_GSID_DAWRX0)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx1, 64, KVMPPC_GSID_DAWRX1)
+KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dexcr, 64, KVMPPC_GSID_DEXCR)
+KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hashkeyr, 64, KVMPPC_GSID_HASHKEYR)
+KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hashpkeyr, 64, KVMPPC_GSID_HASHPKEYR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ciabr, 64, KVMPPC_GSID_CIABR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(wort, 64, KVMPPC_GSID_WORT)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ppr, 64, KVMPPC_GSID_PPR)
diff --git a/arch/powerpc/kvm/book3s_hv_nestedv2.c b/arch/powerpc/kvm/book3s_hv_nestedv2.c
index 8e6f5355f08b..eeecea8f202b 100644
--- a/arch/powerpc/kvm/book3s_hv_nestedv2.c
+++ b/arch/powerpc/kvm/book3s_hv_nestedv2.c
@@ -71,8 +71,8 @@ gs_msg_ops_kvmhv_nestedv2_config_fill_info(struct kvmppc_gs_buff *gsb,
}
if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_RUN_OUTPUT)) {
- kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_OUTPUT,
- cfg->vcpu_run_output_cfg);
+ rc = kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_OUTPUT,
+ cfg->vcpu_run_output_cfg);
if (rc < 0)
return rc;
}
@@ -193,6 +193,15 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
case KVMPPC_GSID_DAWRX1:
rc = kvmppc_gse_put_u32(gsb, iden, vcpu->arch.dawrx1);
break;
+ case KVMPPC_GSID_DEXCR:
+ rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.dexcr);
+ break;
+ case KVMPPC_GSID_HASHKEYR:
+ rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.hashkeyr);
+ break;
+ case KVMPPC_GSID_HASHPKEYR:
+ rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.hashpkeyr);
+ break;
case KVMPPC_GSID_CIABR:
rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.ciabr);
break;
@@ -311,6 +320,10 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
rc = kvmppc_gse_put_u64(gsb, iden,
vcpu->arch.vcore->vtb);
break;
+ case KVMPPC_GSID_DPDES:
+ rc = kvmppc_gse_put_u64(gsb, iden,
+ vcpu->arch.vcore->dpdes);
+ break;
case KVMPPC_GSID_LPCR:
rc = kvmppc_gse_put_u64(gsb, iden,
vcpu->arch.vcore->lpcr);
@@ -441,6 +454,15 @@ static int gs_msg_ops_vcpu_refresh_info(struct kvmppc_gs_msg *gsm,
case KVMPPC_GSID_DAWRX1:
vcpu->arch.dawrx1 = kvmppc_gse_get_u32(gse);
break;
+ case KVMPPC_GSID_DEXCR:
+ vcpu->arch.dexcr = kvmppc_gse_get_u64(gse);
+ break;
+ case KVMPPC_GSID_HASHKEYR:
+ vcpu->arch.hashkeyr = kvmppc_gse_get_u64(gse);
+ break;
+ case KVMPPC_GSID_HASHPKEYR:
+ vcpu->arch.hashpkeyr = kvmppc_gse_get_u64(gse);
+ break;
case KVMPPC_GSID_CIABR:
vcpu->arch.ciabr = kvmppc_gse_get_u64(gse);
break;
@@ -543,6 +565,9 @@ static int gs_msg_ops_vcpu_refresh_info(struct kvmppc_gs_msg *gsm,
case KVMPPC_GSID_VTB:
vcpu->arch.vcore->vtb = kvmppc_gse_get_u64(gse);
break;
+ case KVMPPC_GSID_DPDES:
+ vcpu->arch.vcore->dpdes = kvmppc_gse_get_u64(gse);
+ break;
case KVMPPC_GSID_LPCR:
vcpu->arch.vcore->lpcr = kvmppc_gse_get_u64(gse);
break;
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c
index e42984878503..f2636414d82a 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -837,7 +837,7 @@ static inline void this_cpu_inc_rm(unsigned int __percpu *addr)
*/
static void kvmppc_rm_handle_irq_desc(struct irq_desc *desc)
{
- this_cpu_inc_rm(desc->kstat_irqs);
+ this_cpu_inc_rm(&desc->kstat_irqs->cnt);
__this_cpu_inc(kstat.irqs_sum);
}
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 5b92619a05fd..7b8ae509328f 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -461,12 +461,6 @@ static bool kvm_test_age_gfn_pr(struct kvm *kvm, struct kvm_gfn_range *range)
return false;
}
-static bool kvm_set_spte_gfn_pr(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- /* The page will get remapped properly on its next fault */
- return do_kvm_unmap_gfn(kvm, range);
-}
-
/*****************************************/
static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)
@@ -2071,7 +2065,6 @@ static struct kvmppc_ops kvm_ops_pr = {
.unmap_gfn_range = kvm_unmap_gfn_range_pr,
.age_gfn = kvm_age_gfn_pr,
.test_age_gfn = kvm_test_age_gfn_pr,
- .set_spte_gfn = kvm_set_spte_gfn_pr,
.free_memslot = kvmppc_core_free_memslot_pr,
.init_vm = kvmppc_core_init_vm_pr,
.destroy_vm = kvmppc_core_destroy_vm_pr,
@@ -2118,6 +2111,7 @@ void kvmppc_book3s_exit_pr(void)
module_init(kvmppc_book3s_init_pr);
module_exit(kvmppc_book3s_exit_pr);
+MODULE_DESCRIPTION("KVM on Book3S without using hypervisor mode");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(KVM_MINOR);
MODULE_ALIAS("devname:kvm");
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index 29a382249770..1362c672387e 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -531,7 +531,7 @@ static int xive_vm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
xc->cppr = xive_prio_from_guest(new_cppr);
/*
- * IPIs are synthetized from MFRR and thus don't need
+ * IPIs are synthesized from MFRR and thus don't need
* any special EOI handling. The underlying interrupt
* used to signal MFRR changes is EOId when fetched from
* the queue.
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c
index ccb8f16ffe41..c664fdec75b1 100644
--- a/arch/powerpc/kvm/e500_mmu_host.c
+++ b/arch/powerpc/kvm/e500_mmu_host.c
@@ -747,12 +747,6 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
return false;
}
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- /* The page will get remapped properly on its next fault */
- return kvm_e500_mmu_unmap_gfn(kvm, range);
-}
-
/*****************************************/
int e500_mmu_host_init(struct kvmppc_vcpu_e500 *vcpu_e500)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index d32abe7fe6ab..5e6c7b527677 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -1852,7 +1852,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_sigset_activate(vcpu);
- if (run->immediate_exit)
+ if (!vcpu->wants_to_run)
r = -EINTR;
else
r = kvmppc_vcpu_run(vcpu);
@@ -1984,8 +1984,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
break;
r = -ENXIO;
- if (!xive_enabled())
+ if (!xive_enabled()) {
+ fdput(f);
break;
+ }
r = -EPERM;
dev = kvm_device_from_filp(f.file);
diff --git a/arch/powerpc/kvm/test-guest-state-buffer.c b/arch/powerpc/kvm/test-guest-state-buffer.c
index 4720b8dc8837..bfd225329a18 100644
--- a/arch/powerpc/kvm/test-guest-state-buffer.c
+++ b/arch/powerpc/kvm/test-guest-state-buffer.c
@@ -151,7 +151,7 @@ static void test_gs_bitmap(struct kunit *test)
i++;
}
- for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSID_CTRL; iden++) {
+ for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSE_DW_REGS_END; iden++) {
kvmppc_gsbm_set(&gsbm, iden);
kvmppc_gsbm_set(&gsbm1, iden);
KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
@@ -325,4 +325,5 @@ static struct kunit_suite guest_state_buffer_test_suite = {
kunit_test_suites(&guest_state_buffer_test_suite);
+MODULE_DESCRIPTION("KUnit tests for Guest State Buffer APIs");
MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/kvm/trace_hv.h b/arch/powerpc/kvm/trace_hv.h
index 8d57c8428531..77ebc724e6cd 100644
--- a/arch/powerpc/kvm/trace_hv.h
+++ b/arch/powerpc/kvm/trace_hv.h
@@ -512,6 +512,35 @@ TRACE_EVENT(kvmppc_run_vcpu_exit,
__entry->vcpu_id, __entry->exit, __entry->ret)
);
+#ifdef CONFIG_PPC_PSERIES
+
+TRACE_EVENT_FN_COND(kvmppc_vcpu_stats,
+ TP_PROTO(struct kvm_vcpu *vcpu, u64 l1_to_l2_cs, u64 l2_to_l1_cs, u64 l2_runtime),
+
+ TP_ARGS(vcpu, l1_to_l2_cs, l2_to_l1_cs, l2_runtime),
+
+ TP_CONDITION(l1_to_l2_cs || l2_to_l1_cs || l2_runtime),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(u64, l1_to_l2_cs)
+ __field(u64, l2_to_l1_cs)
+ __field(u64, l2_runtime)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu->vcpu_id;
+ __entry->l1_to_l2_cs = l1_to_l2_cs;
+ __entry->l2_to_l1_cs = l2_to_l1_cs;
+ __entry->l2_runtime = l2_runtime;
+ ),
+
+ TP_printk("VCPU %d: l1_to_l2_cs_time=%llu ns l2_to_l1_cs_time=%llu ns l2_runtime=%llu ns",
+ __entry->vcpu_id, __entry->l1_to_l2_cs,
+ __entry->l2_to_l1_cs, __entry->l2_runtime),
+ kmvhv_counters_tracepoint_regfunc, kmvhv_counters_tracepoint_unregfunc
+);
+#endif
#endif /* _TRACE_KVM_HV_H */
/* This part must be outside protection */
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 0ab65eeb93ee..f14ecab674a3 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -3,8 +3,6 @@
# Makefile for ppc-specific library files..
#
-ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-
CFLAGS_code-patching.o += -fno-stack-protector
CFLAGS_feature-fixups.o += -fno-stack-protector
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index c6ab46156cda..0d1f3ee91115 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -225,7 +225,7 @@ void __init poking_init(void)
static unsigned long get_patch_pfn(void *addr)
{
- if (IS_ENABLED(CONFIG_MODULES) && is_vmalloc_or_module_addr(addr))
+ if (IS_ENABLED(CONFIG_EXECMEM) && is_vmalloc_or_module_addr(addr))
return vmalloc_to_pfn(addr);
else
return __pa_symbol(addr) >> PAGE_SHIFT;
@@ -372,9 +372,32 @@ int patch_instruction(u32 *addr, ppc_inst_t instr)
}
NOKPROBE_SYMBOL(patch_instruction);
+static int patch_memset64(u64 *addr, u64 val, size_t count)
+{
+ for (u64 *end = addr + count; addr < end; addr++)
+ __put_kernel_nofault(addr, &val, u64, failed);
+
+ return 0;
+
+failed:
+ return -EPERM;
+}
+
+static int patch_memset32(u32 *addr, u32 val, size_t count)
+{
+ for (u32 *end = addr + count; addr < end; addr++)
+ __put_kernel_nofault(addr, &val, u32, failed);
+
+ return 0;
+
+failed:
+ return -EPERM;
+}
+
static int __patch_instructions(u32 *patch_addr, u32 *code, size_t len, bool repeat_instr)
{
unsigned long start = (unsigned long)patch_addr;
+ int err;
/* Repeat instruction */
if (repeat_instr) {
@@ -383,19 +406,19 @@ static int __patch_instructions(u32 *patch_addr, u32 *code, size_t len, bool rep
if (ppc_inst_prefixed(instr)) {
u64 val = ppc_inst_as_ulong(instr);
- memset64((u64 *)patch_addr, val, len / 8);
+ err = patch_memset64((u64 *)patch_addr, val, len / 8);
} else {
u32 val = ppc_inst_val(instr);
- memset32(patch_addr, val, len / 4);
+ err = patch_memset32(patch_addr, val, len / 4);
}
} else {
- memcpy(patch_addr, code, len);
+ err = copy_to_kernel_nofault(patch_addr, code, len);
}
smp_wmb(); /* smp write barrier */
flush_icache_range(start, start + len);
- return 0;
+ return err;
}
/*
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 4f82581ca203..b7201ba50b2e 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -25,6 +25,13 @@
#include <asm/firmware.h>
#include <asm/inst.h>
+/*
+ * Used to generate warnings if mmu or cpu feature check functions that
+ * use static keys before they are initialized.
+ */
+bool static_key_feature_checks_initialized __read_mostly;
+EXPORT_SYMBOL_GPL(static_key_feature_checks_initialized);
+
struct fixup_entry {
unsigned long mask;
unsigned long value;
@@ -679,6 +686,7 @@ void __init setup_feature_keys(void)
jump_label_init();
cpu_feature_keys_init();
mmu_feature_keys_init();
+ static_key_feature_checks_initialized = true;
}
static int __init check_features(void)
diff --git a/arch/powerpc/lib/test-code-patching.c b/arch/powerpc/lib/test-code-patching.c
index c44823292f73..f76030087f98 100644
--- a/arch/powerpc/lib/test-code-patching.c
+++ b/arch/powerpc/lib/test-code-patching.c
@@ -347,6 +347,97 @@ static void __init test_prefixed_patching(void)
check(!memcmp(iptr, expected, sizeof(expected)));
}
+static void __init test_multi_instruction_patching(void)
+{
+ u32 code[32];
+ void *buf;
+ u32 *addr32;
+ u64 *addr64;
+ ppc_inst_t inst64 = ppc_inst_prefix(OP_PREFIX << 26 | 3UL << 24, PPC_RAW_TRAP());
+ u32 inst32 = PPC_RAW_NOP();
+
+ buf = vzalloc(PAGE_SIZE * 8);
+ check(buf);
+ if (!buf)
+ return;
+
+ /* Test single page 32-bit repeated instruction */
+ addr32 = buf + PAGE_SIZE;
+ check(!patch_instructions(addr32 + 1, &inst32, 12, true));
+
+ check(addr32[0] == 0);
+ check(addr32[1] == inst32);
+ check(addr32[2] == inst32);
+ check(addr32[3] == inst32);
+ check(addr32[4] == 0);
+
+ /* Test single page 64-bit repeated instruction */
+ if (IS_ENABLED(CONFIG_PPC64)) {
+ check(ppc_inst_prefixed(inst64));
+
+ addr64 = buf + PAGE_SIZE * 2;
+ ppc_inst_write(code, inst64);
+ check(!patch_instructions((u32 *)(addr64 + 1), code, 24, true));
+
+ check(addr64[0] == 0);
+ check(ppc_inst_equal(ppc_inst_read((u32 *)&addr64[1]), inst64));
+ check(ppc_inst_equal(ppc_inst_read((u32 *)&addr64[2]), inst64));
+ check(ppc_inst_equal(ppc_inst_read((u32 *)&addr64[3]), inst64));
+ check(addr64[4] == 0);
+ }
+
+ /* Test single page memcpy */
+ addr32 = buf + PAGE_SIZE * 3;
+
+ for (int i = 0; i < ARRAY_SIZE(code); i++)
+ code[i] = i + 1;
+
+ check(!patch_instructions(addr32 + 1, code, sizeof(code), false));
+
+ check(addr32[0] == 0);
+ check(!memcmp(&addr32[1], code, sizeof(code)));
+ check(addr32[ARRAY_SIZE(code) + 1] == 0);
+
+ /* Test multipage 32-bit repeated instruction */
+ addr32 = buf + PAGE_SIZE * 4 - 8;
+ check(!patch_instructions(addr32 + 1, &inst32, 12, true));
+
+ check(addr32[0] == 0);
+ check(addr32[1] == inst32);
+ check(addr32[2] == inst32);
+ check(addr32[3] == inst32);
+ check(addr32[4] == 0);
+
+ /* Test multipage 64-bit repeated instruction */
+ if (IS_ENABLED(CONFIG_PPC64)) {
+ check(ppc_inst_prefixed(inst64));
+
+ addr64 = buf + PAGE_SIZE * 5 - 8;
+ ppc_inst_write(code, inst64);
+ check(!patch_instructions((u32 *)(addr64 + 1), code, 24, true));
+
+ check(addr64[0] == 0);
+ check(ppc_inst_equal(ppc_inst_read((u32 *)&addr64[1]), inst64));
+ check(ppc_inst_equal(ppc_inst_read((u32 *)&addr64[2]), inst64));
+ check(ppc_inst_equal(ppc_inst_read((u32 *)&addr64[3]), inst64));
+ check(addr64[4] == 0);
+ }
+
+ /* Test multipage memcpy */
+ addr32 = buf + PAGE_SIZE * 6 - 12;
+
+ for (int i = 0; i < ARRAY_SIZE(code); i++)
+ code[i] = i + 1;
+
+ check(!patch_instructions(addr32 + 1, code, sizeof(code), false));
+
+ check(addr32[0] == 0);
+ check(!memcmp(&addr32[1], code, sizeof(code)));
+ check(addr32[ARRAY_SIZE(code) + 1] == 0);
+
+ vfree(buf);
+}
+
static int __init test_code_patching(void)
{
pr_info("Running code patching self-tests ...\n");
@@ -356,6 +447,7 @@ static int __init test_code_patching(void)
test_create_function_call();
test_translate_branch();
test_prefixed_patching();
+ test_multi_instruction_patching();
return 0;
}
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 503a6e249940..0fe2f085c05a 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -3,8 +3,6 @@
# Makefile for the linux ppc-specific parts of the memory manager.
#
-ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-
obj-y := fault.o mem.o pgtable.o maccess.o pageattr.o \
init_$(BITS).o pgtable_$(BITS).o \
pgtable-frag.o ioremap.o ioremap_$(BITS).o \
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 100f999871bc..625fe7d08e06 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -184,7 +184,7 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
static bool is_module_segment(unsigned long addr)
{
- if (!IS_ENABLED(CONFIG_MODULES))
+ if (!IS_ENABLED(CONFIG_EXECMEM))
return false;
if (addr < ALIGN_DOWN(MODULES_VADDR, SZ_256M))
return false;
diff --git a/arch/powerpc/mm/book3s64/Makefile b/arch/powerpc/mm/book3s64/Makefile
index cad2abc1730f..33af5795856a 100644
--- a/arch/powerpc/mm/book3s64/Makefile
+++ b/arch/powerpc/mm/book3s64/Makefile
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-ccflags-y := $(NO_MINIMAL_TOC)
-
obj-y += mmu_context.o pgtable.o trace.o
ifdef CONFIG_PPC_64S_HASH_MMU
CFLAGS_REMOVE_slb.o = $(CC_FLAGS_FTRACE)
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index 01c3b4b65241..6727a15ab94f 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1233,10 +1233,6 @@ void __init hash__early_init_mmu(void)
__pmd_table_size = H_PMD_TABLE_SIZE;
__pud_table_size = H_PUD_TABLE_SIZE;
__pgd_table_size = H_PGD_TABLE_SIZE;
- /*
- * 4k use hugepd format, so for hash set then to
- * zero
- */
__pmd_val_bits = HASH_PMD_VAL_BITS;
__pud_val_bits = HASH_PUD_VAL_BITS;
__pgd_val_bits = HASH_PGD_VAL_BITS;
@@ -1546,6 +1542,13 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
goto bail;
}
+ if (IS_ENABLED(CONFIG_PPC_4K_PAGES) && !radix_enabled()) {
+ if (hugeshift == PMD_SHIFT && psize == MMU_PAGE_16M)
+ hugeshift = mmu_psize_defs[MMU_PAGE_16M].shift;
+ if (hugeshift == PUD_SHIFT && psize == MMU_PAGE_16G)
+ hugeshift = mmu_psize_defs[MMU_PAGE_16G].shift;
+ }
+
/*
* Add _PAGE_PRESENT to the required access perm. If there are parallel
* updates to the pte that can possibly clear _PAGE_PTE, catch that too.
diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
index 5a2e512e96db..83c3361b358b 100644
--- a/arch/powerpc/mm/book3s64/hugetlbpage.c
+++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
@@ -53,6 +53,16 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
/* If PTE permissions don't match, take page fault */
if (unlikely(!check_pte_access(access, old_pte)))
return 1;
+ /*
+ * If hash-4k, hugepages use seeral contiguous PxD entries
+ * so bail out and let mm make the page young or dirty
+ */
+ if (IS_ENABLED(CONFIG_PPC_4K_PAGES)) {
+ if (!(old_pte & _PAGE_ACCESSED))
+ return 1;
+ if ((access & _PAGE_WRITE) && !(old_pte & _PAGE_DIRTY))
+ return 1;
+ }
/*
* Try to lock the PTE, add ACCESSED and DIRTY if it was
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 83823db3488b..f4d8d3c40e5c 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -170,6 +170,7 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
{
unsigned long old_pmd;
+ VM_WARN_ON_ONCE(!pmd_present(*pmdp));
old_pmd = pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, _PAGE_INVALID);
flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
return __pmd(old_pmd);
@@ -460,18 +461,6 @@ static inline void pgtable_free(void *table, int index)
case PUD_INDEX:
__pud_free(table);
break;
-#if defined(CONFIG_PPC_4K_PAGES) && defined(CONFIG_HUGETLB_PAGE)
- /* 16M hugepd directory at pud level */
- case HTLB_16M_INDEX:
- BUILD_BUG_ON(H_16M_CACHE_INDEX <= 0);
- kmem_cache_free(PGT_CACHE(H_16M_CACHE_INDEX), table);
- break;
- /* 16G hugepd directory at the pgd level */
- case HTLB_16G_INDEX:
- BUILD_BUG_ON(H_16G_CACHE_INDEX <= 0);
- kmem_cache_free(PGT_CACHE(H_16G_CACHE_INDEX), table);
- break;
-#endif
/* We don't free pgd table via RCU callback */
default:
BUG();
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 15e88f1439ec..b0d927009af8 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -17,6 +17,7 @@
#include <linux/hugetlb.h>
#include <linux/string_helpers.h>
#include <linux/memory.h>
+#include <linux/kfence.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
@@ -31,6 +32,7 @@
#include <asm/uaccess.h>
#include <asm/ultravisor.h>
#include <asm/set_memory.h>
+#include <asm/kfence.h>
#include <trace/events/thp.h>
@@ -293,7 +295,8 @@ static unsigned long next_boundary(unsigned long addr, unsigned long end)
static int __meminit create_physical_mapping(unsigned long start,
unsigned long end,
- int nid, pgprot_t _prot)
+ int nid, pgprot_t _prot,
+ unsigned long mapping_sz_limit)
{
unsigned long vaddr, addr, mapping_size = 0;
bool prev_exec, exec = false;
@@ -301,7 +304,10 @@ static int __meminit create_physical_mapping(unsigned long start,
int psize;
unsigned long max_mapping_size = memory_block_size;
- if (debug_pagealloc_enabled_or_kfence())
+ if (mapping_sz_limit < max_mapping_size)
+ max_mapping_size = mapping_sz_limit;
+
+ if (debug_pagealloc_enabled())
max_mapping_size = PAGE_SIZE;
start = ALIGN(start, PAGE_SIZE);
@@ -356,8 +362,74 @@ static int __meminit create_physical_mapping(unsigned long start,
return 0;
}
+#ifdef CONFIG_KFENCE
+static bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL;
+
+static int __init parse_kfence_early_init(char *arg)
+{
+ int val;
+
+ if (get_option(&arg, &val))
+ kfence_early_init = !!val;
+ return 0;
+}
+early_param("kfence.sample_interval", parse_kfence_early_init);
+
+static inline phys_addr_t alloc_kfence_pool(void)
+{
+ phys_addr_t kfence_pool;
+
+ /*
+ * TODO: Support to enable KFENCE after bootup depends on the ability to
+ * split page table mappings. As such support is not currently
+ * implemented for radix pagetables, support enabling KFENCE
+ * only at system startup for now.
+ *
+ * After support for splitting mappings is available on radix,
+ * alloc_kfence_pool() & map_kfence_pool() can be dropped and
+ * mapping for __kfence_pool memory can be
+ * split during arch_kfence_init_pool().
+ */
+ if (!kfence_early_init)
+ goto no_kfence;
+
+ kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
+ if (!kfence_pool)
+ goto no_kfence;
+
+ memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+ return kfence_pool;
+
+no_kfence:
+ disable_kfence();
+ return 0;
+}
+
+static inline void map_kfence_pool(phys_addr_t kfence_pool)
+{
+ if (!kfence_pool)
+ return;
+
+ if (create_physical_mapping(kfence_pool, kfence_pool + KFENCE_POOL_SIZE,
+ -1, PAGE_KERNEL, PAGE_SIZE))
+ goto err;
+
+ memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
+ __kfence_pool = __va(kfence_pool);
+ return;
+
+err:
+ memblock_phys_free(kfence_pool, KFENCE_POOL_SIZE);
+ disable_kfence();
+}
+#else
+static inline phys_addr_t alloc_kfence_pool(void) { return 0; }
+static inline void map_kfence_pool(phys_addr_t kfence_pool) { }
+#endif
+
static void __init radix_init_pgtable(void)
{
+ phys_addr_t kfence_pool;
unsigned long rts_field;
phys_addr_t start, end;
u64 i;
@@ -365,6 +437,8 @@ static void __init radix_init_pgtable(void)
/* We don't support slb for radix */
slb_set_size(0);
+ kfence_pool = alloc_kfence_pool();
+
/*
* Create the linear mapping
*/
@@ -381,9 +455,11 @@ static void __init radix_init_pgtable(void)
}
WARN_ON(create_physical_mapping(start, end,
- -1, PAGE_KERNEL));
+ -1, PAGE_KERNEL, ~0UL));
}
+ map_kfence_pool(kfence_pool);
+
if (!cpu_has_feature(CPU_FTR_HVMODE) &&
cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
/*
@@ -875,7 +951,7 @@ int __meminit radix__create_section_mapping(unsigned long start,
}
return create_physical_mapping(__pa(start), __pa(end),
- nid, prot);
+ nid, prot, ~0UL);
}
int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end)
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index c0b58afb9a47..ef3ce37f1bb3 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -282,12 +282,10 @@ static unsigned long slice_find_area_bottomup(struct mm_struct *mm,
{
int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT);
unsigned long found, next_end;
- struct vm_unmapped_area_info info;
-
- info.flags = 0;
- info.length = len;
- info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
- info.align_offset = 0;
+ struct vm_unmapped_area_info info = {
+ .length = len,
+ .align_mask = PAGE_MASK & ((1ul << pshift) - 1),
+ };
/*
* Check till the allow max value for this mmap request
*/
@@ -326,13 +324,13 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
{
int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT);
unsigned long found, prev;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {
+ .flags = VM_UNMAPPED_AREA_TOPDOWN,
+ .length = len,
+ .align_mask = PAGE_MASK & ((1ul << pshift) - 1),
+ };
unsigned long min_addr = max(PAGE_SIZE, mmap_min_addr);
- info.flags = VM_UNMAPPED_AREA_TOPDOWN;
- info.length = len;
- info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
- info.align_offset = 0;
/*
* If we are trying to allocate above DEFAULT_MAP_WINDOW
* Add the different to the mmap_base.
diff --git a/arch/powerpc/mm/cacheflush.c b/arch/powerpc/mm/cacheflush.c
index 15189592da09..7186516eca52 100644
--- a/arch/powerpc/mm/cacheflush.c
+++ b/arch/powerpc/mm/cacheflush.c
@@ -78,7 +78,7 @@ EXPORT_SYMBOL(flush_icache_range);
#ifdef CONFIG_HIGHMEM
/**
- * flush_dcache_icache_phys() - Flush a page by it's physical address
+ * flush_dcache_icache_phys() - Flush a page by its physical address
* @physaddr: the physical address of the page
*/
static void flush_dcache_icache_phys(unsigned long physaddr)
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
index c110ab8fa8a3..8dd7b340d51f 100644
--- a/arch/powerpc/mm/drmem.c
+++ b/arch/powerpc/mm/drmem.c
@@ -491,10 +491,8 @@ static int __init drmem_init(void)
const __be32 *prop;
dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
- if (!dn) {
- pr_info("No dynamic reconfiguration memory found\n");
+ if (!dn)
return 0;
- }
if (init_drmem_lmb_size(dn)) {
of_node_put(dn);
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 53335ae21a40..81c77ddce2e3 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -71,23 +71,26 @@ static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long add
return __bad_area_nosemaphore(regs, address, SEGV_MAPERR);
}
-static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code)
+static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code,
+ struct mm_struct *mm, struct vm_area_struct *vma)
{
- struct mm_struct *mm = current->mm;
/*
* 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);
+ if (mm)
+ mmap_read_unlock(mm);
+ else
+ vma_end_read(vma);
return __bad_area_nosemaphore(regs, address, si_code);
}
static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
+ struct mm_struct *mm,
struct vm_area_struct *vma)
{
- struct mm_struct *mm = current->mm;
int pkey;
/*
@@ -109,7 +112,10 @@ static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
*/
pkey = vma_pkey(vma);
- mmap_read_unlock(mm);
+ if (mm)
+ mmap_read_unlock(mm);
+ else
+ vma_end_read(vma);
/*
* If we are in kernel mode, bail out with a SEGV, this will
@@ -124,9 +130,10 @@ static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
return 0;
}
-static noinline int bad_access(struct pt_regs *regs, unsigned long address)
+static noinline int bad_access(struct pt_regs *regs, unsigned long address,
+ struct mm_struct *mm, struct vm_area_struct *vma)
{
- return __bad_area(regs, address, SEGV_ACCERR);
+ return __bad_area(regs, address, SEGV_ACCERR, mm, vma);
}
static int do_sigbus(struct pt_regs *regs, unsigned long address,
@@ -361,13 +368,13 @@ static void sanity_check_fault(bool is_write, bool is_user,
* Define the correct "is_write" bit in error_code based
* on the processor family
*/
-#if (defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#ifdef CONFIG_BOOKE
#define page_fault_is_write(__err) ((__err) & ESR_DST)
#else
#define page_fault_is_write(__err) ((__err) & DSISR_ISSTORE)
#endif
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_BOOKE
#define page_fault_is_bad(__err) (0)
#elif defined(CONFIG_PPC_8xx)
#define page_fault_is_bad(__err) ((__err) & DSISR_NOEXEC_OR_G)
@@ -479,13 +486,13 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
if (unlikely(access_pkey_error(is_write, is_exec,
(error_code & DSISR_KEYFAULT), vma))) {
- vma_end_read(vma);
- goto lock_mmap;
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ return bad_access_pkey(regs, address, NULL, vma);
}
if (unlikely(access_error(is_write, is_exec, vma))) {
- vma_end_read(vma);
- goto lock_mmap;
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ return bad_access(regs, address, NULL, vma);
}
fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs);
@@ -521,10 +528,10 @@ retry:
if (unlikely(access_pkey_error(is_write, is_exec,
(error_code & DSISR_KEYFAULT), vma)))
- return bad_access_pkey(regs, address, vma);
+ return bad_access_pkey(regs, address, mm, vma);
if (unlikely(access_error(is_write, is_exec, vma)))
- return bad_access(regs, address);
+ return bad_access(regs, address, mm, vma);
/*
* If for any reason at all we couldn't handle the fault,
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 594a4b7b2ca2..6b043180220a 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -28,8 +28,6 @@
bool hugetlb_disabled = false;
-#define hugepd_none(hpd) (hpd_val(hpd) == 0)
-
#define PTE_T_ORDER (__builtin_ffs(sizeof(pte_basic_t)) - \
__builtin_ffs(sizeof(void *)))
@@ -42,156 +40,43 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long s
return __find_linux_pte(mm->pgd, addr, NULL, NULL);
}
-static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
- unsigned long address, unsigned int pdshift,
- unsigned int pshift, spinlock_t *ptl)
+pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, unsigned long sz)
{
- struct kmem_cache *cachep;
- pte_t *new;
- int i;
- int num_hugepd;
-
- if (pshift >= pdshift) {
- cachep = PGT_CACHE(PTE_T_ORDER);
- num_hugepd = 1 << (pshift - pdshift);
- } else {
- cachep = PGT_CACHE(pdshift - pshift);
- num_hugepd = 1;
- }
-
- if (!cachep) {
- WARN_ONCE(1, "No page table cache created for hugetlb tables");
- return -ENOMEM;
- }
-
- new = kmem_cache_alloc(cachep, pgtable_gfp_flags(mm, GFP_KERNEL));
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
- BUG_ON(pshift > HUGEPD_SHIFT_MASK);
- BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK);
+ addr &= ~(sz - 1);
- if (!new)
- return -ENOMEM;
+ p4d = p4d_offset(pgd_offset(mm, addr), addr);
+ if (!mm_pud_folded(mm) && sz >= P4D_SIZE)
+ return (pte_t *)p4d;
- /*
- * Make sure other cpus find the hugepd set only after a
- * properly initialized page table is visible to them.
- * For more details look for comment in __pte_alloc().
- */
- smp_wmb();
+ pud = pud_alloc(mm, p4d, addr);
+ if (!pud)
+ return NULL;
+ if (!mm_pmd_folded(mm) && sz >= PUD_SIZE)
+ return (pte_t *)pud;
- spin_lock(ptl);
- /*
- * We have multiple higher-level entries that point to the same
- * actual pte location. Fill in each as we go and backtrack on error.
- * We need all of these so the DTLB pgtable walk code can find the
- * right higher-level entry without knowing if it's a hugepage or not.
- */
- for (i = 0; i < num_hugepd; i++, hpdp++) {
- if (unlikely(!hugepd_none(*hpdp)))
- break;
- hugepd_populate(hpdp, new, pshift);
- }
- /* If we bailed from the for loop early, an error occurred, clean up */
- if (i < num_hugepd) {
- for (i = i - 1 ; i >= 0; i--, hpdp--)
- *hpdp = __hugepd(0);
- kmem_cache_free(cachep, new);
- } else {
- kmemleak_ignore(new);
- }
- spin_unlock(ptl);
- return 0;
-}
+ pmd = pmd_alloc(mm, pud, addr);
+ if (!pmd)
+ return NULL;
-/*
- * At this point we do the placement change only for BOOK3S 64. This would
- * possibly work on other subarchs.
- */
-pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, unsigned long sz)
-{
- pgd_t *pg;
- p4d_t *p4;
- pud_t *pu;
- pmd_t *pm;
- hugepd_t *hpdp = NULL;
- unsigned pshift = __ffs(sz);
- unsigned pdshift = PGDIR_SHIFT;
- spinlock_t *ptl;
-
- addr &= ~(sz-1);
- pg = pgd_offset(mm, addr);
- p4 = p4d_offset(pg, addr);
+ if (sz >= PMD_SIZE) {
+ /* On 8xx, all hugepages are handled as contiguous PTEs */
+ if (IS_ENABLED(CONFIG_PPC_8xx)) {
+ int i;
-#ifdef CONFIG_PPC_BOOK3S_64
- if (pshift == PGDIR_SHIFT)
- /* 16GB huge page */
- return (pte_t *) p4;
- else if (pshift > PUD_SHIFT) {
- /*
- * We need to use hugepd table
- */
- ptl = &mm->page_table_lock;
- hpdp = (hugepd_t *)p4;
- } else {
- pdshift = PUD_SHIFT;
- pu = pud_alloc(mm, p4, addr);
- if (!pu)
- return NULL;
- if (pshift == PUD_SHIFT)
- return (pte_t *)pu;
- else if (pshift > PMD_SHIFT) {
- ptl = pud_lockptr(mm, pu);
- hpdp = (hugepd_t *)pu;
- } else {
- pdshift = PMD_SHIFT;
- pm = pmd_alloc(mm, pu, addr);
- if (!pm)
- return NULL;
- if (pshift == PMD_SHIFT)
- /* 16MB hugepage */
- return (pte_t *)pm;
- else {
- ptl = pmd_lockptr(mm, pm);
- hpdp = (hugepd_t *)pm;
+ for (i = 0; i < sz / PMD_SIZE; i++) {
+ if (!pte_alloc_huge(mm, pmd + i, addr))
+ return NULL;
}
}
+ return (pte_t *)pmd;
}
-#else
- if (pshift >= PGDIR_SHIFT) {
- ptl = &mm->page_table_lock;
- hpdp = (hugepd_t *)p4;
- } else {
- pdshift = PUD_SHIFT;
- pu = pud_alloc(mm, p4, addr);
- if (!pu)
- return NULL;
- if (pshift >= PUD_SHIFT) {
- ptl = pud_lockptr(mm, pu);
- hpdp = (hugepd_t *)pu;
- } else {
- pdshift = PMD_SHIFT;
- pm = pmd_alloc(mm, pu, addr);
- if (!pm)
- return NULL;
- ptl = pmd_lockptr(mm, pm);
- hpdp = (hugepd_t *)pm;
- }
- }
-#endif
- if (!hpdp)
- return NULL;
-
- if (IS_ENABLED(CONFIG_PPC_8xx) && pshift < PMD_SHIFT)
- return pte_alloc_huge(mm, (pmd_t *)hpdp, addr);
-
- BUG_ON(!hugepd_none(*hpdp) && !hugepd_ok(*hpdp));
- if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr,
- pdshift, pshift, ptl))
- return NULL;
-
- return hugepte_offset(*hpdp, addr, pdshift);
+ return pte_alloc_huge(mm, pmd, addr);
}
#ifdef CONFIG_PPC_BOOK3S_64
@@ -248,264 +133,6 @@ int __init alloc_bootmem_huge_page(struct hstate *h, int nid)
return __alloc_bootmem_huge_page(h, nid);
}
-#ifndef CONFIG_PPC_BOOK3S_64
-#define HUGEPD_FREELIST_SIZE \
- ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t))
-
-struct hugepd_freelist {
- struct rcu_head rcu;
- unsigned int index;
- void *ptes[];
-};
-
-static DEFINE_PER_CPU(struct hugepd_freelist *, hugepd_freelist_cur);
-
-static void hugepd_free_rcu_callback(struct rcu_head *head)
-{
- struct hugepd_freelist *batch =
- container_of(head, struct hugepd_freelist, rcu);
- unsigned int i;
-
- for (i = 0; i < batch->index; i++)
- kmem_cache_free(PGT_CACHE(PTE_T_ORDER), batch->ptes[i]);
-
- free_page((unsigned long)batch);
-}
-
-static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
-{
- struct hugepd_freelist **batchp;
-
- batchp = &get_cpu_var(hugepd_freelist_cur);
-
- if (atomic_read(&tlb->mm->mm_users) < 2 ||
- mm_is_thread_local(tlb->mm)) {
- kmem_cache_free(PGT_CACHE(PTE_T_ORDER), hugepte);
- put_cpu_var(hugepd_freelist_cur);
- return;
- }
-
- if (*batchp == NULL) {
- *batchp = (struct hugepd_freelist *)__get_free_page(GFP_ATOMIC);
- (*batchp)->index = 0;
- }
-
- (*batchp)->ptes[(*batchp)->index++] = hugepte;
- if ((*batchp)->index == HUGEPD_FREELIST_SIZE) {
- call_rcu(&(*batchp)->rcu, hugepd_free_rcu_callback);
- *batchp = NULL;
- }
- put_cpu_var(hugepd_freelist_cur);
-}
-#else
-static inline void hugepd_free(struct mmu_gather *tlb, void *hugepte) {}
-#endif
-
-/* Return true when the entry to be freed maps more than the area being freed */
-static bool range_is_outside_limits(unsigned long start, unsigned long end,
- unsigned long floor, unsigned long ceiling,
- unsigned long mask)
-{
- if ((start & mask) < floor)
- return true;
- if (ceiling) {
- ceiling &= mask;
- if (!ceiling)
- return true;
- }
- return end - 1 > ceiling - 1;
-}
-
-static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift,
- unsigned long start, unsigned long end,
- unsigned long floor, unsigned long ceiling)
-{
- pte_t *hugepte = hugepd_page(*hpdp);
- int i;
-
- unsigned long pdmask = ~((1UL << pdshift) - 1);
- unsigned int num_hugepd = 1;
- unsigned int shift = hugepd_shift(*hpdp);
-
- /* Note: On fsl the hpdp may be the first of several */
- if (shift > pdshift)
- num_hugepd = 1 << (shift - pdshift);
-
- if (range_is_outside_limits(start, end, floor, ceiling, pdmask))
- return;
-
- for (i = 0; i < num_hugepd; i++, hpdp++)
- *hpdp = __hugepd(0);
-
- if (shift >= pdshift)
- hugepd_free(tlb, hugepte);
- else
- pgtable_free_tlb(tlb, hugepte,
- get_hugepd_cache_index(pdshift - shift));
-}
-
-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)
-{
- pgtable_t token = pmd_pgtable(*pmd);
-
- if (range_is_outside_limits(addr, end, floor, ceiling, PMD_MASK))
- return;
-
- pmd_clear(pmd);
- pte_free_tlb(tlb, token, addr);
- mm_dec_nr_ptes(tlb->mm);
-}
-
-static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
- unsigned long addr, unsigned long end,
- unsigned long floor, unsigned long ceiling)
-{
- pmd_t *pmd;
- unsigned long next;
- unsigned long start;
-
- start = addr;
- do {
- unsigned long more;
-
- pmd = pmd_offset(pud, addr);
- next = pmd_addr_end(addr, end);
- if (!is_hugepd(__hugepd(pmd_val(*pmd)))) {
- if (pmd_none_or_clear_bad(pmd))
- continue;
-
- /*
- * if it is not hugepd pointer, we should already find
- * it cleared.
- */
- WARN_ON(!IS_ENABLED(CONFIG_PPC_8xx));
-
- hugetlb_free_pte_range(tlb, pmd, addr, end, floor, ceiling);
-
- continue;
- }
- /*
- * Increment next by the size of the huge mapping since
- * there may be more than one entry at this level for a
- * single hugepage, but all of them point to
- * the same kmem cache that holds the hugepte.
- */
- more = addr + (1UL << hugepd_shift(*(hugepd_t *)pmd));
- if (more > next)
- next = more;
-
- free_hugepd_range(tlb, (hugepd_t *)pmd, PMD_SHIFT,
- addr, next, floor, ceiling);
- } while (addr = next, addr != end);
-
- if (range_is_outside_limits(start, end, floor, ceiling, PUD_MASK))
- return;
-
- pmd = pmd_offset(pud, start & PUD_MASK);
- pud_clear(pud);
- pmd_free_tlb(tlb, pmd, start & PUD_MASK);
- mm_dec_nr_pmds(tlb->mm);
-}
-
-static void hugetlb_free_pud_range(struct mmu_gather *tlb, p4d_t *p4d,
- unsigned long addr, unsigned long end,
- unsigned long floor, unsigned long ceiling)
-{
- pud_t *pud;
- unsigned long next;
- unsigned long start;
-
- start = addr;
- do {
- pud = pud_offset(p4d, addr);
- next = pud_addr_end(addr, end);
- if (!is_hugepd(__hugepd(pud_val(*pud)))) {
- if (pud_none_or_clear_bad(pud))
- continue;
- hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
- ceiling);
- } else {
- unsigned long more;
- /*
- * Increment next by the size of the huge mapping since
- * there may be more than one entry at this level for a
- * single hugepage, but all of them point to
- * the same kmem cache that holds the hugepte.
- */
- more = addr + (1UL << hugepd_shift(*(hugepd_t *)pud));
- if (more > next)
- next = more;
-
- free_hugepd_range(tlb, (hugepd_t *)pud, PUD_SHIFT,
- addr, next, floor, ceiling);
- }
- } while (addr = next, addr != end);
-
- if (range_is_outside_limits(start, end, floor, ceiling, PGDIR_MASK))
- return;
-
- pud = pud_offset(p4d, start & PGDIR_MASK);
- p4d_clear(p4d);
- pud_free_tlb(tlb, pud, start & PGDIR_MASK);
- mm_dec_nr_puds(tlb->mm);
-}
-
-/*
- * This function frees user-level page tables of a process.
- */
-void hugetlb_free_pgd_range(struct mmu_gather *tlb,
- unsigned long addr, unsigned long end,
- unsigned long floor, unsigned long ceiling)
-{
- pgd_t *pgd;
- p4d_t *p4d;
- unsigned long next;
-
- /*
- * Because there are a number of different possible pagetable
- * layouts for hugepage ranges, we limit knowledge of how
- * things should be laid out to the allocation path
- * (huge_pte_alloc(), above). Everything else works out the
- * structure as it goes from information in the hugepd
- * pointers. That means that we can't here use the
- * optimization used in the normal page free_pgd_range(), of
- * checking whether we're actually covering a large enough
- * range to have to do anything at the top level of the walk
- * instead of at the bottom.
- *
- * To make sense of this, you should probably go read the big
- * block comment at the top of the normal free_pgd_range(),
- * too.
- */
-
- do {
- next = pgd_addr_end(addr, end);
- pgd = pgd_offset(tlb->mm, addr);
- p4d = p4d_offset(pgd, addr);
- if (!is_hugepd(__hugepd(pgd_val(*pgd)))) {
- if (p4d_none_or_clear_bad(p4d))
- continue;
- hugetlb_free_pud_range(tlb, p4d, addr, next, floor, ceiling);
- } else {
- unsigned long more;
- /*
- * Increment next by the size of the huge mapping since
- * there may be more than one entry at the pgd level
- * for a single hugepage, but all of them point to the
- * same kmem cache that holds the hugepte.
- */
- more = addr + (1UL << hugepd_shift(*(hugepd_t *)pgd));
- if (more > next)
- next = more;
-
- free_hugepd_range(tlb, (hugepd_t *)p4d, PGDIR_SHIFT,
- addr, next, floor, ceiling);
- }
- } while (addr = next, addr != end);
-}
-
bool __init arch_hugetlb_valid_size(unsigned long size)
{
int shift = __ffs(size);
@@ -552,44 +179,14 @@ static int __init hugetlbpage_init(void)
for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
unsigned shift;
- unsigned pdshift;
if (!mmu_psize_defs[psize].shift)
continue;
shift = mmu_psize_to_shift(psize);
-#ifdef CONFIG_PPC_BOOK3S_64
- if (shift > PGDIR_SHIFT)
- continue;
- else if (shift > PUD_SHIFT)
- pdshift = PGDIR_SHIFT;
- else if (shift > PMD_SHIFT)
- pdshift = PUD_SHIFT;
- else
- pdshift = PMD_SHIFT;
-#else
- if (shift < PUD_SHIFT)
- pdshift = PMD_SHIFT;
- else if (shift < PGDIR_SHIFT)
- pdshift = PUD_SHIFT;
- else
- pdshift = PGDIR_SHIFT;
-#endif
-
if (add_huge_page_size(1ULL << shift) < 0)
continue;
- /*
- * if we have pdshift and shift value same, we don't
- * use pgt cache for hugepd.
- */
- if (pdshift > shift) {
- if (!IS_ENABLED(CONFIG_PPC_8xx))
- pgtable_cache_add(pdshift - shift);
- } else if (IS_ENABLED(CONFIG_PPC_E500) ||
- IS_ENABLED(CONFIG_PPC_8xx)) {
- pgtable_cache_add(PTE_T_ORDER);
- }
configured = true;
}
diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c
index d3a7726ecf51..9b4a675eb8f8 100644
--- a/arch/powerpc/mm/init-common.c
+++ b/arch/powerpc/mm/init-common.c
@@ -31,6 +31,9 @@ EXPORT_SYMBOL_GPL(kernstart_virt_addr);
bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP);
bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP);
+#ifdef CONFIG_KFENCE
+bool __ro_after_init kfence_disabled;
+#endif
static int __init parse_nosmep(char *p)
{
@@ -120,12 +123,8 @@ void pgtable_cache_add(unsigned int shift)
/* When batching pgtable pointers for RCU freeing, we store
* the index size in the low bits. Table alignment must be
* big enough to fit it.
- *
- * Likewise, hugeapge pagetable pointers contain a (different)
- * shift value in the low bits. All tables must be aligned so
- * as to leave enough 0 bits in the address to contain it. */
- unsigned long minalign = max(MAX_PGTABLE_INDEX_SIZE + 1,
- HUGEPD_SHIFT_MASK + 1);
+ */
+ unsigned long minalign = MAX_PGTABLE_INDEX_SIZE + 1;
struct kmem_cache *new = NULL;
/* It would be nice if this was a BUILD_BUG_ON(), but at the
diff --git a/arch/powerpc/mm/kasan/8xx.c b/arch/powerpc/mm/kasan/8xx.c
index 2784224054f8..989d6cdf4141 100644
--- a/arch/powerpc/mm/kasan/8xx.c
+++ b/arch/powerpc/mm/kasan/8xx.c
@@ -6,28 +6,33 @@
#include <linux/memblock.h>
#include <linux/hugetlb.h>
+#include <asm/pgalloc.h>
+
static int __init
kasan_init_shadow_8M(unsigned long k_start, unsigned long k_end, void *block)
{
pmd_t *pmd = pmd_off_k(k_start);
unsigned long k_cur, k_next;
- for (k_cur = k_start; k_cur != k_end; k_cur = k_next, pmd += 2, block += SZ_8M) {
- pte_basic_t *new;
+ for (k_cur = k_start; k_cur != k_end; k_cur = k_next, pmd++, block += SZ_4M) {
+ pte_t *ptep;
+ int i;
k_next = pgd_addr_end(k_cur, k_end);
- k_next = pgd_addr_end(k_next, k_end);
if ((void *)pmd_page_vaddr(*pmd) != kasan_early_shadow_pte)
continue;
- new = memblock_alloc(sizeof(pte_basic_t), SZ_4K);
- if (!new)
+ ptep = memblock_alloc(PTE_FRAG_SIZE, PTE_FRAG_SIZE);
+ if (!ptep)
return -ENOMEM;
- *new = pte_val(pte_mkhuge(pfn_pte(PHYS_PFN(__pa(block)), PAGE_KERNEL)));
+ for (i = 0; i < PTRS_PER_PTE; i++) {
+ pte_t pte = pte_mkhuge(pfn_pte(PHYS_PFN(__pa(block + i * PAGE_SIZE)), PAGE_KERNEL));
- hugepd_populate_kernel((hugepd_t *)pmd, (pte_t *)new, PAGE_SHIFT_8M);
- hugepd_populate_kernel((hugepd_t *)pmd + 1, (pte_t *)new, PAGE_SHIFT_8M);
+ __set_pte_at(&init_mm, k_cur, ptep + i, pte, 1);
+ }
+ pmd_populate_kernel(&init_mm, pmd, ptep);
+ *pmd = __pmd(pmd_val(*pmd) | _PMD_PAGE_8M);
}
return 0;
}
diff --git a/arch/powerpc/mm/kasan/init_book3e_64.c b/arch/powerpc/mm/kasan/init_book3e_64.c
index 11519e88dc6b..43c03b84ff32 100644
--- a/arch/powerpc/mm/kasan/init_book3e_64.c
+++ b/arch/powerpc/mm/kasan/init_book3e_64.c
@@ -112,7 +112,7 @@ void __init kasan_init(void)
pte_t zero_pte = pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL_RO);
for_each_mem_range(i, &start, &end)
- kasan_init_phys_region((void *)start, (void *)end);
+ kasan_init_phys_region(phys_to_virt(start), phys_to_virt(end));
if (IS_ENABLED(CONFIG_KASAN_VMALLOC))
kasan_remove_zero_shadow((void *)VMALLOC_START, VMALLOC_SIZE);
diff --git a/arch/powerpc/mm/kasan/init_book3s_64.c b/arch/powerpc/mm/kasan/init_book3s_64.c
index 9300d641cf9a..3fb5ce4f48f4 100644
--- a/arch/powerpc/mm/kasan/init_book3s_64.c
+++ b/arch/powerpc/mm/kasan/init_book3s_64.c
@@ -62,7 +62,7 @@ void __init kasan_init(void)
}
for_each_mem_range(i, &start, &end)
- kasan_init_phys_region((void *)start, (void *)end);
+ kasan_init_phys_region(phys_to_virt(start), phys_to_virt(end));
for (i = 0; i < PTRS_PER_PTE; i++)
__set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page,
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 3a440004b97d..d325217ab201 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -16,6 +16,8 @@
#include <linux/highmem.h>
#include <linux/suspend.h>
#include <linux/dma-direct.h>
+#include <linux/execmem.h>
+#include <linux/vmalloc.h>
#include <asm/swiotlb.h>
#include <asm/machdep.h>
@@ -30,7 +32,7 @@
#include <mm/mmu_decl.h>
-unsigned long long memory_limit;
+unsigned long long memory_limit __initdata;
unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss;
EXPORT_SYMBOL(empty_zero_page);
@@ -406,3 +408,66 @@ int devmem_is_allowed(unsigned long pfn)
* the EHEA driver. Drop this when drivers/net/ethernet/ibm/ehea is removed.
*/
EXPORT_SYMBOL_GPL(walk_system_ram_range);
+
+#ifdef CONFIG_EXECMEM
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ pgprot_t kprobes_prot = strict_module_rwx_enabled() ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
+ pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC;
+ unsigned long fallback_start = 0, fallback_end = 0;
+ unsigned long start, end;
+
+ /*
+ * BOOK3S_32 and 8xx define MODULES_VADDR for text allocations and
+ * allow allocating data in the entire vmalloc space
+ */
+#ifdef MODULES_VADDR
+ unsigned long limit = (unsigned long)_etext - SZ_32M;
+
+ BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
+
+ /* First try within 32M limit from _etext to avoid branch trampolines */
+ if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) {
+ start = limit;
+ fallback_start = MODULES_VADDR;
+ fallback_end = MODULES_END;
+ } else {
+ start = MODULES_VADDR;
+ }
+
+ end = MODULES_END;
+#else
+ start = VMALLOC_START;
+ end = VMALLOC_END;
+#endif
+
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = start,
+ .end = end,
+ .pgprot = prot,
+ .alignment = 1,
+ .fallback_start = fallback_start,
+ .fallback_end = fallback_end,
+ },
+ [EXECMEM_KPROBES] = {
+ .start = VMALLOC_START,
+ .end = VMALLOC_END,
+ .pgprot = kprobes_prot,
+ .alignment = 1,
+ },
+ [EXECMEM_MODULE_DATA] = {
+ .start = VMALLOC_START,
+ .end = VMALLOC_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c
index b24c19078eb1..3e3af29b4523 100644
--- a/arch/powerpc/mm/mmu_context.c
+++ b/arch/powerpc/mm/mmu_context.c
@@ -21,7 +21,7 @@ static inline void switch_mm_pgdir(struct task_struct *tsk,
#ifdef CONFIG_PPC_BOOK3S_32
tsk->thread.sr0 = mm->context.sr0;
#endif
-#if defined(CONFIG_BOOKE_OR_40x) && defined(CONFIG_PPC_KUAP)
+#if defined(CONFIG_BOOKE) && defined(CONFIG_PPC_KUAP)
tsk->thread.pid = mm->context.id;
#endif
}
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 6949c2c937e7..b2d1eea09761 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -20,9 +20,9 @@
#include <asm/trace.h>
/*
- * On 40x and 8xx, we directly inline tlbia and tlbivax
+ * On 8xx, we directly inline tlbia
*/
-#if defined(CONFIG_40x) || defined(CONFIG_PPC_8xx)
+#ifdef CONFIG_PPC_8xx
static inline void _tlbil_all(void)
{
asm volatile ("sync; tlbia; isync" : : : "memory");
@@ -35,7 +35,7 @@ static inline void _tlbil_pid(unsigned int pid)
}
#define _tlbil_pid_noind(pid) _tlbil_pid(pid)
-#else /* CONFIG_40x || CONFIG_PPC_8xx */
+#else /* CONFIG_PPC_8xx */
extern void _tlbil_all(void);
extern void _tlbil_pid(unsigned int pid);
#ifdef CONFIG_PPC_BOOK3E_64
@@ -43,7 +43,7 @@ extern void _tlbil_pid_noind(unsigned int pid);
#else
#define _tlbil_pid_noind(pid) _tlbil_pid(pid)
#endif
-#endif /* !(CONFIG_40x || CONFIG_PPC_8xx) */
+#endif /* !CONFIG_PPC_8xx */
/*
* On 8xx, we directly inline tlbie, on others, it's extern
diff --git a/arch/powerpc/mm/nohash/40x.c b/arch/powerpc/mm/nohash/40x.c
deleted file mode 100644
index e835e80c09db..000000000000
--- a/arch/powerpc/mm/nohash/40x.c
+++ /dev/null
@@ -1,161 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * This file contains the routines for initializing the MMU
- * on the 4xx series of chips.
- * -- paulus
- *
- * Derived from arch/ppc/mm/init.c:
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
- * and Cort Dougan (PReP) (cort@cs.nmt.edu)
- * Copyright (C) 1996 Paul Mackerras
- *
- * Derived from "arch/i386/mm/init.c"
- * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
- */
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/stddef.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/highmem.h>
-#include <linux/memblock.h>
-
-#include <asm/io.h>
-#include <asm/mmu_context.h>
-#include <asm/mmu.h>
-#include <linux/uaccess.h>
-#include <asm/smp.h>
-#include <asm/bootx.h>
-#include <asm/machdep.h>
-#include <asm/setup.h>
-
-#include <mm/mmu_decl.h>
-
-/*
- * MMU_init_hw does the chip-specific initialization of the MMU hardware.
- */
-void __init MMU_init_hw(void)
-{
- int i;
- unsigned long zpr;
-
- /*
- * The Zone Protection Register (ZPR) defines how protection will
- * be applied to every page which is a member of a given zone.
- * The zone index bits (of ZSEL) in the PTE are used for software
- * indicators. We use the 4 upper bits of virtual address to select
- * the zone. We set all zones above TASK_SIZE to zero, allowing
- * only kernel access as indicated in the PTE. For zones below
- * TASK_SIZE, we set a 01 binary (a value of 10 will not work)
- * to allow user access as indicated in the PTE. This also allows
- * kernel access as indicated in the PTE.
- */
-
- for (i = 0, zpr = 0; i < TASK_SIZE >> 28; i++)
- zpr |= 1 << (30 - i * 2);
-
- mtspr(SPRN_ZPR, zpr);
-
- flush_instruction_cache();
-
- /*
- * Set up the real-mode cache parameters for the exception vector
- * handlers (which are run in real-mode).
- */
-
- mtspr(SPRN_DCWR, 0x00000000); /* All caching is write-back */
-
- /*
- * Cache instruction and data space where the exception
- * vectors and the kernel live in real-mode.
- */
-
- mtspr(SPRN_DCCR, 0xFFFF0000); /* 2GByte of data space at 0x0. */
- mtspr(SPRN_ICCR, 0xFFFF0000); /* 2GByte of instr. space at 0x0. */
-}
-
-#define LARGE_PAGE_SIZE_16M (1<<24)
-#define LARGE_PAGE_SIZE_4M (1<<22)
-
-unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
-{
- unsigned long v, s, mapped;
- phys_addr_t p;
-
- v = KERNELBASE;
- p = 0;
- s = total_lowmem;
-
- if (IS_ENABLED(CONFIG_KFENCE))
- return 0;
-
- if (debug_pagealloc_enabled())
- return 0;
-
- if (strict_kernel_rwx_enabled())
- return 0;
-
- while (s >= LARGE_PAGE_SIZE_16M) {
- pmd_t *pmdp;
- unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_RW;
-
- pmdp = pmd_off_k(v);
- *pmdp++ = __pmd(val);
- *pmdp++ = __pmd(val);
- *pmdp++ = __pmd(val);
- *pmdp++ = __pmd(val);
-
- v += LARGE_PAGE_SIZE_16M;
- p += LARGE_PAGE_SIZE_16M;
- s -= LARGE_PAGE_SIZE_16M;
- }
-
- while (s >= LARGE_PAGE_SIZE_4M) {
- pmd_t *pmdp;
- unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_RW;
-
- pmdp = pmd_off_k(v);
- *pmdp = __pmd(val);
-
- v += LARGE_PAGE_SIZE_4M;
- p += LARGE_PAGE_SIZE_4M;
- s -= LARGE_PAGE_SIZE_4M;
- }
-
- mapped = total_lowmem - s;
-
- /* If the size of RAM is not an exact power of two, we may not
- * have covered RAM in its entirety with 16 and 4 MiB
- * pages. Consequently, restrict the top end of RAM currently
- * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
- * coverage with normal-sized pages (or other reasons) do not
- * attempt to allocate outside the allowed range.
- */
- memblock_set_current_limit(mapped);
-
- return mapped;
-}
-
-void 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);
-
- /* 40x can only access 16MB at the moment (see head_40x.S) */
- memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
-}
diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
index 43d4842bb1c7..388bba0ab3e7 100644
--- a/arch/powerpc/mm/nohash/8xx.c
+++ b/arch/powerpc/mm/nohash/8xx.c
@@ -11,6 +11,7 @@
#include <linux/hugetlb.h>
#include <asm/fixmap.h>
+#include <asm/pgalloc.h>
#include <mm/mmu_decl.h>
@@ -48,20 +49,6 @@ unsigned long p_block_mapped(phys_addr_t pa)
return 0;
}
-static pte_t __init *early_hugepd_alloc_kernel(hugepd_t *pmdp, unsigned long va)
-{
- if (hpd_val(*pmdp) == 0) {
- pte_t *ptep = memblock_alloc(sizeof(pte_basic_t), SZ_4K);
-
- if (!ptep)
- return NULL;
-
- hugepd_populate_kernel((hugepd_t *)pmdp, ptep, PAGE_SHIFT_8M);
- hugepd_populate_kernel((hugepd_t *)pmdp + 1, ptep, PAGE_SHIFT_8M);
- }
- return hugepte_offset(*(hugepd_t *)pmdp, va, PGDIR_SHIFT);
-}
-
static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
pgprot_t prot, int psize, bool new)
{
@@ -75,26 +62,36 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa,
if (WARN_ON(slab_is_available()))
return -EINVAL;
- if (psize == MMU_PAGE_512K)
+ if (psize == MMU_PAGE_512K) {
ptep = early_pte_alloc_kernel(pmdp, va);
- else
- ptep = early_hugepd_alloc_kernel((hugepd_t *)pmdp, va);
+ /* The PTE should never be already present */
+ if (WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
+ return -EINVAL;
+ } else {
+ if (WARN_ON(!pmd_none(*pmdp) || !pmd_none(*(pmdp + 1))))
+ return -EINVAL;
+
+ ptep = early_alloc_pgtable(PTE_FRAG_SIZE);
+ pmd_populate_kernel(&init_mm, pmdp, ptep);
+
+ ptep = early_alloc_pgtable(PTE_FRAG_SIZE);
+ pmd_populate_kernel(&init_mm, pmdp + 1, ptep);
+
+ ptep = (pte_t *)pmdp;
+ }
} else {
if (psize == MMU_PAGE_512K)
ptep = pte_offset_kernel(pmdp, va);
else
- ptep = hugepte_offset(*(hugepd_t *)pmdp, va, PGDIR_SHIFT);
+ ptep = (pte_t *)pmdp;
}
if (WARN_ON(!ptep))
return -ENOMEM;
- /* The PTE should never be already present */
- if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot)))
- return -EINVAL;
-
set_huge_pte_at(&init_mm, va, ptep,
- pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)), psize);
+ pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)),
+ 1UL << mmu_psize_to_shift(psize));
return 0;
}
diff --git a/arch/powerpc/mm/nohash/Makefile b/arch/powerpc/mm/nohash/Makefile
index f3894e79d5f7..cf60c776c883 100644
--- a/arch/powerpc/mm/nohash/Makefile
+++ b/arch/powerpc/mm/nohash/Makefile
@@ -1,10 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-
obj-y += mmu_context.o tlb.o tlb_low.o kup.o
-obj-$(CONFIG_PPC_BOOK3E_64) += tlb_low_64e.o book3e_pgtable.o
-obj-$(CONFIG_40x) += 40x.o
+obj-$(CONFIG_PPC_BOOK3E_64) += tlb_64e.o tlb_low_64e.o book3e_pgtable.o
obj-$(CONFIG_44x) += 44x.o
obj-$(CONFIG_PPC_8xx) += 8xx.o
obj-$(CONFIG_PPC_E500) += e500.o
diff --git a/arch/powerpc/mm/nohash/book3e_pgtable.c b/arch/powerpc/mm/nohash/book3e_pgtable.c
index 1c5e4ecbebeb..ad2a7c26f2a0 100644
--- a/arch/powerpc/mm/nohash/book3e_pgtable.c
+++ b/arch/powerpc/mm/nohash/book3e_pgtable.c
@@ -29,10 +29,10 @@ int __meminit vmemmap_create_mapping(unsigned long start,
_PAGE_KERNEL_RW;
/* PTEs only contain page size encodings up to 32M */
- BUG_ON(mmu_psize_defs[mmu_vmemmap_psize].enc > 0xf);
+ BUG_ON(mmu_psize_defs[mmu_vmemmap_psize].shift - 10 > 0xf);
/* Encode the size in the PTE */
- flags |= mmu_psize_defs[mmu_vmemmap_psize].enc << 8;
+ flags |= (mmu_psize_defs[mmu_vmemmap_psize].shift - 10) << 8;
/* For each PTE for that area, map things. Note that we don't
* increment phys because all PTEs are of the large size and
diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c
index cdff129abb14..5c8d1bb98b3e 100644
--- a/arch/powerpc/mm/nohash/kaslr_booke.c
+++ b/arch/powerpc/mm/nohash/kaslr_booke.c
@@ -376,7 +376,7 @@ notrace void __init kaslr_early_init(void *dt_ptr, phys_addr_t size)
create_kaslr_tlb_entry(1, tlb_virt, tlb_phys);
}
- /* Copy the kernel to it's new location and run */
+ /* Copy the kernel to its new location and run */
memcpy((void *)kernstart_virt_addr, (void *)_stext, kernel_sz);
flush_icache_range(kernstart_virt_addr, kernstart_virt_addr + kernel_sz);
diff --git a/arch/powerpc/mm/nohash/kup.c b/arch/powerpc/mm/nohash/kup.c
index e1f7de2e54ec..c20c4f357fbf 100644
--- a/arch/powerpc/mm/nohash/kup.c
+++ b/arch/powerpc/mm/nohash/kup.c
@@ -15,8 +15,6 @@
void setup_kuap(bool disabled)
{
if (disabled) {
- if (IS_ENABLED(CONFIG_40x))
- disable_kuep = true;
if (smp_processor_id() == boot_cpuid)
cur_cpu_spec->mmu_features &= ~MMU_FTR_KUAP;
return;
diff --git a/arch/powerpc/mm/nohash/mmu_context.c b/arch/powerpc/mm/nohash/mmu_context.c
index ccd5819b1bd9..0b181da40ddb 100644
--- a/arch/powerpc/mm/nohash/mmu_context.c
+++ b/arch/powerpc/mm/nohash/mmu_context.c
@@ -219,9 +219,6 @@ static void set_context(unsigned long id, pgd_t *pgd)
/* sync */
mb();
} else if (kuap_is_disabled()) {
- if (IS_ENABLED(CONFIG_40x))
- mb(); /* sync */
-
mtspr(SPRN_PID, id);
isync();
}
@@ -306,7 +303,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next,
if (IS_ENABLED(CONFIG_BDI_SWITCH))
abatron_pteptrs[1] = next->pgd;
set_context(id, next->pgd);
-#if defined(CONFIG_BOOKE_OR_40x) && defined(CONFIG_PPC_KUAP)
+#if defined(CONFIG_BOOKE) && defined(CONFIG_PPC_KUAP)
tsk->thread.pid = id;
#endif
raw_spin_unlock(&context_lock);
diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c
index 5ffa0af4328a..b653a7be4cb1 100644
--- a/arch/powerpc/mm/nohash/tlb.c
+++ b/arch/powerpc/mm/nohash/tlb.c
@@ -53,37 +53,30 @@
struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
[MMU_PAGE_4K] = {
.shift = 12,
- .enc = BOOK3E_PAGESZ_4K,
},
[MMU_PAGE_2M] = {
.shift = 21,
- .enc = BOOK3E_PAGESZ_2M,
},
[MMU_PAGE_4M] = {
.shift = 22,
- .enc = BOOK3E_PAGESZ_4M,
},
[MMU_PAGE_16M] = {
.shift = 24,
- .enc = BOOK3E_PAGESZ_16M,
},
[MMU_PAGE_64M] = {
.shift = 26,
- .enc = BOOK3E_PAGESZ_64M,
},
[MMU_PAGE_256M] = {
.shift = 28,
- .enc = BOOK3E_PAGESZ_256M,
},
[MMU_PAGE_1G] = {
.shift = 30,
- .enc = BOOK3E_PAGESZ_1GB,
},
};
static inline int mmu_get_tsize(int psize)
{
- return mmu_psize_defs[psize].enc;
+ return mmu_psize_defs[psize].shift - 10;
}
#else
static inline int mmu_get_tsize(int psize)
@@ -110,28 +103,6 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
};
#endif
-/* The variables below are currently only used on 64-bit Book3E
- * though this will probably be made common with other nohash
- * implementations at some point
- */
-#ifdef CONFIG_PPC64
-
-int mmu_pte_psize; /* Page size used for PTE pages */
-int mmu_vmemmap_psize; /* Page size used for the virtual mem map */
-int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */
-unsigned long linear_map_top; /* Top of linear mapping */
-
-
-/*
- * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
- * exceptions. This is used for bolted and e6500 TLB miss handlers which
- * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
- * this is set to zero.
- */
-int extlb_level_exc;
-
-#endif /* CONFIG_PPC64 */
-
#ifdef CONFIG_PPC_E500
/* next_tlbcam_idx is used to round-robin tlbcam entry assignment */
DEFINE_PER_CPU(int, next_tlbcam_idx);
@@ -358,381 +329,7 @@ void tlb_flush(struct mmu_gather *tlb)
flush_tlb_mm(tlb->mm);
}
-/*
- * Below are functions specific to the 64-bit variant of Book3E though that
- * may change in the future
- */
-
-#ifdef CONFIG_PPC64
-
-/*
- * Handling of virtual linear page tables or indirect TLB entries
- * flushing when PTE pages are freed
- */
-void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
-{
- int tsize = mmu_psize_defs[mmu_pte_psize].enc;
-
- if (book3e_htw_mode != PPC_HTW_NONE) {
- unsigned long start = address & PMD_MASK;
- unsigned long end = address + PMD_SIZE;
- unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
-
- /* This isn't the most optimal, ideally we would factor out the
- * while preempt & CPU mask mucking around, or even the IPI but
- * it will do for now
- */
- while (start < end) {
- __flush_tlb_page(tlb->mm, start, tsize, 1);
- start += size;
- }
- } else {
- unsigned long rmask = 0xf000000000000000ul;
- unsigned long rid = (address & rmask) | 0x1000000000000000ul;
- unsigned long vpte = address & ~rmask;
-
- vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
- vpte |= rid;
- __flush_tlb_page(tlb->mm, vpte, tsize, 0);
- }
-}
-
-static void __init setup_page_sizes(void)
-{
- unsigned int tlb0cfg;
- unsigned int tlb0ps;
- unsigned int eptcfg;
- int i, psize;
-
-#ifdef CONFIG_PPC_E500
- unsigned int mmucfg = mfspr(SPRN_MMUCFG);
- int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E);
-
- if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
- unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
- unsigned int min_pg, max_pg;
-
- min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
- max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
-
- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
- struct mmu_psize_def *def;
- unsigned int shift;
-
- def = &mmu_psize_defs[psize];
- shift = def->shift;
-
- if (shift == 0 || shift & 1)
- continue;
-
- /* adjust to be in terms of 4^shift Kb */
- shift = (shift - 10) >> 1;
-
- if ((shift >= min_pg) && (shift <= max_pg))
- def->flags |= MMU_PAGE_SIZE_DIRECT;
- }
-
- goto out;
- }
-
- if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
- u32 tlb1cfg, tlb1ps;
-
- tlb0cfg = mfspr(SPRN_TLB0CFG);
- tlb1cfg = mfspr(SPRN_TLB1CFG);
- tlb1ps = mfspr(SPRN_TLB1PS);
- eptcfg = mfspr(SPRN_EPTCFG);
-
- if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
- book3e_htw_mode = PPC_HTW_E6500;
-
- /*
- * We expect 4K subpage size and unrestricted indirect size.
- * The lack of a restriction on indirect size is a Freescale
- * extension, indicated by PSn = 0 but SPSn != 0.
- */
- if (eptcfg != 2)
- book3e_htw_mode = PPC_HTW_NONE;
-
- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
- struct mmu_psize_def *def = &mmu_psize_defs[psize];
-
- if (!def->shift)
- continue;
-
- if (tlb1ps & (1U << (def->shift - 10))) {
- def->flags |= MMU_PAGE_SIZE_DIRECT;
-
- if (book3e_htw_mode && psize == MMU_PAGE_2M)
- def->flags |= MMU_PAGE_SIZE_INDIRECT;
- }
- }
-
- goto out;
- }
-#endif
-
- tlb0cfg = mfspr(SPRN_TLB0CFG);
- tlb0ps = mfspr(SPRN_TLB0PS);
- eptcfg = mfspr(SPRN_EPTCFG);
-
- /* Look for supported direct sizes */
- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
- struct mmu_psize_def *def = &mmu_psize_defs[psize];
-
- if (tlb0ps & (1U << (def->shift - 10)))
- def->flags |= MMU_PAGE_SIZE_DIRECT;
- }
-
- /* Indirect page sizes supported ? */
- if ((tlb0cfg & TLBnCFG_IND) == 0 ||
- (tlb0cfg & TLBnCFG_PT) == 0)
- goto out;
-
- book3e_htw_mode = PPC_HTW_IBM;
-
- /* Now, we only deal with one IND page size for each
- * direct size. Hopefully all implementations today are
- * unambiguous, but we might want to be careful in the
- * future.
- */
- for (i = 0; i < 3; i++) {
- unsigned int ps, sps;
-
- sps = eptcfg & 0x1f;
- eptcfg >>= 5;
- ps = eptcfg & 0x1f;
- eptcfg >>= 5;
- if (!ps || !sps)
- continue;
- for (psize = 0; psize < MMU_PAGE_COUNT; psize++) {
- struct mmu_psize_def *def = &mmu_psize_defs[psize];
-
- if (ps == (def->shift - 10))
- def->flags |= MMU_PAGE_SIZE_INDIRECT;
- if (sps == (def->shift - 10))
- def->ind = ps + 10;
- }
- }
-
-out:
- /* Cleanup array and print summary */
- pr_info("MMU: Supported page sizes\n");
- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
- struct mmu_psize_def *def = &mmu_psize_defs[psize];
- const char *__page_type_names[] = {
- "unsupported",
- "direct",
- "indirect",
- "direct & indirect"
- };
- if (def->flags == 0) {
- def->shift = 0;
- continue;
- }
- pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10),
- __page_type_names[def->flags & 0x3]);
- }
-}
-
-static void __init setup_mmu_htw(void)
-{
- /*
- * If we want to use HW tablewalk, enable it by patching the TLB miss
- * handlers to branch to the one dedicated to it.
- */
-
- switch (book3e_htw_mode) {
- case PPC_HTW_IBM:
- patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e);
- patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e);
- break;
-#ifdef CONFIG_PPC_E500
- case PPC_HTW_E6500:
- extlb_level_exc = EX_TLB_SIZE;
- patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
- patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
- break;
-#endif
- }
- pr_info("MMU: Book3E HW tablewalk %s\n",
- book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
-}
-
-/*
- * Early initialization of the MMU TLB code
- */
-static void early_init_this_mmu(void)
-{
- unsigned int mas4;
-
- /* Set MAS4 based on page table setting */
-
- mas4 = 0x4 << MAS4_WIMGED_SHIFT;
- switch (book3e_htw_mode) {
- case PPC_HTW_E6500:
- mas4 |= MAS4_INDD;
- mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
- mas4 |= MAS4_TLBSELD(1);
- mmu_pte_psize = MMU_PAGE_2M;
- break;
-
- case PPC_HTW_IBM:
- mas4 |= MAS4_INDD;
- mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT;
- mmu_pte_psize = MMU_PAGE_1M;
- break;
-
- case PPC_HTW_NONE:
- mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
- mmu_pte_psize = mmu_virtual_psize;
- break;
- }
- mtspr(SPRN_MAS4, mas4);
-
-#ifdef CONFIG_PPC_E500
- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
- unsigned int num_cams;
- bool map = true;
-
- /* use a quarter of the TLBCAM for bolted linear map */
- num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
-
- /*
- * Only do the mapping once per core, or else the
- * transient mapping would cause problems.
- */
-#ifdef CONFIG_SMP
- if (hweight32(get_tensr()) > 1)
- map = false;
-#endif
-
- if (map)
- linear_map_top = map_mem_in_cams(linear_map_top,
- num_cams, false, true);
- }
-#endif
-
- /* A sync won't hurt us after mucking around with
- * the MMU configuration
- */
- mb();
-}
-
-static void __init early_init_mmu_global(void)
-{
- /* XXX This should be decided at runtime based on supported
- * page sizes in the TLB, but for now let's assume 16M is
- * always there and a good fit (which it probably is)
- *
- * Freescale booke only supports 4K pages in TLB0, so use that.
- */
- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
- mmu_vmemmap_psize = MMU_PAGE_4K;
- else
- mmu_vmemmap_psize = MMU_PAGE_16M;
-
- /* XXX This code only checks for TLB 0 capabilities and doesn't
- * check what page size combos are supported by the HW. It
- * also doesn't handle the case where a separate array holds
- * the IND entries from the array loaded by the PT.
- */
- /* Look for supported page sizes */
- setup_page_sizes();
-
- /* Look for HW tablewalk support */
- setup_mmu_htw();
-
-#ifdef CONFIG_PPC_E500
- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
- if (book3e_htw_mode == PPC_HTW_NONE) {
- extlb_level_exc = EX_TLB_SIZE;
- patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
- patch_exception(0x1e0,
- exc_instruction_tlb_miss_bolted_book3e);
- }
- }
-#endif
-
- /* Set the global containing the top of the linear mapping
- * for use by the TLB miss code
- */
- linear_map_top = memblock_end_of_DRAM();
-
- ioremap_bot = IOREMAP_BASE;
-}
-
-static void __init early_mmu_set_memory_limit(void)
-{
-#ifdef CONFIG_PPC_E500
- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
- /*
- * Limit memory so we dont have linear faults.
- * Unlike memblock_set_current_limit, which limits
- * memory available during early boot, this permanently
- * reduces the memory available to Linux. We need to
- * do this because highmem is not supported on 64-bit.
- */
- memblock_enforce_memory_limit(linear_map_top);
- }
-#endif
-
- memblock_set_current_limit(linear_map_top);
-}
-
-/* boot cpu only */
-void __init early_init_mmu(void)
-{
- early_init_mmu_global();
- early_init_this_mmu();
- early_mmu_set_memory_limit();
-}
-
-void early_init_mmu_secondary(void)
-{
- early_init_this_mmu();
-}
-
-void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
-{
- /* On non-FSL Embedded 64-bit, we adjust the RMA size to match
- * the bolted TLB entry. We know for now that only 1G
- * entries are supported though that may eventually
- * change.
- *
- * on FSL Embedded 64-bit, usually all RAM is bolted, but with
- * unusual memory sizes it's possible for some RAM to not be mapped
- * (such RAM is not used at all by Linux, since we don't support
- * highmem on 64-bit). We limit ppc64_rma_size to what would be
- * mappable if this memblock is the only one. Additional memblocks
- * can only increase, not decrease, the amount that ends up getting
- * mapped. We still limit max to 1G even if we'll eventually map
- * more. This is due to what the early init code is set up to do.
- *
- * We crop it to the size of the first MEMBLOCK to
- * avoid going over total available memory just in case...
- */
-#ifdef CONFIG_PPC_E500
- if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
- unsigned long linear_sz;
- unsigned int num_cams;
-
- /* use a quarter of the TLBCAM for bolted linear map */
- num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
-
- linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
- true, true);
-
- ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
- } else
-#endif
- ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
-
- /* Finally limit subsequent allocations */
- memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
-}
-#else /* ! CONFIG_PPC64 */
+#ifndef CONFIG_PPC64
void __init early_init_mmu(void)
{
unsigned long root = of_get_flat_dt_root();
diff --git a/arch/powerpc/mm/nohash/tlb_64e.c b/arch/powerpc/mm/nohash/tlb_64e.c
new file mode 100644
index 000000000000..113edf76d3ce
--- /dev/null
+++ b/arch/powerpc/mm/nohash/tlb_64e.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2008,2009 Ben Herrenschmidt <benh@kernel.crashing.org>
+ * IBM Corp.
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/memblock.h>
+
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/tlb.h>
+#include <asm/code-patching.h>
+#include <asm/cputhreads.h>
+
+#include <mm/mmu_decl.h>
+
+/* The variables below are currently only used on 64-bit Book3E
+ * though this will probably be made common with other nohash
+ * implementations at some point
+ */
+int mmu_pte_psize; /* Page size used for PTE pages */
+int mmu_vmemmap_psize; /* Page size used for the virtual mem map */
+int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */
+unsigned long linear_map_top; /* Top of linear mapping */
+
+
+/*
+ * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
+ * exceptions. This is used for bolted and e6500 TLB miss handlers which
+ * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
+ * this is set to zero.
+ */
+int extlb_level_exc;
+
+/*
+ * Handling of virtual linear page tables or indirect TLB entries
+ * flushing when PTE pages are freed
+ */
+void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
+{
+ int tsize = mmu_psize_defs[mmu_pte_psize].shift - 10;
+
+ if (book3e_htw_mode != PPC_HTW_NONE) {
+ unsigned long start = address & PMD_MASK;
+ unsigned long end = address + PMD_SIZE;
+ unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
+
+ /* This isn't the most optimal, ideally we would factor out the
+ * while preempt & CPU mask mucking around, or even the IPI but
+ * it will do for now
+ */
+ while (start < end) {
+ __flush_tlb_page(tlb->mm, start, tsize, 1);
+ start += size;
+ }
+ } else {
+ unsigned long rmask = 0xf000000000000000ul;
+ unsigned long rid = (address & rmask) | 0x1000000000000000ul;
+ unsigned long vpte = address & ~rmask;
+
+ vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
+ vpte |= rid;
+ __flush_tlb_page(tlb->mm, vpte, tsize, 0);
+ }
+}
+
+static void __init setup_page_sizes(void)
+{
+ unsigned int tlb0cfg;
+ unsigned int eptcfg;
+ int psize;
+
+ unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+
+ if ((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
+ unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
+ unsigned int min_pg, max_pg;
+
+ min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+ max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
+
+ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+ struct mmu_psize_def *def;
+ unsigned int shift;
+
+ def = &mmu_psize_defs[psize];
+ shift = def->shift;
+
+ if (shift == 0 || shift & 1)
+ continue;
+
+ /* adjust to be in terms of 4^shift Kb */
+ shift = (shift - 10) >> 1;
+
+ if ((shift >= min_pg) && (shift <= max_pg))
+ def->flags |= MMU_PAGE_SIZE_DIRECT;
+ }
+
+ goto out;
+ }
+
+ if ((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
+ u32 tlb1cfg, tlb1ps;
+
+ tlb0cfg = mfspr(SPRN_TLB0CFG);
+ tlb1cfg = mfspr(SPRN_TLB1CFG);
+ tlb1ps = mfspr(SPRN_TLB1PS);
+ eptcfg = mfspr(SPRN_EPTCFG);
+
+ if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
+ book3e_htw_mode = PPC_HTW_E6500;
+
+ /*
+ * We expect 4K subpage size and unrestricted indirect size.
+ * The lack of a restriction on indirect size is a Freescale
+ * extension, indicated by PSn = 0 but SPSn != 0.
+ */
+ if (eptcfg != 2)
+ book3e_htw_mode = PPC_HTW_NONE;
+
+ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+ struct mmu_psize_def *def = &mmu_psize_defs[psize];
+
+ if (!def->shift)
+ continue;
+
+ if (tlb1ps & (1U << (def->shift - 10))) {
+ def->flags |= MMU_PAGE_SIZE_DIRECT;
+
+ if (book3e_htw_mode && psize == MMU_PAGE_2M)
+ def->flags |= MMU_PAGE_SIZE_INDIRECT;
+ }
+ }
+
+ goto out;
+ }
+out:
+ /* Cleanup array and print summary */
+ pr_info("MMU: Supported page sizes\n");
+ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+ struct mmu_psize_def *def = &mmu_psize_defs[psize];
+ const char *__page_type_names[] = {
+ "unsupported",
+ "direct",
+ "indirect",
+ "direct & indirect"
+ };
+ if (def->flags == 0) {
+ def->shift = 0;
+ continue;
+ }
+ pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10),
+ __page_type_names[def->flags & 0x3]);
+ }
+}
+
+/*
+ * Early initialization of the MMU TLB code
+ */
+static void early_init_this_mmu(void)
+{
+ unsigned int mas4;
+
+ /* Set MAS4 based on page table setting */
+
+ mas4 = 0x4 << MAS4_WIMGED_SHIFT;
+ switch (book3e_htw_mode) {
+ case PPC_HTW_E6500:
+ mas4 |= MAS4_INDD;
+ mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
+ mas4 |= MAS4_TLBSELD(1);
+ mmu_pte_psize = MMU_PAGE_2M;
+ break;
+
+ case PPC_HTW_NONE:
+ mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
+ mmu_pte_psize = mmu_virtual_psize;
+ break;
+ }
+ mtspr(SPRN_MAS4, mas4);
+
+ unsigned int num_cams;
+ bool map = true;
+
+ /* use a quarter of the TLBCAM for bolted linear map */
+ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+
+ /*
+ * Only do the mapping once per core, or else the
+ * transient mapping would cause problems.
+ */
+#ifdef CONFIG_SMP
+ if (hweight32(get_tensr()) > 1)
+ map = false;
+#endif
+
+ if (map)
+ linear_map_top = map_mem_in_cams(linear_map_top,
+ num_cams, false, true);
+
+ /* A sync won't hurt us after mucking around with
+ * the MMU configuration
+ */
+ mb();
+}
+
+static void __init early_init_mmu_global(void)
+{
+ /*
+ * Freescale booke only supports 4K pages in TLB0, so use that.
+ */
+ mmu_vmemmap_psize = MMU_PAGE_4K;
+
+ /* XXX This code only checks for TLB 0 capabilities and doesn't
+ * check what page size combos are supported by the HW. It
+ * also doesn't handle the case where a separate array holds
+ * the IND entries from the array loaded by the PT.
+ */
+ /* Look for supported page sizes */
+ setup_page_sizes();
+
+ /*
+ * If we want to use HW tablewalk, enable it by patching the TLB miss
+ * handlers to branch to the one dedicated to it.
+ */
+ extlb_level_exc = EX_TLB_SIZE;
+ switch (book3e_htw_mode) {
+ case PPC_HTW_E6500:
+ patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
+ patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
+ break;
+ }
+
+ pr_info("MMU: Book3E HW tablewalk %s\n",
+ book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
+
+ /* Set the global containing the top of the linear mapping
+ * for use by the TLB miss code
+ */
+ linear_map_top = memblock_end_of_DRAM();
+
+ ioremap_bot = IOREMAP_BASE;
+}
+
+static void __init early_mmu_set_memory_limit(void)
+{
+ /*
+ * Limit memory so we dont have linear faults.
+ * Unlike memblock_set_current_limit, which limits
+ * memory available during early boot, this permanently
+ * reduces the memory available to Linux. We need to
+ * do this because highmem is not supported on 64-bit.
+ */
+ memblock_enforce_memory_limit(linear_map_top);
+
+ memblock_set_current_limit(linear_map_top);
+}
+
+/* boot cpu only */
+void __init early_init_mmu(void)
+{
+ early_init_mmu_global();
+ early_init_this_mmu();
+ early_mmu_set_memory_limit();
+}
+
+void early_init_mmu_secondary(void)
+{
+ early_init_this_mmu();
+}
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /*
+ * On FSL Embedded 64-bit, usually all RAM is bolted, but with
+ * unusual memory sizes it's possible for some RAM to not be mapped
+ * (such RAM is not used at all by Linux, since we don't support
+ * highmem on 64-bit). We limit ppc64_rma_size to what would be
+ * mappable if this memblock is the only one. Additional memblocks
+ * can only increase, not decrease, the amount that ends up getting
+ * mapped. We still limit max to 1G even if we'll eventually map
+ * more. This is due to what the early init code is set up to do.
+ *
+ * We crop it to the size of the first MEMBLOCK to
+ * avoid going over total available memory just in case...
+ */
+ unsigned long linear_sz;
+ unsigned int num_cams;
+
+ /* use a quarter of the TLBCAM for bolted linear map */
+ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+
+ linear_sz = map_mem_in_cams(first_memblock_size, num_cams, true, true);
+ ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
+
+ /* Finally limit subsequent allocations */
+ memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
+}
diff --git a/arch/powerpc/mm/nohash/tlb_low.S b/arch/powerpc/mm/nohash/tlb_low.S
index e1199608ff4d..c4d296e73731 100644
--- a/arch/powerpc/mm/nohash/tlb_low.S
+++ b/arch/powerpc/mm/nohash/tlb_low.S
@@ -32,32 +32,7 @@
#include <asm/asm-compat.h>
#include <asm/feature-fixups.h>
-#if defined(CONFIG_40x)
-
-/*
- * 40x implementation needs only tlbil_va
- */
-_GLOBAL(__tlbil_va)
- /* We run the search with interrupts disabled because we have to change
- * the PID and I don't want to preempt when that happens.
- */
- mfmsr r5
- mfspr r6,SPRN_PID
- wrteei 0
- mtspr SPRN_PID,r4
- tlbsx. r3, 0, r3
- mtspr SPRN_PID,r6
- wrtee r5
- bne 1f
- sync
- /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is
- * clear. Since 25 is the V bit in the TLB_TAG, loading this value
- * will invalidate the TLB entry. */
- tlbwe r3, r3, TLB_TAG
- isync
-1: blr
-
-#elif defined(CONFIG_PPC_8xx)
+#if defined(CONFIG_PPC_8xx)
/*
* Nothing to do for 8xx, everything is inline
diff --git a/arch/powerpc/mm/nohash/tlb_low_64e.S b/arch/powerpc/mm/nohash/tlb_low_64e.S
index 7e0b8fe1c279..de568297d5c5 100644
--- a/arch/powerpc/mm/nohash/tlb_low_64e.S
+++ b/arch/powerpc/mm/nohash/tlb_low_64e.S
@@ -450,11 +450,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SMT)
tlb_miss_huge_e6500:
beq tlb_miss_fault_e6500
- li r10,1
- andi. r15,r14,HUGEPD_SHIFT_MASK@l /* r15 = psize */
- rldimi r14,r10,63,0 /* Set PD_HUGE */
- xor r14,r14,r15 /* Clear size bits */
- ldx r14,0,r14
+ rlwinm r15,r14,32-_PAGE_PSIZE_SHIFT,0x1e
/*
* Now we build the MAS for a huge page.
@@ -465,7 +461,6 @@ tlb_miss_huge_e6500:
* MAS 2,3+7: Needs to be redone similar to non-tablewalk handler
*/
- subi r15,r15,10 /* Convert psize to tsize */
mfspr r10,SPRN_MAS1
rlwinm r10,r10,0,~MAS1_IND
rlwimi r10,r15,MAS1_TSIZE_SHIFT,MAS1_TSIZE_MASK
@@ -511,232 +506,6 @@ itlb_miss_fault_e6500:
tlb_epilog_bolted
b exc_instruction_storage_book3e
-/**********************************************************************
- * *
- * TLB miss handling for Book3E with TLB reservation and HES support *
- * *
- **********************************************************************/
-
-
-/* Data TLB miss */
- START_EXCEPTION(data_tlb_miss)
- TLB_MISS_PROLOG
-
- /* Now we handle the fault proper. We only save DEAR in normal
- * fault case since that's the only interesting values here.
- * We could probably also optimize by not saving SRR0/1 in the
- * linear mapping case but I'll leave that for later
- */
- mfspr r14,SPRN_ESR
- mfspr r16,SPRN_DEAR /* get faulting address */
- srdi r15,r16,44 /* get region */
- xoris r15,r15,0xc
- cmpldi cr0,r15,0 /* linear mapping ? */
- beq tlb_load_linear /* yes -> go to linear map load */
- cmpldi cr1,r15,1 /* vmalloc mapping ? */
-
- /* The page tables are mapped virtually linear. At this point, though,
- * we don't know whether we are trying to fault in a first level
- * virtual address or a virtual page table address. We can get that
- * from bit 0x1 of the region ID which we have set for a page table
- */
- andis. r10,r15,0x1
- bne- virt_page_table_tlb_miss
-
- std r14,EX_TLB_ESR(r12); /* save ESR */
- std r16,EX_TLB_DEAR(r12); /* save DEAR */
-
- /* We need _PAGE_PRESENT and _PAGE_ACCESSED set */
- li r11,_PAGE_PRESENT
- oris r11,r11,_PAGE_ACCESSED@h
-
- /* We do the user/kernel test for the PID here along with the RW test
- */
- srdi. r15,r16,60 /* Check for user region */
-
- /* We pre-test some combination of permissions to avoid double
- * faults:
- *
- * We move the ESR:ST bit into the position of _PAGE_BAP_SW in the PTE
- * ESR_ST is 0x00800000
- * _PAGE_BAP_SW is 0x00000010
- * So the shift is >> 19. This tests for supervisor writeability.
- * If the page happens to be supervisor writeable and not user
- * writeable, we will take a new fault later, but that should be
- * a rare enough case.
- *
- * We also move ESR_ST in _PAGE_DIRTY position
- * _PAGE_DIRTY is 0x00001000 so the shift is >> 11
- *
- * MAS1 is preset for all we need except for TID that needs to
- * be cleared for kernel translations
- */
- rlwimi r11,r14,32-19,27,27
- rlwimi r11,r14,32-16,19,19
- beq normal_tlb_miss_user
- /* XXX replace the RMW cycles with immediate loads + writes */
-1: mfspr r10,SPRN_MAS1
- rlwinm r10,r10,0,16,1 /* Clear TID */
- mtspr SPRN_MAS1,r10
- beq+ cr1,normal_tlb_miss
-
- /* We got a crappy address, just fault with whatever DEAR and ESR
- * are here
- */
- TLB_MISS_EPILOG_ERROR
- b exc_data_storage_book3e
-
-/* Instruction TLB miss */
- START_EXCEPTION(instruction_tlb_miss)
- TLB_MISS_PROLOG
-
- /* If we take a recursive fault, the second level handler may need
- * to know whether we are handling a data or instruction fault in
- * order to get to the right store fault handler. We provide that
- * info by writing a crazy value in ESR in our exception frame
- */
- li r14,-1 /* store to exception frame is done later */
-
- /* Now we handle the fault proper. We only save DEAR in the non
- * linear mapping case since we know the linear mapping case will
- * not re-enter. We could indeed optimize and also not save SRR0/1
- * in the linear mapping case but I'll leave that for later
- *
- * Faulting address is SRR0 which is already in r16
- */
- srdi r15,r16,44 /* get region */
- xoris r15,r15,0xc
- cmpldi cr0,r15,0 /* linear mapping ? */
- beq tlb_load_linear /* yes -> go to linear map load */
- cmpldi cr1,r15,1 /* vmalloc mapping ? */
-
- /* We do the user/kernel test for the PID here along with the RW test
- */
- li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */
- oris r11,r11,_PAGE_ACCESSED@h
-
- srdi. r15,r16,60 /* Check for user region */
- std r14,EX_TLB_ESR(r12) /* write crazy -1 to frame */
- beq normal_tlb_miss_user
-
- li r11,_PAGE_PRESENT|_PAGE_BAP_SX /* Base perm */
- oris r11,r11,_PAGE_ACCESSED@h
- /* XXX replace the RMW cycles with immediate loads + writes */
- mfspr r10,SPRN_MAS1
- rlwinm r10,r10,0,16,1 /* Clear TID */
- mtspr SPRN_MAS1,r10
- beq+ cr1,normal_tlb_miss
-
- /* We got a crappy address, just fault */
- TLB_MISS_EPILOG_ERROR
- b exc_instruction_storage_book3e
-
-/*
- * This is the guts of the first-level TLB miss handler for direct
- * misses. We are entered with:
- *
- * r16 = faulting address
- * r15 = region ID
- * r14 = crap (free to use)
- * r13 = PACA
- * r12 = TLB exception frame in PACA
- * r11 = PTE permission mask
- * r10 = crap (free to use)
- */
-normal_tlb_miss_user:
-#ifdef CONFIG_PPC_KUAP
- mfspr r14,SPRN_MAS1
- rlwinm. r14,r14,0,0x3fff0000
- beq- normal_tlb_miss_access_fault /* KUAP fault */
-#endif
-normal_tlb_miss:
- /* So we first construct the page table address. We do that by
- * shifting the bottom of the address (not the region ID) by
- * PAGE_SHIFT-3, clearing the bottom 3 bits (get a PTE ptr) and
- * or'ing the fourth high bit.
- *
- * NOTE: For 64K pages, we do things slightly differently in
- * order to handle the weird page table format used by linux
- */
- srdi r15,r16,44
- oris r10,r15,0x1
- rldicl r14,r16,64-(PAGE_SHIFT-3),PAGE_SHIFT-3+4
- sldi r15,r10,44
- clrrdi r14,r14,19
- or r10,r15,r14
-
- ld r14,0(r10)
-
-finish_normal_tlb_miss:
- /* Check if required permissions are met */
- andc. r15,r11,r14
- bne- normal_tlb_miss_access_fault
-
- /* Now we build the MAS:
- *
- * MAS 0 : Fully setup with defaults in MAS4 and TLBnCFG
- * MAS 1 : Almost fully setup
- * - PID already updated by caller if necessary
- * - TSIZE need change if !base page size, not
- * yet implemented for now
- * MAS 2 : Defaults not useful, need to be redone
- * MAS 3+7 : Needs to be done
- *
- * TODO: mix up code below for better scheduling
- */
- clrrdi r10,r16,12 /* Clear low crap in EA */
- rlwimi r10,r14,32-19,27,31 /* Insert WIMGE */
- mtspr SPRN_MAS2,r10
-
- /* Check page size, if not standard, update MAS1 */
- rldicl r10,r14,64-8,64-8
- cmpldi cr0,r10,BOOK3E_PAGESZ_4K
- beq- 1f
- mfspr r11,SPRN_MAS1
- rlwimi r11,r14,31,21,24
- rlwinm r11,r11,0,21,19
- mtspr SPRN_MAS1,r11
-1:
- /* Move RPN in position */
- rldicr r11,r14,64-(PTE_RPN_SHIFT-PAGE_SHIFT),63-PAGE_SHIFT
- clrldi r15,r11,12 /* Clear crap at the top */
- rlwimi r15,r14,32-8,22,25 /* Move in U bits */
- rlwimi r15,r14,32-2,26,31 /* Move in BAP bits */
-
- /* Mask out SW and UW if !DIRTY (XXX optimize this !) */
- andi. r11,r14,_PAGE_DIRTY
- bne 1f
- li r11,MAS3_SW|MAS3_UW
- andc r15,r15,r11
-1:
- srdi r16,r15,32
- mtspr SPRN_MAS3,r15
- mtspr SPRN_MAS7,r16
-
- tlbwe
-
-normal_tlb_miss_done:
- /* We don't bother with restoring DEAR or ESR since we know we are
- * level 0 and just going back to userland. They are only needed
- * if you are going to take an access fault
- */
- TLB_MISS_EPILOG_SUCCESS
- rfi
-
-normal_tlb_miss_access_fault:
- /* We need to check if it was an instruction miss */
- andi. r10,r11,_PAGE_BAP_UX
- bne 1f
- ld r14,EX_TLB_DEAR(r12)
- ld r15,EX_TLB_ESR(r12)
- mtspr SPRN_DEAR,r14
- mtspr SPRN_ESR,r15
- TLB_MISS_EPILOG_ERROR
- b exc_data_storage_book3e
-1: TLB_MISS_EPILOG_ERROR
- b exc_instruction_storage_book3e
-
-
/*
* This is the guts of the second-level TLB miss handler for direct
* misses. We are entered with:
@@ -893,201 +662,6 @@ virt_page_table_tlb_miss_whacko_fault:
TLB_MISS_EPILOG_ERROR
b exc_data_storage_book3e
-
-/**************************************************************
- * *
- * TLB miss handling for Book3E with hw page table support *
- * *
- **************************************************************/
-
-
-/* Data TLB miss */
- START_EXCEPTION(data_tlb_miss_htw)
- TLB_MISS_PROLOG
-
- /* Now we handle the fault proper. We only save DEAR in normal
- * fault case since that's the only interesting values here.
- * We could probably also optimize by not saving SRR0/1 in the
- * linear mapping case but I'll leave that for later
- */
- mfspr r14,SPRN_ESR
- mfspr r16,SPRN_DEAR /* get faulting address */
- srdi r11,r16,44 /* get region */
- xoris r11,r11,0xc
- cmpldi cr0,r11,0 /* linear mapping ? */
- beq tlb_load_linear /* yes -> go to linear map load */
- cmpldi cr1,r11,1 /* vmalloc mapping ? */
-
- /* We do the user/kernel test for the PID here along with the RW test
- */
- srdi. r11,r16,60 /* Check for user region */
- ld r15,PACAPGD(r13) /* Load user pgdir */
- beq htw_tlb_miss
-
- /* XXX replace the RMW cycles with immediate loads + writes */
-1: mfspr r10,SPRN_MAS1
- rlwinm r10,r10,0,16,1 /* Clear TID */
- mtspr SPRN_MAS1,r10
- ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */
- beq+ cr1,htw_tlb_miss
-
- /* We got a crappy address, just fault with whatever DEAR and ESR
- * are here
- */
- TLB_MISS_EPILOG_ERROR
- b exc_data_storage_book3e
-
-/* Instruction TLB miss */
- START_EXCEPTION(instruction_tlb_miss_htw)
- TLB_MISS_PROLOG
-
- /* If we take a recursive fault, the second level handler may need
- * to know whether we are handling a data or instruction fault in
- * order to get to the right store fault handler. We provide that
- * info by keeping a crazy value for ESR in r14
- */
- li r14,-1 /* store to exception frame is done later */
-
- /* Now we handle the fault proper. We only save DEAR in the non
- * linear mapping case since we know the linear mapping case will
- * not re-enter. We could indeed optimize and also not save SRR0/1
- * in the linear mapping case but I'll leave that for later
- *
- * Faulting address is SRR0 which is already in r16
- */
- srdi r11,r16,44 /* get region */
- xoris r11,r11,0xc
- cmpldi cr0,r11,0 /* linear mapping ? */
- beq tlb_load_linear /* yes -> go to linear map load */
- cmpldi cr1,r11,1 /* vmalloc mapping ? */
-
- /* We do the user/kernel test for the PID here along with the RW test
- */
- srdi. r11,r16,60 /* Check for user region */
- ld r15,PACAPGD(r13) /* Load user pgdir */
- beq htw_tlb_miss
-
- /* XXX replace the RMW cycles with immediate loads + writes */
-1: mfspr r10,SPRN_MAS1
- rlwinm r10,r10,0,16,1 /* Clear TID */
- mtspr SPRN_MAS1,r10
- ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */
- beq+ htw_tlb_miss
-
- /* We got a crappy address, just fault */
- TLB_MISS_EPILOG_ERROR
- b exc_instruction_storage_book3e
-
-
-/*
- * This is the guts of the second-level TLB miss handler for direct
- * misses. We are entered with:
- *
- * r16 = virtual page table faulting address
- * r15 = PGD pointer
- * r14 = ESR
- * r13 = PACA
- * r12 = TLB exception frame in PACA
- * r11 = crap (free to use)
- * r10 = crap (free to use)
- *
- * It can be re-entered by the linear mapping miss handler. However, to
- * avoid too much complication, it will save/restore things for us
- */
-htw_tlb_miss:
-#ifdef CONFIG_PPC_KUAP
- mfspr r10,SPRN_MAS1
- rlwinm. r10,r10,0,0x3fff0000
- beq- htw_tlb_miss_fault /* KUAP fault */
-#endif
- /* Search if we already have a TLB entry for that virtual address, and
- * if we do, bail out.
- *
- * MAS1:IND should be already set based on MAS4
- */
- PPC_TLBSRX_DOT(0,R16)
- beq htw_tlb_miss_done
-
- /* Now, we need to walk the page tables. First check if we are in
- * range.
- */
- rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4
- bne- htw_tlb_miss_fault
-
- /* Get the PGD pointer */
- cmpldi cr0,r15,0
- beq- htw_tlb_miss_fault
-
- /* Get to PGD entry */
- rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3
- clrrdi r10,r11,3
- ldx r15,r10,r15
- cmpdi cr0,r15,0
- bge htw_tlb_miss_fault
-
- /* Get to PUD entry */
- rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
- clrrdi r10,r11,3
- ldx r15,r10,r15
- cmpdi cr0,r15,0
- bge htw_tlb_miss_fault
-
- /* Get to PMD entry */
- rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
- clrrdi r10,r11,3
- ldx r15,r10,r15
- cmpdi cr0,r15,0
- bge htw_tlb_miss_fault
-
- /* Ok, we're all right, we can now create an indirect entry for
- * a 1M or 256M page.
- *
- * The last trick is now that because we use "half" pages for
- * the HTW (1M IND is 2K and 256M IND is 32K) we need to account
- * for an added LSB bit to the RPN. For 64K pages, there is no
- * problem as we already use 32K arrays (half PTE pages), but for
- * 4K page we need to extract a bit from the virtual address and
- * insert it into the "PA52" bit of the RPN.
- */
- rlwimi r15,r16,32-9,20,20
- /* Now we build the MAS:
- *
- * MAS 0 : Fully setup with defaults in MAS4 and TLBnCFG
- * MAS 1 : Almost fully setup
- * - PID already updated by caller if necessary
- * - TSIZE for now is base ind page size always
- * MAS 2 : Use defaults
- * MAS 3+7 : Needs to be done
- */
- ori r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
-
- srdi r16,r10,32
- mtspr SPRN_MAS3,r10
- mtspr SPRN_MAS7,r16
-
- tlbwe
-
-htw_tlb_miss_done:
- /* We don't bother with restoring DEAR or ESR since we know we are
- * level 0 and just going back to userland. They are only needed
- * if you are going to take an access fault
- */
- TLB_MISS_EPILOG_SUCCESS
- rfi
-
-htw_tlb_miss_fault:
- /* We need to check if it was an instruction miss. We know this
- * though because r14 would contain -1
- */
- cmpdi cr0,r14,-1
- beq 1f
- mtspr SPRN_DEAR,r16
- mtspr SPRN_ESR,r14
- TLB_MISS_EPILOG_ERROR
- b exc_data_storage_book3e
-1: TLB_MISS_EPILOG_ERROR
- b exc_instruction_storage_book3e
-
/*
* This is the guts of "any" level TLB miss handler for kernel linear
* mapping misses. We are entered with:
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index a490724e84ad..aa89899f0c1a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -896,7 +896,7 @@ static int __init numa_setup_drmem_lmb(struct drmem_lmb *lmb,
static int __init parse_numa_properties(void)
{
- struct device_node *memory;
+ struct device_node *memory, *pci;
int default_nid = 0;
unsigned long i;
const __be32 *associativity;
@@ -1010,6 +1010,18 @@ new_range:
goto new_range;
}
+ for_each_node_by_name(pci, "pci") {
+ int nid = NUMA_NO_NODE;
+
+ associativity = of_get_associativity(pci);
+ if (associativity) {
+ nid = associativity_to_nid(associativity);
+ initialize_form1_numa_distance(associativity);
+ }
+ if (likely(nid >= 0) && !node_online(nid))
+ node_set_online(nid);
+ }
+
/*
* Now do the same thing for each MEMBLOCK listed in the
* ibm,dynamic-memory property in the
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 9e7ba9c3851f..ab0656115424 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -297,11 +297,8 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
}
#if defined(CONFIG_PPC_8xx)
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
- pte_t pte, unsigned long sz)
+static void __set_huge_pte_at(pmd_t *pmd, pte_t *ptep, pte_basic_t val)
{
- pmd_t *pmd = pmd_off(mm, addr);
- pte_basic_t val;
pte_basic_t *entry = (pte_basic_t *)ptep;
int num, i;
@@ -311,15 +308,60 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
*/
VM_WARN_ON(pte_hw_valid(*ptep) && !pte_protnone(*ptep));
- pte = set_pte_filter(pte, addr);
-
- 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;
}
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte, unsigned long sz)
+{
+ pmd_t *pmdp = pmd_off(mm, addr);
+
+ pte = set_pte_filter(pte, addr);
+
+ if (sz == SZ_8M) { /* Flag both PMD entries as 8M and fill both page tables */
+ *pmdp = __pmd(pmd_val(*pmdp) | _PMD_PAGE_8M);
+ *(pmdp + 1) = __pmd(pmd_val(*(pmdp + 1)) | _PMD_PAGE_8M);
+
+ __set_huge_pte_at(pmdp, pte_offset_kernel(pmdp, 0), pte_val(pte));
+ __set_huge_pte_at(pmdp, pte_offset_kernel(pmdp + 1, 0), pte_val(pte) + SZ_4M);
+ } else {
+ __set_huge_pte_at(pmdp, ptep, pte_val(pte));
+ }
+}
+#else
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte, unsigned long sz)
+{
+ unsigned long pdsize;
+ int i;
+
+ pte = set_pte_filter(pte, addr);
+
+ /*
+ * Make sure hardware valid bit is not set. We don't do
+ * tlb flush for this update.
+ */
+ VM_WARN_ON(pte_hw_valid(*ptep) && !pte_protnone(*ptep));
+
+ if (sz < PMD_SIZE)
+ pdsize = PAGE_SIZE;
+ else if (sz < PUD_SIZE)
+ pdsize = PMD_SIZE;
+ else if (sz < P4D_SIZE)
+ pdsize = PUD_SIZE;
+ else if (sz < PGDIR_SIZE)
+ pdsize = P4D_SIZE;
+ else
+ pdsize = PGDIR_SIZE;
+
+ for (i = 0; i < sz / pdsize; i++, ptep++, addr += pdsize) {
+ __set_pte_at(mm, addr, ptep, pte, 0);
+ pte = __pte(pte_val(pte) + ((unsigned long long)pdsize / PAGE_SIZE << PFN_PTE_SHIFT));
+ }
+}
#endif
#endif /* CONFIG_HUGETLB_PAGE */
@@ -367,11 +409,10 @@ unsigned long vmalloc_to_phys(void *va)
EXPORT_SYMBOL_GPL(vmalloc_to_phys);
/*
- * We have 4 cases for pgds and pmds:
+ * We have 3 cases for pgds and pmds:
* (1) invalid (all zeroes)
* (2) pointer to next table, as normal; bottom 6 bits == 0
* (3) leaf pte for huge page _PAGE_PTE set
- * (4) hugepd pointer, _PAGE_PTE = 0 and bits [2..6] indicate size of table
*
* So long as we atomically load page table pointers we are safe against teardown,
* we can follow the address down to the page and take a ref on it.
@@ -382,11 +423,12 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
bool *is_thp, unsigned *hpage_shift)
{
pgd_t *pgdp;
+#ifdef CONFIG_PPC64
p4d_t p4d, *p4dp;
pud_t pud, *pudp;
+#endif
pmd_t pmd, *pmdp;
pte_t *ret_pte;
- hugepd_t *hpdp = NULL;
unsigned pdshift;
if (hpage_shift)
@@ -401,8 +443,12 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
* page fault or a page unmap. The return pte_t * is still not
* stable. So should be checked there for above conditions.
* Top level is an exception because it is folded into p4d.
+ *
+ * On PPC32, P4D/PUD/PMD are folded into PGD so go straight to
+ * PMD level.
*/
pgdp = pgdir + pgd_index(ea);
+#ifdef CONFIG_PPC64
p4dp = p4d_offset(pgdp, ea);
p4d = READ_ONCE(*p4dp);
pdshift = P4D_SHIFT;
@@ -415,11 +461,6 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
goto out;
}
- if (is_hugepd(__hugepd(p4d_val(p4d)))) {
- hpdp = (hugepd_t *)&p4d;
- goto out_huge;
- }
-
/*
* Even if we end up with an unmap, the pgtable will not
* be freed, because we do an rcu free and here we are
@@ -437,13 +478,11 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
goto out;
}
- if (is_hugepd(__hugepd(pud_val(pud)))) {
- hpdp = (hugepd_t *)&pud;
- goto out_huge;
- }
-
- pdshift = PMD_SHIFT;
pmdp = pmd_offset(&pud, ea);
+#else
+ pmdp = pmd_offset(pud_offset(p4d_offset(pgdp, ea), ea), ea);
+#endif
+ pdshift = PMD_SHIFT;
pmd = READ_ONCE(*pmdp);
/*
@@ -476,19 +515,8 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
goto out;
}
- if (is_hugepd(__hugepd(pmd_val(pmd)))) {
- hpdp = (hugepd_t *)&pmd;
- goto out_huge;
- }
-
return pte_offset_kernel(&pmd, ea);
-out_huge:
- if (!hpdp)
- return NULL;
-
- ret_pte = hugepte_offset(*hpdp, ea, pdshift);
- pdshift = hugepd_shift(*hpdp);
out:
if (hpage_shift)
*hpage_shift = pdshift;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index cfd622ebf774..787b22206386 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -48,7 +48,7 @@ notrace void __init early_ioremap_init(void)
early_ioremap_setup();
}
-static void __init *early_alloc_pgtable(unsigned long size)
+void __init *early_alloc_pgtable(unsigned long size)
{
void *ptr = memblock_alloc(size, size);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 9b99113cb51a..6621cfc3baf8 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -102,7 +102,7 @@ struct page *p4d_page(p4d_t p4d)
{
if (p4d_leaf(p4d)) {
if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
- VM_WARN_ON(!p4d_huge(p4d));
+ VM_WARN_ON(!p4d_leaf(p4d));
return pte_page(p4d_pte(p4d));
}
return virt_to_page(p4d_pgtable(p4d));
@@ -113,7 +113,7 @@ struct page *pud_page(pud_t pud)
{
if (pud_leaf(pud)) {
if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
- VM_WARN_ON(!pud_huge(pud));
+ VM_WARN_ON(!pud_leaf(pud));
return pte_page(pud_pte(pud));
}
return virt_to_page(pud_pgtable(pud));
@@ -132,7 +132,7 @@ struct page *pmd_page(pmd_t pmd)
* enabled so these checks can't be used.
*/
if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
- VM_WARN_ON(!(pmd_leaf(pmd) || pmd_huge(pmd)));
+ VM_WARN_ON(!pmd_leaf(pmd));
return pte_page(pmd_pte(pmd));
}
return virt_to_page(pmd_page_vaddr(pmd));
diff --git a/arch/powerpc/mm/ptdump/Makefile b/arch/powerpc/mm/ptdump/Makefile
index dc896d2874f3..0f7a050f327e 100644
--- a/arch/powerpc/mm/ptdump/Makefile
+++ b/arch/powerpc/mm/ptdump/Makefile
@@ -2,7 +2,7 @@
obj-y += ptdump.o
-obj-$(CONFIG_4xx) += shared.o
+obj-$(CONFIG_44x) += shared.o
obj-$(CONFIG_PPC_8xx) += 8xx.o
obj-$(CONFIG_PPC_E500) += shared.o
obj-$(CONFIG_PPC_BOOK3S_32) += shared.o
diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c
index 9a601587836b..a6baa6166d94 100644
--- a/arch/powerpc/mm/ptdump/hashpagetable.c
+++ b/arch/powerpc/mm/ptdump/hashpagetable.c
@@ -491,7 +491,7 @@ static void walk_vmemmap(struct pg_state *st)
* Traverse the vmemmaped memory and dump pages that are in the hash
* pagetable.
*/
- while (ptr->list) {
+ while (ptr) {
hpte_find(st, ptr->virt_addr, mmu_vmemmap_psize);
ptr = ptr->list;
}
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 0f9a21783329..2a36cc2e7e9e 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -225,7 +225,7 @@ skip_init_ctx:
fp->jited_len = proglen + FUNCTION_DESCR_SIZE;
if (!fp->is_func || extra_pass) {
- if (bpf_jit_binary_pack_finalize(fp, fhdr, hdr)) {
+ if (bpf_jit_binary_pack_finalize(fhdr, hdr)) {
fp = org_fp;
goto out_addrs;
}
@@ -348,7 +348,7 @@ void bpf_jit_free(struct bpf_prog *fp)
* before freeing it.
*/
if (jit_data) {
- bpf_jit_binary_pack_finalize(fp, jit_data->fhdr, jit_data->hdr);
+ bpf_jit_binary_pack_finalize(jit_data->fhdr, jit_data->hdr);
kvfree(jit_data->addrs);
kfree(jit_data);
}
@@ -359,3 +359,13 @@ void bpf_jit_free(struct bpf_prog *fp)
bpf_prog_unlock_free(fp);
}
+
+bool bpf_jit_supports_kfunc_call(void)
+{
+ return true;
+}
+
+bool bpf_jit_supports_far_kfunc_call(void)
+{
+ return IS_ENABLED(CONFIG_PPC64);
+}
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
index 2f39c50ca729..a0c4f1bde83e 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -450,10 +450,16 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
}
break;
case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */
- EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(dst_reg, src2_reg, src_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg));
break;
case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */
- EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(_R0, src2_reg, src_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg));
EMIT(PPC_RAW_MULW(_R0, src_reg, _R0));
EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0));
break;
@@ -467,10 +473,16 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
if (imm == 1) {
EMIT(PPC_RAW_MR(dst_reg, src2_reg));
} else if (is_power_of_2((u32)imm)) {
- EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm)));
+ if (off)
+ EMIT(PPC_RAW_SRAWI(dst_reg, src2_reg, ilog2(imm)));
+ else
+ EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm)));
} else {
PPC_LI32(_R0, imm);
- EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0));
+ if (off)
+ EMIT(PPC_RAW_DIVW(dst_reg, src2_reg, _R0));
+ else
+ EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0));
}
break;
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
@@ -480,11 +492,19 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
if (!is_power_of_2((u32)imm)) {
bpf_set_seen_register(ctx, tmp_reg);
PPC_LI32(tmp_reg, imm);
- EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(_R0, src2_reg, tmp_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg));
EMIT(PPC_RAW_MULW(_R0, tmp_reg, _R0));
EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0));
} else if (imm == 1) {
EMIT(PPC_RAW_LI(dst_reg, 0));
+ } else if (off) {
+ EMIT(PPC_RAW_SRAWI(_R0, src2_reg, ilog2(imm)));
+ EMIT(PPC_RAW_ADDZE(_R0, _R0));
+ EMIT(PPC_RAW_SLWI(_R0, _R0, ilog2(imm)));
+ EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0));
} else {
imm = ilog2((u32)imm);
EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - imm, 31));
@@ -497,11 +517,21 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
imm = -imm;
if (!is_power_of_2(imm))
return -EOPNOTSUPP;
- if (imm == 1)
+ if (imm == 1) {
EMIT(PPC_RAW_LI(dst_reg, 0));
- else
+ EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ } else if (off) {
+ EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, 31));
+ EMIT(PPC_RAW_XOR(dst_reg, src2_reg, dst_reg_h));
+ EMIT(PPC_RAW_SUBFC(dst_reg, dst_reg_h, dst_reg));
+ EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 32 - ilog2(imm), 31));
+ EMIT(PPC_RAW_XOR(dst_reg, dst_reg, dst_reg_h));
+ EMIT(PPC_RAW_SUBFC(dst_reg, dst_reg_h, dst_reg));
+ EMIT(PPC_RAW_SUBFE(dst_reg_h, dst_reg_h, dst_reg_h));
+ } else {
EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - ilog2(imm), 31));
- EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ }
break;
case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
if (!imm)
@@ -727,15 +757,30 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* MOV
*/
case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
- if (dst_reg == src_reg)
- break;
- EMIT(PPC_RAW_MR(dst_reg, src_reg));
- EMIT(PPC_RAW_MR(dst_reg_h, src_reg_h));
+ if (off == 8) {
+ EMIT(PPC_RAW_EXTSB(dst_reg, src_reg));
+ EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31));
+ } else if (off == 16) {
+ EMIT(PPC_RAW_EXTSH(dst_reg, src_reg));
+ EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31));
+ } else if (off == 32 && dst_reg == src_reg) {
+ EMIT(PPC_RAW_SRAWI(dst_reg_h, src_reg, 31));
+ } else if (off == 32) {
+ EMIT(PPC_RAW_MR(dst_reg, src_reg));
+ EMIT(PPC_RAW_SRAWI(dst_reg_h, src_reg, 31));
+ } else if (dst_reg != src_reg) {
+ EMIT(PPC_RAW_MR(dst_reg, src_reg));
+ EMIT(PPC_RAW_MR(dst_reg_h, src_reg_h));
+ }
break;
case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */
/* special mov32 for zext */
if (imm == 1)
EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ else if (off == 8)
+ EMIT(PPC_RAW_EXTSB(dst_reg, src_reg));
+ else if (off == 16)
+ EMIT(PPC_RAW_EXTSH(dst_reg, src_reg));
else if (dst_reg != src_reg)
EMIT(PPC_RAW_MR(dst_reg, src_reg));
break;
@@ -751,6 +796,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* BPF_FROM_BE/LE
*/
case BPF_ALU | BPF_END | BPF_FROM_LE:
+ case BPF_ALU64 | BPF_END | BPF_FROM_LE:
switch (imm) {
case 16:
/* Copy 16 bits to upper part */
@@ -785,6 +831,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
EMIT(PPC_RAW_MR(dst_reg_h, tmp_reg));
break;
}
+ if (BPF_CLASS(code) == BPF_ALU64 && imm != 64)
+ EMIT(PPC_RAW_LI(dst_reg_h, 0));
break;
case BPF_ALU | BPF_END | BPF_FROM_BE:
switch (imm) {
@@ -852,6 +900,15 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
/* Get offset into TMP_REG */
EMIT(PPC_RAW_LI(tmp_reg, off));
+ /*
+ * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync'
+ * before and after the operation.
+ *
+ * This is a requirement in the Linux Kernel Memory Model.
+ * See __cmpxchg_u32() in asm/cmpxchg.h as an example.
+ */
+ if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP))
+ EMIT(PPC_RAW_SYNC());
tmp_idx = ctx->idx * 4;
/* load value from memory into r0 */
EMIT(PPC_RAW_LWARX(_R0, tmp_reg, dst_reg, 0));
@@ -905,6 +962,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
/* For the BPF_FETCH variant, get old data into src_reg */
if (imm & BPF_FETCH) {
+ /* Emit 'sync' to enforce full ordering */
+ if (IS_ENABLED(CONFIG_SMP))
+ EMIT(PPC_RAW_SYNC());
EMIT(PPC_RAW_MR(ret_reg, ax_reg));
if (!fp->aux->verifier_zext)
EMIT(PPC_RAW_LI(ret_reg - 1, 0)); /* higher 32-bit */
@@ -918,11 +978,17 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* BPF_LDX
*/
case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */
+ case BPF_LDX | BPF_MEMSX | BPF_B:
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
+ case BPF_LDX | BPF_MEMSX | BPF_H:
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
+ case BPF_LDX | BPF_MEMSX | BPF_W:
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
/*
@@ -931,7 +997,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* load only if addr is kernel address (see is_kernel_addr()), otherwise
* set dst_reg=0 and move on.
*/
- if (BPF_MODE(code) == BPF_PROBE_MEM) {
+ if (BPF_MODE(code) == BPF_PROBE_MEM || BPF_MODE(code) == BPF_PROBE_MEMSX) {
PPC_LI32(_R0, TASK_SIZE - off);
EMIT(PPC_RAW_CMPLW(src_reg, _R0));
PPC_BCC_SHORT(COND_GT, (ctx->idx + 4) * 4);
@@ -953,30 +1019,48 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* as there are two load instructions for dst_reg_h & dst_reg
* respectively.
*/
- if (size == BPF_DW)
+ if (size == BPF_DW ||
+ (size == BPF_B && BPF_MODE(code) == BPF_PROBE_MEMSX))
PPC_JMP((ctx->idx + 3) * 4);
else
PPC_JMP((ctx->idx + 2) * 4);
}
- switch (size) {
- case BPF_B:
- EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
- break;
- case BPF_H:
- EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
- break;
- case BPF_W:
- EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
- break;
- case BPF_DW:
- EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off));
- EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4));
- break;
- }
+ if (BPF_MODE(code) == BPF_MEMSX || BPF_MODE(code) == BPF_PROBE_MEMSX) {
+ switch (size) {
+ case BPF_B:
+ EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
+ EMIT(PPC_RAW_EXTSB(dst_reg, dst_reg));
+ break;
+ case BPF_H:
+ EMIT(PPC_RAW_LHA(dst_reg, src_reg, off));
+ break;
+ case BPF_W:
+ EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
+ break;
+ }
+ if (!fp->aux->verifier_zext)
+ EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31));
- if (size != BPF_DW && !fp->aux->verifier_zext)
- EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ } else {
+ switch (size) {
+ case BPF_B:
+ EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
+ break;
+ case BPF_H:
+ EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
+ break;
+ case BPF_W:
+ EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
+ break;
+ case BPF_DW:
+ EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off));
+ EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4));
+ break;
+ }
+ if (size != BPF_DW && !fp->aux->verifier_zext)
+ EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ }
if (BPF_MODE(code) == BPF_PROBE_MEM) {
int insn_idx = ctx->idx - 1;
@@ -1068,6 +1152,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
case BPF_JMP | BPF_JA:
PPC_JMP(addrs[i + 1 + off]);
break;
+ case BPF_JMP32 | BPF_JA:
+ PPC_JMP(addrs[i + 1 + imm]);
+ break;
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JGT | BPF_X:
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index 79f23974a320..2cbcdf93cc19 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -202,29 +202,47 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
EMIT(PPC_RAW_BLR());
}
-static int bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx, u64 func)
+static int
+bpf_jit_emit_func_call_hlp(u32 *image, u32 *fimage, struct codegen_context *ctx, u64 func)
{
unsigned long func_addr = func ? ppc_function_entry((void *)func) : 0;
long reladdr;
- if (WARN_ON_ONCE(!core_kernel_text(func_addr)))
+ if (WARN_ON_ONCE(!kernel_text_address(func_addr)))
return -EINVAL;
- if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) {
- reladdr = func_addr - CTX_NIA(ctx);
-
- if (reladdr >= (long)SZ_8G || reladdr < -(long)SZ_8G) {
- pr_err("eBPF: address of %ps out of range of pcrel address.\n",
- (void *)func);
- return -ERANGE;
- }
- /* pla r12,addr */
- EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(1) | IMM_H18(reladdr));
- EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | IMM_L(reladdr));
- EMIT(PPC_RAW_MTCTR(_R12));
- EMIT(PPC_RAW_BCTR());
+#ifdef CONFIG_PPC_KERNEL_PCREL
+ reladdr = func_addr - local_paca->kernelbase;
+ if (reladdr < (long)SZ_8G && reladdr >= -(long)SZ_8G) {
+ EMIT(PPC_RAW_LD(_R12, _R13, offsetof(struct paca_struct, kernelbase)));
+ /* Align for subsequent prefix instruction */
+ if (!IS_ALIGNED((unsigned long)fimage + CTX_NIA(ctx), 8))
+ EMIT(PPC_RAW_NOP());
+ /* paddi r12,r12,addr */
+ EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(0) | IMM_H18(reladdr));
+ EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | ___PPC_RA(_R12) | IMM_L(reladdr));
} else {
+ unsigned long pc = (unsigned long)fimage + CTX_NIA(ctx);
+ bool alignment_needed = !IS_ALIGNED(pc, 8);
+
+ reladdr = func_addr - (alignment_needed ? pc + 4 : pc);
+
+ if (reladdr < (long)SZ_8G && reladdr >= -(long)SZ_8G) {
+ if (alignment_needed)
+ EMIT(PPC_RAW_NOP());
+ /* pla r12,addr */
+ EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(1) | IMM_H18(reladdr));
+ EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | IMM_L(reladdr));
+ } else {
+ /* We can clobber r12 */
+ PPC_LI64(_R12, func);
+ }
+ }
+ EMIT(PPC_RAW_MTCTR(_R12));
+ EMIT(PPC_RAW_BCTRL());
+#else
+ if (core_kernel_text(func_addr)) {
reladdr = func_addr - kernel_toc_addr();
if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
pr_err("eBPF: address of %ps out of range of kernel_toc.\n", (void *)func);
@@ -235,7 +253,32 @@ static int bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx, u
EMIT(PPC_RAW_ADDI(_R12, _R12, PPC_LO(reladdr)));
EMIT(PPC_RAW_MTCTR(_R12));
EMIT(PPC_RAW_BCTRL());
+ } else {
+ if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V1)) {
+ /* func points to the function descriptor */
+ PPC_LI64(bpf_to_ppc(TMP_REG_2), func);
+ /* Load actual entry point from function descriptor */
+ EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), 0));
+ /* ... and move it to CTR */
+ EMIT(PPC_RAW_MTCTR(bpf_to_ppc(TMP_REG_1)));
+ /*
+ * Load TOC from function descriptor at offset 8.
+ * We can clobber r2 since we get called through a
+ * function pointer (so caller will save/restore r2).
+ */
+ EMIT(PPC_RAW_LD(_R2, bpf_to_ppc(TMP_REG_2), 8));
+ } else {
+ PPC_LI64(_R12, func);
+ EMIT(PPC_RAW_MTCTR(_R12));
+ }
+ EMIT(PPC_RAW_BCTRL());
+ /*
+ * Load r2 with kernel TOC as kernel TOC is used if function address falls
+ * within core kernel text.
+ */
+ EMIT(PPC_RAW_LD(_R2, _R13, offsetof(struct paca_struct, kernel_toc)));
}
+#endif
return 0;
}
@@ -285,7 +328,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
int b2p_index = bpf_to_ppc(BPF_REG_3);
int bpf_tailcall_prologue_size = 8;
- if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2))
+ if (!IS_ENABLED(CONFIG_PPC_KERNEL_PCREL) && IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2))
bpf_tailcall_prologue_size += 4; /* skip past the toc load */
/*
@@ -467,20 +510,33 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */
case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */
if (BPF_OP(code) == BPF_MOD) {
- EMIT(PPC_RAW_DIVWU(tmp1_reg, dst_reg, src_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(tmp1_reg, dst_reg, src_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(tmp1_reg, dst_reg, src_reg));
+
EMIT(PPC_RAW_MULW(tmp1_reg, src_reg, tmp1_reg));
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
} else
- EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(dst_reg, dst_reg, src_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
if (BPF_OP(code) == BPF_MOD) {
- EMIT(PPC_RAW_DIVDU(tmp1_reg, dst_reg, src_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVD(tmp1_reg, dst_reg, src_reg));
+ else
+ EMIT(PPC_RAW_DIVDU(tmp1_reg, dst_reg, src_reg));
EMIT(PPC_RAW_MULD(tmp1_reg, src_reg, tmp1_reg));
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
} else
- EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, src_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVD(dst_reg, dst_reg, src_reg));
+ else
+ EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, src_reg));
break;
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
@@ -501,19 +557,31 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
switch (BPF_CLASS(code)) {
case BPF_ALU:
if (BPF_OP(code) == BPF_MOD) {
- EMIT(PPC_RAW_DIVWU(tmp2_reg, dst_reg, tmp1_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(tmp2_reg, dst_reg, tmp1_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(tmp2_reg, dst_reg, tmp1_reg));
EMIT(PPC_RAW_MULW(tmp1_reg, tmp1_reg, tmp2_reg));
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
} else
- EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, tmp1_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVW(dst_reg, dst_reg, tmp1_reg));
+ else
+ EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, tmp1_reg));
break;
case BPF_ALU64:
if (BPF_OP(code) == BPF_MOD) {
- EMIT(PPC_RAW_DIVDU(tmp2_reg, dst_reg, tmp1_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVD(tmp2_reg, dst_reg, tmp1_reg));
+ else
+ EMIT(PPC_RAW_DIVDU(tmp2_reg, dst_reg, tmp1_reg));
EMIT(PPC_RAW_MULD(tmp1_reg, tmp1_reg, tmp2_reg));
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
} else
- EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, tmp1_reg));
+ if (off)
+ EMIT(PPC_RAW_DIVD(dst_reg, dst_reg, tmp1_reg));
+ else
+ EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, tmp1_reg));
break;
}
goto bpf_alu32_trunc;
@@ -633,8 +701,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
/* special mov32 for zext */
EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31));
break;
- }
- EMIT(PPC_RAW_MR(dst_reg, src_reg));
+ } else if (off == 8) {
+ EMIT(PPC_RAW_EXTSB(dst_reg, src_reg));
+ } else if (off == 16) {
+ EMIT(PPC_RAW_EXTSH(dst_reg, src_reg));
+ } else if (off == 32) {
+ EMIT(PPC_RAW_EXTSW(dst_reg, src_reg));
+ } else if (dst_reg != src_reg)
+ EMIT(PPC_RAW_MR(dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */
case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = (s64) imm */
@@ -656,11 +730,12 @@ bpf_alu32_trunc:
*/
case BPF_ALU | BPF_END | BPF_FROM_LE:
case BPF_ALU | BPF_END | BPF_FROM_BE:
+ case BPF_ALU64 | BPF_END | BPF_FROM_LE:
#ifdef __BIG_ENDIAN__
if (BPF_SRC(code) == BPF_FROM_BE)
goto emit_clear;
#else /* !__BIG_ENDIAN__ */
- if (BPF_SRC(code) == BPF_FROM_LE)
+ if (BPF_CLASS(code) == BPF_ALU && BPF_SRC(code) == BPF_FROM_LE)
goto emit_clear;
#endif
switch (imm) {
@@ -803,6 +878,15 @@ emit_clear:
/* Get offset into TMP_REG_1 */
EMIT(PPC_RAW_LI(tmp1_reg, off));
+ /*
+ * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync'
+ * before and after the operation.
+ *
+ * This is a requirement in the Linux Kernel Memory Model.
+ * See __cmpxchg_u64() in asm/cmpxchg.h as an example.
+ */
+ if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP))
+ EMIT(PPC_RAW_SYNC());
tmp_idx = ctx->idx * 4;
/* load value from memory into TMP_REG_2 */
if (size == BPF_DW)
@@ -865,6 +949,9 @@ emit_clear:
PPC_BCC_SHORT(COND_NE, tmp_idx);
if (imm & BPF_FETCH) {
+ /* Emit 'sync' to enforce full ordering */
+ if (IS_ENABLED(CONFIG_SMP))
+ EMIT(PPC_RAW_SYNC());
EMIT(PPC_RAW_MR(ret_reg, _R0));
/*
* Skip unnecessary zero-extension for 32-bit cmpxchg.
@@ -881,13 +968,19 @@ emit_clear:
*/
/* dst = *(u8 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_B:
+ case BPF_LDX | BPF_MEMSX | BPF_B:
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
/* dst = *(u16 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_H:
+ case BPF_LDX | BPF_MEMSX | BPF_H:
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
/* dst = *(u32 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_W:
+ case BPF_LDX | BPF_MEMSX | BPF_W:
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
/* dst = *(u64 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_DW:
case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
@@ -897,7 +990,7 @@ emit_clear:
* load only if addr is kernel address (see is_kernel_addr()), otherwise
* set dst_reg=0 and move on.
*/
- if (BPF_MODE(code) == BPF_PROBE_MEM) {
+ if (BPF_MODE(code) == BPF_PROBE_MEM || BPF_MODE(code) == BPF_PROBE_MEMSX) {
EMIT(PPC_RAW_ADDI(tmp1_reg, src_reg, off));
if (IS_ENABLED(CONFIG_PPC_BOOK3E_64))
PPC_LI64(tmp2_reg, 0x8000000000000000ul);
@@ -910,30 +1003,47 @@ emit_clear:
* Check if 'off' is word aligned for BPF_DW, because
* we might generate two instructions.
*/
- if (BPF_SIZE(code) == BPF_DW && (off & 3))
+ if ((BPF_SIZE(code) == BPF_DW ||
+ (BPF_SIZE(code) == BPF_B && BPF_MODE(code) == BPF_PROBE_MEMSX)) &&
+ (off & 3))
PPC_JMP((ctx->idx + 3) * 4);
else
PPC_JMP((ctx->idx + 2) * 4);
}
- switch (size) {
- case BPF_B:
- EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
- break;
- case BPF_H:
- EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
- break;
- case BPF_W:
- EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
- break;
- case BPF_DW:
- if (off % 4) {
- EMIT(PPC_RAW_LI(tmp1_reg, off));
- EMIT(PPC_RAW_LDX(dst_reg, src_reg, tmp1_reg));
- } else {
- EMIT(PPC_RAW_LD(dst_reg, src_reg, off));
+ if (BPF_MODE(code) == BPF_MEMSX || BPF_MODE(code) == BPF_PROBE_MEMSX) {
+ switch (size) {
+ case BPF_B:
+ EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
+ EMIT(PPC_RAW_EXTSB(dst_reg, dst_reg));
+ break;
+ case BPF_H:
+ EMIT(PPC_RAW_LHA(dst_reg, src_reg, off));
+ break;
+ case BPF_W:
+ EMIT(PPC_RAW_LWA(dst_reg, src_reg, off));
+ break;
+ }
+ } else {
+ switch (size) {
+ case BPF_B:
+ EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
+ break;
+ case BPF_H:
+ EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
+ break;
+ case BPF_W:
+ EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
+ break;
+ case BPF_DW:
+ if (off % 4) {
+ EMIT(PPC_RAW_LI(tmp1_reg, off));
+ EMIT(PPC_RAW_LDX(dst_reg, src_reg, tmp1_reg));
+ } else {
+ EMIT(PPC_RAW_LD(dst_reg, src_reg, off));
+ }
+ break;
}
- break;
}
if (size != BPF_DW && insn_is_zext(&insn[i + 1]))
@@ -993,7 +1103,7 @@ emit_clear:
return ret;
if (func_addr_fixed)
- ret = bpf_jit_emit_func_call_hlp(image, ctx, func_addr);
+ ret = bpf_jit_emit_func_call_hlp(image, fimage, ctx, func_addr);
else
ret = bpf_jit_emit_func_call_rel(image, fimage, ctx, func_addr);
@@ -1010,6 +1120,9 @@ emit_clear:
case BPF_JMP | BPF_JA:
PPC_JMP(addrs[i + 1 + off]);
break;
+ case BPF_JMP32 | BPF_JA:
+ PPC_JMP(addrs[i + 1 + imm]);
+ break;
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JGT | BPF_X:
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 6b5f8a94e7d8..42867469752d 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -266,51 +266,44 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs)
static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{
bool use_siar = regs_use_siar(regs);
- unsigned long mmcra = regs->dsisr;
- int marked = mmcra & MMCRA_SAMPLE_ENABLE;
+ unsigned long siar;
+ unsigned long addr;
if (!use_siar)
return perf_flags_from_msr(regs);
/*
- * Check the address in SIAR to identify the
- * privilege levels since the SIER[MSR_HV, MSR_PR]
- * bits are not set for marked events in power10
- * DD1.
- */
- if (marked && (ppmu->flags & PPMU_P10_DD1)) {
- unsigned long siar = mfspr(SPRN_SIAR);
- if (siar) {
- if (is_kernel_addr(siar))
- return PERF_RECORD_MISC_KERNEL;
- return PERF_RECORD_MISC_USER;
- } else {
- if (is_kernel_addr(regs->nip))
- return PERF_RECORD_MISC_KERNEL;
- return PERF_RECORD_MISC_USER;
- }
- }
-
- /*
* If we don't have flags in MMCRA, rather than using
* the MSR, we intuit the flags from the address in
* SIAR which should give slightly more reliable
* results
*/
if (ppmu->flags & PPMU_NO_SIPR) {
- unsigned long siar = mfspr(SPRN_SIAR);
+ siar = mfspr(SPRN_SIAR);
if (is_kernel_addr(siar))
return PERF_RECORD_MISC_KERNEL;
return PERF_RECORD_MISC_USER;
}
/* PR has priority over HV, so order below is important */
- if (regs_sipr(regs))
- return PERF_RECORD_MISC_USER;
-
- if (regs_sihv(regs) && (freeze_events_kernel != MMCR0_FCHV))
+ if (regs_sipr(regs)) {
+ if (!(ppmu->flags & PPMU_P10))
+ return PERF_RECORD_MISC_USER;
+ } else if (regs_sihv(regs) && (freeze_events_kernel != MMCR0_FCHV))
return PERF_RECORD_MISC_HYPERVISOR;
+ /*
+ * Check the address in SIAR to identify the
+ * privilege levels since the SIER[MSR_HV, MSR_PR]
+ * bits are not set correctly in power10 sometimes
+ */
+ if (ppmu->flags & PPMU_P10) {
+ siar = mfspr(SPRN_SIAR);
+ addr = siar ? siar : regs->nip;
+ if (!is_kernel_addr(addr))
+ return PERF_RECORD_MISC_USER;
+ }
+
return PERF_RECORD_MISC_KERNEL;
}
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 057ec2e3451d..d400fa391c27 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -425,16 +425,6 @@ static char *memdup_to_str(char *maybe_str, int max_len, gfp_t gfp)
return kasprintf(gfp, "%.*s", max_len, maybe_str);
}
-static ssize_t device_show_string(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct dev_ext_attribute *d;
-
- d = container_of(attr, struct dev_ext_attribute, attr);
-
- return sprintf(buf, "%s\n", (char *)d->var);
-}
-
static ssize_t cpumask_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c
index 62a68b6b2d4b..bb57b7cfe640 100644
--- a/arch/powerpc/perf/power10-pmu.c
+++ b/arch/powerpc/perf/power10-pmu.c
@@ -593,7 +593,8 @@ static struct power_pmu power10_pmu = {
.get_mem_weight = isa207_get_mem_weight,
.disable_pmc = isa207_disable_pmc,
.flags = PPMU_HAS_SIER | PPMU_ARCH_207S |
- PPMU_ARCH_31 | PPMU_HAS_ATTR_CONFIG1,
+ PPMU_ARCH_31 | PPMU_HAS_ATTR_CONFIG1 |
+ PPMU_P10,
.n_generic = ARRAY_SIZE(power10_generic_events),
.generic_events = power10_generic_events,
.cache_events = &power10_cache_events,
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
deleted file mode 100644
index b3c466c50535..000000000000
--- a/arch/powerpc/platforms/40x/Kconfig
+++ /dev/null
@@ -1,78 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config ACADIA
- bool "Acadia"
- depends on 40x
- select PPC40x_SIMPLE
- select 405EZ
- help
- This option enables support for the AMCC 405EZ Acadia evaluation board.
-
-config HOTFOOT
- bool "Hotfoot"
- depends on 40x
- select PPC40x_SIMPLE
- select FORCE_PCI
- help
- This option enables support for the ESTEEM 195E Hotfoot board.
-
-config KILAUEA
- bool "Kilauea"
- depends on 40x
- select 405EX
- select PPC40x_SIMPLE
- select PPC4xx_PCI_EXPRESS
- select FORCE_PCI
- select PCI_MSI
- help
- This option enables support for the AMCC PPC405EX evaluation board.
-
-config MAKALU
- bool "Makalu"
- depends on 40x
- select 405EX
- select FORCE_PCI
- select PPC4xx_PCI_EXPRESS
- select PPC40x_SIMPLE
- help
- This option enables support for the AMCC PPC405EX board.
-
-config OBS600
- bool "OpenBlockS 600"
- depends on 40x
- select 405EX
- select PPC40x_SIMPLE
- help
- This option enables support for PlatHome OpenBlockS 600 server
-
-config PPC40x_SIMPLE
- bool "Simple PowerPC 40x board support"
- depends on 40x
- help
- This option enables the simple PowerPC 40x platform support.
-
-config 405EX
- bool
- select IBM_EMAC_EMAC4 if IBM_EMAC
- select IBM_EMAC_RGMII if IBM_EMAC
-
-config 405EZ
- bool
- select IBM_EMAC_NO_FLOW_CTRL if IBM_EMAC
- select IBM_EMAC_MAL_CLR_ICINTSTAT if IBM_EMAC
- select IBM_EMAC_MAL_COMMON_ERR if IBM_EMAC
-
-config PPC4xx_GPIO
- bool "PPC4xx GPIO support"
- depends on 40x
- select GPIOLIB
- select OF_GPIO_MM_GPIOCHIP
- help
- Enable gpiolib support for ppc40x based boards
-
-config APM8018X
- bool "APM8018X"
- depends on 40x
- select PPC40x_SIMPLE
- help
- This option enables support for the AppliedMicro APM8018X evaluation
- board.
diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile
deleted file mode 100644
index 122de98527c4..000000000000
--- a/arch/powerpc/platforms/40x/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_PPC40x_SIMPLE) += ppc40x_simple.o
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
deleted file mode 100644
index 294ab2728588..000000000000
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Generic PowerPC 40x platform support
- *
- * Copyright 2008 IBM Corporation
- *
- * This implements simple platform support for PowerPC 44x chips. This is
- * mostly used for eval boards or other simple and "generic" 44x boards. If
- * your board has custom functions or hardware, then you will likely want to
- * implement your own board.c file to accommodate it.
- */
-
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-#include <asm/time.h>
-#include <asm/udbg.h>
-#include <asm/uic.h>
-
-#include <linux/init.h>
-#include <linux/of_platform.h>
-
-static const struct of_device_id ppc40x_of_bus[] __initconst = {
- { .compatible = "ibm,plb3", },
- { .compatible = "ibm,plb4", },
- { .compatible = "ibm,opb", },
- { .compatible = "ibm,ebc", },
- { .compatible = "simple-bus", },
- {},
-};
-
-static int __init ppc40x_device_probe(void)
-{
- of_platform_bus_probe(NULL, ppc40x_of_bus, NULL);
-
- return 0;
-}
-machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
-
-/* This is the list of boards that can be supported by this simple
- * platform code. This does _not_ mean the boards are compatible,
- * as they most certainly are not from a device tree perspective.
- * However, their differences are handled by the device tree and the
- * drivers and therefore they don't need custom board support files.
- *
- * Again, if your board needs to do things differently then create a
- * board.c file for it rather than adding it to this list.
- */
-static const char * const board[] __initconst = {
- "amcc,acadia",
- "amcc,haleakala",
- "amcc,kilauea",
- "amcc,makalu",
- "apm,klondike",
- "est,hotfoot",
- "plathome,obs600",
- NULL
-};
-
-static int __init ppc40x_probe(void)
-{
- pci_set_flags(PCI_REASSIGN_ALL_RSRC);
- return 1;
-}
-
-define_machine(ppc40x_simple) {
- .name = "PowerPC 40x Platform",
- .compatibles = board,
- .probe = ppc40x_probe,
- .progress = udbg_progress,
- .init_IRQ = uic_init_tree,
- .get_irq = uic_get_irq,
- .restart = ppc4xx_reset_system,
-};
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index 5ba031f57652..ca7b1bb442d9 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-obj-y += misc_44x.o machine_check.o
+obj-y += misc_44x.o machine_check.o uic.o soc.o
ifneq ($(CONFIG_PPC4xx_CPM),y)
obj-y += idle.o
endif
@@ -12,3 +12,7 @@ obj-$(CONFIG_CANYONLANDS)+= canyonlands.o
obj-$(CONFIG_CURRITUCK) += ppc476.o
obj-$(CONFIG_AKEBONO) += ppc476.o
obj-$(CONFIG_FSP2) += fsp2.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_PPC4xx_HSTA_MSI) += hsta_msi.o
+obj-$(CONFIG_PPC4xx_CPM) += cpm.o
+obj-$(CONFIG_PPC4xx_GPIO) += gpio.o
diff --git a/arch/powerpc/platforms/4xx/cpm.c b/arch/powerpc/platforms/44x/cpm.c
index 670f8ad4465b..670f8ad4465b 100644
--- a/arch/powerpc/platforms/4xx/cpm.c
+++ b/arch/powerpc/platforms/44x/cpm.c
diff --git a/arch/powerpc/platforms/4xx/gpio.c b/arch/powerpc/platforms/44x/gpio.c
index e5f2319e5cbe..e5f2319e5cbe 100644
--- a/arch/powerpc/platforms/4xx/gpio.c
+++ b/arch/powerpc/platforms/44x/gpio.c
diff --git a/arch/powerpc/platforms/4xx/hsta_msi.c b/arch/powerpc/platforms/44x/hsta_msi.c
index c6bd846b0d65..c6bd846b0d65 100644
--- a/arch/powerpc/platforms/4xx/hsta_msi.c
+++ b/arch/powerpc/platforms/44x/hsta_msi.c
diff --git a/arch/powerpc/platforms/44x/machine_check.c b/arch/powerpc/platforms/44x/machine_check.c
index 5d19daacd78a..85ff33a8d9b6 100644
--- a/arch/powerpc/platforms/44x/machine_check.c
+++ b/arch/powerpc/platforms/44x/machine_check.c
@@ -9,6 +9,21 @@
#include <asm/reg.h>
#include <asm/cacheflush.h>
+int machine_check_4xx(struct pt_regs *regs)
+{
+ unsigned long reason = regs->esr;
+
+ if (reason & ESR_IMCP) {
+ printk("Instruction");
+ mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ } else
+ printk("Data");
+
+ printk(" machine check in kernel mode.\n");
+
+ return 0;
+}
+
int machine_check_440A(struct pt_regs *regs)
{
unsigned long reason = regs->esr;
diff --git a/arch/powerpc/platforms/4xx/pci.c b/arch/powerpc/platforms/44x/pci.c
index 48626615b18b..db6d33ca753f 100644
--- a/arch/powerpc/platforms/4xx/pci.c
+++ b/arch/powerpc/platforms/44x/pci.c
@@ -1263,102 +1263,6 @@ static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
#endif /* CONFIG_44x */
-#ifdef CONFIG_40x
-
-static int __init ppc405ex_pciex_core_init(struct device_node *np)
-{
- /* Nothing to do, return 2 ports */
- return 2;
-}
-
-static void __init ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port)
-{
- /* Assert the PE0_PHY reset */
- mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01010000);
- msleep(1);
-
- /* deassert the PE0_hotreset */
- if (port->endpoint)
- mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01111000);
- else
- mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01101000);
-
- /* poll for phy !reset */
- /* XXX FIXME add timeout */
- while (!(mfdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSTA) & 0x00001000))
- ;
-
- /* deassert the PE0_gpl_utl_reset */
- mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000);
-}
-
-static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
-{
- u32 val;
-
- if (port->endpoint)
- val = PTYPE_LEGACY_ENDPOINT;
- else
- val = PTYPE_ROOT_PORT;
-
- mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET,
- 1 << 24 | val << 20 | LNKW_X1 << 12);
-
- mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000);
- mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000);
- mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET1, 0x720F0000);
- mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET2, 0x70600003);
-
- /*
- * Only reset the PHY when no link is currently established.
- * This is for the Atheros PCIe board which has problems to establish
- * the link (again) after this PHY reset. All other currently tested
- * PCIe boards don't show this problem.
- * This has to be re-tested and fixed in a later release!
- */
- val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
- if (!(val & 0x00001000))
- ppc405ex_pcie_phy_reset(port);
-
- dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000); /* guarded on */
-
- port->has_ibpre = 1;
-
- return ppc4xx_pciex_port_reset_sdr(port);
-}
-
-static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
-{
- dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0);
-
- /*
- * Set buffer allocations and then assert VRB and TXE.
- */
- out_be32(port->utl_base + PEUTL_OUTTR, 0x02000000);
- out_be32(port->utl_base + PEUTL_INTR, 0x02000000);
- out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000);
- out_be32(port->utl_base + PEUTL_PBBSZ, 0x21000000);
- out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000);
- out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000);
- out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000);
- out_be32(port->utl_base + PEUTL_PCTL, 0x80800066);
-
- out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000);
-
- return 0;
-}
-
-static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
-{
- .want_sdr = true,
- .core_init = ppc405ex_pciex_core_init,
- .port_init_hw = ppc405ex_pciex_init_port_hw,
- .setup_utl = ppc405ex_pciex_init_utl,
- .check_link = ppc4xx_pciex_check_link_sdr,
-};
-
-#endif /* CONFIG_40x */
-
#ifdef CONFIG_476FPE
static int __init ppc_476fpe_pciex_core_init(struct device_node *np)
{
@@ -1427,10 +1331,6 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
if (of_device_is_compatible(np, "ibm,plb-pciex-apm821xx"))
ppc4xx_pciex_hwops = &apm821xx_pcie_hwops;
#endif /* CONFIG_44x */
-#ifdef CONFIG_40x
- if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
- ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops;
-#endif
#ifdef CONFIG_476FPE
if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe")
|| of_device_is_compatible(np, "ibm,plb-pciex-476gtr"))
diff --git a/arch/powerpc/platforms/4xx/pci.h b/arch/powerpc/platforms/44x/pci.h
index bb4821938ab1..bb4821938ab1 100644
--- a/arch/powerpc/platforms/4xx/pci.h
+++ b/arch/powerpc/platforms/44x/pci.h
diff --git a/arch/powerpc/platforms/4xx/soc.c b/arch/powerpc/platforms/44x/soc.c
index 5412e6b21e10..5412e6b21e10 100644
--- a/arch/powerpc/platforms/4xx/soc.c
+++ b/arch/powerpc/platforms/44x/soc.c
diff --git a/arch/powerpc/platforms/4xx/uic.c b/arch/powerpc/platforms/44x/uic.c
index e3e148b9dd18..e3e148b9dd18 100644
--- a/arch/powerpc/platforms/4xx/uic.c
+++ b/arch/powerpc/platforms/44x/uic.c
diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile
deleted file mode 100644
index 2071a0abe09b..000000000000
--- a/arch/powerpc/platforms/4xx/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-y += uic.o machine_check.o
-obj-$(CONFIG_4xx_SOC) += soc.o
-obj-$(CONFIG_PCI) += pci.o
-obj-$(CONFIG_PPC4xx_HSTA_MSI) += hsta_msi.o
-obj-$(CONFIG_PPC4xx_CPM) += cpm.o
-obj-$(CONFIG_PPC4xx_GPIO) += gpio.o
diff --git a/arch/powerpc/platforms/4xx/machine_check.c b/arch/powerpc/platforms/4xx/machine_check.c
deleted file mode 100644
index a905da1d6f41..000000000000
--- a/arch/powerpc/platforms/4xx/machine_check.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- */
-
-#include <linux/kernel.h>
-#include <linux/printk.h>
-#include <linux/ptrace.h>
-
-#include <asm/reg.h>
-
-int machine_check_4xx(struct pt_regs *regs)
-{
- unsigned long reason = regs->esr;
-
- if (reason & ESR_IMCP) {
- printk("Instruction");
- mtspr(SPRN_ESR, reason & ~ESR_IMCP);
- } else
- printk("Data");
- printk(" machine check in kernel mode.\n");
-
- return 0;
-}
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index 8f75e9574c27..8c1f3b629fc7 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -279,7 +279,7 @@ static void __init mpc512x_setup_diu(void)
* and so negatively affect boot time. Instead we reserve the
* already configured frame buffer area so that it won't be
* destroyed. The starting address of the area to reserve and
- * also it's length is passed to memblock_reserve(). It will be
+ * also its length is passed to memblock_reserve(). It will be
* freed later on first open of fbdev, when splash image is not
* needed any more.
*/
diff --git a/arch/powerpc/platforms/52xx/lite5200_sleep.S b/arch/powerpc/platforms/52xx/lite5200_sleep.S
index 0b12647e7b42..0ec2522ee4ad 100644
--- a/arch/powerpc/platforms/52xx/lite5200_sleep.S
+++ b/arch/powerpc/platforms/52xx/lite5200_sleep.S
@@ -203,7 +203,8 @@ lite5200_wakeup:
/* HIDs, MSR */
LOAD_SPRN(HID1, 0x19)
- LOAD_SPRN(HID2, 0x1a)
+ /* FIXME: Should this use HID2_G2_LE? */
+ LOAD_SPRN(HID2_750FX, 0x1a)
/* address translation is tricky (see turn_on_mmu) */
@@ -283,7 +284,8 @@ SYM_FUNC_START_LOCAL(save_regs)
SAVE_SPRN(HID0, 0x18)
SAVE_SPRN(HID1, 0x19)
- SAVE_SPRN(HID2, 0x1a)
+ /* FIXME: Should this use HID2_G2_LE? */
+ SAVE_SPRN(HID2_750FX, 0x1a)
mfmsr r10
stw r10, (4*0x1b)(r4)
/*SAVE_SPRN(LR, 0x1c) have to save it before the call */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index b4938e344f71..253421ffb4e5 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -12,12 +12,10 @@
#undef DEBUG
-#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
#include <linux/export.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 581059527c36..2bd6abcdc113 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -48,6 +48,7 @@
* the output mode. This driver does not change the output mode setting.
*/
+#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -56,7 +57,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
-#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/property.h>
diff --git a/arch/powerpc/platforms/83xx/suspend-asm.S b/arch/powerpc/platforms/83xx/suspend-asm.S
index bc6bd4d0ae96..6a62ed6082c9 100644
--- a/arch/powerpc/platforms/83xx/suspend-asm.S
+++ b/arch/powerpc/platforms/83xx/suspend-asm.S
@@ -68,7 +68,8 @@ _GLOBAL(mpc83xx_enter_deep_sleep)
mfspr r5, SPRN_HID0
mfspr r6, SPRN_HID1
- mfspr r7, SPRN_HID2
+ /* FIXME: Should this use SPRN_HID2_G2_LE? */
+ mfspr r7, SPRN_HID2_750FX
stw r5, SS_HID+0(r3)
stw r6, SS_HID+4(r3)
@@ -396,7 +397,8 @@ mpc83xx_deep_resume:
mtspr SPRN_HID0, r5
mtspr SPRN_HID1, r6
- mtspr SPRN_HID2, r7
+ /* FIXME: Should this use SPRN_HID2_G2_LE? */
+ mtspr SPRN_HID2_750FX, r7
lwz r4, SS_IABR+0(r3)
lwz r5, SS_IABR+4(r3)
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 40aa58206888..e52b848b64b7 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -398,6 +398,7 @@ static void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
hard_irq_disable();
mpic_teardown_this_cpu(secondary);
+#ifdef CONFIG_CRASH_DUMP
if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) {
/*
* We enter the crash kernel on whatever cpu crashed,
@@ -406,9 +407,11 @@ static void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
*/
disable_threadbit = 1;
disable_cpu = cpu_first_thread_sibling(cpu);
- } else if (sibling != crashing_cpu &&
- cpu_thread_in_core(cpu) == 0 &&
- cpu_thread_in_core(sibling) != 0) {
+ } else if (sibling == crashing_cpu) {
+ return;
+ }
+#endif
+ if (cpu_thread_in_core(cpu) == 0 && cpu_thread_in_core(sibling) != 0) {
disable_threadbit = 2;
disable_cpu = sibling;
}
diff --git a/arch/powerpc/platforms/85xx/t1042rdb_diu.c b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
index 767eed98a0a8..d4fbb6eff38a 100644
--- a/arch/powerpc/platforms/85xx/t1042rdb_diu.c
+++ b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
@@ -149,4 +149,5 @@ static int __init t1042rdb_diu_init(void)
early_initcall(t1042rdb_diu_init);
+MODULE_DESCRIPTION("Freescale T1042 DIU driver");
MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 1fd253f92a77..1112a5831619 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -18,7 +18,6 @@ source "arch/powerpc/platforms/85xx/Kconfig"
source "arch/powerpc/platforms/86xx/Kconfig"
source "arch/powerpc/platforms/embedded6xx/Kconfig"
source "arch/powerpc/platforms/44x/Kconfig"
-source "arch/powerpc/platforms/40x/Kconfig"
source "arch/powerpc/platforms/amigaone/Kconfig"
source "arch/powerpc/platforms/book3s/Kconfig"
source "arch/powerpc/platforms/microwatt/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index b2d8c0da2ad9..4b0d7d4f88f6 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -43,19 +43,10 @@ config PPC_8xx
select HAVE_ARCH_VMAP_STACK
select HUGETLBFS
-config 40x
- bool "AMCC 40x"
- select PPC_DCR_NATIVE
- select PPC_UDBG_16550
- select 4xx_SOC
- select HAVE_PCI
- select PPC_KUEP if PPC_KUAP
-
config 44x
bool "AMCC 44x, 46x or 47x"
select PPC_DCR_NATIVE
select PPC_UDBG_16550
- select 4xx_SOC
select HAVE_PCI
select PHYS_64BIT
select PPC_KUEP
@@ -194,11 +185,6 @@ config E6500_CPU
depends on !CC_IS_CLANG
select PPC_HAS_LBARX_LHARX
-config 405_CPU
- bool "40x family"
- depends on 40x
- depends on !CC_IS_CLANG
-
config 440_CPU
bool "440 (44x family)"
depends on 44x
@@ -264,7 +250,6 @@ config TARGET_CPU
default "e6500" if E6500_CPU
default "power4" if POWERPC64_CPU && !CPU_LITTLE_ENDIAN
default "power8" if POWERPC64_CPU && CPU_LITTLE_ENDIAN
- default "405" if 405_CPU
default "440" if 440_CPU
default "464" if 464_CPU
default "476" if 476_CPU
@@ -340,7 +325,7 @@ config FSL_EMB_PERF_EVENT_E500
config 4xx
bool
- depends on 40x || 44x
+ depends on 44x
default y
config BOOKE
@@ -348,11 +333,6 @@ config BOOKE
depends on PPC_E500 || 44x
default y
-config BOOKE_OR_40x
- bool
- depends on BOOKE || 40x
- default y
-
config PTE_64BIT
bool
depends on 44x || PPC_E500 || PPC_86xx
@@ -495,8 +475,8 @@ config PPC_KERNEL_PCREL
This option builds the kernel with the pc relative ABI model.
config PPC_KUEP
- bool "Kernel Userspace Execution Prevention" if !40x
- default y if !40x
+ bool "Kernel Userspace Execution Prevention"
+ default y
help
Enable support for Kernel Userspace Execution Prevention (KUEP)
@@ -582,7 +562,7 @@ config NR_CPUS
config NOT_COHERENT_CACHE
bool
- depends on 4xx || PPC_8xx || PPC_MPC512x || \
+ depends on 44x || PPC_8xx || PPC_MPC512x || \
GAMECUBE_COMMON || AMIGAONE
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 94470fb27c99..786d374bff31 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -4,8 +4,6 @@ obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o
obj-$(CONFIG_PPC_PMAC) += powermac/
obj-$(CONFIG_PPC_CHRP) += chrp/
-obj-$(CONFIG_4xx) += 4xx/
-obj-$(CONFIG_40x) += 40x/
obj-$(CONFIG_44x) += 44x/
obj-$(CONFIG_PPC_MPC512x) += 512x/
obj-$(CONFIG_PPC_MPC52xx) += 52xx/
diff --git a/arch/powerpc/platforms/cell/cbe_powerbutton.c b/arch/powerpc/platforms/cell/cbe_powerbutton.c
index a3ee397486f6..3d121acdf69b 100644
--- a/arch/powerpc/platforms/cell/cbe_powerbutton.c
+++ b/arch/powerpc/platforms/cell/cbe_powerbutton.c
@@ -101,5 +101,6 @@ static void __exit cbe_powerbutton_exit(void)
module_init(cbe_powerbutton_init);
module_exit(cbe_powerbutton_exit);
+MODULE_DESCRIPTION("Driver for powerbutton on IBM cell blades");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c
index 2f45428e32c8..c295c6714f9b 100644
--- a/arch/powerpc/platforms/cell/cbe_thermal.c
+++ b/arch/powerpc/platforms/cell/cbe_thermal.c
@@ -381,6 +381,7 @@ static void __exit thermal_exit(void)
}
module_exit(thermal_exit);
+MODULE_DESCRIPTION("Cell processor thermal driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/cpufreq_spudemand.c b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
index ca7849e113d7..79172ba36eca 100644
--- a/arch/powerpc/platforms/cell/cpufreq_spudemand.c
+++ b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
@@ -129,5 +129,6 @@ static struct cpufreq_governor spu_governor = {
cpufreq_governor_init(spu_governor);
cpufreq_governor_exit(spu_governor);
+MODULE_DESCRIPTION("SPU-aware cpufreq governor for the cell processor");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 1202a69b0a20..4cd9c0de22c2 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -424,23 +424,6 @@ static void __init cell_iommu_setup_hardware(struct cbe_iommu *iommu,
cell_iommu_enable_hardware(iommu);
}
-#if 0/* Unused for now */
-static struct iommu_window *find_window(struct cbe_iommu *iommu,
- unsigned long offset, unsigned long size)
-{
- struct iommu_window *window;
-
- /* todo: check for overlapping (but not equal) windows) */
-
- list_for_each_entry(window, &(iommu->windows), list) {
- if (window->offset == offset && window->size == size)
- return window;
- }
-
- return NULL;
-}
-#endif
-
static inline u32 cell_iommu_get_ioid(struct device_node *np)
{
const u32 *ioid;
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index 30394c6f8894..fee638fd8970 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -54,6 +54,7 @@ static cpumask_t of_spin_map;
/**
* smp_startup_cpu() - start the given cpu
+ * @lcpu: Logical CPU ID of the CPU to be started.
*
* At boot time, there is nothing to do for primary threads which were
* started from Open Firmware. For anything else, call RTAS with the
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 02a8158c469d..7f4e0db8eb08 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1704,23 +1704,11 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
ret = spu_acquire(ctx);
if (ret)
- goto out;
-#if 0
-/* this currently hangs */
- ret = spufs_wait(ctx->mfc_wq,
- ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2));
- if (ret)
- goto out;
- ret = spufs_wait(ctx->mfc_wq,
- ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
- if (ret)
- goto out;
-#else
- ret = 0;
-#endif
+ return ret;
+
spu_release(ctx);
-out:
- return ret;
+
+ return 0;
}
static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int datasync)
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 030de2b8c145..70236d1df3d3 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -822,6 +822,7 @@ static void __exit spufs_exit(void)
}
module_exit(spufs_exit);
+MODULE_DESCRIPTION("SPU file system");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 99bd027a7f7c..610ca8570682 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -868,7 +868,7 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
}
/**
- * spu_deactivate - unbind a context from it's physical spu
+ * spu_deactivate - unbind a context from its physical spu
* @ctx: spu context to unbind
*
* Unbind @ctx from the physical spu it is running on and schedule
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
index 0eedae96498c..d3bf56a46656 100644
--- a/arch/powerpc/platforms/chrp/nvram.c
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -92,4 +92,5 @@ void __init chrp_nvram_init(void)
return;
}
+MODULE_DESCRIPTION("PPC NVRAM device driver");
MODULE_LICENSE("GPL v2");
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index b911b31717cc..b9ff37c7f6f0 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -595,7 +595,7 @@ void __init maple_pci_init(void)
/* Probe root PCI hosts, that is on U3 the AGP host and the
* HyperTransport host. That one is actually "kept" around
- * and actually added last as it's resource management relies
+ * and actually added last as its resource management relies
* on the AGP resources to have been setup first
*/
root = of_find_node_by_path("/");
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 7135ea1d7db6..2202bf77c7a3 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -2,7 +2,7 @@
/*
* Support for the interrupt controllers found on Power Macintosh,
* currently Apple's "Grand Central" interrupt controller in all
- * it's incarnations. OpenPIC support used on newer machines is
+ * its incarnations. OpenPIC support used on newer machines is
* in a separate file
*
* Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
index d497a60003d2..822ed70cdcbf 100644
--- a/arch/powerpc/platforms/powermac/sleep.S
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -176,7 +176,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
* memory location containing the PC to resume from
* at address 0.
* - On Core99, we must store the wakeup vector at
- * address 0x80 and eventually it's parameters
+ * address 0x80 and eventually its parameters
* at address 0x84. I've have some trouble with those
* parameters however and I no longer use them.
*/
diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c
index 964f464b1b0e..c9c1dfb35464 100644
--- a/arch/powerpc/platforms/powernv/opal-fadump.c
+++ b/arch/powerpc/platforms/powernv/opal-fadump.c
@@ -513,8 +513,8 @@ out:
final_note(note_buf);
pr_debug("Updating elfcore header (%llx) with cpu notes\n",
- fdh->elfcorehdr_addr);
- fadump_update_elfcore_header(__va(fdh->elfcorehdr_addr));
+ fadump_conf->elfcorehdr_addr);
+ fadump_update_elfcore_header((char *)fadump_conf->elfcorehdr_addr);
return 0;
}
@@ -526,12 +526,7 @@ static int __init opal_fadump_process(struct fw_dump *fadump_conf)
if (!opal_fdm_active || !fadump_conf->fadumphdr_addr)
return rc;
- /* Validate the fadump crash info header */
fdh = __va(fadump_conf->fadumphdr_addr);
- if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
- pr_err("Crash info header is not valid.\n");
- return rc;
- }
#ifdef CONFIG_OPAL_CORE
/*
@@ -545,18 +540,7 @@ static int __init opal_fadump_process(struct fw_dump *fadump_conf)
kernel_initiated = true;
#endif
- rc = opal_fadump_build_cpu_notes(fadump_conf, fdh);
- if (rc)
- return rc;
-
- /*
- * We are done validating dump info and elfcore header is now ready
- * to be exported. set elfcorehdr_addr so that vmcore module will
- * export the elfcore header through '/proc/vmcore'.
- */
- elfcorehdr_addr = fdh->elfcorehdr_addr;
-
- return rc;
+ return opal_fadump_build_cpu_notes(fadump_conf, fdh);
}
static void opal_fadump_region_show(struct fw_dump *fadump_conf,
@@ -615,6 +599,12 @@ static void opal_fadump_trigger(struct fadump_crash_info_header *fdh,
pr_emerg("No backend support for MPIPL!\n");
}
+/* FADUMP_MAX_MEM_REGS or lower */
+static int opal_fadump_max_boot_mem_rgns(void)
+{
+ return FADUMP_MAX_MEM_REGS;
+}
+
static struct fadump_ops opal_fadump_ops = {
.fadump_init_mem_struct = opal_fadump_init_mem_struct,
.fadump_get_metadata_size = opal_fadump_get_metadata_size,
@@ -627,6 +617,7 @@ static struct fadump_ops opal_fadump_ops = {
.fadump_process = opal_fadump_process,
.fadump_region_show = opal_fadump_region_show,
.fadump_trigger = opal_fadump_trigger,
+ .fadump_max_boot_mem_rgns = opal_fadump_max_boot_mem_rgns,
};
void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
@@ -674,8 +665,10 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
}
}
- fadump_conf->ops = &opal_fadump_ops;
- fadump_conf->fadump_supported = 1;
+ fadump_conf->ops = &opal_fadump_ops;
+ fadump_conf->fadump_supported = 1;
+ /* TODO: Add support to pass additional parameters */
+ fadump_conf->param_area_supported = 0;
/*
* Firmware supports 32-bit field for size. Align it to PAGE_SIZE
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 45dd77e3ccf6..5d0f35bb917e 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -792,14 +792,6 @@ static int __init opal_sysfs_init(void)
return 0;
}
-static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
-{
- return memory_read_from_buffer(buf, count, &off, bin_attr->private,
- bin_attr->size);
-}
-
static int opal_add_one_export(struct kobject *parent, const char *export_name,
struct device_node *np, const char *prop_name)
{
@@ -826,7 +818,7 @@ static int opal_add_one_export(struct kobject *parent, const char *export_name,
sysfs_bin_attr_init(attr);
attr->attr.name = name;
attr->attr.mode = 0400;
- attr->read = export_attr_read;
+ attr->read = sysfs_bin_attr_simple_read;
attr->private = __va(vals[0]);
attr->size = vals[1];
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 23f5b5093ec1..b0a14e48175c 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1537,7 +1537,8 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
}
}
-static long pnv_ioda2_take_ownership(struct iommu_table_group *table_group)
+static long pnv_ioda2_take_ownership(struct iommu_table_group *table_group,
+ struct device *dev __maybe_unused)
{
struct pnv_ioda_pe *pe = container_of(table_group, struct pnv_ioda_pe,
table_group);
@@ -1562,7 +1563,8 @@ static long pnv_ioda2_take_ownership(struct iommu_table_group *table_group)
return 0;
}
-static void pnv_ioda2_release_ownership(struct iommu_table_group *table_group)
+static void pnv_ioda2_release_ownership(struct iommu_table_group *table_group,
+ struct device *dev __maybe_unused)
{
struct pnv_ioda_pe *pe = container_of(table_group, struct pnv_ioda_pe,
table_group);
diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c
index 59882da3e742..cc7b1dd54ac6 100644
--- a/arch/powerpc/platforms/powernv/pci-sriov.c
+++ b/arch/powerpc/platforms/powernv/pci-sriov.c
@@ -238,7 +238,7 @@ void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev)
} else if (pdev->is_physfn) {
/*
* For PFs adjust their allocated IOV resources to match what
- * the PHB can support using it's M64 BAR table.
+ * the PHB can support using its M64 BAR table.
*/
pnv_pci_ioda_fixup_iov_resources(pdev);
}
@@ -658,7 +658,7 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
list_add_tail(&pe->list, &phb->ioda.pe_list);
mutex_unlock(&phb->ioda.pe_list_mutex);
- /* associate this pe to it's pdn */
+ /* associate this pe to its pdn */
list_for_each_entry(vf_pdn, &pdn->parent->child_list, list) {
if (vf_pdn->busno == vf_bus &&
vf_pdn->devfn == vf_devfn) {
diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
index b664838008c1..5147df3a18ac 100644
--- a/arch/powerpc/platforms/powernv/vas-window.c
+++ b/arch/powerpc/platforms/powernv/vas-window.c
@@ -1059,7 +1059,7 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
}
} else {
/*
- * Interrupt hanlder or fault window setup failed. Means
+ * Interrupt handler or fault window setup failed. Means
* NX can not generate fault for page fault. So not
* opening for user space tx window.
*/
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 878bc160246e..b18e1c92e554 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -770,49 +770,51 @@ static struct task_struct *probe_task;
static int ps3_probe_thread(void *data)
{
- struct ps3_notification_device dev;
+ struct {
+ struct ps3_notification_device dev;
+ u8 buf[512];
+ } *local;
+ struct ps3_notify_cmd *notify_cmd;
+ struct ps3_notify_event *notify_event;
int res;
unsigned int irq;
u64 lpar;
- void *buf;
- struct ps3_notify_cmd *notify_cmd;
- struct ps3_notify_event *notify_event;
pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
- buf = kzalloc(512, GFP_KERNEL);
- if (!buf)
+ local = kzalloc(sizeof(*local), GFP_KERNEL);
+ if (!local)
return -ENOMEM;
- lpar = ps3_mm_phys_to_lpar(__pa(buf));
- notify_cmd = buf;
- notify_event = buf;
+ lpar = ps3_mm_phys_to_lpar(__pa(&local->buf));
+ notify_cmd = (struct ps3_notify_cmd *)&local->buf;
+ notify_event = (struct ps3_notify_event *)&local->buf;
/* dummy system bus device */
- dev.sbd.bus_id = (u64)data;
- dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
- dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
+ local->dev.sbd.bus_id = (u64)data;
+ local->dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
+ local->dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
- res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
+ res = lv1_open_device(local->dev.sbd.bus_id, local->dev.sbd.dev_id, 0);
if (res) {
pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
__LINE__, ps3_result(res));
goto fail_free;
}
- res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
- &irq);
+ res = ps3_sb_event_receive_port_setup(&local->dev.sbd,
+ PS3_BINDING_CPU_ANY, &irq);
if (res) {
pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
__func__, __LINE__, res);
goto fail_close_device;
}
- spin_lock_init(&dev.lock);
- rcuwait_init(&dev.wait);
+ spin_lock_init(&local->dev.lock);
+ rcuwait_init(&local->dev.wait);
res = request_irq(irq, ps3_notification_interrupt, 0,
- "ps3_notification", &dev);
+ "ps3_notification", &local->dev);
if (res) {
pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
res);
@@ -823,7 +825,7 @@ static int ps3_probe_thread(void *data)
notify_cmd->operation_code = 0; /* must be zero */
notify_cmd->event_mask = 1UL << notify_region_probe;
- res = ps3_notification_read_write(&dev, lpar, 1);
+ res = ps3_notification_read_write(&local->dev, lpar, 1);
if (res)
goto fail_free_irq;
@@ -834,36 +836,37 @@ static int ps3_probe_thread(void *data)
memset(notify_event, 0, sizeof(*notify_event));
- res = ps3_notification_read_write(&dev, lpar, 0);
+ res = ps3_notification_read_write(&local->dev, lpar, 0);
if (res)
break;
pr_debug("%s:%u: notify event type 0x%llx bus id %llu dev id %llu"
" type %llu port %llu\n", __func__, __LINE__,
- notify_event->event_type, notify_event->bus_id,
- notify_event->dev_id, notify_event->dev_type,
- notify_event->dev_port);
+ notify_event->event_type, notify_event->bus_id,
+ notify_event->dev_id, notify_event->dev_type,
+ notify_event->dev_port);
if (notify_event->event_type != notify_region_probe ||
- notify_event->bus_id != dev.sbd.bus_id) {
+ notify_event->bus_id != local->dev.sbd.bus_id) {
pr_warn("%s:%u: bad notify_event: event %llu, dev_id %llu, dev_type %llu\n",
__func__, __LINE__, notify_event->event_type,
notify_event->dev_id, notify_event->dev_type);
continue;
}
- ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
+ ps3_find_and_add_device(local->dev.sbd.bus_id,
+ notify_event->dev_id);
} while (!kthread_should_stop());
fail_free_irq:
- free_irq(irq, &dev);
+ free_irq(irq, &local->dev);
fail_sb_event_receive_port_destroy:
- ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
+ ps3_sb_event_receive_port_destroy(&local->dev.sbd, irq);
fail_close_device:
- lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
+ lv1_close_device(local->dev.sbd.bus_id, local->dev.sbd.dev_id);
fail_free:
- kfree(buf);
+ kfree(local);
probe_task = NULL;
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index d6b5f5ecd515..b9a7d9bae687 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -333,10 +333,10 @@ int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
static int ps3_system_bus_match(struct device *_dev,
- struct device_driver *_drv)
+ const struct device_driver *_drv)
{
int result;
- struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
+ const struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
if (!dev->match_sub_id)
@@ -695,7 +695,7 @@ 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,
+ .alloc_pages_op = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
};
@@ -709,7 +709,7 @@ 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,
+ .alloc_pages_op = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
};
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index f936962a2946..7bf506f6b8c8 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG
obj-y := lpar.o hvCall.o nvram.o reconfig.o \
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index b401282727a4..3436b0af795e 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -339,7 +339,7 @@ static struct attribute *ibmbus_bus_attrs[] = {
};
ATTRIBUTE_GROUPS(ibmbus_bus);
-static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv)
+static int ibmebus_bus_bus_match(struct device *dev, const struct device_driver *drv)
{
const struct of_device_id *matches = drv->of_match_table;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index b1e6d275cda9..534cd159e9ab 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -21,6 +21,7 @@
#include <linux/dma-mapping.h>
#include <linux/crash_dump.h>
#include <linux/memory.h>
+#include <linux/vmalloc.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/iommu.h>
@@ -67,6 +68,10 @@ static struct iommu_table *iommu_pseries_alloc_table(int node)
return tbl;
}
+#ifdef CONFIG_IOMMU_API
+static struct iommu_table_group_ops spapr_tce_table_group_ops;
+#endif
+
static struct iommu_table_group *iommu_pseries_alloc_group(int node)
{
struct iommu_table_group *table_group;
@@ -102,7 +107,7 @@ static void iommu_pseries_free_group(struct iommu_table_group *table_group,
#endif
/* Default DMA window table is at index 0, while DDW at 1. SR-IOV
- * adapters only have table on index 1.
+ * adapters only have table on index 0(if not direct mapped).
*/
if (table_group->tables[0])
iommu_tce_table_put(table_group->tables[0]);
@@ -143,7 +148,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
}
-static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
+static void tce_clear_pSeries(struct iommu_table *tbl, long index, long npages)
{
__be64 *tcep;
@@ -162,6 +167,39 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
return be64_to_cpu(*tcep);
}
+#ifdef CONFIG_IOMMU_API
+static long pseries_tce_iommu_userspace_view_alloc(struct iommu_table *tbl)
+{
+ unsigned long cb = ALIGN(sizeof(tbl->it_userspace[0]) * tbl->it_size, PAGE_SIZE);
+ unsigned long *uas;
+
+ if (tbl->it_indirect_levels) /* Impossible */
+ return -EPERM;
+
+ WARN_ON(tbl->it_userspace);
+
+ uas = vzalloc(cb);
+ if (!uas)
+ return -ENOMEM;
+
+ tbl->it_userspace = (__be64 *) uas;
+
+ return 0;
+}
+#endif
+
+static void tce_iommu_userspace_view_free(struct iommu_table *tbl)
+{
+ vfree(tbl->it_userspace);
+ tbl->it_userspace = NULL;
+}
+
+static void tce_free_pSeries(struct iommu_table *tbl)
+{
+ if (!tbl->it_userspace)
+ tce_iommu_userspace_view_free(tbl);
+}
+
static void tce_free_pSeriesLP(unsigned long liobn, long, long, long);
static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long);
@@ -576,7 +614,7 @@ struct iommu_table_ops iommu_table_lpar_multi_ops;
struct iommu_table_ops iommu_table_pseries_ops = {
.set = tce_build_pSeries,
- .clear = tce_free_pSeries,
+ .clear = tce_clear_pSeries,
.get = tce_get_pseries
};
@@ -685,17 +723,47 @@ static int tce_exchange_pseries(struct iommu_table *tbl, long index, unsigned
return rc;
}
+
+static __be64 *tce_useraddr_pSeriesLP(struct iommu_table *tbl, long index,
+ bool __always_unused alloc)
+{
+ return tbl->it_userspace ? &tbl->it_userspace[index - tbl->it_offset] : NULL;
+}
#endif
struct iommu_table_ops iommu_table_lpar_multi_ops = {
.set = tce_buildmulti_pSeriesLP,
#ifdef CONFIG_IOMMU_API
.xchg_no_kill = tce_exchange_pseries,
+ .useraddrptr = tce_useraddr_pSeriesLP,
#endif
.clear = tce_freemulti_pSeriesLP,
- .get = tce_get_pSeriesLP
+ .get = tce_get_pSeriesLP,
+ .free = tce_free_pSeries
};
+#ifdef CONFIG_IOMMU_API
+/*
+ * When the DMA window properties might have been removed,
+ * the parent node has the table_group setup on it.
+ */
+static struct device_node *pci_dma_find_parent_node(struct pci_dev *dev,
+ struct iommu_table_group *table_group)
+{
+ struct device_node *dn = pci_device_to_OF_node(dev);
+ struct pci_dn *rpdn;
+
+ for (; dn && PCI_DN(dn); dn = dn->parent) {
+ rpdn = PCI_DN(dn);
+
+ if (table_group == rpdn->table_group)
+ return dn;
+ }
+
+ return NULL;
+}
+#endif
+
/*
* Find nearest ibm,dma-window (default DMA window) or direct DMA window or
* dynamic 64bit DMA window, walking up the device tree.
@@ -812,13 +880,6 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
be32_to_cpu(prop.tce_shift), NULL,
&iommu_table_lpar_multi_ops);
- /* Only for normal boot with default window. Doesn't matter even
- * if we set these with DDW which is 64bit during kdump, since
- * these will not be used during kdump.
- */
- ppci->table_group->tce32_start = be64_to_cpu(prop.dma_base);
- ppci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift);
-
if (!iommu_init_table(tbl, ppci->phb->node, 0, 0))
panic("Failed to initialize iommu table");
@@ -917,7 +978,7 @@ static void __remove_dma_window(struct device_node *np, u32 *ddw_avail, u64 liob
}
static void remove_dma_window(struct device_node *np, u32 *ddw_avail,
- struct property *win)
+ struct property *win, bool cleanup)
{
struct dynamic_dma_window_prop *dwp;
u64 liobn;
@@ -925,11 +986,44 @@ static void remove_dma_window(struct device_node *np, u32 *ddw_avail,
dwp = win->value;
liobn = (u64)be32_to_cpu(dwp->liobn);
- clean_dma_window(np, dwp);
+ if (cleanup)
+ clean_dma_window(np, dwp);
__remove_dma_window(np, ddw_avail, liobn);
}
-static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_name)
+static void copy_property(struct device_node *pdn, const char *from, const char *to)
+{
+ struct property *src, *dst;
+
+ src = of_find_property(pdn, from, NULL);
+ if (!src)
+ return;
+
+ dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+ if (!dst)
+ return;
+
+ dst->name = kstrdup(to, GFP_KERNEL);
+ dst->value = kmemdup(src->value, src->length, GFP_KERNEL);
+ dst->length = src->length;
+ if (!dst->name || !dst->value)
+ return;
+
+ if (of_add_property(pdn, dst)) {
+ pr_err("Unable to add DMA window property for %pOF", pdn);
+ goto free_prop;
+ }
+
+ return;
+
+free_prop:
+ kfree(dst->name);
+ kfree(dst->value);
+ kfree(dst);
+}
+
+static int remove_dma_window_named(struct device_node *np, bool remove_prop, const char *win_name,
+ bool cleanup)
{
struct property *win;
u32 ddw_avail[DDW_APPLICABLE_SIZE];
@@ -944,13 +1038,20 @@ static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_
if (ret)
return 0;
-
if (win->length >= sizeof(struct dynamic_dma_window_prop))
- remove_dma_window(np, ddw_avail, win);
+ remove_dma_window(np, ddw_avail, win, cleanup);
if (!remove_prop)
return 0;
+ /* Default window property if removed is lost as reset-pe doesn't restore it.
+ * Though FDT has a copy of it, the DLPAR hotplugged devices will not have a
+ * node on FDT until next reboot. So, back it up.
+ */
+ if ((strcmp(win_name, "ibm,dma-window") == 0) &&
+ !of_find_property(np, "ibm,dma-window-saved", NULL))
+ copy_property(np, win_name, "ibm,dma-window-saved");
+
ret = of_remove_property(np, win);
if (ret)
pr_warn("%pOF: failed to remove DMA window property: %d\n",
@@ -1008,7 +1109,7 @@ static void find_existing_ddw_windows_named(const char *name)
for_each_node_with_property(pdn, name) {
dma64 = of_get_property(pdn, name, &len);
if (!dma64 || len < sizeof(*dma64)) {
- remove_ddw(pdn, true, name);
+ remove_dma_window_named(pdn, true, name, true);
continue;
}
@@ -1304,7 +1405,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
struct ddw_query_response query;
struct ddw_create_response create;
int page_shift;
- u64 win_addr;
+ u64 win_addr, dynamic_offset = 0;
const char *win_name;
struct device_node *dn;
u32 ddw_avail[DDW_APPLICABLE_SIZE];
@@ -1312,6 +1413,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
struct property *win64;
struct failed_ddw_pdn *fpdn;
bool default_win_removed = false, direct_mapping = false;
+ bool dynamic_mapping = false;
bool pmem_present;
struct pci_dn *pci = PCI_DN(pdn);
struct property *default_win = NULL;
@@ -1385,7 +1487,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
if (reset_win_ext)
goto out_failed;
- remove_dma_window(pdn, ddw_avail, default_win);
+ remove_dma_window(pdn, ddw_avail, default_win, true);
default_win_removed = true;
/* Query again, to check if the window is available */
@@ -1407,7 +1509,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
goto out_failed;
}
-
/*
* The "ibm,pmemory" can appear anywhere in the address space.
* Assuming it is still backed by page structs, try MAX_PHYSMEM_BITS
@@ -1432,14 +1533,42 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1ULL << page_shift);
len = order_base_2(query.largest_available_block << page_shift);
- win_name = DMA64_PROPNAME;
+
+ dynamic_mapping = true;
} else {
direct_mapping = !default_win_removed ||
(len == MAX_PHYSMEM_BITS) ||
(!pmem_present && (len == max_ram_len));
- win_name = direct_mapping ? DIRECT64_PROPNAME : DMA64_PROPNAME;
+
+ /* DDW is big enough to direct map RAM. If there is vPMEM, check
+ * if enough space is left in DDW where we can dynamically
+ * allocate TCEs for vPMEM. For now, this Hybrid sharing of DDW
+ * is only for SR-IOV devices.
+ */
+ if (default_win_removed && pmem_present && !direct_mapping) {
+ /* DDW is big enough to be split */
+ if ((query.largest_available_block << page_shift) >=
+ MIN_DDW_VPMEM_DMA_WINDOW + (1ULL << max_ram_len)) {
+ direct_mapping = true;
+
+ /* offset of the Dynamic part of DDW */
+ dynamic_offset = 1ULL << max_ram_len;
+ }
+
+ /* DDW will at least have dynamic allocation */
+ dynamic_mapping = true;
+
+ /* create max size DDW possible */
+ len = order_base_2(query.largest_available_block
+ << page_shift);
+ }
}
+ /* Even if the DDW is split into both direct mapped RAM and dynamically
+ * mapped vPMEM, the DDW property in OF will be marked as Direct.
+ */
+ win_name = direct_mapping ? DIRECT64_PROPNAME : DMA64_PROPNAME;
+
ret = create_ddw(dev, ddw_avail, &create, page_shift, len);
if (ret != 0)
goto out_failed;
@@ -1467,9 +1596,9 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
if (!window)
goto out_del_prop;
- if (direct_mapping) {
- window->direct = true;
+ window->direct = direct_mapping;
+ if (direct_mapping) {
/* DDW maps the whole partition, so enable direct DMA mapping */
ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT,
win64->value, tce_setrange_multi_pSeriesLP_walk);
@@ -1481,12 +1610,18 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
clean_dma_window(pdn, win64->value);
goto out_del_list;
}
- } else {
+ if (default_win_removed) {
+ iommu_tce_table_put(pci->table_group->tables[0]);
+ pci->table_group->tables[0] = NULL;
+ set_iommu_table_base(&dev->dev, NULL);
+ }
+ }
+
+ if (dynamic_mapping) {
struct iommu_table *newtbl;
int i;
unsigned long start = 0, end = 0;
-
- window->direct = false;
+ u64 dynamic_addr, dynamic_len;
for (i = 0; i < ARRAY_SIZE(pci->phb->mem_resources); i++) {
const unsigned long mask = IORESOURCE_MEM_64 | IORESOURCE_MEM;
@@ -1506,20 +1641,26 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
goto out_del_list;
}
- iommu_table_setparms_common(newtbl, pci->phb->bus->number, create.liobn, win_addr,
- 1UL << len, page_shift, NULL, &iommu_table_lpar_multi_ops);
+ /* If the DDW is split between directly mapped RAM and Dynamic
+ * mapped for TCES, offset into the DDW where the dynamic part
+ * begins.
+ */
+ dynamic_addr = win_addr + dynamic_offset;
+ dynamic_len = (1UL << len) - dynamic_offset;
+ iommu_table_setparms_common(newtbl, pci->phb->bus->number, create.liobn,
+ dynamic_addr, dynamic_len, page_shift, NULL,
+ &iommu_table_lpar_multi_ops);
iommu_init_table(newtbl, pci->phb->node, start, end);
- pci->table_group->tables[1] = newtbl;
+ pci->table_group->tables[default_win_removed ? 0 : 1] = newtbl;
set_iommu_table_base(&dev->dev, newtbl);
}
if (default_win_removed) {
- iommu_tce_table_put(pci->table_group->tables[0]);
- pci->table_group->tables[0] = NULL;
-
/* default_win is valid here because default_win_removed == true */
+ if (!of_find_property(pdn, "ibm,dma-window-saved", NULL))
+ copy_property(pdn, "ibm,dma-window", "ibm,dma-window-saved");
of_remove_property(pdn, default_win);
dev_info(&dev->dev, "Removed default DMA window for %pOF\n", pdn);
}
@@ -1559,17 +1700,81 @@ out_failed:
out_unlock:
mutex_unlock(&dma_win_init_mutex);
- /*
- * If we have persistent memory and the window size is only as big
- * as RAM, then we failed to create a window to cover persistent
- * memory and need to set the DMA limit.
+ /* If we have persistent memory and the window size is not big enough
+ * to directly map both RAM and vPMEM, then we need to set DMA limit.
*/
- if (pmem_present && direct_mapping && len == max_ram_len)
- dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + (1ULL << len);
+ if (pmem_present && direct_mapping && len != MAX_PHYSMEM_BITS)
+ dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset +
+ (1ULL << max_ram_len);
return direct_mapping;
}
+static __u64 query_page_size_to_mask(u32 query_page_size)
+{
+ const long shift[] = {
+ (SZ_4K), (SZ_64K), (SZ_16M),
+ (SZ_32M), (SZ_64M), (SZ_128M),
+ (SZ_256M), (SZ_16G), (SZ_2M)
+ };
+ int i, ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(shift); i++) {
+ if (query_page_size & (1 << i))
+ ret |= shift[i];
+ }
+
+ return ret;
+}
+
+static void spapr_tce_init_table_group(struct pci_dev *pdev,
+ struct device_node *pdn,
+ struct dynamic_dma_window_prop prop)
+{
+ struct iommu_table_group *table_group = PCI_DN(pdn)->table_group;
+ u32 ddw_avail[DDW_APPLICABLE_SIZE];
+
+ struct ddw_query_response query;
+ int ret;
+
+ /* Only for normal boot with default window. Doesn't matter during
+ * kdump, since these will not be used during kdump.
+ */
+ if (is_kdump_kernel())
+ return;
+
+ if (table_group->max_dynamic_windows_supported != 0)
+ return; /* already initialized */
+
+ table_group->tce32_start = be64_to_cpu(prop.dma_base);
+ table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift);
+
+ if (!of_find_property(pdn, "ibm,dma-window", NULL))
+ dev_err(&pdev->dev, "default dma window missing!\n");
+
+ ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable",
+ &ddw_avail[0], DDW_APPLICABLE_SIZE);
+ if (ret) {
+ table_group->max_dynamic_windows_supported = -1;
+ return;
+ }
+
+ ret = query_ddw(pdev, ddw_avail, &query, pdn);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: query_ddw failed\n", __func__);
+ table_group->max_dynamic_windows_supported = -1;
+ return;
+ }
+
+ if (query.windows_available == 0)
+ table_group->max_dynamic_windows_supported = 1;
+ else
+ table_group->max_dynamic_windows_supported = IOMMU_TABLE_GROUP_MAX_TABLES;
+
+ table_group->max_levels = 1;
+ table_group->pgsizes |= query_page_size_to_mask(query.page_size);
+}
+
static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
{
struct device_node *pdn, *dn;
@@ -1609,13 +1814,6 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
be32_to_cpu(prop.tce_shift), NULL,
&iommu_table_lpar_multi_ops);
- /* Only for normal boot with default window. Doesn't matter even
- * if we set these with DDW which is 64bit during kdump, since
- * these will not be used during kdump.
- */
- pci->table_group->tce32_start = be64_to_cpu(prop.dma_base);
- pci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift);
-
iommu_init_table(tbl, pci->phb->node, 0, 0);
iommu_register_group(pci->table_group,
pci_domain_nr(pci->phb->bus), 0);
@@ -1624,6 +1822,8 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
pr_debug(" found DMA window, table: %p\n", pci->table_group);
}
+ spapr_tce_init_table_group(dev, pdn, prop);
+
set_iommu_table_base(&dev->dev, pci->table_group->tables[0]);
iommu_add_device(pci->table_group, &dev->dev);
}
@@ -1651,6 +1851,491 @@ static bool iommu_bypass_supported_pSeriesLP(struct pci_dev *pdev, u64 dma_mask)
return false;
}
+#ifdef CONFIG_IOMMU_API
+/*
+ * A simple iommu_table_group_ops which only allows reusing the existing
+ * iommu_table. This handles VFIO for POWER7 or the nested KVM.
+ * The ops does not allow creating windows and only allows reusing the existing
+ * one if it matches table_group->tce32_start/tce32_size/page_shift.
+ */
+static unsigned long spapr_tce_get_table_size(__u32 page_shift,
+ __u64 window_size, __u32 levels)
+{
+ unsigned long size;
+
+ if (levels > 1)
+ return ~0U;
+ size = window_size >> (page_shift - 3);
+ return size;
+}
+
+static struct pci_dev *iommu_group_get_first_pci_dev(struct iommu_group *group)
+{
+ struct pci_dev *pdev = NULL;
+ int ret;
+
+ /* No IOMMU group ? */
+ if (!group)
+ return NULL;
+
+ ret = iommu_group_for_each_dev(group, &pdev, dev_has_iommu_table);
+ if (!ret || !pdev)
+ return NULL;
+ return pdev;
+}
+
+static void restore_default_dma_window(struct pci_dev *pdev, struct device_node *pdn)
+{
+ reset_dma_window(pdev, pdn);
+ copy_property(pdn, "ibm,dma-window-saved", "ibm,dma-window");
+}
+
+static long remove_dynamic_dma_windows(struct pci_dev *pdev, struct device_node *pdn)
+{
+ struct pci_dn *pci = PCI_DN(pdn);
+ struct dma_win *window;
+ bool direct_mapping;
+ int len;
+
+ if (find_existing_ddw(pdn, &pdev->dev.archdata.dma_offset, &len, &direct_mapping)) {
+ remove_dma_window_named(pdn, true, direct_mapping ?
+ DIRECT64_PROPNAME : DMA64_PROPNAME, true);
+ if (!direct_mapping) {
+ WARN_ON(!pci->table_group->tables[0] && !pci->table_group->tables[1]);
+
+ if (pci->table_group->tables[1]) {
+ iommu_tce_table_put(pci->table_group->tables[1]);
+ pci->table_group->tables[1] = NULL;
+ } else if (pci->table_group->tables[0]) {
+ /* Default window was removed and only the DDW exists */
+ iommu_tce_table_put(pci->table_group->tables[0]);
+ pci->table_group->tables[0] = NULL;
+ }
+ }
+ spin_lock(&dma_win_list_lock);
+ list_for_each_entry(window, &dma_win_list, list) {
+ if (window->device == pdn) {
+ list_del(&window->list);
+ kfree(window);
+ break;
+ }
+ }
+ spin_unlock(&dma_win_list_lock);
+ }
+
+ return 0;
+}
+
+static long pseries_setup_default_iommu_config(struct iommu_table_group *table_group,
+ struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ const __be32 *default_prop;
+ long liobn, offset, size;
+ struct device_node *pdn;
+ struct iommu_table *tbl;
+ struct pci_dn *pci;
+
+ pdn = pci_dma_find_parent_node(pdev, table_group);
+ if (!pdn || !PCI_DN(pdn)) {
+ dev_warn(&pdev->dev, "No table_group configured for the node %pOF\n", pdn);
+ return -1;
+ }
+ pci = PCI_DN(pdn);
+
+ /* The default window is restored if not present already on removal of DDW.
+ * However, if used by VFIO SPAPR sub driver, the user's order of removal of
+ * windows might have been different to not leading to auto restoration,
+ * suppose the DDW was removed first followed by the default one.
+ * So, restore the default window with reset-pe-dma call explicitly.
+ */
+ restore_default_dma_window(pdev, pdn);
+
+ default_prop = of_get_property(pdn, "ibm,dma-window", NULL);
+ of_parse_dma_window(pdn, default_prop, &liobn, &offset, &size);
+ tbl = iommu_pseries_alloc_table(pci->phb->node);
+ if (!tbl) {
+ dev_err(&pdev->dev, "couldn't create new IOMMU table\n");
+ return -1;
+ }
+
+ iommu_table_setparms_common(tbl, pci->phb->bus->number, liobn, offset,
+ size, IOMMU_PAGE_SHIFT_4K, NULL,
+ &iommu_table_lpar_multi_ops);
+ iommu_init_table(tbl, pci->phb->node, 0, 0);
+
+ pci->table_group->tables[0] = tbl;
+ set_iommu_table_base(&pdev->dev, tbl);
+
+ return 0;
+}
+
+static bool is_default_window_request(struct iommu_table_group *table_group, __u32 page_shift,
+ __u64 window_size)
+{
+ if ((window_size <= table_group->tce32_size) &&
+ (page_shift == IOMMU_PAGE_SHIFT_4K))
+ return true;
+
+ return false;
+}
+
+static long spapr_tce_create_table(struct iommu_table_group *table_group, int num,
+ __u32 page_shift, __u64 window_size, __u32 levels,
+ struct iommu_table **ptbl)
+{
+ struct pci_dev *pdev = iommu_group_get_first_pci_dev(table_group->group);
+ u32 ddw_avail[DDW_APPLICABLE_SIZE];
+ struct ddw_create_response create;
+ unsigned long liobn, offset, size;
+ unsigned long start = 0, end = 0;
+ struct ddw_query_response query;
+ const __be32 *default_prop;
+ struct failed_ddw_pdn *fpdn;
+ unsigned int window_shift;
+ struct device_node *pdn;
+ struct iommu_table *tbl;
+ struct dma_win *window;
+ struct property *win64;
+ struct pci_dn *pci;
+ u64 win_addr;
+ int len, i;
+ long ret;
+
+ if (!is_power_of_2(window_size) || levels > 1)
+ return -EINVAL;
+
+ window_shift = order_base_2(window_size);
+
+ mutex_lock(&dma_win_init_mutex);
+
+ ret = -ENODEV;
+
+ pdn = pci_dma_find_parent_node(pdev, table_group);
+ if (!pdn || !PCI_DN(pdn)) { /* Niether of 32s|64-bit exist! */
+ dev_warn(&pdev->dev, "No dma-windows exist for the node %pOF\n", pdn);
+ goto out_failed;
+ }
+ pci = PCI_DN(pdn);
+
+ /* If the enable DDW failed for the pdn, dont retry! */
+ list_for_each_entry(fpdn, &failed_ddw_pdn_list, list) {
+ if (fpdn->pdn == pdn) {
+ dev_info(&pdev->dev, "%pOF in failed DDW device list\n", pdn);
+ goto out_unlock;
+ }
+ }
+
+ tbl = iommu_pseries_alloc_table(pci->phb->node);
+ if (!tbl) {
+ dev_dbg(&pdev->dev, "couldn't create new IOMMU table\n");
+ goto out_unlock;
+ }
+
+ if (num == 0) {
+ bool direct_mapping;
+ /* The request is not for default window? Ensure there is no DDW window already */
+ if (!is_default_window_request(table_group, page_shift, window_size)) {
+ if (find_existing_ddw(pdn, &pdev->dev.archdata.dma_offset, &len,
+ &direct_mapping)) {
+ dev_warn(&pdev->dev, "%pOF: 64-bit window already present.", pdn);
+ ret = -EPERM;
+ goto out_unlock;
+ }
+ } else {
+ /* Request is for Default window, ensure there is no DDW if there is a
+ * need to reset. reset-pe otherwise removes the DDW also
+ */
+ default_prop = of_get_property(pdn, "ibm,dma-window", NULL);
+ if (!default_prop) {
+ if (find_existing_ddw(pdn, &pdev->dev.archdata.dma_offset, &len,
+ &direct_mapping)) {
+ dev_warn(&pdev->dev, "%pOF: Attempt to create window#0 when 64-bit window is present. Preventing the attempt as that would destroy the 64-bit window",
+ pdn);
+ ret = -EPERM;
+ goto out_unlock;
+ }
+
+ restore_default_dma_window(pdev, pdn);
+
+ default_prop = of_get_property(pdn, "ibm,dma-window", NULL);
+ of_parse_dma_window(pdn, default_prop, &liobn, &offset, &size);
+ /* Limit the default window size to window_size */
+ iommu_table_setparms_common(tbl, pci->phb->bus->number, liobn,
+ offset, 1UL << window_shift,
+ IOMMU_PAGE_SHIFT_4K, NULL,
+ &iommu_table_lpar_multi_ops);
+ iommu_init_table(tbl, pci->phb->node, start, end);
+
+ table_group->tables[0] = tbl;
+
+ mutex_unlock(&dma_win_init_mutex);
+
+ goto exit;
+ }
+ }
+ }
+
+ ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable",
+ &ddw_avail[0], DDW_APPLICABLE_SIZE);
+ if (ret) {
+ dev_info(&pdev->dev, "ibm,ddw-applicable not found\n");
+ goto out_failed;
+ }
+ ret = -ENODEV;
+
+ pr_err("%s: Calling query %pOF\n", __func__, pdn);
+ ret = query_ddw(pdev, ddw_avail, &query, pdn);
+ if (ret)
+ goto out_failed;
+ ret = -ENODEV;
+
+ len = window_shift;
+ if (query.largest_available_block < (1ULL << (len - page_shift))) {
+ dev_dbg(&pdev->dev, "can't map window 0x%llx with %llu %llu-sized pages\n",
+ 1ULL << len, query.largest_available_block,
+ 1ULL << page_shift);
+ ret = -EINVAL; /* Retry with smaller window size */
+ goto out_unlock;
+ }
+
+ if (create_ddw(pdev, ddw_avail, &create, page_shift, len)) {
+ pr_err("%s: Create ddw failed %pOF\n", __func__, pdn);
+ goto out_failed;
+ }
+
+ win_addr = ((u64)create.addr_hi << 32) | create.addr_lo;
+ win64 = ddw_property_create(DMA64_PROPNAME, create.liobn, win_addr, page_shift, len);
+ if (!win64)
+ goto remove_window;
+
+ ret = of_add_property(pdn, win64);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add DMA window property for %pOF: %ld", pdn, ret);
+ goto free_property;
+ }
+ ret = -ENODEV;
+
+ window = ddw_list_new_entry(pdn, win64->value);
+ if (!window)
+ goto remove_property;
+
+ window->direct = false;
+
+ for (i = 0; i < ARRAY_SIZE(pci->phb->mem_resources); i++) {
+ const unsigned long mask = IORESOURCE_MEM_64 | IORESOURCE_MEM;
+
+ /* Look for MMIO32 */
+ if ((pci->phb->mem_resources[i].flags & mask) == IORESOURCE_MEM) {
+ start = pci->phb->mem_resources[i].start;
+ end = pci->phb->mem_resources[i].end;
+ break;
+ }
+ }
+
+ /* New table for using DDW instead of the default DMA window */
+ iommu_table_setparms_common(tbl, pci->phb->bus->number, create.liobn, win_addr,
+ 1UL << len, page_shift, NULL, &iommu_table_lpar_multi_ops);
+ iommu_init_table(tbl, pci->phb->node, start, end);
+
+ pci->table_group->tables[num] = tbl;
+ set_iommu_table_base(&pdev->dev, tbl);
+ pdev->dev.archdata.dma_offset = win_addr;
+
+ spin_lock(&dma_win_list_lock);
+ list_add(&window->list, &dma_win_list);
+ spin_unlock(&dma_win_list_lock);
+
+ mutex_unlock(&dma_win_init_mutex);
+
+ goto exit;
+
+remove_property:
+ of_remove_property(pdn, win64);
+free_property:
+ kfree(win64->name);
+ kfree(win64->value);
+ kfree(win64);
+remove_window:
+ __remove_dma_window(pdn, ddw_avail, create.liobn);
+
+out_failed:
+ fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL);
+ if (!fpdn)
+ goto out_unlock;
+ fpdn->pdn = pdn;
+ list_add(&fpdn->list, &failed_ddw_pdn_list);
+
+out_unlock:
+ mutex_unlock(&dma_win_init_mutex);
+
+ return ret;
+exit:
+ /* Allocate the userspace view */
+ pseries_tce_iommu_userspace_view_alloc(tbl);
+ tbl->it_allocated_size = spapr_tce_get_table_size(page_shift, window_size, levels);
+
+ *ptbl = iommu_tce_table_get(tbl);
+
+ return 0;
+}
+
+static bool is_default_window_table(struct iommu_table_group *table_group, struct iommu_table *tbl)
+{
+ if (((tbl->it_size << tbl->it_page_shift) <= table_group->tce32_size) &&
+ (tbl->it_page_shift == IOMMU_PAGE_SHIFT_4K))
+ return true;
+
+ return false;
+}
+
+static long spapr_tce_set_window(struct iommu_table_group *table_group,
+ int num, struct iommu_table *tbl)
+{
+ return tbl == table_group->tables[num] ? 0 : -EPERM;
+}
+
+static long spapr_tce_unset_window(struct iommu_table_group *table_group, int num)
+{
+ struct pci_dev *pdev = iommu_group_get_first_pci_dev(table_group->group);
+ struct device_node *dn = pci_device_to_OF_node(pdev), *pdn;
+ struct iommu_table *tbl = table_group->tables[num];
+ struct failed_ddw_pdn *fpdn;
+ struct dma_win *window;
+ const char *win_name;
+ int ret = -ENODEV;
+
+ mutex_lock(&dma_win_init_mutex);
+
+ if ((num == 0) && is_default_window_table(table_group, tbl))
+ win_name = "ibm,dma-window";
+ else
+ win_name = DMA64_PROPNAME;
+
+ pdn = pci_dma_find(dn, NULL);
+ if (!pdn || !PCI_DN(pdn)) { /* Niether of 32s|64-bit exist! */
+ dev_warn(&pdev->dev, "No dma-windows exist for the node %pOF\n", pdn);
+ goto out_failed;
+ }
+
+ /* Dont clear the TCEs, User should have done it */
+ if (remove_dma_window_named(pdn, true, win_name, false)) {
+ pr_err("%s: The existing DDW removal failed for node %pOF\n", __func__, pdn);
+ goto out_failed; /* Could not remove it either! */
+ }
+
+ if (strcmp(win_name, DMA64_PROPNAME) == 0) {
+ spin_lock(&dma_win_list_lock);
+ list_for_each_entry(window, &dma_win_list, list) {
+ if (window->device == pdn) {
+ list_del(&window->list);
+ kfree(window);
+ break;
+ }
+ }
+ spin_unlock(&dma_win_list_lock);
+ }
+
+ iommu_tce_table_put(table_group->tables[num]);
+ table_group->tables[num] = NULL;
+
+ ret = 0;
+
+ goto out_unlock;
+
+out_failed:
+ fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL);
+ if (!fpdn)
+ goto out_unlock;
+ fpdn->pdn = pdn;
+ list_add(&fpdn->list, &failed_ddw_pdn_list);
+
+out_unlock:
+ mutex_unlock(&dma_win_init_mutex);
+
+ return ret;
+}
+
+static long spapr_tce_take_ownership(struct iommu_table_group *table_group, struct device *dev)
+{
+ struct iommu_table *tbl = table_group->tables[0];
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct device_node *dn = pci_device_to_OF_node(pdev);
+ struct device_node *pdn;
+
+ /* SRIOV VFs using direct map by the host driver OR multifunction devices
+ * where the ownership was taken on the attempt by the first function
+ */
+ if (!tbl && (table_group->max_dynamic_windows_supported != 1))
+ return 0;
+
+ mutex_lock(&dma_win_init_mutex);
+
+ pdn = pci_dma_find(dn, NULL);
+ if (!pdn || !PCI_DN(pdn)) { /* Niether of 32s|64-bit exist! */
+ dev_warn(&pdev->dev, "No dma-windows exist for the node %pOF\n", pdn);
+ mutex_unlock(&dma_win_init_mutex);
+ return -1;
+ }
+
+ /*
+ * Though rtas call reset-pe removes the DDW, it doesn't clear the entries on the table
+ * if there are any. In case of direct map, the entries will be left over, which
+ * is fine for PEs with 2 DMA windows where the second window is created with create-pe
+ * at which point the table is cleared. However, on VFs having only one DMA window, the
+ * default window would end up seeing the entries left over from the direct map done
+ * on the second window. So, remove the ddw explicitly so that clean_dma_window()
+ * cleans up the entries if any.
+ */
+ if (remove_dynamic_dma_windows(pdev, pdn)) {
+ dev_warn(&pdev->dev, "The existing DDW removal failed for node %pOF\n", pdn);
+ mutex_unlock(&dma_win_init_mutex);
+ return -1;
+ }
+
+ /* The table_group->tables[0] is not null now, it must be the default window
+ * Remove it, let the userspace create it as it needs.
+ */
+ if (table_group->tables[0]) {
+ remove_dma_window_named(pdn, true, "ibm,dma-window", true);
+ iommu_tce_table_put(tbl);
+ table_group->tables[0] = NULL;
+ }
+ set_iommu_table_base(dev, NULL);
+
+ mutex_unlock(&dma_win_init_mutex);
+
+ return 0;
+}
+
+static void spapr_tce_release_ownership(struct iommu_table_group *table_group, struct device *dev)
+{
+ struct iommu_table *tbl = table_group->tables[0];
+
+ if (tbl) { /* Default window already restored */
+ return;
+ }
+
+ mutex_lock(&dma_win_init_mutex);
+
+ /* Restore the default window */
+ pseries_setup_default_iommu_config(table_group, dev);
+
+ mutex_unlock(&dma_win_init_mutex);
+
+ return;
+}
+
+static struct iommu_table_group_ops spapr_tce_table_group_ops = {
+ .get_table_size = spapr_tce_get_table_size,
+ .create_table = spapr_tce_create_table,
+ .set_window = spapr_tce_set_window,
+ .unset_window = spapr_tce_unset_window,
+ .take_ownership = spapr_tce_take_ownership,
+ .release_ownership = spapr_tce_release_ownership,
+};
+#endif
+
static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
void *data)
{
@@ -1712,8 +2397,8 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
* we have to remove the property when releasing
* the device node.
*/
- if (remove_ddw(np, false, DIRECT64_PROPNAME))
- remove_ddw(np, false, DMA64_PROPNAME);
+ if (remove_dma_window_named(np, false, DIRECT64_PROPNAME, true))
+ remove_dma_window_named(np, false, DMA64_PROPNAME, true);
if (pci && pci->table_group)
iommu_pseries_free_group(pci->table_group,
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index 096d09ed89f6..431be156ca9b 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -61,11 +61,3 @@ void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
} else
xics_kexec_teardown_cpu(secondary);
}
-
-void pseries_machine_kexec(struct kimage *image)
-{
- if (firmware_has_feature(FW_FEATURE_SET_MODE))
- pseries_disable_reloc_on_exc();
-
- default_machine_kexec(image);
-}
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 4e9916bb03d7..c1d8bee8f701 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -1886,10 +1886,10 @@ out:
* h_get_mpp
* H_GET_MPP hcall returns info in 7 parms
*/
-int h_get_mpp(struct hvcall_mpp_data *mpp_data)
+long h_get_mpp(struct hvcall_mpp_data *mpp_data)
{
- int rc;
- unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+ long rc;
rc = plpar_hcall9(H_GET_MPP, retbuf);
diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
index f73c4d1c26af..62da20f9700a 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -113,8 +113,8 @@ struct hvcall_ppp_data {
*/
static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
{
- unsigned long rc;
- unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+ long rc;
rc = plpar_hcall9(H_GET_PPP, retbuf);
@@ -170,20 +170,24 @@ out:
kfree(buf);
}
-static unsigned h_pic(unsigned long *pool_idle_time,
- unsigned long *num_procs)
+static long h_pic(unsigned long *pool_idle_time,
+ unsigned long *num_procs)
{
- unsigned long rc;
- unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+ long rc;
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = {0};
rc = plpar_hcall(H_PIC, retbuf);
- *pool_idle_time = retbuf[0];
- *num_procs = retbuf[1];
+ if (pool_idle_time)
+ *pool_idle_time = retbuf[0];
+ if (num_procs)
+ *num_procs = retbuf[1];
return rc;
}
+unsigned long boot_pool_idle_time;
+
/*
* parse_ppp_data
* Parse out the data returned from h_get_ppp and h_pic
@@ -193,7 +197,7 @@ static void parse_ppp_data(struct seq_file *m)
struct hvcall_ppp_data ppp_data;
struct device_node *root;
const __be32 *perf_level;
- int rc;
+ long rc;
rc = h_get_ppp(&ppp_data);
if (rc)
@@ -215,9 +219,15 @@ static void parse_ppp_data(struct seq_file *m)
seq_printf(m, "pool_capacity=%d\n",
ppp_data.active_procs_in_pool * 100);
- h_pic(&pool_idle_time, &pool_procs);
- seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
- seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
+ /* In case h_pic call is not successful, this would result in
+ * APP values being wrong in tools like lparstat.
+ */
+
+ if (h_pic(&pool_idle_time, &pool_procs) == H_SUCCESS) {
+ seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
+ seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
+ seq_printf(m, "boot_pool_idle_time=%ld\n", boot_pool_idle_time);
+ }
}
seq_printf(m, "unallocated_capacity_weight=%d\n",
@@ -361,8 +371,8 @@ static int read_dt_lpar_name(struct seq_file *m)
static void read_lpar_name(struct seq_file *m)
{
- if (read_rtas_lpar_name(m) && read_dt_lpar_name(m))
- pr_err_once("Error can't get the LPAR name");
+ if (read_rtas_lpar_name(m))
+ read_dt_lpar_name(m);
}
#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
@@ -792,6 +802,7 @@ static const struct proc_ops lparcfg_proc_ops = {
static int __init lparcfg_init(void)
{
umode_t mode = 0444;
+ long retval;
/* Allow writing if we have FW_FEATURE_SPLPAR */
if (firmware_has_feature(FW_FEATURE_SPLPAR))
@@ -801,6 +812,16 @@ static int __init lparcfg_init(void)
printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
return -EIO;
}
+
+ /* If this call fails, it would result in APP values
+ * being wrong for since boot reports of lparstat
+ */
+ retval = h_pic(&boot_pool_idle_time, NULL);
+
+ if (retval != H_SUCCESS)
+ pr_debug("H_PIC failed during lparcfg init retval: %ld\n",
+ retval);
+
return 0;
}
machine_device_initcall(pseries, lparcfg_init);
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index c233f9db039b..f6a70bc92e83 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -16,7 +16,8 @@
#include <linux/nd.h>
#include <asm/plpar_wrappers.h>
-#include <asm/papr_pdsm.h>
+#include <uapi/linux/papr_pdsm.h>
+#include <linux/papr_scm.h>
#include <asm/mce.h>
#include <asm/unaligned.h>
#include <linux/perf_event.h>
@@ -29,46 +30,6 @@
(1ul << ND_CMD_SET_CONFIG_DATA) | \
(1ul << ND_CMD_CALL))
-/* DIMM health bitmap indicators */
-/* SCM device is unable to persist memory contents */
-#define PAPR_PMEM_UNARMED (1ULL << (63 - 0))
-/* SCM device failed to persist memory contents */
-#define PAPR_PMEM_SHUTDOWN_DIRTY (1ULL << (63 - 1))
-/* SCM device contents are persisted from previous IPL */
-#define PAPR_PMEM_SHUTDOWN_CLEAN (1ULL << (63 - 2))
-/* SCM device contents are not persisted from previous IPL */
-#define PAPR_PMEM_EMPTY (1ULL << (63 - 3))
-/* SCM device memory life remaining is critically low */
-#define PAPR_PMEM_HEALTH_CRITICAL (1ULL << (63 - 4))
-/* SCM device will be garded off next IPL due to failure */
-#define PAPR_PMEM_HEALTH_FATAL (1ULL << (63 - 5))
-/* SCM contents cannot persist due to current platform health status */
-#define PAPR_PMEM_HEALTH_UNHEALTHY (1ULL << (63 - 6))
-/* SCM device is unable to persist memory contents in certain conditions */
-#define PAPR_PMEM_HEALTH_NON_CRITICAL (1ULL << (63 - 7))
-/* SCM device is encrypted */
-#define PAPR_PMEM_ENCRYPTED (1ULL << (63 - 8))
-/* SCM device has been scrubbed and locked */
-#define PAPR_PMEM_SCRUBBED_AND_LOCKED (1ULL << (63 - 9))
-
-/* Bits status indicators for health bitmap indicating unarmed dimm */
-#define PAPR_PMEM_UNARMED_MASK (PAPR_PMEM_UNARMED | \
- PAPR_PMEM_HEALTH_UNHEALTHY)
-
-/* Bits status indicators for health bitmap indicating unflushed dimm */
-#define PAPR_PMEM_BAD_SHUTDOWN_MASK (PAPR_PMEM_SHUTDOWN_DIRTY)
-
-/* Bits status indicators for health bitmap indicating unrestored dimm */
-#define PAPR_PMEM_BAD_RESTORE_MASK (PAPR_PMEM_EMPTY)
-
-/* Bit status indicators for smart event notification */
-#define PAPR_PMEM_SMART_EVENT_MASK (PAPR_PMEM_HEALTH_CRITICAL | \
- PAPR_PMEM_HEALTH_FATAL | \
- PAPR_PMEM_HEALTH_UNHEALTHY)
-
-#define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS)
-#define PAPR_SCM_PERF_STATS_VERSION 0x1
-
/* Struct holding a single performance metric */
struct papr_scm_perf_stat {
u8 stat_id[8];
@@ -1575,5 +1536,6 @@ static void __exit papr_scm_exit(void)
module_exit(papr_scm_exit);
MODULE_DEVICE_TABLE(of, papr_scm_match);
+MODULE_DESCRIPTION("PAPR Storage Class Memory interface driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("IBM Corporation");
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 1772ae3d193d..6dbc73eb2ca2 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -18,33 +18,6 @@
#include <asm/pci.h>
#include "pseries.h"
-#if 0
-void pcibios_name_device(struct pci_dev *dev)
-{
- struct device_node *dn;
-
- /*
- * Add IBM loc code (slot) as a prefix to the device names for service
- */
- dn = pci_device_to_OF_node(dev);
- if (dn) {
- const char *loc_code = of_get_property(dn, "ibm,loc-code",
- NULL);
- if (loc_code) {
- int loc_len = strlen(loc_code);
- if (loc_len < sizeof(dev->dev.name)) {
- memmove(dev->dev.name+loc_len+1, dev->dev.name,
- sizeof(dev->dev.name)-loc_len-1);
- memcpy(dev->dev.name, loc_code, loc_len);
- dev->dev.name[loc_len] = ' ';
- dev->dev.name[sizeof(dev->dev.name)-1] = '\0';
- }
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
-#endif
-
#ifdef CONFIG_PCI_IOV
#define MAX_VFS_FOR_MAP_PE 256
struct pe_map_bar_entry {
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 4448386268d9..52e2623a741d 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -11,6 +11,7 @@
#include <linux/pci.h>
#include <linux/export.h>
+#include <linux/node.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
#include <asm/firmware.h>
@@ -21,9 +22,22 @@
struct pci_controller *init_phb_dynamic(struct device_node *dn)
{
struct pci_controller *phb;
+ int nid;
pr_debug("PCI: Initializing new hotplug PHB %pOF\n", dn);
+ nid = of_node_to_nid(dn);
+ if (likely((nid) >= 0)) {
+ if (!node_online(nid)) {
+ if (__register_one_node(nid)) {
+ pr_err("PCI: Failed to register node %d\n", nid);
+ } else {
+ update_numa_distance(dn);
+ node_set_online(nid);
+ }
+ }
+ }
+
phb = pcibios_alloc_controller(dn);
if (!phb)
return NULL;
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index bba4ad192b0f..3968a6970fa8 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -38,7 +38,6 @@ static inline void smp_init_pseries(void) { }
#endif
extern void pseries_kexec_cpu_down(int crash_shutdown, int secondary);
-void pseries_machine_kexec(struct kimage *image);
extern void pSeries_final_fixup(void);
diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c
index b5853e9fcc3c..eceb3289383e 100644
--- a/arch/powerpc/platforms/pseries/rtas-fadump.c
+++ b/arch/powerpc/platforms/pseries/rtas-fadump.c
@@ -18,6 +18,7 @@
#include <asm/page.h>
#include <asm/rtas.h>
+#include <asm/setup.h>
#include <asm/fadump.h>
#include <asm/fadump-internal.h>
@@ -29,9 +30,6 @@ static const struct rtas_fadump_mem_struct *fdm_active;
static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
const struct rtas_fadump_mem_struct *fdm)
{
- fadump_conf->boot_mem_dest_addr =
- be64_to_cpu(fdm->rmr_region.destination_address);
-
fadump_conf->fadumphdr_addr = (fadump_conf->boot_mem_dest_addr +
fadump_conf->boot_memory_size);
}
@@ -43,20 +41,56 @@ static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
static void __init rtas_fadump_get_config(struct fw_dump *fadump_conf,
const struct rtas_fadump_mem_struct *fdm)
{
- fadump_conf->boot_mem_addr[0] =
- be64_to_cpu(fdm->rmr_region.source_address);
- fadump_conf->boot_mem_sz[0] = be64_to_cpu(fdm->rmr_region.source_len);
- fadump_conf->boot_memory_size = fadump_conf->boot_mem_sz[0];
+ unsigned long base, size, last_end, hole_size;
- fadump_conf->boot_mem_top = fadump_conf->boot_memory_size;
- fadump_conf->boot_mem_regs_cnt = 1;
+ last_end = 0;
+ hole_size = 0;
+ fadump_conf->boot_memory_size = 0;
+ fadump_conf->boot_mem_regs_cnt = 0;
+ pr_debug("Boot memory regions:\n");
+ for (int i = 0; i < be16_to_cpu(fdm->header.dump_num_sections); i++) {
+ int type = be16_to_cpu(fdm->rgn[i].source_data_type);
+ u64 addr;
- /*
- * Start address of reserve dump area (permanent reservation) for
- * re-registering FADump after dump capture.
- */
- fadump_conf->reserve_dump_area_start =
- be64_to_cpu(fdm->cpu_state_data.destination_address);
+ switch (type) {
+ case RTAS_FADUMP_CPU_STATE_DATA:
+ addr = be64_to_cpu(fdm->rgn[i].destination_address);
+
+ fadump_conf->cpu_state_dest_vaddr = (u64)__va(addr);
+ /*
+ * Start address of reserve dump area (permanent reservation) for
+ * re-registering FADump after dump capture.
+ */
+ fadump_conf->reserve_dump_area_start = addr;
+ break;
+ case RTAS_FADUMP_HPTE_REGION:
+ /* Not processed currently. */
+ break;
+ case RTAS_FADUMP_REAL_MODE_REGION:
+ base = be64_to_cpu(fdm->rgn[i].source_address);
+ size = be64_to_cpu(fdm->rgn[i].source_len);
+ pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size);
+ if (!base) {
+ fadump_conf->boot_mem_dest_addr =
+ be64_to_cpu(fdm->rgn[i].destination_address);
+ }
+
+ fadump_conf->boot_mem_addr[fadump_conf->boot_mem_regs_cnt] = base;
+ fadump_conf->boot_mem_sz[fadump_conf->boot_mem_regs_cnt] = size;
+ fadump_conf->boot_memory_size += size;
+ hole_size += (base - last_end);
+ last_end = base + size;
+ fadump_conf->boot_mem_regs_cnt++;
+ break;
+ case RTAS_FADUMP_PARAM_AREA:
+ fadump_conf->param_area = be64_to_cpu(fdm->rgn[i].destination_address);
+ break;
+ default:
+ pr_warn("Section type %d unsupported on this kernel. Ignoring!\n", type);
+ break;
+ }
+ }
+ fadump_conf->boot_mem_top = fadump_conf->boot_memory_size + hole_size;
rtas_fadump_update_config(fadump_conf, fdm);
}
@@ -64,16 +98,15 @@ static void __init rtas_fadump_get_config(struct fw_dump *fadump_conf,
static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
{
u64 addr = fadump_conf->reserve_dump_area_start;
+ u16 sec_cnt = 0;
memset(&fdm, 0, sizeof(struct rtas_fadump_mem_struct));
addr = addr & PAGE_MASK;
fdm.header.dump_format_version = cpu_to_be32(0x00000001);
- fdm.header.dump_num_sections = cpu_to_be16(3);
fdm.header.dump_status_flag = 0;
fdm.header.offset_first_dump_section =
- cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct,
- cpu_state_data));
+ cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct, rgn));
/*
* Fields for disk dump option.
@@ -89,25 +122,22 @@ static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
/* Kernel dump sections */
/* cpu state data section. */
- fdm.cpu_state_data.request_flag =
- cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
- fdm.cpu_state_data.source_data_type =
- cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);
- fdm.cpu_state_data.source_address = 0;
- fdm.cpu_state_data.source_len =
- cpu_to_be64(fadump_conf->cpu_state_data_size);
- fdm.cpu_state_data.destination_address = cpu_to_be64(addr);
+ fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
+ fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);
+ fdm.rgn[sec_cnt].source_address = 0;
+ fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->cpu_state_data_size);
+ fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
addr += fadump_conf->cpu_state_data_size;
+ sec_cnt++;
/* hpte region section */
- fdm.hpte_region.request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
- fdm.hpte_region.source_data_type =
- cpu_to_be16(RTAS_FADUMP_HPTE_REGION);
- fdm.hpte_region.source_address = 0;
- fdm.hpte_region.source_len =
- cpu_to_be64(fadump_conf->hpte_region_size);
- fdm.hpte_region.destination_address = cpu_to_be64(addr);
+ fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
+ fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_HPTE_REGION);
+ fdm.rgn[sec_cnt].source_address = 0;
+ fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->hpte_region_size);
+ fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
addr += fadump_conf->hpte_region_size;
+ sec_cnt++;
/*
* Align boot memory area destination address to page boundary to
@@ -115,14 +145,29 @@ static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
*/
addr = PAGE_ALIGN(addr);
- /* RMA region section */
- fdm.rmr_region.request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
- fdm.rmr_region.source_data_type =
- cpu_to_be16(RTAS_FADUMP_REAL_MODE_REGION);
- fdm.rmr_region.source_address = cpu_to_be64(0);
- fdm.rmr_region.source_len = cpu_to_be64(fadump_conf->boot_memory_size);
- fdm.rmr_region.destination_address = cpu_to_be64(addr);
- addr += fadump_conf->boot_memory_size;
+ /* First boot memory region destination address */
+ fadump_conf->boot_mem_dest_addr = addr;
+ for (int i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) {
+ /* Boot memory regions */
+ fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
+ fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_REAL_MODE_REGION);
+ fdm.rgn[sec_cnt].source_address = cpu_to_be64(fadump_conf->boot_mem_addr[i]);
+ fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->boot_mem_sz[i]);
+ fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
+ addr += fadump_conf->boot_mem_sz[i];
+ sec_cnt++;
+ }
+
+ /* Parameters area */
+ if (fadump_conf->param_area) {
+ fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
+ fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_PARAM_AREA);
+ fdm.rgn[sec_cnt].source_address = cpu_to_be64(fadump_conf->param_area);
+ fdm.rgn[sec_cnt].source_len = cpu_to_be64(COMMAND_LINE_SIZE);
+ fdm.rgn[sec_cnt].destination_address = cpu_to_be64(fadump_conf->param_area);
+ sec_cnt++;
+ }
+ fdm.header.dump_num_sections = cpu_to_be16(sec_cnt);
rtas_fadump_update_config(fadump_conf, &fdm);
@@ -136,14 +181,21 @@ static u64 rtas_fadump_get_bootmem_min(void)
static int rtas_fadump_register(struct fw_dump *fadump_conf)
{
- unsigned int wait_time;
+ unsigned int wait_time, fdm_size;
int rc, err = -EIO;
+ /*
+ * Platform requires the exact size of the Dump Memory Structure.
+ * Avoid including any unused rgns in the calculation, as this
+ * could result in a parameter error (-3) from the platform.
+ */
+ fdm_size = sizeof(struct rtas_fadump_section_header);
+ fdm_size += be16_to_cpu(fdm.header.dump_num_sections) * sizeof(struct rtas_fadump_section);
+
/* TODO: Add upper time limit for the delay */
do {
rc = rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
- NULL, FADUMP_REGISTER, &fdm,
- sizeof(struct rtas_fadump_mem_struct));
+ NULL, FADUMP_REGISTER, &fdm, fdm_size);
wait_time = rtas_busy_delay_time(rc);
if (wait_time)
@@ -161,9 +213,7 @@ static int rtas_fadump_register(struct fw_dump *fadump_conf)
pr_err("Failed to register. Hardware Error(%d).\n", rc);
break;
case -3:
- if (!is_fadump_boot_mem_contiguous())
- pr_err("Can't have holes in boot memory area.\n");
- else if (!is_fadump_reserved_mem_contiguous())
+ if (!is_fadump_reserved_mem_contiguous())
pr_err("Can't have holes in reserved memory area.\n");
pr_err("Failed to register. Parameter Error(%d).\n", rc);
@@ -316,11 +366,9 @@ static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)
u32 num_cpus, *note_buf;
int i, rc = 0, cpu = 0;
struct pt_regs regs;
- unsigned long addr;
void *vaddr;
- addr = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
- vaddr = __va(addr);
+ vaddr = (void *)fadump_conf->cpu_state_dest_vaddr;
reg_header = vaddr;
if (be64_to_cpu(reg_header->magic_number) !=
@@ -375,11 +423,8 @@ static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)
}
final_note(note_buf);
- if (fdh) {
- pr_debug("Updating elfcore header (%llx) with cpu notes\n",
- fdh->elfcorehdr_addr);
- fadump_update_elfcore_header(__va(fdh->elfcorehdr_addr));
- }
+ pr_debug("Updating elfcore header (%llx) with cpu notes\n", fadump_conf->elfcorehdr_addr);
+ fadump_update_elfcore_header((char *)fadump_conf->elfcorehdr_addr);
return 0;
error_out:
@@ -389,57 +434,66 @@ error_out:
}
/*
- * Validate and process the dump data stored by firmware before exporting
- * it through '/proc/vmcore'.
+ * Validate and process the dump data stored by the firmware, and update
+ * the CPU notes of elfcorehdr.
*/
static int __init rtas_fadump_process(struct fw_dump *fadump_conf)
{
- struct fadump_crash_info_header *fdh;
- int rc = 0;
-
if (!fdm_active || !fadump_conf->fadumphdr_addr)
return -EINVAL;
/* Check if the dump data is valid. */
- if ((be16_to_cpu(fdm_active->header.dump_status_flag) ==
- RTAS_FADUMP_ERROR_FLAG) ||
- (fdm_active->cpu_state_data.error_flags != 0) ||
- (fdm_active->rmr_region.error_flags != 0)) {
- pr_err("Dump taken by platform is not valid\n");
- return -EINVAL;
- }
- if ((fdm_active->rmr_region.bytes_dumped !=
- fdm_active->rmr_region.source_len) ||
- !fdm_active->cpu_state_data.bytes_dumped) {
- pr_err("Dump taken by platform is incomplete\n");
- return -EINVAL;
- }
+ for (int i = 0; i < be16_to_cpu(fdm_active->header.dump_num_sections); i++) {
+ int type = be16_to_cpu(fdm_active->rgn[i].source_data_type);
+ int rc = 0;
- /* Validate the fadump crash info header */
- fdh = __va(fadump_conf->fadumphdr_addr);
- if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
- pr_err("Crash info header is not valid.\n");
- return -EINVAL;
+ switch (type) {
+ case RTAS_FADUMP_CPU_STATE_DATA:
+ case RTAS_FADUMP_HPTE_REGION:
+ case RTAS_FADUMP_REAL_MODE_REGION:
+ if (fdm_active->rgn[i].error_flags != 0) {
+ pr_err("Dump taken by platform is not valid (%d)\n", i);
+ rc = -EINVAL;
+ }
+ if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len) {
+ pr_err("Dump taken by platform is incomplete (%d)\n", i);
+ rc = -EINVAL;
+ }
+ if (rc) {
+ pr_warn("Region type: %u src addr: 0x%llx dest addr: 0x%llx\n",
+ be16_to_cpu(fdm_active->rgn[i].source_data_type),
+ be64_to_cpu(fdm_active->rgn[i].source_address),
+ be64_to_cpu(fdm_active->rgn[i].destination_address));
+ return rc;
+ }
+ break;
+ case RTAS_FADUMP_PARAM_AREA:
+ if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len ||
+ fdm_active->rgn[i].error_flags != 0) {
+ pr_warn("Failed to process additional parameters! Proceeding anyway..\n");
+ fadump_conf->param_area = 0;
+ }
+ break;
+ default:
+ /*
+ * If the first/crashed kernel added a new region type that the
+ * second/fadump kernel doesn't recognize, skip it and process
+ * assuming backward compatibility.
+ */
+ pr_warn("Unknown region found: type: %u src addr: 0x%llx dest addr: 0x%llx\n",
+ be16_to_cpu(fdm_active->rgn[i].source_data_type),
+ be64_to_cpu(fdm_active->rgn[i].source_address),
+ be64_to_cpu(fdm_active->rgn[i].destination_address));
+ break;
+ }
}
- rc = rtas_fadump_build_cpu_notes(fadump_conf);
- if (rc)
- return rc;
-
- /*
- * We are done validating dump info and elfcore header is now ready
- * to be exported. set elfcorehdr_addr so that vmcore module will
- * export the elfcore header through '/proc/vmcore'.
- */
- elfcorehdr_addr = fdh->elfcorehdr_addr;
-
- return 0;
+ return rtas_fadump_build_cpu_notes(fadump_conf);
}
static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
struct seq_file *m)
{
- const struct rtas_fadump_section *cpu_data_section;
const struct rtas_fadump_mem_struct *fdm_ptr;
if (fdm_active)
@@ -447,27 +501,49 @@ static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
else
fdm_ptr = &fdm;
- cpu_data_section = &(fdm_ptr->cpu_state_data);
- seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
- be64_to_cpu(cpu_data_section->destination_address),
- be64_to_cpu(cpu_data_section->destination_address) +
- be64_to_cpu(cpu_data_section->source_len) - 1,
- be64_to_cpu(cpu_data_section->source_len),
- be64_to_cpu(cpu_data_section->bytes_dumped));
-
- seq_printf(m, "HPTE:[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
- be64_to_cpu(fdm_ptr->hpte_region.destination_address),
- be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
- be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
- be64_to_cpu(fdm_ptr->hpte_region.source_len),
- be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
-
- seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ",
- be64_to_cpu(fdm_ptr->rmr_region.source_address),
- be64_to_cpu(fdm_ptr->rmr_region.destination_address));
- seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",
- be64_to_cpu(fdm_ptr->rmr_region.source_len),
- be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
+
+ for (int i = 0; i < be16_to_cpu(fdm_ptr->header.dump_num_sections); i++) {
+ int type = be16_to_cpu(fdm_ptr->rgn[i].source_data_type);
+
+ switch (type) {
+ case RTAS_FADUMP_CPU_STATE_DATA:
+ seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address),
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address) +
+ be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,
+ be64_to_cpu(fdm_ptr->rgn[i].source_len),
+ be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));
+ break;
+ case RTAS_FADUMP_HPTE_REGION:
+ seq_printf(m, "HPTE:[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address),
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address) +
+ be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,
+ be64_to_cpu(fdm_ptr->rgn[i].source_len),
+ be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));
+ break;
+ case RTAS_FADUMP_REAL_MODE_REGION:
+ seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ",
+ be64_to_cpu(fdm_ptr->rgn[i].source_address),
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address));
+ seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",
+ be64_to_cpu(fdm_ptr->rgn[i].source_len),
+ be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));
+ break;
+ case RTAS_FADUMP_PARAM_AREA:
+ seq_printf(m, "\n[%#016llx-%#016llx]: cmdline append: '%s'\n",
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address),
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address) +
+ be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,
+ (char *)__va(be64_to_cpu(fdm_ptr->rgn[i].destination_address)));
+ break;
+ default:
+ seq_printf(m, "Unknown region type %d : Src: %#016llx, Dest: %#016llx, ",
+ type, be64_to_cpu(fdm_ptr->rgn[i].source_address),
+ be64_to_cpu(fdm_ptr->rgn[i].destination_address));
+ break;
+ }
+ }
/* Dump is active. Show preserved area start address. */
if (fdm_active) {
@@ -483,6 +559,20 @@ static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,
rtas_os_term((char *)msg);
}
+/* FADUMP_MAX_MEM_REGS or lower */
+static int rtas_fadump_max_boot_mem_rgns(void)
+{
+ /*
+ * Version 1 of Kernel Assisted Dump Memory Structure (PAPR) supports 10 sections.
+ * With one each section taken for CPU state data & HPTE respectively, 8 sections
+ * can be used for boot memory regions.
+ *
+ * If new region(s) is(are) defined, maximum boot memory regions will decrease
+ * proportionally.
+ */
+ return RTAS_FADUMP_MAX_BOOT_MEM_REGS;
+}
+
static struct fadump_ops rtas_fadump_ops = {
.fadump_init_mem_struct = rtas_fadump_init_mem_struct,
.fadump_get_bootmem_min = rtas_fadump_get_bootmem_min,
@@ -492,6 +582,7 @@ static struct fadump_ops rtas_fadump_ops = {
.fadump_process = rtas_fadump_process,
.fadump_region_show = rtas_fadump_region_show,
.fadump_trigger = rtas_fadump_trigger,
+ .fadump_max_boot_mem_rgns = rtas_fadump_max_boot_mem_rgns,
};
void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
@@ -508,9 +599,10 @@ void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
if (!token)
return;
- fadump_conf->ibm_configure_kernel_dump = be32_to_cpu(*token);
- fadump_conf->ops = &rtas_fadump_ops;
- fadump_conf->fadump_supported = 1;
+ fadump_conf->ibm_configure_kernel_dump = be32_to_cpu(*token);
+ fadump_conf->ops = &rtas_fadump_ops;
+ fadump_conf->fadump_supported = 1;
+ fadump_conf->param_area_supported = 1;
/* Firmware supports 64-bit value for size, align it to pagesize. */
fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);
diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.h b/arch/powerpc/platforms/pseries/rtas-fadump.h
index fd59bd7ca9c3..c109abf6befd 100644
--- a/arch/powerpc/platforms/pseries/rtas-fadump.h
+++ b/arch/powerpc/platforms/pseries/rtas-fadump.h
@@ -23,12 +23,24 @@
#define RTAS_FADUMP_HPTE_REGION 0x0002
#define RTAS_FADUMP_REAL_MODE_REGION 0x0011
+/* OS defined sections */
+#define RTAS_FADUMP_PARAM_AREA 0x0100
+
/* Dump request flag */
#define RTAS_FADUMP_REQUEST_FLAG 0x00000001
/* Dump status flag */
#define RTAS_FADUMP_ERROR_FLAG 0x2000
+/*
+ * The Firmware Assisted Dump Memory structure supports a maximum of 10 sections
+ * in the dump memory structure. Presently, three sections are used for
+ * CPU state data, HPTE & Parameters area, while the remaining seven sections
+ * can be used for boot memory regions.
+ */
+#define MAX_SECTIONS 10
+#define RTAS_FADUMP_MAX_BOOT_MEM_REGS 7
+
/* Kernel Dump section info */
struct rtas_fadump_section {
__be32 request_flag;
@@ -61,20 +73,15 @@ struct rtas_fadump_section_header {
* Firmware Assisted dump memory structure. This structure is required for
* registering future kernel dump with power firmware through rtas call.
*
- * No disk dump option. Hence disk dump path string section is not included.
+ * In version 1, the platform permits one section header, dump-disk path
+ * and ten sections.
+ *
+ * Note: No disk dump option. Hence disk dump path string section is not
+ * included.
*/
struct rtas_fadump_mem_struct {
struct rtas_fadump_section_header header;
-
- /* Kernel dump sections */
- struct rtas_fadump_section cpu_state_data;
- struct rtas_fadump_section hpte_region;
-
- /*
- * TODO: Extend multiple boot memory regions support in the kernel
- * for this platform.
- */
- struct rtas_fadump_section rmr_region;
+ struct rtas_fadump_section rgn[MAX_SECTIONS];
};
/*
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 284a6fa04b0c..b10a25325238 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -343,8 +343,8 @@ static int alloc_dispatch_log_kmem_cache(void)
{
void (*ctor)(void *) = get_dtl_cache_ctor();
- dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES,
- DISPATCH_LOG_BYTES, 0, ctor);
+ dtl_cache = kmem_cache_create_usercopy("dtl", DISPATCH_LOG_BYTES,
+ DISPATCH_LOG_BYTES, 0, 0, DISPATCH_LOG_BYTES, ctor);
if (!dtl_cache) {
pr_warn("Failed to create dispatch trace log buffer cache\n");
pr_warn("Stolen time statistics will be unreliable\n");
@@ -1159,7 +1159,6 @@ define_machine(pseries) {
.machine_check_exception = pSeries_machine_check_exception,
.machine_check_log_err = pSeries_machine_check_log_err,
#ifdef CONFIG_KEXEC_CORE
- .machine_kexec = pseries_machine_kexec,
.kexec_cpu_down = pseries_kexec_cpu_down,
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index 71d52a670d95..c25eb1a38185 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -38,7 +38,27 @@ static long hcall_return_busy_check(long rc)
{
/* Check if we are stalled for some time */
if (H_IS_LONG_BUSY(rc)) {
- msleep(get_longbusy_msecs(rc));
+ unsigned int ms;
+ /*
+ * Allocate, Modify and Deallocate HCALLs returns
+ * H_LONG_BUSY_ORDER_1_MSEC or H_LONG_BUSY_ORDER_10_MSEC
+ * for the long delay. So the sleep time should always
+ * be either 1 or 10msecs, but in case if the HCALL
+ * returns the long delay > 10 msecs, clamp the sleep
+ * time to 10msecs.
+ */
+ ms = clamp(get_longbusy_msecs(rc), 1, 10);
+
+ /*
+ * msleep() will often sleep at least 20 msecs even
+ * though the hypervisor suggests that the OS reissue
+ * HCALLs after 1 or 10msecs. Also the delay hint from
+ * the HCALL is just a suggestion. So OK to pause for
+ * less time than the hinted delay. Use usleep_range()
+ * to ensure we don't sleep much longer than actually
+ * needed.
+ */
+ usleep_range(ms * (USEC_PER_MSEC / 10), ms * USEC_PER_MSEC);
rc = H_BUSY;
} else if (rc == H_BUSY) {
cond_resched();
@@ -228,7 +248,7 @@ static irqreturn_t pseries_vas_irq_handler(int irq, void *data)
struct pseries_vas_window *txwin = data;
/*
- * The thread hanlder will process this interrupt if it is
+ * The thread handler will process this interrupt if it is
* already running.
*/
atomic_inc(&txwin->pending_faults);
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index 90ff85c879bf..ac1d2d2c9a88 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -611,7 +611,7 @@ 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,
+ .alloc_pages_op = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
};
@@ -1576,10 +1576,10 @@ void vio_unregister_device(struct vio_dev *viodev)
}
EXPORT_SYMBOL(vio_unregister_device);
-static int vio_bus_match(struct device *dev, struct device_driver *drv)
+static int vio_bus_match(struct device *dev, const struct device_driver *drv)
{
const struct vio_dev *vio_dev = to_vio_dev(dev);
- struct vio_driver *vio_drv = to_vio_driver(drv);
+ const struct vio_driver *vio_drv = to_vio_driver(drv);
const struct vio_device_id *ids = vio_drv->id_table;
return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
@@ -1592,13 +1592,9 @@ static int vio_hotplug(const struct device *dev, struct kobj_uevent_env *env)
const char *cp;
dn = dev->of_node;
- if (!dn)
- return -ENODEV;
- cp = of_get_property(dn, "compatible", NULL);
- if (!cp)
- return -ENODEV;
+ if (dn && (cp = of_get_property(dn, "compatible", NULL)))
+ add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
- add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
return 0;
}
@@ -1693,7 +1689,7 @@ struct vio_dev *vio_find_node(struct device_node *vnode)
/* construct the kobject name from the device node */
if (of_node_is_type(vnode_parent, "vdevice")) {
const __be32 *prop;
-
+
prop = of_get_property(vnode, "reg", NULL);
if (!prop)
goto out;
diff --git a/arch/powerpc/purgatory/Makefile b/arch/powerpc/purgatory/Makefile
index 78473d69cd2b..e9890085953e 100644
--- a/arch/powerpc/purgatory/Makefile
+++ b/arch/powerpc/purgatory/Makefile
@@ -1,8 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-
targets += trampoline_$(BITS).o purgatory.ro
# When profile-guided optimization is enabled, llvm emits two different
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
index 5aa92ff3622d..18ff2c4a814a 100644
--- a/arch/powerpc/sysdev/Kconfig
+++ b/arch/powerpc/sysdev/Kconfig
@@ -5,12 +5,12 @@
config PPC4xx_PCI_EXPRESS
bool
- depends on PCI && 4xx
+ depends on PCI && 44x
config PPC4xx_HSTA_MSI
bool
depends on PCI_MSI
- depends on PCI && 4xx
+ depends on PCI && 44x
config PPC_MSI_BITMAP
bool
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 9cb1d029511a..24a177d164f1 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-
mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o
obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
obj-$(CONFIG_MPIC_TIMER) += mpic_timer.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 98096bbfd62e..c0d10c149661 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -24,7 +24,6 @@
#include <linux/suspend.h>
#include <linux/memblock.h>
#include <linux/gfp.h>
-#include <linux/kmemleak.h>
#include <linux/of_address.h>
#include <asm/io.h>
#include <asm/iommu.h>
@@ -243,9 +242,6 @@ static void __init allocate_dart(void)
if (!dart_tablebase)
panic("Failed to allocate 16MB below 2GB for DART table\n");
- /* There is no point scanning the DART space for leaks*/
- kmemleak_no_scan((void *)dart_tablebase);
-
/* Allocate a spare page to map all invalid DART pages. We need to do
* that to work around what looks like a problem with the HT bridge
* prefetching into invalid pages and corrupting data
diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c
index 39186ad6b3c3..3dabc9621810 100644
--- a/arch/powerpc/sysdev/fsl_gtm.c
+++ b/arch/powerpc/sysdev/fsl_gtm.c
@@ -77,7 +77,7 @@ struct gtm {
static LIST_HEAD(gtms);
/**
- * gtm_get_timer - request GTM timer to use it with the rest of GTM API
+ * gtm_get_timer16 - request GTM timer to use it with the rest of GTM API
* Context: non-IRQ
*
* This function reserves GTM timer for later use. It returns gtm_timer
@@ -110,7 +110,7 @@ struct gtm_timer *gtm_get_timer16(void)
EXPORT_SYMBOL(gtm_get_timer16);
/**
- * gtm_get_specific_timer - request specific GTM timer
+ * gtm_get_specific_timer16 - request specific GTM timer
* @gtm: specific GTM, pass here GTM's device_node->data
* @timer: specific timer number, Timer1 is 0.
* Context: non-IRQ
@@ -260,7 +260,7 @@ int gtm_set_timer16(struct gtm_timer *tmr, unsigned long usec, bool reload)
EXPORT_SYMBOL(gtm_set_timer16);
/**
- * gtm_set_exact_utimer16 - (re)set 16 bits timer
+ * gtm_set_exact_timer16 - (re)set 16 bits timer
* @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer
* @usec: timer interval in microseconds
* @reload: if set, the timer will reset upon expiry rather than
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 8e6c84df4ca1..e205135ae1fe 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -564,10 +564,12 @@ static const struct fsl_msi_feature ipic_msi_feature = {
.msiir_offset = 0x38,
};
+#ifdef CONFIG_EPAPR_PARAVIRT
static const struct fsl_msi_feature vmpic_msi_feature = {
.fsl_pic_ip = FSL_PIC_IP_VMPIC,
.msiir_offset = 0,
};
+#endif
static const struct of_device_id fsl_of_msi_ids[] = {
{
diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c
index 47cc87bd6a33..9a232ae5e360 100644
--- a/arch/powerpc/sysdev/rtc_cmos_setup.c
+++ b/arch/powerpc/sysdev/rtc_cmos_setup.c
@@ -66,4 +66,5 @@ static int __init add_rtc(void)
}
fs_initcall(add_rtc);
+MODULE_DESCRIPTION("PPC RTC CMOS driver");
MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index a289cb97c1d7..fa01818c1972 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -383,7 +383,7 @@ static unsigned int xive_get_irq(void)
* CPU.
*
* If we find that there is indeed more in there, we call
- * force_external_irq_replay() to make Linux synthetize an
+ * force_external_irq_replay() to make Linux synthesize an
* external interrupt on the next call to local_irq_restore().
*/
static void xive_do_queue_eoi(struct xive_cpu *xc)
@@ -874,7 +874,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
*
* This also tells us that it's in flight to a host queue
* or has already been fetched but hasn't been EOIed yet
- * by the host. This it's potentially using up a host
+ * by the host. Thus it's potentially using up a host
* queue slot. This is important to know because as long
* as this is the case, we must not hard-unmask it when
* "returning" that interrupt to the host.
diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
index f1c0fa6ece21..517b963e3e6a 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -415,7 +415,7 @@ static void xive_native_setup_cpu(unsigned int cpu, struct xive_cpu *xc)
return;
}
- /* Grab it's CAM value */
+ /* Grab its CAM value */
rc = opal_xive_get_vp_info(vp, NULL, &vp_cam_be, NULL, NULL);
if (rc) {
pr_err("Failed to get pool VP info CPU %d\n", cpu);
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index 682c7c0a6f77..d778011060a8 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -10,8 +10,6 @@ KCSAN_SANITIZE := n
# Disable ftrace for the entire directory
ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE)
-ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-
# Clang stores addresses on the stack causing the frame size to blow
# out. See https://github.com/ClangBuiltLinux/linux/issues/252
ccflags-$(CONFIG_CC_IS_CLANG) += -Wframe-larger-than=4096
diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c
index 75fa98221d48..af105e1bc3fc 100644
--- a/arch/powerpc/xmon/ppc-dis.c
+++ b/arch/powerpc/xmon/ppc-dis.c
@@ -122,32 +122,21 @@ int print_insn_powerpc (unsigned long insn, unsigned long memaddr)
bool insn_is_short;
ppc_cpu_t dialect;
- dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON
- | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
+ dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON;
- if (cpu_has_feature(CPU_FTRS_POWER5))
- dialect |= PPC_OPCODE_POWER5;
+ if (IS_ENABLED(CONFIG_PPC64))
+ dialect |= PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_CELL |
+ PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 |
+ PPC_OPCODE_POWER9;
- if (cpu_has_feature(CPU_FTRS_CELL))
- dialect |= (PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC);
+ if (cpu_has_feature(CPU_FTR_TM))
+ dialect |= PPC_OPCODE_HTM;
- if (cpu_has_feature(CPU_FTRS_POWER6))
- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC);
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ dialect |= PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2;
- if (cpu_has_feature(CPU_FTRS_POWER7))
- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
- | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX);
-
- if (cpu_has_feature(CPU_FTRS_POWER8))
- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
- | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
- | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX);
-
- if (cpu_has_feature(CPU_FTRS_POWER9))
- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
- | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 | PPC_OPCODE_HTM
- | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2
- | PPC_OPCODE_VSX | PPC_OPCODE_VSX3);
+ if (cpu_has_feature(CPU_FTR_VSX))
+ dialect |= PPC_OPCODE_VSX | PPC_OPCODE_VSX3;
/* Get the major opcode of the insn. */
opcode = NULL;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index d79d6633f333..bd4813bad317 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1350,7 +1350,7 @@ static int cpu_cmd(void)
}
termch = cpu;
- if (!scanhex(&cpu)) {
+ if (!scanhex(&cpu) || cpu >= num_possible_cpus()) {
/* print cpus waiting or in xmon */
printf("cpus stopped:");
last_cpu = first_cpu = NR_CPUS;
@@ -2772,7 +2772,7 @@ static void dump_pacas(void)
termch = c; /* Put c back, it wasn't 'a' */
- if (scanhex(&num))
+ if (scanhex(&num) && num < num_possible_cpus())
dump_one_paca(num);
else
dump_one_paca(xmon_owner);
@@ -2845,7 +2845,7 @@ static void dump_xives(void)
termch = c; /* Put c back, it wasn't 'a' */
- if (scanhex(&num))
+ if (scanhex(&num) && num < num_possible_cpus())
dump_one_xive(num);
else
dump_one_xive(xmon_owner);
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index be09c8836d56..3ceec2ca84fa 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -16,6 +16,8 @@ config RISCV
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ARCH_DMA_DEFAULT_COHERENT
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
+ select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM_VMEMMAP
+ select ARCH_ENABLE_MEMORY_HOTREMOVE if MEMORY_HOTPLUG
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
select ARCH_HAS_BINFMT_FLAT
@@ -23,16 +25,19 @@ config RISCV
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
+ select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
+ select ARCH_HAS_KERNEL_FPU_SUPPORT if 64BIT && FPU
select ARCH_HAS_MEMBARRIER_CALLBACKS
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_MMIOWB
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
select ARCH_HAS_PMEM_API
select ARCH_HAS_PREPARE_SYNC_CORE_CMD
+ select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SET_DIRECT_MAP if MMU
select ARCH_HAS_SET_MEMORY if MMU
@@ -44,6 +49,7 @@ config RISCV
select ARCH_HAS_UBSAN
select ARCH_HAS_VDSO_DATA
select ARCH_KEEP_MEMBLOCK if ACPI
+ select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if 64BIT && MMU
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
select ARCH_STACKWALK
@@ -57,21 +63,23 @@ config RISCV
select ARCH_SUPPORTS_PAGE_TABLE_CHECK if MMU
select ARCH_SUPPORTS_PER_VMA_LOCK if MMU
select ARCH_SUPPORTS_SHADOW_CALL_STACK if HAVE_SHADOW_CALL_STACK
+ select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
select ARCH_USE_MEMTEST
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USES_CFI_TRAPS if CFI_CLANG
- select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP && MMU
+ select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if MMU
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
select ARCH_WANT_FRAME_POINTERS
select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
select ARCH_WANT_LD_ORPHAN_WARN if !XIP_KERNEL
+ select ARCH_WANT_OPTIMIZE_DAX_VMEMMAP
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
select ARCH_WANTS_NO_INSTR
select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
select BINFMT_FLAT_NO_DATA_START_OFFSET if !MMU
select BUILDTIME_TABLE_SORT if MMU
- select CLINT_TIMER if !MMU
+ select CLINT_TIMER if RISCV_M_MODE
select CLONE_BACKWARDS
select COMMON_CLK
select CPU_PM if CPU_IDLE || HIBERNATION || SUSPEND
@@ -103,7 +111,7 @@ config RISCV
select HAS_IOPORT if MMU
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
- select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT && !XIP_KERNEL
+ select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL
select HAVE_ARCH_KASAN if MMU && 64BIT
@@ -126,18 +134,25 @@ config RISCV
select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
- select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
+ select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !PREEMPTION
select HAVE_EBPF_JIT if MMU
- select HAVE_FAST_GUP if MMU
+ select HAVE_GUP_FAST if MMU
select HAVE_FUNCTION_ARG_ACCESS_API
select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_GCC_PLUGINS
select HAVE_GENERIC_VDSO if MMU && 64BIT
select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
+ select HAVE_KERNEL_GZIP if !XIP_KERNEL && !EFI_ZBOOT
+ select HAVE_KERNEL_LZ4 if !XIP_KERNEL && !EFI_ZBOOT
+ select HAVE_KERNEL_LZMA if !XIP_KERNEL && !EFI_ZBOOT
+ select HAVE_KERNEL_LZO if !XIP_KERNEL && !EFI_ZBOOT
+ select HAVE_KERNEL_UNCOMPRESSED if !XIP_KERNEL && !EFI_ZBOOT
+ select HAVE_KERNEL_ZSTD if !XIP_KERNEL && !EFI_ZBOOT
select HAVE_KPROBES if !XIP_KERNEL
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
select HAVE_KRETPROBES if !XIP_KERNEL
@@ -155,6 +170,7 @@ config RISCV
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RETHOOK if !XIP_KERNEL
select HAVE_RSEQ
+ select HAVE_RUST if 64BIT
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_STACKPROTECTOR
@@ -166,13 +182,14 @@ config RISCV
select LOCK_MM_AND_FIND_VMA
select MMU_GATHER_RCU_TABLE_FREE if SMP && MMU
select MODULES_USE_ELF_RELA if MODULES
- select MODULE_SECTIONS if MODULES
select OF
select OF_EARLY_FLATTREE
select OF_IRQ
select PCI_DOMAINS_GENERIC if PCI
select PCI_MSI if PCI
select RISCV_ALTERNATIVE if !XIP_KERNEL
+ select RISCV_APLIC
+ select RISCV_IMSIC
select RISCV_INTC
select RISCV_TIMER if RISCV_SBI
select SIFIVE_PLIC
@@ -229,8 +246,12 @@ config ARCH_MMAP_RND_COMPAT_BITS_MAX
# set if we run in machine mode, cleared if we run in supervisor mode
config RISCV_M_MODE
- bool
- default !MMU
+ bool "Build a kernel that runs in machine mode"
+ depends on !MMU
+ default y
+ help
+ Select this option if you want to run the kernel in M-mode,
+ without the assistance of any other firmware.
# set if we are running in S-mode and can use SBI calls
config RISCV_SBI
@@ -247,8 +268,9 @@ config MMU
config PAGE_OFFSET
hex
- default 0xC0000000 if 32BIT && MMU
- default 0x80000000 if !MMU
+ default 0x80000000 if !MMU && RISCV_M_MODE
+ default 0x80200000 if !MMU
+ default 0xc0000000 if 32BIT
default 0xff60000000000000 if 64BIT
config KASAN_SHADOW_OFFSET
@@ -578,6 +600,19 @@ config RISCV_ISA_V_PREEMPTIVE
preemption. Enabling this config will result in higher memory
consumption due to the allocation of per-task's kernel Vector context.
+config RISCV_ISA_ZAWRS
+ bool "Zawrs extension support for more efficient busy waiting"
+ depends on RISCV_ALTERNATIVE
+ default y
+ help
+ The Zawrs extension defines instructions to be used in polling loops
+ which allow a hart to enter a low-power state or to trap to the
+ hypervisor while waiting on a store to a memory location. Enable the
+ use of these instructions in the kernel when the Zawrs extension is
+ detected at boot.
+
+ If you don't know what to do here, say Y.
+
config TOOLCHAIN_HAS_ZBB
bool
default y
@@ -593,10 +628,21 @@ config TOOLCHAIN_HAS_VECTOR_CRYPTO
def_bool $(as-instr, .option arch$(comma) +v$(comma) +zvkb)
depends on AS_HAS_OPTION_ARCH
+config RISCV_ISA_ZBA
+ bool "Zba extension support for bit manipulation instructions"
+ default y
+ help
+ Add support for enabling optimisations in the kernel when the Zba
+ extension is detected at boot.
+
+ The Zba extension provides instructions to accelerate the generation
+ of addresses that index into arrays of basic data types.
+
+ If you don't know what to do here, say Y.
+
config RISCV_ISA_ZBB
bool "Zbb extension support for bit manipulation instructions"
depends on TOOLCHAIN_HAS_ZBB
- depends on MMU
depends on RISCV_ALTERNATIVE
default y
help
@@ -609,6 +655,29 @@ config RISCV_ISA_ZBB
If you don't know what to do here, say Y.
+config TOOLCHAIN_HAS_ZBC
+ bool
+ default y
+ depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zbc)
+ depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zbc)
+ depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
+ depends on AS_HAS_OPTION_ARCH
+
+config RISCV_ISA_ZBC
+ bool "Zbc extension support for carry-less multiplication instructions"
+ depends on TOOLCHAIN_HAS_ZBC
+ depends on MMU
+ depends on RISCV_ALTERNATIVE
+ default y
+ help
+ Adds support to dynamically detect the presence of the Zbc
+ extension (carry-less multiplication) and enable its usage.
+
+ The Zbc extension could accelerate CRC (cyclic redundancy check)
+ calculations.
+
+ If you don't know what to do here, say Y.
+
config RISCV_ISA_ZICBOM
bool "Zicbom extension support for non-coherent DMA operation"
depends on MMU
@@ -628,7 +697,6 @@ config RISCV_ISA_ZICBOM
config RISCV_ISA_ZICBOZ
bool "Zicboz extension support for faster zeroing of memory"
- depends on MMU
depends on RISCV_ALTERNATIVE
default y
help
@@ -639,13 +707,6 @@ config RISCV_ISA_ZICBOZ
If you don't know what to do here, say Y.
-config TOOLCHAIN_HAS_ZIHINTPAUSE
- bool
- default y
- depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zihintpause)
- depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause)
- depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600
-
config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
def_bool y
# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc
@@ -852,6 +913,7 @@ config PARAVIRT_TIME_ACCOUNTING
config RELOCATABLE
bool "Build a relocatable kernel"
depends on MMU && 64BIT && !XIP_KERNEL
+ select MODULE_SECTIONS if MODULES
help
This builds a kernel as a Position Independent Executable (PIE),
which retains all relocation metadata required to relocate the
@@ -898,7 +960,8 @@ config CMDLINE
line here and choose how the kernel should use it later on.
choice
- prompt "Built-in command line usage" if CMDLINE != ""
+ prompt "Built-in command line usage"
+ depends on CMDLINE != ""
default CMDLINE_FALLBACK
help
Choose how the kernel will handle the provided built-in command
@@ -951,6 +1014,17 @@ config EFI
allow the kernel to be booted as an EFI application. This
is only useful on systems that have UEFI firmware.
+config DMI
+ bool "Enable support for SMBIOS (DMI) tables"
+ depends on EFI
+ default y
+ help
+ This enables SMBIOS/DMI feature for systems.
+
+ This option is only useful on systems that have UEFI firmware.
+ However, even with this option, the resultant kernel should
+ continue to boot on existing non-UEFI platforms.
+
config CC_HAVE_STACKPROTECTOR_TLS
def_bool $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=tp -mstack-protector-guard-offset=0)
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 623de5f8a208..f51bb24bc84c 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -1,12 +1,12 @@
menu "SoC selection"
config ARCH_MICROCHIP_POLARFIRE
- def_bool SOC_MICROCHIP_POLARFIRE
+ def_bool ARCH_MICROCHIP
-config SOC_MICROCHIP_POLARFIRE
- bool "Microchip PolarFire SoCs"
+config ARCH_MICROCHIP
+ bool "Microchip SoCs"
help
- This enables support for Microchip PolarFire SoC platforms.
+ This enables support for Microchip SoC platforms.
config ARCH_RENESAS
bool "Renesas RISC-V SoCs"
@@ -14,9 +14,6 @@ config ARCH_RENESAS
This enables support for the RISC-V based Renesas SoCs.
config ARCH_SIFIVE
- def_bool SOC_SIFIVE
-
-config SOC_SIFIVE
bool "SiFive SoCs"
select ERRATA_SIFIVE if !XIP_KERNEL
help
@@ -55,9 +52,6 @@ config ARCH_THEAD
This enables support for the RISC-V based T-HEAD SoCs.
config ARCH_VIRT
- def_bool SOC_VIRT
-
-config SOC_VIRT
bool "QEMU Virt Machine"
select CLINT_TIMER if RISCV_M_MODE
select POWER_RESET
@@ -72,11 +66,13 @@ config SOC_VIRT
This enables support for QEMU Virt Machine.
config ARCH_CANAAN
- def_bool SOC_CANAAN
+ bool "Canaan Kendryte SoC"
+ help
+ This enables support for Canaan Kendryte series SoC platform hardware.
-config SOC_CANAAN
+config SOC_CANAAN_K210
bool "Canaan Kendryte K210 SoC"
- depends on !MMU
+ depends on !MMU && ARCH_CANAAN
select CLINT_TIMER if RISCV_M_MODE
select ARCH_HAS_RESET_CONTROLLER
select PINCTRL
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 5b3115a19852..6fe682139d2e 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -34,6 +34,9 @@ ifeq ($(CONFIG_ARCH_RV64I),y)
KBUILD_AFLAGS += -mabi=lp64
KBUILD_LDFLAGS += -melf64lriscv
+
+ KBUILD_RUSTFLAGS += -Ctarget-cpu=generic-rv64 --target=riscv64imac-unknown-none-elf \
+ -Cno-redzone
else
BITS := 32
UTS_MACHINE := riscv32
@@ -68,6 +71,10 @@ riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
+ifneq ($(CONFIG_RISCV_ISA_C),y)
+ KBUILD_RUSTFLAGS += -Ctarget-feature=-c
+endif
+
ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
KBUILD_CFLAGS += -Wa,-misa-spec=2.2
KBUILD_AFLAGS += -Wa,-misa-spec=2.2
@@ -75,15 +82,15 @@ else
riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
endif
-# Check if the toolchain supports Zihintpause extension
-riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
-
# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
KBUILD_AFLAGS += -march=$(riscv-march-y)
+# For C code built with floating-point support, exclude V but keep F and D.
+CC_FLAGS_FPU := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)([^v_]*)v?/\1\2/')
+
KBUILD_CFLAGS += -mno-save-restore
KBUILD_CFLAGS += -DCONFIG_PAGE_OFFSET=$(CONFIG_PAGE_OFFSET)
@@ -133,8 +140,31 @@ boot := arch/riscv/boot
ifeq ($(CONFIG_XIP_KERNEL),y)
KBUILD_IMAGE := $(boot)/xipImage
else
+ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN_K210),yy)
+KBUILD_IMAGE := $(boot)/loader.bin
+else
+ifeq ($(CONFIG_EFI_ZBOOT),)
KBUILD_IMAGE := $(boot)/Image.gz
+else
+KBUILD_IMAGE := $(boot)/vmlinuz.efi
+endif
+endif
+endif
+
+boot := arch/riscv/boot
+boot-image-y := Image
+boot-image-$(CONFIG_KERNEL_BZIP2) := Image.bz2
+boot-image-$(CONFIG_KERNEL_GZIP) := Image.gz
+boot-image-$(CONFIG_KERNEL_LZ4) := Image.lz4
+boot-image-$(CONFIG_KERNEL_LZMA) := Image.lzma
+boot-image-$(CONFIG_KERNEL_LZO) := Image.lzo
+boot-image-$(CONFIG_KERNEL_ZSTD) := Image.zst
+ifdef CONFIG_RISCV_M_MODE
+boot-image-$(CONFIG_ARCH_CANAAN) := loader.bin
endif
+boot-image-$(CONFIG_EFI_ZBOOT) := vmlinuz.efi
+boot-image-$(CONFIG_XIP_KERNEL) := xipImage
+KBUILD_IMAGE := $(boot)/$(boot-image-y)
libs-y += arch/riscv/lib/
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
@@ -153,32 +183,19 @@ endif
vdso-install-y += arch/riscv/kernel/vdso/vdso.so.dbg
vdso-install-$(CONFIG_COMPAT) += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg
-ifneq ($(CONFIG_XIP_KERNEL),y)
-ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_ARCH_CANAAN),yy)
-KBUILD_IMAGE := $(boot)/loader.bin
-else
-ifeq ($(CONFIG_EFI_ZBOOT),)
-KBUILD_IMAGE := $(boot)/Image.gz
-else
-KBUILD_IMAGE := $(boot)/vmlinuz.efi
-endif
-endif
-endif
-BOOT_TARGETS := Image Image.gz loader loader.bin xipImage vmlinuz.efi
+BOOT_TARGETS := Image Image.gz Image.bz2 Image.lz4 Image.lzma Image.lzo Image.zst loader loader.bin xipImage vmlinuz.efi
all: $(notdir $(KBUILD_IMAGE))
loader.bin: loader
-Image.gz loader vmlinuz.efi: Image
+Image.gz Image.bz2 Image.lz4 Image.lzma Image.lzo Image.zst loader xipImage vmlinuz.efi: Image
+
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
@$(kecho) ' Kernel: $(boot)/$@ is ready'
-Image.%: Image
- $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
-
-install: KBUILD_IMAGE := $(boot)/Image
-zinstall: KBUILD_IMAGE := $(boot)/Image.gz
+# the install target always installs KBUILD_IMAGE (which may be compressed)
+# but keep the zinstall target for compatibility with older releases
install zinstall:
$(call cmd,install)
@@ -199,3 +216,20 @@ rv32_defconfig:
PHONY += rv32_nommu_virt_defconfig
rv32_nommu_virt_defconfig:
$(Q)$(MAKE) -f $(srctree)/Makefile nommu_virt_defconfig 32-bit.config
+
+define archhelp
+ echo ' Image - Uncompressed kernel image (arch/riscv/boot/Image)'
+ echo ' Image.gz - Compressed kernel image (arch/riscv/boot/Image.gz)'
+ echo ' Image.bz2 - Compressed kernel image (arch/riscv/boot/Image.bz2)'
+ echo ' Image.lz4 - Compressed kernel image (arch/riscv/boot/Image.lz4)'
+ echo ' Image.lzma - Compressed kernel image (arch/riscv/boot/Image.lzma)'
+ echo ' Image.lzo - Compressed kernel image (arch/riscv/boot/Image.lzo)'
+ echo ' Image.zst - Compressed kernel image (arch/riscv/boot/Image.zst)'
+ echo ' vmlinuz.efi - Compressed EFI kernel image (arch/riscv/boot/vmlinuz.efi)'
+ echo ' Default when CONFIG_EFI_ZBOOT=y'
+ echo ' xipImage - Execute-in-place kernel image (arch/riscv/boot/xipImage)'
+ echo ' Default when CONFIG_XIP_KERNEL=y'
+ echo ' install - Install kernel using (your) ~/bin/$(INSTALLKERNEL) or'
+ echo ' (distribution) /sbin/$(INSTALLKERNEL) or install to '
+ echo ' $$(INSTALL_PATH)'
+endef
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
index 8e7fc0edf21d..869c0345b908 100644
--- a/arch/riscv/boot/Makefile
+++ b/arch/riscv/boot/Makefile
@@ -14,8 +14,6 @@
# Based on the ia64 and arm64 boot/Makefile.
#
-KCOV_INSTRUMENT := n
-
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
OBJCOPYFLAGS_loader.bin :=-O binary
OBJCOPYFLAGS_xipImage :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
diff --git a/arch/riscv/boot/dts/allwinner/Makefile b/arch/riscv/boot/dts/allwinner/Makefile
index 87f70b1af6b4..1c91be38ea16 100644
--- a/arch/riscv/boot/dts/allwinner/Makefile
+++ b/arch/riscv/boot/dts/allwinner/Makefile
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-clockworkpi-v3.14.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-devterm-v3.14.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-dongshan-nezha-stu.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-lichee-rv-86-panel-480p.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-lichee-rv-86-panel-720p.dtb
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-clockworkpi-v3.14.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-clockworkpi-v3.14.dts
new file mode 100644
index 000000000000..750aec6cf2f2
--- /dev/null
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-clockworkpi-v3.14.dts
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
+
+#include <dt-bindings/gpio/gpio.h>
+
+/dts-v1/;
+
+#include "sun20i-d1.dtsi"
+#include "sun20i-common-regulators.dtsi"
+
+/ {
+ model = "ClockworkPi v3.14 (R-01)";
+ compatible = "clockwork,r-01-clockworkpi-v3.14", "allwinner,sun20i-d1";
+
+ aliases {
+ ethernet0 = &ap6256;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ /*
+ * This regulator is PWM-controlled, but the PWM controller is not
+ * yet supported, so fix the regulator to its default voltage.
+ */
+ reg_vdd_cpu: vdd-cpu {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-cpu";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&reg_vcc>;
+ };
+
+ wifi_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>; /* PG11/GPIO3 */
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_vdd_cpu>;
+};
+
+&dcxo {
+ clock-frequency = <24000000>;
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pb10_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ axp221: pmic@34 {
+ compatible = "x-powers,axp228", "x-powers,axp221";
+ reg = <0x34>;
+ interrupt-parent = <&pio>;
+ interrupts = <4 9 IRQ_TYPE_LEVEL_LOW>; /* PE9/GPIO2 */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ ac_power_supply: ac-power {
+ compatible = "x-powers,axp221-ac-power-supply";
+ };
+
+ axp_adc: adc {
+ compatible = "x-powers,axp221-adc";
+ #io-channel-cells = <1>;
+ };
+
+ battery_power_supply: battery-power {
+ compatible = "x-powers,axp221-battery-power-supply";
+ };
+
+ axp_gpio: gpio {
+ compatible = "x-powers,axp221-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ regulators {
+ x-powers,dcdc-freq = <3000>;
+
+ reg_dcdc1: dcdc1 {
+ regulator-name = "sys-3v3";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-name = "sys-1v8";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_aldo1: aldo1 {
+ regulator-name = "aud-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_aldo2: aldo2 {
+ regulator-name = "disp-3v3";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_aldo3: aldo3 {
+ regulator-name = "vdd-wifi";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ /* DLDO1 and ELDO1-3 are connected in parallel. */
+ reg_dldo1: dldo1 {
+ regulator-name = "vbat-wifi-a";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ /* DLDO2-DLDO4 are connected in parallel. */
+ reg_dldo2: dldo2 {
+ regulator-name = "vcc-3v3-ext-a";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_dldo3: dldo3 {
+ regulator-name = "vcc-3v3-ext-b";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_dldo4: dldo4 {
+ regulator-name = "vcc-3v3-ext-c";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_eldo1: eldo1 {
+ regulator-name = "vbat-wifi-b";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_eldo2: eldo2 {
+ regulator-name = "vbat-wifi-c";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_eldo3: eldo3 {
+ regulator-name = "vbat-wifi-d";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+
+ usb_power_supply: usb-power {
+ compatible = "x-powers,axp221-usb-power-supply";
+ status = "disabled";
+ };
+ };
+};
+
+&mmc0 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ vmmc-supply = <&reg_dcdc1>;
+ vqmmc-supply = <&reg_vcc_3v3>;
+ pinctrl-0 = <&mmc0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&mmc1 {
+ bus-width = <4>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ non-removable;
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_aldo3>;
+ pinctrl-0 = <&mmc1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ ap6256: wifi@1 {
+ compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10/GPIO4 */
+ interrupt-names = "host-wake";
+ };
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ vcc-pg-supply = <&reg_ldoa>;
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_pb8_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart1 {
+ uart-has-rtscts;
+ pinctrl-0 = <&uart1_pg6_pins>, <&uart1_pg8_rts_cts_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm4345c5";
+ interrupt-parent = <&pio>;
+ interrupts = <6 17 IRQ_TYPE_LEVEL_HIGH>; /* PG17/GPIO6 */
+ device-wakeup-gpios = <&pio 6 16 GPIO_ACTIVE_HIGH>; /* PG16/GPIO7 */
+ shutdown-gpios = <&pio 6 18 GPIO_ACTIVE_HIGH>; /* PG18/GPIO5 */
+ max-speed = <1500000>;
+ vbat-supply = <&reg_dldo1>;
+ vddio-supply = <&reg_aldo3>;
+ };
+};
+
+&usb_otg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_vbus_power-supply = <&ac_power_supply>;
+ usb1_vbus-supply = <&reg_vcc>;
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-devterm-v3.14.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-devterm-v3.14.dts
new file mode 100644
index 000000000000..bc5c84f22762
--- /dev/null
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-devterm-v3.14.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
+
+#include "sun20i-d1-clockworkpi-v3.14.dts"
+
+/ {
+ model = "Clockwork DevTerm (R-01)";
+ compatible = "clockwork,r-01-devterm-v3.14",
+ "clockwork,r-01-clockworkpi-v3.14",
+ "allwinner,sun20i-d1";
+
+ fan {
+ compatible = "gpio-fan";
+ gpios = <&pio 3 10 GPIO_ACTIVE_HIGH>; /* PD10/GPIO41 */
+ gpio-fan,speed-map = <0 0>,
+ <6000 1>;
+ #cooling-cells = <2>;
+ };
+
+ i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&pio 3 14 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; /* PD14/GPIO44 */
+ scl-gpios = <&pio 3 15 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; /* PD15/GPIO45 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@54 {
+ compatible = "ti,adc101c";
+ reg = <0x54>;
+ interrupt-parent = <&pio>;
+ interrupts = <4 12 IRQ_TYPE_LEVEL_LOW>; /* PE12/GPIO35 */
+ vref-supply = <&reg_dldo2>;
+ #io-channel-cells = <1>;
+ };
+ };
+};
diff --git a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
index 5a9d7f5a75b4..e4175adb028d 100644
--- a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
@@ -396,6 +396,17 @@
ranges;
#address-cells = <1>;
#size-cells = <1>;
+
+ regulators@3000150 {
+ compatible = "allwinner,sun20i-d1-system-ldos";
+ reg = <0x3000150 0x4>;
+
+ reg_ldoa: ldoa {
+ };
+
+ reg_ldob: ldob {
+ };
+ };
};
dma: dma-controller@3002000 {
diff --git a/arch/riscv/boot/dts/canaan/canaan_kd233.dts b/arch/riscv/boot/dts/canaan/canaan_kd233.dts
index 8df4cf3656f2..a7d753b6fdfd 100644
--- a/arch/riscv/boot/dts/canaan/canaan_kd233.dts
+++ b/arch/riscv/boot/dts/canaan/canaan_kd233.dts
@@ -15,6 +15,10 @@
model = "Kendryte KD233";
compatible = "canaan,kendryte-kd233", "canaan,kendryte-k210";
+ aliases {
+ serial0 = &uarths0;
+ };
+
chosen {
bootargs = "earlycon console=ttySIF0";
stdout-path = "serial0:115200n8";
@@ -46,7 +50,6 @@
&fpioa {
pinctrl-0 = <&jtag_pinctrl>;
pinctrl-names = "default";
- status = "okay";
jtag_pinctrl: jtag-pinmux {
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>,
@@ -118,6 +121,7 @@
#sound-dai-cells = <1>;
pinctrl-0 = <&i2s0_pinctrl>;
pinctrl-names = "default";
+ status = "okay";
};
&spi0 {
@@ -125,6 +129,7 @@
pinctrl-names = "default";
num-cs = <1>;
cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
panel@0 {
compatible = "canaan,kd233-tft", "ilitek,ili9341";
diff --git a/arch/riscv/boot/dts/canaan/k210.dtsi b/arch/riscv/boot/dts/canaan/k210.dtsi
index f87c5164d9cf..4f5d40fa1e77 100644
--- a/arch/riscv/boot/dts/canaan/k210.dtsi
+++ b/arch/riscv/boot/dts/canaan/k210.dtsi
@@ -16,13 +16,6 @@
#size-cells = <1>;
compatible = "canaan,kendryte-k210";
- aliases {
- serial0 = &uarths0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- };
-
/*
* The K210 has an sv39 MMU following the privileged specification v1.9.
* Since this is a non-ratified draft specification, the kernel does not
@@ -137,6 +130,7 @@
reg = <0x38000000 0x1000>;
interrupts = <33>;
clocks = <&sysclk K210_CLK_CPU>;
+ status = "disabled";
};
gpio0: gpio-controller@38001000 {
@@ -152,6 +146,7 @@
<62>, <63>, <64>, <65>;
gpio-controller;
ngpios = <32>;
+ status = "disabled";
};
dmac0: dma-controller@50000000 {
@@ -187,6 +182,7 @@
<&sysclk K210_CLK_GPIO>;
clock-names = "bus", "db";
resets = <&sysrst K210_RST_GPIO>;
+ status = "disabled";
gpio1_0: gpio-port@0 {
#gpio-cells = <2>;
@@ -214,6 +210,7 @@
dsr-override;
cts-override;
ri-override;
+ status = "disabled";
};
uart2: serial@50220000 {
@@ -230,6 +227,7 @@
dsr-override;
cts-override;
ri-override;
+ status = "disabled";
};
uart3: serial@50230000 {
@@ -246,6 +244,7 @@
dsr-override;
cts-override;
ri-override;
+ status = "disabled";
};
spi2: spi@50240000 {
@@ -259,6 +258,7 @@
<&sysclk K210_CLK_APB0>;
clock-names = "ssi_clk", "pclk";
resets = <&sysrst K210_RST_SPI2>;
+ status = "disabled";
};
i2s0: i2s@50250000 {
@@ -268,6 +268,7 @@
clocks = <&sysclk K210_CLK_I2S0>;
clock-names = "i2sclk";
resets = <&sysrst K210_RST_I2S0>;
+ status = "disabled";
};
i2s1: i2s@50260000 {
@@ -277,6 +278,7 @@
clocks = <&sysclk K210_CLK_I2S1>;
clock-names = "i2sclk";
resets = <&sysrst K210_RST_I2S1>;
+ status = "disabled";
};
i2s2: i2s@50270000 {
@@ -286,6 +288,7 @@
clocks = <&sysclk K210_CLK_I2S2>;
clock-names = "i2sclk";
resets = <&sysrst K210_RST_I2S2>;
+ status = "disabled";
};
i2c0: i2c@50280000 {
@@ -296,6 +299,7 @@
<&sysclk K210_CLK_APB0>;
clock-names = "ref", "pclk";
resets = <&sysrst K210_RST_I2C0>;
+ status = "disabled";
};
i2c1: i2c@50290000 {
@@ -306,6 +310,7 @@
<&sysclk K210_CLK_APB0>;
clock-names = "ref", "pclk";
resets = <&sysrst K210_RST_I2C1>;
+ status = "disabled";
};
i2c2: i2c@502a0000 {
@@ -316,6 +321,7 @@
<&sysclk K210_CLK_APB0>;
clock-names = "ref", "pclk";
resets = <&sysrst K210_RST_I2C2>;
+ status = "disabled";
};
fpioa: pinmux@502b0000 {
@@ -464,6 +470,7 @@
reset-names = "spi";
num-cs = <4>;
reg-io-width = <4>;
+ status = "disabled";
};
spi1: spi@53000000 {
@@ -479,6 +486,7 @@
reset-names = "spi";
num-cs = <4>;
reg-io-width = <4>;
+ status = "disabled";
};
spi3: spi@54000000 {
@@ -495,6 +503,7 @@
num-cs = <4>;
reg-io-width = <4>;
+ status = "disabled";
};
};
};
diff --git a/arch/riscv/boot/dts/canaan/k210_generic.dts b/arch/riscv/boot/dts/canaan/k210_generic.dts
index 396c8ca4d24d..5734cc03753b 100644
--- a/arch/riscv/boot/dts/canaan/k210_generic.dts
+++ b/arch/riscv/boot/dts/canaan/k210_generic.dts
@@ -15,6 +15,10 @@
model = "Kendryte K210 generic";
compatible = "canaan,kendryte-k210";
+ aliases {
+ serial0 = &uarths0;
+ };
+
chosen {
bootargs = "earlycon console=ttySIF0";
stdout-path = "serial0:115200n8";
@@ -24,7 +28,6 @@
&fpioa {
pinctrl-0 = <&jtag_pins>;
pinctrl-names = "default";
- status = "okay";
jtag_pins: jtag-pinmux {
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>,
diff --git a/arch/riscv/boot/dts/canaan/sipeed_maix_bit.dts b/arch/riscv/boot/dts/canaan/sipeed_maix_bit.dts
index 6d25bf07481a..2ab376d609d2 100644
--- a/arch/riscv/boot/dts/canaan/sipeed_maix_bit.dts
+++ b/arch/riscv/boot/dts/canaan/sipeed_maix_bit.dts
@@ -17,6 +17,10 @@
compatible = "sipeed,maix-bit", "sipeed,maix-bitm",
"canaan,kendryte-k210";
+ aliases {
+ serial0 = &uarths0;
+ };
+
chosen {
bootargs = "earlycon console=ttySIF0";
stdout-path = "serial0:115200n8";
@@ -58,7 +62,6 @@
&fpioa {
pinctrl-names = "default";
pinctrl-0 = <&jtag_pinctrl>;
- status = "okay";
jtag_pinctrl: jtag-pinmux {
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>,
@@ -156,6 +159,7 @@
#sound-dai-cells = <1>;
pinctrl-0 = <&i2s0_pinctrl>;
pinctrl-names = "default";
+ status = "okay";
};
&i2c1 {
@@ -170,6 +174,7 @@
pinctrl-names = "default";
num-cs = <1>;
cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
panel@0 {
compatible = "sitronix,st7789v";
@@ -199,6 +204,8 @@
};
&spi3 {
+ status = "okay";
+
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
diff --git a/arch/riscv/boot/dts/canaan/sipeed_maix_dock.dts b/arch/riscv/boot/dts/canaan/sipeed_maix_dock.dts
index f4f4d8d5e8b8..d98e20775c07 100644
--- a/arch/riscv/boot/dts/canaan/sipeed_maix_dock.dts
+++ b/arch/riscv/boot/dts/canaan/sipeed_maix_dock.dts
@@ -17,6 +17,10 @@
compatible = "sipeed,maix-dock-m1", "sipeed,maix-dock-m1w",
"canaan,kendryte-k210";
+ aliases {
+ serial0 = &uarths0;
+ };
+
chosen {
bootargs = "earlycon console=ttySIF0";
stdout-path = "serial0:115200n8";
@@ -63,7 +67,6 @@
&fpioa {
pinctrl-0 = <&jtag_pinctrl>;
pinctrl-names = "default";
- status = "okay";
jtag_pinctrl: jtag-pinmux {
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>,
@@ -159,6 +162,7 @@
#sound-dai-cells = <1>;
pinctrl-0 = <&i2s0_pinctrl>;
pinctrl-names = "default";
+ status = "okay";
};
&i2c1 {
@@ -173,6 +177,7 @@
pinctrl-names = "default";
num-cs = <1>;
cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
panel@0 {
compatible = "sitronix,st7789v";
diff --git a/arch/riscv/boot/dts/canaan/sipeed_maix_go.dts b/arch/riscv/boot/dts/canaan/sipeed_maix_go.dts
index 0d86df47e1ed..79ecd549700a 100644
--- a/arch/riscv/boot/dts/canaan/sipeed_maix_go.dts
+++ b/arch/riscv/boot/dts/canaan/sipeed_maix_go.dts
@@ -16,6 +16,10 @@
model = "SiPeed MAIX GO";
compatible = "sipeed,maix-go", "canaan,kendryte-k210";
+ aliases {
+ serial0 = &uarths0;
+ };
+
chosen {
bootargs = "earlycon console=ttySIF0";
stdout-path = "serial0:115200n8";
@@ -69,7 +73,6 @@
&fpioa {
pinctrl-0 = <&jtag_pinctrl>;
pinctrl-names = "default";
- status = "okay";
jtag_pinctrl: jtag-pinmux {
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>,
@@ -167,6 +170,7 @@
#sound-dai-cells = <1>;
pinctrl-0 = <&i2s0_pinctrl>;
pinctrl-names = "default";
+ status = "okay";
};
&i2c1 {
@@ -181,6 +185,7 @@
pinctrl-names = "default";
num-cs = <1>;
cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
panel@0 {
compatible = "sitronix,st7789v";
@@ -209,6 +214,8 @@
};
&spi3 {
+ status = "okay";
+
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
diff --git a/arch/riscv/boot/dts/canaan/sipeed_maixduino.dts b/arch/riscv/boot/dts/canaan/sipeed_maixduino.dts
index 5c05c498e2b8..019c03ae51f6 100644
--- a/arch/riscv/boot/dts/canaan/sipeed_maixduino.dts
+++ b/arch/riscv/boot/dts/canaan/sipeed_maixduino.dts
@@ -15,6 +15,10 @@
model = "SiPeed MAIXDUINO";
compatible = "sipeed,maixduino", "canaan,kendryte-k210";
+ aliases {
+ serial0 = &uarths0;
+ };
+
chosen {
bootargs = "earlycon console=ttySIF0";
stdout-path = "serial0:115200n8";
@@ -39,8 +43,6 @@
};
&fpioa {
- status = "okay";
-
uarths_pinctrl: uarths-pinmux {
pinmux = <K210_FPIOA(4, K210_PCF_UARTHS_RX)>, /* Header "0" */
<K210_FPIOA(5, K210_PCF_UARTHS_TX)>; /* Header "1" */
@@ -132,6 +134,7 @@
#sound-dai-cells = <1>;
pinctrl-0 = <&i2s0_pinctrl>;
pinctrl-names = "default";
+ status = "okay";
};
&i2c1 {
@@ -146,6 +149,7 @@
pinctrl-names = "default";
num-cs = <1>;
cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
panel@0 {
compatible = "sitronix,st7789v";
@@ -174,6 +178,8 @@
};
&spi3 {
+ status = "okay";
+
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
diff --git a/arch/riscv/boot/dts/microchip/Makefile b/arch/riscv/boot/dts/microchip/Makefile
index e177815bf1a2..f51aeeb9fd3b 100644
--- a/arch/riscv/boot/dts/microchip/Makefile
+++ b/arch/riscv/boot/dts/microchip/Makefile
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-beaglev-fire.dtb
dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-icicle-kit.dtb
dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-m100pfsevp.dtb
dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-polarberry.dtb
diff --git a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire-fabric.dtsi b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire-fabric.dtsi
new file mode 100644
index 000000000000..e153eaf9b90e
--- /dev/null
+++ b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire-fabric.dtsi
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/ {
+ fabric_clk3: fabric-clk3 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ };
+
+ fabric_clk1: fabric-clk1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ };
+
+ fabric-bus@40000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x40000000 0x0 0x40000000 0x0 0x20000000>, /* FIC3-FAB */
+ <0x0 0x60000000 0x0 0x60000000 0x0 0x20000000>, /* FIC0, LO */
+ <0x0 0xe0000000 0x0 0xe0000000 0x0 0x20000000>, /* FIC1, LO */
+ <0x20 0x0 0x20 0x0 0x10 0x0>, /* FIC0,HI */
+ <0x30 0x0 0x30 0x0 0x10 0x0>; /* FIC1,HI */
+
+ cape_gpios_p8: gpio@41100000 {
+ compatible = "microchip,coregpio-rtl-v3";
+ reg = <0x0 0x41100000 0x0 0x1000>;
+ clocks = <&fabric_clk3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <16>;
+ gpio-line-names = "P8_PIN31", "P8_PIN32", "P8_PIN33", "P8_PIN34",
+ "P8_PIN35", "P8_PIN36", "P8_PIN37", "P8_PIN38",
+ "P8_PIN39", "P8_PIN40", "P8_PIN41", "P8_PIN42",
+ "P8_PIN43", "P8_PIN44", "P8_PIN45", "P8_PIN46";
+ };
+
+ cape_gpios_p9: gpio@41200000 {
+ compatible = "microchip,coregpio-rtl-v3";
+ reg = <0x0 0x41200000 0x0 0x1000>;
+ clocks = <&fabric_clk3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <20>;
+ gpio-line-names = "P9_PIN11", "P9_PIN12", "P9_PIN13", "P9_PIN14",
+ "P9_PIN15", "P9_PIN16", "P9_PIN17", "P9_PIN18",
+ "P9_PIN21", "P9_PIN22", "P9_PIN23", "P9_PIN24",
+ "P9_PIN25", "P9_PIN26", "P9_PIN27", "P9_PIN28",
+ "P9_PIN29", "P9_PIN31", "P9_PIN41", "P9_PIN42";
+ };
+
+ hsi_gpios: gpio@44000000 {
+ compatible = "microchip,coregpio-rtl-v3";
+ reg = <0x0 0x44000000 0x0 0x1000>;
+ clocks = <&fabric_clk3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <20>;
+ gpio-line-names = "B0_HSIO70N", "B0_HSIO71N", "B0_HSIO83N",
+ "B0_HSIO73N_C2P_CLKN", "B0_HSIO70P", "B0_HSIO71P",
+ "B0_HSIO83P", "B0_HSIO73N_C2P_CLKP", "XCVR1_RX_VALID",
+ "XCVR1_LOCK", "XCVR1_ERROR", "XCVR2_RX_VALID",
+ "XCVR2_LOCK", "XCVR2_ERROR", "XCVR3_RX_VALID",
+ "XCVR3_LOCK", "XCVR3_ERROR", "XCVR_0B_REF_CLK_PLL_LOCK",
+ "XCVR_0C_REF_CLK_PLL_LOCK", "B0_HSIO81N";
+ };
+ };
+
+ refclk_ccc: cccrefclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+};
+
+&ccc_nw {
+ clocks = <&refclk_ccc>, <&refclk_ccc>, <&refclk_ccc>, <&refclk_ccc>,
+ <&refclk_ccc>, <&refclk_ccc>;
+ clock-names = "pll0_ref0", "pll0_ref1", "pll1_ref0", "pll1_ref1",
+ "dll0_ref", "dll1_ref";
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
new file mode 100644
index 000000000000..47cf693beb68
--- /dev/null
+++ b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Copyright (c) 2020-2021 Microchip Technology Inc */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "mpfs.dtsi"
+#include "mpfs-beaglev-fire-fabric.dtsi"
+
+/* Clock frequency (in Hz) of MTIMER */
+#define MTIMER_FREQ 1000000
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "BeagleBoard BeagleV-Fire";
+ compatible = "beagle,beaglev-fire", "microchip,mpfs";
+
+ aliases {
+ serial0 = &mmuart0;
+ serial1 = &mmuart1;
+ serial2 = &mmuart2;
+ serial3 = &mmuart3;
+ serial4 = &mmuart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ cpus {
+ timebase-frequency = <MTIMER_FREQ>;
+ };
+
+ ddrc_cache_lo: memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x40000000>;
+ status = "okay";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ hss: hss-buffer@103fc00000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10 0x3fc00000 0x0 0x400000>;
+ no-map;
+ };
+ };
+
+ imx219_clk: camera-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+
+ imx219_vana: fixedregulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "imx219_vana";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ imx219_vdig: fixedregulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "imx219_vdig";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ imx219_vddl: fixedregulator-2 {
+ compatible = "regulator-fixed";
+ regulator-name = "imx219_vddl";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+};
+
+&gpio2 {
+ interrupts = <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>,
+ <53>, <53>, <53>, <53>;
+ ngpios=<32>;
+ gpio-line-names = "P8_PIN3_USER_LED_0", "P8_PIN4_USER_LED_1", "P8_PIN5_USER_LED_2",
+ "P8_PIN6_USER_LED_3", "P8_PIN7_USER_LED_4", "P8_PIN8_USER_LED_5",
+ "P8_PIN9_USER_LED_6", "P8_PIN10_USER_LED_7", "P8_PIN11_USER_LED_8",
+ "P8_PIN12_USER_LED_9", "P8_PIN13_USER_LED_10", "P8_PIN14_USER_LED_11",
+ "P8_PIN15", "P8_PIN16", "P8_PIN17", "P8_PIN18", "P8_PIN19", "P8_PIN20",
+ "P8_PIN21", "P8_PIN22", "P8_PIN23", "P8_PIN24", "P8_PIN25", "P8_PIN26",
+ "P8_PIN27", "P8_PIN28", "P8_PIN29", "P8_PIN30", "M2_W_DISABLE1",
+ "M2_W_DISABLE2", "VIO_ENABLE", "SD_DET";
+ status = "okay";
+
+ vio-enable-hog {
+ gpio-hog;
+ gpios = <30 30>;
+ output-high;
+ line-name = "VIO_ENABLE";
+ };
+
+ sd-det-hog {
+ gpio-hog;
+ gpios = <31 31>;
+ input;
+ line-name = "SD_DET";
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c32";
+ reg = <0x50>;
+ };
+
+ imx219: sensor@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+ clocks = <&imx219_clk>;
+ VANA-supply = <&imx219_vana>; /* 2.8v */
+ VDIG-supply = <&imx219_vdig>; /* 1.8v */
+ VDDL-supply = <&imx219_vddl>; /* 1.2v */
+
+ port {
+ imx219_0: endpoint {
+ data-lanes = <1 2>;
+ clock-noncontinuous;
+ link-frequencies = /bits/ 64 <456000000>;
+ };
+ };
+ };
+};
+
+&mac0 {
+ status = "okay";
+ phy-mode = "sgmii";
+ phy-handle = <&phy0>;
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&mbox {
+ status = "okay";
+};
+
+&mmc {
+ bus-width = <4>;
+ disable-wp;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&mmuart0 {
+ status = "okay";
+};
+
+&mmuart1 {
+ status = "okay";
+};
+
+&refclk {
+ clock-frequency = <125000000>;
+};
+
+&refclk_ccc {
+ clock-frequency = <50000000>;
+};
+
+&rtc {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+};
+
+&spi1 {
+ status = "okay";
+};
+
+&syscontroller {
+ microchip,bitstream-flash = <&sys_ctrl_flash>;
+ status = "okay";
+};
+
+&syscontroller_qspi {
+ status = "okay";
+
+ sys_ctrl_flash: flash@0 { // MT25QL01GBBB8ESF-0SIT
+ compatible = "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <20000000>;
+ spi-rx-bus-width = <1>;
+ reg = <0>;
+ };
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "otg";
+};
diff --git a/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts b/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts
index 222a39d90f85..f80df225f72b 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts
@@ -100,6 +100,38 @@
&i2c1 {
status = "okay";
+
+ power-monitor@10 {
+ compatible = "microchip,pac1934";
+ reg = <0x10>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@1 {
+ reg = <0x1>;
+ shunt-resistor-micro-ohms = <10000>;
+ label = "VDDREG";
+ };
+
+ channel@2 {
+ reg = <0x2>;
+ shunt-resistor-micro-ohms = <10000>;
+ label = "VDDA25";
+ };
+
+ channel@3 {
+ reg = <0x3>;
+ shunt-resistor-micro-ohms = <10000>;
+ label = "VDD25";
+ };
+
+ channel@4 {
+ reg = <0x4>;
+ shunt-resistor-micro-ohms = <10000>;
+ label = "VDDA_REG";
+ };
+ };
};
&i2c2 {
diff --git a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
index f35324b9173c..e0ddf8f602c7 100644
--- a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
+++ b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
@@ -54,6 +54,81 @@
dma-noncoherent;
interrupt-parent = <&plic>;
+ irqc: interrupt-controller@110a0000 {
+ compatible = "renesas,r9a07g043f-irqc";
+ reg = <0 0x110a0000 0 0x20000>;
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+ <33 IRQ_TYPE_LEVEL_HIGH>,
+ <34 IRQ_TYPE_LEVEL_HIGH>,
+ <35 IRQ_TYPE_LEVEL_HIGH>,
+ <36 IRQ_TYPE_LEVEL_HIGH>,
+ <37 IRQ_TYPE_LEVEL_HIGH>,
+ <38 IRQ_TYPE_LEVEL_HIGH>,
+ <39 IRQ_TYPE_LEVEL_HIGH>,
+ <40 IRQ_TYPE_LEVEL_HIGH>,
+ <476 IRQ_TYPE_LEVEL_HIGH>,
+ <477 IRQ_TYPE_LEVEL_HIGH>,
+ <478 IRQ_TYPE_LEVEL_HIGH>,
+ <479 IRQ_TYPE_LEVEL_HIGH>,
+ <480 IRQ_TYPE_LEVEL_HIGH>,
+ <481 IRQ_TYPE_LEVEL_HIGH>,
+ <482 IRQ_TYPE_LEVEL_HIGH>,
+ <483 IRQ_TYPE_LEVEL_HIGH>,
+ <484 IRQ_TYPE_LEVEL_HIGH>,
+ <485 IRQ_TYPE_LEVEL_HIGH>,
+ <486 IRQ_TYPE_LEVEL_HIGH>,
+ <487 IRQ_TYPE_LEVEL_HIGH>,
+ <488 IRQ_TYPE_LEVEL_HIGH>,
+ <489 IRQ_TYPE_LEVEL_HIGH>,
+ <490 IRQ_TYPE_LEVEL_HIGH>,
+ <491 IRQ_TYPE_LEVEL_HIGH>,
+ <492 IRQ_TYPE_LEVEL_HIGH>,
+ <493 IRQ_TYPE_LEVEL_HIGH>,
+ <494 IRQ_TYPE_LEVEL_HIGH>,
+ <495 IRQ_TYPE_LEVEL_HIGH>,
+ <496 IRQ_TYPE_LEVEL_HIGH>,
+ <497 IRQ_TYPE_LEVEL_HIGH>,
+ <498 IRQ_TYPE_LEVEL_HIGH>,
+ <499 IRQ_TYPE_LEVEL_HIGH>,
+ <500 IRQ_TYPE_LEVEL_HIGH>,
+ <501 IRQ_TYPE_LEVEL_HIGH>,
+ <502 IRQ_TYPE_LEVEL_HIGH>,
+ <503 IRQ_TYPE_LEVEL_HIGH>,
+ <504 IRQ_TYPE_LEVEL_HIGH>,
+ <505 IRQ_TYPE_LEVEL_HIGH>,
+ <506 IRQ_TYPE_LEVEL_HIGH>,
+ <507 IRQ_TYPE_LEVEL_HIGH>,
+ <57 IRQ_TYPE_LEVEL_HIGH>,
+ <66 IRQ_TYPE_EDGE_RISING>,
+ <67 IRQ_TYPE_EDGE_RISING>,
+ <68 IRQ_TYPE_EDGE_RISING>,
+ <69 IRQ_TYPE_EDGE_RISING>,
+ <70 IRQ_TYPE_EDGE_RISING>,
+ <71 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "nmi",
+ "irq0", "irq1", "irq2", "irq3",
+ "irq4", "irq5", "irq6", "irq7",
+ "tint0", "tint1", "tint2", "tint3",
+ "tint4", "tint5", "tint6", "tint7",
+ "tint8", "tint9", "tint10", "tint11",
+ "tint12", "tint13", "tint14", "tint15",
+ "tint16", "tint17", "tint18", "tint19",
+ "tint20", "tint21", "tint22", "tint23",
+ "tint24", "tint25", "tint26", "tint27",
+ "tint28", "tint29", "tint30", "tint31",
+ "bus-err", "ec7tie1-0", "ec7tie2-0",
+ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
+ "ec7tiovf-1";
+ clocks = <&cpg CPG_MOD R9A07G043_IAX45_CLK>,
+ <&cpg CPG_MOD R9A07G043_IAX45_PCLK>;
+ clock-names = "clk", "pclk";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G043_IAX45_RESETN>;
+ };
+
plic: interrupt-controller@12c00000 {
compatible = "renesas,r9a07g043-plic", "andestech,nceplic100";
#interrupt-cells = <2>;
diff --git a/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi b/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
index 433ab5c6a626..5e808242649e 100644
--- a/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
+++ b/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
@@ -6,19 +6,3 @@
*/
#include <arm64/renesas/rzg2ul-smarc-som.dtsi>
-
-#if (!SW_ET0_EN_N)
-&eth0 {
- phy0: ethernet-phy@7 {
- /delete-property/ interrupt-parent;
- /delete-property/ interrupts;
- };
-};
-#endif
-
-&eth1 {
- phy1: ethernet-phy@7 {
- /delete-property/ interrupt-parent;
- /delete-property/ interrupts;
- };
-};
diff --git a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
index 3af9e34b3bc7..375ff2661b6e 100644
--- a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
+++ b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
@@ -23,9 +23,15 @@
stdout-path = "serial0:115200n8";
};
- memory@80000000 {
- device_type = "memory";
- reg = <0x80000000 0x3f40000>;
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ coprocessor_rtos: region@83f40000 {
+ reg = <0x83f40000 0xc0000>;
+ no-map;
+ };
};
};
@@ -33,6 +39,15 @@
clock-frequency = <25000000>;
};
+&sdhci0 {
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/sophgo/cv1800b.dtsi b/arch/riscv/boot/dts/sophgo/cv1800b.dtsi
index 165e9e320a8c..ec9530972ae2 100644
--- a/arch/riscv/boot/dts/sophgo/cv1800b.dtsi
+++ b/arch/riscv/boot/dts/sophgo/cv1800b.dtsi
@@ -7,6 +7,11 @@
/ {
compatible = "sophgo,cv1800b";
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x4000000>;
+ };
};
&plic {
@@ -16,3 +21,7 @@
&clint {
compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
};
+
+&clk {
+ compatible = "sophgo,cv1800-clk";
+};
diff --git a/arch/riscv/boot/dts/sophgo/cv1812h.dtsi b/arch/riscv/boot/dts/sophgo/cv1812h.dtsi
index 3e7a942f5c1a..7fa4c1e2d1da 100644
--- a/arch/riscv/boot/dts/sophgo/cv1812h.dtsi
+++ b/arch/riscv/boot/dts/sophgo/cv1812h.dtsi
@@ -22,3 +22,7 @@
&clint {
compatible = "sophgo,cv1812h-clint", "thead,c900-clint";
};
+
+&clk {
+ compatible = "sophgo,cv1810-clk";
+};
diff --git a/arch/riscv/boot/dts/sophgo/cv18xx.dtsi b/arch/riscv/boot/dts/sophgo/cv18xx.dtsi
index 2d6f4a4b1e58..891932ae470f 100644
--- a/arch/riscv/boot/dts/sophgo/cv18xx.dtsi
+++ b/arch/riscv/boot/dts/sophgo/cv18xx.dtsi
@@ -4,6 +4,8 @@
* Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
*/
+#include <dt-bindings/clock/sophgo,cv1800.h>
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
@@ -53,6 +55,12 @@
dma-noncoherent;
ranges;
+ clk: clock-controller@3002000 {
+ reg = <0x03002000 0x1000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+
gpio0: gpio@3020000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3020000 0x1000>;
@@ -125,11 +133,67 @@
};
};
+ i2c0: i2c@4000000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x04000000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C0>;
+ clock-names = "ref", "pclk";
+ interrupts = <49 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@4010000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x04010000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C1>;
+ clock-names = "ref", "pclk";
+ interrupts = <50 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@4020000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x04020000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C2>;
+ clock-names = "ref", "pclk";
+ interrupts = <51 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@4030000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x04030000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C3>;
+ clock-names = "ref", "pclk";
+ interrupts = <52 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@4040000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x04040000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C4>;
+ clock-names = "ref", "pclk";
+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
uart0: serial@4140000 {
compatible = "snps,dw-apb-uart";
reg = <0x04140000 0x100>;
interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&osc>;
+ clocks = <&clk CLK_UART0>, <&clk CLK_APB_UART0>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -139,7 +203,8 @@
compatible = "snps,dw-apb-uart";
reg = <0x04150000 0x100>;
interrupts = <45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&osc>;
+ clocks = <&clk CLK_UART1>, <&clk CLK_APB_UART1>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -149,7 +214,8 @@
compatible = "snps,dw-apb-uart";
reg = <0x04160000 0x100>;
interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&osc>;
+ clocks = <&clk CLK_UART2>, <&clk CLK_APB_UART2>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -159,22 +225,78 @@
compatible = "snps,dw-apb-uart";
reg = <0x04170000 0x100>;
interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&osc>;
+ clocks = <&clk CLK_UART3>, <&clk CLK_APB_UART3>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
+ spi0: spi@4180000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x04180000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI0>;
+ clock-names = "ssi_clk", "pclk";
+ interrupts = <54 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi1: spi@4190000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x04190000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI1>;
+ clock-names = "ssi_clk", "pclk";
+ interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi2: spi@41a0000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x041a0000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI2>;
+ clock-names = "ssi_clk", "pclk";
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi3: spi@41b0000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x041b0000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI3>;
+ clock-names = "ssi_clk", "pclk";
+ interrupts = <57 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
uart4: serial@41c0000 {
compatible = "snps,dw-apb-uart";
reg = <0x041c0000 0x100>;
interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&osc>;
+ clocks = <&clk CLK_UART4>, <&clk CLK_APB_UART4>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
+ sdhci0: mmc@4310000 {
+ compatible = "sophgo,cv1800b-dwcmshc";
+ reg = <0x4310000 0x1000>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk CLK_AXI4_SD0>,
+ <&clk CLK_SD0>;
+ clock-names = "core", "bus";
+ status = "disabled";
+ };
+
plic: interrupt-controller@70000000 {
reg = <0x70000000 0x4000000>;
interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
index 49b4b9c2c101..80cb017974d8 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
@@ -14,6 +14,18 @@
};
};
+&cgi_main {
+ clock-frequency = <25000000>;
+};
+
+&cgi_dpll0 {
+ clock-frequency = <25000000>;
+};
+
+&cgi_dpll1 {
+ clock-frequency = <25000000>;
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
index 81fda312f988..34c802bd3f9b 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi
+++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
@@ -4,8 +4,10 @@
*/
/dts-v1/;
+#include <dt-bindings/clock/sophgo,sg2042-clkgen.h>
+#include <dt-bindings/clock/sophgo,sg2042-pll.h>
+#include <dt-bindings/clock/sophgo,sg2042-rpgate.h>
#include <dt-bindings/interrupt-controller/irq.h>
-
#include <dt-bindings/reset/sophgo,sg2042-reset.h>
#include "sg2042-cpus.dtsi"
@@ -20,12 +22,60 @@
serial0 = &uart0;
};
+ cgi_main: oscillator0 {
+ compatible = "fixed-clock";
+ clock-output-names = "cgi_main";
+ #clock-cells = <0>;
+ };
+
+ cgi_dpll0: oscillator1 {
+ compatible = "fixed-clock";
+ clock-output-names = "cgi_dpll0";
+ #clock-cells = <0>;
+ };
+
+ cgi_dpll1: oscillator2 {
+ compatible = "fixed-clock";
+ clock-output-names = "cgi_dpll1";
+ #clock-cells = <0>;
+ };
+
soc: soc {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
+ pllclk: clock-controller@70300100c0 {
+ compatible = "sophgo,sg2042-pll";
+ reg = <0x70 0x300100c0 0x0 0x40>;
+ clocks = <&cgi_main>, <&cgi_dpll0>, <&cgi_dpll1>;
+ clock-names = "cgi_main", "cgi_dpll0", "cgi_dpll1";
+ #clock-cells = <1>;
+ };
+
+ rpgate: clock-controller@7030010368 {
+ compatible = "sophgo,sg2042-rpgate";
+ reg = <0x70 0x30010368 0x0 0x98>;
+ clocks = <&clkgen GATE_CLK_RP_CPU_NORMAL>;
+ clock-names = "rpgate";
+ #clock-cells = <1>;
+ };
+
+ clkgen: clock-controller@7030012000 {
+ compatible = "sophgo,sg2042-clkgen";
+ reg = <0x70 0x30012000 0x0 0x1000>;
+ clocks = <&pllclk MPLL_CLK>,
+ <&pllclk FPLL_CLK>,
+ <&pllclk DPLL0_CLK>,
+ <&pllclk DPLL1_CLK>;
+ clock-names = "mpll",
+ "fpll",
+ "dpll0",
+ "dpll1";
+ #clock-cells = <1>;
+ };
+
clint_mswi: interrupt-controller@7094000000 {
compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi";
reg = <0x00000070 0x94000000 0x00000000 0x00004000>;
@@ -341,6 +391,9 @@
interrupt-parent = <&intc>;
interrupts = <112 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <500000000>;
+ clocks = <&clkgen GATE_CLK_UART_500M>,
+ <&clkgen GATE_CLK_APB_UART>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
resets = <&rstgen RST_UART0>;
diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
index 0141504c0f5c..7a163a7d6ba3 100644
--- a/arch/riscv/boot/dts/starfive/Makefile
+++ b/arch/riscv/boot/dts/starfive/Makefile
@@ -8,5 +8,7 @@ DTC_FLAGS_jh7110-starfive-visionfive-2-v1.3b := -@
dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-mars.dtb
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-pine64-star64.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 9a2e9583af88..7de0732b8eab 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -13,7 +13,7 @@
#address-cells = <2>;
#size-cells = <2>;
- cpus {
+ cpus: cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
new file mode 100644
index 000000000000..ca2d44d59d48
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
@@ -0,0 +1,658 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+/dts-v1/;
+#include "jh7110.dtsi"
+#include "jh7110-pinfunc.h"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ aliases {
+ ethernet0 = &gmac0;
+ i2c0 = &i2c0;
+ i2c2 = &i2c2;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0x1 0x0>;
+ };
+
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
+ priority = <224>;
+ };
+
+ pwmdac_codec: audio-codec {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ format = "left_j";
+ bitclock-master = <&sndcpu0>;
+ frame-master = <&sndcpu0>;
+
+ sndcpu0: cpu {
+ sound-dai = <&pwmdac>;
+ };
+
+ codec {
+ sound-dai = <&pwmdac_codec>;
+ };
+ };
+ };
+};
+
+&cpus {
+ timebase-frequency = <4000000>;
+};
+
+&dvp_clk {
+ clock-frequency = <74250000>;
+};
+
+&gmac0_rgmii_rxin {
+ clock-frequency = <125000000>;
+};
+
+&gmac0_rmii_refin {
+ clock-frequency = <50000000>;
+};
+
+&gmac1_rgmii_rxin {
+ clock-frequency = <125000000>;
+};
+
+&gmac1_rmii_refin {
+ clock-frequency = <50000000>;
+};
+
+&hdmitx0_pixelclk {
+ clock-frequency = <297000000>;
+};
+
+&i2srx_bclk_ext {
+ clock-frequency = <12288000>;
+};
+
+&i2srx_lrck_ext {
+ clock-frequency = <192000>;
+};
+
+&i2stx_bclk_ext {
+ clock-frequency = <12288000>;
+};
+
+&i2stx_lrck_ext {
+ clock-frequency = <192000>;
+};
+
+&mclk_ext {
+ clock-frequency = <12288000>;
+};
+
+&osc {
+ clock-frequency = <24000000>;
+};
+
+&rtc_osc {
+ clock-frequency = <32768>;
+};
+
+&tdm_ext {
+ clock-frequency = <49152000>;
+};
+
+&camss {
+ assigned-clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
+ <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>;
+ assigned-clock-rates = <49500000>, <198000000>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+
+ camss_from_csi2rx: endpoint {
+ remote-endpoint = <&csi2rx_to_camss>;
+ };
+ };
+ };
+};
+
+&csi2rx {
+ assigned-clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>;
+ assigned-clock-rates = <297000000>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ /* remote MIPI sensor endpoint */
+ };
+
+ port@1 {
+ reg = <1>;
+
+ csi2rx_to_camss: endpoint {
+ remote-endpoint = <&camss_from_csi2rx>;
+ };
+ };
+ };
+};
+
+&gmac0 {
+ phy-handle = <&phy0>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <510>;
+ i2c-scl-falling-time-ns = <510>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <510>;
+ i2c-scl-falling-time-ns = <510>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ status = "okay";
+};
+
+&i2c5 {
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <510>;
+ i2c-scl-falling-time-ns = <510>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins>;
+ status = "okay";
+
+ axp15060: pmic@36 {
+ compatible = "x-powers,axp15060";
+ reg = <0x36>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ regulators {
+ vcc_3v3: dcdc1 {
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3";
+ };
+
+ vdd_cpu: dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1540000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ emmc_vdd: aldo4 {
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "emmc_vdd";
+ };
+ };
+ };
+};
+
+&i2c6 {
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <510>;
+ i2c-scl-falling-time-ns = <510>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_pins>;
+ status = "okay";
+};
+
+&mmc0 {
+ max-frequency = <100000000>;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
+ assigned-clock-rates = <50000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ cap-mmc-hw-reset;
+ post-power-on-delay-ms = <200>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
+ status = "okay";
+};
+
+&mmc1 {
+ max-frequency = <100000000>;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
+ assigned-clock-rates = <50000000>;
+ bus-width = <4>;
+ no-sdio;
+ no-mmc;
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ cap-sd-highspeed;
+ post-power-on-delay-ms = <200>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ status = "okay";
+};
+
+&pcie0 {
+ perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
+ phys = <&pciephy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins>;
+};
+
+&pcie1 {
+ perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
+ phys = <&pciephy1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins>;
+};
+
+&pwmdac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwmdac_pins>;
+ status = "okay";
+};
+
+&qspi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ nor_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ cdns,read-delay = <5>;
+ spi-max-frequency = <12000000>;
+ cdns,tshsl-ns = <1>;
+ cdns,tsd2d-ns = <1>;
+ cdns,tchsh-ns = <1>;
+ cdns,tslch-ns = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ spl@0 {
+ reg = <0x0 0xf0000>;
+ };
+ uboot-env@f0000 {
+ reg = <0xf0000 0x10000>;
+ };
+ uboot@100000 {
+ reg = <0x100000 0xf00000>;
+ };
+ };
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ status = "okay";
+
+ spi_dev0: spi@0 {
+ compatible = "rohm,dh2228fv";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
+&sysgpio {
+ i2c0_pins: i2c0-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(57, GPOUT_LOW,
+ GPOEN_SYS_I2C0_CLK,
+ GPI_SYS_I2C0_CLK)>,
+ <GPIOMUX(58, GPOUT_LOW,
+ GPOEN_SYS_I2C0_DATA,
+ GPI_SYS_I2C0_DATA)>;
+ bias-disable; /* external pull-up */
+ input-enable;
+ input-schmitt-enable;
+ };
+ };
+
+ i2c2_pins: i2c2-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(3, GPOUT_LOW,
+ GPOEN_SYS_I2C2_CLK,
+ GPI_SYS_I2C2_CLK)>,
+ <GPIOMUX(2, GPOUT_LOW,
+ GPOEN_SYS_I2C2_DATA,
+ GPI_SYS_I2C2_DATA)>;
+ bias-disable; /* external pull-up */
+ input-enable;
+ input-schmitt-enable;
+ };
+ };
+
+ i2c5_pins: i2c5-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(19, GPOUT_LOW,
+ GPOEN_SYS_I2C5_CLK,
+ GPI_SYS_I2C5_CLK)>,
+ <GPIOMUX(20, GPOUT_LOW,
+ GPOEN_SYS_I2C5_DATA,
+ GPI_SYS_I2C5_DATA)>;
+ bias-disable; /* external pull-up */
+ input-enable;
+ input-schmitt-enable;
+ };
+ };
+
+ i2c6_pins: i2c6-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(16, GPOUT_LOW,
+ GPOEN_SYS_I2C6_CLK,
+ GPI_SYS_I2C6_CLK)>,
+ <GPIOMUX(17, GPOUT_LOW,
+ GPOEN_SYS_I2C6_DATA,
+ GPI_SYS_I2C6_DATA)>;
+ bias-disable; /* external pull-up */
+ input-enable;
+ input-schmitt-enable;
+ };
+ };
+
+ mmc0_pins: mmc0-0 {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ mmc-pins {
+ pinmux = <PINMUX(64, 0)>,
+ <PINMUX(65, 0)>,
+ <PINMUX(66, 0)>,
+ <PINMUX(67, 0)>,
+ <PINMUX(68, 0)>,
+ <PINMUX(69, 0)>,
+ <PINMUX(70, 0)>,
+ <PINMUX(71, 0)>,
+ <PINMUX(72, 0)>,
+ <PINMUX(73, 0)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-enable;
+ };
+ };
+
+ mmc1_pins: mmc1-0 {
+ clk-pins {
+ pinmux = <GPIOMUX(10, GPOUT_SYS_SDIO1_CLK,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ mmc-pins {
+ pinmux = <GPIOMUX(9, GPOUT_SYS_SDIO1_CMD,
+ GPOEN_SYS_SDIO1_CMD,
+ GPI_SYS_SDIO1_CMD)>,
+ <GPIOMUX(11, GPOUT_SYS_SDIO1_DATA0,
+ GPOEN_SYS_SDIO1_DATA0,
+ GPI_SYS_SDIO1_DATA0)>,
+ <GPIOMUX(12, GPOUT_SYS_SDIO1_DATA1,
+ GPOEN_SYS_SDIO1_DATA1,
+ GPI_SYS_SDIO1_DATA1)>,
+ <GPIOMUX(7, GPOUT_SYS_SDIO1_DATA2,
+ GPOEN_SYS_SDIO1_DATA2,
+ GPI_SYS_SDIO1_DATA2)>,
+ <GPIOMUX(8, GPOUT_SYS_SDIO1_DATA3,
+ GPOEN_SYS_SDIO1_DATA3,
+ GPI_SYS_SDIO1_DATA3)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-enable;
+ input-schmitt-enable;
+ slew-rate = <0>;
+ };
+ };
+
+ pcie0_pins: pcie0-0 {
+ clkreq-pins {
+ pinmux = <GPIOMUX(27, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_NONE)>;
+ bias-pull-down;
+ drive-strength = <2>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ wake-pins {
+ pinmux = <GPIOMUX(32, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <2>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
+ pcie1_pins: pcie1-0 {
+ clkreq-pins {
+ pinmux = <GPIOMUX(29, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_NONE)>;
+ bias-pull-down;
+ drive-strength = <2>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ wake-pins {
+ pinmux = <GPIOMUX(21, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <2>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
+ pwmdac_pins: pwmdac-0 {
+ pwmdac-pins {
+ pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
+ GPOEN_ENABLE,
+ GPI_NONE)>,
+ <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <2>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
+ pwm_pins: pwm-0 {
+ pwm-pins {
+ pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
+ GPOEN_SYS_PWM0_CHANNEL0,
+ GPI_NONE)>,
+ <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
+ GPOEN_SYS_PWM0_CHANNEL1,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
+ spi0_pins: spi0-0 {
+ mosi-pins {
+ pinmux = <GPIOMUX(52, GPOUT_SYS_SPI0_TXD,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ input-disable;
+ input-schmitt-disable;
+ };
+
+ miso-pins {
+ pinmux = <GPIOMUX(53, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_SPI0_RXD)>;
+ bias-pull-up;
+ input-enable;
+ input-schmitt-enable;
+ };
+
+ sck-pins {
+ pinmux = <GPIOMUX(48, GPOUT_SYS_SPI0_CLK,
+ GPOEN_ENABLE,
+ GPI_SYS_SPI0_CLK)>;
+ bias-disable;
+ input-disable;
+ input-schmitt-disable;
+ };
+
+ ss-pins {
+ pinmux = <GPIOMUX(49, GPOUT_SYS_SPI0_FSS,
+ GPOEN_ENABLE,
+ GPI_SYS_SPI0_FSS)>;
+ bias-disable;
+ input-disable;
+ input-schmitt-disable;
+ };
+ };
+
+ uart0_pins: uart0-0 {
+ tx-pins {
+ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ rx-pins {
+ pinmux = <GPIOMUX(6, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_UART0_RX)>;
+ bias-disable; /* external pull-up */
+ drive-strength = <2>;
+ input-enable;
+ input-schmitt-enable;
+ slew-rate = <0>;
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&usb0 {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&U74_1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&U74_2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&U74_3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&U74_4 {
+ cpu-supply = <&vdd_cpu>;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
new file mode 100644
index 000000000000..5cb9e99e1dac
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+#include "jh7110-common.dtsi"
+
+/ {
+ model = "Milk-V Mars";
+ compatible = "milkv,mars", "starfive,jh7110";
+};
+
+&gmac0 {
+ starfive,tx-use-rgmii-clk;
+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
+};
+
+&pcie0 {
+ status = "okay";
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&phy0 {
+ motorcomm,tx-clk-adj-enabled;
+ motorcomm,tx-clk-10-inverted;
+ motorcomm,tx-clk-100-inverted;
+ motorcomm,tx-clk-1000-inverted;
+ motorcomm,rx-clk-drv-microamp = <3970>;
+ motorcomm,rx-data-drv-microamp = <2910>;
+ rx-internal-delay-ps = <1500>;
+ tx-internal-delay-ps = <1500>;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
new file mode 100644
index 000000000000..b720cdd15ed6
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2024 Henry Bell <dmoo_dv@protonmail.com>
+ */
+
+/dts-v1/;
+#include "jh7110-common.dtsi"
+
+/ {
+ model = "Pine64 Star64";
+ compatible = "pine64,star64", "starfive,jh7110";
+ aliases {
+ ethernet1 = &gmac1;
+ };
+};
+
+&gmac0 {
+ starfive,tx-use-rgmii-clk;
+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
+};
+
+&gmac1 {
+ phy-handle = <&phy1>;
+ phy-mode = "rgmii-id";
+ starfive,tx-use-rgmii-clk;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>;
+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&phy0 {
+ rx-internal-delay-ps = <1900>;
+ tx-internal-delay-ps = <1500>;
+ motorcomm,rx-clk-drv-microamp = <2910>;
+ motorcomm,rx-data-drv-microamp = <2910>;
+ motorcomm,tx-clk-adj-enabled;
+ motorcomm,tx-clk-10-inverted;
+ motorcomm,tx-clk-100-inverted;
+ motorcomm,tx-clk-1000-inverted;
+};
+
+&phy1 {
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <300>;
+ motorcomm,rx-clk-drv-microamp = <2910>;
+ motorcomm,rx-data-drv-microamp = <2910>;
+ motorcomm,tx-clk-adj-enabled;
+ motorcomm,tx-clk-10-inverted;
+ motorcomm,tx-clk-100-inverted;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
index 45b58b6f3df8..18f38fc790a4 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -5,188 +5,11 @@
*/
/dts-v1/;
-#include "jh7110.dtsi"
-#include "jh7110-pinfunc.h"
-#include <dt-bindings/gpio/gpio.h>
+#include "jh7110-common.dtsi"
/ {
aliases {
- ethernet0 = &gmac0;
ethernet1 = &gmac1;
- i2c0 = &i2c0;
- i2c2 = &i2c2;
- i2c5 = &i2c5;
- i2c6 = &i2c6;
- mmc0 = &mmc0;
- mmc1 = &mmc1;
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- cpus {
- timebase-frequency = <4000000>;
- };
-
- memory@40000000 {
- device_type = "memory";
- reg = <0x0 0x40000000 0x1 0x0>;
- };
-
- gpio-restart {
- compatible = "gpio-restart";
- gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
- priority = <224>;
- };
-
- pwmdac_codec: pwmdac-codec {
- compatible = "linux,spdif-dit";
- #sound-dai-cells = <0>;
- };
-
- sound-pwmdac {
- compatible = "simple-audio-card";
- simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
- #address-cells = <1>;
- #size-cells = <0>;
-
- simple-audio-card,dai-link@0 {
- reg = <0>;
- format = "left_j";
- bitclock-master = <&sndcpu0>;
- frame-master = <&sndcpu0>;
-
- sndcpu0: cpu {
- sound-dai = <&pwmdac>;
- };
-
- codec {
- sound-dai = <&pwmdac_codec>;
- };
- };
- };
-};
-
-&dvp_clk {
- clock-frequency = <74250000>;
-};
-
-&gmac0_rgmii_rxin {
- clock-frequency = <125000000>;
-};
-
-&gmac0_rmii_refin {
- clock-frequency = <50000000>;
-};
-
-&gmac1_rgmii_rxin {
- clock-frequency = <125000000>;
-};
-
-&gmac1_rmii_refin {
- clock-frequency = <50000000>;
-};
-
-&hdmitx0_pixelclk {
- clock-frequency = <297000000>;
-};
-
-&i2srx_bclk_ext {
- clock-frequency = <12288000>;
-};
-
-&i2srx_lrck_ext {
- clock-frequency = <192000>;
-};
-
-&i2stx_bclk_ext {
- clock-frequency = <12288000>;
-};
-
-&i2stx_lrck_ext {
- clock-frequency = <192000>;
-};
-
-&mclk_ext {
- clock-frequency = <12288000>;
-};
-
-&osc {
- clock-frequency = <24000000>;
-};
-
-&rtc_osc {
- clock-frequency = <32768>;
-};
-
-&tdm_ext {
- clock-frequency = <49152000>;
-};
-
-&camss {
- assigned-clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
- <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>;
- assigned-clock-rates = <49500000>, <198000000>;
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- };
-
- port@1 {
- reg = <1>;
-
- camss_from_csi2rx: endpoint {
- remote-endpoint = <&csi2rx_to_camss>;
- };
- };
- };
-};
-
-&csi2rx {
- assigned-clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>;
- assigned-clock-rates = <297000000>;
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- /* remote MIPI sensor endpoint */
- };
-
- port@1 {
- reg = <1>;
-
- csi2rx_to_camss: endpoint {
- remote-endpoint = <&camss_from_csi2rx>;
- };
- };
- };
-};
-
-&gmac0 {
- phy-handle = <&phy0>;
- phy-mode = "rgmii-id";
- status = "okay";
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "snps,dwmac-mdio";
-
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
};
};
@@ -206,510 +29,14 @@
};
};
-&i2c0 {
- clock-frequency = <100000>;
- i2c-sda-hold-time-ns = <300>;
- i2c-sda-falling-time-ns = <510>;
- i2c-scl-falling-time-ns = <510>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
-};
-
-&i2c2 {
- clock-frequency = <100000>;
- i2c-sda-hold-time-ns = <300>;
- i2c-sda-falling-time-ns = <510>;
- i2c-scl-falling-time-ns = <510>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_pins>;
- status = "okay";
-};
-
-&i2c5 {
- clock-frequency = <100000>;
- i2c-sda-hold-time-ns = <300>;
- i2c-sda-falling-time-ns = <510>;
- i2c-scl-falling-time-ns = <510>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c5_pins>;
- status = "okay";
-
- axp15060: pmic@36 {
- compatible = "x-powers,axp15060";
- reg = <0x36>;
- interrupts = <0>;
- interrupt-controller;
- #interrupt-cells = <1>;
-
- regulators {
- vcc_3v3: dcdc1 {
- regulator-boot-on;
- regulator-always-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-name = "vcc_3v3";
- };
-
- vdd_cpu: dcdc2 {
- regulator-always-on;
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1540000>;
- regulator-name = "vdd-cpu";
- };
-
- emmc_vdd: aldo4 {
- regulator-boot-on;
- regulator-always-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-name = "emmc_vdd";
- };
- };
- };
-};
-
-&i2c6 {
- clock-frequency = <100000>;
- i2c-sda-hold-time-ns = <300>;
- i2c-sda-falling-time-ns = <510>;
- i2c-scl-falling-time-ns = <510>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c6_pins>;
- status = "okay";
-};
-
-&i2srx {
- pinctrl-names = "default";
- pinctrl-0 = <&i2srx_pins>;
- status = "okay";
-};
-
-&i2stx0 {
- pinctrl-names = "default";
- pinctrl-0 = <&mclk_ext_pins>;
- status = "okay";
-};
-
-&i2stx1 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2stx1_pins>;
- status = "okay";
-};
-
&mmc0 {
- max-frequency = <100000000>;
- assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
- assigned-clock-rates = <50000000>;
- bus-width = <8>;
- cap-mmc-highspeed;
- mmc-ddr-1_8v;
- mmc-hs200-1_8v;
non-removable;
- cap-mmc-hw-reset;
- post-power-on-delay-ms = <200>;
- pinctrl-names = "default";
- pinctrl-0 = <&mmc0_pins>;
- vmmc-supply = <&vcc_3v3>;
- vqmmc-supply = <&emmc_vdd>;
- status = "okay";
-};
-
-&mmc1 {
- max-frequency = <100000000>;
- assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
- assigned-clock-rates = <50000000>;
- bus-width = <4>;
- no-sdio;
- no-mmc;
- broken-cd;
- cap-sd-highspeed;
- post-power-on-delay-ms = <200>;
- pinctrl-names = "default";
- pinctrl-0 = <&mmc1_pins>;
- status = "okay";
-};
-
-&pwmdac {
- pinctrl-names = "default";
- pinctrl-0 = <&pwmdac_pins>;
- status = "okay";
-};
-
-&qspi {
- #address-cells = <1>;
- #size-cells = <0>;
- status = "okay";
-
- nor_flash: flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- cdns,read-delay = <5>;
- spi-max-frequency = <12000000>;
- cdns,tshsl-ns = <1>;
- cdns,tsd2d-ns = <1>;
- cdns,tchsh-ns = <1>;
- cdns,tslch-ns = <1>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- spl@0 {
- reg = <0x0 0x80000>;
- };
- uboot-env@f0000 {
- reg = <0xf0000 0x10000>;
- };
- uboot@100000 {
- reg = <0x100000 0x400000>;
- };
- reserved-data@600000 {
- reg = <0x600000 0xa00000>;
- };
- };
- };
-};
-
-&pwm {
- pinctrl-names = "default";
- pinctrl-0 = <&pwm_pins>;
- status = "okay";
-};
-
-&spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_pins>;
- status = "okay";
-
- spi_dev0: spi@0 {
- compatible = "rohm,dh2228fv";
- reg = <0>;
- spi-max-frequency = <10000000>;
- };
-};
-
-&sysgpio {
- i2c0_pins: i2c0-0 {
- i2c-pins {
- pinmux = <GPIOMUX(57, GPOUT_LOW,
- GPOEN_SYS_I2C0_CLK,
- GPI_SYS_I2C0_CLK)>,
- <GPIOMUX(58, GPOUT_LOW,
- GPOEN_SYS_I2C0_DATA,
- GPI_SYS_I2C0_DATA)>;
- bias-disable; /* external pull-up */
- input-enable;
- input-schmitt-enable;
- };
- };
-
- i2c2_pins: i2c2-0 {
- i2c-pins {
- pinmux = <GPIOMUX(3, GPOUT_LOW,
- GPOEN_SYS_I2C2_CLK,
- GPI_SYS_I2C2_CLK)>,
- <GPIOMUX(2, GPOUT_LOW,
- GPOEN_SYS_I2C2_DATA,
- GPI_SYS_I2C2_DATA)>;
- bias-disable; /* external pull-up */
- input-enable;
- input-schmitt-enable;
- };
- };
-
- i2c5_pins: i2c5-0 {
- i2c-pins {
- pinmux = <GPIOMUX(19, GPOUT_LOW,
- GPOEN_SYS_I2C5_CLK,
- GPI_SYS_I2C5_CLK)>,
- <GPIOMUX(20, GPOUT_LOW,
- GPOEN_SYS_I2C5_DATA,
- GPI_SYS_I2C5_DATA)>;
- bias-disable; /* external pull-up */
- input-enable;
- input-schmitt-enable;
- };
- };
-
- i2c6_pins: i2c6-0 {
- i2c-pins {
- pinmux = <GPIOMUX(16, GPOUT_LOW,
- GPOEN_SYS_I2C6_CLK,
- GPI_SYS_I2C6_CLK)>,
- <GPIOMUX(17, GPOUT_LOW,
- GPOEN_SYS_I2C6_DATA,
- GPI_SYS_I2C6_DATA)>;
- bias-disable; /* external pull-up */
- input-enable;
- input-schmitt-enable;
- };
- };
-
- i2srx_pins: i2srx-0 {
- clk-sd-pins {
- pinmux = <GPIOMUX(38, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_I2SRX_BCLK)>,
- <GPIOMUX(63, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_I2SRX_LRCK)>,
- <GPIOMUX(38, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_I2STX1_BCLK)>,
- <GPIOMUX(63, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_I2STX1_LRCK)>,
- <GPIOMUX(61, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_I2SRX_SDIN0)>;
- input-enable;
- };
- };
-
- i2stx1_pins: i2stx1-0 {
- sd-pins {
- pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-disable;
- input-disable;
- };
- };
-
- mclk_ext_pins: mclk-ext-0 {
- mclk-ext-pins {
- pinmux = <GPIOMUX(4, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_MCLK_EXT)>;
- input-enable;
- };
- };
-
- mmc0_pins: mmc0-0 {
- rst-pins {
- pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-pull-up;
- drive-strength = <12>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
-
- mmc-pins {
- pinmux = <PINMUX(64, 0)>,
- <PINMUX(65, 0)>,
- <PINMUX(66, 0)>,
- <PINMUX(67, 0)>,
- <PINMUX(68, 0)>,
- <PINMUX(69, 0)>,
- <PINMUX(70, 0)>,
- <PINMUX(71, 0)>,
- <PINMUX(72, 0)>,
- <PINMUX(73, 0)>;
- bias-pull-up;
- drive-strength = <12>;
- input-enable;
- };
- };
-
- mmc1_pins: mmc1-0 {
- clk-pins {
- pinmux = <GPIOMUX(10, GPOUT_SYS_SDIO1_CLK,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-pull-up;
- drive-strength = <12>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
-
- mmc-pins {
- pinmux = <GPIOMUX(9, GPOUT_SYS_SDIO1_CMD,
- GPOEN_SYS_SDIO1_CMD,
- GPI_SYS_SDIO1_CMD)>,
- <GPIOMUX(11, GPOUT_SYS_SDIO1_DATA0,
- GPOEN_SYS_SDIO1_DATA0,
- GPI_SYS_SDIO1_DATA0)>,
- <GPIOMUX(12, GPOUT_SYS_SDIO1_DATA1,
- GPOEN_SYS_SDIO1_DATA1,
- GPI_SYS_SDIO1_DATA1)>,
- <GPIOMUX(7, GPOUT_SYS_SDIO1_DATA2,
- GPOEN_SYS_SDIO1_DATA2,
- GPI_SYS_SDIO1_DATA2)>,
- <GPIOMUX(8, GPOUT_SYS_SDIO1_DATA3,
- GPOEN_SYS_SDIO1_DATA3,
- GPI_SYS_SDIO1_DATA3)>;
- bias-pull-up;
- drive-strength = <12>;
- input-enable;
- input-schmitt-enable;
- slew-rate = <0>;
- };
- };
-
- pwmdac_pins: pwmdac-0 {
- pwmdac-pins {
- pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
- GPOEN_ENABLE,
- GPI_NONE)>,
- <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-disable;
- drive-strength = <2>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
- };
-
- pwm_pins: pwm-0 {
- pwm-pins {
- pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
- GPOEN_SYS_PWM0_CHANNEL0,
- GPI_NONE)>,
- <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
- GPOEN_SYS_PWM0_CHANNEL1,
- GPI_NONE)>;
- bias-disable;
- drive-strength = <12>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
- };
-
- spi0_pins: spi0-0 {
- mosi-pins {
- pinmux = <GPIOMUX(52, GPOUT_SYS_SPI0_TXD,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-disable;
- input-disable;
- input-schmitt-disable;
- };
-
- miso-pins {
- pinmux = <GPIOMUX(53, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_SPI0_RXD)>;
- bias-pull-up;
- input-enable;
- input-schmitt-enable;
- };
-
- sck-pins {
- pinmux = <GPIOMUX(48, GPOUT_SYS_SPI0_CLK,
- GPOEN_ENABLE,
- GPI_SYS_SPI0_CLK)>;
- bias-disable;
- input-disable;
- input-schmitt-disable;
- };
-
- ss-pins {
- pinmux = <GPIOMUX(49, GPOUT_SYS_SPI0_FSS,
- GPOEN_ENABLE,
- GPI_SYS_SPI0_FSS)>;
- bias-disable;
- input-disable;
- input-schmitt-disable;
- };
- };
-
- tdm_pins: tdm-0 {
- tx-pins {
- pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-pull-up;
- drive-strength = <2>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
-
- rx-pins {
- pinmux = <GPIOMUX(61, GPOUT_HIGH,
- GPOEN_DISABLE,
- GPI_SYS_TDM_RXD)>;
- input-enable;
- };
-
- sync-pins {
- pinmux = <GPIOMUX(63, GPOUT_HIGH,
- GPOEN_DISABLE,
- GPI_SYS_TDM_SYNC)>;
- input-enable;
- };
-
- pcmclk-pins {
- pinmux = <GPIOMUX(38, GPOUT_HIGH,
- GPOEN_DISABLE,
- GPI_SYS_TDM_CLK)>;
- input-enable;
- };
- };
-
- uart0_pins: uart0-0 {
- tx-pins {
- pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-disable;
- drive-strength = <12>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
-
- rx-pins {
- pinmux = <GPIOMUX(6, GPOUT_LOW,
- GPOEN_DISABLE,
- GPI_SYS_UART0_RX)>;
- bias-disable; /* external pull-up */
- drive-strength = <2>;
- input-enable;
- input-schmitt-enable;
- slew-rate = <0>;
- };
- };
};
-&tdm {
- pinctrl-names = "default";
- pinctrl-0 = <&tdm_pins>;
+&pcie0 {
status = "okay";
};
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
+&pcie1 {
status = "okay";
};
-
-&usb0 {
- dr_mode = "peripheral";
- status = "okay";
-};
-
-&U74_1 {
- cpu-supply = <&vdd_cpu>;
-};
-
-&U74_2 {
- cpu-supply = <&vdd_cpu>;
-};
-
-&U74_3 {
- cpu-supply = <&vdd_cpu>;
-};
-
-&U74_4 {
- cpu-supply = <&vdd_cpu>;
-};
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index 4a5708f7fcf7..0d8339357bad 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -15,7 +15,7 @@
#address-cells = <2>;
#size-cells = <2>;
- cpus {
+ cpus: cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -387,12 +387,13 @@
};
uart0: serial@10000000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "starfive,jh7110-uart", "snps,dw-apb-uart";
reg = <0x0 0x10000000 0x0 0x10000>;
clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
<&syscrg JH7110_SYSCLK_UART0_APB>;
clock-names = "baudclk", "apb_pclk";
- resets = <&syscrg JH7110_SYSRST_UART0_APB>;
+ resets = <&syscrg JH7110_SYSRST_UART0_APB>,
+ <&syscrg JH7110_SYSRST_UART0_CORE>;
interrupts = <32>;
reg-io-width = <4>;
reg-shift = <2>;
@@ -400,12 +401,13 @@
};
uart1: serial@10010000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "starfive,jh7110-uart", "snps,dw-apb-uart";
reg = <0x0 0x10010000 0x0 0x10000>;
clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
<&syscrg JH7110_SYSCLK_UART1_APB>;
clock-names = "baudclk", "apb_pclk";
- resets = <&syscrg JH7110_SYSRST_UART1_APB>;
+ resets = <&syscrg JH7110_SYSRST_UART1_APB>,
+ <&syscrg JH7110_SYSRST_UART1_CORE>;
interrupts = <33>;
reg-io-width = <4>;
reg-shift = <2>;
@@ -413,12 +415,13 @@
};
uart2: serial@10020000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "starfive,jh7110-uart", "snps,dw-apb-uart";
reg = <0x0 0x10020000 0x0 0x10000>;
clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
<&syscrg JH7110_SYSCLK_UART2_APB>;
clock-names = "baudclk", "apb_pclk";
- resets = <&syscrg JH7110_SYSRST_UART2_APB>;
+ resets = <&syscrg JH7110_SYSRST_UART2_APB>,
+ <&syscrg JH7110_SYSRST_UART2_CORE>;
interrupts = <34>;
reg-io-width = <4>;
reg-shift = <2>;
@@ -642,12 +645,13 @@
};
uart3: serial@12000000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "starfive,jh7110-uart", "snps,dw-apb-uart";
reg = <0x0 0x12000000 0x0 0x10000>;
clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
<&syscrg JH7110_SYSCLK_UART3_APB>;
clock-names = "baudclk", "apb_pclk";
- resets = <&syscrg JH7110_SYSRST_UART3_APB>;
+ resets = <&syscrg JH7110_SYSRST_UART3_APB>,
+ <&syscrg JH7110_SYSRST_UART3_CORE>;
interrupts = <45>;
reg-io-width = <4>;
reg-shift = <2>;
@@ -655,12 +659,13 @@
};
uart4: serial@12010000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "starfive,jh7110-uart", "snps,dw-apb-uart";
reg = <0x0 0x12010000 0x0 0x10000>;
clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
<&syscrg JH7110_SYSCLK_UART4_APB>;
clock-names = "baudclk", "apb_pclk";
- resets = <&syscrg JH7110_SYSRST_UART4_APB>;
+ resets = <&syscrg JH7110_SYSRST_UART4_APB>,
+ <&syscrg JH7110_SYSRST_UART4_CORE>;
interrupts = <46>;
reg-io-width = <4>;
reg-shift = <2>;
@@ -668,12 +673,13 @@
};
uart5: serial@12020000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "starfive,jh7110-uart", "snps,dw-apb-uart";
reg = <0x0 0x12020000 0x0 0x10000>;
clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
<&syscrg JH7110_SYSCLK_UART5_APB>;
clock-names = "baudclk", "apb_pclk";
- resets = <&syscrg JH7110_SYSRST_UART5_APB>;
+ resets = <&syscrg JH7110_SYSRST_UART5_APB>,
+ <&syscrg JH7110_SYSRST_UART5_CORE>;
interrupts = <47>;
reg-io-width = <4>;
reg-shift = <2>;
@@ -1214,5 +1220,91 @@
#reset-cells = <1>;
power-domains = <&pwrc JH7110_PD_VOUT>;
};
+
+ pcie0: pcie@940000000 {
+ compatible = "starfive,jh7110-pcie";
+ reg = <0x9 0x40000000 0x0 0x1000000>,
+ <0x0 0x2b000000 0x0 0x100000>;
+ reg-names = "cfg", "apb";
+ linux,pci-domain = <0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
+ interrupts = <56>;
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
+ msi-controller;
+ device_type = "pci";
+ starfive,stg-syscon = <&stg_syscon>;
+ bus-range = <0x0 0xff>;
+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
+ <&stgcrg JH7110_STGCLK_PCIE0_TL>,
+ <&stgcrg JH7110_STGCLK_PCIE0_AXI_MST0>,
+ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
+ clock-names = "noc", "tl", "axi_mst0", "apb";
+ resets = <&stgcrg JH7110_STGRST_PCIE0_AXI_MST0>,
+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV0>,
+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV>,
+ <&stgcrg JH7110_STGRST_PCIE0_BRG>,
+ <&stgcrg JH7110_STGRST_PCIE0_CORE>,
+ <&stgcrg JH7110_STGRST_PCIE0_APB>;
+ reset-names = "mst0", "slv0", "slv", "brg",
+ "core", "apb";
+ status = "disabled";
+
+ pcie_intc0: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ pcie1: pcie@9c0000000 {
+ compatible = "starfive,jh7110-pcie";
+ reg = <0x9 0xc0000000 0x0 0x1000000>,
+ <0x0 0x2c000000 0x0 0x100000>;
+ reg-names = "cfg", "apb";
+ linux,pci-domain = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
+ <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
+ interrupts = <57>;
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc1 0x1>,
+ <0x0 0x0 0x0 0x2 &pcie_intc1 0x2>,
+ <0x0 0x0 0x0 0x3 &pcie_intc1 0x3>,
+ <0x0 0x0 0x0 0x4 &pcie_intc1 0x4>;
+ msi-controller;
+ device_type = "pci";
+ starfive,stg-syscon = <&stg_syscon>;
+ bus-range = <0x0 0xff>;
+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
+ <&stgcrg JH7110_STGCLK_PCIE1_TL>,
+ <&stgcrg JH7110_STGCLK_PCIE1_AXI_MST0>,
+ <&stgcrg JH7110_STGCLK_PCIE1_APB>;
+ clock-names = "noc", "tl", "axi_mst0", "apb";
+ resets = <&stgcrg JH7110_STGRST_PCIE1_AXI_MST0>,
+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV0>,
+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV>,
+ <&stgcrg JH7110_STGRST_PCIE1_BRG>,
+ <&stgcrg JH7110_STGRST_PCIE1_CORE>,
+ <&stgcrg JH7110_STGRST_PCIE1_APB>;
+ reset-names = "mst0", "slv0", "slv", "brg",
+ "core", "apb";
+ status = "disabled";
+
+ pcie_intc1: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
};
};
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index 8b915e206f3a..3c9974062c20 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -122,6 +122,87 @@
};
};
+ pmu {
+ compatible = "riscv,pmu";
+ riscv,event-to-mhpmcounters =
+ <0x00003 0x00003 0x0007fff8>,
+ <0x00004 0x00004 0x0007fff8>,
+ <0x00005 0x00005 0x0007fff8>,
+ <0x00006 0x00006 0x0007fff8>,
+ <0x00007 0x00007 0x0007fff8>,
+ <0x00008 0x00008 0x0007fff8>,
+ <0x00009 0x00009 0x0007fff8>,
+ <0x0000a 0x0000a 0x0007fff8>,
+ <0x10000 0x10000 0x0007fff8>,
+ <0x10001 0x10001 0x0007fff8>,
+ <0x10002 0x10002 0x0007fff8>,
+ <0x10003 0x10003 0x0007fff8>,
+ <0x10010 0x10010 0x0007fff8>,
+ <0x10011 0x10011 0x0007fff8>,
+ <0x10012 0x10012 0x0007fff8>,
+ <0x10013 0x10013 0x0007fff8>;
+ riscv,event-to-mhpmevent =
+ <0x00003 0x00000000 0x00000001>,
+ <0x00004 0x00000000 0x00000002>,
+ <0x00006 0x00000000 0x00000006>,
+ <0x00005 0x00000000 0x00000007>,
+ <0x00007 0x00000000 0x00000008>,
+ <0x00008 0x00000000 0x00000009>,
+ <0x00009 0x00000000 0x0000000a>,
+ <0x0000a 0x00000000 0x0000000b>,
+ <0x10000 0x00000000 0x0000000c>,
+ <0x10001 0x00000000 0x0000000d>,
+ <0x10002 0x00000000 0x0000000e>,
+ <0x10003 0x00000000 0x0000000f>,
+ <0x10010 0x00000000 0x00000010>,
+ <0x10011 0x00000000 0x00000011>,
+ <0x10012 0x00000000 0x00000012>,
+ <0x10013 0x00000000 0x00000013>;
+ riscv,raw-event-to-mhpmcounters =
+ <0x00000000 0x00000001 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000002 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000003 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000004 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000005 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000006 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000007 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000008 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000009 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000000a 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000000b 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000000c 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000000d 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000000e 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000000f 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000010 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000011 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000012 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000013 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000014 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000015 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000016 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000017 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000018 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000019 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000001a 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000001b 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000001c 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000001d 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000001e 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000001f 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000020 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000021 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000022 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000023 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000024 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000025 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000026 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000027 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000028 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x00000029 0xffffffff 0xffffffff 0x0007fff8>,
+ <0x00000000 0x0000002a 0xffffffff 0xffffffff 0x0007fff8>;
+ };
+
osc: oscillator {
compatible = "fixed-clock";
clock-output-names = "osc_24m";
@@ -193,6 +274,33 @@
status = "disabled";
};
+ emmc: mmc@ffe7080000 {
+ compatible = "thead,th1520-dwcmshc";
+ reg = <0xff 0xe7080000 0x0 0x10000>;
+ interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sdhci_clk>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
+ sdio0: mmc@ffe7090000 {
+ compatible = "thead,th1520-dwcmshc";
+ reg = <0xff 0xe7090000 0x0 0x10000>;
+ interrupts = <64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sdhci_clk>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
+ sdio1: mmc@ffe70a0000 {
+ compatible = "thead,th1520-dwcmshc";
+ reg = <0xff 0xe70a0000 0x0 0x10000>;
+ interrupts = <71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sdhci_clk>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
uart1: serial@ffe7f00000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7f00000 0x0 0x100>;
@@ -311,33 +419,6 @@
status = "disabled";
};
- emmc: mmc@ffe7080000 {
- compatible = "thead,th1520-dwcmshc";
- reg = <0xff 0xe7080000 0x0 0x10000>;
- interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
- clock-names = "core";
- status = "disabled";
- };
-
- sdio0: mmc@ffe7090000 {
- compatible = "thead,th1520-dwcmshc";
- reg = <0xff 0xe7090000 0x0 0x10000>;
- interrupts = <64 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
- clock-names = "core";
- status = "disabled";
- };
-
- sdio1: mmc@ffe70a0000 {
- compatible = "thead,th1520-dwcmshc";
- reg = <0xff 0xe70a0000 0x0 0x10000>;
- interrupts = <71 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
- clock-names = "core";
- status = "disabled";
- };
-
timer0: timer@ffefc32000 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32000 0x0 0x14>;
diff --git a/arch/riscv/boot/install.sh b/arch/riscv/boot/install.sh
index 4c63f3f0643d..4b3d8bf91cc6 100755
--- a/arch/riscv/boot/install.sh
+++ b/arch/riscv/boot/install.sh
@@ -17,15 +17,20 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
-if [ "$(basename $2)" = "Image.gz" ]; then
+set -e
+
+case "${2##*/}" in
# Compressed install
+Image.*|vmlinuz.efi)
echo "Installing compressed kernel"
base=vmlinuz
-else
+ ;;
# Normal install
+*)
echo "Installing normal kernel"
base=vmlinux
-fi
+ ;;
+esac
if [ -f $4/$base-$1 ]; then
mv $4/$base-$1 $4/$base-$1.old
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index fc0ec2ee13bc..3f1f055866af 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -25,14 +25,15 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_PROFILING=y
-CONFIG_SOC_MICROCHIP_POLARFIRE=y
+CONFIG_ARCH_MICROCHIP=y
CONFIG_ARCH_RENESAS=y
-CONFIG_SOC_SIFIVE=y
+CONFIG_ARCH_SIFIVE=y
CONFIG_ARCH_SOPHGO=y
CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_THEAD=y
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
+CONFIG_ARCH_CANAAN=y
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
CONFIG_PM=y
@@ -109,8 +110,10 @@ CONFIG_PCIEPORTBUS=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCIE_XILINX=y
CONFIG_PCIE_FU740=y
+CONFIG_PCIE_STARFIVE_HOST=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_SIFIVE_CCACHE=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
@@ -142,6 +145,7 @@ CONFIG_RAVB=y
CONFIG_STMMAC_ETH=m
CONFIG_MICREL_PHY=y
CONFIG_MICROSEMI_PHY=y
+CONFIG_MOTORCOMM_PHY=y
CONFIG_CAN_RCAR_CANFD=m
CONFIG_INPUT_MOUSEDEV=y
CONFIG_KEYBOARD_SUN4I_LRADC=m
@@ -154,24 +158,35 @@ CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_VIRTIO=y
+CONFIG_HW_RANDOM_JH7110=m
+CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_MV64XXX=m
CONFIG_I2C_RIIC=y
CONFIG_SPI=y
+CONFIG_SPI_CADENCE_QUADSPI=m
+CONFIG_SPI_PL022=m
CONFIG_SPI_RSPI=m
CONFIG_SPI_SIFIVE=y
CONFIG_SPI_SUN6I=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_GPIO_SIFIVE=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_SENSORS_SFCTEMP=m
CONFIG_CPU_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_RZG2L_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=y
CONFIG_RENESAS_RZG2LWDT=y
+CONFIG_MFD_AXP20X_I2C=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_GPIO=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_VIDEO_CADENCE_CSI2RX=m
CONFIG_DRM=m
CONFIG_DRM_RADEON=m
CONFIG_DRM_NOUVEAU=m
@@ -183,6 +198,10 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_RZ=m
+CONFIG_SND_DESIGNWARE_I2S=m
+CONFIG_SND_SOC_STARFIVE=m
+CONFIG_SND_SOC_JH7110_PWMDAC=m
+CONFIG_SND_SOC_JH7110_TDM=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_USB=y
@@ -196,6 +215,11 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_RENESAS_USBHS=m
CONFIG_USB_STORAGE=y
CONFIG_USB_UAS=y
+CONFIG_USB_CDNS_SUPPORT=m
+CONFIG_USB_CDNS3=m
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
+CONFIG_USB_CDNS3_STARFIVE=m
CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_SUNXI=m
CONFIG_NOP_USB_XCEIV=m
@@ -233,6 +257,7 @@ CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_RENESAS_OSTM=y
+CONFIG_CLK_SOPHGO_CV1800=y
CONFIG_SUN8I_DE2_CCU=m
CONFIG_SUN50I_IOMMU=y
CONFIG_RPMSG_CHAR=y
@@ -244,6 +269,9 @@ CONFIG_RZG2L_ADC=m
CONFIG_RESET_RZG2L_USBPHY_CTRL=y
CONFIG_PHY_SUN4I_USB=m
CONFIG_PHY_RCAR_GEN3_USB2=y
+CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=m
+CONFIG_PHY_STARFIVE_JH7110_PCIE=m
+CONFIG_PHY_STARFIVE_JH7110_USB=m
CONFIG_LIBNVDIMM=y
CONFIG_NVMEM_SUNXI_SID=y
CONFIG_EXT4_FS=y
diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig
index 7e75200543f4..af9601da4643 100644
--- a/arch/riscv/configs/nommu_k210_defconfig
+++ b/arch/riscv/configs/nommu_k210_defconfig
@@ -11,7 +11,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_SYSFS_SYSCALL is not set
# CONFIG_FHANDLE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
@@ -27,7 +27,8 @@ CONFIG_EXPERT=y
CONFIG_SLUB=y
CONFIG_SLUB_TINY=y
# CONFIG_MMU is not set
-CONFIG_SOC_CANAAN=y
+CONFIG_ARCH_CANAAN=y
+CONFIG_SOC_CANAAN_K210=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
diff --git a/arch/riscv/configs/nommu_k210_sdcard_defconfig b/arch/riscv/configs/nommu_k210_sdcard_defconfig
index 0ba353e9ca71..dd460c649152 100644
--- a/arch/riscv/configs/nommu_k210_sdcard_defconfig
+++ b/arch/riscv/configs/nommu_k210_sdcard_defconfig
@@ -3,7 +3,7 @@ CONFIG_LOG_BUF_SHIFT=13
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_SYSFS_SYSCALL is not set
# CONFIG_FHANDLE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
@@ -19,7 +19,8 @@ CONFIG_EXPERT=y
CONFIG_SLUB=y
CONFIG_SLUB_TINY=y
# CONFIG_MMU is not set
-CONFIG_SOC_CANAAN=y
+CONFIG_ARCH_CANAAN=y
+CONFIG_SOC_CANAAN_K210=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
diff --git a/arch/riscv/configs/nommu_virt_defconfig b/arch/riscv/configs/nommu_virt_defconfig
index b794e2f8144e..d4b03dc3c2c0 100644
--- a/arch/riscv/configs/nommu_virt_defconfig
+++ b/arch/riscv/configs/nommu_virt_defconfig
@@ -10,7 +10,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
# CONFIG_FHANDLE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
# CONFIG_TIMERFD is not set
@@ -24,7 +24,7 @@ CONFIG_EXPERT=y
CONFIG_SLUB=y
CONFIG_SLUB_TINY=y
# CONFIG_MMU is not set
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y
CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c
index 3d9a32d791f7..716cfedad3a2 100644
--- a/arch/riscv/errata/sifive/errata.c
+++ b/arch/riscv/errata/sifive/errata.c
@@ -42,6 +42,11 @@ static bool errata_cip_1200_check_func(unsigned long arch_id, unsigned long imp
return false;
if ((impid & 0xffffff) > 0x200630 || impid == 0x1200626)
return false;
+
+#ifdef CONFIG_MMU
+ tlb_flush_all_threshold = 0;
+#endif
+
return true;
}
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 504f8b7e72d4..5c589770f2a8 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -1,4 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
+syscall-y += syscall_table_64.h
+
generic-y += early_ioremap.h
generic-y += flat.h
generic-y += kvm_para.h
diff --git a/arch/riscv/include/asm/arch_hweight.h b/arch/riscv/include/asm/arch_hweight.h
index 85b2c443823e..613769b9cdc9 100644
--- a/arch/riscv/include/asm/arch_hweight.h
+++ b/arch/riscv/include/asm/arch_hweight.h
@@ -26,9 +26,9 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w)
asm (".option push\n"
".option arch,+zbb\n"
- CPOPW "%0, %0\n"
+ CPOPW "%0, %1\n"
".option pop\n"
- : "+r" (w) : :);
+ : "=r" (w) : "r" (w) :);
return w;
@@ -57,9 +57,9 @@ static __always_inline unsigned long __arch_hweight64(__u64 w)
asm (".option push\n"
".option arch,+zbb\n"
- "cpop %0, %0\n"
+ "cpop %0, %1\n"
".option pop\n"
- : "+r" (w) : :);
+ : "=r" (w) : "r" (w) :);
return w;
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 0e0522e588ca..5b96c2f61adb 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -195,22 +195,28 @@ ATOMIC_OPS(xor, xor, i)
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
+#define _arch_atomic_fetch_add_unless(_prev, _rc, counter, _a, _u, sfx) \
+({ \
+ __asm__ __volatile__ ( \
+ "0: lr." sfx " %[p], %[c]\n" \
+ " beq %[p], %[u], 1f\n" \
+ " add %[rc], %[p], %[a]\n" \
+ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \
+ " bnez %[rc], 0b\n" \
+ " fence rw, rw\n" \
+ "1:\n" \
+ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
+ : [a]"r" (_a), [u]"r" (_u) \
+ : "memory"); \
+})
+
/* This is required to provide a full barrier on success. */
static __always_inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
{
int prev, rc;
- __asm__ __volatile__ (
- "0: lr.w %[p], %[c]\n"
- " beq %[p], %[u], 1f\n"
- " add %[rc], %[p], %[a]\n"
- " sc.w.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- : [a]"r" (a), [u]"r" (u)
- : "memory");
+ _arch_atomic_fetch_add_unless(prev, rc, v->counter, a, u, "w");
+
return prev;
}
#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless
@@ -221,77 +227,86 @@ static __always_inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a,
s64 prev;
long rc;
- __asm__ __volatile__ (
- "0: lr.d %[p], %[c]\n"
- " beq %[p], %[u], 1f\n"
- " add %[rc], %[p], %[a]\n"
- " sc.d.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- : [a]"r" (a), [u]"r" (u)
- : "memory");
+ _arch_atomic_fetch_add_unless(prev, rc, v->counter, a, u, "d");
+
return prev;
}
#define arch_atomic64_fetch_add_unless arch_atomic64_fetch_add_unless
#endif
+#define _arch_atomic_inc_unless_negative(_prev, _rc, counter, sfx) \
+({ \
+ __asm__ __volatile__ ( \
+ "0: lr." sfx " %[p], %[c]\n" \
+ " bltz %[p], 1f\n" \
+ " addi %[rc], %[p], 1\n" \
+ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \
+ " bnez %[rc], 0b\n" \
+ " fence rw, rw\n" \
+ "1:\n" \
+ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
+ : \
+ : "memory"); \
+})
+
static __always_inline bool arch_atomic_inc_unless_negative(atomic_t *v)
{
int prev, rc;
- __asm__ __volatile__ (
- "0: lr.w %[p], %[c]\n"
- " bltz %[p], 1f\n"
- " addi %[rc], %[p], 1\n"
- " sc.w.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- :
- : "memory");
+ _arch_atomic_inc_unless_negative(prev, rc, v->counter, "w");
+
return !(prev < 0);
}
#define arch_atomic_inc_unless_negative arch_atomic_inc_unless_negative
+#define _arch_atomic_dec_unless_positive(_prev, _rc, counter, sfx) \
+({ \
+ __asm__ __volatile__ ( \
+ "0: lr." sfx " %[p], %[c]\n" \
+ " bgtz %[p], 1f\n" \
+ " addi %[rc], %[p], -1\n" \
+ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \
+ " bnez %[rc], 0b\n" \
+ " fence rw, rw\n" \
+ "1:\n" \
+ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
+ : \
+ : "memory"); \
+})
+
static __always_inline bool arch_atomic_dec_unless_positive(atomic_t *v)
{
int prev, rc;
- __asm__ __volatile__ (
- "0: lr.w %[p], %[c]\n"
- " bgtz %[p], 1f\n"
- " addi %[rc], %[p], -1\n"
- " sc.w.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- :
- : "memory");
+ _arch_atomic_dec_unless_positive(prev, rc, v->counter, "w");
+
return !(prev > 0);
}
#define arch_atomic_dec_unless_positive arch_atomic_dec_unless_positive
+#define _arch_atomic_dec_if_positive(_prev, _rc, counter, sfx) \
+({ \
+ __asm__ __volatile__ ( \
+ "0: lr." sfx " %[p], %[c]\n" \
+ " addi %[rc], %[p], -1\n" \
+ " bltz %[rc], 1f\n" \
+ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \
+ " bnez %[rc], 0b\n" \
+ " fence rw, rw\n" \
+ "1:\n" \
+ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
+ : \
+ : "memory"); \
+})
+
static __always_inline int arch_atomic_dec_if_positive(atomic_t *v)
{
int prev, rc;
- __asm__ __volatile__ (
- "0: lr.w %[p], %[c]\n"
- " addi %[rc], %[p], -1\n"
- " bltz %[rc], 1f\n"
- " sc.w.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- :
- : "memory");
+ _arch_atomic_dec_if_positive(prev, rc, v->counter, "w");
+
return prev - 1;
}
@@ -303,17 +318,8 @@ static __always_inline bool arch_atomic64_inc_unless_negative(atomic64_t *v)
s64 prev;
long rc;
- __asm__ __volatile__ (
- "0: lr.d %[p], %[c]\n"
- " bltz %[p], 1f\n"
- " addi %[rc], %[p], 1\n"
- " sc.d.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- :
- : "memory");
+ _arch_atomic_inc_unless_negative(prev, rc, v->counter, "d");
+
return !(prev < 0);
}
@@ -324,17 +330,8 @@ static __always_inline bool arch_atomic64_dec_unless_positive(atomic64_t *v)
s64 prev;
long rc;
- __asm__ __volatile__ (
- "0: lr.d %[p], %[c]\n"
- " bgtz %[p], 1f\n"
- " addi %[rc], %[p], -1\n"
- " sc.d.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- :
- : "memory");
+ _arch_atomic_dec_unless_positive(prev, rc, v->counter, "d");
+
return !(prev > 0);
}
@@ -345,17 +342,8 @@ static __always_inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
s64 prev;
long rc;
- __asm__ __volatile__ (
- "0: lr.d %[p], %[c]\n"
- " addi %[rc], %[p], -1\n"
- " bltz %[rc], 1f\n"
- " sc.d.rl %[rc], %[rc], %[c]\n"
- " bnez %[rc], 0b\n"
- RISCV_FULL_BARRIER
- "1:\n"
- : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
- :
- : "memory");
+ _arch_atomic_dec_if_positive(prev, rc, v->counter, "d");
+
return prev - 1;
}
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
index 880b56d8480d..e1d9bf1deca6 100644
--- a/arch/riscv/include/asm/barrier.h
+++ b/arch/riscv/include/asm/barrier.h
@@ -11,6 +11,7 @@
#define _ASM_RISCV_BARRIER_H
#ifndef __ASSEMBLY__
+#include <asm/cmpxchg.h>
#include <asm/fence.h>
#define nop() __asm__ __volatile__ ("nop")
@@ -28,21 +29,6 @@
#define __smp_rmb() RISCV_FENCE(r, r)
#define __smp_wmb() RISCV_FENCE(w, w)
-#define __smp_store_release(p, v) \
-do { \
- compiletime_assert_atomic_type(*p); \
- RISCV_FENCE(rw, w); \
- WRITE_ONCE(*p, v); \
-} while (0)
-
-#define __smp_load_acquire(p) \
-({ \
- typeof(*p) ___p1 = READ_ONCE(*p); \
- compiletime_assert_atomic_type(*p); \
- RISCV_FENCE(r, rw); \
- ___p1; \
-})
-
/*
* This is a very specific barrier: it's currently only used in two places in
* the kernel, both in the scheduler. See include/linux/spinlock.h for the two
@@ -70,6 +56,35 @@ do { \
*/
#define smp_mb__after_spinlock() RISCV_FENCE(iorw, iorw)
+#define __smp_store_release(p, v) \
+do { \
+ compiletime_assert_atomic_type(*p); \
+ RISCV_FENCE(rw, w); \
+ WRITE_ONCE(*p, v); \
+} while (0)
+
+#define __smp_load_acquire(p) \
+({ \
+ typeof(*p) ___p1 = READ_ONCE(*p); \
+ compiletime_assert_atomic_type(*p); \
+ RISCV_FENCE(r, rw); \
+ ___p1; \
+})
+
+#ifdef CONFIG_RISCV_ISA_ZAWRS
+#define smp_cond_load_relaxed(ptr, cond_expr) ({ \
+ typeof(ptr) __PTR = (ptr); \
+ __unqual_scalar_typeof(*ptr) VAL; \
+ for (;;) { \
+ VAL = READ_ONCE(*__PTR); \
+ if (cond_expr) \
+ break; \
+ __cmpwait_relaxed(ptr, VAL); \
+ } \
+ (typeof(*ptr))VAL; \
+})
+#endif
+
#include <asm-generic/barrier.h>
#endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 880606b0469a..71af9ecfcfcb 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -170,7 +170,7 @@ legacy:
({ \
typeof(x) x_ = (x); \
__builtin_constant_p(x_) ? \
- (int)((x_ != 0) ? (32 - __builtin_clz(x_)) : 0) \
+ ((x_ != 0) ? (32 - __builtin_clz(x_)) : 0) \
: \
variable_fls(x_); \
})
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
index 2174fe7bac9a..570e9d8acad1 100644
--- a/arch/riscv/include/asm/cache.h
+++ b/arch/riscv/include/asm/cache.h
@@ -26,8 +26,8 @@
#ifndef __ASSEMBLY__
-#ifdef CONFIG_RISCV_DMA_NONCOHERENT
extern int dma_cache_alignment;
+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
#define dma_get_cache_alignment dma_get_cache_alignment
static inline int dma_get_cache_alignment(void)
{
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index a129dac4521d..ce79c558a4c8 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -13,6 +13,12 @@ static inline void local_flush_icache_all(void)
asm volatile ("fence.i" ::: "memory");
}
+static inline void local_flush_icache_range(unsigned long start,
+ unsigned long end)
+{
+ local_flush_icache_all();
+}
+
#define PG_dcache_clean PG_arch_1
static inline void flush_dcache_folio(struct folio *folio)
@@ -33,8 +39,11 @@ static inline void flush_dcache_page(struct page *page)
* so instead we just flush the whole thing.
*/
#define flush_icache_range(start, end) flush_icache_all()
-#define flush_icache_user_page(vma, pg, addr, len) \
- flush_icache_mm(vma->vm_mm, 0)
+#define flush_icache_user_page(vma, pg, addr, len) \
+do { \
+ if (vma->vm_flags & VM_EXEC) \
+ flush_icache_mm(vma->vm_mm, 0); \
+} while (0)
#ifdef CONFIG_64BIT
#define flush_cache_vmap(start, end) flush_tlb_kernel_range(start, end)
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 2fee65cc8443..ebbce134917c 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -8,142 +8,86 @@
#include <linux/bug.h>
+#include <asm/alternative-macros.h>
#include <asm/fence.h>
+#include <asm/hwcap.h>
+#include <asm/insn-def.h>
-#define __xchg_relaxed(ptr, new, size) \
+#define __arch_xchg_masked(sc_sfx, prepend, append, r, p, n) \
({ \
- __typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- switch (size) { \
- case 4: \
- __asm__ __volatile__ ( \
- " amoswap.w %0, %2, %1\n" \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
- break; \
- case 8: \
- __asm__ __volatile__ ( \
- " amoswap.d %0, %2, %1\n" \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
- __ret; \
+ u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3); \
+ ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE; \
+ ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0) \
+ << __s; \
+ ulong __newx = (ulong)(n) << __s; \
+ ulong __retx; \
+ ulong __rc; \
+ \
+ __asm__ __volatile__ ( \
+ prepend \
+ "0: lr.w %0, %2\n" \
+ " and %1, %0, %z4\n" \
+ " or %1, %1, %z3\n" \
+ " sc.w" sc_sfx " %1, %1, %2\n" \
+ " bnez %1, 0b\n" \
+ append \
+ : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b)) \
+ : "rJ" (__newx), "rJ" (~__mask) \
+ : "memory"); \
+ \
+ r = (__typeof__(*(p)))((__retx & __mask) >> __s); \
})
-#define arch_xchg_relaxed(ptr, x) \
+#define __arch_xchg(sfx, prepend, append, r, p, n) \
({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __xchg_relaxed((ptr), \
- _x_, sizeof(*(ptr))); \
+ __asm__ __volatile__ ( \
+ prepend \
+ " amoswap" sfx " %0, %2, %1\n" \
+ append \
+ : "=r" (r), "+A" (*(p)) \
+ : "r" (n) \
+ : "memory"); \
})
-#define __xchg_acquire(ptr, new, size) \
+#define _arch_xchg(ptr, new, sc_sfx, swap_sfx, prepend, \
+ sc_append, swap_append) \
({ \
__typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- switch (size) { \
+ __typeof__(*(__ptr)) __new = (new); \
+ __typeof__(*(__ptr)) __ret; \
+ \
+ switch (sizeof(*__ptr)) { \
+ case 1: \
+ case 2: \
+ __arch_xchg_masked(sc_sfx, prepend, sc_append, \
+ __ret, __ptr, __new); \
+ break; \
case 4: \
- __asm__ __volatile__ ( \
- " amoswap.w %0, %2, %1\n" \
- RISCV_ACQUIRE_BARRIER \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
+ __arch_xchg(".w" swap_sfx, prepend, swap_append, \
+ __ret, __ptr, __new); \
break; \
case 8: \
- __asm__ __volatile__ ( \
- " amoswap.d %0, %2, %1\n" \
- RISCV_ACQUIRE_BARRIER \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
+ __arch_xchg(".d" swap_sfx, prepend, swap_append, \
+ __ret, __ptr, __new); \
break; \
default: \
BUILD_BUG(); \
} \
- __ret; \
+ (__typeof__(*(__ptr)))__ret; \
})
-#define arch_xchg_acquire(ptr, x) \
-({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __xchg_acquire((ptr), \
- _x_, sizeof(*(ptr))); \
-})
+#define arch_xchg_relaxed(ptr, x) \
+ _arch_xchg(ptr, x, "", "", "", "", "")
-#define __xchg_release(ptr, new, size) \
-({ \
- __typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- switch (size) { \
- case 4: \
- __asm__ __volatile__ ( \
- RISCV_RELEASE_BARRIER \
- " amoswap.w %0, %2, %1\n" \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
- break; \
- case 8: \
- __asm__ __volatile__ ( \
- RISCV_RELEASE_BARRIER \
- " amoswap.d %0, %2, %1\n" \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
- __ret; \
-})
+#define arch_xchg_acquire(ptr, x) \
+ _arch_xchg(ptr, x, "", "", "", \
+ RISCV_ACQUIRE_BARRIER, RISCV_ACQUIRE_BARRIER)
#define arch_xchg_release(ptr, x) \
-({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __xchg_release((ptr), \
- _x_, sizeof(*(ptr))); \
-})
-
-#define __arch_xchg(ptr, new, size) \
-({ \
- __typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- switch (size) { \
- case 4: \
- __asm__ __volatile__ ( \
- " amoswap.w.aqrl %0, %2, %1\n" \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
- break; \
- case 8: \
- __asm__ __volatile__ ( \
- " amoswap.d.aqrl %0, %2, %1\n" \
- : "=r" (__ret), "+A" (*__ptr) \
- : "r" (__new) \
- : "memory"); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
- __ret; \
-})
+ _arch_xchg(ptr, x, "", "", RISCV_RELEASE_BARRIER, "", "")
#define arch_xchg(ptr, x) \
-({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __arch_xchg((ptr), _x_, sizeof(*(ptr))); \
-})
+ _arch_xchg(ptr, x, ".rl", ".aqrl", "", RISCV_FULL_BARRIER, "")
#define xchg32(ptr, x) \
({ \
@@ -162,190 +106,95 @@
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
-#define __cmpxchg_relaxed(ptr, old, new, size) \
-({ \
- __typeof__(ptr) __ptr = (ptr); \
- __typeof__(*(ptr)) __old = (old); \
- __typeof__(*(ptr)) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- register unsigned int __rc; \
- switch (size) { \
- case 4: \
- __asm__ __volatile__ ( \
- "0: lr.w %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.w %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" ((long)__old), "rJ" (__new) \
- : "memory"); \
- break; \
- case 8: \
- __asm__ __volatile__ ( \
- "0: lr.d %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.d %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" (__old), "rJ" (__new) \
- : "memory"); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
- __ret; \
-})
-#define arch_cmpxchg_relaxed(ptr, o, n) \
+#define __arch_cmpxchg_masked(sc_sfx, prepend, append, r, p, o, n) \
({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \
- _o_, _n_, sizeof(*(ptr))); \
+ u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3); \
+ ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE; \
+ ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0) \
+ << __s; \
+ ulong __newx = (ulong)(n) << __s; \
+ ulong __oldx = (ulong)(o) << __s; \
+ ulong __retx; \
+ ulong __rc; \
+ \
+ __asm__ __volatile__ ( \
+ prepend \
+ "0: lr.w %0, %2\n" \
+ " and %1, %0, %z5\n" \
+ " bne %1, %z3, 1f\n" \
+ " and %1, %0, %z6\n" \
+ " or %1, %1, %z4\n" \
+ " sc.w" sc_sfx " %1, %1, %2\n" \
+ " bnez %1, 0b\n" \
+ append \
+ "1:\n" \
+ : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b)) \
+ : "rJ" ((long)__oldx), "rJ" (__newx), \
+ "rJ" (__mask), "rJ" (~__mask) \
+ : "memory"); \
+ \
+ r = (__typeof__(*(p)))((__retx & __mask) >> __s); \
})
-#define __cmpxchg_acquire(ptr, old, new, size) \
+#define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \
({ \
- __typeof__(ptr) __ptr = (ptr); \
- __typeof__(*(ptr)) __old = (old); \
- __typeof__(*(ptr)) __new = (new); \
- __typeof__(*(ptr)) __ret; \
register unsigned int __rc; \
- switch (size) { \
- case 4: \
- __asm__ __volatile__ ( \
- "0: lr.w %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.w %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- RISCV_ACQUIRE_BARRIER \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" ((long)__old), "rJ" (__new) \
- : "memory"); \
- break; \
- case 8: \
- __asm__ __volatile__ ( \
- "0: lr.d %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.d %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- RISCV_ACQUIRE_BARRIER \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" (__old), "rJ" (__new) \
- : "memory"); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
- __ret; \
-})
-
-#define arch_cmpxchg_acquire(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \
- _o_, _n_, sizeof(*(ptr))); \
+ \
+ __asm__ __volatile__ ( \
+ prepend \
+ "0: lr" lr_sfx " %0, %2\n" \
+ " bne %0, %z3, 1f\n" \
+ " sc" sc_sfx " %1, %z4, %2\n" \
+ " bnez %1, 0b\n" \
+ append \
+ "1:\n" \
+ : "=&r" (r), "=&r" (__rc), "+A" (*(p)) \
+ : "rJ" (co o), "rJ" (n) \
+ : "memory"); \
})
-#define __cmpxchg_release(ptr, old, new, size) \
+#define _arch_cmpxchg(ptr, old, new, sc_sfx, prepend, append) \
({ \
__typeof__(ptr) __ptr = (ptr); \
- __typeof__(*(ptr)) __old = (old); \
- __typeof__(*(ptr)) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- register unsigned int __rc; \
- switch (size) { \
+ __typeof__(*(__ptr)) __old = (old); \
+ __typeof__(*(__ptr)) __new = (new); \
+ __typeof__(*(__ptr)) __ret; \
+ \
+ switch (sizeof(*__ptr)) { \
+ case 1: \
+ case 2: \
+ __arch_cmpxchg_masked(sc_sfx, prepend, append, \
+ __ret, __ptr, __old, __new); \
+ break; \
case 4: \
- __asm__ __volatile__ ( \
- RISCV_RELEASE_BARRIER \
- "0: lr.w %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.w %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" ((long)__old), "rJ" (__new) \
- : "memory"); \
+ __arch_cmpxchg(".w", ".w" sc_sfx, prepend, append, \
+ __ret, __ptr, (long), __old, __new); \
break; \
case 8: \
- __asm__ __volatile__ ( \
- RISCV_RELEASE_BARRIER \
- "0: lr.d %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.d %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" (__old), "rJ" (__new) \
- : "memory"); \
+ __arch_cmpxchg(".d", ".d" sc_sfx, prepend, append, \
+ __ret, __ptr, /**/, __old, __new); \
break; \
default: \
BUILD_BUG(); \
} \
- __ret; \
+ (__typeof__(*(__ptr)))__ret; \
})
-#define arch_cmpxchg_release(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg_release((ptr), \
- _o_, _n_, sizeof(*(ptr))); \
-})
+#define arch_cmpxchg_relaxed(ptr, o, n) \
+ _arch_cmpxchg((ptr), (o), (n), "", "", "")
-#define __cmpxchg(ptr, old, new, size) \
-({ \
- __typeof__(ptr) __ptr = (ptr); \
- __typeof__(*(ptr)) __old = (old); \
- __typeof__(*(ptr)) __new = (new); \
- __typeof__(*(ptr)) __ret; \
- register unsigned int __rc; \
- switch (size) { \
- case 4: \
- __asm__ __volatile__ ( \
- "0: lr.w %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.w.rl %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- RISCV_FULL_BARRIER \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" ((long)__old), "rJ" (__new) \
- : "memory"); \
- break; \
- case 8: \
- __asm__ __volatile__ ( \
- "0: lr.d %0, %2\n" \
- " bne %0, %z3, 1f\n" \
- " sc.d.rl %1, %z4, %2\n" \
- " bnez %1, 0b\n" \
- RISCV_FULL_BARRIER \
- "1:\n" \
- : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
- : "rJ" (__old), "rJ" (__new) \
- : "memory"); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
- __ret; \
-})
+#define arch_cmpxchg_acquire(ptr, o, n) \
+ _arch_cmpxchg((ptr), (o), (n), "", "", RISCV_ACQUIRE_BARRIER)
+
+#define arch_cmpxchg_release(ptr, o, n) \
+ _arch_cmpxchg((ptr), (o), (n), "", RISCV_RELEASE_BARRIER, "")
#define arch_cmpxchg(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg((ptr), \
- _o_, _n_, sizeof(*(ptr))); \
-})
+ _arch_cmpxchg((ptr), (o), (n), ".rl", "", " fence rw, rw\n")
#define arch_cmpxchg_local(ptr, o, n) \
- (__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr))))
+ arch_cmpxchg_relaxed((ptr), (o), (n))
#define arch_cmpxchg64(ptr, o, n) \
({ \
@@ -359,4 +208,77 @@
arch_cmpxchg_relaxed((ptr), (o), (n)); \
})
+#define arch_cmpxchg64_relaxed(ptr, o, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ arch_cmpxchg_relaxed((ptr), (o), (n)); \
+})
+
+#define arch_cmpxchg64_acquire(ptr, o, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ arch_cmpxchg_acquire((ptr), (o), (n)); \
+})
+
+#define arch_cmpxchg64_release(ptr, o, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ arch_cmpxchg_release((ptr), (o), (n)); \
+})
+
+#ifdef CONFIG_RISCV_ISA_ZAWRS
+/*
+ * Despite wrs.nto being "WRS-with-no-timeout", in the absence of changes to
+ * @val we expect it to still terminate within a "reasonable" amount of time
+ * for an implementation-specific other reason, a pending, locally-enabled
+ * interrupt, or because it has been configured to raise an illegal
+ * instruction exception.
+ */
+static __always_inline void __cmpwait(volatile void *ptr,
+ unsigned long val,
+ int size)
+{
+ unsigned long tmp;
+
+ asm goto(ALTERNATIVE("j %l[no_zawrs]", "nop",
+ 0, RISCV_ISA_EXT_ZAWRS, 1)
+ : : : : no_zawrs);
+
+ switch (size) {
+ case 4:
+ asm volatile(
+ " lr.w %0, %1\n"
+ " xor %0, %0, %2\n"
+ " bnez %0, 1f\n"
+ ZAWRS_WRS_NTO "\n"
+ "1:"
+ : "=&r" (tmp), "+A" (*(u32 *)ptr)
+ : "r" (val));
+ break;
+#if __riscv_xlen == 64
+ case 8:
+ asm volatile(
+ " lr.d %0, %1\n"
+ " xor %0, %0, %2\n"
+ " bnez %0, 1f\n"
+ ZAWRS_WRS_NTO "\n"
+ "1:"
+ : "=&r" (tmp), "+A" (*(u64 *)ptr)
+ : "r" (val));
+ break;
+#endif
+ default:
+ BUILD_BUG();
+ }
+
+ return;
+
+no_zawrs:
+ asm volatile(RISCV_PAUSE : : : "memory");
+}
+
+#define __cmpwait_relaxed(ptr, val) \
+ __cmpwait((ptr), (unsigned long)(val), sizeof(*(ptr)))
+#endif
+
#endif /* _ASM_RISCV_CMPXCHG_H */
diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
index 347805446151..000796c2d0b1 100644
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -70,6 +70,7 @@ struct riscv_isa_ext_data {
const char *property;
const unsigned int *subset_ext_ids;
const unsigned int subset_ext_size;
+ int (*validate)(const struct riscv_isa_ext_data *data, const unsigned long *isa_bitmap);
};
extern const struct riscv_isa_ext_data riscv_isa_ext[];
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 2468c55933cd..25966995da04 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -168,7 +168,8 @@
#define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT)
#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \
(_AC(1, UL) << IRQ_S_TIMER) | \
- (_AC(1, UL) << IRQ_S_EXT))
+ (_AC(1, UL) << IRQ_S_EXT) | \
+ (_AC(1, UL) << IRQ_PMU_OVF))
/* AIA CSR bits */
#define TOPI_IID_SHIFT 16
@@ -281,7 +282,7 @@
#define CSR_HPMCOUNTER30H 0xc9e
#define CSR_HPMCOUNTER31H 0xc9f
-#define CSR_SSCOUNTOVF 0xda0
+#define CSR_SCOUNTOVF 0xda0
#define CSR_SSTATUS 0x100
#define CSR_SIE 0x104
diff --git a/arch/riscv/include/asm/dmi.h b/arch/riscv/include/asm/dmi.h
new file mode 100644
index 000000000000..ca7cce557ef7
--- /dev/null
+++ b/arch/riscv/include/asm/dmi.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 Intel Corporation
+ *
+ * based on arch/arm64/include/asm/dmi.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ASM_DMI_H
+#define __ASM_DMI_H
+
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define dmi_early_remap(x, l) memremap(x, l, MEMREMAP_WB)
+#define dmi_early_unmap(x, l) memunmap(x)
+#define dmi_remap(x, l) memremap(x, l, MEMREMAP_WB)
+#define dmi_unmap(x) memunmap(x)
+#define dmi_alloc(l) kzalloc(l, GFP_KERNEL)
+
+#endif
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index efd851e1b483..7c8a71a526a3 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -43,11 +43,21 @@ ALTERNATIVE(__stringify(RISCV_PTR do_page_fault), \
CONFIG_ERRATA_SIFIVE_CIP_453)
#else /* !__ASSEMBLY__ */
-#define ALT_FLUSH_TLB_PAGE(x) \
+#define ALT_SFENCE_VMA_ASID(asid) \
+asm(ALTERNATIVE("sfence.vma x0, %0", "sfence.vma", SIFIVE_VENDOR_ID, \
+ ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
+ : : "r" (asid) : "memory")
+
+#define ALT_SFENCE_VMA_ADDR(addr) \
asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
: : "r" (addr) : "memory")
+#define ALT_SFENCE_VMA_ADDR_ASID(addr, asid) \
+asm(ALTERNATIVE("sfence.vma %0, %1", "sfence.vma", SIFIVE_VENDOR_ID, \
+ ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
+ : : "r" (addr), "r" (asid) : "memory")
+
/*
* _val is marked as "will be overwritten", so need to set it to 0
* in the default case.
diff --git a/arch/riscv/include/asm/fpu.h b/arch/riscv/include/asm/fpu.h
new file mode 100644
index 000000000000..91c04c244e12
--- /dev/null
+++ b/arch/riscv/include/asm/fpu.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 SiFive
+ */
+
+#ifndef _ASM_RISCV_FPU_H
+#define _ASM_RISCV_FPU_H
+
+#include <asm/switch_to.h>
+
+#define kernel_fpu_available() has_fpu()
+
+void kernel_fpu_begin(void);
+void kernel_fpu_end(void);
+
+#endif /* ! _ASM_RISCV_FPU_H */
diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
index 1276d7d9ca8b..2cddd79ff21b 100644
--- a/arch/riscv/include/asm/ftrace.h
+++ b/arch/riscv/include/asm/ftrace.h
@@ -11,7 +11,6 @@
#if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER)
#define HAVE_FUNCTION_GRAPH_FP_TEST
#endif
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
#define ARCH_SUPPORTS_FTRACE_OPS 1
#ifndef __ASSEMBLY__
@@ -124,20 +123,82 @@ struct dyn_ftrace;
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
#define ftrace_init_nop ftrace_init_nop
-#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
+#define arch_ftrace_get_regs(regs) NULL
struct ftrace_ops;
-struct ftrace_regs;
+struct ftrace_regs {
+ unsigned long epc;
+ unsigned long ra;
+ unsigned long sp;
+ unsigned long s0;
+ unsigned long t1;
+ union {
+ unsigned long args[8];
+ struct {
+ unsigned long a0;
+ unsigned long a1;
+ unsigned long a2;
+ unsigned long a3;
+ unsigned long a4;
+ unsigned long a5;
+ unsigned long a6;
+ unsigned long a7;
+ };
+ };
+};
+
+static __always_inline unsigned long ftrace_regs_get_instruction_pointer(const struct ftrace_regs
+ *fregs)
+{
+ return fregs->epc;
+}
+
+static __always_inline void ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
+ unsigned long pc)
+{
+ fregs->epc = pc;
+}
+
+static __always_inline unsigned long ftrace_regs_get_stack_pointer(const struct ftrace_regs *fregs)
+{
+ return fregs->sp;
+}
+
+static __always_inline unsigned long ftrace_regs_get_argument(struct ftrace_regs *fregs,
+ unsigned int n)
+{
+ if (n < 8)
+ return fregs->args[n];
+ return 0;
+}
+
+static __always_inline unsigned long ftrace_regs_get_return_value(const struct ftrace_regs *fregs)
+{
+ return fregs->a0;
+}
+
+static __always_inline void ftrace_regs_set_return_value(struct ftrace_regs *fregs,
+ unsigned long ret)
+{
+ fregs->a0 = ret;
+}
+
+static __always_inline void ftrace_override_function_with_return(struct ftrace_regs *fregs)
+{
+ fregs->epc = fregs->ra;
+}
+
+int ftrace_regs_query_register_offset(const char *name);
+
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs);
#define ftrace_graph_func ftrace_graph_func
-static inline void __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
+static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsigned long addr)
{
- regs->t1 = addr;
+ fregs->t1 = addr;
}
-#define arch_ftrace_set_direct_caller(fregs, addr) \
- __arch_ftrace_set_direct_caller(&(fregs)->regs, addr)
-#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
#endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
index 22deb7a2a6ec..faf3624d8057 100644
--- a/arch/riscv/include/asm/hugetlb.h
+++ b/arch/riscv/include/asm/hugetlb.h
@@ -5,11 +5,11 @@
#include <asm/cacheflush.h>
#include <asm/page.h>
-static inline void arch_clear_hugepage_flags(struct page *page)
+static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
- clear_bit(PG_dcache_clean, &page->flags);
+ clear_bit(PG_dcache_clean, &folio->flags);
}
-#define arch_clear_hugepage_flags arch_clear_hugepage_flags
+#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
#ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
bool arch_hugetlb_migration_supported(struct hstate *h);
@@ -44,7 +44,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
pte_t pte, int dirty);
#define __HAVE_ARCH_HUGE_PTEP_GET
-pte_t huge_ptep_get(pte_t *ptep);
+pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
#define arch_make_huge_pte arch_make_huge_pte
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index e17d0078a651..b18b202ca141 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -81,6 +81,18 @@
#define RISCV_ISA_EXT_ZTSO 72
#define RISCV_ISA_EXT_ZACAS 73
#define RISCV_ISA_EXT_XANDESPMU 74
+#define RISCV_ISA_EXT_ZVE32X 75
+#define RISCV_ISA_EXT_ZVE32F 76
+#define RISCV_ISA_EXT_ZVE64X 77
+#define RISCV_ISA_EXT_ZVE64F 78
+#define RISCV_ISA_EXT_ZVE64D 79
+#define RISCV_ISA_EXT_ZIMOP 80
+#define RISCV_ISA_EXT_ZCA 81
+#define RISCV_ISA_EXT_ZCB 82
+#define RISCV_ISA_EXT_ZCD 83
+#define RISCV_ISA_EXT_ZCF 84
+#define RISCV_ISA_EXT_ZCMOP 85
+#define RISCV_ISA_EXT_ZAWRS 86
#define RISCV_ISA_EXT_XLINUXENVCFG 127
diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
index 630507dff5ea..150a9877b0af 100644
--- a/arch/riscv/include/asm/hwprobe.h
+++ b/arch/riscv/include/asm/hwprobe.h
@@ -8,7 +8,7 @@
#include <uapi/asm/hwprobe.h>
-#define RISCV_HWPROBE_MAX_KEY 6
+#define RISCV_HWPROBE_MAX_KEY 7
static inline bool riscv_hwprobe_key_is_valid(__s64 key)
{
diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h
index e27179b26086..9a913010cdd9 100644
--- a/arch/riscv/include/asm/insn-def.h
+++ b/arch/riscv/include/asm/insn-def.h
@@ -196,4 +196,8 @@
INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
RS1(base), SIMM12(4))
+#define RISCV_PAUSE ".4byte 0x100000f"
+#define ZAWRS_WRS_NTO ".4byte 0x00d00073"
+#define ZAWRS_WRS_STO ".4byte 0x01d00073"
+
#endif /* __ASM_INSN_DEF_H */
diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
index 06e439eeef9a..09fde95a5e8f 100644
--- a/arch/riscv/include/asm/insn.h
+++ b/arch/riscv/include/asm/insn.h
@@ -145,7 +145,7 @@
/* parts of opcode for RVF, RVD and RVQ */
#define RVFDQ_FL_FS_WIDTH_OFF 12
-#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(3, 0)
+#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(2, 0)
#define RVFDQ_FL_FS_WIDTH_W 2
#define RVFDQ_FL_FS_WIDTH_D 3
#define RVFDQ_LS_FS_WIDTH_Q 4
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index 08d4d6a5b7e9..6fd8cbfcfcc7 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -7,7 +7,6 @@
#ifndef _ASM_RISCV_IRQFLAGS_H
#define _ASM_RISCV_IRQFLAGS_H
-#include <asm/processor.h>
#include <asm/csr.h>
/* read interrupt enabled status */
diff --git a/arch/riscv/include/asm/jump_label.h b/arch/riscv/include/asm/jump_label.h
index 4a35d787c019..1c768d02bd0c 100644
--- a/arch/riscv/include/asm/jump_label.h
+++ b/arch/riscv/include/asm/jump_label.h
@@ -12,6 +12,8 @@
#include <linux/types.h>
#include <asm/asm.h>
+#define HAVE_JUMP_LABEL_BATCH
+
#define JUMP_LABEL_NOP_SIZE 4
static __always_inline bool arch_static_branch(struct static_key * const key,
@@ -44,7 +46,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
" .option push \n\t"
" .option norelax \n\t"
" .option norvc \n\t"
- "1: jal zero, %l[label] \n\t"
+ "1: j %l[label] \n\t"
" .option pop \n\t"
" .pushsection __jump_table, \"aw\" \n\t"
" .align " RISCV_LGPTR " \n\t"
diff --git a/arch/riscv/include/asm/kasan.h b/arch/riscv/include/asm/kasan.h
index 0b85e363e778..e6a0071bdb56 100644
--- a/arch/riscv/include/asm/kasan.h
+++ b/arch/riscv/include/asm/kasan.h
@@ -6,8 +6,6 @@
#ifndef __ASSEMBLY__
-#ifdef CONFIG_KASAN
-
/*
* The following comment was copied from arm64:
* KASAN_SHADOW_START: beginning of the kernel virtual addresses.
@@ -34,6 +32,8 @@
*/
#define KASAN_SHADOW_START ((KASAN_SHADOW_END - KASAN_SHADOW_SIZE) & PGDIR_MASK)
#define KASAN_SHADOW_END MODULES_LOWEST_VADDR
+
+#ifdef CONFIG_KASAN
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
void kasan_init(void);
diff --git a/arch/riscv/include/asm/kvm_aia_aplic.h b/arch/riscv/include/asm/kvm_aia_aplic.h
deleted file mode 100644
index 6dd1a4809ec1..000000000000
--- a/arch/riscv/include/asm/kvm_aia_aplic.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2021 Western Digital Corporation or its affiliates.
- * Copyright (C) 2022 Ventana Micro Systems Inc.
- */
-#ifndef __KVM_RISCV_AIA_IMSIC_H
-#define __KVM_RISCV_AIA_IMSIC_H
-
-#include <linux/bitops.h>
-
-#define APLIC_MAX_IDC BIT(14)
-#define APLIC_MAX_SOURCE 1024
-
-#define APLIC_DOMAINCFG 0x0000
-#define APLIC_DOMAINCFG_RDONLY 0x80000000
-#define APLIC_DOMAINCFG_IE BIT(8)
-#define APLIC_DOMAINCFG_DM BIT(2)
-#define APLIC_DOMAINCFG_BE BIT(0)
-
-#define APLIC_SOURCECFG_BASE 0x0004
-#define APLIC_SOURCECFG_D BIT(10)
-#define APLIC_SOURCECFG_CHILDIDX_MASK 0x000003ff
-#define APLIC_SOURCECFG_SM_MASK 0x00000007
-#define APLIC_SOURCECFG_SM_INACTIVE 0x0
-#define APLIC_SOURCECFG_SM_DETACH 0x1
-#define APLIC_SOURCECFG_SM_EDGE_RISE 0x4
-#define APLIC_SOURCECFG_SM_EDGE_FALL 0x5
-#define APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6
-#define APLIC_SOURCECFG_SM_LEVEL_LOW 0x7
-
-#define APLIC_IRQBITS_PER_REG 32
-
-#define APLIC_SETIP_BASE 0x1c00
-#define APLIC_SETIPNUM 0x1cdc
-
-#define APLIC_CLRIP_BASE 0x1d00
-#define APLIC_CLRIPNUM 0x1ddc
-
-#define APLIC_SETIE_BASE 0x1e00
-#define APLIC_SETIENUM 0x1edc
-
-#define APLIC_CLRIE_BASE 0x1f00
-#define APLIC_CLRIENUM 0x1fdc
-
-#define APLIC_SETIPNUM_LE 0x2000
-#define APLIC_SETIPNUM_BE 0x2004
-
-#define APLIC_GENMSI 0x3000
-
-#define APLIC_TARGET_BASE 0x3004
-#define APLIC_TARGET_HART_IDX_SHIFT 18
-#define APLIC_TARGET_HART_IDX_MASK 0x3fff
-#define APLIC_TARGET_GUEST_IDX_SHIFT 12
-#define APLIC_TARGET_GUEST_IDX_MASK 0x3f
-#define APLIC_TARGET_IPRIO_MASK 0xff
-#define APLIC_TARGET_EIID_MASK 0x7ff
-
-#endif
diff --git a/arch/riscv/include/asm/kvm_aia_imsic.h b/arch/riscv/include/asm/kvm_aia_imsic.h
deleted file mode 100644
index da5881d2bde0..000000000000
--- a/arch/riscv/include/asm/kvm_aia_imsic.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2021 Western Digital Corporation or its affiliates.
- * Copyright (C) 2022 Ventana Micro Systems Inc.
- */
-#ifndef __KVM_RISCV_AIA_IMSIC_H
-#define __KVM_RISCV_AIA_IMSIC_H
-
-#include <linux/types.h>
-#include <asm/csr.h>
-
-#define IMSIC_MMIO_PAGE_SHIFT 12
-#define IMSIC_MMIO_PAGE_SZ (1UL << IMSIC_MMIO_PAGE_SHIFT)
-#define IMSIC_MMIO_PAGE_LE 0x00
-#define IMSIC_MMIO_PAGE_BE 0x04
-
-#define IMSIC_MIN_ID 63
-#define IMSIC_MAX_ID 2048
-
-#define IMSIC_EIDELIVERY 0x70
-
-#define IMSIC_EITHRESHOLD 0x72
-
-#define IMSIC_EIP0 0x80
-#define IMSIC_EIP63 0xbf
-#define IMSIC_EIPx_BITS 32
-
-#define IMSIC_EIE0 0xc0
-#define IMSIC_EIE63 0xff
-#define IMSIC_EIEx_BITS 32
-
-#define IMSIC_FIRST IMSIC_EIDELIVERY
-#define IMSIC_LAST IMSIC_EIE63
-
-#define IMSIC_MMIO_SETIPNUM_LE 0x00
-#define IMSIC_MMIO_SETIPNUM_BE 0x04
-
-#endif
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 484d04a92fa6..2e2254fd2a2a 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -43,6 +43,17 @@
KVM_ARCH_REQ_FLAGS(5, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(6)
+#define KVM_HEDELEG_DEFAULT (BIT(EXC_INST_MISALIGNED) | \
+ BIT(EXC_BREAKPOINT) | \
+ BIT(EXC_SYSCALL) | \
+ BIT(EXC_INST_PAGE_FAULT) | \
+ BIT(EXC_LOAD_PAGE_FAULT) | \
+ BIT(EXC_STORE_PAGE_FAULT))
+
+#define KVM_HIDELEG_DEFAULT (BIT(IRQ_VS_SOFT) | \
+ BIT(IRQ_VS_TIMER) | \
+ BIT(IRQ_VS_EXT))
+
enum kvm_riscv_hfence_type {
KVM_RISCV_HFENCE_UNKNOWN = 0,
KVM_RISCV_HFENCE_GVMA_VMID_GPA,
@@ -69,6 +80,7 @@ struct kvm_vcpu_stat {
struct kvm_vcpu_stat_generic generic;
u64 ecall_exit_stat;
u64 wfi_exit_stat;
+ u64 wrs_exit_stat;
u64 mmio_exit_user;
u64 mmio_exit_kernel;
u64 csr_exit_user;
@@ -169,6 +181,7 @@ struct kvm_vcpu_csr {
struct kvm_vcpu_config {
u64 henvcfg;
u64 hstateen0;
+ unsigned long hedeleg;
};
struct kvm_vcpu_smstateen_csr {
@@ -211,6 +224,7 @@ struct kvm_vcpu_arch {
/* CPU context upon Guest VCPU reset */
struct kvm_cpu_context guest_reset_context;
+ spinlock_t reset_cntx_lock;
/* CPU CSR context upon Guest VCPU reset */
struct kvm_vcpu_csr guest_reset_csr;
@@ -252,8 +266,9 @@ struct kvm_vcpu_arch {
/* Cache pages needed to program page tables with spinlock held */
struct kvm_mmu_memory_cache mmu_page_cache;
- /* VCPU power-off state */
- bool power_off;
+ /* VCPU power state */
+ struct kvm_mp_state mp_state;
+ spinlock_t mp_state_lock;
/* Don't run the VCPU (blocked) */
bool pause;
@@ -272,7 +287,6 @@ struct kvm_vcpu_arch {
};
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
#define KVM_RISCV_GSTAGE_TLB_MIN_ORDER 12
@@ -374,8 +388,11 @@ int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);
void kvm_riscv_vcpu_flush_interrupts(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu);
bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask);
+void __kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
+void __kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
+bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_sbi_sta_reset(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu);
diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm/kvm_vcpu_pmu.h
index 395518a1664e..fa0f535bbbf0 100644
--- a/arch/riscv/include/asm/kvm_vcpu_pmu.h
+++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h
@@ -20,7 +20,7 @@ static_assert(RISCV_KVM_MAX_COUNTERS <= 64);
struct kvm_fw_event {
/* Current value of the event */
- unsigned long value;
+ u64 value;
/* Event monitoring status */
bool started;
@@ -36,6 +36,7 @@ struct kvm_pmc {
bool started;
/* Monitoring event ID */
unsigned long event_idx;
+ struct kvm_vcpu *vcpu;
};
/* PMU data structure per vcpu */
@@ -50,6 +51,12 @@ struct kvm_pmu {
bool init_done;
/* Bit map of all the virtual counter used */
DECLARE_BITMAP(pmc_in_use, RISCV_KVM_MAX_COUNTERS);
+ /* Bit map of all the virtual counter overflown */
+ DECLARE_BITMAP(pmc_overflown, RISCV_KVM_MAX_COUNTERS);
+ /* The address of the counter snapshot area (guest physical address) */
+ gpa_t snapshot_addr;
+ /* The actual data of the snapshot */
+ struct riscv_pmu_snapshot_data *sdata;
};
#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu_context)
@@ -82,9 +89,14 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
unsigned long ctr_mask, unsigned long flags,
unsigned long eidx, u64 evtdata,
struct kvm_vcpu_sbi_return *retdata);
-int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
+int kvm_riscv_vcpu_pmu_fw_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
struct kvm_vcpu_sbi_return *retdata);
+int kvm_riscv_vcpu_pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx,
+ struct kvm_vcpu_sbi_return *retdata);
void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
+int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
+ unsigned long saddr_high, unsigned long flags,
+ struct kvm_vcpu_sbi_return *retdata);
void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);
diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
index 355504b37f8e..c9e03e9da3dc 100644
--- a/arch/riscv/include/asm/mmu.h
+++ b/arch/riscv/include/asm/mmu.h
@@ -19,6 +19,8 @@ typedef struct {
#ifdef CONFIG_SMP
/* A local icache flush is needed before user execution can resume. */
cpumask_t icache_stale_mask;
+ /* Force local icache flush on all migrations. */
+ bool force_icache_flush;
#endif
#ifdef CONFIG_BINFMT_ELF_FDPIC
unsigned long exec_fdpic_loadmap;
@@ -26,8 +28,11 @@ 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);
+#define cntx2asid(cntx) ((cntx) & SATP_ASID_MASK)
+#define cntx2version(cntx) ((cntx) & ~SATP_ASID_MASK)
+
+void __meminit 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/include/asm/page.h b/arch/riscv/include/asm/page.h
index 115ac98b8d72..235fd45d998d 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -188,6 +188,11 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);
unsigned long kaslr_offset(void);
+static __always_inline void *pfn_to_kaddr(unsigned long pfn)
+{
+ return __va(pfn << PAGE_SHIFT);
+}
+
#endif /* __ASSEMBLY__ */
#define virt_addr_valid(vaddr) ({ \
diff --git a/arch/riscv/include/asm/patch.h b/arch/riscv/include/asm/patch.h
index e88b52d39eac..7228e266b9a1 100644
--- a/arch/riscv/include/asm/patch.h
+++ b/arch/riscv/include/asm/patch.h
@@ -6,9 +6,10 @@
#ifndef _ASM_RISCV_PATCH_H
#define _ASM_RISCV_PATCH_H
+int patch_insn_write(void *addr, const void *insn, size_t len);
int patch_text_nosync(void *addr, const void *insns, size_t len);
int patch_text_set_nosync(void *addr, u8 c, size_t len);
-int patch_text(void *addr, u32 *insns, int ninsns);
+int patch_text(void *addr, u32 *insns, size_t len);
extern int riscv_patch_in_stop_machine;
diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index deaf971253a2..f52264304f77 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -8,6 +8,7 @@
#define _ASM_RISCV_PGALLOC_H
#include <linux/mm.h>
+#include <asm/sbi.h>
#include <asm/tlb.h>
#ifdef CONFIG_MMU
@@ -15,6 +16,14 @@
#define __HAVE_ARCH_PUD_FREE
#include <asm-generic/pgalloc.h>
+static inline void riscv_tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt)
+{
+ if (riscv_use_sbi_for_rfence())
+ tlb_remove_ptdesc(tlb, pt);
+ else
+ tlb_remove_page_ptdesc(tlb, pt);
+}
+
static inline void pmd_populate_kernel(struct mm_struct *mm,
pmd_t *pmd, pte_t *pte)
{
@@ -102,10 +111,7 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
struct ptdesc *ptdesc = virt_to_ptdesc(pud);
pagetable_pud_dtor(ptdesc);
- if (riscv_use_ipi_for_rfence())
- tlb_remove_page_ptdesc(tlb, ptdesc);
- else
- tlb_remove_ptdesc(tlb, ptdesc);
+ riscv_tlb_remove_ptdesc(tlb, ptdesc);
}
}
@@ -139,12 +145,8 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
unsigned long addr)
{
- if (pgtable_l5_enabled) {
- if (riscv_use_ipi_for_rfence())
- tlb_remove_page_ptdesc(tlb, virt_to_ptdesc(p4d));
- else
- tlb_remove_ptdesc(tlb, virt_to_ptdesc(p4d));
- }
+ if (pgtable_l5_enabled)
+ riscv_tlb_remove_ptdesc(tlb, virt_to_ptdesc(p4d));
}
#endif /* __PAGETABLE_PMD_FOLDED */
@@ -176,10 +178,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
struct ptdesc *ptdesc = virt_to_ptdesc(pmd);
pagetable_pmd_dtor(ptdesc);
- if (riscv_use_ipi_for_rfence())
- tlb_remove_page_ptdesc(tlb, ptdesc);
- else
- tlb_remove_ptdesc(tlb, ptdesc);
+ riscv_tlb_remove_ptdesc(tlb, ptdesc);
}
#endif /* __PAGETABLE_PMD_FOLDED */
@@ -190,10 +189,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
struct ptdesc *ptdesc = page_ptdesc(pte);
pagetable_pte_dtor(ptdesc);
- if (riscv_use_ipi_for_rfence())
- tlb_remove_page_ptdesc(tlb, ptdesc);
- else
- tlb_remove_ptdesc(tlb, ptdesc);
+ riscv_tlb_remove_ptdesc(tlb, ptdesc);
}
#endif /* CONFIG_MMU */
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 221a5c1ee287..0897dd99ab8d 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -16,8 +16,6 @@ extern bool pgtable_l5_enabled;
#define PGDIR_SHIFT_L3 30
#define PGDIR_SHIFT_L4 39
#define PGDIR_SHIFT_L5 48
-#define PGDIR_SIZE_L3 (_AC(1, UL) << PGDIR_SHIFT_L3)
-
#define PGDIR_SHIFT (pgtable_l5_enabled ? PGDIR_SHIFT_L5 : \
(pgtable_l4_enabled ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3))
/* Size of region mapped by a page global directory */
@@ -400,4 +398,24 @@ static inline struct page *pgd_page(pgd_t pgd)
#define p4d_offset p4d_offset
p4d_t *p4d_offset(pgd_t *pgd, unsigned long address);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static inline int pte_devmap(pte_t pte);
+static inline pte_t pmd_pte(pmd_t pmd);
+
+static inline int pmd_devmap(pmd_t pmd)
+{
+ return pte_devmap(pmd_pte(pmd));
+}
+
+static inline int pud_devmap(pud_t pud)
+{
+ return 0;
+}
+
+static inline int pgd_devmap(pgd_t pgd)
+{
+ return 0;
+}
+#endif
+
#endif /* _ASM_RISCV_PGTABLE_64_H */
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index 179bd4afece4..a8f5205cea54 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -19,6 +19,7 @@
#define _PAGE_SOFT (3 << 8) /* Reserved for software */
#define _PAGE_SPECIAL (1 << 8) /* RSW: 0x1 */
+#define _PAGE_DEVMAP (1 << 9) /* RSW, devmap */
#define _PAGE_TABLE _PAGE_PRESENT
/*
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 6afd6bb4882e..089f3c9f56a3 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -55,6 +55,9 @@
#define MODULES_LOWEST_VADDR (KERNEL_LINK_ADDR - SZ_2G)
#define MODULES_VADDR (PFN_ALIGN((unsigned long)&_end) - SZ_2G)
#define MODULES_END (PFN_ALIGN((unsigned long)&_start))
+#else
+#define MODULES_VADDR VMALLOC_START
+#define MODULES_END VMALLOC_END
#endif
/*
@@ -162,7 +165,7 @@ struct pt_alloc_ops {
#endif
};
-extern struct pt_alloc_ops pt_ops __initdata;
+extern struct pt_alloc_ops pt_ops __meminitdata;
#ifdef CONFIG_MMU
/* Number of PGD entries that a user-mode program can use */
@@ -347,6 +350,19 @@ static inline int pte_present(pte_t pte)
return (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
}
+#define pte_accessible pte_accessible
+static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
+{
+ if (pte_val(a) & _PAGE_PRESENT)
+ return true;
+
+ if ((pte_val(a) & _PAGE_PROT_NONE) &&
+ atomic_read(&mm->tlb_flush_pending))
+ return true;
+
+ return false;
+}
+
static inline int pte_none(pte_t pte)
{
return (pte_val(pte) == 0);
@@ -387,6 +403,13 @@ static inline int pte_special(pte_t pte)
return pte_val(pte) & _PAGE_SPECIAL;
}
+#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
+static inline int pte_devmap(pte_t pte)
+{
+ return pte_val(pte) & _PAGE_DEVMAP;
+}
+#endif
+
/* static inline pte_t pte_rdprotect(pte_t pte) */
static inline pte_t pte_wrprotect(pte_t pte)
@@ -428,6 +451,11 @@ static inline pte_t pte_mkspecial(pte_t pte)
return __pte(pte_val(pte) | _PAGE_SPECIAL);
}
+static inline pte_t pte_mkdevmap(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_DEVMAP);
+}
+
static inline pte_t pte_mkhuge(pte_t pte)
{
return pte;
@@ -486,8 +514,8 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
#define update_mmu_cache(vma, addr, ptep) \
update_mmu_cache_range(NULL, vma, addr, ptep, 1)
-#define __HAVE_ARCH_UPDATE_MMU_TLB
-#define update_mmu_tlb update_mmu_cache
+#define update_mmu_tlb_range(vma, addr, ptep, nr) \
+ update_mmu_cache_range(NULL, vma, addr, ptep, nr)
static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp)
@@ -648,6 +676,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd)
#define __pud_to_phys(pud) (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT)
+#define pud_pfn pud_pfn
static inline unsigned long pud_pfn(pud_t pud)
{
return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT);
@@ -717,6 +746,11 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd)
return pte_pmd(pte_mkdirty(pmd_pte(pmd)));
}
+static inline pmd_t pmd_mkdevmap(pmd_t pmd)
+{
+ return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
+}
+
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp, pmd_t pmd)
{
@@ -876,7 +910,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
*/
#ifdef CONFIG_64BIT
#define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2)
-#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
+#define TASK_SIZE_MAX LONG_MAX
#ifdef CONFIG_COMPAT
#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
@@ -888,7 +922,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
#else
#define TASK_SIZE FIXADDR_START
-#define TASK_SIZE_MIN TASK_SIZE
#endif
#else /* CONFIG_MMU */
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 0faf5f161f1e..8702b8721a27 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -57,6 +57,12 @@
#define STACK_TOP DEFAULT_MAP_WINDOW
+#ifdef CONFIG_MMU
+#define user_max_virt_addr() arch_get_mmap_end(ULONG_MAX, 0, 0)
+#else
+#define user_max_virt_addr() 0
+#endif /* CONFIG_MMU */
+
/*
* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
@@ -68,6 +74,7 @@
#endif
#ifndef __ASSEMBLY__
+#include <linux/cpumask.h>
struct task_struct;
struct pt_regs;
@@ -122,6 +129,12 @@ struct thread_struct {
struct __riscv_v_ext_state vstate;
unsigned long align_ctl;
struct __riscv_v_ext_state kernel_vstate;
+#ifdef CONFIG_SMP
+ /* Flush the icache on migration */
+ bool force_icache_flush;
+ /* A forced icache flush is not needed if migrating to the previous cpu. */
+ unsigned int prev_cpu;
+#endif
};
/* Whitelist the fstate from the task_struct for hardened usercopy */
@@ -183,6 +196,9 @@ extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
#define GET_UNALIGN_CTL(tsk, addr) get_unalign_ctl((tsk), (addr))
#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val))
+#define RISCV_SET_ICACHE_FLUSH_CTX(arg1, arg2) riscv_set_icache_flush_ctx(arg1, arg2)
+extern int riscv_set_icache_flush_ctx(unsigned long ctx, unsigned long per_thread);
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_PROCESSOR_H */
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 6e68f8dff76b..7cffd4ffecd0 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -131,6 +131,8 @@ enum sbi_ext_pmu_fid {
SBI_EXT_PMU_COUNTER_START,
SBI_EXT_PMU_COUNTER_STOP,
SBI_EXT_PMU_COUNTER_FW_READ,
+ SBI_EXT_PMU_COUNTER_FW_READ_HI,
+ SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
};
union sbi_pmu_ctr_info {
@@ -147,6 +149,13 @@ union sbi_pmu_ctr_info {
};
};
+/* Data structure to contain the pmu snapshot data */
+struct riscv_pmu_snapshot_data {
+ u64 ctr_overflow_mask;
+ u64 ctr_values[64];
+ u64 reserved[447];
+};
+
#define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
#define RISCV_PMU_RAW_EVENT_IDX 0x20000
@@ -232,20 +241,22 @@ enum sbi_pmu_ctr_type {
#define SBI_PMU_EVENT_IDX_INVALID 0xFFFFFFFF
/* Flags defined for config matching function */
-#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0)
-#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1)
-#define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2)
-#define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3)
-#define SBI_PMU_CFG_FLAG_SET_VSINH (1 << 4)
-#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5)
-#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6)
-#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
+#define SBI_PMU_CFG_FLAG_SKIP_MATCH BIT(0)
+#define SBI_PMU_CFG_FLAG_CLEAR_VALUE BIT(1)
+#define SBI_PMU_CFG_FLAG_AUTO_START BIT(2)
+#define SBI_PMU_CFG_FLAG_SET_VUINH BIT(3)
+#define SBI_PMU_CFG_FLAG_SET_VSINH BIT(4)
+#define SBI_PMU_CFG_FLAG_SET_UINH BIT(5)
+#define SBI_PMU_CFG_FLAG_SET_SINH BIT(6)
+#define SBI_PMU_CFG_FLAG_SET_MINH BIT(7)
/* Flags defined for counter start function */
-#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
+#define SBI_PMU_START_FLAG_SET_INIT_VALUE BIT(0)
+#define SBI_PMU_START_FLAG_INIT_SNAPSHOT BIT(1)
/* Flags defined for counter stop function */
-#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
+#define SBI_PMU_STOP_FLAG_RESET BIT(0)
+#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT BIT(1)
enum sbi_ext_dbcn_fid {
SBI_EXT_DBCN_CONSOLE_WRITE = 0,
@@ -266,7 +277,7 @@ struct sbi_sta_struct {
u8 pad[47];
} __packed;
-#define SBI_STA_SHMEM_DISABLE -1
+#define SBI_SHMEM_DISABLE -1
/* SBI spec version fields */
#define SBI_SPEC_VERSION_DEFAULT 0x1
@@ -284,6 +295,7 @@ struct sbi_sta_struct {
#define SBI_ERR_ALREADY_AVAILABLE -6
#define SBI_ERR_ALREADY_STARTED -7
#define SBI_ERR_ALREADY_STOPPED -8
+#define SBI_ERR_NO_SHMEM -9
extern unsigned long sbi_spec_version;
struct sbiret {
@@ -292,10 +304,12 @@ struct sbiret {
};
void sbi_init(void);
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5);
+struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5,
+ int fid, int ext);
+#define sbi_ecall(e, f, a0, a1, a2, a3, a4, a5) \
+ __sbi_ecall(a0, a1, a2, a3, a4, a5, f, e)
#ifdef CONFIG_RISCV_SBI_V01
void sbi_console_putchar(int ch);
@@ -355,8 +369,8 @@ static inline unsigned long sbi_minor_version(void)
static inline unsigned long sbi_mk_version(unsigned long major,
unsigned long minor)
{
- return ((major & SBI_SPEC_VERSION_MAJOR_MASK) <<
- SBI_SPEC_VERSION_MAJOR_SHIFT) | minor;
+ return ((major & SBI_SPEC_VERSION_MAJOR_MASK) << SBI_SPEC_VERSION_MAJOR_SHIFT)
+ | (minor & SBI_SPEC_VERSION_MINOR_MASK);
}
int sbi_err_map_linux_errno(int err);
@@ -370,13 +384,19 @@ static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1
static inline void sbi_init(void) {}
#endif /* CONFIG_RISCV_SBI */
+unsigned long riscv_get_mvendorid(void);
+unsigned long riscv_get_marchid(void);
unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
unsigned long riscv_cached_marchid(unsigned int cpu_id);
unsigned long riscv_cached_mimpid(unsigned int cpu_id);
#if IS_ENABLED(CONFIG_SMP) && IS_ENABLED(CONFIG_RISCV_SBI)
+DECLARE_STATIC_KEY_FALSE(riscv_sbi_for_rfence);
+#define riscv_use_sbi_for_rfence() \
+ static_branch_unlikely(&riscv_sbi_for_rfence)
void sbi_ipi_init(void);
#else
+static inline bool riscv_use_sbi_for_rfence(void) { return false; }
static inline void sbi_ipi_init(void) { }
#endif
diff --git a/arch/riscv/include/asm/signal.h b/arch/riscv/include/asm/signal.h
deleted file mode 100644
index 956ae0a01bad..000000000000
--- a/arch/riscv/include/asm/signal.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef __ASM_SIGNAL_H
-#define __ASM_SIGNAL_H
-
-#include <uapi/asm/signal.h>
-#include <uapi/asm/ptrace.h>
-
-asmlinkage __visible
-void do_work_pending(struct pt_regs *regs, unsigned long thread_info_flags);
-
-#endif
diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
index 0d555847cde6..7ac80e9f2288 100644
--- a/arch/riscv/include/asm/smp.h
+++ b/arch/riscv/include/asm/smp.h
@@ -49,12 +49,7 @@ void riscv_ipi_disable(void);
bool riscv_ipi_have_virq_range(void);
/* Set the IPI interrupt numbers for arch (called by irqchip drivers) */
-void riscv_ipi_set_virq_range(int virq, int nr, bool use_for_rfence);
-
-/* Check if we can use IPIs for remote FENCEs */
-DECLARE_STATIC_KEY_FALSE(riscv_ipi_for_rfence);
-#define riscv_use_ipi_for_rfence() \
- static_branch_unlikely(&riscv_ipi_for_rfence)
+void riscv_ipi_set_virq_range(int virq, int nr);
/* Check other CPUs stop or not */
bool smp_crash_stop_failed(void);
@@ -104,16 +99,10 @@ static inline bool riscv_ipi_have_virq_range(void)
return false;
}
-static inline void riscv_ipi_set_virq_range(int virq, int nr,
- bool use_for_rfence)
+static inline void riscv_ipi_set_virq_range(int virq, int nr)
{
}
-static inline bool riscv_use_ipi_for_rfence(void)
-{
- return false;
-}
-
#endif /* CONFIG_SMP */
#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP)
diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h
index 4718096fa5e3..4ffb022b097f 100644
--- a/arch/riscv/include/asm/suspend.h
+++ b/arch/riscv/include/asm/suspend.h
@@ -13,7 +13,6 @@ struct suspend_context {
/* Saved and restored by low-level functions */
struct pt_regs regs;
/* Saved and restored by high-level functions */
- unsigned long scratch;
unsigned long envcfg;
unsigned long tvec;
unsigned long ie;
diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index 7efdb0584d47..7594df37cc9f 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -8,6 +8,7 @@
#include <linux/jump_label.h>
#include <linux/sched/task_stack.h>
+#include <linux/mm_types.h>
#include <asm/vector.h>
#include <asm/cpufeature.h>
#include <asm/processor.h>
@@ -72,14 +73,36 @@ static __always_inline bool has_fpu(void) { return false; }
extern struct task_struct *__switch_to(struct task_struct *,
struct task_struct *);
+static inline bool switch_to_should_flush_icache(struct task_struct *task)
+{
+#ifdef CONFIG_SMP
+ bool stale_mm = task->mm && task->mm->context.force_icache_flush;
+ bool stale_thread = task->thread.force_icache_flush;
+ bool thread_migrated = smp_processor_id() != task->thread.prev_cpu;
+
+ return thread_migrated && (stale_mm || stale_thread);
+#else
+ return false;
+#endif
+}
+
+#ifdef CONFIG_SMP
+#define __set_prev_cpu(thread) ((thread).prev_cpu = smp_processor_id())
+#else
+#define __set_prev_cpu(thread)
+#endif
+
#define switch_to(prev, next, last) \
do { \
struct task_struct *__prev = (prev); \
struct task_struct *__next = (next); \
+ __set_prev_cpu(__prev->thread); \
if (has_fpu()) \
__switch_to_fpu(__prev, __next); \
if (has_vector()) \
__switch_to_vector(__prev, __next); \
+ if (switch_to_should_flush_icache(__next)) \
+ local_flush_icache_all(); \
((last) = __switch_to(__prev, __next)); \
} while (0)
diff --git a/arch/riscv/include/asm/syscall_table.h b/arch/riscv/include/asm/syscall_table.h
new file mode 100644
index 000000000000..0c2d61782813
--- /dev/null
+++ b/arch/riscv/include/asm/syscall_table.h
@@ -0,0 +1,7 @@
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscall_table_64.h>
+#else
+#include <asm/syscall_table_32.h>
+#endif
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index 4112cc8d1d69..72e559934952 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -15,24 +15,34 @@
#define FLUSH_TLB_NO_ASID ((unsigned long)-1)
#ifdef CONFIG_MMU
-extern unsigned long asid_mask;
-
static inline void local_flush_tlb_all(void)
{
__asm__ __volatile__ ("sfence.vma" : : : "memory");
}
+static inline void local_flush_tlb_all_asid(unsigned long asid)
+{
+ if (asid != FLUSH_TLB_NO_ASID)
+ ALT_SFENCE_VMA_ASID(asid);
+ else
+ local_flush_tlb_all();
+}
+
/* Flush one page from local TLB */
static inline void local_flush_tlb_page(unsigned long addr)
{
- ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+ ALT_SFENCE_VMA_ADDR(addr);
+}
+
+static inline void local_flush_tlb_page_asid(unsigned long addr,
+ unsigned long asid)
+{
+ if (asid != FLUSH_TLB_NO_ASID)
+ ALT_SFENCE_VMA_ADDR_ASID(addr, asid);
+ else
+ local_flush_tlb_page(addr);
}
-#else /* CONFIG_MMU */
-#define local_flush_tlb_all() do { } while (0)
-#define local_flush_tlb_page(addr) do { } while (0)
-#endif /* CONFIG_MMU */
-#if defined(CONFIG_SMP) && defined(CONFIG_MMU)
void flush_tlb_all(void);
void flush_tlb_mm(struct mm_struct *mm);
void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
@@ -55,27 +65,9 @@ void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch,
void arch_flush_tlb_batched_pending(struct mm_struct *mm);
void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch);
-#else /* CONFIG_SMP && CONFIG_MMU */
-
-#define flush_tlb_all() local_flush_tlb_all()
-#define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
-
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- local_flush_tlb_all();
-}
-
-/* Flush a range of kernel pages */
-static inline void flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
-{
- local_flush_tlb_all();
-}
-
-#define flush_tlb_mm(mm) flush_tlb_all()
-#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
-#define local_flush_tlb_kernel_range(start, end) flush_tlb_all()
-#endif /* !CONFIG_SMP || !CONFIG_MMU */
+extern unsigned long tlb_flush_all_threshold;
+#else /* CONFIG_MMU */
+#define local_flush_tlb_all() do { } while (0)
+#endif /* CONFIG_MMU */
#endif /* _ASM_RISCV_TLBFLUSH_H */
diff --git a/arch/riscv/include/asm/trace.h b/arch/riscv/include/asm/trace.h
new file mode 100644
index 000000000000..6151cee5450c
--- /dev/null
+++ b/arch/riscv/include/asm/trace.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM riscv
+
+#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RISCV_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT_CONDITION(sbi_call,
+ TP_PROTO(int ext, int fid),
+ TP_ARGS(ext, fid),
+ TP_CONDITION(ext != SBI_EXT_HSM),
+
+ TP_STRUCT__entry(
+ __field(int, ext)
+ __field(int, fid)
+ ),
+
+ TP_fast_assign(
+ __entry->ext = ext;
+ __entry->fid = fid;
+ ),
+
+ TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid)
+);
+
+TRACE_EVENT_CONDITION(sbi_return,
+ TP_PROTO(int ext, long error, long value),
+ TP_ARGS(ext, error, value),
+ TP_CONDITION(ext != SBI_EXT_HSM),
+
+ TP_STRUCT__entry(
+ __field(long, error)
+ __field(long, value)
+ ),
+
+ TP_fast_assign(
+ __entry->error = error;
+ __entry->value = value;
+ ),
+
+ TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value)
+);
+
+#endif /* _TRACE_RISCV_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH asm
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
index 221630bdbd07..e6d904fa67c5 100644
--- a/arch/riscv/include/asm/unistd.h
+++ b/arch/riscv/include/asm/unistd.h
@@ -3,11 +3,6 @@
* Copyright (C) 2012 Regents of the University of California
*/
-/*
- * There is explicitly no include guard here because this file is expected to
- * be included multiple times.
- */
-
#define __ARCH_WANT_SYS_CLONE
#ifdef CONFIG_COMPAT
@@ -21,6 +16,14 @@
#define __ARCH_WANT_COMPAT_FADVISE64_64
#endif
+#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
+#define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+#endif /* __LP64__ */
+
+#define __ARCH_WANT_MEMFD_SECRET
+
+
#include <uapi/asm/unistd.h>
#define NR_syscalls (__NR_syscalls)
diff --git a/arch/riscv/include/asm/vdso/processor.h b/arch/riscv/include/asm/vdso/processor.h
index 96b65a5396df..8f383f05a290 100644
--- a/arch/riscv/include/asm/vdso/processor.h
+++ b/arch/riscv/include/asm/vdso/processor.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
#include <asm/barrier.h>
+#include <asm/insn-def.h>
static inline void cpu_relax(void)
{
@@ -14,16 +15,11 @@ static inline void cpu_relax(void)
__asm__ __volatile__ ("div %0, %0, zero" : "=r" (dummy));
#endif
-#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE
/*
* Reduce instruction retirement.
* This assumes the PC changes.
*/
- __asm__ __volatile__ ("pause");
-#else
- /* Encoding of the pause instruction */
- __asm__ __volatile__ (".4byte 0x100000F");
-#endif
+ __asm__ __volatile__ (RISCV_PAUSE);
barrier();
}
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index 731dcd0ed4de..be7d309cca8a 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -37,7 +37,7 @@ static inline u32 riscv_v_flags(void)
static __always_inline bool has_vector(void)
{
- return riscv_has_extension_unlikely(RISCV_ISA_EXT_v);
+ return riscv_has_extension_unlikely(RISCV_ISA_EXT_ZVE32X);
}
static inline void __riscv_v_vstate_clean(struct pt_regs *regs)
@@ -91,7 +91,7 @@ static __always_inline void __vstate_csr_restore(struct __riscv_v_ext_state *src
{
asm volatile (
".option push\n\t"
- ".option arch, +v\n\t"
+ ".option arch, +zve32x\n\t"
"vsetvl x0, %2, %1\n\t"
".option pop\n\t"
"csrw " __stringify(CSR_VSTART) ", %0\n\t"
@@ -109,7 +109,7 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
__vstate_csr_save(save_to);
asm volatile (
".option push\n\t"
- ".option arch, +v\n\t"
+ ".option arch, +zve32x\n\t"
"vsetvli %0, x0, e8, m8, ta, ma\n\t"
"vse8.v v0, (%1)\n\t"
"add %1, %1, %0\n\t"
@@ -131,7 +131,7 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
riscv_v_enable();
asm volatile (
".option push\n\t"
- ".option arch, +v\n\t"
+ ".option arch, +zve32x\n\t"
"vsetvli %0, x0, e8, m8, ta, ma\n\t"
"vle8.v v0, (%1)\n\t"
"add %1, %1, %0\n\t"
@@ -153,7 +153,7 @@ static inline void __riscv_v_vstate_discard(void)
riscv_v_enable();
asm volatile (
".option push\n\t"
- ".option arch, +v\n\t"
+ ".option arch, +zve32x\n\t"
"vsetvli %0, x0, e8, m8, ta, ma\n\t"
"vmv.v.i v0, -1\n\t"
"vmv.v.i v8, -1\n\t"
diff --git a/arch/riscv/include/uapi/asm/Kbuild b/arch/riscv/include/uapi/asm/Kbuild
index f66554cd5c45..89ac01faa5ae 100644
--- a/arch/riscv/include/uapi/asm/Kbuild
+++ b/arch/riscv/include/uapi/asm/Kbuild
@@ -1 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
+syscall-y += unistd_64.h
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 2902f68dc913..8b8f6ac0eae2 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -59,6 +59,19 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
+#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
+#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
+#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
+#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
+#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
+#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
+#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
+#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
+#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
+#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
+#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
+#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
+#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
@@ -67,6 +80,7 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
+#define RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS 7
/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
/* Flags */
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index b1c503c2959c..e97db3296456 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -167,6 +167,14 @@ enum KVM_RISCV_ISA_EXT_ID {
KVM_RISCV_ISA_EXT_ZFA,
KVM_RISCV_ISA_EXT_ZTSO,
KVM_RISCV_ISA_EXT_ZACAS,
+ KVM_RISCV_ISA_EXT_SSCOFPMF,
+ KVM_RISCV_ISA_EXT_ZIMOP,
+ KVM_RISCV_ISA_EXT_ZCA,
+ KVM_RISCV_ISA_EXT_ZCB,
+ KVM_RISCV_ISA_EXT_ZCD,
+ KVM_RISCV_ISA_EXT_ZCF,
+ KVM_RISCV_ISA_EXT_ZCMOP,
+ KVM_RISCV_ISA_EXT_ZAWRS,
KVM_RISCV_ISA_EXT_MAX,
};
diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h
index 950ab3fd4409..81896bbbf727 100644
--- a/arch/riscv/include/uapi/asm/unistd.h
+++ b/arch/riscv/include/uapi/asm/unistd.h
@@ -14,41 +14,10 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include <asm/bitsperlong.h>
-#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
-#define __ARCH_WANT_NEW_STAT
-#define __ARCH_WANT_SET_GET_RLIMIT
-#endif /* __LP64__ */
-
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_MEMFD_SECRET
-
-#include <asm-generic/unistd.h>
-
-/*
- * Allows the instruction cache to be flushed from userspace. Despite RISC-V
- * having a direct 'fence.i' instruction available to userspace (which we
- * can't trap!), that's not actually viable when running on Linux because the
- * kernel might schedule a process on another hart. There is no way for
- * userspace to handle this without invoking the kernel (as it doesn't know the
- * thread->hart mappings), so we've defined a RISC-V specific system call to
- * flush the instruction cache.
- *
- * __NR_riscv_flush_icache is defined to flush the instruction cache over an
- * address range, with the flush applying to either all threads or just the
- * caller. We don't currently do anything with the address range, that's just
- * in there for forwards compatibility.
- */
-#ifndef __NR_riscv_flush_icache
-#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
-#endif
-__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
-
-/*
- * Allows userspace to query the kernel for CPU architecture and
- * microarchitecture details across a given set of CPUs.
- */
-#ifndef __NR_riscv_hwprobe
-#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14)
+#if __BITS_PER_LONG == 64
+#include <asm/unistd_64.h>
+#else
+#include <asm/unistd_32.h>
#endif
-__SYSCALL(__NR_riscv_hwprobe, sys_riscv_hwprobe)
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 81d94a8ee10f..5b243d46f4b1 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_RISCV_MISALIGNED) += unaligned_access_speed.o
obj-$(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS) += copy-unaligned.o
obj-$(CONFIG_FPU) += fpu.o
+obj-$(CONFIG_FPU) += kernel_mode_fpu.o
obj-$(CONFIG_RISCV_ISA_V) += vector.o
obj-$(CONFIG_RISCV_ISA_V) += kernel_mode_vector.o
obj-$(CONFIG_SMP) += smpboot.o
diff --git a/arch/riscv/kernel/Makefile.syscalls b/arch/riscv/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..52087a023b3d
--- /dev/null
+++ b/arch/riscv/kernel/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += riscv memfd_secret
+syscall_abis_64 += riscv newstat rlimit memfd_secret
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index a03129f40c46..b09ca5f944f7 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -9,6 +9,7 @@
#include <linux/kbuild.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/ftrace.h>
#include <linux/suspend.h>
#include <asm/kvm_host.h>
#include <asm/thread_info.h>
@@ -488,4 +489,21 @@ void asm_offsets(void)
DEFINE(STACKFRAME_SIZE_ON_STACK, ALIGN(sizeof(struct stackframe), STACK_ALIGN));
OFFSET(STACKFRAME_FP, stackframe, fp);
OFFSET(STACKFRAME_RA, stackframe, ra);
+
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
+ DEFINE(FREGS_SIZE_ON_STACK, ALIGN(sizeof(struct ftrace_regs), STACK_ALIGN));
+ DEFINE(FREGS_EPC, offsetof(struct ftrace_regs, epc));
+ DEFINE(FREGS_RA, offsetof(struct ftrace_regs, ra));
+ DEFINE(FREGS_SP, offsetof(struct ftrace_regs, sp));
+ DEFINE(FREGS_S0, offsetof(struct ftrace_regs, s0));
+ DEFINE(FREGS_T1, offsetof(struct ftrace_regs, t1));
+ DEFINE(FREGS_A0, offsetof(struct ftrace_regs, a0));
+ DEFINE(FREGS_A1, offsetof(struct ftrace_regs, a1));
+ DEFINE(FREGS_A2, offsetof(struct ftrace_regs, a2));
+ DEFINE(FREGS_A3, offsetof(struct ftrace_regs, a3));
+ DEFINE(FREGS_A4, offsetof(struct ftrace_regs, a4));
+ DEFINE(FREGS_A5, offsetof(struct ftrace_regs, a5));
+ DEFINE(FREGS_A6, offsetof(struct ftrace_regs, a6));
+ DEFINE(FREGS_A7, offsetof(struct ftrace_regs, a7));
+#endif
}
diff --git a/arch/riscv/kernel/compat_syscall_table.c b/arch/riscv/kernel/compat_syscall_table.c
index ad7f2d712f5f..e884c069e88f 100644
--- a/arch/riscv/kernel/compat_syscall_table.c
+++ b/arch/riscv/kernel/compat_syscall_table.c
@@ -8,9 +8,11 @@
#include <asm-generic/syscalls.h>
#include <asm/syscall.h>
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat)
+
#undef __SYSCALL
#define __SYSCALL(nr, call) asmlinkage long __riscv_##call(const struct pt_regs *);
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = __riscv_##call,
@@ -19,5 +21,5 @@ asmlinkage long compat_sys_rt_sigreturn(void);
void * const compat_sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = __riscv_sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile
index 3df4cb788c1f..24e37d1ef7ec 100644
--- a/arch/riscv/kernel/compat_vdso/Makefile
+++ b/arch/riscv/kernel/compat_vdso/Makefile
@@ -34,12 +34,6 @@ obj-compat_vdso := $(addprefix $(obj)/, $(obj-compat_vdso))
obj-y += compat_vdso.o
CPPFLAGS_compat_vdso.lds += -P -C -DCOMPAT_VDSO -U$(ARCH)
-# Disable profiling and instrumentation for VDSO code
-GCOV_PROFILE := n
-KCOV_INSTRUMENT := n
-KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
-
# Force dependency
$(obj)/compat_vdso.o: $(obj)/compat_vdso.so
@@ -58,7 +52,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
# Generate VDSO offsets using helper script
-gen-compat_vdsosym := $(srctree)/$(src)/gen_compat_vdso_offsets.sh
+gen-compat_vdsosym := $(src)/gen_compat_vdso_offsets.sh
quiet_cmd_compat_vdsosym = VDSOSYM $@
cmd_compat_vdsosym = $(NM) $< | $(gen-compat_vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index d11d6320fb0d..c1f3655238fd 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -139,6 +139,34 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
return -1;
}
+unsigned long __init riscv_get_marchid(void)
+{
+ struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
+
+#if IS_ENABLED(CONFIG_RISCV_SBI)
+ ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
+ ci->marchid = csr_read(CSR_MARCHID);
+#else
+ ci->marchid = 0;
+#endif
+ return ci->marchid;
+}
+
+unsigned long __init riscv_get_mvendorid(void)
+{
+ struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
+
+#if IS_ENABLED(CONFIG_RISCV_SBI)
+ ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
+ ci->mvendorid = csr_read(CSR_MVENDORID);
+#else
+ ci->mvendorid = 0;
+#endif
+ return ci->mvendorid;
+}
+
DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
@@ -170,12 +198,16 @@ static int riscv_cpuinfo_starting(unsigned int cpu)
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
#if IS_ENABLED(CONFIG_RISCV_SBI)
- ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
- ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
+ if (!ci->mvendorid)
+ ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
+ if (!ci->marchid)
+ ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
- ci->mvendorid = csr_read(CSR_MVENDORID);
- ci->marchid = csr_read(CSR_MARCHID);
+ if (!ci->mvendorid)
+ ci->mvendorid = csr_read(CSR_MVENDORID);
+ if (!ci->marchid)
+ ci->marchid = csr_read(CSR_MARCHID);
ci->mimpid = csr_read(CSR_MIMPID);
#else
ci->mvendorid = 0;
diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
index 1cc7df740edd..e6fbaaf54956 100644
--- a/arch/riscv/kernel/cpu_ops_sbi.c
+++ b/arch/riscv/kernel/cpu_ops_sbi.c
@@ -72,7 +72,7 @@ static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
/* Make sure tidle is updated */
smp_mb();
bdata->task_ptr = tidle;
- bdata->stack_ptr = task_stack_page(tidle) + THREAD_SIZE;
+ bdata->stack_ptr = task_pt_regs(tidle);
/* Make sure boot data is updated */
smp_mb();
hsm_data = __pa(bdata);
diff --git a/arch/riscv/kernel/cpu_ops_spinwait.c b/arch/riscv/kernel/cpu_ops_spinwait.c
index 613872b0a21a..24869eb88908 100644
--- a/arch/riscv/kernel/cpu_ops_spinwait.c
+++ b/arch/riscv/kernel/cpu_ops_spinwait.c
@@ -34,8 +34,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
/* Make sure tidle is updated */
smp_mb();
- WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid],
- task_stack_page(tidle) + THREAD_SIZE);
+ WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid], task_pt_regs(tidle));
WRITE_ONCE(__cpu_spinwait_task_pointer[hartid], tidle);
}
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 3ed2359eae35..0366dc3baf33 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -72,51 +72,89 @@ bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, unsigned i
}
EXPORT_SYMBOL_GPL(__riscv_isa_extension_available);
-static bool riscv_isa_extension_check(int id)
+static int riscv_ext_zicbom_validate(const struct riscv_isa_ext_data *data,
+ const unsigned long *isa_bitmap)
{
- switch (id) {
- case RISCV_ISA_EXT_ZICBOM:
- if (!riscv_cbom_block_size) {
- pr_err("Zicbom detected in ISA string, disabling as no cbom-block-size found\n");
- return false;
- } else if (!is_power_of_2(riscv_cbom_block_size)) {
- pr_err("Zicbom disabled as cbom-block-size present, but is not a power-of-2\n");
- return false;
- }
- return true;
- case RISCV_ISA_EXT_ZICBOZ:
- if (!riscv_cboz_block_size) {
- pr_err("Zicboz detected in ISA string, disabling as no cboz-block-size found\n");
- return false;
- } else if (!is_power_of_2(riscv_cboz_block_size)) {
- pr_err("Zicboz disabled as cboz-block-size present, but is not a power-of-2\n");
- return false;
- }
- return true;
- case RISCV_ISA_EXT_INVALID:
- return false;
+ if (!riscv_cbom_block_size) {
+ pr_err("Zicbom detected in ISA string, disabling as no cbom-block-size found\n");
+ return -EINVAL;
+ }
+ if (!is_power_of_2(riscv_cbom_block_size)) {
+ pr_err("Zicbom disabled as cbom-block-size present, but is not a power-of-2\n");
+ return -EINVAL;
}
+ return 0;
+}
- return true;
+static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
+ const unsigned long *isa_bitmap)
+{
+ if (!riscv_cboz_block_size) {
+ pr_err("Zicboz detected in ISA string, disabling as no cboz-block-size found\n");
+ return -EINVAL;
+ }
+ if (!is_power_of_2(riscv_cboz_block_size)) {
+ pr_err("Zicboz disabled as cboz-block-size present, but is not a power-of-2\n");
+ return -EINVAL;
+ }
+ return 0;
}
-#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size) { \
- .name = #_name, \
- .property = #_name, \
- .id = _id, \
- .subset_ext_ids = _subset_exts, \
- .subset_ext_size = _subset_exts_size \
+#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \
+ .name = #_name, \
+ .property = #_name, \
+ .id = _id, \
+ .subset_ext_ids = _subset_exts, \
+ .subset_ext_size = _subset_exts_size, \
+ .validate = _validate \
}
-#define __RISCV_ISA_EXT_DATA(_name, _id) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0)
+#define __RISCV_ISA_EXT_DATA(_name, _id) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, NULL)
+
+#define __RISCV_ISA_EXT_DATA_VALIDATE(_name, _id, _validate) \
+ _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, _validate)
/* Used to declare pure "lasso" extension (Zk for instance) */
#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \
- _RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, ARRAY_SIZE(_bundled_exts))
+ _RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
+ ARRAY_SIZE(_bundled_exts), NULL)
/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */
#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \
- _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts))
+ _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), NULL)
+#define __RISCV_ISA_EXT_SUPERSET_VALIDATE(_name, _id, _sub_exts, _validate) \
+ _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate)
+
+static int riscv_ext_zca_depends(const struct riscv_isa_ext_data *data,
+ const unsigned long *isa_bitmap)
+{
+ if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZCA))
+ return 0;
+
+ return -EPROBE_DEFER;
+}
+static int riscv_ext_zcd_validate(const struct riscv_isa_ext_data *data,
+ const unsigned long *isa_bitmap)
+{
+ if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZCA) &&
+ __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_d))
+ return 0;
+
+ return -EPROBE_DEFER;
+}
+
+static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data,
+ const unsigned long *isa_bitmap)
+{
+ if (IS_ENABLED(CONFIG_64BIT))
+ return -EINVAL;
+
+ if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZCA) &&
+ __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_f))
+ return 0;
+
+ return -EPROBE_DEFER;
+}
static const unsigned int riscv_zk_bundled_exts[] = {
RISCV_ISA_EXT_ZBKB,
@@ -188,6 +226,40 @@ static const unsigned int riscv_zvbb_exts[] = {
RISCV_ISA_EXT_ZVKB
};
+#define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \
+ RISCV_ISA_EXT_ZVE64X, \
+ RISCV_ISA_EXT_ZVE32F, \
+ RISCV_ISA_EXT_ZVE32X
+
+#define RISCV_ISA_EXT_ZVE64D_IMPLY_LIST \
+ RISCV_ISA_EXT_ZVE64F, \
+ RISCV_ISA_EXT_ZVE64F_IMPLY_LIST
+
+#define RISCV_ISA_EXT_V_IMPLY_LIST \
+ RISCV_ISA_EXT_ZVE64D, \
+ RISCV_ISA_EXT_ZVE64D_IMPLY_LIST
+
+static const unsigned int riscv_zve32f_exts[] = {
+ RISCV_ISA_EXT_ZVE32X
+};
+
+static const unsigned int riscv_zve64f_exts[] = {
+ RISCV_ISA_EXT_ZVE64F_IMPLY_LIST
+};
+
+static const unsigned int riscv_zve64d_exts[] = {
+ RISCV_ISA_EXT_ZVE64D_IMPLY_LIST
+};
+
+static const unsigned int riscv_v_exts[] = {
+ RISCV_ISA_EXT_V_IMPLY_LIST
+};
+
+static const unsigned int riscv_zve64x_exts[] = {
+ RISCV_ISA_EXT_ZVE32X,
+ RISCV_ISA_EXT_ZVE64X
+};
+
/*
* While the [ms]envcfg CSRs were not defined until version 1.12 of the RISC-V
* privileged ISA, the existence of the CSRs is implied by any extension which
@@ -199,6 +271,21 @@ static const unsigned int riscv_xlinuxenvcfg_exts[] = {
};
/*
+ * Zc* spec states that:
+ * - C always implies Zca
+ * - C+F implies Zcf (RV32 only)
+ * - C+D implies Zcd
+ *
+ * These extensions will be enabled and then validated depending on the
+ * availability of F/D RV32.
+ */
+static const unsigned int riscv_c_exts[] = {
+ RISCV_ISA_EXT_ZCA,
+ RISCV_ISA_EXT_ZCF,
+ RISCV_ISA_EXT_ZCD,
+};
+
+/*
* The canonical order of ISA extension names in the ISA string is defined in
* chapter 27 of the unprivileged specification.
*
@@ -244,11 +331,13 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(f, RISCV_ISA_EXT_f),
__RISCV_ISA_EXT_DATA(d, RISCV_ISA_EXT_d),
__RISCV_ISA_EXT_DATA(q, RISCV_ISA_EXT_q),
- __RISCV_ISA_EXT_DATA(c, RISCV_ISA_EXT_c),
- __RISCV_ISA_EXT_DATA(v, RISCV_ISA_EXT_v),
+ __RISCV_ISA_EXT_SUPERSET(c, RISCV_ISA_EXT_c, riscv_c_exts),
+ __RISCV_ISA_EXT_SUPERSET(v, RISCV_ISA_EXT_v, riscv_v_exts),
__RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
- __RISCV_ISA_EXT_SUPERSET(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts),
- __RISCV_ISA_EXT_SUPERSET(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts),
+ __RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts,
+ riscv_ext_zicbom_validate),
+ __RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts,
+ riscv_ext_zicboz_validate),
__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
__RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR),
@@ -256,10 +345,17 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(zihintntl, RISCV_ISA_EXT_ZIHINTNTL),
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
__RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
+ __RISCV_ISA_EXT_DATA(zimop, RISCV_ISA_EXT_ZIMOP),
__RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
+ __RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
__RISCV_ISA_EXT_DATA(zfa, RISCV_ISA_EXT_ZFA),
__RISCV_ISA_EXT_DATA(zfh, RISCV_ISA_EXT_ZFH),
__RISCV_ISA_EXT_DATA(zfhmin, RISCV_ISA_EXT_ZFHMIN),
+ __RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
+ __RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends),
+ __RISCV_ISA_EXT_DATA_VALIDATE(zcd, RISCV_ISA_EXT_ZCD, riscv_ext_zcd_validate),
+ __RISCV_ISA_EXT_DATA_VALIDATE(zcf, RISCV_ISA_EXT_ZCF, riscv_ext_zcf_validate),
+ __RISCV_ISA_EXT_DATA_VALIDATE(zcmop, RISCV_ISA_EXT_ZCMOP, riscv_ext_zca_depends),
__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
@@ -280,6 +376,11 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO),
__RISCV_ISA_EXT_SUPERSET(zvbb, RISCV_ISA_EXT_ZVBB, riscv_zvbb_exts),
__RISCV_ISA_EXT_DATA(zvbc, RISCV_ISA_EXT_ZVBC),
+ __RISCV_ISA_EXT_SUPERSET(zve32f, RISCV_ISA_EXT_ZVE32F, riscv_zve32f_exts),
+ __RISCV_ISA_EXT_DATA(zve32x, RISCV_ISA_EXT_ZVE32X),
+ __RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts),
+ __RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts),
+ __RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts),
__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
__RISCV_ISA_EXT_DATA(zvkb, RISCV_ISA_EXT_ZVKB),
@@ -309,33 +410,93 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
-static void __init match_isa_ext(const struct riscv_isa_ext_data *ext, const char *name,
- const char *name_end, struct riscv_isainfo *isainfo)
+static void riscv_isa_set_ext(const struct riscv_isa_ext_data *ext, unsigned long *bitmap)
{
- if ((name_end - name == strlen(ext->name)) &&
- !strncasecmp(name, ext->name, name_end - name)) {
- /*
- * If this is a bundle, enable all the ISA extensions that
- * comprise the bundle.
- */
- if (ext->subset_ext_size) {
- for (int i = 0; i < ext->subset_ext_size; i++) {
- if (riscv_isa_extension_check(ext->subset_ext_ids[i]))
- set_bit(ext->subset_ext_ids[i], isainfo->isa);
+ if (ext->id != RISCV_ISA_EXT_INVALID)
+ set_bit(ext->id, bitmap);
+
+ for (int i = 0; i < ext->subset_ext_size; i++) {
+ if (ext->subset_ext_ids[i] != RISCV_ISA_EXT_INVALID)
+ set_bit(ext->subset_ext_ids[i], bitmap);
+ }
+}
+
+static const struct riscv_isa_ext_data *riscv_get_isa_ext_data(unsigned int ext_id)
+{
+ for (int i = 0; i < riscv_isa_ext_count; i++) {
+ if (riscv_isa_ext[i].id == ext_id)
+ return &riscv_isa_ext[i];
+ }
+
+ return NULL;
+}
+
+/*
+ * "Resolve" a source ISA bitmap into one that matches kernel configuration as
+ * well as correct extension dependencies. Some extensions depends on specific
+ * kernel configuration to be usable (V needs CONFIG_RISCV_ISA_V for instance)
+ * and this function will actually validate all the extensions provided in
+ * source_isa into the resolved_isa based on extensions validate() callbacks.
+ */
+static void __init riscv_resolve_isa(unsigned long *source_isa,
+ unsigned long *resolved_isa, unsigned long *this_hwcap,
+ unsigned long *isa2hwcap)
+{
+ bool loop;
+ const struct riscv_isa_ext_data *ext;
+ DECLARE_BITMAP(prev_resolved_isa, RISCV_ISA_EXT_MAX);
+ int max_loop_count = riscv_isa_ext_count, ret;
+ unsigned int bit;
+
+ do {
+ loop = false;
+ if (max_loop_count-- < 0) {
+ pr_err("Failed to reach a stable ISA state\n");
+ return;
+ }
+ bitmap_copy(prev_resolved_isa, resolved_isa, RISCV_ISA_EXT_MAX);
+ for_each_set_bit(bit, source_isa, RISCV_ISA_EXT_MAX) {
+ ext = riscv_get_isa_ext_data(bit);
+ if (!ext)
+ continue;
+
+ if (ext->validate) {
+ ret = ext->validate(ext, resolved_isa);
+ if (ret == -EPROBE_DEFER) {
+ loop = true;
+ continue;
+ } else if (ret) {
+ /* Disable the extension entirely */
+ clear_bit(ext->id, source_isa);
+ continue;
+ }
}
+
+ set_bit(ext->id, resolved_isa);
+ /* No need to keep it in source isa now that it is enabled */
+ clear_bit(ext->id, source_isa);
+
+ /* Single letter extensions get set in hwcap */
+ if (ext->id < RISCV_ISA_EXT_BASE)
+ *this_hwcap |= isa2hwcap[ext->id];
}
+ } while (loop && memcmp(prev_resolved_isa, resolved_isa, sizeof(prev_resolved_isa)));
+}
- /*
- * This is valid even for bundle extensions which uses the RISCV_ISA_EXT_INVALID id
- * (rejected by riscv_isa_extension_check()).
- */
- if (riscv_isa_extension_check(ext->id))
- set_bit(ext->id, isainfo->isa);
+static void __init match_isa_ext(const char *name, const char *name_end, unsigned long *bitmap)
+{
+ for (int i = 0; i < riscv_isa_ext_count; i++) {
+ const struct riscv_isa_ext_data *ext = &riscv_isa_ext[i];
+
+ if ((name_end - name == strlen(ext->name)) &&
+ !strncasecmp(name, ext->name, name_end - name)) {
+ riscv_isa_set_ext(ext, bitmap);
+ break;
+ }
}
}
-static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct riscv_isainfo *isainfo,
- unsigned long *isa2hwcap, const char *isa)
+static void __init riscv_parse_isa_string(const char *isa, unsigned long *bitmap)
{
/*
* For all possible cpus, we have already validated in
@@ -348,7 +509,7 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
while (*isa) {
const char *ext = isa++;
const char *ext_end = isa;
- bool ext_long = false, ext_err = false;
+ bool ext_err = false;
switch (*ext) {
case 's':
@@ -388,7 +549,6 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
* character itself while eliminating the extensions version number.
* A simple re-increment solves this problem.
*/
- ext_long = true;
for (; *isa && *isa != '_'; ++isa)
if (unlikely(!isalnum(*isa)))
ext_err = true;
@@ -468,17 +628,8 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
if (unlikely(ext_err))
continue;
- if (!ext_long) {
- int nr = tolower(*ext) - 'a';
- if (riscv_isa_extension_check(nr)) {
- *this_hwcap |= isa2hwcap[nr];
- set_bit(nr, isainfo->isa);
- }
- } else {
- for (int i = 0; i < riscv_isa_ext_count; i++)
- match_isa_ext(&riscv_isa_ext[i], ext, ext_end, isainfo);
- }
+ match_isa_ext(ext, ext_end, bitmap);
}
}
@@ -490,6 +641,8 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
struct acpi_table_header *rhct;
acpi_status status;
unsigned int cpu;
+ u64 boot_vendorid;
+ u64 boot_archid;
if (!acpi_disabled) {
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
@@ -497,9 +650,13 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
return;
}
+ boot_vendorid = riscv_get_mvendorid();
+ boot_archid = riscv_get_marchid();
+
for_each_possible_cpu(cpu) {
struct riscv_isainfo *isainfo = &hart_isa[cpu];
unsigned long this_hwcap = 0;
+ DECLARE_BITMAP(source_isa, RISCV_ISA_EXT_MAX) = { 0 };
if (acpi_disabled) {
node = of_cpu_device_node_get(cpu);
@@ -522,7 +679,7 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
}
}
- riscv_parse_isa_string(&this_hwcap, isainfo, isa2hwcap, isa);
+ riscv_parse_isa_string(isa, source_isa);
/*
* These ones were as they were part of the base ISA when the
@@ -530,10 +687,10 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
* unconditionally where `i` is in riscv,isa on DT systems.
*/
if (acpi_disabled) {
- set_bit(RISCV_ISA_EXT_ZICSR, isainfo->isa);
- set_bit(RISCV_ISA_EXT_ZIFENCEI, isainfo->isa);
- set_bit(RISCV_ISA_EXT_ZICNTR, isainfo->isa);
- set_bit(RISCV_ISA_EXT_ZIHPM, isainfo->isa);
+ set_bit(RISCV_ISA_EXT_ZICSR, source_isa);
+ set_bit(RISCV_ISA_EXT_ZIFENCEI, source_isa);
+ set_bit(RISCV_ISA_EXT_ZICNTR, source_isa);
+ set_bit(RISCV_ISA_EXT_ZIHPM, source_isa);
}
/*
@@ -544,12 +701,13 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
* CPU cores with the ratified spec will contain non-zero
* marchid.
*/
- if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
- riscv_cached_marchid(cpu) == 0x0) {
+ if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
- clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
+ clear_bit(RISCV_ISA_EXT_v, source_isa);
}
+ riscv_resolve_isa(source_isa, isainfo->isa, &this_hwcap, isa2hwcap);
+
/*
* All "okay" hart should have same isa. Set HWCAP based on
* common capabilities of every "okay" hart, in case they don't
@@ -578,6 +736,7 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
unsigned long this_hwcap = 0;
struct device_node *cpu_node;
struct riscv_isainfo *isainfo = &hart_isa[cpu];
+ DECLARE_BITMAP(source_isa, RISCV_ISA_EXT_MAX) = { 0 };
cpu_node = of_cpu_device_node_get(cpu);
if (!cpu_node) {
@@ -597,22 +756,11 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
ext->property) < 0)
continue;
- if (ext->subset_ext_size) {
- for (int j = 0; j < ext->subset_ext_size; j++) {
- if (riscv_isa_extension_check(ext->subset_ext_ids[i]))
- set_bit(ext->subset_ext_ids[j], isainfo->isa);
- }
- }
-
- if (riscv_isa_extension_check(ext->id)) {
- set_bit(ext->id, isainfo->isa);
-
- /* Only single letter extensions get set in hwcap */
- if (strnlen(riscv_isa_ext[i].name, 2) == 1)
- this_hwcap |= isa2hwcap[riscv_isa_ext[i].id];
- }
+ riscv_isa_set_ext(ext, source_isa);
}
+ riscv_resolve_isa(source_isa, isainfo->isa, &this_hwcap, isa2hwcap);
+
of_node_put(cpu_node);
/*
@@ -682,8 +830,14 @@ void __init riscv_fill_hwcap(void)
elf_hwcap &= ~COMPAT_HWCAP_ISA_F;
}
- if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
+ if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZVE32X)) {
+ /*
+ * This cannot fail when called on the boot hart
+ */
riscv_v_setup_vsize();
+ }
+
+ if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
/*
* ISA string in device tree might have 'v' flag, but
* CONFIG_RISCV_ISA_V is disabled in kernel.
diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
index 54260c16f991..11c0d2e0becf 100644
--- a/arch/riscv/kernel/elf_kexec.c
+++ b/arch/riscv/kernel/elf_kexec.c
@@ -19,6 +19,7 @@
#include <linux/libfdt.h>
#include <linux/types.h>
#include <linux/memblock.h>
+#include <linux/vmalloc.h>
#include <asm/setup.h>
int arch_kimage_file_post_load_cleanup(struct kimage *image)
diff --git a/arch/riscv/kernel/fpu.S b/arch/riscv/kernel/fpu.S
index 2c543f130f93..327cf527dd7e 100644
--- a/arch/riscv/kernel/fpu.S
+++ b/arch/riscv/kernel/fpu.S
@@ -211,7 +211,7 @@ SYM_FUNC_START(put_f64_reg)
SYM_FUNC_END(put_f64_reg)
/*
- * put_f64_reg - Get a 64 bits FP register value and returned it or store it to
+ * get_f64_reg - Get a 64 bits FP register value and returned it or store it to
* a pointer.
* a0 = FP register index to be retrieved
* a1 = If xlen == 32, pointer which should be loaded with the FP register value
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index f5aa24d9e1c1..4b95c574fd04 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -8,6 +8,7 @@
#include <linux/ftrace.h>
#include <linux/uaccess.h>
#include <linux/memory.h>
+#include <linux/stop_machine.h>
#include <asm/cacheflush.h>
#include <asm/patch.h>
@@ -75,8 +76,7 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target,
make_call_t0(hook_pos, target, call);
/* Replace the auipc-jalr pair at once. Return -EPERM on write error. */
- if (patch_text_nosync
- ((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
+ if (patch_insn_write((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
return -EPERM;
return 0;
@@ -88,7 +88,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
make_call_t0(rec->ip, addr, call);
- if (patch_text_nosync((void *)rec->ip, call, MCOUNT_INSN_SIZE))
+ if (patch_insn_write((void *)rec->ip, call, MCOUNT_INSN_SIZE))
return -EPERM;
return 0;
@@ -99,7 +99,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
{
unsigned int nops[2] = {NOP4, NOP4};
- if (patch_text_nosync((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
+ if (patch_insn_write((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
return -EPERM;
return 0;
@@ -127,16 +127,48 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
{
int ret = __ftrace_modify_call((unsigned long)&ftrace_call,
(unsigned long)func, true, true);
- if (!ret) {
- ret = __ftrace_modify_call((unsigned long)&ftrace_regs_call,
- (unsigned long)func, true, true);
- }
return ret;
}
+
+struct ftrace_modify_param {
+ int command;
+ atomic_t cpu_count;
+};
+
+static int __ftrace_modify_code(void *data)
+{
+ struct ftrace_modify_param *param = data;
+
+ if (atomic_inc_return(&param->cpu_count) == num_online_cpus()) {
+ ftrace_modify_all_code(param->command);
+ /*
+ * Make sure the patching store is effective *before* we
+ * increment the counter which releases all waiting CPUs
+ * by using the release variant of atomic increment. The
+ * release pairs with the call to local_flush_icache_all()
+ * on the waiting CPU.
+ */
+ atomic_inc_return_release(&param->cpu_count);
+ } else {
+ while (atomic_read(&param->cpu_count) <= num_online_cpus())
+ cpu_relax();
+
+ local_flush_icache_all();
+ }
+
+ return 0;
+}
+
+void arch_ftrace_update_code(int command)
+{
+ struct ftrace_modify_param param = { command, ATOMIC_INIT(0) };
+
+ stop_machine(__ftrace_modify_code, &param, cpu_online_mask);
+}
#endif
-#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
@@ -178,16 +210,13 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
}
#ifdef CONFIG_DYNAMIC_FTRACE
-#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs)
{
- struct pt_regs *regs = arch_ftrace_get_regs(fregs);
- unsigned long *parent = (unsigned long *)&regs->ra;
-
- prepare_ftrace_return(parent, ip, frame_pointer(regs));
+ prepare_ftrace_return(&fregs->ra, ip, fregs->s0);
}
-#else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
+#else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
extern void ftrace_graph_call(void);
int ftrace_enable_ftrace_graph_caller(void)
{
@@ -200,6 +229,6 @@ int ftrace_disable_ftrace_graph_caller(void)
return __ftrace_modify_call((unsigned long)&ftrace_graph_call,
(unsigned long)&prepare_ftrace_return, false, true);
}
-#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
#endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 4236a69c35cb..356d5397b2a2 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -165,10 +165,21 @@ secondary_start_sbi:
#endif
call .Lsetup_trap_vector
scs_load_current
- tail smp_callin
+ call smp_callin
#endif /* CONFIG_SMP */
.align 2
+.Lsecondary_park:
+ /*
+ * Park this hart if we:
+ * - have too many harts on CONFIG_RISCV_BOOT_SPINWAIT
+ * - receive an early trap, before setup_trap_vector finished
+ * - fail in smp_callin(), as a successful one wouldn't return
+ */
+ wfi
+ j .Lsecondary_park
+
+.align 2
.Lsetup_trap_vector:
/* Set trap vector to exception handler */
la a0, handle_exception
@@ -181,12 +192,6 @@ secondary_start_sbi:
csrw CSR_SCRATCH, zero
ret
-.align 2
-.Lsecondary_park:
- /* We lack SMP support or have too many harts, so park this hart */
- wfi
- j .Lsecondary_park
-
SYM_CODE_END(_start)
SYM_CODE_START(_start_kernel)
@@ -300,6 +305,9 @@ SYM_CODE_START(_start_kernel)
#else
mv a0, a1
#endif /* CONFIG_BUILTIN_DTB */
+ /* Set trap vector to spin forever to help debug */
+ la a3, .Lsecondary_park
+ csrw CSR_TVEC, a3
call setup_vm
#ifdef CONFIG_MMU
la a0, early_pg_dir
diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
index e6694759dbd0..11ad789c60c6 100644
--- a/arch/riscv/kernel/jump_label.c
+++ b/arch/riscv/kernel/jump_label.c
@@ -9,13 +9,14 @@
#include <linux/memory.h>
#include <linux/mutex.h>
#include <asm/bug.h>
+#include <asm/cacheflush.h>
#include <asm/patch.h>
#define RISCV_INSN_NOP 0x00000013U
#define RISCV_INSN_JAL 0x0000006fU
-void arch_jump_label_transform(struct jump_entry *entry,
- enum jump_label_type type)
+bool arch_jump_label_transform_queue(struct jump_entry *entry,
+ enum jump_label_type type)
{
void *addr = (void *)jump_entry_code(entry);
u32 insn;
@@ -24,7 +25,7 @@ void arch_jump_label_transform(struct jump_entry *entry,
long offset = jump_entry_target(entry) - jump_entry_code(entry);
if (WARN_ON(offset & 1 || offset < -524288 || offset >= 524288))
- return;
+ return true;
insn = RISCV_INSN_JAL |
(((u32)offset & GENMASK(19, 12)) << (12 - 12)) |
@@ -36,6 +37,13 @@ void arch_jump_label_transform(struct jump_entry *entry,
}
mutex_lock(&text_mutex);
- patch_text_nosync(addr, &insn, sizeof(insn));
+ patch_insn_write(addr, &insn, sizeof(insn));
mutex_unlock(&text_mutex);
+
+ return true;
+}
+
+void arch_jump_label_transform_apply(void)
+{
+ flush_icache_all();
}
diff --git a/arch/riscv/kernel/kernel_mode_fpu.c b/arch/riscv/kernel/kernel_mode_fpu.c
new file mode 100644
index 000000000000..0ac8348876c4
--- /dev/null
+++ b/arch/riscv/kernel/kernel_mode_fpu.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 SiFive
+ */
+
+#include <linux/export.h>
+#include <linux/preempt.h>
+
+#include <asm/csr.h>
+#include <asm/fpu.h>
+#include <asm/processor.h>
+#include <asm/switch_to.h>
+
+void kernel_fpu_begin(void)
+{
+ preempt_disable();
+ fstate_save(current, task_pt_regs(current));
+ csr_set(CSR_SSTATUS, SR_FS);
+}
+EXPORT_SYMBOL_GPL(kernel_fpu_begin);
+
+void kernel_fpu_end(void)
+{
+ csr_clear(CSR_SSTATUS, SR_FS);
+ fstate_restore(current, task_pt_regs(current));
+ preempt_enable();
+}
+EXPORT_SYMBOL_GPL(kernel_fpu_end);
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index ed9cad20c039..3c830a6f7ef4 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -121,20 +121,12 @@ static void machine_kexec_mask_interrupts(void)
for_each_irq_desc(i, desc) {
struct irq_chip *chip;
- int ret;
chip = irq_desc_get_chip(desc);
if (!chip)
continue;
- /*
- * First try to remove the active state. If this
- * fails, try to EOI the interrupt.
- */
- ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
- if (ret && irqd_irq_inprogress(&desc->irq_data) &&
- chip->irq_eoi)
+ if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);
if (chip->irq_mask)
diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S
index b7561288e8da..745dd4c4a69c 100644
--- a/arch/riscv/kernel/mcount-dyn.S
+++ b/arch/riscv/kernel/mcount-dyn.S
@@ -56,138 +56,77 @@
addi sp, sp, ABI_SIZE_ON_STACK
.endm
-#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
/**
-* SAVE_ABI_REGS - save regs against the pt_regs struct
-*
-* @all: tell if saving all the regs
-*
-* If all is set, all the regs will be saved, otherwise only ABI
-* related regs (a0-a7,epc,ra and optional s0) will be saved.
+* SAVE_ABI_REGS - save regs against the ftrace_regs struct
*
* After the stack is established,
*
* 0(sp) stores the PC of the traced function which can be accessed
-* by &(fregs)->regs->epc in tracing function. Note that the real
+* by &(fregs)->epc in tracing function. Note that the real
* function entry address should be computed with -FENTRY_RA_OFFSET.
*
* 8(sp) stores the function return address (i.e. parent IP) that
-* can be accessed by &(fregs)->regs->ra in tracing function.
+* can be accessed by &(fregs)->ra in tracing function.
*
* The other regs are saved at the respective localtion and accessed
-* by the respective pt_regs member.
+* by the respective ftrace_regs member.
*
* Here is the layout of stack for your reference.
*
* PT_SIZE_ON_STACK -> +++++++++
* + ..... +
-* + t3-t6 +
-* + s2-s11+
* + a0-a7 + --++++-> ftrace_caller saved
-* + s1 + +
-* + s0 + --+
-* + t0-t2 + +
-* + tp + +
-* + gp + +
+* + t1 + --++++-> direct tramp address
+* + s0 + --+ // frame pointer
* + sp + +
* + ra + --+ // parent IP
* sp -> + epc + --+ // PC
* +++++++++
**/
- .macro SAVE_ABI_REGS, all=0
- addi sp, sp, -PT_SIZE_ON_STACK
-
- REG_S t0, PT_EPC(sp)
- REG_S x1, PT_RA(sp)
-
- // save the ABI regs
-
- REG_S x10, PT_A0(sp)
- REG_S x11, PT_A1(sp)
- REG_S x12, PT_A2(sp)
- REG_S x13, PT_A3(sp)
- REG_S x14, PT_A4(sp)
- REG_S x15, PT_A5(sp)
- REG_S x16, PT_A6(sp)
- REG_S x17, PT_A7(sp)
-
- // save the leftover regs
+ .macro SAVE_ABI_REGS
+ mv t4, sp // Save original SP in T4
+ addi sp, sp, -FREGS_SIZE_ON_STACK
- .if \all == 1
- REG_S x2, PT_SP(sp)
- REG_S x3, PT_GP(sp)
- REG_S x4, PT_TP(sp)
- REG_S x5, PT_T0(sp)
- REG_S x6, PT_T1(sp)
- REG_S x7, PT_T2(sp)
- REG_S x8, PT_S0(sp)
- REG_S x9, PT_S1(sp)
- REG_S x18, PT_S2(sp)
- REG_S x19, PT_S3(sp)
- REG_S x20, PT_S4(sp)
- REG_S x21, PT_S5(sp)
- REG_S x22, PT_S6(sp)
- REG_S x23, PT_S7(sp)
- REG_S x24, PT_S8(sp)
- REG_S x25, PT_S9(sp)
- REG_S x26, PT_S10(sp)
- REG_S x27, PT_S11(sp)
- REG_S x28, PT_T3(sp)
- REG_S x29, PT_T4(sp)
- REG_S x30, PT_T5(sp)
- REG_S x31, PT_T6(sp)
-
- // save s0 if FP_TEST defined
-
- .else
+ REG_S t0, FREGS_EPC(sp)
+ REG_S x1, FREGS_RA(sp)
+ REG_S t4, FREGS_SP(sp) // Put original SP on stack
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
- REG_S x8, PT_S0(sp)
+ REG_S x8, FREGS_S0(sp)
#endif
- .endif
+ REG_S x6, FREGS_T1(sp)
+
+ // save the arguments
+ REG_S x10, FREGS_A0(sp)
+ REG_S x11, FREGS_A1(sp)
+ REG_S x12, FREGS_A2(sp)
+ REG_S x13, FREGS_A3(sp)
+ REG_S x14, FREGS_A4(sp)
+ REG_S x15, FREGS_A5(sp)
+ REG_S x16, FREGS_A6(sp)
+ REG_S x17, FREGS_A7(sp)
.endm
.macro RESTORE_ABI_REGS, all=0
- REG_L t0, PT_EPC(sp)
- REG_L x1, PT_RA(sp)
- REG_L x10, PT_A0(sp)
- REG_L x11, PT_A1(sp)
- REG_L x12, PT_A2(sp)
- REG_L x13, PT_A3(sp)
- REG_L x14, PT_A4(sp)
- REG_L x15, PT_A5(sp)
- REG_L x16, PT_A6(sp)
- REG_L x17, PT_A7(sp)
-
- .if \all == 1
- REG_L x2, PT_SP(sp)
- REG_L x3, PT_GP(sp)
- REG_L x4, PT_TP(sp)
- REG_L x6, PT_T1(sp)
- REG_L x7, PT_T2(sp)
- REG_L x8, PT_S0(sp)
- REG_L x9, PT_S1(sp)
- REG_L x18, PT_S2(sp)
- REG_L x19, PT_S3(sp)
- REG_L x20, PT_S4(sp)
- REG_L x21, PT_S5(sp)
- REG_L x22, PT_S6(sp)
- REG_L x23, PT_S7(sp)
- REG_L x24, PT_S8(sp)
- REG_L x25, PT_S9(sp)
- REG_L x26, PT_S10(sp)
- REG_L x27, PT_S11(sp)
- REG_L x28, PT_T3(sp)
- REG_L x29, PT_T4(sp)
- REG_L x30, PT_T5(sp)
- REG_L x31, PT_T6(sp)
-
- .else
+ REG_L t0, FREGS_EPC(sp)
+ REG_L x1, FREGS_RA(sp)
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
- REG_L x8, PT_S0(sp)
+ REG_L x8, FREGS_S0(sp)
#endif
- .endif
- addi sp, sp, PT_SIZE_ON_STACK
+ REG_L x6, FREGS_T1(sp)
+
+ // restore the arguments
+ REG_L x10, FREGS_A0(sp)
+ REG_L x11, FREGS_A1(sp)
+ REG_L x12, FREGS_A2(sp)
+ REG_L x13, FREGS_A3(sp)
+ REG_L x14, FREGS_A4(sp)
+ REG_L x15, FREGS_A5(sp)
+ REG_L x16, FREGS_A6(sp)
+ REG_L x17, FREGS_A7(sp)
+
+ addi sp, sp, FREGS_SIZE_ON_STACK
.endm
.macro PREPARE_ARGS
@@ -198,9 +137,9 @@
mv a3, sp
.endm
-#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
-#ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+#ifndef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
SYM_FUNC_START(ftrace_caller)
SAVE_ABI
@@ -227,33 +166,23 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
jr t0
SYM_FUNC_END(ftrace_caller)
-#else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
-SYM_FUNC_START(ftrace_regs_caller)
+#else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
+SYM_FUNC_START(ftrace_caller)
mv t1, zero
- SAVE_ABI_REGS 1
+ SAVE_ABI_REGS
PREPARE_ARGS
-SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
+SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
call ftrace_stub
- RESTORE_ABI_REGS 1
+ RESTORE_ABI_REGS
bnez t1, .Ldirect
jr t0
.Ldirect:
jr t1
-SYM_FUNC_END(ftrace_regs_caller)
-
-SYM_FUNC_START(ftrace_caller)
- SAVE_ABI_REGS 0
- PREPARE_ARGS
-
-SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
- call ftrace_stub
-
- RESTORE_ABI_REGS 0
- jr t0
SYM_FUNC_END(ftrace_caller)
-#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
+
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
SYM_CODE_START(ftrace_stub_direct_tramp)
diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 5e5a82644451..906f9a3a5d65 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/moduleloader.h>
-#include <linux/vmalloc.h>
#include <linux/sizes.h>
#include <linux/pgtable.h>
#include <asm/alternative.h>
@@ -905,17 +904,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
return 0;
}
-#if defined(CONFIG_MMU) && defined(CONFIG_64BIT)
-void *module_alloc(unsigned long size)
-{
- return __vmalloc_node_range(size, 1, MODULES_VADDR,
- MODULES_END, GFP_KERNEL,
- PAGE_KERNEL, VM_FLUSH_RESET_PERMS,
- NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-#endif
-
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
diff --git a/arch/riscv/kernel/paravirt.c b/arch/riscv/kernel/paravirt.c
index 0d6225fd3194..fa6b0339a65d 100644
--- a/arch/riscv/kernel/paravirt.c
+++ b/arch/riscv/kernel/paravirt.c
@@ -62,7 +62,7 @@ static int sbi_sta_steal_time_set_shmem(unsigned long lo, unsigned long hi,
ret = sbi_ecall(SBI_EXT_STA, SBI_EXT_STA_STEAL_TIME_SET_SHMEM,
lo, hi, flags, 0, 0, 0);
if (ret.error) {
- if (lo == SBI_STA_SHMEM_DISABLE && hi == SBI_STA_SHMEM_DISABLE)
+ if (lo == SBI_SHMEM_DISABLE && hi == SBI_SHMEM_DISABLE)
pr_warn("Failed to disable steal-time shmem");
else
pr_warn("Failed to set steal-time shmem");
@@ -84,8 +84,8 @@ static int pv_time_cpu_online(unsigned int cpu)
static int pv_time_cpu_down_prepare(unsigned int cpu)
{
- return sbi_sta_steal_time_set_shmem(SBI_STA_SHMEM_DISABLE,
- SBI_STA_SHMEM_DISABLE, 0);
+ return sbi_sta_steal_time_set_shmem(SBI_SHMEM_DISABLE,
+ SBI_SHMEM_DISABLE, 0);
}
static u64 pv_time_steal_clock(int cpu)
diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
index 30e12b310cab..69e5796fc51f 100644
--- a/arch/riscv/kernel/patch.c
+++ b/arch/riscv/kernel/patch.c
@@ -19,7 +19,7 @@
struct patch_insn {
void *addr;
u32 *insns;
- int ninsns;
+ size_t len;
atomic_t cpu_count;
};
@@ -54,7 +54,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
BUG_ON(!page);
return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
- (uintaddr & ~PAGE_MASK));
+ offset_in_page(addr));
}
static void patch_unmap(int fixmap)
@@ -65,8 +65,8 @@ NOKPROBE_SYMBOL(patch_unmap);
static int __patch_insn_set(void *addr, u8 c, size_t len)
{
+ bool across_pages = (offset_in_page(addr) + len) > PAGE_SIZE;
void *waddr = addr;
- bool across_pages = (((uintptr_t)addr & ~PAGE_MASK) + len) > PAGE_SIZE;
/*
* Only two pages can be mapped at a time for writing.
@@ -89,6 +89,14 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
memset(waddr, c, len);
+ /*
+ * We could have just patched a function that is about to be
+ * called so make sure we don't execute partially patched
+ * instructions by flushing the icache as soon as possible.
+ */
+ local_flush_icache_range((unsigned long)waddr,
+ (unsigned long)waddr + len);
+
patch_unmap(FIX_TEXT_POKE0);
if (across_pages)
@@ -102,8 +110,8 @@ NOKPROBE_SYMBOL(__patch_insn_set);
static int __patch_insn_write(void *addr, const void *insn, size_t len)
{
+ bool across_pages = (offset_in_page(addr) + len) > PAGE_SIZE;
void *waddr = addr;
- bool across_pages = (((uintptr_t) addr & ~PAGE_MASK) + len) > PAGE_SIZE;
int ret;
/*
@@ -135,6 +143,14 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
ret = copy_to_kernel_nofault(waddr, insn, len);
+ /*
+ * We could have just patched a function that is about to be
+ * called so make sure we don't execute partially patched
+ * instructions by flushing the icache as soon as possible.
+ */
+ local_flush_icache_range((unsigned long)waddr,
+ (unsigned long)waddr + len);
+
patch_unmap(FIX_TEXT_POKE0);
if (across_pages)
@@ -163,69 +179,66 @@ NOKPROBE_SYMBOL(__patch_insn_write);
static int patch_insn_set(void *addr, u8 c, size_t len)
{
- size_t patched = 0;
size_t size;
- int ret = 0;
+ int ret;
/*
* __patch_insn_set() can only work on 2 pages at a time so call it in a
* loop with len <= 2 * PAGE_SIZE.
*/
- while (patched < len && !ret) {
- size = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(addr + patched), len - patched);
- ret = __patch_insn_set(addr + patched, c, size);
-
- patched += size;
+ while (len) {
+ size = min(len, PAGE_SIZE * 2 - offset_in_page(addr));
+ ret = __patch_insn_set(addr, c, size);
+ if (ret)
+ return ret;
+
+ addr += size;
+ len -= size;
}
- return ret;
+ return 0;
}
NOKPROBE_SYMBOL(patch_insn_set);
int patch_text_set_nosync(void *addr, u8 c, size_t len)
{
- u32 *tp = addr;
int ret;
- ret = patch_insn_set(tp, c, len);
-
- if (!ret)
- flush_icache_range((uintptr_t)tp, (uintptr_t)tp + len);
+ ret = patch_insn_set(addr, c, len);
return ret;
}
NOKPROBE_SYMBOL(patch_text_set_nosync);
-static int patch_insn_write(void *addr, const void *insn, size_t len)
+int patch_insn_write(void *addr, const void *insn, size_t len)
{
- size_t patched = 0;
size_t size;
- int ret = 0;
+ int ret;
/*
* Copy the instructions to the destination address, two pages at a time
* because __patch_insn_write() can only handle len <= 2 * PAGE_SIZE.
*/
- while (patched < len && !ret) {
- size = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(addr + patched), len - patched);
- ret = __patch_insn_write(addr + patched, insn + patched, size);
-
- patched += size;
+ while (len) {
+ size = min(len, PAGE_SIZE * 2 - offset_in_page(addr));
+ ret = __patch_insn_write(addr, insn, size);
+ if (ret)
+ return ret;
+
+ addr += size;
+ insn += size;
+ len -= size;
}
- return ret;
+ return 0;
}
NOKPROBE_SYMBOL(patch_insn_write);
int patch_text_nosync(void *addr, const void *insns, size_t len)
{
- u32 *tp = addr;
int ret;
- ret = patch_insn_write(tp, insns, len);
-
- if (!ret)
- flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len);
+ ret = patch_insn_write(addr, insns, len);
return ret;
}
@@ -234,33 +247,36 @@ NOKPROBE_SYMBOL(patch_text_nosync);
static int patch_text_cb(void *data)
{
struct patch_insn *patch = data;
- unsigned long len;
- int i, ret = 0;
+ int ret = 0;
if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) {
- for (i = 0; ret == 0 && i < patch->ninsns; i++) {
- len = GET_INSN_LENGTH(patch->insns[i]);
- ret = patch_text_nosync(patch->addr + i * len,
- &patch->insns[i], len);
- }
- atomic_inc(&patch->cpu_count);
+ ret = patch_insn_write(patch->addr, patch->insns, patch->len);
+ /*
+ * Make sure the patching store is effective *before* we
+ * increment the counter which releases all waiting CPUs
+ * by using the release variant of atomic increment. The
+ * release pairs with the call to local_flush_icache_all()
+ * on the waiting CPU.
+ */
+ atomic_inc_return_release(&patch->cpu_count);
} else {
while (atomic_read(&patch->cpu_count) <= num_online_cpus())
cpu_relax();
- smp_mb();
+
+ local_flush_icache_all();
}
return ret;
}
NOKPROBE_SYMBOL(patch_text_cb);
-int patch_text(void *addr, u32 *insns, int ninsns)
+int patch_text(void *addr, u32 *insns, size_t len)
{
int ret;
struct patch_insn patch = {
.addr = addr,
.insns = insns,
- .ninsns = ninsns,
+ .len = len,
.cpu_count = ATOMIC_INIT(0),
};
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index b75f150b923d..50bc5ef7dd2f 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -17,12 +17,6 @@ KBUILD_CFLAGS += -mcmodel=medany
CFLAGS_cmdline_early.o += -D__NO_FORTIFY
CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
-GCOV_PROFILE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-UBSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-
$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
--remove-section=.note.gnu.property \
--prefix-alloc-sections=.init.pi
diff --git a/arch/riscv/kernel/probes/ftrace.c b/arch/riscv/kernel/probes/ftrace.c
index 7142ec42e889..a69dfa610aa8 100644
--- a/arch/riscv/kernel/probes/ftrace.c
+++ b/arch/riscv/kernel/probes/ftrace.c
@@ -11,6 +11,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe_ctlblk *kcb;
int bit;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index 2f08c14a933d..474a65213657 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -6,6 +6,7 @@
#include <linux/extable.h>
#include <linux/slab.h>
#include <linux/stop_machine.h>
+#include <linux/vmalloc.h>
#include <asm/ptrace.h>
#include <linux/uaccess.h>
#include <asm/sections.h>
@@ -23,14 +24,13 @@ post_kprobe_handler(struct kprobe *, struct kprobe_ctlblk *, struct pt_regs *);
static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
{
+ size_t len = GET_INSN_LENGTH(p->opcode);
u32 insn = __BUG_INSN_32;
- unsigned long offset = GET_INSN_LENGTH(p->opcode);
- p->ainsn.api.restore = (unsigned long)p->addr + offset;
+ p->ainsn.api.restore = (unsigned long)p->addr + len;
- patch_text(p->ainsn.api.insn, &p->opcode, 1);
- patch_text((void *)((unsigned long)(p->ainsn.api.insn) + offset),
- &insn, 1);
+ patch_text_nosync(p->ainsn.api.insn, &p->opcode, len);
+ patch_text_nosync(p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(insn));
}
static void __kprobes arch_prepare_simulate(struct kprobe *p)
@@ -104,29 +104,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
return 0;
}
-#ifdef CONFIG_MMU
-void *alloc_insn_page(void)
-{
- return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
- GFP_KERNEL, PAGE_KERNEL_READ_EXEC,
- VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-#endif
-
/* install breakpoint in text */
void __kprobes arch_arm_kprobe(struct kprobe *p)
{
- u32 insn = (p->opcode & __INSN_LENGTH_MASK) == __INSN_LENGTH_32 ?
- __BUG_INSN_32 : __BUG_INSN_16;
+ size_t len = GET_INSN_LENGTH(p->opcode);
+ u32 insn = len == 4 ? __BUG_INSN_32 : __BUG_INSN_16;
- patch_text(p->addr, &insn, 1);
+ patch_text(p->addr, &insn, len);
}
/* remove breakpoint from text */
void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
- patch_text(p->addr, &p->opcode, 1);
+ size_t len = GET_INSN_LENGTH(p->opcode);
+
+ patch_text(p->addr, &p->opcode, len);
}
void __kprobes arch_remove_kprobe(struct kprobe *p)
diff --git a/arch/riscv/kernel/sbi-ipi.c b/arch/riscv/kernel/sbi-ipi.c
index a4559695ce62..1026e22955cc 100644
--- a/arch/riscv/kernel/sbi-ipi.c
+++ b/arch/riscv/kernel/sbi-ipi.c
@@ -13,6 +13,9 @@
#include <linux/irqdomain.h>
#include <asm/sbi.h>
+DEFINE_STATIC_KEY_FALSE(riscv_sbi_for_rfence);
+EXPORT_SYMBOL_GPL(riscv_sbi_for_rfence);
+
static int sbi_ipi_virq;
static void sbi_ipi_handle(struct irq_desc *desc)
@@ -72,6 +75,12 @@ void __init sbi_ipi_init(void)
"irqchip/sbi-ipi:starting",
sbi_ipi_starting_cpu, NULL);
- riscv_ipi_set_virq_range(virq, BITS_PER_BYTE, false);
+ riscv_ipi_set_virq_range(virq, BITS_PER_BYTE);
pr_info("providing IPIs using SBI IPI extension\n");
+
+ /*
+ * Use the SBI remote fence extension to avoid
+ * the extra context switch needed to handle IPIs.
+ */
+ static_branch_enable(&riscv_sbi_for_rfence);
}
diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index e66e0999a800..837bdab2601b 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -14,6 +14,9 @@
#include <asm/smp.h>
#include <asm/tlbflush.h>
+#define CREATE_TRACE_POINTS
+#include <asm/trace.h>
+
/* default SBI version is 0.1 */
unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT;
EXPORT_SYMBOL(sbi_spec_version);
@@ -24,13 +27,15 @@ static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask,
unsigned long start, unsigned long size,
unsigned long arg4, unsigned long arg5) __ro_after_init;
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5)
+struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5,
+ int fid, int ext)
{
struct sbiret ret;
+ trace_sbi_call(ext, fid);
+
register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
@@ -46,9 +51,11 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
ret.error = a0;
ret.value = a1;
+ trace_sbi_return(ext, ret.error, ret.value);
+
return ret;
}
-EXPORT_SYMBOL(sbi_ecall);
+EXPORT_SYMBOL(__sbi_ecall);
int sbi_err_map_linux_errno(int err)
{
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index 45dd4035416e..8e6eb64459af 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -171,10 +171,7 @@ bool riscv_ipi_have_virq_range(void)
return (ipi_virq_base) ? true : false;
}
-DEFINE_STATIC_KEY_FALSE(riscv_ipi_for_rfence);
-EXPORT_SYMBOL_GPL(riscv_ipi_for_rfence);
-
-void riscv_ipi_set_virq_range(int virq, int nr, bool use_for_rfence)
+void riscv_ipi_set_virq_range(int virq, int nr)
{
int i, err;
@@ -197,12 +194,6 @@ void riscv_ipi_set_virq_range(int virq, int nr, bool use_for_rfence)
/* Enabled IPIs for boot CPU immediately */
riscv_ipi_enable();
-
- /* Update RFENCE static key */
- if (use_for_rfence)
- static_branch_enable(&riscv_ipi_for_rfence);
- else
- static_branch_disable(&riscv_ipi_for_rfence);
}
static const char * const ipi_names[] = {
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index d41090fc3203..19baf0d574d3 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -26,7 +26,7 @@
#include <linux/sched/task_stack.h>
#include <linux/sched/mm.h>
-#include <asm/cpufeature.h>
+#include <asm/cacheflush.h>
#include <asm/cpu_ops.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
@@ -214,6 +214,15 @@ asmlinkage __visible void smp_callin(void)
struct mm_struct *mm = &init_mm;
unsigned int curr_cpuid = smp_processor_id();
+ if (has_vector()) {
+ /*
+ * Return as early as possible so the hart with a mismatching
+ * vlen won't boot.
+ */
+ if (riscv_v_setup_vsize())
+ return;
+ }
+
/* All kernel threads share the same mm context. */
mmgrab(mm);
current->active_mm = mm;
@@ -224,19 +233,15 @@ asmlinkage __visible void smp_callin(void)
riscv_ipi_enable();
numa_add_cpu(curr_cpuid);
- set_cpu_online(curr_cpuid, 1);
-
- if (has_vector()) {
- if (riscv_v_setup_vsize())
- elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
- }
+ set_cpu_online(curr_cpuid, true);
riscv_user_isa_enable();
/*
- * Remote TLB flushes are ignored while the CPU is offline, so emit
- * a local TLB flush right now just in case.
+ * Remote cache and TLB flushes are ignored while the CPU is offline,
+ * so flush them both right now just in case.
*/
+ local_flush_icache_all();
local_flush_tlb_all();
complete(&cpu_running);
/*
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index 64a9c093aef9..10e311b2759d 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -18,10 +18,21 @@
extern asmlinkage void ret_from_exception(void);
+static inline int fp_is_valid(unsigned long fp, unsigned long sp)
+{
+ unsigned long low, high;
+
+ low = sp + sizeof(struct stackframe);
+ high = ALIGN(sp, THREAD_SIZE);
+
+ return !(fp < low || fp > high || fp & 0x07);
+}
+
void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
bool (*fn)(void *, unsigned long), void *arg)
{
unsigned long fp, sp, pc;
+ int graph_idx = 0;
int level = 0;
if (regs) {
@@ -41,26 +52,24 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
}
for (;;) {
- unsigned long low, high;
struct stackframe *frame;
if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc))))
break;
- /* Validate frame pointer */
- low = sp + sizeof(struct stackframe);
- high = ALIGN(sp, THREAD_SIZE);
- if (unlikely(fp < low || fp > high || fp & 0x7))
+ if (unlikely(!fp_is_valid(fp, sp)))
break;
+
/* Unwind stack frame */
frame = (struct stackframe *)fp - 1;
sp = fp;
- if (regs && (regs->epc == pc) && (frame->fp & 0x7)) {
+ if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
+ /* We hit function where ra is not saved on the stack */
fp = frame->ra;
pc = regs->ra;
} else {
fp = frame->fp;
- pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
+ pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
&frame->ra);
if (pc == (unsigned long)ret_from_exception) {
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
@@ -148,7 +157,7 @@ unsigned long __get_wchan(struct task_struct *task)
return pc;
}
-noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
+noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
struct task_struct *task, struct pt_regs *regs)
{
walk_stackframe(task, regs, consume_entry, cookie);
diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c
index 8a327b485b90..c8cec0cc5833 100644
--- a/arch/riscv/kernel/suspend.c
+++ b/arch/riscv/kernel/suspend.c
@@ -14,7 +14,6 @@
void suspend_save_csrs(struct suspend_context *context)
{
- context->scratch = csr_read(CSR_SCRATCH);
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
context->envcfg = csr_read(CSR_ENVCFG);
context->tvec = csr_read(CSR_TVEC);
@@ -37,7 +36,7 @@ void suspend_save_csrs(struct suspend_context *context)
void suspend_restore_csrs(struct suspend_context *context)
{
- csr_write(CSR_SCRATCH, context->scratch);
+ csr_write(CSR_SCRATCH, 0);
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
csr_write(CSR_ENVCFG, context->envcfg);
csr_write(CSR_TVEC, context->tvec);
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 8cae41a502dd..685594769535 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -8,6 +8,7 @@
#include <asm/cacheflush.h>
#include <asm/cpufeature.h>
#include <asm/hwprobe.h>
+#include <asm/processor.h>
#include <asm/sbi.h>
#include <asm/switch_to.h>
#include <asm/uaccess.h>
@@ -69,7 +70,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
if (riscv_isa_extension_available(NULL, c))
pair->value |= RISCV_HWPROBE_IMA_C;
- if (has_vector())
+ if (has_vector() && riscv_isa_extension_available(NULL, v))
pair->value |= RISCV_HWPROBE_IMA_V;
/*
@@ -111,8 +112,23 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
EXT_KEY(ZTSO);
EXT_KEY(ZACAS);
EXT_KEY(ZICOND);
+ EXT_KEY(ZIHINTPAUSE);
+ EXT_KEY(ZIMOP);
+ EXT_KEY(ZCA);
+ EXT_KEY(ZCB);
+ EXT_KEY(ZCMOP);
+ EXT_KEY(ZAWRS);
+ /*
+ * All the following extensions must depend on the kernel
+ * support of V.
+ */
if (has_vector()) {
+ EXT_KEY(ZVE32X);
+ EXT_KEY(ZVE32F);
+ EXT_KEY(ZVE64X);
+ EXT_KEY(ZVE64F);
+ EXT_KEY(ZVE64D);
EXT_KEY(ZVBB);
EXT_KEY(ZVBC);
EXT_KEY(ZVKB);
@@ -131,6 +147,8 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
EXT_KEY(ZFH);
EXT_KEY(ZFHMIN);
EXT_KEY(ZFA);
+ EXT_KEY(ZCD);
+ EXT_KEY(ZCF);
}
#undef EXT_KEY
}
@@ -215,6 +233,9 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
pair->value = riscv_cboz_block_size;
break;
+ case RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS:
+ pair->value = user_max_virt_addr();
+ break;
/*
* For forward compatibility, unknown keys don't fail the whole
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index f1c1416a9f1e..d77afe05578f 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -7,7 +7,6 @@
#include <linux/syscalls.h>
#include <asm/cacheflush.h>
-#include <asm-generic/mman-common.h>
static long riscv_sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
@@ -24,7 +23,7 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
#ifdef CONFIG_64BIT
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
- unsigned long, fd, off_t, offset)
+ unsigned long, fd, unsigned long, offset)
{
return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0);
}
@@ -33,7 +32,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
#if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
- unsigned long, fd, off_t, offset)
+ unsigned long, fd, unsigned long, offset)
{
/*
* Note that the shift for mmap2 is constant (12),
diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c
index dda913764903..6f1a36cb0f3f 100644
--- a/arch/riscv/kernel/syscall_table.c
+++ b/arch/riscv/kernel/syscall_table.c
@@ -9,14 +9,16 @@
#include <asm-generic/syscalls.h>
#include <asm/syscall.h>
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+
#undef __SYSCALL
#define __SYSCALL(nr, call) asmlinkage long __riscv_##call(const struct pt_regs *);
-#include <asm/unistd.h>
+#include <asm/syscall_table.h>
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = __riscv_##call,
void * const sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = __riscv_sys_ni_syscall,
-#include <asm/unistd.h>
+#include <asm/syscall_table.h>
};
diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
index 2adb7c3e4dd5..b62d5a2f4541 100644
--- a/arch/riscv/kernel/traps_misaligned.c
+++ b/arch/riscv/kernel/traps_misaligned.c
@@ -264,86 +264,14 @@ static unsigned long get_f32_rs(unsigned long insn, u8 fp_reg_offset,
#define GET_F32_RS2C(insn, regs) (get_f32_rs(insn, 2, regs))
#define GET_F32_RS2S(insn, regs) (get_f32_rs(RVC_RS2S(insn), 0, regs))
-#ifdef CONFIG_RISCV_M_MODE
-static inline int load_u8(struct pt_regs *regs, const u8 *addr, u8 *r_val)
-{
- u8 val;
-
- asm volatile("lbu %0, %1" : "=&r" (val) : "m" (*addr));
- *r_val = val;
-
- return 0;
-}
-
-static inline int store_u8(struct pt_regs *regs, u8 *addr, u8 val)
-{
- asm volatile ("sb %0, %1\n" : : "r" (val), "m" (*addr));
-
- return 0;
-}
-
-static inline int get_insn(struct pt_regs *regs, ulong mepc, ulong *r_insn)
-{
- register ulong __mepc asm ("a2") = mepc;
- ulong val, rvc_mask = 3, tmp;
-
- asm ("and %[tmp], %[addr], 2\n"
- "bnez %[tmp], 1f\n"
-#if defined(CONFIG_64BIT)
- __stringify(LWU) " %[insn], (%[addr])\n"
-#else
- __stringify(LW) " %[insn], (%[addr])\n"
-#endif
- "and %[tmp], %[insn], %[rvc_mask]\n"
- "beq %[tmp], %[rvc_mask], 2f\n"
- "sll %[insn], %[insn], %[xlen_minus_16]\n"
- "srl %[insn], %[insn], %[xlen_minus_16]\n"
- "j 2f\n"
- "1:\n"
- "lhu %[insn], (%[addr])\n"
- "and %[tmp], %[insn], %[rvc_mask]\n"
- "bne %[tmp], %[rvc_mask], 2f\n"
- "lhu %[tmp], 2(%[addr])\n"
- "sll %[tmp], %[tmp], 16\n"
- "add %[insn], %[insn], %[tmp]\n"
- "2:"
- : [insn] "=&r" (val), [tmp] "=&r" (tmp)
- : [addr] "r" (__mepc), [rvc_mask] "r" (rvc_mask),
- [xlen_minus_16] "i" (XLEN_MINUS_16));
-
- *r_insn = val;
-
- return 0;
-}
-#else
-static inline int load_u8(struct pt_regs *regs, const u8 *addr, u8 *r_val)
-{
- if (user_mode(regs)) {
- return __get_user(*r_val, (u8 __user *)addr);
- } else {
- *r_val = *addr;
- return 0;
- }
-}
-
-static inline int store_u8(struct pt_regs *regs, u8 *addr, u8 val)
-{
- if (user_mode(regs)) {
- return __put_user(val, (u8 __user *)addr);
- } else {
- *addr = val;
- return 0;
- }
-}
-
-#define __read_insn(regs, insn, insn_addr) \
+#define __read_insn(regs, insn, insn_addr, type) \
({ \
int __ret; \
\
if (user_mode(regs)) { \
- __ret = __get_user(insn, insn_addr); \
+ __ret = __get_user(insn, (type __user *) insn_addr); \
} else { \
- insn = *(__force u16 *)insn_addr; \
+ insn = *(type *)insn_addr; \
__ret = 0; \
} \
\
@@ -356,9 +284,8 @@ static inline int get_insn(struct pt_regs *regs, ulong epc, ulong *r_insn)
if (epc & 0x2) {
ulong tmp = 0;
- u16 __user *insn_addr = (u16 __user *)epc;
- if (__read_insn(regs, insn, insn_addr))
+ if (__read_insn(regs, insn, epc, u16))
return -EFAULT;
/* __get_user() uses regular "lw" which sign extend the loaded
* value make sure to clear higher order bits in case we "or" it
@@ -369,16 +296,14 @@ static inline int get_insn(struct pt_regs *regs, ulong epc, ulong *r_insn)
*r_insn = insn;
return 0;
}
- insn_addr++;
- if (__read_insn(regs, tmp, insn_addr))
+ epc += sizeof(u16);
+ if (__read_insn(regs, tmp, epc, u16))
return -EFAULT;
*r_insn = (tmp << 16) | insn;
return 0;
} else {
- u32 __user *insn_addr = (u32 __user *)epc;
-
- if (__read_insn(regs, insn, insn_addr))
+ if (__read_insn(regs, insn, epc, u32))
return -EFAULT;
if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) {
*r_insn = insn;
@@ -390,7 +315,6 @@ static inline int get_insn(struct pt_regs *regs, ulong epc, ulong *r_insn)
return 0;
}
}
-#endif
union reg_data {
u8 data_bytes[8];
@@ -409,7 +333,7 @@ int handle_misaligned_load(struct pt_regs *regs)
unsigned long epc = regs->epc;
unsigned long insn;
unsigned long addr = regs->badaddr;
- int i, fp = 0, shift = 0, len = 0;
+ int fp = 0, shift = 0, len = 0;
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
@@ -492,9 +416,11 @@ int handle_misaligned_load(struct pt_regs *regs)
return -EOPNOTSUPP;
val.data_u64 = 0;
- for (i = 0; i < len; i++) {
- if (load_u8(regs, (void *)(addr + i), &val.data_bytes[i]))
+ if (user_mode(regs)) {
+ if (raw_copy_from_user(&val, (u8 __user *)addr, len))
return -1;
+ } else {
+ memcpy(&val, (u8 *)addr, len);
}
if (!fp)
@@ -515,7 +441,7 @@ int handle_misaligned_store(struct pt_regs *regs)
unsigned long epc = regs->epc;
unsigned long insn;
unsigned long addr = regs->badaddr;
- int i, len = 0, fp = 0;
+ int len = 0, fp = 0;
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
@@ -588,9 +514,11 @@ int handle_misaligned_store(struct pt_regs *regs)
if (!IS_ENABLED(CONFIG_FPU) && fp)
return -EOPNOTSUPP;
- for (i = 0; i < len; i++) {
- if (store_u8(regs, (void *)(addr + i), val.data_bytes[i]))
+ if (user_mode(regs)) {
+ if (raw_copy_to_user((u8 __user *)addr, &val, len))
return -1;
+ } else {
+ memcpy((u8 *)addr, &val, len);
}
regs->epc = epc + INSN_LEN(insn);
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index 272c431ac5b9..f7ef8ad9b550 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -39,12 +39,6 @@ endif
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
CFLAGS_REMOVE_hwprobe.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
-# Disable profiling and instrumentation for VDSO code
-GCOV_PROFILE := n
-KCOV_INSTRUMENT := n
-KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
-
# Force dependency
$(obj)/vdso.o: $(obj)/vdso.so
@@ -60,7 +54,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 6727d1d3b8f2..682b3feee451 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -173,8 +173,11 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
u32 __user *epc = (u32 __user *)regs->epc;
u32 insn = (u32)regs->badaddr;
+ if (!has_vector())
+ return false;
+
/* Do not handle if V is not supported, or disabled */
- if (!(ELF_HWCAP & COMPAT_HWCAP_ISA_V))
+ if (!riscv_v_vstate_ctrl_user_allowed())
return false;
/* If V has been enabled then it is not the first-use trap */
diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile
index c9646521f113..c2cacfbc06a0 100644
--- a/arch/riscv/kvm/Makefile
+++ b/arch/riscv/kvm/Makefile
@@ -3,7 +3,7 @@
# Makefile for RISC-V KVM support
#
-ccflags-y += -I $(srctree)/$(src)
+ccflags-y += -I $(src)
include $(srctree)/virt/kvm/Makefile.kvm
diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index a944294f6f23..2967d305c442 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -10,12 +10,12 @@
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/irq.h>
+#include <linux/irqchip/riscv-imsic.h>
#include <linux/irqdomain.h>
#include <linux/kvm_host.h>
#include <linux/percpu.h>
#include <linux/spinlock.h>
#include <asm/cpufeature.h>
-#include <asm/kvm_aia_imsic.h>
struct aia_hgei_control {
raw_spinlock_t lock;
@@ -394,6 +394,8 @@ int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner,
{
int ret = -ENOENT;
unsigned long flags;
+ const struct imsic_global_config *gc;
+ const struct imsic_local_config *lc;
struct aia_hgei_control *hgctrl = per_cpu_ptr(&aia_hgei, cpu);
if (!kvm_riscv_aia_available() || !hgctrl)
@@ -409,11 +411,14 @@ int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner,
raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
- /* TODO: To be updated later by AIA IMSIC HW guest file support */
- if (hgei_va)
- *hgei_va = NULL;
- if (hgei_pa)
- *hgei_pa = 0;
+ gc = imsic_get_global_config();
+ lc = (gc) ? per_cpu_ptr(gc->local, cpu) : NULL;
+ if (lc && ret > 0) {
+ if (hgei_va)
+ *hgei_va = lc->msi_va + (ret * IMSIC_MMIO_PAGE_SZ);
+ if (hgei_pa)
+ *hgei_pa = lc->msi_pa + (ret * IMSIC_MMIO_PAGE_SZ);
+ }
return ret;
}
@@ -545,6 +550,9 @@ void kvm_riscv_aia_enable(void)
enable_percpu_irq(hgei_parent_irq,
irq_get_trigger_type(hgei_parent_irq));
csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
+ /* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
+ if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
+ csr_write(CSR_HVIEN, BIT(IRQ_PMU_OVF));
}
void kvm_riscv_aia_disable(void)
@@ -558,6 +566,8 @@ void kvm_riscv_aia_disable(void)
return;
hgctrl = get_cpu_ptr(&aia_hgei);
+ if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
+ csr_clear(CSR_HVIEN, BIT(IRQ_PMU_OVF));
/* Disable per-CPU SGEI interrupt */
csr_clear(CSR_HIE, BIT(IRQ_S_GEXT));
disable_percpu_irq(hgei_parent_irq);
@@ -600,9 +610,11 @@ void kvm_riscv_aia_disable(void)
int kvm_riscv_aia_init(void)
{
int rc;
+ const struct imsic_global_config *gc;
if (!riscv_isa_extension_available(NULL, SxAIA))
return -ENODEV;
+ gc = imsic_get_global_config();
/* Figure-out number of bits in HGEIE */
csr_write(CSR_HGEIE, -1UL);
@@ -614,17 +626,17 @@ int kvm_riscv_aia_init(void)
/*
* Number of usable HGEI lines should be minimum of per-HART
* IMSIC guest files and number of bits in HGEIE
- *
- * TODO: To be updated later by AIA IMSIC HW guest file support
*/
- kvm_riscv_aia_nr_hgei = 0;
+ if (gc)
+ kvm_riscv_aia_nr_hgei = min((ulong)kvm_riscv_aia_nr_hgei,
+ BIT(gc->guest_index_bits) - 1);
+ else
+ kvm_riscv_aia_nr_hgei = 0;
- /*
- * Find number of guest MSI IDs
- *
- * TODO: To be updated later by AIA IMSIC HW guest file support
- */
+ /* Find number of guest MSI IDs */
kvm_riscv_aia_max_ids = IMSIC_MAX_ID;
+ if (gc && kvm_riscv_aia_nr_hgei)
+ kvm_riscv_aia_max_ids = gc->nr_guest_ids + 1;
/* Initialize guest external interrupt line management */
rc = aia_hgei_init();
diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c
index b467ba5ed910..da6ff1bade0d 100644
--- a/arch/riscv/kvm/aia_aplic.c
+++ b/arch/riscv/kvm/aia_aplic.c
@@ -7,12 +7,12 @@
* Anup Patel <apatel@ventanamicro.com>
*/
+#include <linux/irqchip/riscv-aplic.h>
#include <linux/kvm_host.h>
#include <linux/math.h>
#include <linux/spinlock.h>
#include <linux/swab.h>
#include <kvm/iodev.h>
-#include <asm/kvm_aia_aplic.h>
struct aplic_irq {
raw_spinlock_t lock;
diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c
index 0eb689351b7d..39cd26af5a69 100644
--- a/arch/riscv/kvm/aia_device.c
+++ b/arch/riscv/kvm/aia_device.c
@@ -8,9 +8,9 @@
*/
#include <linux/bits.h>
+#include <linux/irqchip/riscv-imsic.h>
#include <linux/kvm_host.h>
#include <linux/uaccess.h>
-#include <asm/kvm_aia_imsic.h>
static void unlock_vcpus(struct kvm *kvm, int vcpu_lock_idx)
{
@@ -237,10 +237,11 @@ static gpa_t aia_imsic_ppn(struct kvm_aia *aia, gpa_t addr)
static u32 aia_imsic_hart_index(struct kvm_aia *aia, gpa_t addr)
{
- u32 hart, group = 0;
+ u32 hart = 0, group = 0;
- hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) &
- GENMASK_ULL(aia->nr_hart_bits - 1, 0);
+ if (aia->nr_hart_bits)
+ hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) &
+ GENMASK_ULL(aia->nr_hart_bits - 1, 0);
if (aia->nr_group_bits)
group = (addr >> aia->nr_group_shift) &
GENMASK_ULL(aia->nr_group_bits - 1, 0);
diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index e808723a85f1..0a1e859323b4 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -9,13 +9,13 @@
#include <linux/atomic.h>
#include <linux/bitmap.h>
+#include <linux/irqchip/riscv-imsic.h>
#include <linux/kvm_host.h>
#include <linux/math.h>
#include <linux/spinlock.h>
#include <linux/swab.h>
#include <kvm/iodev.h>
#include <asm/csr.h>
-#include <asm/kvm_aia_imsic.h>
#define IMSIC_MAX_EIX (IMSIC_MAX_ID / BITS_PER_TYPE(u64))
diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c
index 225a435d9c9a..bab2ec34cd87 100644
--- a/arch/riscv/kvm/main.c
+++ b/arch/riscv/kvm/main.c
@@ -22,22 +22,8 @@ long kvm_arch_dev_ioctl(struct file *filp,
int kvm_arch_hardware_enable(void)
{
- unsigned long hideleg, hedeleg;
-
- hedeleg = 0;
- hedeleg |= (1UL << EXC_INST_MISALIGNED);
- hedeleg |= (1UL << EXC_BREAKPOINT);
- hedeleg |= (1UL << EXC_SYSCALL);
- hedeleg |= (1UL << EXC_INST_PAGE_FAULT);
- hedeleg |= (1UL << EXC_LOAD_PAGE_FAULT);
- hedeleg |= (1UL << EXC_STORE_PAGE_FAULT);
- csr_write(CSR_HEDELEG, hedeleg);
-
- hideleg = 0;
- hideleg |= (1UL << IRQ_VS_SOFT);
- hideleg |= (1UL << IRQ_VS_TIMER);
- hideleg |= (1UL << IRQ_VS_EXT);
- csr_write(CSR_HIDELEG, hideleg);
+ csr_write(CSR_HEDELEG, KVM_HEDELEG_DEFAULT);
+ csr_write(CSR_HIDELEG, KVM_HIDELEG_DEFAULT);
/* VS should access only the time counter directly. Everything else should trap */
csr_write(CSR_HCOUNTEREN, 0x02);
diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c
index a9e2fd7245e1..b63650f9b966 100644
--- a/arch/riscv/kvm/mmu.c
+++ b/arch/riscv/kvm/mmu.c
@@ -550,26 +550,6 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
return false;
}
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- int ret;
- kvm_pfn_t pfn = pte_pfn(range->arg.pte);
-
- if (!kvm->arch.pgd)
- return false;
-
- WARN_ON(range->end - range->start != 1);
-
- ret = gstage_map_page(kvm, NULL, range->start << PAGE_SHIFT,
- __pfn_to_phys(pfn), PAGE_SIZE, true, true);
- if (ret) {
- kvm_debug("Failed to map G-stage page (error %d)\n", ret);
- return true;
- }
-
- return false;
-}
-
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
pte_t *ptep;
diff --git a/arch/riscv/kvm/trace.h b/arch/riscv/kvm/trace.h
new file mode 100644
index 000000000000..3d54175d805c
--- /dev/null
+++ b/arch/riscv/kvm/trace.h
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tracepoints for RISC-V KVM
+ *
+ * Copyright 2024 Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ */
+#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+
+TRACE_EVENT(kvm_entry,
+ TP_PROTO(struct kvm_vcpu *vcpu),
+ TP_ARGS(vcpu),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, pc)
+ ),
+
+ TP_fast_assign(
+ __entry->pc = vcpu->arch.guest_context.sepc;
+ ),
+
+ TP_printk("PC: 0x016%lx", __entry->pc)
+);
+
+TRACE_EVENT(kvm_exit,
+ TP_PROTO(struct kvm_cpu_trap *trap),
+ TP_ARGS(trap),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, sepc)
+ __field(unsigned long, scause)
+ __field(unsigned long, stval)
+ __field(unsigned long, htval)
+ __field(unsigned long, htinst)
+ ),
+
+ TP_fast_assign(
+ __entry->sepc = trap->sepc;
+ __entry->scause = trap->scause;
+ __entry->stval = trap->stval;
+ __entry->htval = trap->htval;
+ __entry->htinst = trap->htinst;
+ ),
+
+ TP_printk("SEPC:0x%lx, SCAUSE:0x%lx, STVAL:0x%lx, HTVAL:0x%lx, HTINST:0x%lx",
+ __entry->sepc,
+ __entry->scause,
+ __entry->stval,
+ __entry->htval,
+ __entry->htinst)
+);
+
+#endif /* _TRACE_RSICV_KVM_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index b5ca9f2e98ac..8d7d381737ee 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -21,10 +21,14 @@
#include <asm/cacheflush.h>
#include <asm/kvm_vcpu_vector.h>
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
KVM_GENERIC_VCPU_STATS(),
STATS_DESC_COUNTER(VCPU, ecall_exit_stat),
STATS_DESC_COUNTER(VCPU, wfi_exit_stat),
+ STATS_DESC_COUNTER(VCPU, wrs_exit_stat),
STATS_DESC_COUNTER(VCPU, mmio_exit_user),
STATS_DESC_COUNTER(VCPU, mmio_exit_kernel),
STATS_DESC_COUNTER(VCPU, csr_exit_user),
@@ -64,7 +68,9 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu)
memcpy(csr, reset_csr, sizeof(*csr));
+ spin_lock(&vcpu->arch.reset_cntx_lock);
memcpy(cntx, reset_cntx, sizeof(*cntx));
+ spin_unlock(&vcpu->arch.reset_cntx_lock);
kvm_riscv_vcpu_fp_reset(vcpu);
@@ -102,6 +108,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
struct kvm_cpu_context *cntx;
struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr;
+ spin_lock_init(&vcpu->arch.mp_state_lock);
+
/* Mark this VCPU never ran */
vcpu->arch.ran_atleast_once = false;
vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
@@ -119,12 +127,16 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
spin_lock_init(&vcpu->arch.hfence_lock);
/* Setup reset state of shadow SSTATUS and HSTATUS CSRs */
+ spin_lock_init(&vcpu->arch.reset_cntx_lock);
+
+ spin_lock(&vcpu->arch.reset_cntx_lock);
cntx = &vcpu->arch.guest_reset_context;
cntx->sstatus = SR_SPP | SR_SPIE;
cntx->hstatus = 0;
cntx->hstatus |= HSTATUS_VTW;
cntx->hstatus |= HSTATUS_SPVP;
cntx->hstatus |= HSTATUS_SPV;
+ spin_unlock(&vcpu->arch.reset_cntx_lock);
if (kvm_riscv_vcpu_alloc_vector_context(vcpu, cntx))
return -ENOMEM;
@@ -201,7 +213,7 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
{
return (kvm_riscv_vcpu_has_interrupts(vcpu, -1UL) &&
- !vcpu->arch.power_off && !vcpu->arch.pause);
+ !kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause);
}
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
@@ -365,6 +377,13 @@ void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu)
}
}
+ /* Sync up the HVIP.LCOFIP bit changes (only clear) by the guest */
+ if ((csr->hvip ^ hvip) & (1UL << IRQ_PMU_OVF)) {
+ if (!(hvip & (1UL << IRQ_PMU_OVF)) &&
+ !test_and_set_bit(IRQ_PMU_OVF, v->irqs_pending_mask))
+ clear_bit(IRQ_PMU_OVF, v->irqs_pending);
+ }
+
/* Sync-up AIA high interrupts */
kvm_riscv_vcpu_aia_sync_interrupts(vcpu);
@@ -382,7 +401,8 @@ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
if (irq < IRQ_LOCAL_MAX &&
irq != IRQ_VS_SOFT &&
irq != IRQ_VS_TIMER &&
- irq != IRQ_VS_EXT)
+ irq != IRQ_VS_EXT &&
+ irq != IRQ_PMU_OVF)
return -EINVAL;
set_bit(irq, vcpu->arch.irqs_pending);
@@ -397,14 +417,15 @@ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
{
/*
- * We only allow VS-mode software, timer, and external
+ * We only allow VS-mode software, timer, counter overflow and external
* interrupts when irq is one of the local interrupts
* defined by RISC-V privilege specification.
*/
if (irq < IRQ_LOCAL_MAX &&
irq != IRQ_VS_SOFT &&
irq != IRQ_VS_TIMER &&
- irq != IRQ_VS_EXT)
+ irq != IRQ_VS_EXT &&
+ irq != IRQ_PMU_OVF)
return -EINVAL;
clear_bit(irq, vcpu->arch.irqs_pending);
@@ -429,26 +450,42 @@ bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask)
return kvm_riscv_vcpu_aia_has_interrupts(vcpu, mask);
}
-void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu)
+void __kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu)
{
- vcpu->arch.power_off = true;
+ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
kvm_make_request(KVM_REQ_SLEEP, vcpu);
kvm_vcpu_kick(vcpu);
}
-void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu)
+void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu)
+{
+ spin_lock(&vcpu->arch.mp_state_lock);
+ __kvm_riscv_vcpu_power_off(vcpu);
+ spin_unlock(&vcpu->arch.mp_state_lock);
+}
+
+void __kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu)
{
- vcpu->arch.power_off = false;
+ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_RUNNABLE);
kvm_vcpu_wake_up(vcpu);
}
+void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu)
+{
+ spin_lock(&vcpu->arch.mp_state_lock);
+ __kvm_riscv_vcpu_power_on(vcpu);
+ spin_unlock(&vcpu->arch.mp_state_lock);
+}
+
+bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu)
+{
+ return READ_ONCE(vcpu->arch.mp_state.mp_state) == KVM_MP_STATE_STOPPED;
+}
+
int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
{
- if (vcpu->arch.power_off)
- mp_state->mp_state = KVM_MP_STATE_STOPPED;
- else
- mp_state->mp_state = KVM_MP_STATE_RUNNABLE;
+ *mp_state = READ_ONCE(vcpu->arch.mp_state);
return 0;
}
@@ -458,25 +495,36 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
{
int ret = 0;
+ spin_lock(&vcpu->arch.mp_state_lock);
+
switch (mp_state->mp_state) {
case KVM_MP_STATE_RUNNABLE:
- vcpu->arch.power_off = false;
+ WRITE_ONCE(vcpu->arch.mp_state, *mp_state);
break;
case KVM_MP_STATE_STOPPED:
- kvm_riscv_vcpu_power_off(vcpu);
+ __kvm_riscv_vcpu_power_off(vcpu);
break;
default:
ret = -EINVAL;
}
+ spin_unlock(&vcpu->arch.mp_state_lock);
+
return ret;
}
int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
{
- /* TODO; To be implemented later. */
- return -EINVAL;
+ if (dbg->control & KVM_GUESTDBG_ENABLE) {
+ vcpu->guest_debug = dbg->control;
+ vcpu->arch.cfg.hedeleg &= ~BIT(EXC_BREAKPOINT);
+ } else {
+ vcpu->guest_debug = 0;
+ vcpu->arch.cfg.hedeleg |= BIT(EXC_BREAKPOINT);
+ }
+
+ return 0;
}
static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu)
@@ -505,6 +553,10 @@ static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu)
if (riscv_isa_extension_available(isa, SMSTATEEN))
cfg->hstateen0 |= SMSTATEEN0_SSTATEEN0;
}
+
+ cfg->hedeleg = KVM_HEDELEG_DEFAULT;
+ if (vcpu->guest_debug)
+ cfg->hedeleg &= ~BIT(EXC_BREAKPOINT);
}
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
@@ -519,6 +571,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
csr_write(CSR_VSEPC, csr->vsepc);
csr_write(CSR_VSCAUSE, csr->vscause);
csr_write(CSR_VSTVAL, csr->vstval);
+ csr_write(CSR_HEDELEG, cfg->hedeleg);
csr_write(CSR_HVIP, csr->hvip);
csr_write(CSR_VSATP, csr->vsatp);
csr_write(CSR_HENVCFG, cfg->henvcfg);
@@ -584,11 +637,11 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) {
kvm_vcpu_srcu_read_unlock(vcpu);
rcuwait_wait_event(wait,
- (!vcpu->arch.power_off) && (!vcpu->arch.pause),
+ (!kvm_riscv_vcpu_stopped(vcpu)) && (!vcpu->arch.pause),
TASK_INTERRUPTIBLE);
kvm_vcpu_srcu_read_lock(vcpu);
- if (vcpu->arch.power_off || vcpu->arch.pause) {
+ if (kvm_riscv_vcpu_stopped(vcpu) || vcpu->arch.pause) {
/*
* Awaken to handle a signal, request to
* sleep again later.
@@ -711,7 +764,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
return ret;
}
- if (run->immediate_exit) {
+ if (!vcpu->wants_to_run) {
kvm_vcpu_srcu_read_unlock(vcpu);
return -EINTR;
}
@@ -782,6 +835,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
*/
kvm_riscv_local_tlb_sanitize(vcpu);
+ trace_kvm_entry(vcpu);
+
guest_timing_enter_irqoff();
kvm_riscv_vcpu_enter_exit(vcpu);
@@ -820,6 +875,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
local_irq_enable();
+ trace_kvm_exit(&trap);
+
preempt_enable();
kvm_vcpu_srcu_read_lock(vcpu);
diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c
index 2415722c01b8..fa98e5c024b2 100644
--- a/arch/riscv/kvm/vcpu_exit.c
+++ b/arch/riscv/kvm/vcpu_exit.c
@@ -185,6 +185,8 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
case EXC_INST_ILLEGAL:
case EXC_LOAD_MISALIGNED:
case EXC_STORE_MISALIGNED:
+ case EXC_LOAD_ACCESS:
+ case EXC_STORE_ACCESS:
if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) {
kvm_riscv_vcpu_trap_redirect(vcpu, trap);
ret = 1;
@@ -204,6 +206,10 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV)
ret = kvm_riscv_vcpu_sbi_ecall(vcpu, run);
break;
+ case EXC_BREAKPOINT:
+ run->exit_reason = KVM_EXIT_DEBUG;
+ ret = 0;
+ break;
default:
break;
}
diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c
index ee7215f4071f..97dec18e6989 100644
--- a/arch/riscv/kvm/vcpu_insn.c
+++ b/arch/riscv/kvm/vcpu_insn.c
@@ -16,6 +16,9 @@
#define INSN_MASK_WFI 0xffffffff
#define INSN_MATCH_WFI 0x10500073
+#define INSN_MASK_WRS 0xffffffff
+#define INSN_MATCH_WRS 0x00d00073
+
#define INSN_MATCH_CSRRW 0x1073
#define INSN_MASK_CSRRW 0x707f
#define INSN_MATCH_CSRRS 0x2073
@@ -203,6 +206,13 @@ static int wfi_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
return KVM_INSN_CONTINUE_NEXT_SEPC;
}
+static int wrs_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
+{
+ vcpu->stat.wrs_exit_stat++;
+ kvm_vcpu_on_spin(vcpu, vcpu->arch.guest_context.sstatus & SR_SPP);
+ return KVM_INSN_CONTINUE_NEXT_SEPC;
+}
+
struct csr_func {
unsigned int base;
unsigned int count;
@@ -378,6 +388,11 @@ static const struct insn_func system_opcode_funcs[] = {
.match = INSN_MATCH_WFI,
.func = wfi_insn,
},
+ {
+ .mask = INSN_MASK_WRS,
+ .match = INSN_MATCH_WRS,
+ .func = wrs_insn,
+ },
};
static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 994adc26db4b..b319c4c13c54 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -36,11 +36,13 @@ static const unsigned long kvm_isa_ext_arr[] = {
/* Multi letter extensions (alphabetically sorted) */
KVM_ISA_EXT_ARR(SMSTATEEN),
KVM_ISA_EXT_ARR(SSAIA),
+ KVM_ISA_EXT_ARR(SSCOFPMF),
KVM_ISA_EXT_ARR(SSTC),
KVM_ISA_EXT_ARR(SVINVAL),
KVM_ISA_EXT_ARR(SVNAPOT),
KVM_ISA_EXT_ARR(SVPBMT),
KVM_ISA_EXT_ARR(ZACAS),
+ KVM_ISA_EXT_ARR(ZAWRS),
KVM_ISA_EXT_ARR(ZBA),
KVM_ISA_EXT_ARR(ZBB),
KVM_ISA_EXT_ARR(ZBC),
@@ -48,6 +50,11 @@ static const unsigned long kvm_isa_ext_arr[] = {
KVM_ISA_EXT_ARR(ZBKC),
KVM_ISA_EXT_ARR(ZBKX),
KVM_ISA_EXT_ARR(ZBS),
+ KVM_ISA_EXT_ARR(ZCA),
+ KVM_ISA_EXT_ARR(ZCB),
+ KVM_ISA_EXT_ARR(ZCD),
+ KVM_ISA_EXT_ARR(ZCF),
+ KVM_ISA_EXT_ARR(ZCMOP),
KVM_ISA_EXT_ARR(ZFA),
KVM_ISA_EXT_ARR(ZFH),
KVM_ISA_EXT_ARR(ZFHMIN),
@@ -60,6 +67,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
KVM_ISA_EXT_ARR(ZIHINTNTL),
KVM_ISA_EXT_ARR(ZIHINTPAUSE),
KVM_ISA_EXT_ARR(ZIHPM),
+ KVM_ISA_EXT_ARR(ZIMOP),
KVM_ISA_EXT_ARR(ZKND),
KVM_ISA_EXT_ARR(ZKNE),
KVM_ISA_EXT_ARR(ZKNH),
@@ -99,6 +107,9 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
switch (ext) {
case KVM_RISCV_ISA_EXT_H:
return false;
+ case KVM_RISCV_ISA_EXT_SSCOFPMF:
+ /* Sscofpmf depends on interrupt filtering defined in ssaia */
+ return __riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSAIA);
case KVM_RISCV_ISA_EXT_V:
return riscv_v_vstate_ctrl_user_allowed();
default:
@@ -116,10 +127,13 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_C:
case KVM_RISCV_ISA_EXT_I:
case KVM_RISCV_ISA_EXT_M:
+ /* There is not architectural config bit to disable sscofpmf completely */
+ case KVM_RISCV_ISA_EXT_SSCOFPMF:
case KVM_RISCV_ISA_EXT_SSTC:
case KVM_RISCV_ISA_EXT_SVINVAL:
case KVM_RISCV_ISA_EXT_SVNAPOT:
case KVM_RISCV_ISA_EXT_ZACAS:
+ case KVM_RISCV_ISA_EXT_ZAWRS:
case KVM_RISCV_ISA_EXT_ZBA:
case KVM_RISCV_ISA_EXT_ZBB:
case KVM_RISCV_ISA_EXT_ZBC:
@@ -127,6 +141,11 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_ZBKC:
case KVM_RISCV_ISA_EXT_ZBKX:
case KVM_RISCV_ISA_EXT_ZBS:
+ case KVM_RISCV_ISA_EXT_ZCA:
+ case KVM_RISCV_ISA_EXT_ZCB:
+ case KVM_RISCV_ISA_EXT_ZCD:
+ case KVM_RISCV_ISA_EXT_ZCF:
+ case KVM_RISCV_ISA_EXT_ZCMOP:
case KVM_RISCV_ISA_EXT_ZFA:
case KVM_RISCV_ISA_EXT_ZFH:
case KVM_RISCV_ISA_EXT_ZFHMIN:
@@ -137,6 +156,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_ZIHINTNTL:
case KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
case KVM_RISCV_ISA_EXT_ZIHPM:
+ case KVM_RISCV_ISA_EXT_ZIMOP:
case KVM_RISCV_ISA_EXT_ZKND:
case KVM_RISCV_ISA_EXT_ZKNE:
case KVM_RISCV_ISA_EXT_ZKNH:
@@ -718,9 +738,9 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu,
switch (reg_subtype) {
case KVM_REG_RISCV_ISA_SINGLE:
return riscv_vcpu_set_isa_ext_single(vcpu, reg_num, reg_val);
- case KVM_REG_RISCV_SBI_MULTI_EN:
+ case KVM_REG_RISCV_ISA_MULTI_EN:
return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, true);
- case KVM_REG_RISCV_SBI_MULTI_DIS:
+ case KVM_REG_RISCV_ISA_MULTI_DIS:
return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false);
default:
return -ENOENT;
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 86391a5061dd..bcf41d6e0df0 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -14,6 +14,7 @@
#include <asm/csr.h>
#include <asm/kvm_vcpu_sbi.h>
#include <asm/kvm_vcpu_pmu.h>
+#include <asm/sbi.h>
#include <linux/bitops.h>
#define kvm_pmu_num_counters(pmu) ((pmu)->num_hw_ctrs + (pmu)->num_fw_ctrs)
@@ -39,7 +40,7 @@ static u64 kvm_pmu_get_sample_period(struct kvm_pmc *pmc)
u64 sample_period;
if (!pmc->counter_val)
- sample_period = counter_val_mask + 1;
+ sample_period = counter_val_mask;
else
sample_period = (-pmc->counter_val) & counter_val_mask;
@@ -196,6 +197,36 @@ static int pmu_get_pmc_index(struct kvm_pmu *pmu, unsigned long eidx,
return kvm_pmu_get_programmable_pmc_index(pmu, eidx, cbase, cmask);
}
+static int pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx,
+ unsigned long *out_val)
+{
+ struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu);
+ struct kvm_pmc *pmc;
+ int fevent_code;
+
+ if (!IS_ENABLED(CONFIG_32BIT)) {
+ pr_warn("%s: should be invoked for only RV32\n", __func__);
+ return -EINVAL;
+ }
+
+ if (cidx >= kvm_pmu_num_counters(kvpmu) || cidx == 1) {
+ pr_warn("Invalid counter id [%ld]during read\n", cidx);
+ return -EINVAL;
+ }
+
+ pmc = &kvpmu->pmc[cidx];
+
+ if (pmc->cinfo.type != SBI_PMU_CTR_TYPE_FW)
+ return -EINVAL;
+
+ fevent_code = get_event_code(pmc->event_idx);
+ pmc->counter_val = kvpmu->fw_event[fevent_code].value;
+
+ *out_val = pmc->counter_val >> 32;
+
+ return 0;
+}
+
static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
unsigned long *out_val)
{
@@ -204,6 +235,11 @@ static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
u64 enabled, running;
int fevent_code;
+ if (cidx >= kvm_pmu_num_counters(kvpmu) || cidx == 1) {
+ pr_warn("Invalid counter id [%ld] during read\n", cidx);
+ return -EINVAL;
+ }
+
pmc = &kvpmu->pmc[cidx];
if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW) {
@@ -229,8 +265,50 @@ static int kvm_pmu_validate_counter_mask(struct kvm_pmu *kvpmu, unsigned long ct
return 0;
}
-static int kvm_pmu_create_perf_event(struct kvm_pmc *pmc, struct perf_event_attr *attr,
- unsigned long flags, unsigned long eidx, unsigned long evtdata)
+static void kvm_riscv_pmu_overflow(struct perf_event *perf_event,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ struct kvm_pmc *pmc = perf_event->overflow_handler_context;
+ struct kvm_vcpu *vcpu = pmc->vcpu;
+ struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu);
+ struct riscv_pmu *rpmu = to_riscv_pmu(perf_event->pmu);
+ u64 period;
+
+ /*
+ * Stop the event counting by directly accessing the perf_event.
+ * Otherwise, this needs to deferred via a workqueue.
+ * That will introduce skew in the counter value because the actual
+ * physical counter would start after returning from this function.
+ * It will be stopped again once the workqueue is scheduled
+ */
+ rpmu->pmu.stop(perf_event, PERF_EF_UPDATE);
+
+ /*
+ * The hw counter would start automatically when this function returns.
+ * Thus, the host may continue to interrupt and inject it to the guest
+ * even without the guest configuring the next event. Depending on the hardware
+ * the host may have some sluggishness only if privilege mode filtering is not
+ * available. In an ideal world, where qemu is not the only capable hardware,
+ * this can be removed.
+ * FYI: ARM64 does this way while x86 doesn't do anything as such.
+ * TODO: Should we keep it for RISC-V ?
+ */
+ period = -(local64_read(&perf_event->count));
+
+ local64_set(&perf_event->hw.period_left, 0);
+ perf_event->attr.sample_period = period;
+ perf_event->hw.sample_period = period;
+
+ set_bit(pmc->idx, kvpmu->pmc_overflown);
+ kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_PMU_OVF);
+
+ rpmu->pmu.start(perf_event, PERF_EF_RELOAD);
+}
+
+static long kvm_pmu_create_perf_event(struct kvm_pmc *pmc, struct perf_event_attr *attr,
+ unsigned long flags, unsigned long eidx,
+ unsigned long evtdata)
{
struct perf_event *event;
@@ -247,9 +325,9 @@ static int kvm_pmu_create_perf_event(struct kvm_pmc *pmc, struct perf_event_attr
*/
attr->sample_period = kvm_pmu_get_sample_period(pmc);
- event = perf_event_create_kernel_counter(attr, -1, current, NULL, pmc);
+ event = perf_event_create_kernel_counter(attr, -1, current, kvm_riscv_pmu_overflow, pmc);
if (IS_ERR(event)) {
- pr_err("kvm pmu event creation failed for eidx %lx: %ld\n", eidx, PTR_ERR(event));
+ pr_debug("kvm pmu event creation failed for eidx %lx: %ld\n", eidx, PTR_ERR(event));
return PTR_ERR(event);
}
@@ -310,6 +388,80 @@ int kvm_riscv_vcpu_pmu_read_hpm(struct kvm_vcpu *vcpu, unsigned int csr_num,
return ret;
}
+static void kvm_pmu_clear_snapshot_area(struct kvm_vcpu *vcpu)
+{
+ struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu);
+ int snapshot_area_size = sizeof(struct riscv_pmu_snapshot_data);
+
+ if (kvpmu->sdata) {
+ if (kvpmu->snapshot_addr != INVALID_GPA) {
+ memset(kvpmu->sdata, 0, snapshot_area_size);
+ kvm_vcpu_write_guest(vcpu, kvpmu->snapshot_addr,
+ kvpmu->sdata, snapshot_area_size);
+ } else {
+ pr_warn("snapshot address invalid\n");
+ }
+ kfree(kvpmu->sdata);
+ kvpmu->sdata = NULL;
+ }
+ kvpmu->snapshot_addr = INVALID_GPA;
+}
+
+int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
+ unsigned long saddr_high, unsigned long flags,
+ struct kvm_vcpu_sbi_return *retdata)
+{
+ struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu);
+ int snapshot_area_size = sizeof(struct riscv_pmu_snapshot_data);
+ int sbiret = 0;
+ gpa_t saddr;
+ unsigned long hva;
+ bool writable;
+
+ if (!kvpmu || flags) {
+ sbiret = SBI_ERR_INVALID_PARAM;
+ goto out;
+ }
+
+ if (saddr_low == SBI_SHMEM_DISABLE && saddr_high == SBI_SHMEM_DISABLE) {
+ kvm_pmu_clear_snapshot_area(vcpu);
+ return 0;
+ }
+
+ saddr = saddr_low;
+
+ if (saddr_high != 0) {
+ if (IS_ENABLED(CONFIG_32BIT))
+ saddr |= ((gpa_t)saddr_high << 32);
+ else
+ sbiret = SBI_ERR_INVALID_ADDRESS;
+ goto out;
+ }
+
+ hva = kvm_vcpu_gfn_to_hva_prot(vcpu, saddr >> PAGE_SHIFT, &writable);
+ if (kvm_is_error_hva(hva) || !writable) {
+ sbiret = SBI_ERR_INVALID_ADDRESS;
+ goto out;
+ }
+
+ kvpmu->sdata = kzalloc(snapshot_area_size, GFP_ATOMIC);
+ if (!kvpmu->sdata)
+ return -ENOMEM;
+
+ if (kvm_vcpu_write_guest(vcpu, saddr, kvpmu->sdata, snapshot_area_size)) {
+ kfree(kvpmu->sdata);
+ sbiret = SBI_ERR_FAILURE;
+ goto out;
+ }
+
+ kvpmu->snapshot_addr = saddr;
+
+out:
+ retdata->err_val = sbiret;
+
+ return 0;
+}
+
int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu,
struct kvm_vcpu_sbi_return *retdata)
{
@@ -343,20 +495,40 @@ int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_base,
int i, pmc_index, sbiret = 0;
struct kvm_pmc *pmc;
int fevent_code;
+ bool snap_flag_set = flags & SBI_PMU_START_FLAG_INIT_SNAPSHOT;
if (kvm_pmu_validate_counter_mask(kvpmu, ctr_base, ctr_mask) < 0) {
sbiret = SBI_ERR_INVALID_PARAM;
goto out;
}
+ if (snap_flag_set) {
+ if (kvpmu->snapshot_addr == INVALID_GPA) {
+ sbiret = SBI_ERR_NO_SHMEM;
+ goto out;
+ }
+ if (kvm_vcpu_read_guest(vcpu, kvpmu->snapshot_addr, kvpmu->sdata,
+ sizeof(struct riscv_pmu_snapshot_data))) {
+ pr_warn("Unable to read snapshot shared memory while starting counters\n");
+ sbiret = SBI_ERR_FAILURE;
+ goto out;
+ }
+ }
/* Start the counters that have been configured and requested by the guest */
for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) {
pmc_index = i + ctr_base;
if (!test_bit(pmc_index, kvpmu->pmc_in_use))
continue;
+ /* The guest started the counter again. Reset the overflow status */
+ clear_bit(pmc_index, kvpmu->pmc_overflown);
pmc = &kvpmu->pmc[pmc_index];
- if (flags & SBI_PMU_START_FLAG_SET_INIT_VALUE)
+ if (flags & SBI_PMU_START_FLAG_SET_INIT_VALUE) {
pmc->counter_val = ival;
+ } else if (snap_flag_set) {
+ /* The counter index in the snapshot are relative to the counter base */
+ pmc->counter_val = kvpmu->sdata->ctr_values[i];
+ }
+
if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW) {
fevent_code = get_event_code(pmc->event_idx);
if (fevent_code >= SBI_PMU_FW_MAX) {
@@ -400,12 +572,19 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
u64 enabled, running;
struct kvm_pmc *pmc;
int fevent_code;
+ bool snap_flag_set = flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT;
+ bool shmem_needs_update = false;
if (kvm_pmu_validate_counter_mask(kvpmu, ctr_base, ctr_mask) < 0) {
sbiret = SBI_ERR_INVALID_PARAM;
goto out;
}
+ if (snap_flag_set && kvpmu->snapshot_addr == INVALID_GPA) {
+ sbiret = SBI_ERR_NO_SHMEM;
+ goto out;
+ }
+
/* Stop the counters that have been configured and requested by the guest */
for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) {
pmc_index = i + ctr_base;
@@ -432,21 +611,49 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
sbiret = SBI_ERR_ALREADY_STOPPED;
}
- if (flags & SBI_PMU_STOP_FLAG_RESET) {
- /* Relase the counter if this is a reset request */
- pmc->counter_val += perf_event_read_value(pmc->perf_event,
- &enabled, &running);
+ if (flags & SBI_PMU_STOP_FLAG_RESET)
+ /* Release the counter if this is a reset request */
kvm_pmu_release_perf_event(pmc);
- }
} else {
sbiret = SBI_ERR_INVALID_PARAM;
}
+
+ if (snap_flag_set && !sbiret) {
+ if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW)
+ pmc->counter_val = kvpmu->fw_event[fevent_code].value;
+ else if (pmc->perf_event)
+ pmc->counter_val += perf_event_read_value(pmc->perf_event,
+ &enabled, &running);
+ /*
+ * The counter and overflow indicies in the snapshot region are w.r.to
+ * cbase. Modify the set bit in the counter mask instead of the pmc_index
+ * which indicates the absolute counter index.
+ */
+ if (test_bit(pmc_index, kvpmu->pmc_overflown))
+ kvpmu->sdata->ctr_overflow_mask |= BIT(i);
+ kvpmu->sdata->ctr_values[i] = pmc->counter_val;
+ shmem_needs_update = true;
+ }
+
if (flags & SBI_PMU_STOP_FLAG_RESET) {
pmc->event_idx = SBI_PMU_EVENT_IDX_INVALID;
clear_bit(pmc_index, kvpmu->pmc_in_use);
+ clear_bit(pmc_index, kvpmu->pmc_overflown);
+ if (snap_flag_set) {
+ /*
+ * Only clear the given counter as the caller is responsible to
+ * validate both the overflow mask and configured counters.
+ */
+ kvpmu->sdata->ctr_overflow_mask &= ~BIT(i);
+ shmem_needs_update = true;
+ }
}
}
+ if (shmem_needs_update)
+ kvm_vcpu_write_guest(vcpu, kvpmu->snapshot_addr, kvpmu->sdata,
+ sizeof(struct riscv_pmu_snapshot_data));
+
out:
retdata->err_val = sbiret;
@@ -458,7 +665,8 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
unsigned long eidx, u64 evtdata,
struct kvm_vcpu_sbi_return *retdata)
{
- int ctr_idx, ret, sbiret = 0;
+ int ctr_idx, sbiret = 0;
+ long ret;
bool is_fevent;
unsigned long event_code;
u32 etype = kvm_pmu_get_perf_event_type(eidx);
@@ -517,8 +725,10 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
kvpmu->fw_event[event_code].started = true;
} else {
ret = kvm_pmu_create_perf_event(pmc, &attr, flags, eidx, evtdata);
- if (ret)
- return ret;
+ if (ret) {
+ sbiret = SBI_ERR_NOT_SUPPORTED;
+ goto out;
+ }
}
set_bit(ctr_idx, kvpmu->pmc_in_use);
@@ -530,7 +740,19 @@ out:
return 0;
}
-int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
+int kvm_riscv_vcpu_pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx,
+ struct kvm_vcpu_sbi_return *retdata)
+{
+ int ret;
+
+ ret = pmu_fw_ctr_read_hi(vcpu, cidx, &retdata->out_val);
+ if (ret == -EINVAL)
+ retdata->err_val = SBI_ERR_INVALID_PARAM;
+
+ return 0;
+}
+
+int kvm_riscv_vcpu_pmu_fw_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
struct kvm_vcpu_sbi_return *retdata)
{
int ret;
@@ -566,6 +788,7 @@ void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu)
kvpmu->num_hw_ctrs = num_hw_ctrs + 1;
kvpmu->num_fw_ctrs = SBI_PMU_FW_MAX;
memset(&kvpmu->fw_event, 0, SBI_PMU_FW_MAX * sizeof(struct kvm_fw_event));
+ kvpmu->snapshot_addr = INVALID_GPA;
if (kvpmu->num_hw_ctrs > RISCV_KVM_MAX_HW_CTRS) {
pr_warn_once("Limiting the hardware counters to 32 as specified by the ISA");
@@ -585,6 +808,7 @@ void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu)
pmc = &kvpmu->pmc[i];
pmc->idx = i;
pmc->event_idx = SBI_PMU_EVENT_IDX_INVALID;
+ pmc->vcpu = vcpu;
if (i < kvpmu->num_hw_ctrs) {
pmc->cinfo.type = SBI_PMU_CTR_TYPE_HW;
if (i < 3)
@@ -601,7 +825,7 @@ void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu)
pmc->cinfo.csr = CSR_CYCLE + i;
} else {
pmc->cinfo.type = SBI_PMU_CTR_TYPE_FW;
- pmc->cinfo.width = BITS_PER_LONG - 1;
+ pmc->cinfo.width = 63;
}
}
@@ -617,14 +841,16 @@ void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu)
if (!kvpmu)
return;
- for_each_set_bit(i, kvpmu->pmc_in_use, RISCV_MAX_COUNTERS) {
+ for_each_set_bit(i, kvpmu->pmc_in_use, RISCV_KVM_MAX_COUNTERS) {
pmc = &kvpmu->pmc[i];
pmc->counter_val = 0;
kvm_pmu_release_perf_event(pmc);
pmc->event_idx = SBI_PMU_EVENT_IDX_INVALID;
}
- bitmap_zero(kvpmu->pmc_in_use, RISCV_MAX_COUNTERS);
+ bitmap_zero(kvpmu->pmc_in_use, RISCV_KVM_MAX_COUNTERS);
+ bitmap_zero(kvpmu->pmc_overflown, RISCV_KVM_MAX_COUNTERS);
memset(&kvpmu->fw_event, 0, SBI_PMU_FW_MAX * sizeof(struct kvm_fw_event));
+ kvm_pmu_clear_snapshot_area(vcpu);
}
void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu)
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 72a2ffb8dcd1..62f409d4176e 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -138,8 +138,11 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
unsigned long i;
struct kvm_vcpu *tmp;
- kvm_for_each_vcpu(i, tmp, vcpu->kvm)
- tmp->arch.power_off = true;
+ kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
+ spin_lock(&vcpu->arch.mp_state_lock);
+ WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
+ spin_unlock(&vcpu->arch.mp_state_lock);
+ }
kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
memset(&run->system_event, 0, sizeof(run->system_event));
diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
index 7dca0e9381d9..dce667f4b6ab 100644
--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -18,13 +18,20 @@ static int kvm_sbi_hsm_vcpu_start(struct kvm_vcpu *vcpu)
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
struct kvm_vcpu *target_vcpu;
unsigned long target_vcpuid = cp->a0;
+ int ret = 0;
target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, target_vcpuid);
if (!target_vcpu)
return SBI_ERR_INVALID_PARAM;
- if (!target_vcpu->arch.power_off)
- return SBI_ERR_ALREADY_AVAILABLE;
+ spin_lock(&target_vcpu->arch.mp_state_lock);
+
+ if (!kvm_riscv_vcpu_stopped(target_vcpu)) {
+ ret = SBI_ERR_ALREADY_AVAILABLE;
+ goto out;
+ }
+
+ spin_lock(&target_vcpu->arch.reset_cntx_lock);
reset_cntx = &target_vcpu->arch.guest_reset_context;
/* start address */
reset_cntx->sepc = cp->a1;
@@ -32,21 +39,35 @@ static int kvm_sbi_hsm_vcpu_start(struct kvm_vcpu *vcpu)
reset_cntx->a0 = target_vcpuid;
/* private data passed from kernel */
reset_cntx->a1 = cp->a2;
+ spin_unlock(&target_vcpu->arch.reset_cntx_lock);
+
kvm_make_request(KVM_REQ_VCPU_RESET, target_vcpu);
- kvm_riscv_vcpu_power_on(target_vcpu);
+ __kvm_riscv_vcpu_power_on(target_vcpu);
- return 0;
+out:
+ spin_unlock(&target_vcpu->arch.mp_state_lock);
+
+ return ret;
}
static int kvm_sbi_hsm_vcpu_stop(struct kvm_vcpu *vcpu)
{
- if (vcpu->arch.power_off)
- return SBI_ERR_FAILURE;
+ int ret = 0;
- kvm_riscv_vcpu_power_off(vcpu);
+ spin_lock(&vcpu->arch.mp_state_lock);
- return 0;
+ if (kvm_riscv_vcpu_stopped(vcpu)) {
+ ret = SBI_ERR_FAILURE;
+ goto out;
+ }
+
+ __kvm_riscv_vcpu_power_off(vcpu);
+
+out:
+ spin_unlock(&vcpu->arch.mp_state_lock);
+
+ return ret;
}
static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
@@ -58,7 +79,7 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, target_vcpuid);
if (!target_vcpu)
return SBI_ERR_INVALID_PARAM;
- if (!target_vcpu->arch.power_off)
+ if (!kvm_riscv_vcpu_stopped(target_vcpu))
return SBI_HSM_STATE_STARTED;
else if (vcpu->stat.generic.blocking)
return SBI_HSM_STATE_SUSPENDED;
@@ -71,14 +92,11 @@ static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
{
int ret = 0;
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
- struct kvm *kvm = vcpu->kvm;
unsigned long funcid = cp->a6;
switch (funcid) {
case SBI_EXT_HSM_HART_START:
- mutex_lock(&kvm->lock);
ret = kvm_sbi_hsm_vcpu_start(vcpu);
- mutex_unlock(&kvm->lock);
break;
case SBI_EXT_HSM_HART_STOP:
ret = kvm_sbi_hsm_vcpu_stop(vcpu);
diff --git a/arch/riscv/kvm/vcpu_sbi_pmu.c b/arch/riscv/kvm/vcpu_sbi_pmu.c
index 7eca72df2cbd..e4be34e03e83 100644
--- a/arch/riscv/kvm/vcpu_sbi_pmu.c
+++ b/arch/riscv/kvm/vcpu_sbi_pmu.c
@@ -42,9 +42,9 @@ static int kvm_sbi_ext_pmu_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
#endif
/*
* This can fail if perf core framework fails to create an event.
- * Forward the error to userspace because it's an error which
- * happened within the host kernel. The other option would be
- * to convert to an SBI error and forward to the guest.
+ * No need to forward the error to userspace and exit the guest.
+ * The operation can continue without profiling. Forward the
+ * appropriate SBI error to the guest.
*/
ret = kvm_riscv_vcpu_pmu_ctr_cfg_match(vcpu, cp->a0, cp->a1,
cp->a2, cp->a3, temp, retdata);
@@ -62,7 +62,16 @@ static int kvm_sbi_ext_pmu_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
ret = kvm_riscv_vcpu_pmu_ctr_stop(vcpu, cp->a0, cp->a1, cp->a2, retdata);
break;
case SBI_EXT_PMU_COUNTER_FW_READ:
- ret = kvm_riscv_vcpu_pmu_ctr_read(vcpu, cp->a0, retdata);
+ ret = kvm_riscv_vcpu_pmu_fw_ctr_read(vcpu, cp->a0, retdata);
+ break;
+ case SBI_EXT_PMU_COUNTER_FW_READ_HI:
+ if (IS_ENABLED(CONFIG_32BIT))
+ ret = kvm_riscv_vcpu_pmu_fw_ctr_read_hi(vcpu, cp->a0, retdata);
+ else
+ retdata->out_val = 0;
+ break;
+ case SBI_EXT_PMU_SNAPSHOT_SET_SHMEM:
+ ret = kvm_riscv_vcpu_pmu_snapshot_set_shmem(vcpu, cp->a0, cp->a1, cp->a2, retdata);
break;
default:
retdata->err_val = SBI_ERR_NOT_SUPPORTED;
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
index d8cf9ca28c61..5f35427114c1 100644
--- a/arch/riscv/kvm/vcpu_sbi_sta.c
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -93,8 +93,8 @@ static int kvm_sbi_sta_steal_time_set_shmem(struct kvm_vcpu *vcpu)
if (flags != 0)
return SBI_ERR_INVALID_PARAM;
- if (shmem_phys_lo == SBI_STA_SHMEM_DISABLE &&
- shmem_phys_hi == SBI_STA_SHMEM_DISABLE) {
+ if (shmem_phys_lo == SBI_SHMEM_DISABLE &&
+ shmem_phys_hi == SBI_SHMEM_DISABLE) {
vcpu->arch.sta.shmem = INVALID_GPA;
return 0;
}
diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
index ce58bc48e5b8..7396b8654f45 100644
--- a/arch/riscv/kvm/vm.c
+++ b/arch/riscv/kvm/vm.c
@@ -186,6 +186,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_READONLY_MEM:
case KVM_CAP_MP_STATE:
case KVM_CAP_IMMEDIATE_EXIT:
+ case KVM_CAP_SET_GUEST_DEBUG:
r = 1;
break;
case KVM_CAP_NR_VCPUS:
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index bd6e6c1b0497..2b369f51b0a5 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -13,6 +13,7 @@ endif
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
+lib-$(CONFIG_RISCV_ISA_ZBC) += crc32.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
lib-$(CONFIG_RISCV_ISA_V) += xor.o
diff --git a/arch/riscv/lib/crc32.c b/arch/riscv/lib/crc32.c
new file mode 100644
index 000000000000..d7dc599af3ef
--- /dev/null
+++ b/arch/riscv/lib/crc32.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC32 implementation with Zbc extension.
+ *
+ * Copyright (C) 2024 Intel Corporation
+ */
+
+#include <asm/hwcap.h>
+#include <asm/alternative-macros.h>
+#include <asm/byteorder.h>
+
+#include <linux/types.h>
+#include <linux/minmax.h>
+#include <linux/crc32poly.h>
+#include <linux/crc32.h>
+#include <linux/byteorder/generic.h>
+
+/*
+ * Refer to https://www.corsix.org/content/barrett-reduction-polynomials for
+ * better understanding of how this math works.
+ *
+ * let "+" denotes polynomial add (XOR)
+ * let "-" denotes polynomial sub (XOR)
+ * let "*" denotes polynomial multiplication
+ * let "/" denotes polynomial floor division
+ * let "S" denotes source data, XLEN bit wide
+ * let "P" denotes CRC32 polynomial
+ * let "T" denotes 2^(XLEN+32)
+ * let "QT" denotes quotient of T/P, with the bit for 2^XLEN being implicit
+ *
+ * crc32(S, P)
+ * => S * (2^32) - S * (2^32) / P * P
+ * => lowest 32 bits of: S * (2^32) / P * P
+ * => lowest 32 bits of: S * (2^32) * (T / P) / T * P
+ * => lowest 32 bits of: S * (2^32) * quotient / T * P
+ * => lowest 32 bits of: S * quotient / 2^XLEN * P
+ * => lowest 32 bits of: (clmul_high_part(S, QT) + S) * P
+ * => clmul_low_part(clmul_high_part(S, QT) + S, P)
+ *
+ * In terms of below implementations, the BE case is more intuitive, since the
+ * higher order bit sits at more significant position.
+ */
+
+#if __riscv_xlen == 64
+/* Slide by XLEN bits per iteration */
+# define STEP_ORDER 3
+
+/* Each below polynomial quotient has an implicit bit for 2^XLEN */
+
+/* Polynomial quotient of (2^(XLEN+32))/CRC32_POLY, in LE format */
+# define CRC32_POLY_QT_LE 0x5a72d812fb808b20
+
+/* Polynomial quotient of (2^(XLEN+32))/CRC32C_POLY, in LE format */
+# define CRC32C_POLY_QT_LE 0xa434f61c6f5389f8
+
+/* Polynomial quotient of (2^(XLEN+32))/CRC32_POLY, in BE format, it should be
+ * the same as the bit-reversed version of CRC32_POLY_QT_LE
+ */
+# define CRC32_POLY_QT_BE 0x04d101df481b4e5a
+
+static inline u64 crc32_le_prep(u32 crc, unsigned long const *ptr)
+{
+ return (u64)crc ^ (__force u64)__cpu_to_le64(*ptr);
+}
+
+static inline u32 crc32_le_zbc(unsigned long s, u32 poly, unsigned long poly_qt)
+{
+ u32 crc;
+
+ /* We don't have a "clmulrh" insn, so use clmul + slli instead. */
+ asm volatile (".option push\n"
+ ".option arch,+zbc\n"
+ "clmul %0, %1, %2\n"
+ "slli %0, %0, 1\n"
+ "xor %0, %0, %1\n"
+ "clmulr %0, %0, %3\n"
+ "srli %0, %0, 32\n"
+ ".option pop\n"
+ : "=&r" (crc)
+ : "r" (s),
+ "r" (poly_qt),
+ "r" ((u64)poly << 32)
+ :);
+ return crc;
+}
+
+static inline u64 crc32_be_prep(u32 crc, unsigned long const *ptr)
+{
+ return ((u64)crc << 32) ^ (__force u64)__cpu_to_be64(*ptr);
+}
+
+#elif __riscv_xlen == 32
+# define STEP_ORDER 2
+/* Each quotient should match the upper half of its analog in RV64 */
+# define CRC32_POLY_QT_LE 0xfb808b20
+# define CRC32C_POLY_QT_LE 0x6f5389f8
+# define CRC32_POLY_QT_BE 0x04d101df
+
+static inline u32 crc32_le_prep(u32 crc, unsigned long const *ptr)
+{
+ return crc ^ (__force u32)__cpu_to_le32(*ptr);
+}
+
+static inline u32 crc32_le_zbc(unsigned long s, u32 poly, unsigned long poly_qt)
+{
+ u32 crc;
+
+ /* We don't have a "clmulrh" insn, so use clmul + slli instead. */
+ asm volatile (".option push\n"
+ ".option arch,+zbc\n"
+ "clmul %0, %1, %2\n"
+ "slli %0, %0, 1\n"
+ "xor %0, %0, %1\n"
+ "clmulr %0, %0, %3\n"
+ ".option pop\n"
+ : "=&r" (crc)
+ : "r" (s),
+ "r" (poly_qt),
+ "r" (poly)
+ :);
+ return crc;
+}
+
+static inline u32 crc32_be_prep(u32 crc, unsigned long const *ptr)
+{
+ return crc ^ (__force u32)__cpu_to_be32(*ptr);
+}
+
+#else
+# error "Unexpected __riscv_xlen"
+#endif
+
+static inline u32 crc32_be_zbc(unsigned long s)
+{
+ u32 crc;
+
+ asm volatile (".option push\n"
+ ".option arch,+zbc\n"
+ "clmulh %0, %1, %2\n"
+ "xor %0, %0, %1\n"
+ "clmul %0, %0, %3\n"
+ ".option pop\n"
+ : "=&r" (crc)
+ : "r" (s),
+ "r" (CRC32_POLY_QT_BE),
+ "r" (CRC32_POLY_BE)
+ :);
+ return crc;
+}
+
+#define STEP (1 << STEP_ORDER)
+#define OFFSET_MASK (STEP - 1)
+
+typedef u32 (*fallback)(u32 crc, unsigned char const *p, size_t len);
+
+static inline u32 crc32_le_unaligned(u32 crc, unsigned char const *p,
+ size_t len, u32 poly,
+ unsigned long poly_qt)
+{
+ size_t bits = len * 8;
+ unsigned long s = 0;
+ u32 crc_low = 0;
+
+ for (int i = 0; i < len; i++)
+ s = ((unsigned long)*p++ << (__riscv_xlen - 8)) | (s >> 8);
+
+ s ^= (unsigned long)crc << (__riscv_xlen - bits);
+ if (__riscv_xlen == 32 || len < sizeof(u32))
+ crc_low = crc >> bits;
+
+ crc = crc32_le_zbc(s, poly, poly_qt);
+ crc ^= crc_low;
+
+ return crc;
+}
+
+static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
+ size_t len, u32 poly,
+ unsigned long poly_qt,
+ fallback crc_fb)
+{
+ size_t offset, head_len, tail_len;
+ unsigned long const *p_ul;
+ unsigned long s;
+
+ asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
+ RISCV_ISA_EXT_ZBC, 1)
+ : : : : legacy);
+
+ /* Handle the unaligned head. */
+ offset = (unsigned long)p & OFFSET_MASK;
+ if (offset && len) {
+ head_len = min(STEP - offset, len);
+ crc = crc32_le_unaligned(crc, p, head_len, poly, poly_qt);
+ p += head_len;
+ len -= head_len;
+ }
+
+ tail_len = len & OFFSET_MASK;
+ len = len >> STEP_ORDER;
+ p_ul = (unsigned long const *)p;
+
+ for (int i = 0; i < len; i++) {
+ s = crc32_le_prep(crc, p_ul);
+ crc = crc32_le_zbc(s, poly, poly_qt);
+ p_ul++;
+ }
+
+ /* Handle the tail bytes. */
+ p = (unsigned char const *)p_ul;
+ if (tail_len)
+ crc = crc32_le_unaligned(crc, p, tail_len, poly, poly_qt);
+
+ return crc;
+
+legacy:
+ return crc_fb(crc, p, len);
+}
+
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+ return crc32_le_generic(crc, p, len, CRC32_POLY_LE, CRC32_POLY_QT_LE,
+ crc32_le_base);
+}
+
+u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+ return crc32_le_generic(crc, p, len, CRC32C_POLY_LE,
+ CRC32C_POLY_QT_LE, __crc32c_le_base);
+}
+
+static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
+ size_t len)
+{
+ size_t bits = len * 8;
+ unsigned long s = 0;
+ u32 crc_low = 0;
+
+ s = 0;
+ for (int i = 0; i < len; i++)
+ s = *p++ | (s << 8);
+
+ if (__riscv_xlen == 32 || len < sizeof(u32)) {
+ s ^= crc >> (32 - bits);
+ crc_low = crc << bits;
+ } else {
+ s ^= (unsigned long)crc << (bits - 32);
+ }
+
+ crc = crc32_be_zbc(s);
+ crc ^= crc_low;
+
+ return crc;
+}
+
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+ size_t offset, head_len, tail_len;
+ unsigned long const *p_ul;
+ unsigned long s;
+
+ asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
+ RISCV_ISA_EXT_ZBC, 1)
+ : : : : legacy);
+
+ /* Handle the unaligned head. */
+ offset = (unsigned long)p & OFFSET_MASK;
+ if (offset && len) {
+ head_len = min(STEP - offset, len);
+ crc = crc32_be_unaligned(crc, p, head_len);
+ p += head_len;
+ len -= head_len;
+ }
+
+ tail_len = len & OFFSET_MASK;
+ len = len >> STEP_ORDER;
+ p_ul = (unsigned long const *)p;
+
+ for (int i = 0; i < len; i++) {
+ s = crc32_be_prep(crc, p_ul);
+ crc = crc32_be_zbc(s);
+ p_ul++;
+ }
+
+ /* Handle the tail bytes. */
+ p = (unsigned char const *)p_ul;
+ if (tail_len)
+ crc = crc32_be_unaligned(crc, p, tail_len);
+
+ return crc;
+
+legacy:
+ return crc32_be_base(crc, p, len);
+}
diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
index bc22c078aba8..6a9f116bb545 100644
--- a/arch/riscv/lib/uaccess.S
+++ b/arch/riscv/lib/uaccess.S
@@ -14,7 +14,7 @@
SYM_FUNC_START(__asm_copy_to_user)
#ifdef CONFIG_RISCV_ISA_V
- ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_v, CONFIG_RISCV_ISA_V)
+ ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_ZVE32X, CONFIG_RISCV_ISA_V)
REG_L t0, riscv_v_usercopy_threshold
bltu a2, t0, fallback_scalar_usercopy
tail enter_vector_usercopy
@@ -44,7 +44,7 @@ SYM_FUNC_START(fallback_scalar_usercopy)
* Use byte copy only if too small.
* SZREG holds 4 for RV32 and 8 for RV64
*/
- li a3, 9*SZREG /* size must be larger than size in word_copy */
+ li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */
bltu a2, a3, .Lbyte_copy_tail
/*
@@ -103,7 +103,7 @@ SYM_FUNC_START(fallback_scalar_usercopy)
fixup REG_S t4, 7*SZREG(a0), 10f
addi a0, a0, 8*SZREG
addi a1, a1, 8*SZREG
- bltu a0, t0, 2b
+ bleu a0, t0, 2b
addi t0, t0, 8*SZREG /* revert to original value */
j .Lbyte_copy_tail
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index 2c869f8026a8..cbe4d775ef56 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -13,14 +13,11 @@ endif
KCOV_INSTRUMENT_init.o := n
obj-y += init.o
-obj-$(CONFIG_MMU) += extable.o fault.o pageattr.o pgtable.o
+obj-$(CONFIG_MMU) += extable.o fault.o pageattr.o pgtable.o tlbflush.o
obj-y += cacheflush.o
obj-y += context.o
obj-y += pmem.o
-ifeq ($(CONFIG_MMU),y)
-obj-$(CONFIG_SMP) += tlbflush.o
-endif
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PTDUMP_CORE) += ptdump.o
obj-$(CONFIG_KASAN) += kasan_init.o
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index bc61ee5975e4..a03c994eed3b 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -5,6 +5,7 @@
#include <linux/acpi.h>
#include <linux/of.h>
+#include <linux/prctl.h>
#include <asm/acpi.h>
#include <asm/cacheflush.h>
@@ -21,7 +22,9 @@ void flush_icache_all(void)
{
local_flush_icache_all();
- if (IS_ENABLED(CONFIG_RISCV_SBI) && !riscv_use_ipi_for_rfence())
+ if (num_online_cpus() < 2)
+ return;
+ else if (riscv_use_sbi_for_rfence())
sbi_remote_fence_i(NULL);
else
on_each_cpu(ipi_remote_fence_i, NULL, 1);
@@ -69,8 +72,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
* with flush_icache_deferred().
*/
smp_mb();
- } else if (IS_ENABLED(CONFIG_RISCV_SBI) &&
- !riscv_use_ipi_for_rfence()) {
+ } else if (riscv_use_sbi_for_rfence()) {
sbi_remote_fence_i(&others);
} else {
on_each_cpu_mask(&others, ipi_remote_fence_i, NULL, 1);
@@ -152,3 +154,115 @@ void __init riscv_init_cbo_blocksizes(void)
if (cboz_block_size)
riscv_cboz_block_size = cboz_block_size;
}
+
+#ifdef CONFIG_SMP
+static void set_icache_stale_mask(void)
+{
+ cpumask_t *mask;
+ bool stale_cpu;
+
+ /*
+ * Mark every other hart's icache as needing a flush for
+ * this MM. Maintain the previous value of the current
+ * cpu to handle the case when this function is called
+ * concurrently on different harts.
+ */
+ mask = &current->mm->context.icache_stale_mask;
+ stale_cpu = cpumask_test_cpu(smp_processor_id(), mask);
+
+ cpumask_setall(mask);
+ cpumask_assign_cpu(smp_processor_id(), mask, stale_cpu);
+}
+#endif
+
+/**
+ * riscv_set_icache_flush_ctx() - Enable/disable icache flushing instructions in
+ * userspace.
+ * @ctx: Set the type of icache flushing instructions permitted/prohibited in
+ * userspace. Supported values described below.
+ *
+ * Supported values for ctx:
+ *
+ * * %PR_RISCV_CTX_SW_FENCEI_ON: Allow fence.i in user space.
+ *
+ * * %PR_RISCV_CTX_SW_FENCEI_OFF: Disallow fence.i in user space. All threads in
+ * a process will be affected when ``scope == PR_RISCV_SCOPE_PER_PROCESS``.
+ * Therefore, caution must be taken; use this flag only when you can guarantee
+ * that no thread in the process will emit fence.i from this point onward.
+ *
+ * @scope: Set scope of where icache flushing instructions are allowed to be
+ * emitted. Supported values described below.
+ *
+ * Supported values for scope:
+ *
+ * * %PR_RISCV_SCOPE_PER_PROCESS: Ensure the icache of any thread in this process
+ * is coherent with instruction storage upon
+ * migration.
+ *
+ * * %PR_RISCV_SCOPE_PER_THREAD: Ensure the icache of the current thread is
+ * coherent with instruction storage upon
+ * migration.
+ *
+ * When ``scope == PR_RISCV_SCOPE_PER_PROCESS``, all threads in the process are
+ * permitted to emit icache flushing instructions. Whenever any thread in the
+ * process is migrated, the corresponding hart's icache will be guaranteed to be
+ * consistent with instruction storage. This does not enforce any guarantees
+ * outside of migration. If a thread modifies an instruction that another thread
+ * may attempt to execute, the other thread must still emit an icache flushing
+ * instruction before attempting to execute the potentially modified
+ * instruction. This must be performed by the user-space program.
+ *
+ * In per-thread context (eg. ``scope == PR_RISCV_SCOPE_PER_THREAD``) only the
+ * thread calling this function is permitted to emit icache flushing
+ * instructions. When the thread is migrated, the corresponding hart's icache
+ * will be guaranteed to be consistent with instruction storage.
+ *
+ * On kernels configured without SMP, this function is a nop as migrations
+ * across harts will not occur.
+ */
+int riscv_set_icache_flush_ctx(unsigned long ctx, unsigned long scope)
+{
+#ifdef CONFIG_SMP
+ switch (ctx) {
+ case PR_RISCV_CTX_SW_FENCEI_ON:
+ switch (scope) {
+ case PR_RISCV_SCOPE_PER_PROCESS:
+ current->mm->context.force_icache_flush = true;
+ break;
+ case PR_RISCV_SCOPE_PER_THREAD:
+ current->thread.force_icache_flush = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case PR_RISCV_CTX_SW_FENCEI_OFF:
+ switch (scope) {
+ case PR_RISCV_SCOPE_PER_PROCESS:
+ current->mm->context.force_icache_flush = false;
+
+ set_icache_stale_mask();
+ break;
+ case PR_RISCV_SCOPE_PER_THREAD:
+ current->thread.force_icache_flush = false;
+
+ set_icache_stale_mask();
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+#else
+ switch (ctx) {
+ case PR_RISCV_CTX_SW_FENCEI_ON:
+ case PR_RISCV_CTX_SW_FENCEI_OFF:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+#endif
+}
diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
index ba8eb3944687..4abe3de23225 100644
--- a/arch/riscv/mm/context.c
+++ b/arch/riscv/mm/context.c
@@ -15,14 +15,13 @@
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
+#include <asm/switch_to.h>
#ifdef CONFIG_MMU
DEFINE_STATIC_KEY_FALSE(use_asid_allocator);
-static unsigned long asid_bits;
static unsigned long num_asids;
-unsigned long asid_mask;
static atomic_long_t current_version;
@@ -81,7 +80,7 @@ static void __flush_context(void)
if (cntx == 0)
cntx = per_cpu(reserved_context, i);
- __set_bit(cntx & asid_mask, context_asid_map);
+ __set_bit(cntx2asid(cntx), context_asid_map);
per_cpu(reserved_context, i) = cntx;
}
@@ -102,7 +101,7 @@ static unsigned long __new_context(struct mm_struct *mm)
lockdep_assert_held(&context_lock);
if (cntx != 0) {
- unsigned long newcntx = ver | (cntx & asid_mask);
+ unsigned long newcntx = ver | cntx2asid(cntx);
/*
* If our current CONTEXT was active during a rollover, we
@@ -115,7 +114,7 @@ static unsigned long __new_context(struct mm_struct *mm)
* We had a valid CONTEXT in a previous life, so try to
* re-use it if possible.
*/
- if (!__test_and_set_bit(cntx & asid_mask, context_asid_map))
+ if (!__test_and_set_bit(cntx2asid(cntx), context_asid_map))
return newcntx;
}
@@ -128,7 +127,7 @@ static unsigned long __new_context(struct mm_struct *mm)
goto set_asid;
/* We're out of ASIDs, so increment current_version */
- ver = atomic_long_add_return_relaxed(num_asids, &current_version);
+ ver = atomic_long_add_return_relaxed(BIT(SATP_ASID_BITS), &current_version);
/* Flush everything */
__flush_context();
@@ -168,7 +167,7 @@ static void set_mm_asid(struct mm_struct *mm, unsigned int cpu)
*/
old_active_cntx = atomic_long_read(&per_cpu(active_context, cpu));
if (old_active_cntx &&
- ((cntx & ~asid_mask) == atomic_long_read(&current_version)) &&
+ (cntx2version(cntx) == atomic_long_read(&current_version)) &&
atomic_long_cmpxchg_relaxed(&per_cpu(active_context, cpu),
old_active_cntx, cntx))
goto switch_mm_fast;
@@ -177,7 +176,7 @@ static void set_mm_asid(struct mm_struct *mm, unsigned int cpu)
/* Check that our ASID belongs to the current_version. */
cntx = atomic_long_read(&mm->context.id);
- if ((cntx & ~asid_mask) != atomic_long_read(&current_version)) {
+ if (cntx2version(cntx) != atomic_long_read(&current_version)) {
cntx = __new_context(mm);
atomic_long_set(&mm->context.id, cntx);
}
@@ -191,7 +190,7 @@ static void set_mm_asid(struct mm_struct *mm, unsigned int cpu)
switch_mm_fast:
csr_write(CSR_SATP, virt_to_pfn(mm->pgd) |
- ((cntx & asid_mask) << SATP_ASID_SHIFT) |
+ (cntx2asid(cntx) << SATP_ASID_SHIFT) |
satp_mode);
if (need_flush_tlb)
@@ -202,7 +201,7 @@ static void set_mm_noasid(struct mm_struct *mm)
{
/* Switch the page table and blindly nuke entire local TLB */
csr_write(CSR_SATP, virt_to_pfn(mm->pgd) | satp_mode);
- local_flush_tlb_all();
+ local_flush_tlb_all_asid(0);
}
static inline void set_mm(struct mm_struct *prev,
@@ -227,7 +226,7 @@ static inline void set_mm(struct mm_struct *prev,
static int __init asids_init(void)
{
- unsigned long old;
+ unsigned long asid_bits, old;
/* Figure-out number of ASID bits in HW */
old = csr_read(CSR_SATP);
@@ -247,7 +246,6 @@ static int __init asids_init(void)
/* Pre-compute ASID details */
if (asid_bits) {
num_asids = 1 << asid_bits;
- asid_mask = num_asids - 1;
}
/*
@@ -255,7 +253,7 @@ static int __init asids_init(void)
* at-least twice more than CPUs
*/
if (num_asids > (2 * num_possible_cpus())) {
- atomic_long_set(&current_version, num_asids);
+ atomic_long_set(&current_version, BIT(SATP_ASID_BITS));
context_asid_map = bitmap_zalloc(num_asids, GFP_KERNEL);
if (!context_asid_map)
@@ -297,21 +295,23 @@ static inline void set_mm(struct mm_struct *prev,
*
* The "cpu" argument must be the current local CPU number.
*/
-static inline void flush_icache_deferred(struct mm_struct *mm, unsigned int cpu)
+static inline void flush_icache_deferred(struct mm_struct *mm, unsigned int cpu,
+ struct task_struct *task)
{
#ifdef CONFIG_SMP
- cpumask_t *mask = &mm->context.icache_stale_mask;
-
- if (cpumask_test_cpu(cpu, mask)) {
- cpumask_clear_cpu(cpu, mask);
+ if (cpumask_test_and_clear_cpu(cpu, &mm->context.icache_stale_mask)) {
/*
* Ensure the remote hart's writes are visible to this hart.
* This pairs with a barrier in flush_icache_mm.
*/
smp_mb();
- local_flush_icache_all();
- }
+ /*
+ * If cache will be flushed in switch_to, no need to flush here.
+ */
+ if (!(task && switch_to_should_flush_icache(task)))
+ local_flush_icache_all();
+ }
#endif
}
@@ -334,5 +334,5 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
set_mm(prev, next, cpu);
- flush_icache_deferred(next, cpu);
+ flush_icache_deferred(next, cpu, task);
}
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index 843107f834b2..cb89d7e0ba88 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -128,8 +128,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
ALT_CMO_OP(FLUSH, flush_addr, size, riscv_cbom_block_size);
}
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
{
WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
TAINT_CPU_OUT_OF_SPEC,
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 3ba1d4dde5dd..5224f3733802 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -292,7 +292,10 @@ void handle_page_fault(struct pt_regs *regs)
if (unlikely(access_error(cause, vma))) {
vma_end_read(vma);
- goto lock_mmap;
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ tsk->thread.bad_cause = cause;
+ bad_area_nosemaphore(regs, SEGV_ACCERR, addr);
+ return;
}
fault = handle_mm_fault(vma, addr, flags | FAULT_FLAG_VMA_LOCK, regs);
diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
index 5ef2a6891158..42314f093922 100644
--- a/arch/riscv/mm/hugetlbpage.c
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -3,7 +3,7 @@
#include <linux/err.h>
#ifdef CONFIG_RISCV_ISA_SVNAPOT
-pte_t huge_ptep_get(pte_t *ptep)
+pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
unsigned long pte_num;
int i;
@@ -399,16 +399,6 @@ static bool is_napot_size(unsigned long size)
#endif /*CONFIG_RISCV_ISA_SVNAPOT*/
-int pud_huge(pud_t pud)
-{
- return pud_leaf(pud);
-}
-
-int pmd_huge(pmd_t pmd)
-{
- return pmd_leaf(pmd);
-}
-
static bool __hugetlb_valid_size(unsigned long size)
{
if (size == HPAGE_SIZE)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 968761843203..bfa2dea95354 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -24,9 +24,11 @@
#include <linux/elf.h>
#endif
#include <linux/kfence.h>
+#include <linux/execmem.h>
#include <asm/fixmap.h>
#include <asm/io.h>
+#include <asm/kasan.h>
#include <asm/numa.h>
#include <asm/pgtable.h>
#include <asm/sections.h>
@@ -49,8 +51,8 @@ u64 satp_mode __ro_after_init = SATP_MODE_32;
EXPORT_SYMBOL(satp_mode);
#ifdef CONFIG_64BIT
-bool pgtable_l4_enabled = IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL);
-bool pgtable_l5_enabled = IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL);
+bool pgtable_l4_enabled __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL);
+bool pgtable_l5_enabled __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL);
EXPORT_SYMBOL(pgtable_l4_enabled);
EXPORT_SYMBOL(pgtable_l5_enabled);
#endif
@@ -161,11 +163,25 @@ static void print_vm_layout(void) { }
void __init mem_init(void)
{
+ bool swiotlb = max_pfn > PFN_DOWN(dma32_phys_limit);
#ifdef CONFIG_FLATMEM
BUG_ON(!mem_map);
#endif /* CONFIG_FLATMEM */
- swiotlb_init(max_pfn > PFN_DOWN(dma32_phys_limit), SWIOTLB_VERBOSE);
+ if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb &&
+ dma_cache_alignment != 1) {
+ /*
+ * If no bouncing needed for ZONE_DMA, allocate 1MB swiotlb
+ * buffer per 1GB of RAM for kmalloc() bouncing on
+ * non-coherent platforms.
+ */
+ unsigned long size =
+ DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
+ swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
+ swiotlb = true;
+ }
+
+ swiotlb_init(swiotlb, SWIOTLB_VERBOSE);
memblock_free_all();
print_vm_layout();
@@ -235,18 +251,19 @@ static void __init setup_bootmem(void)
kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
/*
- * memblock allocator is not aware of the fact that last 4K bytes of
- * the addressable memory can not be mapped because of IS_ERR_VALUE
- * macro. Make sure that last 4k bytes are not usable by memblock
- * if end of dram is equal to maximum addressable memory. For 64-bit
- * kernel, this problem can't happen here as the end of the virtual
- * address space is occupied by the kernel mapping then this check must
- * be done as soon as the kernel mapping base address is determined.
+ * Reserve physical address space that would be mapped to virtual
+ * addresses greater than (void *)(-PAGE_SIZE) because:
+ * - This memory would overlap with ERR_PTR
+ * - This memory belongs to high memory, which is not supported
+ *
+ * This is not applicable to 64-bit kernel, because virtual addresses
+ * after (void *)(-PAGE_SIZE) are not linearly mapped: they are
+ * occupied by kernel mapping. Also it is unrealistic for high memory
+ * to exist on 64-bit platforms.
*/
if (!IS_ENABLED(CONFIG_64BIT)) {
- max_mapped_addr = __pa(~(ulong)0);
- if (max_mapped_addr == (phys_ram_end - 1))
- memblock_set_current_limit(max_mapped_addr - 4096);
+ max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE);
+ memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr);
}
min_low_pfn = PFN_UP(phys_ram_base);
@@ -280,7 +297,7 @@ static void __init setup_bootmem(void)
}
#ifdef CONFIG_MMU
-struct pt_alloc_ops pt_ops __initdata;
+struct pt_alloc_ops pt_ops __meminitdata;
pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
@@ -342,7 +359,7 @@ static inline pte_t *__init get_pte_virt_fixmap(phys_addr_t pa)
return (pte_t *)set_fixmap_offset(FIX_PTE, pa);
}
-static inline pte_t *__init get_pte_virt_late(phys_addr_t pa)
+static inline pte_t *__meminit get_pte_virt_late(phys_addr_t pa)
{
return (pte_t *) __va(pa);
}
@@ -361,7 +378,7 @@ static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __init alloc_pte_late(uintptr_t va)
+static phys_addr_t __meminit alloc_pte_late(uintptr_t va)
{
struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0);
@@ -369,9 +386,8 @@ static phys_addr_t __init alloc_pte_late(uintptr_t va)
return __pa((pte_t *)ptdesc_address(ptdesc));
}
-static void __init create_pte_mapping(pte_t *ptep,
- uintptr_t va, phys_addr_t pa,
- phys_addr_t sz, pgprot_t prot)
+static void __meminit create_pte_mapping(pte_t *ptep, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
+ pgprot_t prot)
{
uintptr_t pte_idx = pte_index(va);
@@ -425,7 +441,7 @@ static pmd_t *__init get_pmd_virt_fixmap(phys_addr_t pa)
return (pmd_t *)set_fixmap_offset(FIX_PMD, pa);
}
-static pmd_t *__init get_pmd_virt_late(phys_addr_t pa)
+static pmd_t *__meminit get_pmd_virt_late(phys_addr_t pa)
{
return (pmd_t *) __va(pa);
}
@@ -442,7 +458,7 @@ static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __init alloc_pmd_late(uintptr_t va)
+static phys_addr_t __meminit alloc_pmd_late(uintptr_t va)
{
struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0);
@@ -450,9 +466,9 @@ static phys_addr_t __init alloc_pmd_late(uintptr_t va)
return __pa((pmd_t *)ptdesc_address(ptdesc));
}
-static void __init create_pmd_mapping(pmd_t *pmdp,
- uintptr_t va, phys_addr_t pa,
- phys_addr_t sz, pgprot_t prot)
+static void __meminit create_pmd_mapping(pmd_t *pmdp,
+ uintptr_t va, phys_addr_t pa,
+ phys_addr_t sz, pgprot_t prot)
{
pte_t *ptep;
phys_addr_t pte_phys;
@@ -488,7 +504,7 @@ static pud_t *__init get_pud_virt_fixmap(phys_addr_t pa)
return (pud_t *)set_fixmap_offset(FIX_PUD, pa);
}
-static pud_t *__init get_pud_virt_late(phys_addr_t pa)
+static pud_t *__meminit get_pud_virt_late(phys_addr_t pa)
{
return (pud_t *)__va(pa);
}
@@ -506,7 +522,7 @@ static phys_addr_t __init alloc_pud_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t alloc_pud_late(uintptr_t va)
+static phys_addr_t __meminit alloc_pud_late(uintptr_t va)
{
unsigned long vaddr;
@@ -526,7 +542,7 @@ static p4d_t *__init get_p4d_virt_fixmap(phys_addr_t pa)
return (p4d_t *)set_fixmap_offset(FIX_P4D, pa);
}
-static p4d_t *__init get_p4d_virt_late(phys_addr_t pa)
+static p4d_t *__meminit get_p4d_virt_late(phys_addr_t pa)
{
return (p4d_t *)__va(pa);
}
@@ -544,7 +560,7 @@ static phys_addr_t __init alloc_p4d_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t alloc_p4d_late(uintptr_t va)
+static phys_addr_t __meminit alloc_p4d_late(uintptr_t va)
{
unsigned long vaddr;
@@ -553,9 +569,8 @@ static phys_addr_t alloc_p4d_late(uintptr_t va)
return __pa(vaddr);
}
-static void __init create_pud_mapping(pud_t *pudp,
- uintptr_t va, phys_addr_t pa,
- phys_addr_t sz, pgprot_t prot)
+static void __meminit create_pud_mapping(pud_t *pudp, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
+ pgprot_t prot)
{
pmd_t *nextp;
phys_addr_t next_phys;
@@ -580,9 +595,8 @@ static void __init create_pud_mapping(pud_t *pudp,
create_pmd_mapping(nextp, va, pa, sz, prot);
}
-static void __init create_p4d_mapping(p4d_t *p4dp,
- uintptr_t va, phys_addr_t pa,
- phys_addr_t sz, pgprot_t prot)
+static void __meminit create_p4d_mapping(p4d_t *p4dp, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
+ pgprot_t prot)
{
pud_t *nextp;
phys_addr_t next_phys;
@@ -638,9 +652,8 @@ static void __init create_p4d_mapping(p4d_t *p4dp,
#define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
#endif /* __PAGETABLE_PMD_FOLDED */
-void __init create_pgd_mapping(pgd_t *pgdp,
- uintptr_t va, phys_addr_t pa,
- phys_addr_t sz, pgprot_t prot)
+void __meminit create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
+ pgprot_t prot)
{
pgd_next_t *nextp;
phys_addr_t next_phys;
@@ -665,9 +678,11 @@ void __init create_pgd_mapping(pgd_t *pgdp,
create_pgd_next_mapping(nextp, va, pa, sz, prot);
}
-static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
- phys_addr_t size)
+static uintptr_t __meminit best_map_size(phys_addr_t pa, uintptr_t va, phys_addr_t size)
{
+ if (debug_pagealloc_enabled())
+ return PAGE_SIZE;
+
if (pgtable_l5_enabled &&
!(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
return P4D_SIZE;
@@ -699,7 +714,7 @@ asmlinkage void __init __copy_data(void)
#endif
#ifdef CONFIG_STRICT_KERNEL_RWX
-static __init pgprot_t pgprot_from_va(uintptr_t va)
+static __meminit pgprot_t pgprot_from_va(uintptr_t va)
{
if (is_va_kernel_text(va))
return PAGE_KERNEL_READ_EXEC;
@@ -724,7 +739,7 @@ void mark_rodata_ro(void)
set_memory_ro);
}
#else
-static __init pgprot_t pgprot_from_va(uintptr_t va)
+static __meminit pgprot_t pgprot_from_va(uintptr_t va)
{
if (IS_ENABLED(CONFIG_64BIT) && !is_kernel_mapping(va))
return PAGE_KERNEL;
@@ -1216,9 +1231,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
pt_ops_set_fixmap();
}
-static void __init create_linear_mapping_range(phys_addr_t start,
- phys_addr_t end,
- uintptr_t fixed_map_size)
+static void __meminit create_linear_mapping_range(phys_addr_t start, phys_addr_t end,
+ uintptr_t fixed_map_size, const pgprot_t *pgprot)
{
phys_addr_t pa;
uintptr_t va, map_size;
@@ -1229,7 +1243,7 @@ static void __init create_linear_mapping_range(phys_addr_t start,
best_map_size(pa, va, end - pa);
create_pgd_mapping(swapper_pg_dir, va, pa, map_size,
- pgprot_from_va(va));
+ pgprot ? *pgprot : pgprot_from_va(va));
}
}
@@ -1273,22 +1287,19 @@ static void __init create_linear_mapping_page_table(void)
if (end >= __pa(PAGE_OFFSET) + memory_limit)
end = __pa(PAGE_OFFSET) + memory_limit;
- create_linear_mapping_range(start, end, 0);
+ create_linear_mapping_range(start, end, 0, NULL);
}
#ifdef CONFIG_STRICT_KERNEL_RWX
- create_linear_mapping_range(ktext_start, ktext_start + ktext_size, 0);
- create_linear_mapping_range(krodata_start,
- krodata_start + krodata_size, 0);
+ create_linear_mapping_range(ktext_start, ktext_start + ktext_size, 0, NULL);
+ create_linear_mapping_range(krodata_start, krodata_start + krodata_size, 0, NULL);
memblock_clear_nomap(ktext_start, ktext_size);
memblock_clear_nomap(krodata_start, krodata_size);
#endif
#ifdef CONFIG_KFENCE
- create_linear_mapping_range(kfence_pool,
- kfence_pool + KFENCE_POOL_SIZE,
- PAGE_SIZE);
+ create_linear_mapping_range(kfence_pool, kfence_pool + KFENCE_POOL_SIZE, PAGE_SIZE, NULL);
memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
#endif
@@ -1420,7 +1431,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
* memory hotplug, we are not able to update all the page tables with
* the new PMDs.
*/
- return vmemmap_populate_hugepages(start, end, node, NULL);
+ return vmemmap_populate_hugepages(start, end, node, altmap);
}
#endif
@@ -1474,10 +1485,319 @@ failed:
panic("Failed to pre-allocate %s pages for %s area\n", lvl, area);
}
+#define PAGE_END KASAN_SHADOW_START
+
void __init pgtable_cache_init(void)
{
preallocate_pgd_pages_range(VMALLOC_START, VMALLOC_END, "vmalloc");
if (IS_ENABLED(CONFIG_MODULES))
preallocate_pgd_pages_range(MODULES_VADDR, MODULES_END, "bpf/modules");
+ if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG)) {
+ preallocate_pgd_pages_range(VMEMMAP_START, VMEMMAP_END, "vmemmap");
+ preallocate_pgd_pages_range(PAGE_OFFSET, PAGE_END, "direct map");
+ if (IS_ENABLED(CONFIG_KASAN))
+ preallocate_pgd_pages_range(KASAN_SHADOW_START, KASAN_SHADOW_END, "kasan");
+ }
}
#endif
+
+#ifdef CONFIG_EXECMEM
+#ifdef CONFIG_MMU
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = MODULES_VADDR,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ },
+ [EXECMEM_KPROBES] = {
+ .start = VMALLOC_START,
+ .end = VMALLOC_END,
+ .pgprot = PAGE_KERNEL_READ_EXEC,
+ .alignment = 1,
+ },
+ [EXECMEM_BPF] = {
+ .start = BPF_JIT_REGION_START,
+ .end = BPF_JIT_REGION_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = PAGE_SIZE,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_MMU */
+#endif /* CONFIG_EXECMEM */
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
+{
+ struct page *page = pmd_page(*pmd);
+ struct ptdesc *ptdesc = page_ptdesc(page);
+ pte_t *pte;
+ int i;
+
+ for (i = 0; i < PTRS_PER_PTE; i++) {
+ pte = pte_start + i;
+ if (!pte_none(*pte))
+ return;
+ }
+
+ pagetable_pte_dtor(ptdesc);
+ if (PageReserved(page))
+ free_reserved_page(page);
+ else
+ pagetable_free(ptdesc);
+ pmd_clear(pmd);
+}
+
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
+{
+ struct page *page = pud_page(*pud);
+ struct ptdesc *ptdesc = page_ptdesc(page);
+ pmd_t *pmd;
+ int i;
+
+ for (i = 0; i < PTRS_PER_PMD; i++) {
+ pmd = pmd_start + i;
+ if (!pmd_none(*pmd))
+ return;
+ }
+
+ pagetable_pmd_dtor(ptdesc);
+ if (PageReserved(page))
+ free_reserved_page(page);
+ else
+ pagetable_free(ptdesc);
+ pud_clear(pud);
+}
+
+static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
+{
+ struct page *page = p4d_page(*p4d);
+ pud_t *pud;
+ int i;
+
+ for (i = 0; i < PTRS_PER_PUD; i++) {
+ pud = pud_start + i;
+ if (!pud_none(*pud))
+ return;
+ }
+
+ if (PageReserved(page))
+ free_reserved_page(page);
+ else
+ free_pages((unsigned long)page_address(page), 0);
+ p4d_clear(p4d);
+}
+
+static void __meminit free_vmemmap_storage(struct page *page, size_t size,
+ struct vmem_altmap *altmap)
+{
+ int order = get_order(size);
+
+ if (altmap) {
+ vmem_altmap_free(altmap, size >> PAGE_SHIFT);
+ return;
+ }
+
+ if (PageReserved(page)) {
+ unsigned int nr_pages = 1 << order;
+
+ while (nr_pages--)
+ free_reserved_page(page++);
+ return;
+ }
+
+ free_pages((unsigned long)page_address(page), order);
+}
+
+static void __meminit remove_pte_mapping(pte_t *pte_base, unsigned long addr, unsigned long end,
+ bool is_vmemmap, struct vmem_altmap *altmap)
+{
+ unsigned long next;
+ pte_t *ptep, pte;
+
+ for (; addr < end; addr = next) {
+ next = (addr + PAGE_SIZE) & PAGE_MASK;
+ if (next > end)
+ next = end;
+
+ ptep = pte_base + pte_index(addr);
+ pte = ptep_get(ptep);
+ if (!pte_present(*ptep))
+ continue;
+
+ pte_clear(&init_mm, addr, ptep);
+ if (is_vmemmap)
+ free_vmemmap_storage(pte_page(pte), PAGE_SIZE, altmap);
+ }
+}
+
+static void __meminit remove_pmd_mapping(pmd_t *pmd_base, unsigned long addr, unsigned long end,
+ bool is_vmemmap, struct vmem_altmap *altmap)
+{
+ unsigned long next;
+ pte_t *pte_base;
+ pmd_t *pmdp, pmd;
+
+ for (; addr < end; addr = next) {
+ next = pmd_addr_end(addr, end);
+ pmdp = pmd_base + pmd_index(addr);
+ pmd = pmdp_get(pmdp);
+ if (!pmd_present(pmd))
+ continue;
+
+ if (pmd_leaf(pmd)) {
+ pmd_clear(pmdp);
+ if (is_vmemmap)
+ free_vmemmap_storage(pmd_page(pmd), PMD_SIZE, altmap);
+ continue;
+ }
+
+ pte_base = (pte_t *)pmd_page_vaddr(*pmdp);
+ remove_pte_mapping(pte_base, addr, next, is_vmemmap, altmap);
+ free_pte_table(pte_base, pmdp);
+ }
+}
+
+static void __meminit remove_pud_mapping(pud_t *pud_base, unsigned long addr, unsigned long end,
+ bool is_vmemmap, struct vmem_altmap *altmap)
+{
+ unsigned long next;
+ pud_t *pudp, pud;
+ pmd_t *pmd_base;
+
+ for (; addr < end; addr = next) {
+ next = pud_addr_end(addr, end);
+ pudp = pud_base + pud_index(addr);
+ pud = pudp_get(pudp);
+ if (!pud_present(pud))
+ continue;
+
+ if (pud_leaf(pud)) {
+ if (pgtable_l4_enabled) {
+ pud_clear(pudp);
+ if (is_vmemmap)
+ free_vmemmap_storage(pud_page(pud), PUD_SIZE, altmap);
+ }
+ continue;
+ }
+
+ pmd_base = pmd_offset(pudp, 0);
+ remove_pmd_mapping(pmd_base, addr, next, is_vmemmap, altmap);
+
+ if (pgtable_l4_enabled)
+ free_pmd_table(pmd_base, pudp);
+ }
+}
+
+static void __meminit remove_p4d_mapping(p4d_t *p4d_base, unsigned long addr, unsigned long end,
+ bool is_vmemmap, struct vmem_altmap *altmap)
+{
+ unsigned long next;
+ p4d_t *p4dp, p4d;
+ pud_t *pud_base;
+
+ for (; addr < end; addr = next) {
+ next = p4d_addr_end(addr, end);
+ p4dp = p4d_base + p4d_index(addr);
+ p4d = p4dp_get(p4dp);
+ if (!p4d_present(p4d))
+ continue;
+
+ if (p4d_leaf(p4d)) {
+ if (pgtable_l5_enabled) {
+ p4d_clear(p4dp);
+ if (is_vmemmap)
+ free_vmemmap_storage(p4d_page(p4d), P4D_SIZE, altmap);
+ }
+ continue;
+ }
+
+ pud_base = pud_offset(p4dp, 0);
+ remove_pud_mapping(pud_base, addr, next, is_vmemmap, altmap);
+
+ if (pgtable_l5_enabled)
+ free_pud_table(pud_base, p4dp);
+ }
+}
+
+static void __meminit remove_pgd_mapping(unsigned long va, unsigned long end, bool is_vmemmap,
+ struct vmem_altmap *altmap)
+{
+ unsigned long addr, next;
+ p4d_t *p4d_base;
+ pgd_t *pgd;
+
+ for (addr = va; addr < end; addr = next) {
+ next = pgd_addr_end(addr, end);
+ pgd = pgd_offset_k(addr);
+
+ if (!pgd_present(*pgd))
+ continue;
+
+ if (pgd_leaf(*pgd))
+ continue;
+
+ p4d_base = p4d_offset(pgd, 0);
+ remove_p4d_mapping(p4d_base, addr, next, is_vmemmap, altmap);
+ }
+
+ flush_tlb_all();
+}
+
+static void __meminit remove_linear_mapping(phys_addr_t start, u64 size)
+{
+ unsigned long va = (unsigned long)__va(start);
+ unsigned long end = (unsigned long)__va(start + size);
+
+ remove_pgd_mapping(va, end, false, NULL);
+}
+
+struct range arch_get_mappable_range(void)
+{
+ struct range mhp_range;
+
+ mhp_range.start = __pa(PAGE_OFFSET);
+ mhp_range.end = __pa(PAGE_END - 1);
+ return mhp_range;
+}
+
+int __ref arch_add_memory(int nid, u64 start, u64 size, struct mhp_params *params)
+{
+ int ret = 0;
+
+ create_linear_mapping_range(start, start + size, 0, &params->pgprot);
+ ret = __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, params);
+ if (ret) {
+ remove_linear_mapping(start, size);
+ goto out;
+ }
+
+ max_pfn = PFN_UP(start + size);
+ max_low_pfn = max_pfn;
+
+ out:
+ flush_tlb_all();
+ return ret;
+}
+
+void __ref arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
+{
+ __remove_pages(start >> PAGE_SHIFT, size >> PAGE_SHIFT, altmap);
+ remove_linear_mapping(start, size);
+ flush_tlb_all();
+}
+
+void __ref vmemmap_free(unsigned long start, unsigned long end, struct vmem_altmap *altmap)
+{
+ remove_pgd_mapping(start, end, true, altmap);
+}
+#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 410056a50aa9..271d01a5ba4d 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -387,17 +387,33 @@ int set_direct_map_default_noflush(struct page *page)
}
#ifdef CONFIG_DEBUG_PAGEALLOC
+static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
+{
+ int enable = *(int *)data;
+
+ unsigned long val = pte_val(ptep_get(pte));
+
+ if (enable)
+ val |= _PAGE_PRESENT;
+ else
+ val &= ~_PAGE_PRESENT;
+
+ set_pte(pte, __pte(val));
+
+ return 0;
+}
+
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
if (!debug_pagealloc_enabled())
return;
- if (enable)
- __set_memory((unsigned long)page_address(page), numpages,
- __pgprot(_PAGE_PRESENT), __pgprot(0));
- else
- __set_memory((unsigned long)page_address(page), numpages,
- __pgprot(0), __pgprot(_PAGE_PRESENT));
+ unsigned long start = (unsigned long)page_address(page);
+ unsigned long size = PAGE_SIZE * numpages;
+
+ apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable);
+
+ flush_tlb_kernel_range(start, start + size);
}
#endif
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index 1289cc6d3700..9d5f657a251b 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -6,6 +6,7 @@
#include <linux/efi.h>
#include <linux/init.h>
#include <linux/debugfs.h>
+#include <linux/memory_hotplug.h>
#include <linux/seq_file.h>
#include <linux/ptdump.h>
@@ -370,7 +371,9 @@ bool ptdump_check_wx(void)
static int ptdump_show(struct seq_file *m, void *v)
{
+ get_online_mems();
ptdump_walk(m, m->private);
+ put_online_mems();
return 0;
}
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index 07d743f87b3f..9b6e86ce3867 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -7,34 +7,11 @@
#include <asm/sbi.h>
#include <asm/mmu_context.h>
-static inline void local_flush_tlb_all_asid(unsigned long asid)
-{
- if (asid != FLUSH_TLB_NO_ASID)
- __asm__ __volatile__ ("sfence.vma x0, %0"
- :
- : "r" (asid)
- : "memory");
- else
- local_flush_tlb_all();
-}
-
-static inline void local_flush_tlb_page_asid(unsigned long addr,
- unsigned long asid)
-{
- if (asid != FLUSH_TLB_NO_ASID)
- __asm__ __volatile__ ("sfence.vma %0, %1"
- :
- : "r" (addr), "r" (asid)
- : "memory");
- else
- local_flush_tlb_page(addr);
-}
-
/*
* Flush entire TLB if number of entries to be flushed is greater
* than the threshold below.
*/
-static unsigned long tlb_flush_all_threshold __read_mostly = 64;
+unsigned long tlb_flush_all_threshold __read_mostly = 64;
static void local_flush_tlb_range_threshold_asid(unsigned long start,
unsigned long size,
@@ -79,10 +56,12 @@ static void __ipi_flush_tlb_all(void *info)
void flush_tlb_all(void)
{
- if (riscv_use_ipi_for_rfence())
- on_each_cpu(__ipi_flush_tlb_all, NULL, 1);
- else
+ if (num_online_cpus() < 2)
+ local_flush_tlb_all();
+ else if (riscv_use_sbi_for_rfence())
sbi_remote_sfence_vma_asid(NULL, 0, FLUSH_TLB_MAX_SIZE, FLUSH_TLB_NO_ASID);
+ else
+ on_each_cpu(__ipi_flush_tlb_all, NULL, 1);
}
struct flush_tlb_range_data {
@@ -103,46 +82,34 @@ static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
unsigned long start, unsigned long size,
unsigned long stride)
{
- struct flush_tlb_range_data ftd;
- bool broadcast;
+ unsigned int cpu;
if (cpumask_empty(cmask))
return;
- if (cmask != cpu_online_mask) {
- unsigned int cpuid;
+ cpu = get_cpu();
- cpuid = get_cpu();
- /* check if the tlbflush needs to be sent to other CPUs */
- broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
+ /* Check if the TLB flush needs to be sent to other CPUs. */
+ if (cpumask_any_but(cmask, cpu) >= nr_cpu_ids) {
+ local_flush_tlb_range_asid(start, size, stride, asid);
+ } else if (riscv_use_sbi_for_rfence()) {
+ sbi_remote_sfence_vma_asid(cmask, start, size, asid);
} else {
- broadcast = true;
- }
+ struct flush_tlb_range_data ftd;
- if (broadcast) {
- if (riscv_use_ipi_for_rfence()) {
- ftd.asid = asid;
- ftd.start = start;
- ftd.size = size;
- ftd.stride = stride;
- on_each_cpu_mask(cmask,
- __ipi_flush_tlb_range_asid,
- &ftd, 1);
- } else
- sbi_remote_sfence_vma_asid(cmask,
- start, size, asid);
- } else {
- local_flush_tlb_range_asid(start, size, stride, asid);
+ ftd.asid = asid;
+ ftd.start = start;
+ ftd.size = size;
+ ftd.stride = stride;
+ on_each_cpu_mask(cmask, __ipi_flush_tlb_range_asid, &ftd, 1);
}
- if (cmask != cpu_online_mask)
- put_cpu();
+ put_cpu();
}
static inline unsigned long get_mm_asid(struct mm_struct *mm)
{
- return static_branch_unlikely(&use_asid_allocator) ?
- atomic_long_read(&mm->context.id) & asid_mask : FLUSH_TLB_NO_ASID;
+ return cntx2asid(atomic_long_read(&mm->context.id));
}
void flush_tlb_mm(struct mm_struct *mm)
diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
index f4b6b3b9edda..1d1c78d4cff1 100644
--- a/arch/riscv/net/bpf_jit.h
+++ b/arch/riscv/net/bpf_jit.h
@@ -18,6 +18,11 @@ static inline bool rvc_enabled(void)
return IS_ENABLED(CONFIG_RISCV_ISA_C);
}
+static inline bool rvzba_enabled(void)
+{
+ return IS_ENABLED(CONFIG_RISCV_ISA_ZBA) && riscv_has_extension_likely(RISCV_ISA_EXT_ZBA);
+}
+
static inline bool rvzbb_enabled(void)
{
return IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && riscv_has_extension_likely(RISCV_ISA_EXT_ZBB);
@@ -81,6 +86,8 @@ struct rv_jit_context {
int nexentries;
unsigned long flags;
int stack_size;
+ u64 arena_vm_start;
+ u64 user_vm_start;
};
/* Convert from ninsns to bytes. */
@@ -606,7 +613,7 @@ static inline u32 rv_nop(void)
return rv_i_insn(0, 0, 0, 0, 0x13);
}
-/* RVC instrutions. */
+/* RVC instructions. */
static inline u16 rvc_addi4spn(u8 rd, u32 imm10)
{
@@ -735,7 +742,18 @@ static inline u16 rvc_swsp(u32 imm8, u8 rs2)
return rv_css_insn(0x6, imm, rs2, 0x2);
}
-/* RVZBB instrutions. */
+/* RVZBA instructions. */
+static inline u32 rvzba_sh2add(u8 rd, u8 rs1, u8 rs2)
+{
+ return rv_r_insn(0x10, rs2, rs1, 0x4, rd, 0x33);
+}
+
+static inline u32 rvzba_sh3add(u8 rd, u8 rs1, u8 rs2)
+{
+ return rv_r_insn(0x10, rs2, rs1, 0x6, rd, 0x33);
+}
+
+/* RVZBB instructions. */
static inline u32 rvzbb_sextb(u8 rd, u8 rs1)
{
return rv_i_insn(0x604, rs1, 1, rd, 0x13);
@@ -937,6 +955,14 @@ static inline u16 rvc_sdsp(u32 imm9, u8 rs2)
return rv_css_insn(0x7, imm, rs2, 0x2);
}
+/* RV64-only ZBA instructions. */
+
+static inline u32 rvzba_zextw(u8 rd, u8 rs1)
+{
+ /* add.uw rd, rs1, ZERO */
+ return rv_r_insn(0x04, RV_REG_ZERO, rs1, 0, rd, 0x3b);
+}
+
#endif /* __riscv_xlen == 64 */
/* Helper functions that emit RVC instructions when possible. */
@@ -1080,6 +1106,28 @@ static inline void emit_sw(u8 rs1, s32 off, u8 rs2, struct rv_jit_context *ctx)
emit(rv_sw(rs1, off, rs2), ctx);
}
+static inline void emit_sh2add(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
+{
+ if (rvzba_enabled()) {
+ emit(rvzba_sh2add(rd, rs1, rs2), ctx);
+ return;
+ }
+
+ emit_slli(rd, rs1, 2, ctx);
+ emit_add(rd, rd, rs2, ctx);
+}
+
+static inline void emit_sh3add(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
+{
+ if (rvzba_enabled()) {
+ emit(rvzba_sh3add(rd, rs1, rs2), ctx);
+ return;
+ }
+
+ emit_slli(rd, rs1, 3, ctx);
+ emit_add(rd, rd, rs2, ctx);
+}
+
/* RV64-only helper functions. */
#if __riscv_xlen == 64
@@ -1159,6 +1207,11 @@ static inline void emit_zexth(u8 rd, u8 rs, struct rv_jit_context *ctx)
static inline void emit_zextw(u8 rd, u8 rs, struct rv_jit_context *ctx)
{
+ if (rvzba_enabled()) {
+ emit(rvzba_zextw(rd, rs), ctx);
+ return;
+ }
+
emit_slli(rd, rs, 32, ctx);
emit_srli(rd, rd, 32, ctx);
}
diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c
index f5ba73bb153d..592dd86fbf81 100644
--- a/arch/riscv/net/bpf_jit_comp32.c
+++ b/arch/riscv/net/bpf_jit_comp32.c
@@ -811,8 +811,7 @@ static int emit_bpf_tail_call(int insn, struct rv_jit_context *ctx)
* if (!prog)
* goto out;
*/
- emit(rv_slli(RV_REG_T0, lo(idx_reg), 2), ctx);
- emit(rv_add(RV_REG_T0, RV_REG_T0, lo(arr_reg)), ctx);
+ emit_sh2add(RV_REG_T0, lo(idx_reg), lo(arr_reg), ctx);
off = offsetof(struct bpf_array, ptrs);
if (is_12b_check(off, insn))
return -1;
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index ec9d692838fc..99f34409fb60 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -12,12 +12,18 @@
#include <linux/stop_machine.h>
#include <asm/patch.h>
#include <asm/cfi.h>
+#include <asm/percpu.h>
#include "bpf_jit.h"
+#define RV_MAX_REG_ARGS 8
#define RV_FENTRY_NINSNS 2
+#define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4)
+/* imm that allows emit_imm to emit max count insns */
+#define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF
#define RV_REG_TCC RV_REG_A6
#define RV_REG_TCC_SAVED RV_REG_S6 /* Store A6 in S6 if program do calls */
+#define RV_REG_ARENA RV_REG_S7 /* For storing arena_vm_start */
static const int regmap[] = {
[BPF_REG_0] = RV_REG_A5,
@@ -255,6 +261,10 @@ static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx)
emit_ld(RV_REG_S6, store_offset, RV_REG_SP, ctx);
store_offset -= 8;
}
+ if (ctx->arena_vm_start) {
+ emit_ld(RV_REG_ARENA, store_offset, RV_REG_SP, ctx);
+ store_offset -= 8;
+ }
emit_addi(RV_REG_SP, RV_REG_SP, stack_adjust, ctx);
/* Set return value. */
@@ -374,8 +384,7 @@ static int emit_bpf_tail_call(int insn, struct rv_jit_context *ctx)
* if (!prog)
* goto out;
*/
- emit_slli(RV_REG_T2, RV_REG_A2, 3, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_A1, ctx);
+ emit_sh3add(RV_REG_T2, RV_REG_A2, RV_REG_A1, ctx);
off = offsetof(struct bpf_array, ptrs);
if (is_12b_check(off, insn))
return -1;
@@ -498,41 +507,43 @@ static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
break;
/* src_reg = atomic_fetch_<op>(dst_reg + off16, src_reg) */
case BPF_ADD | BPF_FETCH:
- emit(is64 ? rv_amoadd_d(rs, rs, rd, 0, 0) :
- rv_amoadd_w(rs, rs, rd, 0, 0), ctx);
+ emit(is64 ? rv_amoadd_d(rs, rs, rd, 1, 1) :
+ rv_amoadd_w(rs, rs, rd, 1, 1), ctx);
if (!is64)
emit_zextw(rs, rs, ctx);
break;
case BPF_AND | BPF_FETCH:
- emit(is64 ? rv_amoand_d(rs, rs, rd, 0, 0) :
- rv_amoand_w(rs, rs, rd, 0, 0), ctx);
+ emit(is64 ? rv_amoand_d(rs, rs, rd, 1, 1) :
+ rv_amoand_w(rs, rs, rd, 1, 1), ctx);
if (!is64)
emit_zextw(rs, rs, ctx);
break;
case BPF_OR | BPF_FETCH:
- emit(is64 ? rv_amoor_d(rs, rs, rd, 0, 0) :
- rv_amoor_w(rs, rs, rd, 0, 0), ctx);
+ emit(is64 ? rv_amoor_d(rs, rs, rd, 1, 1) :
+ rv_amoor_w(rs, rs, rd, 1, 1), ctx);
if (!is64)
emit_zextw(rs, rs, ctx);
break;
case BPF_XOR | BPF_FETCH:
- emit(is64 ? rv_amoxor_d(rs, rs, rd, 0, 0) :
- rv_amoxor_w(rs, rs, rd, 0, 0), ctx);
+ emit(is64 ? rv_amoxor_d(rs, rs, rd, 1, 1) :
+ rv_amoxor_w(rs, rs, rd, 1, 1), ctx);
if (!is64)
emit_zextw(rs, rs, ctx);
break;
/* src_reg = atomic_xchg(dst_reg + off16, src_reg); */
case BPF_XCHG:
- emit(is64 ? rv_amoswap_d(rs, rs, rd, 0, 0) :
- rv_amoswap_w(rs, rs, rd, 0, 0), ctx);
+ emit(is64 ? rv_amoswap_d(rs, rs, rd, 1, 1) :
+ rv_amoswap_w(rs, rs, rd, 1, 1), ctx);
if (!is64)
emit_zextw(rs, rs, ctx);
break;
/* r0 = atomic_cmpxchg(dst_reg + off16, r0, src_reg); */
case BPF_CMPXCHG:
r0 = bpf_to_rv_reg(BPF_REG_0, ctx);
- emit(is64 ? rv_addi(RV_REG_T2, r0, 0) :
- rv_addiw(RV_REG_T2, r0, 0), ctx);
+ if (is64)
+ emit_mv(RV_REG_T2, r0, ctx);
+ else
+ emit_addiw(RV_REG_T2, r0, 0, ctx);
emit(is64 ? rv_lr_d(r0, 0, rd, 0, 0) :
rv_lr_w(r0, 0, rd, 0, 0), ctx);
jmp_offset = ninsns_rvoff(8);
@@ -548,6 +559,7 @@ static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
#define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0)
#define BPF_FIXUP_REG_MASK GENMASK(31, 27)
+#define REG_DONT_CLEAR_MARKER 0 /* RV_REG_ZERO unused in pt_regmap */
bool ex_handler_bpf(const struct exception_table_entry *ex,
struct pt_regs *regs)
@@ -555,7 +567,8 @@ bool ex_handler_bpf(const struct exception_table_entry *ex,
off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup);
int regs_offset = FIELD_GET(BPF_FIXUP_REG_MASK, ex->fixup);
- *(unsigned long *)((void *)regs + pt_regmap[regs_offset]) = 0;
+ if (regs_offset != REG_DONT_CLEAR_MARKER)
+ *(unsigned long *)((void *)regs + pt_regmap[regs_offset]) = 0;
regs->epc = (unsigned long)&ex->fixup - offset;
return true;
@@ -572,7 +585,8 @@ static int add_exception_handler(const struct bpf_insn *insn,
off_t fixup_offset;
if (!ctx->insns || !ctx->ro_insns || !ctx->prog->aux->extable ||
- (BPF_MODE(insn->code) != BPF_PROBE_MEM && BPF_MODE(insn->code) != BPF_PROBE_MEMSX))
+ (BPF_MODE(insn->code) != BPF_PROBE_MEM && BPF_MODE(insn->code) != BPF_PROBE_MEMSX &&
+ BPF_MODE(insn->code) != BPF_PROBE_MEM32))
return 0;
if (WARN_ON_ONCE(ctx->nexentries >= ctx->prog->aux->num_exentries))
@@ -663,7 +677,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
if (ret)
return ret;
- if (memcmp(ip, old_insns, RV_FENTRY_NINSNS * 4))
+ if (memcmp(ip, old_insns, RV_FENTRY_NBYTES))
return -EFAULT;
ret = gen_jump_or_nops(new_addr, ip, new_insns, is_call);
@@ -672,34 +686,53 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
cpus_read_lock();
mutex_lock(&text_mutex);
- if (memcmp(ip, new_insns, RV_FENTRY_NINSNS * 4))
- ret = patch_text(ip, new_insns, RV_FENTRY_NINSNS);
+ if (memcmp(ip, new_insns, RV_FENTRY_NBYTES))
+ ret = patch_text(ip, new_insns, RV_FENTRY_NBYTES);
mutex_unlock(&text_mutex);
cpus_read_unlock();
return ret;
}
-static void store_args(int nregs, int args_off, struct rv_jit_context *ctx)
+static void store_args(int nr_arg_slots, int args_off, struct rv_jit_context *ctx)
{
int i;
- for (i = 0; i < nregs; i++) {
- emit_sd(RV_REG_FP, -args_off, RV_REG_A0 + i, ctx);
+ for (i = 0; i < nr_arg_slots; i++) {
+ if (i < RV_MAX_REG_ARGS) {
+ emit_sd(RV_REG_FP, -args_off, RV_REG_A0 + i, ctx);
+ } else {
+ /* skip slots for T0 and FP of traced function */
+ emit_ld(RV_REG_T1, 16 + (i - RV_MAX_REG_ARGS) * 8, RV_REG_FP, ctx);
+ emit_sd(RV_REG_FP, -args_off, RV_REG_T1, ctx);
+ }
args_off -= 8;
}
}
-static void restore_args(int nregs, int args_off, struct rv_jit_context *ctx)
+static void restore_args(int nr_reg_args, int args_off, struct rv_jit_context *ctx)
{
int i;
- for (i = 0; i < nregs; i++) {
+ for (i = 0; i < nr_reg_args; i++) {
emit_ld(RV_REG_A0 + i, -args_off, RV_REG_FP, ctx);
args_off -= 8;
}
}
+static void restore_stack_args(int nr_stack_args, int args_off, int stk_arg_off,
+ struct rv_jit_context *ctx)
+{
+ int i;
+
+ for (i = 0; i < nr_stack_args; i++) {
+ emit_ld(RV_REG_T1, -(args_off - RV_MAX_REG_ARGS * 8), RV_REG_FP, ctx);
+ emit_sd(RV_REG_FP, -stk_arg_off, RV_REG_T1, ctx);
+ args_off -= 8;
+ stk_arg_off -= 8;
+ }
+}
+
static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_off,
int run_ctx_off, bool save_ret, struct rv_jit_context *ctx)
{
@@ -772,8 +805,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
{
int i, ret, offset;
int *branches_off = NULL;
- int stack_size = 0, nregs = m->nr_args;
- int retval_off, args_off, nregs_off, ip_off, run_ctx_off, sreg_off;
+ int stack_size = 0, nr_arg_slots = 0;
+ int retval_off, args_off, nregs_off, ip_off, run_ctx_off, sreg_off, stk_arg_off;
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
@@ -819,20 +852,21 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
* FP - sreg_off [ callee saved reg ]
*
* [ pads ] pads for 16 bytes alignment
+ *
+ * [ stack_argN ]
+ * [ ... ]
+ * FP - stk_arg_off [ stack_arg1 ] BPF_TRAMP_F_CALL_ORIG
*/
if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY))
return -ENOTSUPP;
- /* extra regiters for struct arguments */
- for (i = 0; i < m->nr_args; i++)
- if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
- nregs += round_up(m->arg_size[i], 8) / 8 - 1;
-
- /* 8 arguments passed by registers */
- if (nregs > 8)
+ if (m->nr_args > MAX_BPF_FUNC_ARGS)
return -ENOTSUPP;
+ for (i = 0; i < m->nr_args; i++)
+ nr_arg_slots += round_up(m->arg_size[i], 8) / 8;
+
/* room of trampoline frame to store return address and frame pointer */
stack_size += 16;
@@ -842,7 +876,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
retval_off = stack_size;
}
- stack_size += nregs * 8;
+ stack_size += nr_arg_slots * 8;
args_off = stack_size;
stack_size += 8;
@@ -859,7 +893,13 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
stack_size += 8;
sreg_off = stack_size;
- stack_size = round_up(stack_size, 16);
+ if ((flags & BPF_TRAMP_F_CALL_ORIG) && (nr_arg_slots - RV_MAX_REG_ARGS > 0))
+ stack_size += (nr_arg_slots - RV_MAX_REG_ARGS) * 8;
+
+ stack_size = round_up(stack_size, STACK_ALIGN);
+
+ /* room for args on stack must be at the top of stack */
+ stk_arg_off = stack_size;
if (!is_struct_ops) {
/* For the trampoline called from function entry,
@@ -896,17 +936,17 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
emit_sd(RV_REG_FP, -ip_off, RV_REG_T1, ctx);
}
- emit_li(RV_REG_T1, nregs, ctx);
+ emit_li(RV_REG_T1, nr_arg_slots, ctx);
emit_sd(RV_REG_FP, -nregs_off, RV_REG_T1, ctx);
- store_args(nregs, args_off, ctx);
+ store_args(nr_arg_slots, args_off, ctx);
/* skip to actual body of traced function */
if (flags & BPF_TRAMP_F_SKIP_FRAME)
orig_call += RV_FENTRY_NINSNS * 4;
if (flags & BPF_TRAMP_F_CALL_ORIG) {
- emit_imm(RV_REG_A0, (const s64)im, ctx);
+ emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx);
ret = emit_call((const u64)__bpf_tramp_enter, true, ctx);
if (ret)
return ret;
@@ -939,13 +979,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
- restore_args(nregs, args_off, ctx);
+ restore_args(min_t(int, nr_arg_slots, RV_MAX_REG_ARGS), args_off, ctx);
+ restore_stack_args(nr_arg_slots - RV_MAX_REG_ARGS, args_off, stk_arg_off, ctx);
ret = emit_call((const u64)orig_call, true, ctx);
if (ret)
goto out;
emit_sd(RV_REG_FP, -retval_off, RV_REG_A0, ctx);
emit_sd(RV_REG_FP, -(retval_off - 8), regmap[BPF_REG_0], ctx);
- im->ip_after_call = ctx->insns + ctx->ninsns;
+ im->ip_after_call = ctx->ro_insns + ctx->ninsns;
/* 2 nops reserved for auipc+jalr pair */
emit(rv_nop(), ctx);
emit(rv_nop(), ctx);
@@ -966,15 +1007,15 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
- im->ip_epilogue = ctx->insns + ctx->ninsns;
- emit_imm(RV_REG_A0, (const s64)im, ctx);
+ im->ip_epilogue = ctx->ro_insns + ctx->ninsns;
+ emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx);
ret = emit_call((const u64)__bpf_tramp_exit, true, ctx);
if (ret)
goto out;
}
if (flags & BPF_TRAMP_F_RESTORE_REGS)
- restore_args(nregs, args_off, ctx);
+ restore_args(min_t(int, nr_arg_slots, RV_MAX_REG_ARGS), args_off, ctx);
if (save_ret) {
emit_ld(RV_REG_A0, -retval_off, RV_REG_FP, ctx);
@@ -1029,31 +1070,52 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
return ret < 0 ? ret : ninsns_rvoff(ctx.ninsns);
}
-int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
- void *image_end, const struct btf_func_model *m,
+void *arch_alloc_bpf_trampoline(unsigned int size)
+{
+ return bpf_prog_pack_alloc(size, bpf_fill_ill_insns);
+}
+
+void arch_free_bpf_trampoline(void *image, unsigned int size)
+{
+ bpf_prog_pack_free(image, size);
+}
+
+int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image,
+ void *ro_image_end, const struct btf_func_model *m,
u32 flags, struct bpf_tramp_links *tlinks,
void *func_addr)
{
int ret;
+ void *image, *res;
struct rv_jit_context ctx;
+ u32 size = ro_image_end - ro_image;
+
+ image = kvmalloc(size, GFP_KERNEL);
+ if (!image)
+ return -ENOMEM;
ctx.ninsns = 0;
- /*
- * The bpf_int_jit_compile() uses a RW buffer (ctx.insns) to write the
- * JITed instructions and later copies it to a RX region (ctx.ro_insns).
- * It also uses ctx.ro_insns to calculate offsets for jumps etc. As the
- * trampoline image uses the same memory area for writing and execution,
- * both ctx.insns and ctx.ro_insns can be set to image.
- */
ctx.insns = image;
- ctx.ro_insns = image;
+ ctx.ro_insns = ro_image;
ret = __arch_prepare_bpf_trampoline(im, m, tlinks, func_addr, flags, &ctx);
if (ret < 0)
- return ret;
+ goto out;
- bpf_flush_icache(ctx.insns, ctx.insns + ctx.ninsns);
+ if (WARN_ON(size < ninsns_rvoff(ctx.ninsns))) {
+ ret = -E2BIG;
+ goto out;
+ }
- return ninsns_rvoff(ret);
+ res = bpf_arch_text_copy(ro_image, image, size);
+ if (IS_ERR(res)) {
+ ret = PTR_ERR(res);
+ goto out;
+ }
+
+ bpf_flush_icache(ro_image, ro_image_end);
+out:
+ kvfree(image);
+ return ret < 0 ? ret : size;
}
int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
@@ -1073,6 +1135,31 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
/* dst = src */
case BPF_ALU | BPF_MOV | BPF_X:
case BPF_ALU64 | BPF_MOV | BPF_X:
+ if (insn_is_cast_user(insn)) {
+ emit_mv(RV_REG_T1, rs, ctx);
+ emit_zextw(RV_REG_T1, RV_REG_T1, ctx);
+ emit_imm(rd, (ctx->user_vm_start >> 32) << 32, ctx);
+ emit(rv_beq(RV_REG_T1, RV_REG_ZERO, 4), ctx);
+ emit_or(RV_REG_T1, rd, RV_REG_T1, ctx);
+ emit_mv(rd, RV_REG_T1, ctx);
+ break;
+ } else if (insn_is_mov_percpu_addr(insn)) {
+ if (rd != rs)
+ emit_mv(rd, rs, ctx);
+#ifdef CONFIG_SMP
+ /* Load current CPU number in T1 */
+ emit_ld(RV_REG_T1, offsetof(struct thread_info, cpu),
+ RV_REG_TP, ctx);
+ /* Load address of __per_cpu_offset array in T2 */
+ emit_addr(RV_REG_T2, (u64)&__per_cpu_offset, extra_pass, ctx);
+ /* Get address of __per_cpu_offset[cpu] in T1 */
+ emit_sh3add(RV_REG_T1, RV_REG_T1, RV_REG_T2, ctx);
+ /* Load __per_cpu_offset[cpu] in T1 */
+ emit_ld(RV_REG_T1, 0, RV_REG_T1, ctx);
+ /* Add the offset to Rd */
+ emit_add(rd, rd, RV_REG_T1, ctx);
+#endif
+ }
if (imm == 1) {
/* Special mov32 for zext */
emit_zextw(rd, rd, ctx);
@@ -1457,6 +1544,22 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
bool fixed_addr;
u64 addr;
+ /* Inline calls to bpf_get_smp_processor_id()
+ *
+ * RV_REG_TP holds the address of the current CPU's task_struct and thread_info is
+ * at offset 0 in task_struct.
+ * Load cpu from thread_info:
+ * Set R0 to ((struct thread_info *)(RV_REG_TP))->cpu
+ *
+ * This replicates the implementation of raw_smp_processor_id() on RISCV
+ */
+ if (insn->src_reg == 0 && insn->imm == BPF_FUNC_get_smp_processor_id) {
+ /* Load current CPU number in R0 */
+ emit_ld(bpf_to_rv_reg(BPF_REG_0, ctx), offsetof(struct thread_info, cpu),
+ RV_REG_TP, ctx);
+ break;
+ }
+
mark_call(ctx);
ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
&addr, &fixed_addr);
@@ -1539,6 +1642,11 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
+ /* LDX | PROBE_MEM32: dst = *(unsigned size *)(src + RV_REG_ARENA + off) */
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_B:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW:
{
int insn_len, insns_start;
bool sign_ext;
@@ -1546,6 +1654,11 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
sign_ext = BPF_MODE(insn->code) == BPF_MEMSX ||
BPF_MODE(insn->code) == BPF_PROBE_MEMSX;
+ if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
+ emit_add(RV_REG_T2, rs, RV_REG_ARENA, ctx);
+ rs = RV_REG_T2;
+ }
+
switch (BPF_SIZE(code)) {
case BPF_B:
if (is_12b_int(off)) {
@@ -1682,6 +1795,86 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
emit_sd(RV_REG_T2, 0, RV_REG_T1, ctx);
break;
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_B:
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_DW:
+ {
+ int insn_len, insns_start;
+
+ emit_add(RV_REG_T3, rd, RV_REG_ARENA, ctx);
+ rd = RV_REG_T3;
+
+ /* Load imm to a register then store it */
+ emit_imm(RV_REG_T1, imm, ctx);
+
+ switch (BPF_SIZE(code)) {
+ case BPF_B:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit(rv_sb(rd, off, RV_REG_T1), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T2, off, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit(rv_sb(RV_REG_T2, 0, RV_REG_T1), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ case BPF_H:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit(rv_sh(rd, off, RV_REG_T1), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T2, off, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit(rv_sh(RV_REG_T2, 0, RV_REG_T1), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ case BPF_W:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit_sw(rd, off, RV_REG_T1, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T2, off, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit_sw(RV_REG_T2, 0, RV_REG_T1, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ case BPF_DW:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit_sd(rd, off, RV_REG_T1, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T2, off, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit_sd(RV_REG_T2, 0, RV_REG_T1, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER,
+ insn_len);
+ if (ret)
+ return ret;
+
+ break;
+ }
+
/* STX: *(size *)(dst + off) = src */
case BPF_STX | BPF_MEM | BPF_B:
if (is_12b_int(off)) {
@@ -1728,6 +1921,84 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
emit_atomic(rd, rs, off, imm,
BPF_SIZE(code) == BPF_DW, ctx);
break;
+
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_DW:
+ {
+ int insn_len, insns_start;
+
+ emit_add(RV_REG_T2, rd, RV_REG_ARENA, ctx);
+ rd = RV_REG_T2;
+
+ switch (BPF_SIZE(code)) {
+ case BPF_B:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit(rv_sb(rd, off, rs), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T1, off, ctx);
+ emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit(rv_sb(RV_REG_T1, 0, rs), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ case BPF_H:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit(rv_sh(rd, off, rs), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T1, off, ctx);
+ emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit(rv_sh(RV_REG_T1, 0, rs), ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ case BPF_W:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit_sw(rd, off, rs, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T1, off, ctx);
+ emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit_sw(RV_REG_T1, 0, rs, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ case BPF_DW:
+ if (is_12b_int(off)) {
+ insns_start = ctx->ninsns;
+ emit_sd(rd, off, rs, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ emit_imm(RV_REG_T1, off, ctx);
+ emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
+ insns_start = ctx->ninsns;
+ emit_sd(RV_REG_T1, 0, rs, ctx);
+ insn_len = ctx->ninsns - insns_start;
+ break;
+ }
+
+ ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER,
+ insn_len);
+ if (ret)
+ return ret;
+
+ break;
+ }
+
default:
pr_err("bpf-jit: unknown opcode %02x\n", code);
return -EINVAL;
@@ -1740,7 +2011,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
{
int i, stack_adjust = 0, store_offset, bpf_stack_adjust;
- bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16);
+ bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, STACK_ALIGN);
if (bpf_stack_adjust)
mark_fp(ctx);
@@ -1759,8 +2030,10 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
stack_adjust += 8;
if (seen_reg(RV_REG_S6, ctx))
stack_adjust += 8;
+ if (ctx->arena_vm_start)
+ stack_adjust += 8;
- stack_adjust = round_up(stack_adjust, 16);
+ stack_adjust = round_up(stack_adjust, STACK_ALIGN);
stack_adjust += bpf_stack_adjust;
store_offset = stack_adjust - 8;
@@ -1810,6 +2083,10 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
emit_sd(RV_REG_SP, store_offset, RV_REG_S6, ctx);
store_offset -= 8;
}
+ if (ctx->arena_vm_start) {
+ emit_sd(RV_REG_SP, store_offset, RV_REG_ARENA, ctx);
+ store_offset -= 8;
+ }
emit_addi(RV_REG_FP, RV_REG_SP, stack_adjust, ctx);
@@ -1823,6 +2100,9 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
emit_mv(RV_REG_TCC_SAVED, RV_REG_TCC, ctx);
ctx->stack_size = stack_adjust;
+
+ if (ctx->arena_vm_start)
+ emit_imm(RV_REG_ARENA, ctx->arena_vm_start, ctx);
}
void bpf_jit_build_epilogue(struct rv_jit_context *ctx)
@@ -1839,3 +2119,23 @@ bool bpf_jit_supports_ptr_xchg(void)
{
return true;
}
+
+bool bpf_jit_supports_arena(void)
+{
+ return true;
+}
+
+bool bpf_jit_supports_percpu_insn(void)
+{
+ return true;
+}
+
+bool bpf_jit_inlines_helper_call(s32 imm)
+{
+ switch (imm) {
+ case BPF_FUNC_get_smp_processor_id:
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index 6b3acac30c06..6de753c667f4 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -80,6 +80,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
goto skip_init_ctx;
}
+ ctx->arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena);
+ ctx->user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena);
ctx->prog = prog;
ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL);
if (!ctx->offset) {
@@ -176,8 +178,7 @@ skip_init_ctx:
prog->jited_len = prog_size - cfi_get_offset();
if (!prog->is_func || extra_pass) {
- if (WARN_ON(bpf_jit_binary_pack_finalize(prog, jit_data->ro_header,
- jit_data->header))) {
+ if (WARN_ON(bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header))) {
/* ro_header has been freed */
jit_data->ro_header = NULL;
prog = orig_prog;
@@ -219,19 +220,6 @@ u64 bpf_jit_alloc_exec_limit(void)
return BPF_JIT_REGION_SIZE;
}
-void *bpf_jit_alloc_exec(unsigned long size)
-{
- return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
- BPF_JIT_REGION_END, GFP_KERNEL,
- PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-
-void bpf_jit_free_exec(void *addr)
-{
- return vfree(addr);
-}
-
void *bpf_arch_text_copy(void *dst, void *src, size_t len)
{
int ret;
@@ -269,7 +257,7 @@ void bpf_jit_free(struct bpf_prog *prog)
* before freeing it.
*/
if (jit_data) {
- bpf_jit_binary_pack_finalize(prog, jit_data->ro_header, jit_data->header);
+ bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header);
kfree(jit_data);
}
hdr = bpf_jit_binary_pack_hdr(prog);
diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile
index 280b0eb352b8..f11945ee2490 100644
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-OBJECT_FILES_NON_STANDARD := y
purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
purgatory-y += strcmp.o strlen.o strncmp.o
@@ -47,13 +46,6 @@ LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
targets += purgatory.ro purgatory.chk
-# Sanitizer, etc. runtimes are unavailable and cannot be linked here.
-GCOV_PROFILE := n
-KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
-KCSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-
# These are adjustments to the compiler flags used for objects that
# make up the standalone purgatory.ro
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 8f01ada6845e..a822f952f64a 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -17,9 +17,12 @@ config ARCH_HAS_ILOG2_U32
config ARCH_HAS_ILOG2_U64
def_bool n
-config GENERIC_HWEIGHT
+config ARCH_PROC_KCORE_TEXT
def_bool y
+config GENERIC_HWEIGHT
+ def_bool !HAVE_MARCH_Z196_FEATURES
+
config GENERIC_BUG
def_bool y if BUG
@@ -139,6 +142,7 @@ config S390
select FUNCTION_ALIGNMENT_8B if CC_IS_GCC
select FUNCTION_ALIGNMENT_16B if !CC_IS_GCC
select GENERIC_ALLOCATOR
+ select GENERIC_CPU_DEVICES
select GENERIC_CPU_AUTOPROBE
select GENERIC_CPU_VULNERABILITIES
select GENERIC_ENTRY
@@ -155,6 +159,7 @@ config S390
select HAVE_ARCH_KASAN
select HAVE_ARCH_KASAN_VMALLOC
select HAVE_ARCH_KCSAN
+ select HAVE_ARCH_KMSAN
select HAVE_ARCH_KFENCE
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP_FILTER
@@ -174,7 +179,7 @@ config S390
select HAVE_DYNAMIC_FTRACE_WITH_REGS
select HAVE_EBPF_JIT if HAVE_MARCH_Z196_FEATURES
select HAVE_EFFICIENT_UNALIGNED_ACCESS
- select HAVE_FAST_GUP
+ select HAVE_GUP_FAST
select HAVE_FENTRY
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_ARG_ACCESS_API
@@ -552,7 +557,7 @@ config EXPOLINE
If unsure, say N.
config EXPOLINE_EXTERN
- def_bool n
+ def_bool y if EXPOLINE
depends on EXPOLINE
depends on CC_IS_GCC && GCC_VERSION >= 110200
depends on $(success,$(srctree)/arch/s390/tools/gcc-thunk-extern.sh $(CC))
@@ -590,18 +595,6 @@ config RELOCATABLE
Note: this option exists only for documentation purposes, please do
not remove it.
-config PIE_BUILD
- def_bool CC_IS_CLANG && !$(cc-option,-munaligned-symbols)
- help
- If the compiler is unable to generate code that can manage unaligned
- symbols, the kernel is linked as a position-independent executable
- (PIE) and includes dynamic relocations that are processed early
- during bootup.
-
- For kpatch functionality, it is recommended to build the kernel
- without the PIE_BUILD option. PIE_BUILD is only enabled when the
- compiler lacks proper support for handling unaligned symbols.
-
config RANDOMIZE_BASE
bool "Randomize the address of the kernel image (KASLR)"
default y
@@ -611,6 +604,25 @@ config RANDOMIZE_BASE
as a security feature that deters exploit attempts relying on
knowledge of the location of kernel internals.
+config KERNEL_IMAGE_BASE
+ hex "Kernel image base address"
+ range 0x100000 0x1FFFFFE0000000 if !KASAN
+ range 0x100000 0x1BFFFFE0000000 if KASAN
+ default 0x3FFE0000000 if !KASAN
+ default 0x7FFFE0000000 if KASAN
+ help
+ This is the address at which the kernel image is loaded in case
+ Kernel Address Space Layout Randomization (KASLR) is disabled.
+
+ In case the Protected virtualization guest support is enabled the
+ Ultravisor imposes a virtual address limit. If the value of this
+ option leads to the kernel image exceeding the Ultravisor limit,
+ this option is ignored and the image is loaded below the limit.
+
+ If the value of this option leads to the kernel image overlapping
+ the virtual memory where other data structures are located, this
+ option is ignored and the image is loaded above the structures.
+
endmenu
menu "Memory setup"
@@ -724,6 +736,33 @@ config EADM_SCH
To compile this driver as a module, choose M here: the
module will be called eadm_sch.
+config AP
+ def_tristate y
+ prompt "Support for Adjunct Processors (ap)"
+ help
+ This driver allows usage to Adjunct Processor (AP) devices via
+ the ap bus, cards and queues. Supported Adjunct Processors are
+ the CryptoExpress Cards (CEX).
+
+ To compile this driver as a module, choose M here: the
+ module will be called ap.
+
+ If unsure, say Y (default).
+
+config AP_DEBUG
+ def_bool n
+ prompt "Enable debug features for Adjunct Processor (ap) devices"
+ depends on AP
+ help
+ Say 'Y' here to enable some additional debug features for Adjunct
+ Processor (ap) devices.
+
+ There will be some more sysfs attributes displayed for ap queues.
+
+ Do not enable on production level kernel build.
+
+ If unsure, say N.
+
config VFIO_CCW
def_tristate n
prompt "Support for VFIO-CCW subchannels"
@@ -740,7 +779,7 @@ config VFIO_AP
prompt "VFIO support for AP devices"
depends on KVM
depends on VFIO
- depends on ZCRYPT
+ depends on AP
select VFIO_MDEV
help
This driver grants access to Adjunct Processor (AP) devices
@@ -760,17 +799,6 @@ config HAVE_PNETID
menu "Virtualization"
-config PROTECTED_VIRTUALIZATION_GUEST
- def_bool n
- prompt "Protected virtualization guest support"
- help
- Select this option, if you want to be able to run this
- kernel as a protected virtualization KVM guest.
- Protected virtualization capable machines have a mini hypervisor
- located at machine level (an ultravisor). With help of the
- Ultravisor, KVM will be able to run "protected" VMs, special
- VMs whose memory and management data are unavailable to KVM.
-
config PFAULT
def_bool y
prompt "Pseudo page fault support"
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 2dbb2d2f22f9..7fd57398221e 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -14,14 +14,9 @@ KBUILD_AFLAGS_MODULE += -fPIC
KBUILD_CFLAGS_MODULE += -fPIC
KBUILD_AFLAGS += -m64
KBUILD_CFLAGS += -m64
-ifdef CONFIG_PIE_BUILD
-KBUILD_CFLAGS += -fPIE
-LDFLAGS_vmlinux := -pie -z notext
-else
-KBUILD_CFLAGS += $(call cc-option,-munaligned-symbols,)
-LDFLAGS_vmlinux := --emit-relocs --discard-none
+KBUILD_CFLAGS += -fPIC
+LDFLAGS_vmlinux := -no-pie --emit-relocs --discard-none
extra_tools := relocs
-endif
aflags_dwarf := -Wa,-gdwarf-2
KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
ifndef CONFIG_AS_IS_LLVM
@@ -41,7 +36,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option
KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds)
UTS_MACHINE := s390x
-STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384)
+STACK_SIZE := $(if $(CONFIG_KASAN),65536,$(if $(CONFIG_KMSAN),65536,16384))
CHECKFLAGS += -D__s390__ -D__s390x__
export LD_BFD
@@ -88,7 +83,6 @@ endif
ifdef CONFIG_EXPOLINE
ifdef CONFIG_EXPOLINE_EXTERN
- KBUILD_LDFLAGS_MODULE += arch/s390/lib/expoline/expoline.o
CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern
CC_FLAGS_EXPOLINE += -mfunction-return=thunk-extern
else
@@ -167,11 +161,6 @@ vdso_prepare: prepare0
vdso-install-y += arch/s390/kernel/vdso64/vdso64.so.dbg
vdso-install-$(CONFIG_COMPAT) += arch/s390/kernel/vdso32/vdso32.so.dbg
-ifdef CONFIG_EXPOLINE_EXTERN
-modules_prepare: expoline_prepare
-expoline_prepare: scripts
- $(Q)$(MAKE) $(build)=arch/s390/lib/expoline arch/s390/lib/expoline/expoline.o
-endif
endif
# Don't use tabs in echo arguments
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index c2978cb03b36..91a30e017d65 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -46,9 +46,9 @@
* /proc entries (sysctl)
*/
static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata";
-static int appldata_timer_handler(struct ctl_table *ctl, int write,
+static int appldata_timer_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos);
-static int appldata_interval_handler(struct ctl_table *ctl, int write,
+static int appldata_interval_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos);
static struct ctl_table_header *appldata_sysctl_header;
@@ -199,7 +199,7 @@ static void __appldata_vtimer_setup(int cmd)
* Start/Stop timer, show status of timer (0 = not active, 1 = active)
*/
static int
-appldata_timer_handler(struct ctl_table *ctl, int write,
+appldata_timer_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
int timer_active = appldata_timer_active;
@@ -232,7 +232,7 @@ appldata_timer_handler(struct ctl_table *ctl, int write,
* current timer interval.
*/
static int
-appldata_interval_handler(struct ctl_table *ctl, int write,
+appldata_interval_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
int interval = appldata_interval;
@@ -262,7 +262,7 @@ appldata_interval_handler(struct ctl_table *ctl, int write,
* monitoring (0 = not in process, 1 = in process)
*/
static int
-appldata_generic_handler(struct ctl_table *ctl, int write,
+appldata_generic_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
struct appldata_ops *ops = NULL, *tmp_ops;
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 294f08a8811a..4f476884d340 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -3,11 +3,13 @@
# Makefile for the linux s390-specific parts of the memory manager.
#
+# Tooling runtimes are unavailable and cannot be linked for early boot code
KCOV_INSTRUMENT := n
GCOV_PROFILE := n
UBSAN_SANITIZE := n
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n
KBUILD_AFLAGS := $(KBUILD_AFLAGS_DECOMPRESSOR)
KBUILD_CFLAGS := $(KBUILD_CFLAGS_DECOMPRESSOR)
@@ -37,21 +39,18 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
obj-y := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
-obj-y += version.o pgm_check_info.o ctype.o ipl_data.o
-obj-y += $(if $(CONFIG_PIE_BUILD),machine_kexec_reloc.o,relocs.o)
-obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
+obj-y += version.o pgm_check_info.o ctype.o ipl_data.o relocs.o alternative.o uv.o
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+obj-$(CONFIG_KMSAN) += kmsan.o
obj-all := $(obj-y) piggy.o syms.o
targets := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
targets += vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
targets += vmlinux.bin.zst info.bin syms.bin vmlinux.syms $(obj-all)
-ifndef CONFIG_PIE_BUILD
targets += relocs.S
-endif
OBJECTS := $(addprefix $(obj)/,$(obj-y))
OBJECTS_ALL := $(addprefix $(obj)/,$(obj-all))
@@ -110,13 +109,11 @@ OBJCOPYFLAGS_vmlinux.bin := -O binary --remove-section=.comment --remove-section
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
-ifndef CONFIG_PIE_BUILD
CMD_RELOCS=arch/s390/tools/relocs
-quiet_cmd_relocs = RELOCS $@
+quiet_cmd_relocs = RELOCS $@
cmd_relocs = $(CMD_RELOCS) $< > $@
$(obj)/relocs.S: vmlinux FORCE
$(call if_changed,relocs)
-endif
suffix-$(CONFIG_KERNEL_GZIP) := .gz
suffix-$(CONFIG_KERNEL_BZIP2) := .bz2
diff --git a/arch/s390/boot/alternative.c b/arch/s390/boot/alternative.c
new file mode 100644
index 000000000000..abc08d2c873d
--- /dev/null
+++ b/arch/s390/boot/alternative.c
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "../kernel/alternative.c"
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h
index 567d60f78bbc..83e2ce050b6c 100644
--- a/arch/s390/boot/boot.h
+++ b/arch/s390/boot/boot.h
@@ -17,7 +17,6 @@ struct machine_info {
};
struct vmlinux_info {
- unsigned long default_lma;
unsigned long entry;
unsigned long image_size; /* does not include .bss */
unsigned long bss_size; /* uncompressed image .bss size */
@@ -25,18 +24,14 @@ struct vmlinux_info {
unsigned long bootdata_size;
unsigned long bootdata_preserved_off;
unsigned long bootdata_preserved_size;
-#ifdef CONFIG_PIE_BUILD
- unsigned long dynsym_start;
- unsigned long rela_dyn_start;
- unsigned long rela_dyn_end;
-#else
unsigned long got_start;
unsigned long got_end;
-#endif
unsigned long amode31_size;
unsigned long init_mm_off;
unsigned long swapper_pg_dir_off;
unsigned long invalid_pg_dir_off;
+ unsigned long alt_instructions;
+ unsigned long alt_instructions_end;
#ifdef CONFIG_KASAN
unsigned long kasan_early_shadow_page_off;
unsigned long kasan_early_shadow_pte_off;
@@ -74,10 +69,11 @@ void sclp_early_setup_buffer(void);
void print_pgm_check_info(void);
unsigned long randomize_within_range(unsigned long size, unsigned long align,
unsigned long min, unsigned long max);
-void setup_vmem(unsigned long asce_limit);
+void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned long asce_limit);
void __printf(1, 2) decompressor_printk(const char *fmt, ...);
void print_stacktrace(unsigned long sp);
void error(char *m);
+int get_random(unsigned long limit, unsigned long *value);
extern struct machine_info machine;
@@ -95,9 +91,15 @@ extern char _end[], _decompressor_end[];
extern unsigned char _compressed_start[];
extern unsigned char _compressed_end[];
extern struct vmlinux_info _vmlinux_info;
+
#define vmlinux _vmlinux_info
+#define __lowcore_pa(x) ((unsigned long)(x) % sizeof(struct lowcore))
#define __abs_lowcore_pa(x) (((unsigned long)(x) - __abs_lowcore) % sizeof(struct lowcore))
+#define __kernel_va(x) ((void *)((unsigned long)(x) - __kaslr_offset_phys + __kaslr_offset))
+#define __kernel_pa(x) ((unsigned long)(x) - __kaslr_offset + __kaslr_offset_phys)
+#define __identity_va(x) ((void *)((unsigned long)(x) + __identity_base))
+#define __identity_pa(x) ((unsigned long)(x) - __identity_base)
static inline bool intersects(unsigned long addr0, unsigned long size0,
unsigned long addr1, unsigned long size1)
diff --git a/arch/s390/boot/decompressor.c b/arch/s390/boot/decompressor.c
index d762733a0753..f478e8e9cbda 100644
--- a/arch/s390/boot/decompressor.c
+++ b/arch/s390/boot/decompressor.c
@@ -63,24 +63,13 @@ static unsigned long free_mem_end_ptr = (unsigned long) _end + BOOT_HEAP_SIZE;
#include "../../../../lib/decompress_unzstd.c"
#endif
-#define decompress_offset ALIGN((unsigned long)_end + BOOT_HEAP_SIZE, PAGE_SIZE)
-
unsigned long mem_safe_offset(void)
{
- /*
- * due to 4MB HEAD_SIZE for bzip2
- * 'decompress_offset + vmlinux.image_size' could be larger than
- * kernel at final position + its .bss, so take the larger of two
- */
- return max(decompress_offset + vmlinux.image_size,
- vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size);
+ return ALIGN(free_mem_end_ptr, PAGE_SIZE);
}
-void *decompress_kernel(void)
+void deploy_kernel(void *output)
{
- void *output = (void *)decompress_offset;
-
__decompress(_compressed_start, _compressed_end - _compressed_start,
NULL, NULL, output, vmlinux.image_size, NULL, error);
- return output;
}
diff --git a/arch/s390/boot/decompressor.h b/arch/s390/boot/decompressor.h
index 92b81d2ea35d..4f966f06bd65 100644
--- a/arch/s390/boot/decompressor.h
+++ b/arch/s390/boot/decompressor.h
@@ -2,11 +2,9 @@
#ifndef BOOT_COMPRESSED_DECOMPRESSOR_H
#define BOOT_COMPRESSED_DECOMPRESSOR_H
-#ifdef CONFIG_KERNEL_UNCOMPRESSED
-static inline void *decompress_kernel(void) { return NULL; }
-#else
-void *decompress_kernel(void);
-#endif
+#ifndef CONFIG_KERNEL_UNCOMPRESSED
unsigned long mem_safe_offset(void);
+void deploy_kernel(void *output);
+#endif
#endif /* BOOT_COMPRESSED_DECOMPRESSOR_H */
diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh
index a13dd2f2aa1c..fa41486258ee 100755
--- a/arch/s390/boot/install.sh
+++ b/arch/s390/boot/install.sh
@@ -15,6 +15,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
echo "Warning: '${INSTALLKERNEL}' command not available - additional " \
"bootloader config required" >&2
if [ -f "$4/vmlinuz-$1" ]; then mv -- "$4/vmlinuz-$1" "$4/vmlinuz-$1.old"; fi
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index b24de9aabf7d..1773b72a6a7b 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -3,6 +3,7 @@
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/pgtable.h>
+#include <asm/abs_lowcore.h>
#include <asm/page-states.h>
#include <asm/ebcdic.h>
#include <asm/sclp.h>
@@ -51,11 +52,11 @@ static inline int __diag308(unsigned long subcode, void *addr)
: [r1] "+&d" (r1.pair),
[reg1] "=&d" (reg1),
[reg2] "=&a" (reg2),
- "+Q" (S390_lowcore.program_new_psw),
+ "+Q" (get_lowcore()->program_new_psw),
"=Q" (old)
: [subcode] "d" (subcode),
[psw_old] "a" (&old),
- [psw_pgm] "a" (&S390_lowcore.program_new_psw)
+ [psw_pgm] "a" (&get_lowcore()->program_new_psw)
: "cc", "memory");
return r1.odd;
}
@@ -310,5 +311,7 @@ void parse_boot_command_line(void)
prot_virt_host = 1;
}
#endif
+ if (!strcmp(param, "relocate_lowcore") && test_facility(193))
+ relocate_lowcore = 1;
}
}
diff --git a/arch/s390/boot/ipl_report.c b/arch/s390/boot/ipl_report.c
index 1803035e68d2..d00898852a88 100644
--- a/arch/s390/boot/ipl_report.c
+++ b/arch/s390/boot/ipl_report.c
@@ -106,7 +106,7 @@ int read_ipl_report(void)
* the IPL parameter list, then align the address to a double
* word boundary.
*/
- tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr;
+ tmp = (unsigned long)get_lowcore()->ipl_parmblock_ptr;
pl_hdr = (struct ipl_pl_hdr *) tmp;
tmp = (tmp + pl_hdr->len + 7) & -8UL;
rl_hdr = (struct ipl_rl_hdr *) tmp;
diff --git a/arch/s390/boot/kaslr.c b/arch/s390/boot/kaslr.c
index 90602101e2ae..bd3bf5ef472d 100644
--- a/arch/s390/boot/kaslr.c
+++ b/arch/s390/boot/kaslr.c
@@ -43,7 +43,7 @@ static int check_prng(void)
return PRNG_MODE_TDES;
}
-static int get_random(unsigned long limit, unsigned long *value)
+int get_random(unsigned long limit, unsigned long *value)
{
struct prng_parm prng = {
/* initial parameter block for tdes mode, copied from libica */
diff --git a/arch/s390/boot/kmsan.c b/arch/s390/boot/kmsan.c
new file mode 100644
index 000000000000..e7b3ac48143e
--- /dev/null
+++ b/arch/s390/boot/kmsan.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kmsan-checks.h>
+
+void kmsan_unpoison_memory(const void *address, size_t size)
+{
+}
diff --git a/arch/s390/boot/pgm_check_info.c b/arch/s390/boot/pgm_check_info.c
index 97244cd7a206..5352b3d356da 100644
--- a/arch/s390/boot/pgm_check_info.c
+++ b/arch/s390/boot/pgm_check_info.c
@@ -145,20 +145,22 @@ void print_stacktrace(unsigned long sp)
void print_pgm_check_info(void)
{
- unsigned long *gpregs = (unsigned long *)S390_lowcore.gpregs_save_area;
- struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area);
+ unsigned long *gpregs = (unsigned long *)get_lowcore()->gpregs_save_area;
+ struct psw_bits *psw = &psw_bits(get_lowcore()->psw_save_area);
decompressor_printk("Linux version %s\n", kernel_version);
if (!is_prot_virt_guest() && early_command_line[0])
decompressor_printk("Kernel command line: %s\n", early_command_line);
decompressor_printk("Kernel fault: interruption code %04x ilc:%x\n",
- S390_lowcore.pgm_code, S390_lowcore.pgm_ilc >> 1);
- if (kaslr_enabled())
+ get_lowcore()->pgm_code, get_lowcore()->pgm_ilc >> 1);
+ if (kaslr_enabled()) {
decompressor_printk("Kernel random base: %lx\n", __kaslr_offset);
+ decompressor_printk("Kernel random base phys: %lx\n", __kaslr_offset_phys);
+ }
decompressor_printk("PSW : %016lx %016lx (%pS)\n",
- S390_lowcore.psw_save_area.mask,
- S390_lowcore.psw_save_area.addr,
- (void *)S390_lowcore.psw_save_area.addr);
+ get_lowcore()->psw_save_area.mask,
+ get_lowcore()->psw_save_area.addr,
+ (void *)get_lowcore()->psw_save_area.addr);
decompressor_printk(
" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x P:%x AS:%x CC:%x PM:%x RI:%x EA:%x\n",
psw->per, psw->dat, psw->io, psw->ext, psw->key, psw->mcheck,
@@ -172,8 +174,8 @@ void print_pgm_check_info(void)
gpregs[8], gpregs[9], gpregs[10], gpregs[11]);
decompressor_printk(" %016lx %016lx %016lx %016lx\n",
gpregs[12], gpregs[13], gpregs[14], gpregs[15]);
- print_stacktrace(S390_lowcore.gpregs_save_area[15]);
+ print_stacktrace(get_lowcore()->gpregs_save_area[15]);
decompressor_printk("Last Breaking-Event-Address:\n");
- decompressor_printk(" [<%016lx>] %pS\n", (unsigned long)S390_lowcore.pgm_last_break,
- (void *)S390_lowcore.pgm_last_break);
+ decompressor_printk(" [<%016lx>] %pS\n", (unsigned long)get_lowcore()->pgm_last_break,
+ (void *)get_lowcore()->pgm_last_break);
}
diff --git a/arch/s390/boot/physmem_info.c b/arch/s390/boot/physmem_info.c
index 0cf79826eef9..4c9ad8258f7e 100644
--- a/arch/s390/boot/physmem_info.c
+++ b/arch/s390/boot/physmem_info.c
@@ -81,11 +81,11 @@ static int __diag260(unsigned long rx1, unsigned long rx2)
[reg2] "=&a" (reg2),
[rc] "+&d" (rc),
[ry] "+&d" (ry),
- "+Q" (S390_lowcore.program_new_psw),
+ "+Q" (get_lowcore()->program_new_psw),
"=Q" (old)
: [rx] "d" (rx.pair),
[psw_old] "a" (&old),
- [psw_pgm] "a" (&S390_lowcore.program_new_psw)
+ [psw_pgm] "a" (&get_lowcore()->program_new_psw)
: "cc", "memory");
return rc == 0 ? ry : -1;
}
@@ -129,10 +129,10 @@ static int tprot(unsigned long addr)
: [reg1] "=&d" (reg1),
[reg2] "=&a" (reg2),
[rc] "+&d" (rc),
- "=Q" (S390_lowcore.program_new_psw.addr),
+ "=Q" (get_lowcore()->program_new_psw.addr),
"=Q" (old)
: [psw_old] "a" (&old),
- [psw_pgm] "a" (&S390_lowcore.program_new_psw),
+ [psw_pgm] "a" (&get_lowcore()->program_new_psw),
[addr] "a" (addr)
: "cc", "memory");
return rc;
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 6cf89314209a..ce232552bc1c 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -3,6 +3,7 @@
#include <linux/elf.h>
#include <asm/page-states.h>
#include <asm/boot_data.h>
+#include <asm/extmem.h>
#include <asm/sections.h>
#include <asm/maccess.h>
#include <asm/cpu_mf.h>
@@ -18,7 +19,7 @@
#include "boot.h"
#include "uv.h"
-unsigned long __bootdata_preserved(__kaslr_offset);
+struct vm_layout __bootdata_preserved(vm_layout);
unsigned long __bootdata_preserved(__abs_lowcore);
unsigned long __bootdata_preserved(__memcpy_real_area);
pte_t *__bootdata_preserved(memcpy_real_ptep);
@@ -29,10 +30,9 @@ unsigned long __bootdata_preserved(vmemmap_size);
unsigned long __bootdata_preserved(MODULES_VADDR);
unsigned long __bootdata_preserved(MODULES_END);
unsigned long __bootdata_preserved(max_mappable);
-unsigned long __bootdata(ident_map_size);
+int __bootdata_preserved(relocate_lowcore);
u64 __bootdata_preserved(stfle_fac_list[16]);
-u64 __bootdata_preserved(alt_stfle_fac_list[16]);
struct oldmem_data __bootdata_preserved(oldmem_data);
struct machine_info machine;
@@ -79,10 +79,10 @@ static int cmma_test_essa(void)
[reg2] "=&a" (reg2),
[rc] "+&d" (rc),
[tmp] "=&d" (tmp),
- "+Q" (S390_lowcore.program_new_psw),
+ "+Q" (get_lowcore()->program_new_psw),
"=Q" (old)
: [psw_old] "a" (&old),
- [psw_pgm] "a" (&S390_lowcore.program_new_psw),
+ [psw_pgm] "a" (&get_lowcore()->program_new_psw),
[cmd] "i" (ESSA_GET_STATE)
: "cc", "memory");
return rc;
@@ -102,16 +102,26 @@ static void cmma_init(void)
static void setup_lpp(void)
{
- S390_lowcore.current_pid = 0;
- S390_lowcore.lpp = LPP_MAGIC;
+ get_lowcore()->current_pid = 0;
+ get_lowcore()->lpp = LPP_MAGIC;
if (test_facility(40))
- lpp(&S390_lowcore.lpp);
+ lpp(&get_lowcore()->lpp);
}
#ifdef CONFIG_KERNEL_UNCOMPRESSED
-unsigned long mem_safe_offset(void)
+static unsigned long mem_safe_offset(void)
{
- return vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size;
+ return (unsigned long)_compressed_start;
+}
+
+static void deploy_kernel(void *output)
+{
+ void *uncompressed_start = (void *)_compressed_start;
+
+ if (output == uncompressed_start)
+ return;
+ memmove(output, uncompressed_start, vmlinux.image_size);
+ memset(uncompressed_start, 0, vmlinux.image_size);
}
#endif
@@ -141,70 +151,18 @@ static void copy_bootdata(void)
memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
}
-#ifdef CONFIG_PIE_BUILD
-static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
-{
- Elf64_Rela *rela_start, *rela_end, *rela;
- int r_type, r_sym, rc;
- Elf64_Addr loc, val;
- Elf64_Sym *dynsym;
-
- rela_start = (Elf64_Rela *) vmlinux.rela_dyn_start;
- rela_end = (Elf64_Rela *) vmlinux.rela_dyn_end;
- dynsym = (Elf64_Sym *) vmlinux.dynsym_start;
- for (rela = rela_start; rela < rela_end; rela++) {
- loc = rela->r_offset + offset;
- val = rela->r_addend;
- r_sym = ELF64_R_SYM(rela->r_info);
- if (r_sym) {
- if (dynsym[r_sym].st_shndx != SHN_UNDEF)
- val += dynsym[r_sym].st_value + offset;
- } else {
- /*
- * 0 == undefined symbol table index (STN_UNDEF),
- * used for R_390_RELATIVE, only add KASLR offset
- */
- val += offset;
- }
- r_type = ELF64_R_TYPE(rela->r_info);
- rc = arch_kexec_do_relocs(r_type, (void *) loc, val, 0);
- if (rc)
- error("Unknown relocation type");
- }
-}
-
-static void kaslr_adjust_got(unsigned long offset) {}
-static void rescue_relocs(void) {}
-static void free_relocs(void) {}
-#else
-static int *vmlinux_relocs_64_start;
-static int *vmlinux_relocs_64_end;
-
-static void rescue_relocs(void)
-{
- unsigned long size = __vmlinux_relocs_64_end - __vmlinux_relocs_64_start;
-
- vmlinux_relocs_64_start = (void *)physmem_alloc_top_down(RR_RELOC, size, 0);
- vmlinux_relocs_64_end = (void *)vmlinux_relocs_64_start + size;
- memmove(vmlinux_relocs_64_start, __vmlinux_relocs_64_start, size);
-}
-
-static void free_relocs(void)
-{
- physmem_free(RR_RELOC);
-}
-
-static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
+static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
+ unsigned long offset, unsigned long phys_offset)
{
int *reloc;
long loc;
/* Adjust R_390_64 relocations */
- for (reloc = vmlinux_relocs_64_start; reloc < vmlinux_relocs_64_end; reloc++) {
- loc = (long)*reloc + offset;
+ for (reloc = (int *)__vmlinux_relocs_64_start; reloc < (int *)__vmlinux_relocs_64_end; reloc++) {
+ loc = (long)*reloc + phys_offset;
if (loc < min_addr || loc > max_addr)
error("64-bit relocation outside of kernel!\n");
- *(u64 *)loc += offset;
+ *(u64 *)loc += offset - __START_KERNEL;
}
}
@@ -213,13 +171,15 @@ static void kaslr_adjust_got(unsigned long offset)
u64 *entry;
/*
- * Even without -fPIE, Clang still uses a global offset table for some
- * reason. Adjust the GOT entries.
+ * Adjust GOT entries, except for ones for undefined weak symbols
+ * that resolved to zero. This also skips the first three reserved
+ * entries on s390x that are zero.
*/
- for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++)
- *entry += offset;
+ for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) {
+ if (*entry)
+ *entry += offset - __START_KERNEL;
+ }
}
-#endif
/*
* Merge information from several sources into a single ident_map_size value.
@@ -261,9 +221,26 @@ static void setup_ident_map_size(unsigned long max_physmem_end)
#endif
}
-static unsigned long setup_kernel_memory_layout(void)
+#define FIXMAP_SIZE round_up(MEMCPY_REAL_SIZE + ABS_LOWCORE_MAP_SIZE, sizeof(struct lowcore))
+
+static unsigned long get_vmem_size(unsigned long identity_size,
+ unsigned long vmemmap_size,
+ unsigned long vmalloc_size,
+ unsigned long rte_size)
+{
+ unsigned long max_mappable, vsize;
+
+ max_mappable = max(identity_size, MAX_DCSS_ADDR);
+ vsize = round_up(SZ_2G + max_mappable, rte_size) +
+ round_up(vmemmap_size, rte_size) +
+ FIXMAP_SIZE + MODULES_LEN + KASLR_LEN;
+ return size_add(vsize, vmalloc_size);
+}
+
+static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
{
unsigned long vmemmap_start;
+ unsigned long kernel_start;
unsigned long asce_limit;
unsigned long rte_size;
unsigned long pages;
@@ -275,12 +252,19 @@ static unsigned long setup_kernel_memory_layout(void)
vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page);
/* choose kernel address space layout: 4 or 3 levels. */
- vsize = round_up(ident_map_size, _REGION3_SIZE) + vmemmap_size +
- MODULES_LEN + MEMCPY_REAL_SIZE + ABS_LOWCORE_MAP_SIZE;
- vsize = size_add(vsize, vmalloc_size);
- if (IS_ENABLED(CONFIG_KASAN) || (vsize > _REGION2_SIZE)) {
+ BUILD_BUG_ON(!IS_ALIGNED(__START_KERNEL, THREAD_SIZE));
+ BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE));
+ BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE);
+ vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE);
+ if (IS_ENABLED(CONFIG_KASAN) || __NO_KASLR_END_KERNEL > _REGION2_SIZE ||
+ (vsize > _REGION2_SIZE && kaslr_enabled())) {
asce_limit = _REGION1_SIZE;
- rte_size = _REGION2_SIZE;
+ if (__NO_KASLR_END_KERNEL > _REGION2_SIZE) {
+ rte_size = _REGION2_SIZE;
+ vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION2_SIZE);
+ } else {
+ rte_size = _REGION3_SIZE;
+ }
} else {
asce_limit = _REGION2_SIZE;
rte_size = _REGION3_SIZE;
@@ -290,38 +274,74 @@ static unsigned long setup_kernel_memory_layout(void)
* Forcing modules and vmalloc area under the ultravisor
* secure storage limit, so that any vmalloc allocation
* we do could be used to back secure guest storage.
+ *
+ * Assume the secure storage limit always exceeds _REGION2_SIZE,
+ * otherwise asce_limit and rte_size would have been adjusted.
*/
vmax = adjust_to_uv_max(asce_limit);
#ifdef CONFIG_KASAN
+ BUILD_BUG_ON(__NO_KASLR_END_KERNEL > KASAN_SHADOW_START);
/* force vmalloc and modules below kasan shadow */
vmax = min(vmax, KASAN_SHADOW_START);
#endif
- __memcpy_real_area = round_down(vmax - MEMCPY_REAL_SIZE, PAGE_SIZE);
- __abs_lowcore = round_down(__memcpy_real_area - ABS_LOWCORE_MAP_SIZE,
- sizeof(struct lowcore));
- MODULES_END = round_down(__abs_lowcore, _SEGMENT_SIZE);
+ vsize = min(vsize, vmax);
+ if (kaslr_enabled()) {
+ unsigned long kernel_end, kaslr_len, slots, pos;
+
+ kaslr_len = max(KASLR_LEN, vmax - vsize);
+ slots = DIV_ROUND_UP(kaslr_len - kernel_size, THREAD_SIZE);
+ if (get_random(slots, &pos))
+ pos = 0;
+ kernel_end = vmax - pos * THREAD_SIZE;
+ kernel_start = round_down(kernel_end - kernel_size, THREAD_SIZE);
+ } else if (vmax < __NO_KASLR_END_KERNEL || vsize > __NO_KASLR_END_KERNEL) {
+ kernel_start = round_down(vmax - kernel_size, THREAD_SIZE);
+ decompressor_printk("The kernel base address is forced to %lx\n", kernel_start);
+ } else {
+ kernel_start = __NO_KASLR_START_KERNEL;
+ }
+ __kaslr_offset = kernel_start;
+
+ MODULES_END = round_down(kernel_start, _SEGMENT_SIZE);
MODULES_VADDR = MODULES_END - MODULES_LEN;
VMALLOC_END = MODULES_VADDR;
+ if (IS_ENABLED(CONFIG_KMSAN))
+ VMALLOC_END -= MODULES_LEN * 2;
/* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
- vsize = round_down(VMALLOC_END / 2, _SEGMENT_SIZE);
+ vsize = (VMALLOC_END - FIXMAP_SIZE) / 2;
+ vsize = round_down(vsize, _SEGMENT_SIZE);
vmalloc_size = min(vmalloc_size, vsize);
+ if (IS_ENABLED(CONFIG_KMSAN)) {
+ /* take 2/3 of vmalloc area for KMSAN shadow and origins */
+ vmalloc_size = round_down(vmalloc_size / 3, _SEGMENT_SIZE);
+ VMALLOC_END -= vmalloc_size * 2;
+ }
VMALLOC_START = VMALLOC_END - vmalloc_size;
+ __memcpy_real_area = round_down(VMALLOC_START - MEMCPY_REAL_SIZE, PAGE_SIZE);
+ __abs_lowcore = round_down(__memcpy_real_area - ABS_LOWCORE_MAP_SIZE,
+ sizeof(struct lowcore));
+
/* split remaining virtual space between 1:1 mapping & vmemmap array */
- pages = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
+ pages = __abs_lowcore / (PAGE_SIZE + sizeof(struct page));
pages = SECTION_ALIGN_UP(pages);
/* keep vmemmap_start aligned to a top level region table entry */
- vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size);
- vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS);
- /* maximum mappable address as seen by arch_get_mappable_range() */
- max_mappable = vmemmap_start;
+ vmemmap_start = round_down(__abs_lowcore - pages * sizeof(struct page), rte_size);
/* make sure identity map doesn't overlay with vmemmap */
ident_map_size = min(ident_map_size, vmemmap_start);
vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page);
- /* make sure vmemmap doesn't overlay with vmalloc area */
- VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START);
+ /* make sure vmemmap doesn't overlay with absolute lowcore area */
+ if (vmemmap_start + vmemmap_size > __abs_lowcore) {
+ vmemmap_size = SECTION_ALIGN_DOWN(ident_map_size / PAGE_SIZE) * sizeof(struct page);
+ ident_map_size = vmemmap_size / sizeof(struct page) * PAGE_SIZE;
+ }
vmemmap = (struct page *)vmemmap_start;
+ /* maximum address for which linear mapping could be created (DCSS, memory) */
+ BUILD_BUG_ON(MAX_DCSS_ADDR > (1UL << MAX_PHYSMEM_BITS));
+ max_mappable = max(ident_map_size, MAX_DCSS_ADDR);
+ max_mappable = min(max_mappable, vmemmap_start);
+ __identity_base = round_down(vmemmap_start - max_mappable, rte_size);
return asce_limit;
}
@@ -329,9 +349,9 @@ static unsigned long setup_kernel_memory_layout(void)
/*
* This function clears the BSS section of the decompressed Linux kernel and NOT the decompressor's.
*/
-static void clear_bss_section(unsigned long vmlinux_lma)
+static void clear_bss_section(unsigned long kernel_start)
{
- memset((void *)vmlinux_lma + vmlinux.image_size, 0, vmlinux.bss_size);
+ memset((void *)kernel_start + vmlinux.image_size, 0, vmlinux.bss_size);
}
/*
@@ -348,22 +368,17 @@ static void setup_vmalloc_size(void)
vmalloc_size = max(size, vmalloc_size);
}
-static void kaslr_adjust_vmlinux_info(unsigned long offset)
+static void kaslr_adjust_vmlinux_info(long offset)
{
- *(unsigned long *)(&vmlinux.entry) += offset;
vmlinux.bootdata_off += offset;
vmlinux.bootdata_preserved_off += offset;
-#ifdef CONFIG_PIE_BUILD
- vmlinux.rela_dyn_start += offset;
- vmlinux.rela_dyn_end += offset;
- vmlinux.dynsym_start += offset;
-#else
vmlinux.got_start += offset;
vmlinux.got_end += offset;
-#endif
vmlinux.init_mm_off += offset;
vmlinux.swapper_pg_dir_off += offset;
vmlinux.invalid_pg_dir_off += offset;
+ vmlinux.alt_instructions += offset;
+ vmlinux.alt_instructions_end += offset;
#ifdef CONFIG_KASAN
vmlinux.kasan_early_shadow_page_off += offset;
vmlinux.kasan_early_shadow_pte_off += offset;
@@ -373,23 +388,36 @@ static void kaslr_adjust_vmlinux_info(unsigned long offset)
#endif
}
+static void fixup_vmlinux_info(void)
+{
+ vmlinux.entry -= __START_KERNEL;
+ kaslr_adjust_vmlinux_info(-__START_KERNEL);
+}
+
void startup_kernel(void)
{
- unsigned long max_physmem_end;
- unsigned long vmlinux_lma = 0;
+ unsigned long kernel_size = vmlinux.image_size + vmlinux.bss_size;
+ unsigned long nokaslr_offset_phys, kaslr_large_page_offset;
unsigned long amode31_lma = 0;
+ unsigned long max_physmem_end;
unsigned long asce_limit;
unsigned long safe_addr;
- void *img;
psw_t psw;
+ fixup_vmlinux_info();
setup_lpp();
- safe_addr = mem_safe_offset();
/*
- * Reserve decompressor memory together with decompression heap, buffer and
- * memory which might be occupied by uncompressed kernel at default 1Mb
- * position (if KASLR is off or failed).
+ * Non-randomized kernel physical start address must be _SEGMENT_SIZE
+ * aligned (see blow).
+ */
+ nokaslr_offset_phys = ALIGN(mem_safe_offset(), _SEGMENT_SIZE);
+ safe_addr = PAGE_ALIGN(nokaslr_offset_phys + kernel_size);
+
+ /*
+ * Reserve decompressor memory together with decompression heap,
+ * buffer and memory which might be occupied by uncompressed kernel
+ * (if KASLR is off or failed).
*/
physmem_reserve(RR_DECOMPRESSOR, 0, safe_addr);
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && parmarea.initrd_size)
@@ -409,40 +437,58 @@ void startup_kernel(void)
max_physmem_end = detect_max_physmem_end();
setup_ident_map_size(max_physmem_end);
setup_vmalloc_size();
- asce_limit = setup_kernel_memory_layout();
+ asce_limit = setup_kernel_memory_layout(kernel_size);
/* got final ident_map_size, physmem allocations could be performed now */
physmem_set_usable_limit(ident_map_size);
detect_physmem_online_ranges(max_physmem_end);
save_ipl_cert_comp_list();
rescue_initrd(safe_addr, ident_map_size);
- rescue_relocs();
+ /*
+ * __kaslr_offset_phys must be _SEGMENT_SIZE aligned, so the lower
+ * 20 bits (the offset within a large page) are zero. Copy the last
+ * 20 bits of __kaslr_offset, which is THREAD_SIZE aligned, to
+ * __kaslr_offset_phys.
+ *
+ * With this the last 20 bits of __kaslr_offset_phys and __kaslr_offset
+ * are identical, which is required to allow for large mappings of the
+ * kernel image.
+ */
+ kaslr_large_page_offset = __kaslr_offset & ~_SEGMENT_MASK;
if (kaslr_enabled()) {
- vmlinux_lma = randomize_within_range(vmlinux.image_size + vmlinux.bss_size,
- THREAD_SIZE, vmlinux.default_lma,
- ident_map_size);
- if (vmlinux_lma) {
- __kaslr_offset = vmlinux_lma - vmlinux.default_lma;
- kaslr_adjust_vmlinux_info(__kaslr_offset);
- }
- }
- vmlinux_lma = vmlinux_lma ?: vmlinux.default_lma;
- physmem_reserve(RR_VMLINUX, vmlinux_lma, vmlinux.image_size + vmlinux.bss_size);
-
- if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
- img = decompress_kernel();
- memmove((void *)vmlinux_lma, img, vmlinux.image_size);
- } else if (__kaslr_offset) {
- img = (void *)vmlinux.default_lma;
- memmove((void *)vmlinux_lma, img, vmlinux.image_size);
- memset(img, 0, vmlinux.image_size);
+ unsigned long end = ident_map_size - kaslr_large_page_offset;
+
+ __kaslr_offset_phys = randomize_within_range(kernel_size, _SEGMENT_SIZE, 0, end);
}
+ if (!__kaslr_offset_phys)
+ __kaslr_offset_phys = nokaslr_offset_phys;
+ __kaslr_offset_phys |= kaslr_large_page_offset;
+ kaslr_adjust_vmlinux_info(__kaslr_offset_phys);
+ physmem_reserve(RR_VMLINUX, __kaslr_offset_phys, kernel_size);
+ deploy_kernel((void *)__kaslr_offset_phys);
/* vmlinux decompression is done, shrink reserved low memory */
physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end);
- if (kaslr_enabled())
- amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, 0, SZ_2G);
- amode31_lma = amode31_lma ?: vmlinux.default_lma - vmlinux.amode31_size;
+
+ /*
+ * In case KASLR is enabled the randomized location of .amode31
+ * section might overlap with .vmlinux.relocs section. To avoid that
+ * the below randomize_within_range() could have been called with
+ * __vmlinux_relocs_64_end as the lower range address. However,
+ * .amode31 section is written to by the decompressed kernel - at
+ * that time the contents of .vmlinux.relocs is not needed anymore.
+ * Conversly, .vmlinux.relocs is read only by the decompressor, even
+ * before the kernel started. Therefore, in case the two sections
+ * overlap there is no risk of corrupting any data.
+ */
+ if (kaslr_enabled()) {
+ unsigned long amode31_min;
+
+ amode31_min = (unsigned long)_decompressor_end;
+ amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, amode31_min, SZ_2G);
+ }
+ if (!amode31_lma)
+ amode31_lma = __kaslr_offset_phys - vmlinux.amode31_size;
physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size);
/*
@@ -458,23 +504,26 @@ void startup_kernel(void)
* - copy_bootdata() must follow setup_vmem() to propagate changes
* to bootdata made by setup_vmem()
*/
- clear_bss_section(vmlinux_lma);
- kaslr_adjust_relocs(vmlinux_lma, vmlinux_lma + vmlinux.image_size, __kaslr_offset);
+ clear_bss_section(__kaslr_offset_phys);
+ kaslr_adjust_relocs(__kaslr_offset_phys, __kaslr_offset_phys + vmlinux.image_size,
+ __kaslr_offset, __kaslr_offset_phys);
kaslr_adjust_got(__kaslr_offset);
- free_relocs();
- setup_vmem(asce_limit);
+ setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
copy_bootdata();
+ __apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions,
+ (struct alt_instr *)_vmlinux_info.alt_instructions_end,
+ ALT_CTX_EARLY);
/*
* Save KASLR offset for early dumps, before vmcore_info is set.
* Mark as uneven to distinguish from real vmcore_info pointer.
*/
- S390_lowcore.vmcore_info = __kaslr_offset ? __kaslr_offset | 0x1UL : 0;
+ get_lowcore()->vmcore_info = __kaslr_offset_phys ? __kaslr_offset_phys | 0x1UL : 0;
/*
* Jump to the decompressed kernel entry point and switch DAT mode on.
*/
- psw.addr = vmlinux.entry;
+ psw.addr = __kaslr_offset + vmlinux.entry;
psw.mask = PSW_KERNEL_BITS;
__load_psw(psw);
}
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index faccb33b462c..f6b9b1df48a8 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -1,11 +1,18 @@
// SPDX-License-Identifier: GPL-2.0
+#define IN_BOOT_STRING_C 1
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#undef CONFIG_KASAN
#undef CONFIG_KASAN_GENERIC
+#undef CONFIG_KMSAN
#include "../lib/string.c"
+/*
+ * Duplicate some functions from the common lib/string.c
+ * instead of fully including it.
+ */
+
int strncmp(const char *cs, const char *ct, size_t count)
{
unsigned char c1, c2;
@@ -22,6 +29,15 @@ int strncmp(const char *cs, const char *ct, size_t count)
return 0;
}
+void *memset64(uint64_t *s, uint64_t v, size_t count)
+{
+ uint64_t *xs = s;
+
+ while (count--)
+ *xs++ = v;
+ return s;
+}
+
char *skip_spaces(const char *str)
{
while (isspace(*str))
diff --git a/arch/s390/boot/uv.c b/arch/s390/boot/uv.c
index 1e66d2cbb096..318e6ba95bfd 100644
--- a/arch/s390/boot/uv.c
+++ b/arch/s390/boot/uv.c
@@ -8,12 +8,8 @@
#include "uv.h"
/* will be used in arch/s390/kernel/uv.c */
-#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)
@@ -53,14 +49,11 @@ void uv_query_info(void)
uv_info.max_secrets = uvcb.max_secrets;
}
-#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
if (test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list) &&
test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list))
prot_virt_guest = 1;
-#endif
}
-#if IS_ENABLED(CONFIG_KVM)
unsigned long adjust_to_uv_max(unsigned long limit)
{
if (is_prot_virt_host() && uv_info.max_sec_stor_addr)
@@ -92,4 +85,3 @@ void sanitize_prot_virt_host(void)
{
prot_virt_host = is_prot_virt_host_capable();
}
-#endif
diff --git a/arch/s390/boot/uv.h b/arch/s390/boot/uv.h
index 0f3070856f8d..da4a4a8d48e0 100644
--- a/arch/s390/boot/uv.h
+++ b/arch/s390/boot/uv.h
@@ -2,21 +2,8 @@
#ifndef BOOT_UV_H
#define BOOT_UV_H
-#if IS_ENABLED(CONFIG_KVM)
unsigned long adjust_to_uv_max(unsigned long limit);
void sanitize_prot_virt_host(void);
-#else
-static inline unsigned long adjust_to_uv_max(unsigned long limit)
-{
- return limit;
-}
-static inline void sanitize_prot_virt_host(void) {}
-#endif
-
-#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM)
void uv_query_info(void);
-#else
-static inline void uv_query_info(void) {}
-#endif
#endif /* BOOT_UV_H */
diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c
index 09b10bb6e4d0..2847cc059ab7 100644
--- a/arch/s390/boot/vmem.c
+++ b/arch/s390/boot/vmem.c
@@ -26,7 +26,10 @@ atomic_long_t __bootdata_preserved(direct_pages_count[PG_DIRECT_MAP_MAX]);
enum populate_mode {
POPULATE_NONE,
POPULATE_DIRECT,
+ POPULATE_LOWCORE,
POPULATE_ABS_LOWCORE,
+ POPULATE_IDENTITY,
+ POPULATE_KERNEL,
#ifdef CONFIG_KASAN
POPULATE_KASAN_MAP_SHADOW,
POPULATE_KASAN_ZERO_SHADOW,
@@ -54,7 +57,7 @@ static inline void kasan_populate(unsigned long start, unsigned long end, enum p
pgtable_populate(start, end, mode);
}
-static void kasan_populate_shadow(void)
+static void kasan_populate_shadow(unsigned long kernel_start, unsigned long kernel_end)
{
pmd_t pmd_z = __pmd(__pa(kasan_early_shadow_pte) | _SEGMENT_ENTRY);
pud_t pud_z = __pud(__pa(kasan_early_shadow_pmd) | _REGION3_ENTRY);
@@ -76,44 +79,20 @@ static void kasan_populate_shadow(void)
__arch_set_page_dat(kasan_early_shadow_pmd, 1UL << CRST_ALLOC_ORDER);
__arch_set_page_dat(kasan_early_shadow_pte, 1);
- /*
- * Current memory layout:
- * +- 0 -------------+ +- shadow start -+
- * |1:1 ident mapping| /|1/8 of ident map|
- * | | / | |
- * +-end of ident map+ / +----------------+
- * | ... gap ... | / | kasan |
- * | | / | zero page |
- * +- vmalloc area -+ / | mapping |
- * | vmalloc_size | / | (untracked) |
- * +- modules vaddr -+ / +----------------+
- * | 2Gb |/ | unmapped | allocated per module
- * +- shadow start -+ +----------------+
- * | 1/8 addr space | | zero pg mapping| (untracked)
- * +- shadow end ----+---------+- shadow end ---+
- *
- * Current memory layout (KASAN_VMALLOC):
- * +- 0 -------------+ +- shadow start -+
- * |1:1 ident mapping| /|1/8 of ident map|
- * | | / | |
- * +-end of ident map+ / +----------------+
- * | ... gap ... | / | kasan zero page| (untracked)
- * | | / | mapping |
- * +- vmalloc area -+ / +----------------+
- * | vmalloc_size | / |shallow populate|
- * +- modules vaddr -+ / +----------------+
- * | 2Gb |/ |shallow populate|
- * +- shadow start -+ +----------------+
- * | 1/8 addr space | | zero pg mapping| (untracked)
- * +- shadow end ----+---------+- shadow end ---+
- */
-
for_each_physmem_usable_range(i, &start, &end) {
- kasan_populate(start, end, POPULATE_KASAN_MAP_SHADOW);
- if (memgap_start && physmem_info.info_source == MEM_DETECT_DIAG260)
- kasan_populate(memgap_start, start, POPULATE_KASAN_ZERO_SHADOW);
+ kasan_populate((unsigned long)__identity_va(start),
+ (unsigned long)__identity_va(end),
+ POPULATE_KASAN_MAP_SHADOW);
+ if (memgap_start && physmem_info.info_source == MEM_DETECT_DIAG260) {
+ kasan_populate((unsigned long)__identity_va(memgap_start),
+ (unsigned long)__identity_va(start),
+ POPULATE_KASAN_ZERO_SHADOW);
+ }
memgap_start = end;
}
+ kasan_populate(kernel_start, kernel_end, POPULATE_KASAN_MAP_SHADOW);
+ kasan_populate(0, (unsigned long)__identity_va(0), POPULATE_KASAN_ZERO_SHADOW);
+ kasan_populate(AMODE31_START, AMODE31_END, POPULATE_KASAN_ZERO_SHADOW);
if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
untracked_end = VMALLOC_START;
/* shallowly populate kasan shadow for vmalloc and modules */
@@ -122,8 +101,9 @@ static void kasan_populate_shadow(void)
untracked_end = MODULES_VADDR;
}
/* populate kasan shadow for untracked memory */
- kasan_populate(ident_map_size, untracked_end, POPULATE_KASAN_ZERO_SHADOW);
- kasan_populate(MODULES_END, _REGION1_SIZE, POPULATE_KASAN_ZERO_SHADOW);
+ kasan_populate((unsigned long)__identity_va(ident_map_size), untracked_end,
+ POPULATE_KASAN_ZERO_SHADOW);
+ kasan_populate(kernel_end, _REGION1_SIZE, POPULATE_KASAN_ZERO_SHADOW);
}
static bool kasan_pgd_populate_zero_shadow(pgd_t *pgd, unsigned long addr,
@@ -180,7 +160,9 @@ static bool kasan_pte_populate_zero_shadow(pte_t *pte, enum populate_mode mode)
}
#else
-static inline void kasan_populate_shadow(void) {}
+static inline void kasan_populate_shadow(unsigned long kernel_start, unsigned long kernel_end)
+{
+}
static inline bool kasan_pgd_populate_zero_shadow(pgd_t *pgd, unsigned long addr,
unsigned long end, enum populate_mode mode)
@@ -261,8 +243,14 @@ static unsigned long _pa(unsigned long addr, unsigned long size, enum populate_m
return -1;
case POPULATE_DIRECT:
return addr;
+ case POPULATE_LOWCORE:
+ return __lowcore_pa(addr);
case POPULATE_ABS_LOWCORE:
return __abs_lowcore_pa(addr);
+ case POPULATE_KERNEL:
+ return __kernel_pa(addr);
+ case POPULATE_IDENTITY:
+ return __identity_pa(addr);
#ifdef CONFIG_KASAN
case POPULATE_KASAN_MAP_SHADOW:
addr = physmem_alloc_top_down(RR_VMEM, size, size);
@@ -274,16 +262,29 @@ static unsigned long _pa(unsigned long addr, unsigned long size, enum populate_m
}
}
-static bool can_large_pud(pud_t *pu_dir, unsigned long addr, unsigned long end)
+static bool large_allowed(enum populate_mode mode)
{
- return machine.has_edat2 &&
- IS_ALIGNED(addr, PUD_SIZE) && (end - addr) >= PUD_SIZE;
+ return (mode == POPULATE_DIRECT) || (mode == POPULATE_IDENTITY) || (mode == POPULATE_KERNEL);
}
-static bool can_large_pmd(pmd_t *pm_dir, unsigned long addr, unsigned long end)
+static bool can_large_pud(pud_t *pu_dir, unsigned long addr, unsigned long end,
+ enum populate_mode mode)
{
- return machine.has_edat1 &&
- IS_ALIGNED(addr, PMD_SIZE) && (end - addr) >= PMD_SIZE;
+ unsigned long size = end - addr;
+
+ return machine.has_edat2 && large_allowed(mode) &&
+ IS_ALIGNED(addr, PUD_SIZE) && (size >= PUD_SIZE) &&
+ IS_ALIGNED(_pa(addr, size, mode), PUD_SIZE);
+}
+
+static bool can_large_pmd(pmd_t *pm_dir, unsigned long addr, unsigned long end,
+ enum populate_mode mode)
+{
+ unsigned long size = end - addr;
+
+ return machine.has_edat1 && large_allowed(mode) &&
+ IS_ALIGNED(addr, PMD_SIZE) && (size >= PMD_SIZE) &&
+ IS_ALIGNED(_pa(addr, size, mode), PMD_SIZE);
}
static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long end,
@@ -322,7 +323,7 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
if (pmd_none(*pmd)) {
if (kasan_pmd_populate_zero_shadow(pmd, addr, next, mode))
continue;
- if (can_large_pmd(pmd, addr, next)) {
+ if (can_large_pmd(pmd, addr, next, mode)) {
entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode));
entry = set_pmd_bit(entry, SEGMENT_KERNEL);
if (!machine.has_nx)
@@ -355,7 +356,7 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
if (pud_none(*pud)) {
if (kasan_pud_populate_zero_shadow(pud, addr, next, mode))
continue;
- if (can_large_pud(pud, addr, next)) {
+ if (can_large_pud(pud, addr, next, mode)) {
entry = __pud(_pa(addr, _REGION3_SIZE, mode));
entry = set_pud_bit(entry, REGION3_KERNEL);
if (!machine.has_nx)
@@ -418,11 +419,13 @@ static void pgtable_populate(unsigned long addr, unsigned long end, enum populat
}
}
-void setup_vmem(unsigned long asce_limit)
+void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned long asce_limit)
{
+ unsigned long lowcore_address = 0;
unsigned long start, end;
unsigned long asce_type;
unsigned long asce_bits;
+ pgd_t *init_mm_pgd;
int i;
/*
@@ -433,6 +436,15 @@ void setup_vmem(unsigned long asce_limit)
for_each_physmem_online_range(i, &start, &end)
__arch_set_page_nodat((void *)start, (end - start) >> PAGE_SHIFT);
+ /*
+ * init_mm->pgd contains virtual address of swapper_pg_dir.
+ * It is unusable at this stage since DAT is yet off. Swap
+ * it for physical address of swapper_pg_dir and restore
+ * the virtual address after all page tables are created.
+ */
+ init_mm_pgd = init_mm.pgd;
+ init_mm.pgd = (pgd_t *)swapper_pg_dir;
+
if (asce_limit == _REGION1_SIZE) {
asce_type = _REGION2_ENTRY_EMPTY;
asce_bits = _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH;
@@ -447,28 +459,39 @@ void setup_vmem(unsigned long asce_limit)
__arch_set_page_dat((void *)swapper_pg_dir, 1UL << CRST_ALLOC_ORDER);
__arch_set_page_dat((void *)invalid_pg_dir, 1UL << CRST_ALLOC_ORDER);
+ if (relocate_lowcore)
+ lowcore_address = LOWCORE_ALT_ADDRESS;
+
/*
* To allow prefixing the lowcore must be mapped with 4KB pages.
* To prevent creation of a large page at address 0 first map
* the lowcore and create the identity mapping only afterwards.
*/
- pgtable_populate(0, sizeof(struct lowcore), POPULATE_DIRECT);
- for_each_physmem_usable_range(i, &start, &end)
- pgtable_populate(start, end, POPULATE_DIRECT);
+ pgtable_populate(lowcore_address,
+ lowcore_address + sizeof(struct lowcore),
+ POPULATE_LOWCORE);
+ for_each_physmem_usable_range(i, &start, &end) {
+ pgtable_populate((unsigned long)__identity_va(start),
+ (unsigned long)__identity_va(end),
+ POPULATE_IDENTITY);
+ }
+ pgtable_populate(kernel_start, kernel_end, POPULATE_KERNEL);
+ pgtable_populate(AMODE31_START, AMODE31_END, POPULATE_DIRECT);
pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore),
POPULATE_ABS_LOWCORE);
pgtable_populate(__memcpy_real_area, __memcpy_real_area + PAGE_SIZE,
POPULATE_NONE);
- memcpy_real_ptep = __virt_to_kpte(__memcpy_real_area);
+ memcpy_real_ptep = __identity_va(__virt_to_kpte(__memcpy_real_area));
- kasan_populate_shadow();
+ kasan_populate_shadow(kernel_start, kernel_end);
- S390_lowcore.kernel_asce.val = swapper_pg_dir | asce_bits;
- S390_lowcore.user_asce = s390_invalid_asce;
+ get_lowcore()->kernel_asce.val = swapper_pg_dir | asce_bits;
+ get_lowcore()->user_asce = s390_invalid_asce;
- local_ctl_load(1, &S390_lowcore.kernel_asce);
- local_ctl_load(7, &S390_lowcore.user_asce);
- local_ctl_load(13, &S390_lowcore.kernel_asce);
+ local_ctl_load(1, &get_lowcore()->kernel_asce);
+ local_ctl_load(7, &get_lowcore()->user_asce);
+ local_ctl_load(13, &get_lowcore()->kernel_asce);
- init_mm.context.asce = S390_lowcore.kernel_asce.val;
+ init_mm.context.asce = get_lowcore()->kernel_asce.val;
+ init_mm.pgd = init_mm_pgd;
}
diff --git a/arch/s390/boot/vmlinux.lds.S b/arch/s390/boot/vmlinux.lds.S
index 3d7ea585ab99..a750711d44c8 100644
--- a/arch/s390/boot/vmlinux.lds.S
+++ b/arch/s390/boot/vmlinux.lds.S
@@ -99,8 +99,17 @@ SECTIONS
_decompressor_end = .;
+ . = ALIGN(4);
+ .vmlinux.relocs : {
+ __vmlinux_relocs_64_start = .;
+ *(.vmlinux.relocs_64)
+ __vmlinux_relocs_64_end = .;
+ }
+
#ifdef CONFIG_KERNEL_UNCOMPRESSED
- . = 0x100000;
+ . = ALIGN(PAGE_SIZE);
+ . += AMODE31_SIZE; /* .amode31 section */
+ . = ALIGN(1 << 20); /* _SEGMENT_SIZE */
#else
. = ALIGN(8);
#endif
@@ -110,24 +119,6 @@ SECTIONS
_compressed_end = .;
}
-#ifndef CONFIG_PIE_BUILD
- /*
- * When the kernel is built with CONFIG_KERNEL_UNCOMPRESSED, the entire
- * uncompressed vmlinux.bin is positioned in the bzImage decompressor
- * image at the default kernel LMA of 0x100000, enabling it to be
- * executed in-place. However, the size of .vmlinux.relocs could be
- * large enough to cause an overlap with the uncompressed kernel at the
- * address 0x100000. To address this issue, .vmlinux.relocs is
- * positioned after the .rodata.compressed.
- */
- . = ALIGN(4);
- .vmlinux.relocs : {
- __vmlinux_relocs_64_start = .;
- *(.vmlinux.relocs_64)
- __vmlinux_relocs_64_end = .;
- }
-#endif
-
#define SB_TRAILER_SIZE 32
/* Trailer needed for Secure Boot */
. += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index f1fb01cd5a25..ea63a7342f5f 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -43,7 +43,6 @@ CONFIG_PROFILING=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_KEXEC_SIG=y
-CONFIG_CRASH_DUMP=y
CONFIG_LIVEPATCH=y
CONFIG_MARCH_Z13=y
CONFIG_NR_CPUS=512
@@ -51,11 +50,11 @@ CONFIG_NUMA=y
CONFIG_HZ_100=y
CONFIG_CERT_STORE=y
CONFIG_EXPOLINE=y
+# CONFIG_EXPOLINE_EXTERN is not set
CONFIG_EXPOLINE_AUTO=y
CONFIG_CHSC_SCH=y
CONFIG_VFIO_CCW=m
CONFIG_VFIO_AP=m
-CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
CONFIG_CMM=m
CONFIG_APPLDATA_BASE=y
CONFIG_S390_HYPFS_FS=y
@@ -76,6 +75,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG_SHA256=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_WBT=y
CONFIG_BLK_CGROUP_IOLATENCY=y
@@ -100,7 +100,6 @@ CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CMA_DEBUG=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_SYSFS=y
CONFIG_CMA_AREAS=7
@@ -119,6 +118,7 @@ CONFIG_UNIX_DIAG=m
CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
CONFIG_SMC_DIAG=m
+CONFIG_SMC_LO=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
@@ -133,7 +133,6 @@ CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=m
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
@@ -167,6 +166,7 @@ CONFIG_BRIDGE_NETFILTER=m
CONFIG_NETFILTER_NETLINK_HOOK=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
@@ -183,17 +183,39 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NF_CT_NETLINK_HELPER=m
+CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
+CONFIG_NFT_FLOW_OFFLOAD=m
+CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
+CONFIG_NFT_MASQ=m
+CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
+CONFIG_NFT_TUNNEL=m
+CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_FIB_INET=m
-CONFIG_NETFILTER_XTABLES_COMPAT=y
+CONFIG_NFT_XFRM=m
+CONFIG_NFT_SOCKET=m
+CONFIG_NFT_OSF=m
+CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
+CONFIG_NFT_FIB_NETDEV=m
+CONFIG_NFT_REJECT_NETDEV=m
+CONFIG_NF_FLOW_TABLE_INET=m
+CONFIG_NF_FLOW_TABLE=m
+CONFIG_NF_FLOW_TABLE_PROCFS=y
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
@@ -206,8 +228,10 @@ CONFIG_NETFILTER_XT_TARGET_HMARK=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NETMAP=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
CONFIG_NETFILTER_XT_TARGET_TEE=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
@@ -216,6 +240,7 @@ CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
@@ -230,6 +255,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -247,6 +273,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
CONFIG_NETFILTER_XT_MATCH_REALM=m
CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
@@ -302,7 +329,6 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_FIB_IPV6=m
@@ -373,7 +399,6 @@ CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
CONFIG_NET_ACT_NAT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
@@ -462,6 +487,7 @@ CONFIG_DM_VERITY=m
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_DM_SWITCH=m
CONFIG_DM_INTEGRITY=m
+CONFIG_DM_VDO=m
CONFIG_NETDEVICES=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
@@ -574,18 +600,16 @@ CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_DIAG288_WATCHDOG=m
-# CONFIG_DRM_DEBUG_MODESET_LOCK is not set
+CONFIG_DRM=m
+CONFIG_DRM_VIRTIO_GPU=m
CONFIG_FB=y
# CONFIG_FB_DEVICE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_MLX5_INFINIBAND=m
-CONFIG_SYNC_FILE=y
CONFIG_VFIO=m
CONFIG_VFIO_PCI=m
CONFIG_MLX5_VFIO_PCI=m
@@ -645,7 +669,6 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_EXFAT_FS=m
CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
@@ -663,6 +686,7 @@ CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_ROMFS_FS=m
CONFIG_NFS_FS=m
+CONFIG_NFS_V2=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
@@ -760,7 +784,6 @@ CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_STATS=y
CONFIG_CRYPTO_CRC32_S390=y
CONFIG_CRYPTO_SHA512_S390=m
CONFIG_CRYPTO_SHA1_S390=m
@@ -880,6 +903,5 @@ CONFIG_RBTREE_TEST=y
CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_STRING_SELFTEST=y
CONFIG_TEST_BITOPS=m
CONFIG_TEST_BPF=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index d33f814f78b2..d8b28ff8ff45 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -41,7 +41,6 @@ CONFIG_PROFILING=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_KEXEC_SIG=y
-CONFIG_CRASH_DUMP=y
CONFIG_LIVEPATCH=y
CONFIG_MARCH_Z13=y
CONFIG_NR_CPUS=512
@@ -49,11 +48,11 @@ CONFIG_NUMA=y
CONFIG_HZ_100=y
CONFIG_CERT_STORE=y
CONFIG_EXPOLINE=y
+# CONFIG_EXPOLINE_EXTERN is not set
CONFIG_EXPOLINE_AUTO=y
CONFIG_CHSC_SCH=y
CONFIG_VFIO_CCW=m
CONFIG_VFIO_AP=m
-CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
CONFIG_CMM=m
CONFIG_APPLDATA_BASE=y
CONFIG_S390_HYPFS_FS=y
@@ -71,6 +70,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG_SHA256=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_WBT=y
CONFIG_BLK_CGROUP_IOLATENCY=y
@@ -110,6 +110,7 @@ CONFIG_UNIX_DIAG=m
CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
CONFIG_SMC_DIAG=m
+CONFIG_SMC_LO=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
@@ -124,7 +125,6 @@ CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=m
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
@@ -158,6 +158,7 @@ CONFIG_BRIDGE_NETFILTER=m
CONFIG_NETFILTER_NETLINK_HOOK=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
@@ -174,17 +175,39 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NF_CT_NETLINK_HELPER=m
+CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
+CONFIG_NFT_FLOW_OFFLOAD=m
+CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
+CONFIG_NFT_MASQ=m
+CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
+CONFIG_NFT_TUNNEL=m
+CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_FIB_INET=m
-CONFIG_NETFILTER_XTABLES_COMPAT=y
+CONFIG_NFT_XFRM=m
+CONFIG_NFT_SOCKET=m
+CONFIG_NFT_OSF=m
+CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
+CONFIG_NFT_FIB_NETDEV=m
+CONFIG_NFT_REJECT_NETDEV=m
+CONFIG_NF_FLOW_TABLE_INET=m
+CONFIG_NF_FLOW_TABLE=m
+CONFIG_NF_FLOW_TABLE_PROCFS=y
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
@@ -197,8 +220,10 @@ CONFIG_NETFILTER_XT_TARGET_HMARK=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NETMAP=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
CONFIG_NETFILTER_XT_TARGET_TEE=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
@@ -207,6 +232,7 @@ CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
@@ -221,6 +247,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -238,6 +265,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
CONFIG_NETFILTER_XT_MATCH_REALM=m
CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
@@ -293,7 +321,6 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_FIB_IPV6=m
@@ -363,7 +390,6 @@ CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
CONFIG_NET_ACT_NAT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
@@ -452,6 +478,7 @@ CONFIG_DM_VERITY=m
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_DM_SWITCH=m
CONFIG_DM_INTEGRITY=m
+CONFIG_DM_VDO=m
CONFIG_NETDEVICES=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
@@ -564,17 +591,16 @@ CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_DIAG288_WATCHDOG=m
+CONFIG_DRM=m
+CONFIG_DRM_VIRTIO_GPU=m
CONFIG_FB=y
# CONFIG_FB_DEVICE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_MLX5_INFINIBAND=m
-CONFIG_SYNC_FILE=y
CONFIG_VFIO=m
CONFIG_VFIO_PCI=m
CONFIG_MLX5_VFIO_PCI=m
@@ -630,7 +656,6 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_EXFAT_FS=m
CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
@@ -649,6 +674,7 @@ CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_ROMFS_FS=m
CONFIG_NFS_FS=m
+CONFIG_NFS_V2=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
@@ -745,7 +771,6 @@ CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_STATS=y
CONFIG_CRYPTO_CRC32_S390=y
CONFIG_CRYPTO_SHA512_S390=m
CONFIG_CRYPTO_SHA1_S390=m
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig
index c51f3ec4eb28..8c2b61363bab 100644
--- a/arch/s390/configs/zfcpdump_defconfig
+++ b/arch/s390/configs/zfcpdump_defconfig
@@ -9,25 +9,22 @@ CONFIG_BPF_SYSCALL=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_KEXEC=y
-CONFIG_CRASH_DUMP=y
CONFIG_MARCH_Z13=y
CONFIG_NR_CPUS=2
CONFIG_HZ_100=y
# CONFIG_CHSC_SCH is not set
# CONFIG_SCM_BUS is not set
+# CONFIG_AP is not set
# CONFIG_PFAULT is not set
# CONFIG_S390_HYPFS is not set
# CONFIG_VIRTUALIZATION is not set
# CONFIG_S390_GUEST is not set
# CONFIG_SECCOMP is not set
-# CONFIG_GCC_PLUGINS is not set
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
CONFIG_PARTITION_ADVANCED=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_SWAP is not set
# CONFIG_COMPAT_BRK is not set
-# CONFIG_COMPACTION is not set
-# CONFIG_MIGRATION is not set
CONFIG_NET=y
# CONFIG_IUCV is not set
# CONFIG_PCPU_DEV_REFCNT is not set
diff --git a/arch/s390/crypto/crc32-vx.c b/arch/s390/crypto/crc32-vx.c
index 74f17c905d12..89a10337e6ea 100644
--- a/arch/s390/crypto/crc32-vx.c
+++ b/arch/s390/crypto/crc32-vx.c
@@ -297,6 +297,7 @@ module_cpu_feature_match(S390_CPU_FEATURE_VXRS, crc_vx_mod_init);
module_exit(crc_vx_mod_exit);
MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("CRC-32 algorithms using z/Architecture Vector Extension Facility");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CRYPTO("crc32");
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c
index 4024599eb448..0e855c5e91c5 100644
--- a/arch/s390/hypfs/hypfs_dbfs.c
+++ b/arch/s390/hypfs/hypfs_dbfs.c
@@ -39,7 +39,9 @@ static ssize_t dbfs_read(struct file *file, char __user *buf,
return 0;
df = file_inode(file)->i_private;
- mutex_lock(&df->lock);
+ if (mutex_lock_interruptible(&df->lock))
+ return -ERESTARTSYS;
+
data = hypfs_dbfs_data_alloc(df);
if (!data) {
mutex_unlock(&df->lock);
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 279b7bba4d43..26a009f9c49e 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -140,11 +140,22 @@ fail_alloc:
int diag204_store(void *buf, int pages)
{
+ unsigned long subcode;
int rc;
- rc = diag204((unsigned long)diag204_store_sc |
- (unsigned long)diag204_get_info_type(), pages, buf);
- return rc < 0 ? -EOPNOTSUPP : 0;
+ subcode = diag204_get_info_type();
+ subcode |= diag204_store_sc;
+ if (diag204_has_bif())
+ subcode |= DIAG204_BIF_BIT;
+ while (1) {
+ rc = diag204(subcode, pages, buf);
+ if (rc != -EBUSY)
+ break;
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ schedule_timeout_interruptible(DIAG204_BUSY_WAIT);
+ }
+ return rc < 0 ? rc : 0;
}
struct dbfs_d204_hdr {
diff --git a/arch/s390/include/asm/abs_lowcore.h b/arch/s390/include/asm/abs_lowcore.h
index 6f264b79e377..d20df8c923fc 100644
--- a/arch/s390/include/asm/abs_lowcore.h
+++ b/arch/s390/include/asm/abs_lowcore.h
@@ -2,6 +2,7 @@
#ifndef _ASM_S390_ABS_LOWCORE_H
#define _ASM_S390_ABS_LOWCORE_H
+#include <asm/sections.h>
#include <asm/lowcore.h>
#define ABS_LOWCORE_MAP_SIZE (NR_CPUS * sizeof(struct lowcore))
@@ -24,4 +25,11 @@ static inline void put_abs_lowcore(struct lowcore *lc)
put_cpu();
}
+extern int __bootdata_preserved(relocate_lowcore);
+
+static inline int have_relocated_lowcore(void)
+{
+ return relocate_lowcore;
+}
+
#endif /* _ASM_S390_ABS_LOWCORE_H */
diff --git a/arch/s390/include/asm/alternative-asm.h b/arch/s390/include/asm/alternative-asm.h
deleted file mode 100644
index 7db046596b93..000000000000
--- a/arch/s390/include/asm/alternative-asm.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_S390_ALTERNATIVE_ASM_H
-#define _ASM_S390_ALTERNATIVE_ASM_H
-
-#ifdef __ASSEMBLY__
-
-/*
- * Issue one struct alt_instr descriptor entry (need to put it into
- * the section .altinstructions, see below). This entry contains
- * enough information for the alternatives patching code to patch an
- * instruction. See apply_alternatives().
- */
-.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
- .long \orig_start - .
- .long \alt_start - .
- .word \feature
- .byte \orig_end - \orig_start
- .org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
- .org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
-.endm
-
-/*
- * Define an alternative between two instructions. If @feature is
- * present, early code in apply_alternatives() replaces @oldinstr with
- * @newinstr.
- */
-.macro ALTERNATIVE oldinstr, newinstr, feature
- .pushsection .altinstr_replacement,"ax"
-770: \newinstr
-771: .popsection
-772: \oldinstr
-773: .pushsection .altinstructions,"a"
- alt_entry 772b, 773b, 770b, 771b, \feature
- .popsection
-.endm
-
-/*
- * Define an alternative between two instructions. If @feature is
- * present, early code in apply_alternatives() replaces @oldinstr with
- * @newinstr.
- */
-.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
- .pushsection .altinstr_replacement,"ax"
-770: \newinstr1
-771: \newinstr2
-772: .popsection
-773: \oldinstr
-774: .pushsection .altinstructions,"a"
- alt_entry 773b, 774b, 770b, 771b,\feature1
- alt_entry 773b, 774b, 771b, 772b,\feature2
- .popsection
-.endm
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_S390_ALTERNATIVE_ASM_H */
diff --git a/arch/s390/include/asm/alternative.h b/arch/s390/include/asm/alternative.h
index 904dd049f954..de980c938a3e 100644
--- a/arch/s390/include/asm/alternative.h
+++ b/arch/s390/include/asm/alternative.h
@@ -2,6 +2,58 @@
#ifndef _ASM_S390_ALTERNATIVE_H
#define _ASM_S390_ALTERNATIVE_H
+/*
+ * Each alternative comes with a 32 bit feature field:
+ * union {
+ * u32 feature;
+ * struct {
+ * u32 ctx : 4;
+ * u32 type : 8;
+ * u32 data : 20;
+ * };
+ * }
+ *
+ * @ctx is a bitfield, where only one bit must be set. Each bit defines
+ * in which context an alternative is supposed to be applied to the
+ * kernel image:
+ *
+ * - from the decompressor before the kernel itself is executed
+ * - from early kernel code from within the kernel
+ *
+ * @type is a number which defines the type and with that the type
+ * specific alternative patching.
+ *
+ * @data is additional type specific information which defines if an
+ * alternative should be applied.
+ */
+
+#define ALT_CTX_EARLY 1
+#define ALT_CTX_LATE 2
+#define ALT_CTX_ALL (ALT_CTX_EARLY | ALT_CTX_LATE)
+
+#define ALT_TYPE_FACILITY 0
+#define ALT_TYPE_SPEC 1
+#define ALT_TYPE_LOWCORE 2
+
+#define ALT_DATA_SHIFT 0
+#define ALT_TYPE_SHIFT 20
+#define ALT_CTX_SHIFT 28
+
+#define ALT_FACILITY_EARLY(facility) (ALT_CTX_EARLY << ALT_CTX_SHIFT | \
+ ALT_TYPE_FACILITY << ALT_TYPE_SHIFT | \
+ (facility) << ALT_DATA_SHIFT)
+
+#define ALT_FACILITY(facility) (ALT_CTX_LATE << ALT_CTX_SHIFT | \
+ ALT_TYPE_FACILITY << ALT_TYPE_SHIFT | \
+ (facility) << ALT_DATA_SHIFT)
+
+#define ALT_SPEC(facility) (ALT_CTX_LATE << ALT_CTX_SHIFT | \
+ ALT_TYPE_SPEC << ALT_TYPE_SHIFT | \
+ (facility) << ALT_DATA_SHIFT)
+
+#define ALT_LOWCORE (ALT_CTX_EARLY << ALT_CTX_SHIFT | \
+ ALT_TYPE_LOWCORE << ALT_TYPE_SHIFT)
+
#ifndef __ASSEMBLY__
#include <linux/types.h>
@@ -11,12 +63,30 @@
struct alt_instr {
s32 instr_offset; /* original instruction */
s32 repl_offset; /* offset to replacement instruction */
- u16 facility; /* facility bit set for replacement */
+ union {
+ u32 feature; /* feature required for replacement */
+ struct {
+ u32 ctx : 4; /* context */
+ u32 type : 8; /* type of alternative */
+ u32 data : 20; /* patching information */
+ };
+ };
u8 instrlen; /* length of original instruction */
} __packed;
-void apply_alternative_instructions(void);
-void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
+extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
+
+void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsigned int ctx);
+
+static inline void apply_alternative_instructions(void)
+{
+ __apply_alternatives(__alt_instructions, __alt_instructions_end, ALT_CTX_LATE);
+}
+
+static inline void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
+{
+ __apply_alternatives(start, end, ALT_CTX_ALL);
+}
/*
* +---------------------------------+
@@ -48,11 +118,12 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
#define OLDINSTR(oldinstr) \
"661:\n\t" oldinstr "\n662:\n"
-#define ALTINSTR_ENTRY(facility, num) \
+#define ALTINSTR_ENTRY(feature, num) \
"\t.long 661b - .\n" /* old instruction */ \
"\t.long " b_altinstr(num)"b - .\n" /* alt instruction */ \
- "\t.word " __stringify(facility) "\n" /* facility bit */ \
+ "\t.long " __stringify(feature) "\n" /* feature */ \
"\t.byte " oldinstr_len "\n" /* instruction len */ \
+ "\t.org . - (" oldinstr_len ") & 1\n" \
"\t.org . - (" oldinstr_len ") + (" altinstr_len(num) ")\n" \
"\t.org . - (" altinstr_len(num) ") + (" oldinstr_len ")\n"
@@ -60,24 +131,24 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"
/* alternative assembly primitive: */
-#define ALTERNATIVE(oldinstr, altinstr, facility) \
+#define ALTERNATIVE(oldinstr, altinstr, feature) \
".pushsection .altinstr_replacement, \"ax\"\n" \
ALTINSTR_REPLACEMENT(altinstr, 1) \
".popsection\n" \
OLDINSTR(oldinstr) \
".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(facility, 1) \
+ ALTINSTR_ENTRY(feature, 1) \
".popsection\n"
-#define ALTERNATIVE_2(oldinstr, altinstr1, facility1, altinstr2, facility2)\
+#define ALTERNATIVE_2(oldinstr, altinstr1, feature1, altinstr2, feature2)\
".pushsection .altinstr_replacement, \"ax\"\n" \
ALTINSTR_REPLACEMENT(altinstr1, 1) \
ALTINSTR_REPLACEMENT(altinstr2, 2) \
".popsection\n" \
OLDINSTR(oldinstr) \
".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(facility1, 1) \
- ALTINSTR_ENTRY(facility2, 2) \
+ ALTINSTR_ENTRY(feature1, 1) \
+ ALTINSTR_ENTRY(feature2, 2) \
".popsection\n"
/*
@@ -92,12 +163,12 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
* For non barrier like inlines please define new variants
* without volatile and memory clobber.
*/
-#define alternative(oldinstr, altinstr, facility) \
- asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, facility) : : : "memory")
+#define alternative(oldinstr, altinstr, feature) \
+ asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, feature) : : : "memory")
-#define alternative_2(oldinstr, altinstr1, facility1, altinstr2, facility2) \
- asm_inline volatile(ALTERNATIVE_2(oldinstr, altinstr1, facility1, \
- altinstr2, facility2) ::: "memory")
+#define alternative_2(oldinstr, altinstr1, feature1, altinstr2, feature2) \
+ asm_inline volatile(ALTERNATIVE_2(oldinstr, altinstr1, feature1, \
+ altinstr2, feature2) ::: "memory")
/* Alternative inline assembly with input. */
#define alternative_input(oldinstr, newinstr, feature, input...) \
@@ -105,8 +176,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
: : input)
/* Like alternative_input, but with a single output argument */
-#define alternative_io(oldinstr, altinstr, facility, output, input...) \
- asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, facility) \
+#define alternative_io(oldinstr, altinstr, feature, output, input...) \
+ asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, feature) \
: output : input)
/* Use this macro if more than one output parameter is needed. */
@@ -115,6 +186,56 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
/* Use this macro if clobbers are needed without inputs. */
#define ASM_NO_INPUT_CLOBBER(clobber...) : clobber
+#else /* __ASSEMBLY__ */
+
+/*
+ * Issue one struct alt_instr descriptor entry (need to put it into
+ * the section .altinstructions, see below). This entry contains
+ * enough information for the alternatives patching code to patch an
+ * instruction. See apply_alternatives().
+ */
+.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
+ .long \orig_start - .
+ .long \alt_start - .
+ .long \feature
+ .byte \orig_end - \orig_start
+ .org . - ( \orig_end - \orig_start ) & 1
+ .org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
+ .org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
+.endm
+
+/*
+ * Define an alternative between two instructions. If @feature is
+ * present, early code in apply_alternatives() replaces @oldinstr with
+ * @newinstr.
+ */
+.macro ALTERNATIVE oldinstr, newinstr, feature
+ .pushsection .altinstr_replacement,"ax"
+770: \newinstr
+771: .popsection
+772: \oldinstr
+773: .pushsection .altinstructions,"a"
+ alt_entry 772b, 773b, 770b, 771b, \feature
+ .popsection
+.endm
+
+/*
+ * Define an alternative between two instructions. If @feature is
+ * present, early code in apply_alternatives() replaces @oldinstr with
+ * @newinstr.
+ */
+.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
+ .pushsection .altinstr_replacement,"ax"
+770: \newinstr1
+771: \newinstr2
+772: .popsection
+773: \oldinstr
+774: .pushsection .altinstructions,"a"
+ alt_entry 773b, 774b, 770b, 771b,\feature1
+ alt_entry 773b, 774b, 771b, 772b,\feature2
+ .popsection
+.endm
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_ALTERNATIVE_H */
diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h
index 43ac4a64f49b..395b02d6a133 100644
--- a/arch/s390/include/asm/ap.h
+++ b/arch/s390/include/asm/ap.h
@@ -223,13 +223,18 @@ static inline struct ap_queue_status ap_zapq(ap_qid_t qid, int fbit)
* config info as returned by the ap_qci() function.
*/
struct ap_config_info {
- unsigned int apsc : 1; /* S bit */
- unsigned int apxa : 1; /* N bit */
- unsigned int qact : 1; /* C bit */
- unsigned int rc8a : 1; /* R bit */
- unsigned int : 4;
- unsigned int apsb : 1; /* B bit */
- unsigned int : 23;
+ union {
+ unsigned int flags;
+ struct {
+ unsigned int apsc : 1; /* S bit */
+ unsigned int apxa : 1; /* N bit */
+ unsigned int qact : 1; /* C bit */
+ unsigned int rc8a : 1; /* R bit */
+ unsigned int : 4;
+ unsigned int apsb : 1; /* B bit */
+ unsigned int : 23;
+ };
+ };
unsigned char na; /* max # of APs - 1 */
unsigned char nd; /* max # of Domains - 1 */
unsigned char _reserved0[10];
@@ -544,15 +549,4 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
return reg1.status;
}
-/*
- * Interface to tell the AP bus code that a configuration
- * change has happened. The bus code should at least do
- * an ap bus resource rescan.
- */
-#if IS_ENABLED(CONFIG_ZCRYPT)
-void ap_bus_cfg_chg(void);
-#else
-static inline void ap_bus_cfg_chg(void){}
-#endif
-
#endif /* _ASM_S390_AP_H_ */
diff --git a/arch/s390/include/asm/arch_hweight.h b/arch/s390/include/asm/arch_hweight.h
new file mode 100644
index 000000000000..50e23ce854e5
--- /dev/null
+++ b/arch/s390/include/asm/arch_hweight.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_S390_ARCH_HWEIGHT_H
+#define _ASM_S390_ARCH_HWEIGHT_H
+
+#include <linux/types.h>
+
+static __always_inline unsigned long popcnt_z196(unsigned long w)
+{
+ unsigned long cnt;
+
+ asm volatile(".insn rrf,0xb9e10000,%[cnt],%[w],0,0"
+ : [cnt] "=d" (cnt)
+ : [w] "d" (w)
+ : "cc");
+ return cnt;
+}
+
+static __always_inline unsigned long popcnt_z15(unsigned long w)
+{
+ unsigned long cnt;
+
+ asm volatile(".insn rrf,0xb9e10000,%[cnt],%[w],8,0"
+ : [cnt] "=d" (cnt)
+ : [w] "d" (w)
+ : "cc");
+ return cnt;
+}
+
+static __always_inline unsigned long __arch_hweight64(__u64 w)
+{
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z15_FEATURES))
+ return popcnt_z15(w);
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) {
+ w = popcnt_z196(w);
+ w += w >> 32;
+ w += w >> 16;
+ w += w >> 8;
+ return w & 0xff;
+ }
+ return __sw_hweight64(w);
+}
+
+static __always_inline unsigned int __arch_hweight32(unsigned int w)
+{
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z15_FEATURES))
+ return popcnt_z15(w);
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) {
+ w = popcnt_z196(w);
+ w += w >> 16;
+ w += w >> 8;
+ return w & 0xff;
+ }
+ return __sw_hweight32(w);
+}
+
+static __always_inline unsigned int __arch_hweight16(unsigned int w)
+{
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z15_FEATURES))
+ return popcnt_z15((unsigned short)w);
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) {
+ w = popcnt_z196(w);
+ w += w >> 8;
+ return w & 0xff;
+ }
+ return __sw_hweight16(w);
+}
+
+static __always_inline unsigned int __arch_hweight8(unsigned int w)
+{
+ if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES))
+ return popcnt_z196((unsigned char)w);
+ return __sw_hweight8(w);
+}
+
+#endif /* _ASM_S390_ARCH_HWEIGHT_H */
diff --git a/arch/s390/include/asm/asm-prototypes.h b/arch/s390/include/asm/asm-prototypes.h
index 56096ae26f29..f662eb4b9246 100644
--- a/arch/s390/include/asm/asm-prototypes.h
+++ b/arch/s390/include/asm/asm-prototypes.h
@@ -4,6 +4,7 @@
#include <linux/kvm_host.h>
#include <linux/ftrace.h>
#include <asm/fpu.h>
+#include <asm/nospec-branch.h>
#include <asm-generic/asm-prototypes.h>
__int128_t __ashlti3(__int128_t a, int b);
diff --git a/arch/s390/include/asm/atomic_ops.h b/arch/s390/include/asm/atomic_ops.h
index 7fa5f96a553a..742c7919cbcd 100644
--- a/arch/s390/include/asm/atomic_ops.h
+++ b/arch/s390/include/asm/atomic_ops.h
@@ -8,21 +8,29 @@
#ifndef __ARCH_S390_ATOMIC_OPS__
#define __ARCH_S390_ATOMIC_OPS__
+#include <linux/limits.h>
+
static __always_inline int __atomic_read(const atomic_t *v)
{
int c;
asm volatile(
- " l %0,%1\n"
- : "=d" (c) : "R" (v->counter));
+ " l %[c],%[counter]\n"
+ : [c] "=d" (c) : [counter] "R" (v->counter));
return c;
}
static __always_inline void __atomic_set(atomic_t *v, int i)
{
- asm volatile(
- " st %1,%0\n"
- : "=R" (v->counter) : "d" (i));
+ if (__builtin_constant_p(i) && i >= S16_MIN && i <= S16_MAX) {
+ asm volatile(
+ " mvhi %[counter], %[i]\n"
+ : [counter] "=Q" (v->counter) : [i] "K" (i));
+ } else {
+ asm volatile(
+ " st %[i],%[counter]\n"
+ : [counter] "=R" (v->counter) : [i] "d" (i));
+ }
}
static __always_inline s64 __atomic64_read(const atomic64_t *v)
@@ -30,16 +38,22 @@ static __always_inline s64 __atomic64_read(const atomic64_t *v)
s64 c;
asm volatile(
- " lg %0,%1\n"
- : "=d" (c) : "RT" (v->counter));
+ " lg %[c],%[counter]\n"
+ : [c] "=d" (c) : [counter] "RT" (v->counter));
return c;
}
static __always_inline void __atomic64_set(atomic64_t *v, s64 i)
{
- asm volatile(
- " stg %1,%0\n"
- : "=RT" (v->counter) : "d" (i));
+ if (__builtin_constant_p(i) && i >= S16_MIN && i <= S16_MAX) {
+ asm volatile(
+ " mvghi %[counter], %[i]\n"
+ : [counter] "=Q" (v->counter) : [i] "K" (i));
+ } else {
+ asm volatile(
+ " stg %[i],%[counter]\n"
+ : [counter] "=RT" (v->counter) : [i] "d" (i));
+ }
}
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
@@ -164,26 +178,55 @@ static __always_inline int __atomic_cmpxchg(int *ptr, int old, int new)
return old;
}
+static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new)
+{
+ asm volatile(
+ " csg %[old],%[new],%[ptr]"
+ : [old] "+d" (old), [ptr] "+QS" (*ptr)
+ : [new] "d" (new)
+ : "cc", "memory");
+ return old;
+}
+
+/* GCC versions before 14.2.0 may die with an ICE in some configurations. */
+#if defined(__GCC_ASM_FLAG_OUTPUTS__) && !(IS_ENABLED(CONFIG_CC_IS_GCC) && (GCC_VERSION < 140200))
+
static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
{
- int old_expected = old;
+ int cc;
asm volatile(
" cs %[old],%[new],%[ptr]"
- : [old] "+d" (old), [ptr] "+Q" (*ptr)
+ : [old] "+d" (old), [ptr] "+Q" (*ptr), "=@cc" (cc)
: [new] "d" (new)
- : "cc", "memory");
- return old == old_expected;
+ : "memory");
+ return cc == 0;
}
-static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new)
+static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
{
+ int cc;
+
asm volatile(
" csg %[old],%[new],%[ptr]"
- : [old] "+d" (old), [ptr] "+QS" (*ptr)
+ : [old] "+d" (old), [ptr] "+QS" (*ptr), "=@cc" (cc)
+ : [new] "d" (new)
+ : "memory");
+ return cc == 0;
+}
+
+#else /* __GCC_ASM_FLAG_OUTPUTS__ */
+
+static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
+{
+ int old_expected = old;
+
+ asm volatile(
+ " cs %[old],%[new],%[ptr]"
+ : [old] "+d" (old), [ptr] "+Q" (*ptr)
: [new] "d" (new)
: "cc", "memory");
- return old;
+ return old == old_expected;
}
static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
@@ -198,4 +241,6 @@ static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long ne
return old == old_expected;
}
+#endif /* __GCC_ASM_FLAG_OUTPUTS__ */
+
#endif /* __ARCH_S390_ATOMIC_OPS__ */
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
index c467dffa8c12..54a079cd39ed 100644
--- a/arch/s390/include/asm/bitops.h
+++ b/arch/s390/include/asm/bitops.h
@@ -379,8 +379,9 @@ static inline int fls(unsigned int word)
return fls64(word);
}
+#include <asm/arch_hweight.h>
+#include <asm-generic/bitops/const_hweight.h>
#include <asm-generic/bitops/ffz.h>
-#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic-setbit.h>
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index 436365ff6c19..e3afcece375e 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -210,7 +210,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
#define get_ccwdev_lock(x) (x)->ccwlock
#define to_ccwdev(n) container_of(n, struct ccw_device, dev)
-#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
+#define to_ccwdrv(n) container_of_const(n, struct ccw_driver, driver)
extern struct ccw_device *ccw_device_create_console(struct ccw_driver *);
extern void ccw_device_destroy_console(struct ccw_device *);
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index b89159591ca0..46f5c9660616 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -13,6 +13,7 @@
#define _S390_CHECKSUM_H
#include <linux/instrumented.h>
+#include <linux/kmsan-checks.h>
#include <linux/in6.h>
static inline __wsum cksm(const void *buff, int len, __wsum sum)
@@ -23,6 +24,7 @@ static inline __wsum cksm(const void *buff, int len, __wsum sum)
};
instrument_read(buff, len);
+ kmsan_check_memory(buff, len);
asm volatile("\n"
"0: cksm %[sum],%[rp]\n"
" jo 0b\n"
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h
index bb48ea380c0d..bb78159d8042 100644
--- a/arch/s390/include/asm/chsc.h
+++ b/arch/s390/include/asm/chsc.h
@@ -11,6 +11,9 @@
#include <uapi/asm/chsc.h>
+/* struct from linux/notifier.h */
+struct notifier_block;
+
/**
* Operation codes for CHSC PNSO:
* PNSO_OC_NET_BRIDGE_INFO - only addresses that are visible to a bridgeport
@@ -66,4 +69,16 @@ struct chsc_pnso_area {
struct chsc_pnso_naid_l2 entries[];
} __packed __aligned(PAGE_SIZE);
+/*
+ * notifier interface - registered notifiers gets called on
+ * the following events:
+ * - ap config changed (CHSC_NOTIFY_AP_CFG)
+ */
+enum chsc_notify_type {
+ CHSC_NOTIFY_AP_CFG = 3,
+};
+
+int chsc_notifier_register(struct notifier_block *nb);
+int chsc_notifier_unregister(struct notifier_block *nb);
+
#endif /* _ASM_S390_CHSC_H */
diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h
index b378e2b57ad8..dae8843b164f 100644
--- a/arch/s390/include/asm/cpacf.h
+++ b/arch/s390/include/asm/cpacf.h
@@ -12,6 +12,7 @@
#define _ASM_S390_CPACF_H
#include <asm/facility.h>
+#include <linux/kmsan-checks.h>
/*
* Instruction opcodes for the CPACF instructions
@@ -166,28 +167,86 @@
typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
-/**
- * cpacf_query() - check if a specific CPACF function is available
- * @opcode: the opcode of the crypto instruction
- * @func: the function code to test for
- *
- * Executes the query function for the given crypto instruction @opcode
- * and checks if @func is available
- *
- * Returns 1 if @func is available for @opcode, 0 otherwise
+/*
+ * Prototype for a not existing function to produce a link
+ * error if __cpacf_query() or __cpacf_check_opcode() is used
+ * with an invalid compile time const opcode.
*/
-static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
+void __cpacf_bad_opcode(void);
+
+static __always_inline void __cpacf_query_rre(u32 opc, u8 r1, u8 r2,
+ cpacf_mask_t *mask)
{
asm volatile(
- " lghi 0,0\n" /* query function */
- " lgr 1,%[mask]\n"
- " spm 0\n" /* pckmo doesn't change the cc */
- /* Parameter regs are ignored, but must be nonzero and unique */
- "0: .insn rrf,%[opc] << 16,2,4,6,0\n"
- " brc 1,0b\n" /* handle partial completion */
- : "=m" (*mask)
- : [mask] "d" ((unsigned long)mask), [opc] "i" (opcode)
- : "cc", "0", "1");
+ " la %%r1,%[mask]\n"
+ " xgr %%r0,%%r0\n"
+ " .insn rre,%[opc] << 16,%[r1],%[r2]\n"
+ : [mask] "=R" (*mask)
+ : [opc] "i" (opc),
+ [r1] "i" (r1), [r2] "i" (r2)
+ : "cc", "r0", "r1");
+}
+
+static __always_inline void __cpacf_query_rrf(u32 opc,
+ u8 r1, u8 r2, u8 r3, u8 m4,
+ cpacf_mask_t *mask)
+{
+ asm volatile(
+ " la %%r1,%[mask]\n"
+ " xgr %%r0,%%r0\n"
+ " .insn rrf,%[opc] << 16,%[r1],%[r2],%[r3],%[m4]\n"
+ : [mask] "=R" (*mask)
+ : [opc] "i" (opc), [r1] "i" (r1), [r2] "i" (r2),
+ [r3] "i" (r3), [m4] "i" (m4)
+ : "cc", "r0", "r1");
+}
+
+static __always_inline void __cpacf_query(unsigned int opcode,
+ cpacf_mask_t *mask)
+{
+ switch (opcode) {
+ case CPACF_KDSA:
+ __cpacf_query_rre(CPACF_KDSA, 0, 2, mask);
+ break;
+ case CPACF_KIMD:
+ __cpacf_query_rre(CPACF_KIMD, 0, 2, mask);
+ break;
+ case CPACF_KLMD:
+ __cpacf_query_rre(CPACF_KLMD, 0, 2, mask);
+ break;
+ case CPACF_KM:
+ __cpacf_query_rre(CPACF_KM, 2, 4, mask);
+ break;
+ case CPACF_KMA:
+ __cpacf_query_rrf(CPACF_KMA, 2, 4, 6, 0, mask);
+ break;
+ case CPACF_KMAC:
+ __cpacf_query_rre(CPACF_KMAC, 0, 2, mask);
+ break;
+ case CPACF_KMC:
+ __cpacf_query_rre(CPACF_KMC, 2, 4, mask);
+ break;
+ case CPACF_KMCTR:
+ __cpacf_query_rrf(CPACF_KMCTR, 2, 4, 6, 0, mask);
+ break;
+ case CPACF_KMF:
+ __cpacf_query_rre(CPACF_KMF, 2, 4, mask);
+ break;
+ case CPACF_KMO:
+ __cpacf_query_rre(CPACF_KMO, 2, 4, mask);
+ break;
+ case CPACF_PCC:
+ __cpacf_query_rre(CPACF_PCC, 0, 0, mask);
+ break;
+ case CPACF_PCKMO:
+ __cpacf_query_rre(CPACF_PCKMO, 0, 0, mask);
+ break;
+ case CPACF_PRNO:
+ __cpacf_query_rre(CPACF_PRNO, 2, 4, mask);
+ break;
+ default:
+ __cpacf_bad_opcode();
+ }
}
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
@@ -211,10 +270,21 @@ static __always_inline int __cpacf_check_opcode(unsigned int opcode)
case CPACF_KMA:
return test_facility(146); /* check for MSA8 */
default:
- BUG();
+ __cpacf_bad_opcode();
+ return 0;
}
}
+/**
+ * cpacf_query() - check if a specific CPACF function is available
+ * @opcode: the opcode of the crypto instruction
+ * @func: the function code to test for
+ *
+ * Executes the query function for the given crypto instruction @opcode
+ * and checks if @func is available
+ *
+ * Returns 1 if @func is available for @opcode, 0 otherwise
+ */
static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
{
if (__cpacf_check_opcode(opcode)) {
@@ -473,6 +543,8 @@ static inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
: [ucbuf] "+&d" (u.pair), [cbuf] "+&d" (c.pair)
: [fc] "K" (CPACF_PRNO_TRNG), [opc] "i" (CPACF_PRNO)
: "cc", "memory", "0");
+ kmsan_unpoison_memory(ucbuf, ucbuf_len);
+ kmsan_unpoison_memory(cbuf, cbuf_len);
}
/**
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index a0de5b9b02ea..9e4bbc3e53f8 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -10,6 +10,7 @@
#define _ASM_S390_CPU_MF_H
#include <linux/errno.h>
+#include <linux/kmsan-checks.h>
#include <asm/asm-extable.h>
#include <asm/facility.h>
@@ -239,6 +240,11 @@ static __always_inline int stcctm(enum stcctm_ctr_set set, u64 range, u64 *dest)
: "=d" (cc)
: "Q" (*dest), "d" (range), "i" (set)
: "cc", "memory");
+ /*
+ * If cc == 2, less than RANGE counters are stored, but it's not easy
+ * to tell how many. Always unpoison the whole range for simplicity.
+ */
+ kmsan_unpoison_memory(dest, range * sizeof(u64));
return cc;
}
diff --git a/arch/s390/include/asm/current.h b/arch/s390/include/asm/current.h
index 68f84315277c..d03a922c641e 100644
--- a/arch/s390/include/asm/current.h
+++ b/arch/s390/include/asm/current.h
@@ -14,6 +14,6 @@
struct task_struct;
-#define current ((struct task_struct *const)S390_lowcore.current_task)
+#define current ((struct task_struct *const)get_lowcore()->current_task)
#endif /* !(_S390_CURRENT_H) */
diff --git a/arch/s390/include/asm/dat-bits.h b/arch/s390/include/asm/dat-bits.h
new file mode 100644
index 000000000000..8d65eec2f124
--- /dev/null
+++ b/arch/s390/include/asm/dat-bits.h
@@ -0,0 +1,170 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * DAT table and related structures
+ *
+ * Copyright IBM Corp. 2024
+ *
+ */
+
+#ifndef _S390_DAT_BITS_H
+#define _S390_DAT_BITS_H
+
+union asce {
+ unsigned long val;
+ struct {
+ unsigned long rsto: 52;/* Region- or Segment-Table Origin */
+ unsigned long : 2;
+ unsigned long g : 1; /* Subspace Group control */
+ unsigned long p : 1; /* Private Space control */
+ unsigned long s : 1; /* Storage-Alteration-Event control */
+ unsigned long x : 1; /* Space-Switch-Event control */
+ unsigned long r : 1; /* Real-Space control */
+ unsigned long : 1;
+ unsigned long dt : 2; /* Designation-Type control */
+ unsigned long tl : 2; /* Region- or Segment-Table Length */
+ };
+};
+
+enum {
+ ASCE_TYPE_SEGMENT = 0,
+ ASCE_TYPE_REGION3 = 1,
+ ASCE_TYPE_REGION2 = 2,
+ ASCE_TYPE_REGION1 = 3
+};
+
+union region1_table_entry {
+ unsigned long val;
+ struct {
+ unsigned long rto: 52;/* Region-Table Origin */
+ unsigned long : 2;
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long : 1;
+ unsigned long tf : 2; /* Region-Second-Table Offset */
+ unsigned long i : 1; /* Region-Invalid Bit */
+ unsigned long : 1;
+ unsigned long tt : 2; /* Table-Type Bits */
+ unsigned long tl : 2; /* Region-Second-Table Length */
+ };
+};
+
+union region2_table_entry {
+ unsigned long val;
+ struct {
+ unsigned long rto: 52;/* Region-Table Origin */
+ unsigned long : 2;
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long : 1;
+ unsigned long tf : 2; /* Region-Third-Table Offset */
+ unsigned long i : 1; /* Region-Invalid Bit */
+ unsigned long : 1;
+ unsigned long tt : 2; /* Table-Type Bits */
+ unsigned long tl : 2; /* Region-Third-Table Length */
+ };
+};
+
+struct region3_table_entry_fc0 {
+ unsigned long sto: 52;/* Segment-Table Origin */
+ unsigned long : 1;
+ unsigned long fc : 1; /* Format-Control */
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long : 1;
+ unsigned long tf : 2; /* Segment-Table Offset */
+ unsigned long i : 1; /* Region-Invalid Bit */
+ unsigned long cr : 1; /* Common-Region Bit */
+ unsigned long tt : 2; /* Table-Type Bits */
+ unsigned long tl : 2; /* Segment-Table Length */
+};
+
+struct region3_table_entry_fc1 {
+ unsigned long rfaa: 33;/* Region-Frame Absolute Address */
+ unsigned long : 14;
+ unsigned long av : 1; /* ACCF-Validity Control */
+ unsigned long acc : 4; /* Access-Control Bits */
+ unsigned long f : 1; /* Fetch-Protection Bit */
+ unsigned long fc : 1; /* Format-Control */
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long iep : 1; /* Instruction-Execution-Protection */
+ unsigned long : 2;
+ unsigned long i : 1; /* Region-Invalid Bit */
+ unsigned long cr : 1; /* Common-Region Bit */
+ unsigned long tt : 2; /* Table-Type Bits */
+ unsigned long : 2;
+};
+
+union region3_table_entry {
+ unsigned long val;
+ struct region3_table_entry_fc0 fc0;
+ struct region3_table_entry_fc1 fc1;
+ struct {
+ unsigned long : 53;
+ unsigned long fc: 1; /* Format-Control */
+ unsigned long : 4;
+ unsigned long i : 1; /* Region-Invalid Bit */
+ unsigned long cr: 1; /* Common-Region Bit */
+ unsigned long tt: 2; /* Table-Type Bits */
+ unsigned long : 2;
+ };
+};
+
+struct segment_table_entry_fc0 {
+ unsigned long pto: 53;/* Page-Table Origin */
+ unsigned long fc : 1; /* Format-Control */
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long : 3;
+ unsigned long i : 1; /* Segment-Invalid Bit */
+ unsigned long cs : 1; /* Common-Segment Bit */
+ unsigned long tt : 2; /* Table-Type Bits */
+ unsigned long : 2;
+};
+
+struct segment_table_entry_fc1 {
+ unsigned long sfaa: 44;/* Segment-Frame Absolute Address */
+ unsigned long : 3;
+ unsigned long av : 1; /* ACCF-Validity Control */
+ unsigned long acc : 4; /* Access-Control Bits */
+ unsigned long f : 1; /* Fetch-Protection Bit */
+ unsigned long fc : 1; /* Format-Control */
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long iep : 1; /* Instruction-Execution-Protection */
+ unsigned long : 2;
+ unsigned long i : 1; /* Segment-Invalid Bit */
+ unsigned long cs : 1; /* Common-Segment Bit */
+ unsigned long tt : 2; /* Table-Type Bits */
+ unsigned long : 2;
+};
+
+union segment_table_entry {
+ unsigned long val;
+ struct segment_table_entry_fc0 fc0;
+ struct segment_table_entry_fc1 fc1;
+ struct {
+ unsigned long : 53;
+ unsigned long fc: 1; /* Format-Control */
+ unsigned long : 4;
+ unsigned long i : 1; /* Segment-Invalid Bit */
+ unsigned long cs: 1; /* Common-Segment Bit */
+ unsigned long tt: 2; /* Table-Type Bits */
+ unsigned long : 2;
+ };
+};
+
+union page_table_entry {
+ unsigned long val;
+ struct {
+ unsigned long pfra: 52;/* Page-Frame Real Address */
+ unsigned long z : 1; /* Zero Bit */
+ unsigned long i : 1; /* Page-Invalid Bit */
+ unsigned long p : 1; /* DAT-Protection Bit */
+ unsigned long iep : 1; /* Instruction-Execution-Protection */
+ unsigned long : 8;
+ };
+};
+
+enum {
+ TABLE_TYPE_SEGMENT = 0,
+ TABLE_TYPE_REGION3 = 1,
+ TABLE_TYPE_REGION2 = 2,
+ TABLE_TYPE_REGION1 = 3
+};
+
+#endif /* _S390_DAT_BITS_H */
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h
index 20b94220113b..c0d43512f4fc 100644
--- a/arch/s390/include/asm/diag.h
+++ b/arch/s390/include/asm/diag.h
@@ -12,6 +12,7 @@
#include <linux/if_ether.h>
#include <linux/percpu.h>
#include <asm/asm-extable.h>
+#include <asm/sclp.h>
#include <asm/cio.h>
enum diag_stat_enum {
@@ -117,6 +118,8 @@ enum diag204_sc {
};
#define DIAG204_SUBCODE_MASK 0xffff
+#define DIAG204_BIF_BIT 0x80000000
+#define DIAG204_BUSY_WAIT (HZ / 10)
/* The two available diag 204 data formats */
enum diag204_format {
@@ -326,6 +329,11 @@ union diag318_info {
};
};
+static inline bool diag204_has_bif(void)
+{
+ return sclp.has_diag204_bif;
+}
+
int diag204(unsigned long subcode, unsigned long size, void *addr);
int diag224(void *ptr);
int diag26c(void *req, void *resp, enum diag26c_sc subcode);
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 70a30ae258b7..8f2c23cc52b6 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -91,6 +91,14 @@
/* Keep this the last entry. */
#define R_390_NUM 61
+/*
+ * HWCAP flags - for AT_HWCAP
+ *
+ * Bits 32-63 are reserved for use by libc.
+ * Bit 31 is reserved and will be used by libc to determine if a second
+ * argument is passed to IFUNC resolvers. This will be implemented when
+ * there is a need for AT_HWCAP2.
+ */
enum {
HWCAP_NR_ESAN3 = 0,
HWCAP_NR_ZARCH = 1,
diff --git a/arch/s390/include/asm/entry-common.h b/arch/s390/include/asm/entry-common.h
index 7f5004065e8a..35555c944630 100644
--- a/arch/s390/include/asm/entry-common.h
+++ b/arch/s390/include/asm/entry-common.h
@@ -54,7 +54,7 @@ static __always_inline void arch_exit_to_user_mode(void)
static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
unsigned long ti_work)
{
- choose_random_kstack_offset(get_tod_clock_fast() & 0xff);
+ choose_random_kstack_offset(get_tod_clock_fast());
}
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
diff --git a/arch/s390/include/asm/extmem.h b/arch/s390/include/asm/extmem.h
index 568fd81bb77b..e0a06060afdd 100644
--- a/arch/s390/include/asm/extmem.h
+++ b/arch/s390/include/asm/extmem.h
@@ -8,6 +8,13 @@
#define _ASM_S390X_DCSS_H
#ifndef __ASSEMBLY__
+/*
+ * DCSS segment is defined as a contiguous range of pages using DEFSEG command.
+ * The range start and end is a page number with a value less than or equal to
+ * 0x7ffffff (see CP Commands and Utilities Reference).
+ */
+#define MAX_DCSS_ADDR (512UL * SZ_1G)
+
/* possible values for segment type as returned by segment_info */
#define SEG_TYPE_SW 0
#define SEG_TYPE_EW 1
diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h
index 796007125dff..b7d234838a36 100644
--- a/arch/s390/include/asm/facility.h
+++ b/arch/s390/include/asm/facility.h
@@ -20,7 +20,6 @@
#define MAX_FACILITY_BIT (sizeof(stfle_fac_list) * 8)
extern u64 stfle_fac_list[16];
-extern u64 alt_stfle_fac_list[16];
static inline void __set_facility(unsigned long nr, void *facilities)
{
@@ -92,8 +91,8 @@ static inline void __stfle(u64 *stfle_fac_list, int size)
asm volatile(
" stfl 0(0)\n"
- : "=m" (S390_lowcore.stfl_fac_list));
- stfl_fac_list = S390_lowcore.stfl_fac_list;
+ : "=m" (get_lowcore()->stfl_fac_list));
+ stfl_fac_list = get_lowcore()->stfl_fac_list;
memcpy(stfle_fac_list, &stfl_fac_list, 4);
nr = 4; /* bytes stored by stfl */
if (stfl_fac_list & 0x01000000) {
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
index 621f23d5ae30..fbadca645af7 100644
--- a/arch/s390/include/asm/ftrace.h
+++ b/arch/s390/include/asm/ftrace.h
@@ -2,18 +2,13 @@
#ifndef _ASM_S390_FTRACE_H
#define _ASM_S390_FTRACE_H
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
#define ARCH_SUPPORTS_FTRACE_OPS 1
#define MCOUNT_INSN_SIZE 6
#ifndef __ASSEMBLY__
-#ifdef CONFIG_CC_IS_CLANG
-/* https://llvm.org/pr41424 */
-#define ftrace_return_address(n) 0UL
-#else
-#define ftrace_return_address(n) __builtin_return_address(n)
-#endif
+unsigned long return_address(unsigned int n);
+#define ftrace_return_address(n) return_address(n)
void ftrace_caller(void);
diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h
index 5cc46e0dde62..9725586f4259 100644
--- a/arch/s390/include/asm/gmap.h
+++ b/arch/s390/include/asm/gmap.h
@@ -146,7 +146,7 @@ int gmap_mprotect_notify(struct gmap *, unsigned long start,
void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
unsigned long gaddr, unsigned long vmaddr);
-int gmap_mark_unmergeable(void);
+int s390_disable_cow_sharing(void);
void s390_unlist_old_asce(struct gmap *gmap);
int s390_replace_asce(struct gmap *gmap);
void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns);
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h
index 58668ffb5488..a5b45388c91f 100644
--- a/arch/s390/include/asm/hardirq.h
+++ b/arch/s390/include/asm/hardirq.h
@@ -13,9 +13,9 @@
#include <asm/lowcore.h>
-#define local_softirq_pending() (S390_lowcore.softirq_pending)
-#define set_softirq_pending(x) (S390_lowcore.softirq_pending = (x))
-#define or_softirq_pending(x) (S390_lowcore.softirq_pending |= (x))
+#define local_softirq_pending() (get_lowcore()->softirq_pending)
+#define set_softirq_pending(x) (get_lowcore()->softirq_pending = (x))
+#define or_softirq_pending(x) (get_lowcore()->softirq_pending |= (x))
#define __ARCH_IRQ_STAT
#define __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index deb198a61039..cf1b5d6fb1a6 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -19,7 +19,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned long sz);
void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
-pte_t huge_ptep_get(pte_t *ptep);
+pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep);
@@ -39,11 +39,11 @@ static inline int prepare_hugepage_range(struct file *file,
return 0;
}
-static inline void arch_clear_hugepage_flags(struct page *page)
+static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
- clear_bit(PG_arch_1, &page->flags);
+ clear_bit(PG_arch_1, &folio->flags);
}
-#define arch_clear_hugepage_flags arch_clear_hugepage_flags
+#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long sz)
@@ -64,7 +64,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty)
{
- int changed = !pte_same(huge_ptep_get(ptep), pte);
+ int changed = !pte_same(huge_ptep_get(vma->vm_mm, addr, ptep), pte);
if (changed) {
huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index 4453ad7c11ac..0fbc992d7a5e 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -73,6 +73,21 @@ static inline void ioport_unmap(void __iomem *p)
#define __raw_writel zpci_write_u32
#define __raw_writeq zpci_write_u64
+/* combine single writes by using store-block insn */
+static inline void __iowrite32_copy(void __iomem *to, const void *from,
+ size_t count)
+{
+ zpci_memcpy_toio(to, from, count * 4);
+}
+#define __iowrite32_copy __iowrite32_copy
+
+static inline void __iowrite64_copy(void __iomem *to, const void *from,
+ size_t count)
+{
+ zpci_memcpy_toio(to, from, count * 8);
+}
+#define __iowrite64_copy __iowrite64_copy
+
#endif /* CONFIG_PCI */
#include <asm-generic/io.h>
diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h
index 02427b205c11..bcab456dfb80 100644
--- a/arch/s390/include/asm/irqflags.h
+++ b/arch/s390/include/asm/irqflags.h
@@ -37,12 +37,18 @@ static __always_inline void __arch_local_irq_ssm(unsigned long flags)
asm volatile("ssm %0" : : "Q" (flags) : "memory");
}
-static __always_inline unsigned long arch_local_save_flags(void)
+#ifdef CONFIG_KMSAN
+#define arch_local_irq_attributes noinline notrace __no_sanitize_memory __maybe_unused
+#else
+#define arch_local_irq_attributes __always_inline
+#endif
+
+static arch_local_irq_attributes unsigned long arch_local_save_flags(void)
{
return __arch_local_irq_stnsm(0xff);
}
-static __always_inline unsigned long arch_local_irq_save(void)
+static arch_local_irq_attributes unsigned long arch_local_irq_save(void)
{
return __arch_local_irq_stnsm(0xfc);
}
@@ -52,7 +58,12 @@ static __always_inline void arch_local_irq_disable(void)
arch_local_irq_save();
}
-static __always_inline void arch_local_irq_enable(void)
+static arch_local_irq_attributes void arch_local_irq_enable_external(void)
+{
+ __arch_local_irq_stosm(0x01);
+}
+
+static arch_local_irq_attributes void arch_local_irq_enable(void)
{
__arch_local_irq_stosm(0x03);
}
diff --git a/arch/s390/include/asm/kmsan.h b/arch/s390/include/asm/kmsan.h
new file mode 100644
index 000000000000..f73e181d09ae
--- /dev/null
+++ b/arch/s390/include/asm/kmsan.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_KMSAN_H
+#define _ASM_S390_KMSAN_H
+
+#include <asm/lowcore.h>
+#include <asm/page.h>
+#include <linux/kmsan.h>
+#include <linux/mmzone.h>
+#include <linux/stddef.h>
+
+#ifndef MODULE
+
+static inline bool is_lowcore_addr(void *addr)
+{
+ return addr >= (void *)get_lowcore() &&
+ addr < (void *)(get_lowcore() + 1);
+}
+
+static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
+{
+ if (is_lowcore_addr(addr)) {
+ /*
+ * Different lowcores accessed via S390_lowcore are described
+ * by the same struct page. Resolve the prefix manually in
+ * order to get a distinct struct page.
+ */
+ addr += (void *)lowcore_ptr[raw_smp_processor_id()] -
+ (void *)get_lowcore();
+ if (KMSAN_WARN_ON(is_lowcore_addr(addr)))
+ return NULL;
+ return kmsan_get_metadata(addr, is_origin);
+ }
+ return NULL;
+}
+
+static inline bool kmsan_virt_addr_valid(void *addr)
+{
+ bool ret;
+
+ /*
+ * pfn_valid() relies on RCU, and may call into the scheduler on exiting
+ * the critical section. However, this would result in recursion with
+ * KMSAN. Therefore, disable preemption here, and re-enable preemption
+ * below while suppressing reschedules to avoid recursion.
+ *
+ * Note, this sacrifices occasionally breaking scheduling guarantees.
+ * Although, a kernel compiled with KMSAN has already given up on any
+ * performance guarantees due to being heavily instrumented.
+ */
+ preempt_disable();
+ ret = virt_addr_valid(addr);
+ preempt_enable_no_resched();
+
+ return ret;
+}
+
+#endif /* !MODULE */
+
+#endif /* _ASM_S390_KMSAN_H */
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 95990461888f..8e77afbed58e 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -15,7 +15,6 @@
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/kvm_types.h>
-#include <linux/kvm_host.h>
#include <linux/kvm.h>
#include <linux/seqlock.h>
#include <linux/module.h>
@@ -427,6 +426,7 @@ struct kvm_vcpu_stat {
u64 instruction_io_other;
u64 instruction_lpsw;
u64 instruction_lpswe;
+ u64 instruction_lpswey;
u64 instruction_pfmf;
u64 instruction_ptff;
u64 instruction_sck;
@@ -1029,11 +1029,12 @@ void kvm_arch_crypto_clear_masks(struct kvm *kvm);
void kvm_arch_crypto_set_masks(struct kvm *kvm, unsigned long *apm,
unsigned long *aqm, unsigned long *adm);
-int __sie64a(phys_addr_t sie_block_phys, struct kvm_s390_sie_block *sie_block, u64 *rsa);
+int __sie64a(phys_addr_t sie_block_phys, struct kvm_s390_sie_block *sie_block, u64 *rsa,
+ unsigned long gasce);
-static inline int sie64a(struct kvm_s390_sie_block *sie_block, u64 *rsa)
+static inline int sie64a(struct kvm_s390_sie_block *sie_block, u64 *rsa, unsigned long gasce)
{
- return __sie64a(virt_to_phys(sie_block), sie_block, rsa);
+ return __sie64a(virt_to_phys(sie_block), sie_block, rsa, gasce);
}
extern char sie_exit;
@@ -1045,7 +1046,6 @@ extern int kvm_s390_gisc_register(struct kvm *kvm, u32 gisc);
extern int kvm_s390_gisc_unregister(struct kvm *kvm, u32 gisc);
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_free_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot) {}
static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {}
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 8c5f16857539..183ac29afaf8 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -14,10 +14,15 @@
#include <asm/ctlreg.h>
#include <asm/cpu.h>
#include <asm/types.h>
+#include <asm/alternative.h>
#define LC_ORDER 1
#define LC_PAGES 2
+#define LOWCORE_ALT_ADDRESS _AC(0x70000, UL)
+
+#ifndef __ASSEMBLY__
+
struct pgm_tdb {
u64 data[32];
};
@@ -97,8 +102,7 @@ struct lowcore {
__u64 save_area_async[8]; /* 0x0240 */
__u64 save_area_restart[1]; /* 0x0280 */
- /* CPU flags. */
- __u64 cpu_flags; /* 0x0288 */
+ __u64 pcpu; /* 0x0288 */
/* Return psws. */
psw_t return_psw; /* 0x0290 */
@@ -213,7 +217,17 @@ struct lowcore {
__u8 pad_0x1900[0x2000-0x1900]; /* 0x1900 */
} __packed __aligned(8192);
-#define S390_lowcore (*((struct lowcore *) 0))
+static __always_inline struct lowcore *get_lowcore(void)
+{
+ struct lowcore *lc;
+
+ if (__is_defined(__DECOMPRESSOR))
+ return NULL;
+ asm(ALTERNATIVE("llilh %[lc],0", "llilh %[lc],%[alt]", ALT_LOWCORE)
+ : [lc] "=d" (lc)
+ : [alt] "i" (LOWCORE_ALT_ADDRESS >> 16));
+ return lc;
+}
extern struct lowcore *lowcore_ptr[];
@@ -222,4 +236,19 @@ static inline void set_prefix(__u32 address)
asm volatile("spx %0" : : "Q" (address) : "memory");
}
+#else /* __ASSEMBLY__ */
+
+.macro GET_LC reg
+ ALTERNATIVE "llilh \reg,0", \
+ __stringify(llilh \reg, LOWCORE_ALT_ADDRESS >> 16), \
+ ALT_LOWCORE
+.endm
+
+.macro STMG_LC start, end, savearea
+ ALTERNATIVE "stmg \start, \end, \savearea", \
+ __stringify(stmg \start, \end, LOWCORE_ALT_ADDRESS + \savearea), \
+ ALT_LOWCORE
+.endm
+
+#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_LOWCORE_H */
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h
index bb1b4bef1878..4c2dc7abc285 100644
--- a/arch/s390/include/asm/mmu.h
+++ b/arch/s390/include/asm/mmu.h
@@ -32,6 +32,11 @@ typedef struct {
unsigned int uses_skeys:1;
/* The mmu context uses CMM. */
unsigned int uses_cmm:1;
+ /*
+ * The mmu context allows COW-sharing of memory pages (KSM, zeropage).
+ * Note that COW-sharing during fork() is currently always allowed.
+ */
+ unsigned int allow_cow_sharing:1;
/* The gmaps associated with this context are allowed to use huge pages. */
unsigned int allow_gmap_hpage_1m:1;
} mm_context_t;
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index 929af18b0908..d56eb0a1f37b 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -35,6 +35,7 @@ static inline int init_new_context(struct task_struct *tsk,
mm->context.has_pgste = 0;
mm->context.uses_skeys = 0;
mm->context.uses_cmm = 0;
+ mm->context.allow_cow_sharing = 1;
mm->context.allow_gmap_hpage_1m = 0;
#endif
switch (mm->context.asce_limit) {
@@ -75,9 +76,9 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *
int cpu = smp_processor_id();
if (next == &init_mm)
- S390_lowcore.user_asce = s390_invalid_asce;
+ get_lowcore()->user_asce = s390_invalid_asce;
else
- S390_lowcore.user_asce.val = next->context.asce;
+ get_lowcore()->user_asce.val = next->context.asce;
cpumask_set_cpu(cpu, &next->context.cpu_attach_mask);
/* Clear previous user-ASCE from CR7 */
local_ctl_load(7, &s390_invalid_asce);
@@ -110,7 +111,7 @@ static inline void finish_arch_post_lock_switch(void)
__tlb_flush_mm_lazy(mm);
preempt_enable();
}
- local_ctl_load(7, &S390_lowcore.user_asce);
+ local_ctl_load(7, &get_lowcore()->user_asce);
}
#define activate_mm activate_mm
@@ -119,7 +120,7 @@ static inline void activate_mm(struct mm_struct *prev,
{
switch_mm(prev, next, current);
cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
- local_ctl_load(7, &S390_lowcore.user_asce);
+ local_ctl_load(7, &get_lowcore()->user_asce);
}
#include <asm-generic/mmu_context.h>
diff --git a/arch/s390/include/asm/nospec-branch.h b/arch/s390/include/asm/nospec-branch.h
index 82725cf783c7..192835a3e24d 100644
--- a/arch/s390/include/asm/nospec-branch.h
+++ b/arch/s390/include/asm/nospec-branch.h
@@ -5,8 +5,17 @@
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#include <asm/facility.h>
extern int nospec_disable;
+extern int nobp;
+
+static inline bool nobp_enabled(void)
+{
+ if (__is_defined(__DECOMPRESSOR))
+ return false;
+ return nobp && test_facility(82);
+}
void nospec_init_branches(void);
void nospec_auto_detect(void);
@@ -17,6 +26,26 @@ static inline bool nospec_uses_trampoline(void)
return __is_defined(CC_USING_EXPOLINE) && !nospec_disable;
}
+#ifdef CONFIG_EXPOLINE_EXTERN
+
+void __s390_indirect_jump_r1(void);
+void __s390_indirect_jump_r2(void);
+void __s390_indirect_jump_r3(void);
+void __s390_indirect_jump_r4(void);
+void __s390_indirect_jump_r5(void);
+void __s390_indirect_jump_r6(void);
+void __s390_indirect_jump_r7(void);
+void __s390_indirect_jump_r8(void);
+void __s390_indirect_jump_r9(void);
+void __s390_indirect_jump_r10(void);
+void __s390_indirect_jump_r11(void);
+void __s390_indirect_jump_r12(void);
+void __s390_indirect_jump_r13(void);
+void __s390_indirect_jump_r14(void);
+void __s390_indirect_jump_r15(void);
+
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_EXPOLINE_H */
diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h
index 7a946c42ad13..cb15dd25bf21 100644
--- a/arch/s390/include/asm/nospec-insn.h
+++ b/arch/s390/include/asm/nospec-insn.h
@@ -16,24 +16,25 @@
*/
.macro __THUNK_PROLOG_NAME name
#ifdef CONFIG_EXPOLINE_EXTERN
- .pushsection .text,"ax",@progbits
- __ALIGN
+ SYM_CODE_START(\name)
#else
.pushsection .text.\name,"axG",@progbits,\name,comdat
-#endif
.globl \name
.hidden \name
.type \name,@function
\name:
CFI_STARTPROC
+#endif
.endm
.macro __THUNK_EPILOG_NAME name
- CFI_ENDPROC
#ifdef CONFIG_EXPOLINE_EXTERN
- .size \name, .-\name
-#endif
+ SYM_CODE_END(\name)
+ EXPORT_SYMBOL(\name)
+#else
+ CFI_ENDPROC
.popsection
+#endif
.endm
.macro __THUNK_PROLOG_BR r1
diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h
index a4d2e103f116..3ee9e8f5ceae 100644
--- a/arch/s390/include/asm/os_info.h
+++ b/arch/s390/include/asm/os_info.h
@@ -17,11 +17,25 @@
#define OS_INFO_VMCOREINFO 0
#define OS_INFO_REIPL_BLOCK 1
#define OS_INFO_FLAGS_ENTRY 2
+#define OS_INFO_RESERVED 3
+#define OS_INFO_IDENTITY_BASE 4
+#define OS_INFO_KASLR_OFFSET 5
+#define OS_INFO_KASLR_OFF_PHYS 6
+#define OS_INFO_VMEMMAP 7
+#define OS_INFO_AMODE31_START 8
+#define OS_INFO_AMODE31_END 9
+#define OS_INFO_IMAGE_START 10
+#define OS_INFO_IMAGE_END 11
+#define OS_INFO_IMAGE_PHYS 12
+#define OS_INFO_MAX 13
#define OS_INFO_FLAG_REIPL_CLEAR (1UL << 0)
struct os_info_entry {
- u64 addr;
+ union {
+ u64 addr;
+ u64 val;
+ };
u64 size;
u32 csum;
} __packed;
@@ -33,17 +47,24 @@ struct os_info {
u16 version_minor;
u64 crashkernel_addr;
u64 crashkernel_size;
- struct os_info_entry entry[3];
- u8 reserved[4004];
+ struct os_info_entry entry[OS_INFO_MAX];
+ u8 reserved[3804];
} __packed;
void os_info_init(void);
-void os_info_entry_add(int nr, void *ptr, u64 len);
+void os_info_entry_add_data(int nr, void *ptr, u64 len);
+void os_info_entry_add_val(int nr, u64 val);
void os_info_crashkernel_add(unsigned long base, unsigned long size);
u32 os_info_csum(struct os_info *os_info);
#ifdef CONFIG_CRASH_DUMP
void *os_info_old_entry(int nr, unsigned long *size);
+static inline unsigned long os_info_old_value(int nr)
+{
+ unsigned long size;
+
+ return (unsigned long)os_info_old_entry(nr, &size);
+}
#else
static inline void *os_info_old_entry(int nr, unsigned long *size)
{
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 9381879f7ecf..06416b3f94f5 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -162,6 +162,7 @@ static inline int page_reset_referenced(unsigned long addr)
#define _PAGE_ACC_BITS 0xf0 /* HW access control bits */
struct page;
+struct folio;
void arch_free_page(struct page *page, int order);
void arch_alloc_page(struct page *page, int order);
@@ -173,24 +174,57 @@ static inline int devmem_is_allowed(unsigned long pfn)
#define HAVE_ARCH_FREE_PAGE
#define HAVE_ARCH_ALLOC_PAGE
-#if IS_ENABLED(CONFIG_PGSTE)
+int arch_make_folio_accessible(struct folio *folio);
+#define HAVE_ARCH_MAKE_FOLIO_ACCESSIBLE
int arch_make_page_accessible(struct page *page);
#define HAVE_ARCH_MAKE_PAGE_ACCESSIBLE
-#endif
-#define __PAGE_OFFSET 0x0UL
-#define PAGE_OFFSET 0x0UL
+struct vm_layout {
+ unsigned long kaslr_offset;
+ unsigned long kaslr_offset_phys;
+ unsigned long identity_base;
+ unsigned long identity_size;
+};
-#define __pa_nodebug(x) ((unsigned long)(x))
+extern struct vm_layout vm_layout;
+
+#define __kaslr_offset vm_layout.kaslr_offset
+#define __kaslr_offset_phys vm_layout.kaslr_offset_phys
+#define __identity_base vm_layout.identity_base
+#define ident_map_size vm_layout.identity_size
+
+static inline unsigned long kaslr_offset(void)
+{
+ return __kaslr_offset;
+}
+
+extern int __kaslr_enabled;
+static inline int kaslr_enabled(void)
+{
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
+ return __kaslr_enabled;
+ return 0;
+}
+
+#define __PAGE_OFFSET __identity_base
+#define PAGE_OFFSET __PAGE_OFFSET
#ifdef __DECOMPRESSOR
+#define __pa_nodebug(x) ((unsigned long)(x))
#define __pa(x) __pa_nodebug(x)
#define __pa32(x) __pa(x)
#define __va(x) ((void *)(unsigned long)(x))
#else /* __DECOMPRESSOR */
+static inline unsigned long __pa_nodebug(unsigned long x)
+{
+ if (x < __kaslr_offset)
+ return x - __identity_base;
+ return x - __kaslr_offset + __kaslr_offset_phys;
+}
+
#ifdef CONFIG_DEBUG_VIRTUAL
unsigned long __phys_addr(unsigned long x, bool is_31bit);
@@ -206,7 +240,7 @@ static inline unsigned long __phys_addr(unsigned long x, bool is_31bit)
#define __pa(x) __phys_addr((unsigned long)(x), false)
#define __pa32(x) __phys_addr((unsigned long)(x), true)
-#define __va(x) ((void *)(unsigned long)(x))
+#define __va(x) ((void *)((unsigned long)(x) + __identity_base))
#endif /* __DECOMPRESSOR */
@@ -214,7 +248,9 @@ static inline unsigned long __phys_addr(unsigned long x, bool is_31bit)
#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
#define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys))
+#define phys_to_folio(phys) page_folio(phys_to_page(phys))
#define page_to_phys(page) pfn_to_phys(page_to_pfn(page))
+#define folio_to_phys(page) pfn_to_phys(folio_pfn(folio))
static inline void *pfn_to_virt(unsigned long pfn)
{
@@ -231,7 +267,7 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr))
#define page_to_virt(page) pfn_to_virt(page_to_pfn(page))
-#define virt_addr_valid(kaddr) pfn_valid(phys_to_pfn(__pa_nodebug(kaddr)))
+#define virt_addr_valid(kaddr) pfn_valid(phys_to_pfn(__pa_nodebug((unsigned long)(kaddr))))
#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC
@@ -240,4 +276,11 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
+#define AMODE31_SIZE (3 * PAGE_SIZE)
+
+#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
+#define __START_KERNEL 0x100000
+#define __NO_KASLR_START_KERNEL CONFIG_KERNEL_IMAGE_BASE
+#define __NO_KASLR_END_KERNEL (__NO_KASLR_START_KERNEL + KERNEL_IMAGE_SIZE)
+
#endif /* _S390_PAGE_H */
diff --git a/arch/s390/include/asm/pai.h b/arch/s390/include/asm/pai.h
index 3f609565734b..25f2077ba3c9 100644
--- a/arch/s390/include/asm/pai.h
+++ b/arch/s390/include/asm/pai.h
@@ -55,11 +55,11 @@ static __always_inline void pai_kernel_enter(struct pt_regs *regs)
return;
if (!static_branch_unlikely(&pai_key))
return;
- if (!S390_lowcore.ccd)
+ if (!get_lowcore()->ccd)
return;
if (!user_mode(regs))
return;
- WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd | PAI_CRYPTO_KERNEL_OFFSET);
+ WRITE_ONCE(get_lowcore()->ccd, get_lowcore()->ccd | PAI_CRYPTO_KERNEL_OFFSET);
}
static __always_inline void pai_kernel_exit(struct pt_regs *regs)
@@ -68,18 +68,15 @@ static __always_inline void pai_kernel_exit(struct pt_regs *regs)
return;
if (!static_branch_unlikely(&pai_key))
return;
- if (!S390_lowcore.ccd)
+ if (!get_lowcore()->ccd)
return;
if (!user_mode(regs))
return;
- WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd & ~PAI_CRYPTO_KERNEL_OFFSET);
+ WRITE_ONCE(get_lowcore()->ccd, get_lowcore()->ccd & ~PAI_CRYPTO_KERNEL_OFFSET);
}
-enum paievt_mode {
- PAI_MODE_NONE,
- PAI_MODE_SAMPLING,
- PAI_MODE_COUNTING,
-};
-
#define PAI_SAVE_AREA(x) ((x)->hw.event_base)
+#define PAI_CPU_MASK(x) ((x)->hw.addr_filters)
+#define PAI_SWLIST(x) (&(x)->hw.tp_list)
+
#endif
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 264095dd84bc..89a28740b6ab 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -9,7 +9,7 @@
* s390 uses its own implementation for per cpu data, the offset of
* the cpu local data area is cached in the cpu's lowcore memory.
*/
-#define __my_cpu_offset S390_lowcore.percpu_offset
+#define __my_cpu_offset get_lowcore()->percpu_offset
/*
* For 64 bit module code, the module may be more than 4G above the
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 60950e7a25f5..3fa280d0672a 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -107,6 +107,24 @@ static inline int is_module_addr(void *addr)
return 1;
}
+#ifdef CONFIG_KMSAN
+#define KMSAN_VMALLOC_SIZE (VMALLOC_END - VMALLOC_START)
+#define KMSAN_VMALLOC_SHADOW_START VMALLOC_END
+#define KMSAN_VMALLOC_SHADOW_END (KMSAN_VMALLOC_SHADOW_START + KMSAN_VMALLOC_SIZE)
+#define KMSAN_VMALLOC_ORIGIN_START KMSAN_VMALLOC_SHADOW_END
+#define KMSAN_VMALLOC_ORIGIN_END (KMSAN_VMALLOC_ORIGIN_START + KMSAN_VMALLOC_SIZE)
+#define KMSAN_MODULES_SHADOW_START KMSAN_VMALLOC_ORIGIN_END
+#define KMSAN_MODULES_SHADOW_END (KMSAN_MODULES_SHADOW_START + MODULES_LEN)
+#define KMSAN_MODULES_ORIGIN_START KMSAN_MODULES_SHADOW_END
+#define KMSAN_MODULES_ORIGIN_END (KMSAN_MODULES_ORIGIN_START + MODULES_LEN)
+#endif
+
+#ifdef CONFIG_RANDOMIZE_BASE
+#define KASLR_LEN (1UL << 31)
+#else
+#define KASLR_LEN 0UL
+#endif
+
/*
* A 64 bit pagetable entry of S390 has following format:
* | PFRA |0IPC| OS |
@@ -262,12 +280,14 @@ static inline int is_module_addr(void *addr)
#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INVALID)
+#define _REGION3_ENTRY_HARDWARE_BITS 0xfffffffffffff6ffUL
+#define _REGION3_ENTRY_HARDWARE_BITS_LARGE 0xffffffff8001073cUL
#define _REGION3_ENTRY_ORIGIN_LARGE ~0x7fffffffUL /* large page address */
#define _REGION3_ENTRY_DIRTY 0x2000 /* SW region dirty bit */
#define _REGION3_ENTRY_YOUNG 0x1000 /* SW region young bit */
#define _REGION3_ENTRY_LARGE 0x0400 /* RTTE-format control, large page */
-#define _REGION3_ENTRY_READ 0x0002 /* SW region read bit */
-#define _REGION3_ENTRY_WRITE 0x0001 /* SW region write bit */
+#define _REGION3_ENTRY_WRITE 0x0002 /* SW region write bit */
+#define _REGION3_ENTRY_READ 0x0001 /* SW region read bit */
#ifdef CONFIG_MEM_SOFT_DIRTY
#define _REGION3_ENTRY_SOFT_DIRTY 0x4000 /* SW region soft dirty bit */
@@ -278,9 +298,9 @@ static inline int is_module_addr(void *addr)
#define _REGION_ENTRY_BITS 0xfffffffffffff22fUL
/* Bits in the segment table entry */
-#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL
-#define _SEGMENT_ENTRY_HARDWARE_BITS 0xfffffffffffffe30UL
-#define _SEGMENT_ENTRY_HARDWARE_BITS_LARGE 0xfffffffffff00730UL
+#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe3fUL
+#define _SEGMENT_ENTRY_HARDWARE_BITS 0xfffffffffffffe3cUL
+#define _SEGMENT_ENTRY_HARDWARE_BITS_LARGE 0xfffffffffff1073cUL
#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* page table origin */
#define _SEGMENT_ENTRY_PROTECT 0x200 /* segment protection bit */
@@ -566,10 +586,20 @@ static inline pud_t set_pud_bit(pud_t pud, pgprot_t prot)
}
/*
- * In the case that a guest uses storage keys
- * faults should no longer be backed by zero pages
+ * As soon as the guest uses storage keys or enables PV, we deduplicate all
+ * mapped shared zeropages and prevent new shared zeropages from getting
+ * mapped.
*/
-#define mm_forbids_zeropage mm_has_pgste
+#define mm_forbids_zeropage mm_forbids_zeropage
+static inline int mm_forbids_zeropage(struct mm_struct *mm)
+{
+#ifdef CONFIG_PGSTE
+ if (!mm->context.allow_cow_sharing)
+ return 1;
+#endif
+ return 0;
+}
+
static inline int mm_uses_skeys(struct mm_struct *mm)
{
#ifdef CONFIG_PGSTE
@@ -591,7 +621,15 @@ static inline void csp(unsigned int *ptr, unsigned int old, unsigned int new)
: "cc");
}
-static inline void cspg(unsigned long *ptr, unsigned long old, unsigned long new)
+/**
+ * cspg() - Compare and Swap and Purge (CSPG)
+ * @ptr: Pointer to the value to be exchanged
+ * @old: The expected old value
+ * @new: The new value
+ *
+ * Return: True if compare and swap was successful, otherwise false.
+ */
+static inline bool cspg(unsigned long *ptr, unsigned long old, unsigned long new)
{
union register_pair r1 = { .even = old, .odd = new, };
unsigned long address = (unsigned long)ptr | 1;
@@ -601,6 +639,7 @@ static inline void cspg(unsigned long *ptr, unsigned long old, unsigned long new
: [r1] "+&d" (r1.pair), "+m" (*ptr)
: [address] "d" (address)
: "cc");
+ return old == r1.even;
}
#define CRDTE_DTT_PAGE 0x00UL
@@ -609,7 +648,18 @@ static inline void cspg(unsigned long *ptr, unsigned long old, unsigned long new
#define CRDTE_DTT_REGION2 0x18UL
#define CRDTE_DTT_REGION1 0x1cUL
-static inline void crdte(unsigned long old, unsigned long new,
+/**
+ * crdte() - Compare and Replace DAT Table Entry
+ * @old: The expected old value
+ * @new: The new value
+ * @table: Pointer to the value to be exchanged
+ * @dtt: Table type of the table to be exchanged
+ * @address: The address mapped by the entry to be replaced
+ * @asce: The ASCE of this entry
+ *
+ * Return: True if compare and replace was successful, otherwise false.
+ */
+static inline bool crdte(unsigned long old, unsigned long new,
unsigned long *table, unsigned long dtt,
unsigned long address, unsigned long asce)
{
@@ -620,6 +670,7 @@ static inline void crdte(unsigned long old, unsigned long new,
: [r1] "+&d" (r1.pair)
: [r2] "d" (r2.pair), [asce] "a" (asce)
: "memory", "cc");
+ return old == r1.even;
}
/*
@@ -1149,7 +1200,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID));
/* At this point the reference through the mapping is still present */
if (mm_is_protected(mm) && pte_present(res))
- uv_convert_owned_from_secure(pte_val(res) & PAGE_MASK);
+ uv_convert_from_secure_pte(res);
return res;
}
@@ -1167,7 +1218,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
res = ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID));
/* At this point the reference through the mapping is still present */
if (mm_is_protected(vma->vm_mm) && pte_present(res))
- uv_convert_owned_from_secure(pte_val(res) & PAGE_MASK);
+ uv_convert_from_secure_pte(res);
return res;
}
@@ -1199,14 +1250,14 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
* The notifier should have destroyed all protected vCPUs at this
* point, so the destroy should be successful.
*/
- if (full && !uv_destroy_owned_page(pte_val(res) & PAGE_MASK))
+ if (full && !uv_destroy_pte(res))
return res;
/*
* If something went wrong and the page could not be destroyed, or
* if this is not a mm teardown, the slower export is used as
* fallback instead.
*/
- uv_convert_owned_from_secure(pte_val(res) & PAGE_MASK);
+ uv_convert_from_secure_pte(res);
return res;
}
@@ -1405,6 +1456,7 @@ static inline unsigned long pud_deref(pud_t pud)
return (unsigned long)__va(pud_val(pud) & origin_mask);
}
+#define pud_pfn pud_pfn
static inline unsigned long pud_pfn(pud_t pud)
{
return __pa(pud_deref(pud)) >> PAGE_SHIFT;
@@ -1768,8 +1820,10 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma,
static inline pmd_t pmdp_invalidate(struct vm_area_struct *vma,
unsigned long addr, pmd_t *pmdp)
{
- pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
+ pmd_t pmd;
+ VM_WARN_ON_ONCE(!pmd_present(*pmdp));
+ pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
return pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd);
}
diff --git a/arch/s390/include/asm/physmem_info.h b/arch/s390/include/asm/physmem_info.h
index e747b067f8db..f45cfc8bc233 100644
--- a/arch/s390/include/asm/physmem_info.h
+++ b/arch/s390/include/asm/physmem_info.h
@@ -22,7 +22,6 @@ enum reserved_range_type {
RR_DECOMPRESSOR,
RR_INITRD,
RR_VMLINUX,
- RR_RELOC,
RR_AMODE31,
RR_IPLREPORT,
RR_CERT_COMP_LIST,
@@ -170,4 +169,7 @@ static inline unsigned long get_physmem_reserved(enum reserved_range_type type,
return *size;
}
+#define AMODE31_START (physmem_info.reserved[RR_AMODE31].start)
+#define AMODE31_END (physmem_info.reserved[RR_AMODE31].end)
+
#endif
diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h
index 0e3da500e98c..3ae5f31c665d 100644
--- a/arch/s390/include/asm/preempt.h
+++ b/arch/s390/include/asm/preempt.h
@@ -14,7 +14,7 @@
static __always_inline int preempt_count(void)
{
- return READ_ONCE(S390_lowcore.preempt_count) & ~PREEMPT_NEED_RESCHED;
+ return READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED;
}
static __always_inline void preempt_count_set(int pc)
@@ -22,26 +22,26 @@ static __always_inline void preempt_count_set(int pc)
int old, new;
do {
- old = READ_ONCE(S390_lowcore.preempt_count);
+ old = READ_ONCE(get_lowcore()->preempt_count);
new = (old & PREEMPT_NEED_RESCHED) |
(pc & ~PREEMPT_NEED_RESCHED);
- } while (__atomic_cmpxchg(&S390_lowcore.preempt_count,
+ } while (__atomic_cmpxchg(&get_lowcore()->preempt_count,
old, new) != old);
}
static __always_inline void set_preempt_need_resched(void)
{
- __atomic_and(~PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count);
+ __atomic_and(~PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count);
}
static __always_inline void clear_preempt_need_resched(void)
{
- __atomic_or(PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count);
+ __atomic_or(PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count);
}
static __always_inline bool test_preempt_need_resched(void)
{
- return !(READ_ONCE(S390_lowcore.preempt_count) & PREEMPT_NEED_RESCHED);
+ return !(READ_ONCE(get_lowcore()->preempt_count) & PREEMPT_NEED_RESCHED);
}
static __always_inline void __preempt_count_add(int val)
@@ -52,11 +52,11 @@ static __always_inline void __preempt_count_add(int val)
*/
if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) {
if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) {
- __atomic_add_const(val, &S390_lowcore.preempt_count);
+ __atomic_add_const(val, &get_lowcore()->preempt_count);
return;
}
}
- __atomic_add(val, &S390_lowcore.preempt_count);
+ __atomic_add(val, &get_lowcore()->preempt_count);
}
static __always_inline void __preempt_count_sub(int val)
@@ -66,12 +66,12 @@ static __always_inline void __preempt_count_sub(int val)
static __always_inline bool __preempt_count_dec_and_test(void)
{
- return __atomic_add(-1, &S390_lowcore.preempt_count) == 1;
+ return __atomic_add(-1, &get_lowcore()->preempt_count) == 1;
}
static __always_inline bool should_resched(int preempt_offset)
{
- return unlikely(READ_ONCE(S390_lowcore.preempt_count) ==
+ return unlikely(READ_ONCE(get_lowcore()->preempt_count) ==
preempt_offset);
}
@@ -81,12 +81,12 @@ static __always_inline bool should_resched(int preempt_offset)
static __always_inline int preempt_count(void)
{
- return READ_ONCE(S390_lowcore.preempt_count);
+ return READ_ONCE(get_lowcore()->preempt_count);
}
static __always_inline void preempt_count_set(int pc)
{
- S390_lowcore.preempt_count = pc;
+ get_lowcore()->preempt_count = pc;
}
static __always_inline void set_preempt_need_resched(void)
@@ -104,17 +104,17 @@ static __always_inline bool test_preempt_need_resched(void)
static __always_inline void __preempt_count_add(int val)
{
- S390_lowcore.preempt_count += val;
+ get_lowcore()->preempt_count += val;
}
static __always_inline void __preempt_count_sub(int val)
{
- S390_lowcore.preempt_count -= val;
+ get_lowcore()->preempt_count -= val;
}
static __always_inline bool __preempt_count_dec_and_test(void)
{
- return !--S390_lowcore.preempt_count && tif_need_resched();
+ return !--get_lowcore()->preempt_count && tif_need_resched();
}
static __always_inline bool should_resched(int preempt_offset)
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index db9982f0e8cd..5ecd442535b9 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -14,13 +14,11 @@
#include <linux/bits.h>
-#define CIF_SIE 0 /* CPU needs SIE exit cleanup */
#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
#define CIF_ENABLED_WAIT 5 /* in enabled wait state */
#define CIF_MCCK_GUEST 6 /* machine check happening in guest */
#define CIF_DEDICATED_CPU 7 /* this CPU is dedicated */
-#define _CIF_SIE BIT(CIF_SIE)
#define _CIF_NOHZ_DELAY BIT(CIF_NOHZ_DELAY)
#define _CIF_ENABLED_WAIT BIT(CIF_ENABLED_WAIT)
#define _CIF_MCCK_GUEST BIT(CIF_MCCK_GUEST)
@@ -40,22 +38,39 @@
#include <asm/setup.h>
#include <asm/runtime_instr.h>
#include <asm/irqflags.h>
+#include <asm/alternative.h>
+
+struct pcpu {
+ unsigned long ec_mask; /* bit mask for ec_xxx functions */
+ unsigned long ec_clk; /* sigp timestamp for ec_xxx */
+ unsigned long flags; /* per CPU flags */
+ signed char state; /* physical cpu state */
+ signed char polarization; /* physical polarization */
+ u16 address; /* physical cpu address */
+};
+
+DECLARE_PER_CPU(struct pcpu, pcpu_devices);
typedef long (*sys_call_ptr_t)(struct pt_regs *regs);
+static __always_inline struct pcpu *this_pcpu(void)
+{
+ return (struct pcpu *)(get_lowcore()->pcpu);
+}
+
static __always_inline void set_cpu_flag(int flag)
{
- S390_lowcore.cpu_flags |= (1UL << flag);
+ this_pcpu()->flags |= (1UL << flag);
}
static __always_inline void clear_cpu_flag(int flag)
{
- S390_lowcore.cpu_flags &= ~(1UL << flag);
+ this_pcpu()->flags &= ~(1UL << flag);
}
static __always_inline bool test_cpu_flag(int flag)
{
- return S390_lowcore.cpu_flags & (1UL << flag);
+ return this_pcpu()->flags & (1UL << flag);
}
static __always_inline bool test_and_set_cpu_flag(int flag)
@@ -80,9 +95,7 @@ static __always_inline bool test_and_clear_cpu_flag(int flag)
*/
static __always_inline bool test_cpu_flag_of(int flag, int cpu)
{
- struct lowcore *lc = lowcore_ptr[cpu];
-
- return lc->cpu_flags & (1UL << flag);
+ return per_cpu(pcpu_devices, cpu).flags & (1UL << flag);
}
#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
@@ -92,12 +105,21 @@ static inline void get_cpu_id(struct cpuid *ptr)
asm volatile("stidp %0" : "=Q" (*ptr));
}
+static __always_inline unsigned long get_cpu_timer(void)
+{
+ unsigned long timer;
+
+ asm volatile("stpt %[timer]" : [timer] "=Q" (timer));
+ return timer;
+}
+
void s390_adjust_jiffies(void);
void s390_update_cpu_mhz(void);
void cpu_detect_mhz_feature(void);
extern const struct seq_operations cpuinfo_op;
extern void execve_tail(void);
+unsigned long vdso_text_size(void);
unsigned long vdso_size(void);
/*
@@ -259,7 +281,7 @@ static __always_inline unsigned long __current_stack_pointer(void)
static __always_inline bool on_thread_stack(void)
{
- unsigned long ksp = S390_lowcore.kernel_stack;
+ unsigned long ksp = get_lowcore()->kernel_stack;
return !((ksp ^ current_stack_pointer) & ~(THREAD_SIZE - 1));
}
@@ -304,8 +326,8 @@ static inline void __load_psw(psw_t psw)
*/
static __always_inline void __load_psw_mask(unsigned long mask)
{
+ psw_t psw __uninitialized;
unsigned long addr;
- psw_t psw;
psw.mask = mask;
@@ -393,6 +415,11 @@ static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
return arch_irqs_disabled_flags(regs->psw.mask);
}
+static __always_inline void bpon(void)
+{
+ asm volatile(ALTERNATIVE("nop", ".insn rrf,0xb2e80000,0,0,13,0", ALT_SPEC(82)));
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_S390_PROCESSOR_H */
diff --git a/arch/s390/include/asm/runtime-const.h b/arch/s390/include/asm/runtime-const.h
new file mode 100644
index 000000000000..17878b1d048c
--- /dev/null
+++ b/arch/s390/include/asm/runtime-const.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_RUNTIME_CONST_H
+#define _ASM_S390_RUNTIME_CONST_H
+
+#include <linux/uaccess.h>
+
+#define runtime_const_ptr(sym) \
+({ \
+ typeof(sym) __ret; \
+ \
+ asm_inline( \
+ "0: iihf %[__ret],%[c1]\n" \
+ " iilf %[__ret],%[c2]\n" \
+ ".pushsection runtime_ptr_" #sym ",\"a\"\n" \
+ ".long 0b - .\n" \
+ ".popsection" \
+ : [__ret] "=d" (__ret) \
+ : [c1] "i" (0x01234567UL), \
+ [c2] "i" (0x89abcdefUL)); \
+ __ret; \
+})
+
+#define runtime_const_shift_right_32(val, sym) \
+({ \
+ unsigned int __ret = (val); \
+ \
+ asm_inline( \
+ "0: srl %[__ret],12\n" \
+ ".pushsection runtime_shift_" #sym ",\"a\"\n" \
+ ".long 0b - .\n" \
+ ".popsection" \
+ : [__ret] "+d" (__ret)); \
+ __ret; \
+})
+
+#define runtime_const_init(type, sym) do { \
+ extern s32 __start_runtime_##type##_##sym[]; \
+ extern s32 __stop_runtime_##type##_##sym[]; \
+ \
+ runtime_const_fixup(__runtime_fixup_##type, \
+ (unsigned long)(sym), \
+ __start_runtime_##type##_##sym, \
+ __stop_runtime_##type##_##sym); \
+} while (0)
+
+/* 32-bit immediate for iihf and iilf in bits in I2 field */
+static inline void __runtime_fixup_32(u32 *p, unsigned int val)
+{
+ s390_kernel_write(p, &val, sizeof(val));
+}
+
+static inline void __runtime_fixup_ptr(void *where, unsigned long val)
+{
+ __runtime_fixup_32(where + 2, val >> 32);
+ __runtime_fixup_32(where + 8, val);
+}
+
+/* Immediate value is lower 12 bits of D2 field of srl */
+static inline void __runtime_fixup_shift(void *where, unsigned long val)
+{
+ u32 insn = *(u32 *)where;
+
+ insn &= 0xfffff000;
+ insn |= (val & 63);
+ s390_kernel_write(where, &insn, sizeof(insn));
+}
+
+static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
+ unsigned long val, s32 *start, s32 *end)
+{
+ while (start < end) {
+ fn(*start + (void *)start, val);
+ start++;
+ }
+}
+
+#endif /* _ASM_S390_RUNTIME_CONST_H */
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index 5742d23bba13..da3dad18fe50 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -84,6 +84,7 @@ struct sclp_info {
unsigned char has_ibs : 1;
unsigned char has_skey : 1;
unsigned char has_kss : 1;
+ unsigned char has_diag204_bif : 1;
unsigned char has_gisaf : 1;
unsigned char has_diag318 : 1;
unsigned char has_diag320 : 1;
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 03bcaa8effb2..8505737712ee 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -77,24 +77,24 @@ extern unsigned long max_mappable;
/* 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)
-#define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
-
-#define MACHINE_HAS_DIAG9C (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
-#define MACHINE_HAS_ESOP (S390_lowcore.machine_flags & MACHINE_FLAG_ESOP)
-#define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE)
-#define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1)
-#define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2)
-#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
-#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
-#define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC)
-#define MACHINE_HAS_TLB_GUEST (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_GUEST)
-#define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX)
-#define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS)
-#define MACHINE_HAS_SCC (S390_lowcore.machine_flags & MACHINE_FLAG_SCC)
-#define MACHINE_HAS_PCI_MIO (S390_lowcore.machine_flags & MACHINE_FLAG_PCI_MIO)
-#define MACHINE_HAS_RDP (S390_lowcore.machine_flags & MACHINE_FLAG_RDP)
+#define MACHINE_IS_VM (get_lowcore()->machine_flags & MACHINE_FLAG_VM)
+#define MACHINE_IS_KVM (get_lowcore()->machine_flags & MACHINE_FLAG_KVM)
+#define MACHINE_IS_LPAR (get_lowcore()->machine_flags & MACHINE_FLAG_LPAR)
+
+#define MACHINE_HAS_DIAG9C (get_lowcore()->machine_flags & MACHINE_FLAG_DIAG9C)
+#define MACHINE_HAS_ESOP (get_lowcore()->machine_flags & MACHINE_FLAG_ESOP)
+#define MACHINE_HAS_IDTE (get_lowcore()->machine_flags & MACHINE_FLAG_IDTE)
+#define MACHINE_HAS_EDAT1 (get_lowcore()->machine_flags & MACHINE_FLAG_EDAT1)
+#define MACHINE_HAS_EDAT2 (get_lowcore()->machine_flags & MACHINE_FLAG_EDAT2)
+#define MACHINE_HAS_TOPOLOGY (get_lowcore()->machine_flags & MACHINE_FLAG_TOPOLOGY)
+#define MACHINE_HAS_TE (get_lowcore()->machine_flags & MACHINE_FLAG_TE)
+#define MACHINE_HAS_TLB_LC (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_LC)
+#define MACHINE_HAS_TLB_GUEST (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_GUEST)
+#define MACHINE_HAS_NX (get_lowcore()->machine_flags & MACHINE_FLAG_NX)
+#define MACHINE_HAS_GS (get_lowcore()->machine_flags & MACHINE_FLAG_GS)
+#define MACHINE_HAS_SCC (get_lowcore()->machine_flags & MACHINE_FLAG_SCC)
+#define MACHINE_HAS_PCI_MIO (get_lowcore()->machine_flags & MACHINE_FLAG_PCI_MIO)
+#define MACHINE_HAS_RDP (get_lowcore()->machine_flags & MACHINE_FLAG_RDP)
/*
* Console mode. Override with conmode=
@@ -127,20 +127,6 @@ extern void (*_machine_restart)(char *command);
extern void (*_machine_halt)(void);
extern void (*_machine_power_off)(void);
-extern unsigned long __kaslr_offset;
-static inline unsigned long kaslr_offset(void)
-{
- return __kaslr_offset;
-}
-
-extern int __kaslr_enabled;
-static inline int kaslr_enabled(void)
-{
- if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
- return __kaslr_enabled;
- return 0;
-}
-
struct oldmem_data {
unsigned long start;
unsigned long size;
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 6e5b1b4b19a9..cd835f4fb11a 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -11,7 +11,7 @@
#include <asm/lowcore.h>
#include <asm/processor.h>
-#define raw_smp_processor_id() (S390_lowcore.cpu_nr)
+#define raw_smp_processor_id() (get_lowcore()->cpu_nr)
extern struct mutex smp_cpu_state_mutex;
extern unsigned int smp_cpu_mt_shift;
@@ -24,7 +24,6 @@ extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
-extern void smp_call_online_cpu(void (*func)(void *), void *);
extern void smp_call_ipl_cpu(void (*func)(void *), void *);
extern void smp_emergency_stop(void);
@@ -59,7 +58,7 @@ static inline void smp_cpus_done(unsigned int max_cpus)
{
}
-extern int smp_rescan_cpus(void);
+extern int smp_rescan_cpus(bool early);
extern void __noreturn cpu_die(void);
extern void __cpu_die(unsigned int cpu);
extern int __cpu_disable(void);
diff --git a/arch/s390/include/asm/softirq_stack.h b/arch/s390/include/asm/softirq_stack.h
index 1ac5115d3115..42d61296bbad 100644
--- a/arch/s390/include/asm/softirq_stack.h
+++ b/arch/s390/include/asm/softirq_stack.h
@@ -8,7 +8,7 @@
#ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
static inline void do_softirq_own_stack(void)
{
- call_on_stack(0, S390_lowcore.async_stack, void, __do_softirq);
+ call_on_stack(0, get_lowcore()->async_stack, void, __do_softirq);
}
#endif
#endif /* __ASM_S390_SOFTIRQ_STACK_H */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index 37127cd7749e..77d5e804af93 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -16,7 +16,7 @@
#include <asm/processor.h>
#include <asm/alternative.h>
-#define SPINLOCK_LOCKVAL (S390_lowcore.spinlock_lockval)
+#define SPINLOCK_LOCKVAL (get_lowcore()->spinlock_lockval)
extern int spin_retry;
@@ -79,7 +79,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp)
typecheck(int, lp->lock);
kcsan_release();
asm_inline volatile(
- ALTERNATIVE("nop", ".insn rre,0xb2fa0000,7,0", 49) /* NIAI 7 */
+ ALTERNATIVE("nop", ".insn rre,0xb2fa0000,7,0", ALT_FACILITY(49)) /* NIAI 7 */
" sth %1,%0\n"
: "=R" (((unsigned short *) &lp->lock)[1])
: "d" (0) : "cc", "memory");
diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h
index 433fde85b14e..1d5ca13dc90f 100644
--- a/arch/s390/include/asm/stacktrace.h
+++ b/arch/s390/include/asm/stacktrace.h
@@ -2,6 +2,7 @@
#ifndef _ASM_S390_STACKTRACE_H
#define _ASM_S390_STACKTRACE_H
+#include <linux/stacktrace.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>
@@ -12,6 +13,17 @@ struct stack_frame_user {
unsigned long empty2[4];
};
+struct stack_frame_vdso_wrapper {
+ struct stack_frame_user sf;
+ unsigned long return_address;
+};
+
+struct perf_callchain_entry_ctx;
+
+void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie,
+ struct perf_callchain_entry_ctx *entry,
+ const struct pt_regs *regs, bool perf);
+
enum stack_type {
STACK_TYPE_UNKNOWN,
STACK_TYPE_TASK,
@@ -53,6 +65,7 @@ struct stack_frame {
unsigned long sie_reason;
unsigned long sie_flags;
unsigned long sie_control_block_phys;
+ unsigned long sie_guest_asce;
};
};
unsigned long gprs[10];
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index 351685de53d2..2ab868cbae6c 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -15,15 +15,12 @@
#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
#define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */
#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
-#define __HAVE_ARCH_MEMSET16 /* arch function */
-#define __HAVE_ARCH_MEMSET32 /* arch function */
-#define __HAVE_ARCH_MEMSET64 /* arch function */
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
void *memmove(void *dest, const void *src, size_t n);
-#ifndef CONFIG_KASAN
+#if !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN)
#define __HAVE_ARCH_MEMCHR /* inline & arch function */
#define __HAVE_ARCH_MEMCMP /* arch function */
#define __HAVE_ARCH_MEMSCAN /* inline & arch function */
@@ -36,6 +33,9 @@ void *memmove(void *dest, const void *src, size_t n);
#define __HAVE_ARCH_STRNCPY /* arch function */
#define __HAVE_ARCH_STRNLEN /* inline & arch function */
#define __HAVE_ARCH_STRSTR /* arch function */
+#define __HAVE_ARCH_MEMSET16 /* arch function */
+#define __HAVE_ARCH_MEMSET32 /* arch function */
+#define __HAVE_ARCH_MEMSET64 /* arch function */
/* Prototypes for non-inlined arch strings functions. */
int memcmp(const void *s1, const void *s2, size_t n);
@@ -44,7 +44,7 @@ size_t strlcat(char *dest, const char *src, size_t n);
char *strncat(char *dest, const char *src, size_t n);
char *strncpy(char *dest, const char *src, size_t n);
char *strstr(const char *s1, const char *s2);
-#endif /* !CONFIG_KASAN */
+#endif /* !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN) */
#undef __HAVE_ARCH_STRCHR
#undef __HAVE_ARCH_STRNCHR
@@ -74,20 +74,30 @@ void *__memset16(uint16_t *s, uint16_t v, size_t count);
void *__memset32(uint32_t *s, uint32_t v, size_t count);
void *__memset64(uint64_t *s, uint64_t v, size_t count);
+#ifdef __HAVE_ARCH_MEMSET16
static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
{
return __memset16(s, v, count * sizeof(v));
}
+#endif
+#ifdef __HAVE_ARCH_MEMSET32
static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
{
return __memset32(s, v, count * sizeof(v));
}
+#endif
+#ifdef __HAVE_ARCH_MEMSET64
+#ifdef IN_BOOT_STRING_C
+void *memset64(uint64_t *s, uint64_t v, size_t count);
+#else
static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
{
return __memset64(s, v, count * sizeof(v));
}
+#endif
+#endif
#if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index a674c7d25da5..00ac01874a12 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -16,7 +16,7 @@
/*
* General size of kernel stacks
*/
-#ifdef CONFIG_KASAN
+#if defined(CONFIG_KASAN) || defined(CONFIG_KMSAN)
#define THREAD_SIZE_ORDER 4
#else
#define THREAD_SIZE_ORDER 2
@@ -40,6 +40,7 @@ struct thread_info {
unsigned long flags; /* low level flags */
unsigned long syscall_work; /* SYSCALL_WORK_ flags */
unsigned int cpu; /* current CPU */
+ unsigned char sie; /* running in SIE context */
};
/*
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
index 4d646659a5f5..640901f2fbc3 100644
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -161,16 +161,16 @@ static inline unsigned long local_tick_disable(void)
{
unsigned long old;
- old = S390_lowcore.clock_comparator;
- S390_lowcore.clock_comparator = clock_comparator_max;
- set_clock_comparator(S390_lowcore.clock_comparator);
+ old = get_lowcore()->clock_comparator;
+ get_lowcore()->clock_comparator = clock_comparator_max;
+ set_clock_comparator(get_lowcore()->clock_comparator);
return old;
}
static inline void local_tick_enable(unsigned long comp)
{
- S390_lowcore.clock_comparator = comp;
- set_clock_comparator(S390_lowcore.clock_comparator);
+ get_lowcore()->clock_comparator = comp;
+ set_clock_comparator(get_lowcore()->clock_comparator);
}
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 81ae8a98e7ec..a81f897a81ce 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -18,6 +18,7 @@
#include <asm/extable.h>
#include <asm/facility.h>
#include <asm-generic/access_ok.h>
+#include <linux/instrumented.h>
void debug_user_asce(int exit);
@@ -78,13 +79,24 @@ union oac {
int __noreturn __put_user_bad(void);
-#define __put_user_asm(to, from, size) \
-({ \
+#ifdef CONFIG_KMSAN
+#define get_put_user_noinstr_attributes \
+ noinline __maybe_unused __no_sanitize_memory
+#else
+#define get_put_user_noinstr_attributes __always_inline
+#endif
+
+#define DEFINE_PUT_USER(type) \
+static get_put_user_noinstr_attributes int \
+__put_user_##type##_noinstr(unsigned type __user *to, \
+ unsigned type *from, \
+ unsigned long size) \
+{ \
union oac __oac_spec = { \
.oac1.as = PSW_BITS_AS_SECONDARY, \
.oac1.a = 1, \
}; \
- int __rc; \
+ int rc; \
\
asm volatile( \
" lr 0,%[spec]\n" \
@@ -93,12 +105,28 @@ int __noreturn __put_user_bad(void);
"2:\n" \
EX_TABLE_UA_STORE(0b, 2b, %[rc]) \
EX_TABLE_UA_STORE(1b, 2b, %[rc]) \
- : [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
+ : [rc] "=&d" (rc), [_to] "+Q" (*(to)) \
: [_size] "d" (size), [_from] "Q" (*(from)), \
[spec] "d" (__oac_spec.val) \
: "cc", "0"); \
- __rc; \
-})
+ return rc; \
+} \
+ \
+static __always_inline int \
+__put_user_##type(unsigned type __user *to, unsigned type *from, \
+ unsigned long size) \
+{ \
+ int rc; \
+ \
+ rc = __put_user_##type##_noinstr(to, from, size); \
+ instrument_put_user(*from, to, size); \
+ return rc; \
+}
+
+DEFINE_PUT_USER(char);
+DEFINE_PUT_USER(short);
+DEFINE_PUT_USER(int);
+DEFINE_PUT_USER(long);
static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
{
@@ -106,24 +134,24 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon
switch (size) {
case 1:
- rc = __put_user_asm((unsigned char __user *)ptr,
- (unsigned char *)x,
- size);
+ rc = __put_user_char((unsigned char __user *)ptr,
+ (unsigned char *)x,
+ size);
break;
case 2:
- rc = __put_user_asm((unsigned short __user *)ptr,
- (unsigned short *)x,
- size);
+ rc = __put_user_short((unsigned short __user *)ptr,
+ (unsigned short *)x,
+ size);
break;
case 4:
- rc = __put_user_asm((unsigned int __user *)ptr,
+ rc = __put_user_int((unsigned int __user *)ptr,
(unsigned int *)x,
size);
break;
case 8:
- rc = __put_user_asm((unsigned long __user *)ptr,
- (unsigned long *)x,
- size);
+ rc = __put_user_long((unsigned long __user *)ptr,
+ (unsigned long *)x,
+ size);
break;
default:
__put_user_bad();
@@ -134,13 +162,17 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon
int __noreturn __get_user_bad(void);
-#define __get_user_asm(to, from, size) \
-({ \
+#define DEFINE_GET_USER(type) \
+static get_put_user_noinstr_attributes int \
+__get_user_##type##_noinstr(unsigned type *to, \
+ unsigned type __user *from, \
+ unsigned long size) \
+{ \
union oac __oac_spec = { \
.oac2.as = PSW_BITS_AS_SECONDARY, \
.oac2.a = 1, \
}; \
- int __rc; \
+ int rc; \
\
asm volatile( \
" lr 0,%[spec]\n" \
@@ -149,13 +181,29 @@ int __noreturn __get_user_bad(void);
"2:\n" \
EX_TABLE_UA_LOAD_MEM(0b, 2b, %[rc], %[_to], %[_ksize]) \
EX_TABLE_UA_LOAD_MEM(1b, 2b, %[rc], %[_to], %[_ksize]) \
- : [rc] "=&d" (__rc), "=Q" (*(to)) \
+ : [rc] "=&d" (rc), "=Q" (*(to)) \
: [_size] "d" (size), [_from] "Q" (*(from)), \
[spec] "d" (__oac_spec.val), [_to] "a" (to), \
[_ksize] "K" (size) \
: "cc", "0"); \
- __rc; \
-})
+ return rc; \
+} \
+ \
+static __always_inline int \
+__get_user_##type(unsigned type *to, unsigned type __user *from, \
+ unsigned long size) \
+{ \
+ int rc; \
+ \
+ rc = __get_user_##type##_noinstr(to, from, size); \
+ instrument_get_user(*to); \
+ return rc; \
+}
+
+DEFINE_GET_USER(char);
+DEFINE_GET_USER(short);
+DEFINE_GET_USER(int);
+DEFINE_GET_USER(long);
static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
{
@@ -163,24 +211,24 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign
switch (size) {
case 1:
- rc = __get_user_asm((unsigned char *)x,
- (unsigned char __user *)ptr,
- size);
+ rc = __get_user_char((unsigned char *)x,
+ (unsigned char __user *)ptr,
+ size);
break;
case 2:
- rc = __get_user_asm((unsigned short *)x,
- (unsigned short __user *)ptr,
- size);
+ rc = __get_user_short((unsigned short *)x,
+ (unsigned short __user *)ptr,
+ size);
break;
case 4:
- rc = __get_user_asm((unsigned int *)x,
+ rc = __get_user_int((unsigned int *)x,
(unsigned int __user *)ptr,
size);
break;
case 8:
- rc = __get_user_asm((unsigned long *)x,
- (unsigned long __user *)ptr,
- size);
+ rc = __get_user_long((unsigned long *)x,
+ (unsigned long __user *)ptr,
+ size);
break;
default:
__get_user_bad();
@@ -284,7 +332,14 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo
return __clear_user(to, n);
}
-void *s390_kernel_write(void *dst, const void *src, size_t size);
+void *__s390_kernel_write(void *dst, const void *src, size_t size);
+
+static inline void *s390_kernel_write(void *dst, const void *src, size_t size)
+{
+ if (__is_defined(__DECOMPRESSOR))
+ return memcpy(dst, src, size);
+ return __s390_kernel_write(dst, src, size);
+}
int __noreturn __put_kernel_bad(void);
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 4260bc5ce7f8..70fc671397da 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -35,6 +35,5 @@
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
#endif /* _ASM_S390_UNISTD_H_ */
diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
index 0e7bd3873907..0b5f8f3e84f1 100644
--- a/arch/s390/include/asm/uv.h
+++ b/arch/s390/include/asm/uv.h
@@ -414,7 +414,6 @@ static inline bool uv_has_feature(u8 feature_bit)
return test_bit_inv(feature_bit, &uv_info.uv_feature_indications);
}
-#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
extern int prot_virt_guest;
static inline int is_prot_virt_guest(void)
@@ -466,13 +465,6 @@ static inline int uv_remove_shared(unsigned long addr)
return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS);
}
-#else
-#define is_prot_virt_guest() 0
-static inline int uv_set_shared(unsigned long addr) { return 0; }
-static inline int uv_remove_shared(unsigned long addr) { return 0; }
-#endif
-
-#if IS_ENABLED(CONFIG_KVM)
extern int prot_virt_host;
static inline int is_prot_virt_host(void)
@@ -483,35 +475,11 @@ static inline int is_prot_virt_host(void)
int uv_pin_shared(unsigned long paddr);
int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb);
int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr);
-int uv_destroy_owned_page(unsigned long paddr);
-int uv_convert_from_secure(unsigned long paddr);
-int uv_convert_owned_from_secure(unsigned long paddr);
+int uv_destroy_folio(struct folio *folio);
+int uv_destroy_pte(pte_t pte);
+int uv_convert_from_secure_pte(pte_t pte);
int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr);
void setup_uv(void);
-#else
-#define is_prot_virt_host() 0
-static inline void setup_uv(void) {}
-
-static inline int uv_pin_shared(unsigned long paddr)
-{
- return 0;
-}
-
-static inline int uv_destroy_owned_page(unsigned long paddr)
-{
- return 0;
-}
-
-static inline int uv_convert_from_secure(unsigned long paddr)
-{
- return 0;
-}
-
-static inline int uv_convert_owned_from_secure(unsigned long paddr)
-{
- return 0;
-}
-#endif
#endif /* _ASM_S390_UV_H */
diff --git a/arch/s390/include/asm/vdso/gettimeofday.h b/arch/s390/include/asm/vdso/gettimeofday.h
index db84942eb78f..7937765ccfa5 100644
--- a/arch/s390/include/asm/vdso/gettimeofday.h
+++ b/arch/s390/include/asm/vdso/gettimeofday.h
@@ -6,16 +6,13 @@
#define VDSO_HAS_CLOCK_GETRES 1
+#define VDSO_DELTA_NOMASK 1
+
#include <asm/syscall.h>
#include <asm/timex.h>
#include <asm/unistd.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)
{
diff --git a/arch/s390/include/asm/vtime.h b/arch/s390/include/asm/vtime.h
index fe17e448c0c5..9d25fb35a042 100644
--- a/arch/s390/include/asm/vtime.h
+++ b/arch/s390/include/asm/vtime.h
@@ -2,20 +2,22 @@
#ifndef _S390_VTIME_H
#define _S390_VTIME_H
-#define __ARCH_HAS_VTIME_TASK_SWITCH
-
static inline void update_timer_sys(void)
{
- S390_lowcore.system_timer += S390_lowcore.last_update_timer - S390_lowcore.exit_timer;
- S390_lowcore.user_timer += S390_lowcore.exit_timer - S390_lowcore.sys_enter_timer;
- S390_lowcore.last_update_timer = S390_lowcore.sys_enter_timer;
+ struct lowcore *lc = get_lowcore();
+
+ lc->system_timer += lc->last_update_timer - lc->exit_timer;
+ lc->user_timer += lc->exit_timer - lc->sys_enter_timer;
+ lc->last_update_timer = lc->sys_enter_timer;
}
static inline void update_timer_mcck(void)
{
- S390_lowcore.system_timer += S390_lowcore.last_update_timer - S390_lowcore.exit_timer;
- S390_lowcore.user_timer += S390_lowcore.exit_timer - S390_lowcore.mcck_enter_timer;
- S390_lowcore.last_update_timer = S390_lowcore.mcck_enter_timer;
+ struct lowcore *lc = get_lowcore();
+
+ lc->system_timer += lc->last_update_timer - lc->exit_timer;
+ lc->user_timer += lc->exit_timer - lc->mcck_enter_timer;
+ lc->last_update_timer = lc->mcck_enter_timer;
}
#endif /* _S390_VTIME_H */
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index fa029d0dc28f..e47a4be54ff8 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -11,6 +11,8 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
# Do not trace early setup code
CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_stacktrace.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_unwind_bc.o = $(CC_FLAGS_FTRACE)
endif
@@ -41,7 +43,7 @@ obj-y += sysinfo.o lgr.o os_info.o ctlreg.o
obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o
obj-y += entry.o reipl.o kdebugfs.o alternative.o
obj-y += nospec-branch.o ipl_vmparm.o machine_kexec_reloc.o unwind_bc.o
-obj-y += smp.o text_amode31.o stacktrace.o abs_lowcore.o facility.o
+obj-y += smp.o text_amode31.o stacktrace.o abs_lowcore.o facility.o uv.o
extra-y += vmlinux.lds
@@ -57,7 +59,6 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o
obj-$(CONFIG_COMPAT) += $(compat-obj-y)
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KPROBES) += kprobes.o
-obj-$(CONFIG_KPROBES) += kprobes_insn_page.o
obj-$(CONFIG_KPROBES) += mcount.o
obj-$(CONFIG_RETHOOK) += rethook.o
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
@@ -79,7 +80,6 @@ obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o
obj-$(CONFIG_PERF_EVENTS) += perf_pai_crypto.o perf_pai_ext.o
obj-$(CONFIG_TRACEPOINTS) += trace.o
-obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
# vdso
obj-y += vdso64/
diff --git a/arch/s390/kernel/abs_lowcore.c b/arch/s390/kernel/abs_lowcore.c
index f9efc54ec4b7..09cd24cbe74e 100644
--- a/arch/s390/kernel/abs_lowcore.c
+++ b/arch/s390/kernel/abs_lowcore.c
@@ -4,6 +4,7 @@
#include <asm/abs_lowcore.h>
unsigned long __bootdata_preserved(__abs_lowcore);
+int __bootdata_preserved(relocate_lowcore);
int abs_lowcore_map(int cpu, struct lowcore *lc, bool alloc)
{
diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c
index e7bca29f9c34..8d5d0de35de0 100644
--- a/arch/s390/kernel/alternative.c
+++ b/arch/s390/kernel/alternative.c
@@ -1,75 +1,41 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <asm/text-patching.h>
+
+#include <linux/uaccess.h>
+#include <asm/nospec-branch.h>
+#include <asm/abs_lowcore.h>
#include <asm/alternative.h>
#include <asm/facility.h>
-#include <asm/nospec-branch.h>
-static int __initdata_or_module alt_instr_disabled;
-
-static int __init disable_alternative_instructions(char *str)
+void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsigned int ctx)
{
- alt_instr_disabled = 1;
- return 0;
-}
-
-early_param("noaltinstr", disable_alternative_instructions);
-
-static void __init_or_module __apply_alternatives(struct alt_instr *start,
- struct alt_instr *end)
-{
- struct alt_instr *a;
u8 *instr, *replacement;
+ struct alt_instr *a;
+ bool replace;
/*
* The scan order should be from start to end. A later scanned
* alternative code can overwrite previously scanned alternative code.
*/
for (a = start; a < end; a++) {
- instr = (u8 *)&a->instr_offset + a->instr_offset;
- replacement = (u8 *)&a->repl_offset + a->repl_offset;
-
- if (!__test_facility(a->facility, alt_stfle_fac_list))
- continue;
-
- if (unlikely(a->instrlen % 2)) {
- WARN_ONCE(1, "cpu alternatives instructions length is "
- "odd, skipping patching\n");
+ if (!(a->ctx & ctx))
continue;
+ switch (a->type) {
+ case ALT_TYPE_FACILITY:
+ replace = test_facility(a->data);
+ break;
+ case ALT_TYPE_SPEC:
+ replace = nobp_enabled();
+ break;
+ case ALT_TYPE_LOWCORE:
+ replace = have_relocated_lowcore();
+ break;
+ default:
+ replace = false;
}
-
+ if (!replace)
+ continue;
+ instr = (u8 *)&a->instr_offset + a->instr_offset;
+ replacement = (u8 *)&a->repl_offset + a->repl_offset;
s390_kernel_write(instr, replacement, a->instrlen);
}
}
-
-void __init_or_module apply_alternatives(struct alt_instr *start,
- struct alt_instr *end)
-{
- if (!alt_instr_disabled)
- __apply_alternatives(start, end);
-}
-
-extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-void __init apply_alternative_instructions(void)
-{
- apply_alternatives(__alt_instructions, __alt_instructions_end);
-}
-
-static void do_sync_core(void *info)
-{
- sync_core();
-}
-
-void text_poke_sync(void)
-{
- on_each_cpu(do_sync_core, NULL, 1);
-}
-
-void text_poke_sync_lock(void)
-{
- cpus_read_lock();
- text_poke_sync();
- cpus_read_unlock();
-}
diff --git a/arch/s390/kernel/alternative.h b/arch/s390/kernel/alternative.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/arch/s390/kernel/alternative.h
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index fa5f6885c74a..ffa0dd2dbaac 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -13,7 +13,6 @@
#include <linux/purgatory.h>
#include <linux/pgtable.h>
#include <linux/ftrace.h>
-#include <asm/idle.h>
#include <asm/gmap.h>
#include <asm/stacktrace.h>
@@ -29,6 +28,7 @@ int main(void)
BLANK();
/* thread info offsets */
OFFSET(__TI_flags, task_struct, thread_info.flags);
+ OFFSET(__TI_sie, task_struct, thread_info.sie);
BLANK();
/* pt_regs offsets */
OFFSET(__PT_PSW, pt_regs, psw);
@@ -64,12 +64,13 @@ int main(void)
OFFSET(__SF_SIE_REASON, stack_frame, sie_reason);
OFFSET(__SF_SIE_FLAGS, stack_frame, sie_flags);
OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys);
+ OFFSET(__SF_SIE_GUEST_ASCE, stack_frame, sie_guest_asce);
DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame));
BLANK();
- /* idle data offsets */
- OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter);
- OFFSET(__TIMER_IDLE_ENTER, s390_idle_data, timer_idle_enter);
- OFFSET(__MT_CYCLES_ENTER, s390_idle_data, mt_cycles_enter);
+ OFFSET(__SFUSER_BACKCHAIN, stack_frame_user, back_chain);
+ DEFINE(STACK_FRAME_USER_OVERHEAD, sizeof(struct stack_frame_user));
+ OFFSET(__SFVDSO_RETURN_ADDRESS, stack_frame_vdso_wrapper, return_address);
+ DEFINE(STACK_FRAME_VDSO_OVERHEAD, sizeof(struct stack_frame_vdso_wrapper));
BLANK();
/* hardware defined lowcore locations 0x000 - 0x1ff */
OFFSET(__LC_EXT_PARAMS, lowcore, ext_params);
@@ -114,7 +115,7 @@ int main(void)
OFFSET(__LC_SAVE_AREA_SYNC, lowcore, save_area_sync);
OFFSET(__LC_SAVE_AREA_ASYNC, lowcore, save_area_async);
OFFSET(__LC_SAVE_AREA_RESTART, lowcore, save_area_restart);
- OFFSET(__LC_CPU_FLAGS, lowcore, cpu_flags);
+ OFFSET(__LC_PCPU, lowcore, pcpu);
OFFSET(__LC_RETURN_PSW, lowcore, return_psw);
OFFSET(__LC_RETURN_MCCK_PSW, lowcore, return_mcck_psw);
OFFSET(__LC_SYS_ENTER_TIMER, lowcore, sys_enter_timer);
@@ -186,5 +187,7 @@ int main(void)
#endif
OFFSET(__FTRACE_REGS_PT_REGS, ftrace_regs, regs);
DEFINE(__FTRACE_REGS_SIZE, sizeof(struct ftrace_regs));
+
+ OFFSET(__PCPU_FLAGS, pcpu, flags);
return 0;
}
diff --git a/arch/s390/kernel/cert_store.c b/arch/s390/kernel/cert_store.c
index 554447768bdd..bf983513dd33 100644
--- a/arch/s390/kernel/cert_store.c
+++ b/arch/s390/kernel/cert_store.c
@@ -21,6 +21,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
+#include <linux/vmalloc.h>
#include <crypto/sha2.h>
#include <keys/user-type.h>
#include <asm/debug.h>
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index d09ebb6f5262..edae13416196 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -451,7 +451,7 @@ static void *nt_final(void *ptr)
/*
* Initialize ELF header (new kernel)
*/
-static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt)
+static void *ehdr_init(Elf64_Ehdr *ehdr, int phdr_count)
{
memset(ehdr, 0, sizeof(*ehdr));
memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
@@ -465,7 +465,8 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt)
ehdr->e_phoff = sizeof(Elf64_Ehdr);
ehdr->e_ehsize = sizeof(Elf64_Ehdr);
ehdr->e_phentsize = sizeof(Elf64_Phdr);
- ehdr->e_phnum = mem_chunk_cnt + 1;
+ /* Number of PT_LOAD program headers plus PT_NOTE program header */
+ ehdr->e_phnum = phdr_count + 1;
return ehdr + 1;
}
@@ -499,17 +500,20 @@ static int get_mem_chunk_cnt(void)
/*
* Initialize ELF loads (new kernel)
*/
-static void loads_init(Elf64_Phdr *phdr)
+static void loads_init(Elf64_Phdr *phdr, bool os_info_has_vm)
{
+ unsigned long old_identity_base = 0;
phys_addr_t start, end;
u64 idx;
+ if (os_info_has_vm)
+ old_identity_base = os_info_old_value(OS_INFO_IDENTITY_BASE);
for_each_physmem_range(idx, &oldmem_type, &start, &end) {
- phdr->p_filesz = end - start;
phdr->p_type = PT_LOAD;
+ phdr->p_vaddr = old_identity_base + start;
phdr->p_offset = start;
- phdr->p_vaddr = (unsigned long)__va(start);
phdr->p_paddr = start;
+ phdr->p_filesz = end - start;
phdr->p_memsz = end - start;
phdr->p_flags = PF_R | PF_W | PF_X;
phdr->p_align = PAGE_SIZE;
@@ -517,6 +521,30 @@ static void loads_init(Elf64_Phdr *phdr)
}
}
+static bool os_info_has_vm(void)
+{
+ return os_info_old_value(OS_INFO_KASLR_OFFSET);
+}
+
+/*
+ * Prepare PT_LOAD type program header for kernel image region
+ */
+static void text_init(Elf64_Phdr *phdr)
+{
+ unsigned long start_phys = os_info_old_value(OS_INFO_IMAGE_PHYS);
+ unsigned long start = os_info_old_value(OS_INFO_IMAGE_START);
+ unsigned long end = os_info_old_value(OS_INFO_IMAGE_END);
+
+ phdr->p_type = PT_LOAD;
+ phdr->p_vaddr = start;
+ phdr->p_filesz = end - start;
+ phdr->p_memsz = end - start;
+ phdr->p_offset = start_phys;
+ phdr->p_paddr = start_phys;
+ phdr->p_flags = PF_R | PF_W | PF_X;
+ phdr->p_align = PAGE_SIZE;
+}
+
/*
* Initialize notes (new kernel)
*/
@@ -542,7 +570,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
return ptr;
}
-static size_t get_elfcorehdr_size(int mem_chunk_cnt)
+static size_t get_elfcorehdr_size(int phdr_count)
{
size_t size;
@@ -558,7 +586,7 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
/* nt_final */
size += sizeof(Elf64_Nhdr);
/* PT_LOADS */
- size += mem_chunk_cnt * sizeof(Elf64_Phdr);
+ size += phdr_count * sizeof(Elf64_Phdr);
return size;
}
@@ -568,9 +596,9 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
*/
int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
{
- Elf64_Phdr *phdr_notes, *phdr_loads;
+ Elf64_Phdr *phdr_notes, *phdr_loads, *phdr_text;
+ int mem_chunk_cnt, phdr_text_cnt;
size_t alloc_size;
- int mem_chunk_cnt;
void *ptr, *hdr;
u64 hdr_off;
@@ -589,12 +617,14 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
}
mem_chunk_cnt = get_mem_chunk_cnt();
+ phdr_text_cnt = os_info_has_vm() ? 1 : 0;
- alloc_size = get_elfcorehdr_size(mem_chunk_cnt);
+ alloc_size = get_elfcorehdr_size(mem_chunk_cnt + phdr_text_cnt);
hdr = kzalloc(alloc_size, GFP_KERNEL);
- /* Without elfcorehdr /proc/vmcore cannot be created. Thus creating
+ /*
+ * Without elfcorehdr /proc/vmcore cannot be created. Thus creating
* a dump with this crash kernel will fail. Panic now to allow other
* dump mechanisms to take over.
*/
@@ -602,18 +632,25 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
panic("s390 kdump allocating elfcorehdr failed");
/* Init elf header */
- ptr = ehdr_init(hdr, mem_chunk_cnt);
+ phdr_notes = ehdr_init(hdr, mem_chunk_cnt + phdr_text_cnt);
/* Init program headers */
- phdr_notes = ptr;
- ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr));
- phdr_loads = ptr;
- ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr) * mem_chunk_cnt);
+ if (phdr_text_cnt) {
+ phdr_text = phdr_notes + 1;
+ phdr_loads = phdr_text + 1;
+ } else {
+ phdr_loads = phdr_notes + 1;
+ }
+ ptr = PTR_ADD(phdr_loads, sizeof(Elf64_Phdr) * mem_chunk_cnt);
/* Init notes */
hdr_off = PTR_DIFF(ptr, hdr);
ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off);
+ /* Init kernel text program header */
+ if (phdr_text_cnt)
+ text_init(phdr_text);
/* Init loads */
+ loads_init(phdr_loads, phdr_text_cnt);
+ /* Finalize program headers */
hdr_off = PTR_DIFF(ptr, hdr);
- loads_init(phdr_loads);
*addr = (unsigned long long) hdr;
*size = (unsigned long long) hdr_off;
BUG_ON(elfcorehdr_size > alloc_size);
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 85328a0ef3b6..bce50ca75ea7 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -954,7 +954,7 @@ static int debug_active = 1;
* always allow read, allow write only if debug_stoppable is set or
* if debug_active is already off
*/
-static int s390dbf_procactive(struct ctl_table *table, int write,
+static int s390dbf_procactive(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
if (!write || debug_stoppable || !debug_active)
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index 8dee9aa0ec95..ac7b8c8e3133 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -185,6 +185,8 @@ int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
}
EXPORT_SYMBOL(diag14);
+#define DIAG204_BUSY_RC 8
+
static inline int __diag204(unsigned long *subcode, unsigned long size, void *addr)
{
union register_pair rp = { .even = *subcode, .odd = size };
@@ -215,16 +217,18 @@ int diag204(unsigned long subcode, unsigned long size, void *addr)
{
if (addr) {
if (WARN_ON_ONCE(!is_vmalloc_addr(addr)))
- return -1;
+ return -EINVAL;
if (WARN_ON_ONCE(!IS_ALIGNED((unsigned long)addr, PAGE_SIZE)))
- return -1;
+ return -EINVAL;
}
if ((subcode & DIAG204_SUBCODE_MASK) == DIAG204_SUBC_STIB4)
addr = (void *)pfn_to_phys(vmalloc_to_pfn(addr));
diag_stat_inc(DIAG_STAT_X204);
size = __diag204(&subcode, size, addr);
- if (subcode)
- return -1;
+ if (subcode == DIAG204_BUSY_RC)
+ return -EBUSY;
+ else if (subcode)
+ return -EOPNOTSUPP;
return size;
}
EXPORT_SYMBOL(diag204);
@@ -278,12 +282,14 @@ int diag224(void *ptr)
int rc = -EOPNOTSUPP;
diag_stat_inc(DIAG_STAT_X224);
- asm volatile(
- " diag %1,%2,0x224\n"
- "0: lhi %0,0x0\n"
+ asm volatile("\n"
+ " diag %[type],%[addr],0x224\n"
+ "0: lhi %[rc],0\n"
"1:\n"
EX_TABLE(0b,1b)
- : "+d" (rc) :"d" (0), "d" (addr) : "memory");
+ : [rc] "+d" (rc)
+ , "=m" (*(struct { char buf[PAGE_SIZE]; } *)ptr)
+ : [type] "d" (0), [addr] "d" (addr));
return rc;
}
EXPORT_SYMBOL(diag224);
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index d2012635b093..1ecd0580561f 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -61,28 +61,28 @@ static bool in_task_stack(unsigned long sp, struct task_struct *task,
static bool in_irq_stack(unsigned long sp, struct stack_info *info)
{
- unsigned long stack = S390_lowcore.async_stack - STACK_INIT_OFFSET;
+ unsigned long stack = get_lowcore()->async_stack - STACK_INIT_OFFSET;
return in_stack(sp, info, STACK_TYPE_IRQ, stack);
}
static bool in_nodat_stack(unsigned long sp, struct stack_info *info)
{
- unsigned long stack = S390_lowcore.nodat_stack - STACK_INIT_OFFSET;
+ unsigned long stack = get_lowcore()->nodat_stack - STACK_INIT_OFFSET;
return in_stack(sp, info, STACK_TYPE_NODAT, stack);
}
static bool in_mcck_stack(unsigned long sp, struct stack_info *info)
{
- unsigned long stack = S390_lowcore.mcck_stack - STACK_INIT_OFFSET;
+ unsigned long stack = get_lowcore()->mcck_stack - STACK_INIT_OFFSET;
return in_stack(sp, info, STACK_TYPE_MCCK, stack);
}
static bool in_restart_stack(unsigned long sp, struct stack_info *info)
{
- unsigned long stack = S390_lowcore.restart_stack - STACK_INIT_OFFSET;
+ unsigned long stack = get_lowcore()->restart_stack - STACK_INIT_OFFSET;
return in_stack(sp, info, STACK_TYPE_RESTART, stack);
}
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c666271433fb..14d324865e33 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -48,6 +48,7 @@ decompressor_handled_param(dfltcc);
decompressor_handled_param(facilities);
decompressor_handled_param(nokaslr);
decompressor_handled_param(cmma);
+decompressor_handled_param(relocate_lowcore);
#if IS_ENABLED(CONFIG_KVM)
decompressor_handled_param(prot_virt);
#endif
@@ -72,7 +73,7 @@ static void __init reset_tod_clock(void)
memset(&tod_clock_base, 0, sizeof(tod_clock_base));
tod_clock_base.tod = TOD_UNIX_EPOCH;
- S390_lowcore.last_update_clock = TOD_UNIX_EPOCH;
+ get_lowcore()->last_update_clock = TOD_UNIX_EPOCH;
}
/*
@@ -99,7 +100,7 @@ static noinline __init void detect_machine_type(void)
/* Check current-configuration-level */
if (stsi(NULL, 0, 0, 0) <= 2) {
- S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_LPAR;
return;
}
/* Get virtual-machine cpu information. */
@@ -108,9 +109,9 @@ static noinline __init void detect_machine_type(void)
/* Detect known hypervisors */
if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
- S390_lowcore.machine_flags |= MACHINE_FLAG_KVM;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_KVM;
else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4))
- S390_lowcore.machine_flags |= MACHINE_FLAG_VM;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_VM;
}
/* Remove leading, trailing and double whitespace. */
@@ -166,7 +167,7 @@ static __init void setup_topology(void)
if (!test_facility(11))
return;
- S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_TOPOLOGY;
for (max_mnest = 6; max_mnest > 1; max_mnest--) {
if (stsi(&sysinfo_page, 15, 1, max_mnest) == 0)
break;
@@ -186,15 +187,8 @@ static noinline __init void setup_lowcore_early(void)
psw.addr = (unsigned long)early_pgm_check_handler;
psw.mask = PSW_KERNEL_BITS;
- S390_lowcore.program_new_psw = psw;
- S390_lowcore.preempt_count = INIT_PREEMPT_COUNT;
-}
-
-static noinline __init void setup_facility_list(void)
-{
- memcpy(alt_stfle_fac_list, stfle_fac_list, sizeof(alt_stfle_fac_list));
- if (!IS_ENABLED(CONFIG_KERNEL_NOBP))
- __clear_facility(82, alt_stfle_fac_list);
+ get_lowcore()->program_new_psw = psw;
+ get_lowcore()->preempt_count = INIT_PREEMPT_COUNT;
}
static __init void detect_diag9c(void)
@@ -211,43 +205,43 @@ static __init void detect_diag9c(void)
EX_TABLE(0b,1b)
: "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc");
if (!rc)
- S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_DIAG9C;
}
static __init void detect_machine_facilities(void)
{
if (test_facility(8)) {
- S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT1;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT1;
system_ctl_set_bit(0, CR0_EDAT_BIT);
}
if (test_facility(78))
- S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT2;
if (test_facility(3))
- S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_IDTE;
if (test_facility(50) && test_facility(73)) {
- S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_TE;
system_ctl_set_bit(0, CR0_TRANSACTIONAL_EXECUTION_BIT);
}
if (test_facility(51))
- S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_TLB_LC;
if (test_facility(129))
system_ctl_set_bit(0, CR0_VECTOR_BIT);
if (test_facility(130))
- S390_lowcore.machine_flags |= MACHINE_FLAG_NX;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_NX;
if (test_facility(133))
- S390_lowcore.machine_flags |= MACHINE_FLAG_GS;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_GS;
if (test_facility(139) && (tod_clock_base.tod >> 63)) {
/* Enabled signed clock comparator comparisons */
- S390_lowcore.machine_flags |= MACHINE_FLAG_SCC;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_SCC;
clock_comparator_max = -1ULL >> 1;
system_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SIGN_BIT);
}
if (IS_ENABLED(CONFIG_PCI) && test_facility(153)) {
- S390_lowcore.machine_flags |= MACHINE_FLAG_PCI_MIO;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_PCI_MIO;
/* the control bit is set during PCI initialization */
}
if (test_facility(194))
- S390_lowcore.machine_flags |= MACHINE_FLAG_RDP;
+ get_lowcore()->machine_flags |= MACHINE_FLAG_RDP;
}
static inline void save_vector_registers(void)
@@ -291,7 +285,6 @@ void __init startup_init(void)
lockdep_off();
sort_amode31_extable();
setup_lowcore_early();
- setup_facility_list();
detect_machine_type();
setup_arch_string();
setup_boot_command_line();
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 6a1e0fbbaa15..749410cfdbc0 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/asm-extable.h>
-#include <asm/alternative-asm.h>
+#include <asm/alternative.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/dwarf.h>
@@ -28,49 +28,54 @@
#include <asm/setup.h>
#include <asm/nmi.h>
#include <asm/nospec-insn.h>
+#include <asm/lowcore.h>
_LPP_OFFSET = __LC_LPP
.macro STBEAR address
- ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193
+ ALTERNATIVE "nop", ".insn s,0xb2010000,\address", ALT_FACILITY(193)
.endm
.macro LBEAR address
- ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193
+ ALTERNATIVE "nop", ".insn s,0xb2000000,\address", ALT_FACILITY(193)
.endm
- .macro LPSWEY address,lpswe
- ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193
+ .macro LPSWEY address, lpswe
+ ALTERNATIVE_2 "b \lpswe;nopr", \
+ ".insn siy,0xeb0000000071,\address,0", ALT_FACILITY_EARLY(193), \
+ __stringify(.insn siy,0xeb0000000071,LOWCORE_ALT_ADDRESS+\address,0), \
+ ALT_LOWCORE
.endm
- .macro MBEAR reg
- ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
+ .macro MBEAR reg, lowcore
+ ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK(\lowcore)),\
+ ALT_FACILITY(193)
.endm
- .macro CHECK_STACK savearea
+ .macro CHECK_STACK savearea, lowcore
#ifdef CONFIG_CHECK_STACK
tml %r15,THREAD_SIZE - CONFIG_STACK_GUARD
- lghi %r14,\savearea
+ la %r14,\savearea(\lowcore)
jz stack_overflow
#endif
.endm
- .macro CHECK_VMAP_STACK savearea,oklabel
+ .macro CHECK_VMAP_STACK savearea, lowcore, oklabel
#ifdef CONFIG_VMAP_STACK
lgr %r14,%r15
nill %r14,0x10000 - THREAD_SIZE
oill %r14,STACK_INIT_OFFSET
- clg %r14,__LC_KERNEL_STACK
+ clg %r14,__LC_KERNEL_STACK(\lowcore)
je \oklabel
- clg %r14,__LC_ASYNC_STACK
+ clg %r14,__LC_ASYNC_STACK(\lowcore)
je \oklabel
- clg %r14,__LC_MCCK_STACK
+ clg %r14,__LC_MCCK_STACK(\lowcore)
je \oklabel
- clg %r14,__LC_NODAT_STACK
+ clg %r14,__LC_NODAT_STACK(\lowcore)
je \oklabel
- clg %r14,__LC_RESTART_STACK
+ clg %r14,__LC_RESTART_STACK(\lowcore)
je \oklabel
- lghi %r14,\savearea
+ la %r14,\savearea(\lowcore)
j stack_overflow
#else
j \oklabel
@@ -100,30 +105,31 @@ _LPP_OFFSET = __LC_LPP
.endm
.macro BPOFF
- ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82
+ ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", ALT_SPEC(82)
.endm
.macro BPON
- ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82
+ ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", ALT_SPEC(82)
.endm
.macro BPENTER tif_ptr,tif_mask
ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
- "j .+12; nop; nop", 82
+ "j .+12; nop; nop", ALT_SPEC(82)
.endm
.macro BPEXIT tif_ptr,tif_mask
TSTMSK \tif_ptr,\tif_mask
ALTERNATIVE "jz .+8; .insn rrf,0xb2e80000,0,0,12,0", \
- "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
+ "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", ALT_SPEC(82)
.endm
#if IS_ENABLED(CONFIG_KVM)
- .macro SIEEXIT sie_control
- lg %r9,\sie_control # get control block pointer
- ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
- lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
- ni __LC_CPU_FLAGS+7,255-_CIF_SIE
+ .macro SIEEXIT sie_control,lowcore
+ lg %r9,\sie_control # get control block pointer
+ ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
+ lctlg %c1,%c1,__LC_KERNEL_ASCE(\lowcore) # load primary asce
+ lg %r9,__LC_CURRENT(\lowcore)
+ mvi __TI_sie(%r9),0
larl %r9,sie_exit # skip forward to sie_exit
.endm
#endif
@@ -163,13 +169,14 @@ SYM_FUNC_START(__switch_to_asm)
stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev
lg %r15,0(%r4,%r3) # start of kernel stack of next
agr %r15,%r5 # end of kernel stack of next
- stg %r3,__LC_CURRENT # store task struct of next
- stg %r15,__LC_KERNEL_STACK # store end of kernel stack
+ GET_LC %r13
+ stg %r3,__LC_CURRENT(%r13) # store task struct of next
+ stg %r15,__LC_KERNEL_STACK(%r13) # store end of kernel stack
lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next
aghi %r3,__TASK_pid
- mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next
+ mvc __LC_CURRENT_PID(4,%r13),0(%r3) # store pid of next
+ ALTERNATIVE "nop", "lpp _LPP_OFFSET(%r13)", ALT_FACILITY(40)
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
- ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
BR_EX %r14
SYM_FUNC_END(__switch_to_asm)
@@ -179,22 +186,21 @@ SYM_FUNC_END(__switch_to_asm)
* %r2 pointer to sie control block phys
* %r3 pointer to sie control block virt
* %r4 guest register save area
+ * %r5 guest asce
*/
SYM_FUNC_START(__sie64a)
stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
- lg %r12,__LC_CURRENT
+ GET_LC %r13
+ lg %r14,__LC_CURRENT(%r13)
stg %r2,__SF_SIE_CONTROL_PHYS(%r15) # save sie block physical..
stg %r3,__SF_SIE_CONTROL(%r15) # ...and virtual addresses
stg %r4,__SF_SIE_SAVEAREA(%r15) # save guest register save area
+ stg %r5,__SF_SIE_GUEST_ASCE(%r15) # save guest asce
xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
- mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
+ mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r14) # copy thread flags
lmg %r0,%r13,0(%r4) # load guest gprs 0-13
- lg %r14,__LC_GMAP # get gmap pointer
- ltgr %r14,%r14
- jz .Lsie_gmap
- oi __LC_CPU_FLAGS+7,_CIF_SIE
- lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce
-.Lsie_gmap:
+ mvi __TI_sie(%r14),1
+ lctlg %c1,%c1,__SF_SIE_GUEST_ASCE(%r15) # load primary asce
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now
tm __SIE_PROG20+3(%r14),3 # last exit...
@@ -212,8 +218,10 @@ SYM_FUNC_START(__sie64a)
.Lsie_skip:
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
- lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
- ni __LC_CPU_FLAGS+7,255-_CIF_SIE
+ GET_LC %r14
+ lctlg %c1,%c1,__LC_KERNEL_ASCE(%r14) # load primary asce
+ lg %r14,__LC_CURRENT(%r14)
+ mvi __TI_sie(%r14),0
# some program checks are suppressing. C code (e.g. do_protection_exception)
# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
@@ -256,14 +264,15 @@ EXPORT_SYMBOL(sie_exit)
*/
SYM_CODE_START(system_call)
- stpt __LC_SYS_ENTER_TIMER
- stmg %r8,%r15,__LC_SAVE_AREA_SYNC
+ STMG_LC %r8,%r15,__LC_SAVE_AREA_SYNC
+ GET_LC %r13
+ stpt __LC_SYS_ENTER_TIMER(%r13)
BPOFF
lghi %r14,0
.Lsysc_per:
- STBEAR __LC_LAST_BREAK
- lctlg %c1,%c1,__LC_KERNEL_ASCE
- lg %r15,__LC_KERNEL_STACK
+ STBEAR __LC_LAST_BREAK(%r13)
+ lctlg %c1,%c1,__LC_KERNEL_ASCE(%r13)
+ lg %r15,__LC_KERNEL_STACK(%r13)
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
# clear user controlled register to prevent speculative use
@@ -278,17 +287,17 @@ SYM_CODE_START(system_call)
xgr %r10,%r10
xgr %r11,%r11
la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
- mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
- MBEAR %r2
+ mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC(%r13)
+ MBEAR %r2,%r13
lgr %r3,%r14
brasl %r14,__do_syscall
STACKLEAK_ERASE
- lctlg %c1,%c1,__LC_USER_ASCE
- mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
+ lctlg %c1,%c1,__LC_USER_ASCE(%r13)
+ mvc __LC_RETURN_PSW(16,%r13),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
BPON
LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
+ stpt __LC_EXIT_TIMER(%r13)
lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
- stpt __LC_EXIT_TIMER
LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
SYM_CODE_END(system_call)
@@ -299,12 +308,13 @@ SYM_CODE_START(ret_from_fork)
lgr %r3,%r11
brasl %r14,__ret_from_fork
STACKLEAK_ERASE
- lctlg %c1,%c1,__LC_USER_ASCE
- mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
+ GET_LC %r13
+ lctlg %c1,%c1,__LC_USER_ASCE(%r13)
+ mvc __LC_RETURN_PSW(16,%r13),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
BPON
LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
+ stpt __LC_EXIT_TIMER(%r13)
lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
- stpt __LC_EXIT_TIMER
LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
SYM_CODE_END(ret_from_fork)
@@ -313,39 +323,40 @@ SYM_CODE_END(ret_from_fork)
*/
SYM_CODE_START(pgm_check_handler)
- stpt __LC_SYS_ENTER_TIMER
+ STMG_LC %r8,%r15,__LC_SAVE_AREA_SYNC
+ GET_LC %r13
+ stpt __LC_SYS_ENTER_TIMER(%r13)
BPOFF
- stmg %r8,%r15,__LC_SAVE_AREA_SYNC
lgr %r10,%r15
- lmg %r8,%r9,__LC_PGM_OLD_PSW
+ lmg %r8,%r9,__LC_PGM_OLD_PSW(%r13)
tmhh %r8,0x0001 # coming from user space?
jno .Lpgm_skip_asce
- lctlg %c1,%c1,__LC_KERNEL_ASCE
+ lctlg %c1,%c1,__LC_KERNEL_ASCE(%r13)
j 3f # -> fault in user space
.Lpgm_skip_asce:
1: tmhh %r8,0x4000 # PER bit set in old PSW ?
jnz 2f # -> enabled, can't be a double fault
- tm __LC_PGM_ILC+3,0x80 # check for per exception
+ tm __LC_PGM_ILC+3(%r13),0x80 # check for per exception
jnz .Lpgm_svcper # -> single stepped svc
-2: CHECK_STACK __LC_SAVE_AREA_SYNC
+2: CHECK_STACK __LC_SAVE_AREA_SYNC,%r13
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
# CHECK_VMAP_STACK branches to stack_overflow or 4f
- CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
-3: lg %r15,__LC_KERNEL_STACK
+ CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,%r13,4f
+3: lg %r15,__LC_KERNEL_STACK(%r13)
4: la %r11,STACK_FRAME_OVERHEAD(%r15)
xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
stmg %r0,%r7,__PT_R0(%r11)
- mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
- mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK
+ mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC(%r13)
+ mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK(%r13)
stctg %c1,%c1,__PT_CR1(%r11)
#if IS_ENABLED(CONFIG_KVM)
- ltg %r12,__LC_GMAP
+ ltg %r12,__LC_GMAP(%r13)
jz 5f
clc __GMAP_ASCE(8,%r12), __PT_CR1(%r11)
jne 5f
BPENTER __SF_SIE_FLAGS(%r10),_TIF_ISOLATE_BP_GUEST
- SIEEXIT __SF_SIE_CONTROL(%r10)
+ SIEEXIT __SF_SIE_CONTROL(%r10),%r13
#endif
5: stmg %r8,%r9,__PT_PSW(%r11)
# clear user controlled registers to prevent speculative use
@@ -361,11 +372,11 @@ SYM_CODE_START(pgm_check_handler)
tmhh %r8,0x0001 # returning to user space?
jno .Lpgm_exit_kernel
STACKLEAK_ERASE
- lctlg %c1,%c1,__LC_USER_ASCE
+ lctlg %c1,%c1,__LC_USER_ASCE(%r13)
BPON
- stpt __LC_EXIT_TIMER
+ stpt __LC_EXIT_TIMER(%r13)
.Lpgm_exit_kernel:
- mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
+ mvc __LC_RETURN_PSW(16,%r13),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
@@ -374,11 +385,11 @@ SYM_CODE_START(pgm_check_handler)
# single stepped system call
#
.Lpgm_svcper:
- mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
+ mvc __LC_RETURN_PSW(8,%r13),__LC_SVC_NEW_PSW(%r13)
larl %r14,.Lsysc_per
- stg %r14,__LC_RETURN_PSW+8
+ stg %r14,__LC_RETURN_PSW+8(%r13)
lghi %r14,1
- LBEAR __LC_PGM_LAST_BREAK
+ LBEAR __LC_PGM_LAST_BREAK(%r13)
LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per
SYM_CODE_END(pgm_check_handler)
@@ -387,25 +398,27 @@ SYM_CODE_END(pgm_check_handler)
*/
.macro INT_HANDLER name,lc_old_psw,handler
SYM_CODE_START(\name)
- stckf __LC_INT_CLOCK
- stpt __LC_SYS_ENTER_TIMER
- STBEAR __LC_LAST_BREAK
+ STMG_LC %r8,%r15,__LC_SAVE_AREA_ASYNC
+ GET_LC %r13
+ stckf __LC_INT_CLOCK(%r13)
+ stpt __LC_SYS_ENTER_TIMER(%r13)
+ STBEAR __LC_LAST_BREAK(%r13)
BPOFF
- stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
- lmg %r8,%r9,\lc_old_psw
+ lmg %r8,%r9,\lc_old_psw(%r13)
tmhh %r8,0x0001 # interrupting from user ?
jnz 1f
#if IS_ENABLED(CONFIG_KVM)
- TSTMSK __LC_CPU_FLAGS,_CIF_SIE
+ lg %r10,__LC_CURRENT(%r13)
+ tm __TI_sie(%r10),0xff
jz 0f
BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
- SIEEXIT __SF_SIE_CONTROL(%r15)
+ SIEEXIT __SF_SIE_CONTROL(%r15),%r13
#endif
-0: CHECK_STACK __LC_SAVE_AREA_ASYNC
+0: CHECK_STACK __LC_SAVE_AREA_ASYNC,%r13
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j 2f
-1: lctlg %c1,%c1,__LC_KERNEL_ASCE
- lg %r15,__LC_KERNEL_STACK
+1: lctlg %c1,%c1,__LC_KERNEL_ASCE(%r13)
+ lg %r15,__LC_KERNEL_STACK(%r13)
2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
la %r11,STACK_FRAME_OVERHEAD(%r15)
stmg %r0,%r7,__PT_R0(%r11)
@@ -419,18 +432,18 @@ SYM_CODE_START(\name)
xgr %r7,%r7
xgr %r10,%r10
xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
- mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
- MBEAR %r11
+ mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC(%r13)
+ MBEAR %r11,%r13
stmg %r8,%r9,__PT_PSW(%r11)
lgr %r2,%r11 # pass pointer to pt_regs
brasl %r14,\handler
- mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
+ mvc __LC_RETURN_PSW(16,%r13),__PT_PSW(%r11)
tmhh %r8,0x0001 # returning to user ?
jno 2f
STACKLEAK_ERASE
- lctlg %c1,%c1,__LC_USER_ASCE
+ lctlg %c1,%c1,__LC_USER_ASCE(%r13)
BPON
- stpt __LC_EXIT_TIMER
+ stpt __LC_EXIT_TIMER(%r13)
2: LBEAR __PT_LAST_BREAK(%r11)
lmg %r0,%r15,__PT_R0(%r11)
LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
@@ -441,62 +454,41 @@ INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
/*
- * Load idle PSW.
- */
-SYM_FUNC_START(psw_idle)
- stg %r14,(__SF_GPRS+8*8)(%r15)
- stg %r3,__SF_EMPTY(%r15)
- larl %r1,psw_idle_exit
- stg %r1,__SF_EMPTY+8(%r15)
- larl %r1,smp_cpu_mtid
- llgf %r1,0(%r1)
- ltgr %r1,%r1
- jz .Lpsw_idle_stcctm
- .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
-.Lpsw_idle_stcctm:
- oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
- BPON
- stckf __CLOCK_IDLE_ENTER(%r2)
- stpt __TIMER_IDLE_ENTER(%r2)
- lpswe __SF_EMPTY(%r15)
-SYM_INNER_LABEL(psw_idle_exit, SYM_L_GLOBAL)
- BR_EX %r14
-SYM_FUNC_END(psw_idle)
-
-/*
* Machine check handler routines
*/
SYM_CODE_START(mcck_int_handler)
BPOFF
- lmg %r8,%r9,__LC_MCK_OLD_PSW
- TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
+ GET_LC %r13
+ lmg %r8,%r9,__LC_MCK_OLD_PSW(%r13)
+ TSTMSK __LC_MCCK_CODE(%r13),MCCK_CODE_SYSTEM_DAMAGE
jo .Lmcck_panic # yes -> rest of mcck code invalid
- TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID
+ TSTMSK __LC_MCCK_CODE(%r13),MCCK_CODE_CR_VALID
jno .Lmcck_panic # control registers invalid -> panic
ptlb
- lghi %r14,__LC_CPU_TIMER_SAVE_AREA
- mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
- TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
+ lay %r14,__LC_CPU_TIMER_SAVE_AREA(%r13)
+ mvc __LC_MCCK_ENTER_TIMER(8,%r13),0(%r14)
+ TSTMSK __LC_MCCK_CODE(%r13),MCCK_CODE_CPU_TIMER_VALID
jo 3f
- la %r14,__LC_SYS_ENTER_TIMER
- clc 0(8,%r14),__LC_EXIT_TIMER
+ la %r14,__LC_SYS_ENTER_TIMER(%r13)
+ clc 0(8,%r14),__LC_EXIT_TIMER(%r13)
jl 1f
- la %r14,__LC_EXIT_TIMER
-1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
+ la %r14,__LC_EXIT_TIMER(%r13)
+1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER(%r13)
jl 2f
- la %r14,__LC_LAST_UPDATE_TIMER
+ la %r14,__LC_LAST_UPDATE_TIMER(%r13)
2: spt 0(%r14)
- mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
-3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
+ mvc __LC_MCCK_ENTER_TIMER(8,%r13),0(%r14)
+3: TSTMSK __LC_MCCK_CODE(%r13),MCCK_CODE_PSW_MWP_VALID
jno .Lmcck_panic
tmhh %r8,0x0001 # interrupting from user ?
jnz .Lmcck_user
- TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
+ TSTMSK __LC_MCCK_CODE(%r13),MCCK_CODE_PSW_IA_VALID
jno .Lmcck_panic
#if IS_ENABLED(CONFIG_KVM)
- TSTMSK __LC_CPU_FLAGS,_CIF_SIE
+ lg %r10,__LC_CURRENT(%r13)
+ tm __TI_sie(%r10),0xff
jz .Lmcck_user
- # Need to compare the address instead of a CIF_SIE* flag.
+ # Need to compare the address instead of __TI_SIE flag.
# Otherwise there would be a race between setting the flag
# and entering SIE (or leaving and clearing the flag). This
# would cause machine checks targeted at the guest to be
@@ -505,18 +497,19 @@ SYM_CODE_START(mcck_int_handler)
clgrjl %r9,%r14, 4f
larl %r14,.Lsie_leave
clgrjhe %r9,%r14, 4f
- oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
+ lg %r10,__LC_PCPU
+ oi __PCPU_FLAGS+7(%r10), _CIF_MCCK_GUEST
4: BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
- SIEEXIT __SF_SIE_CONTROL(%r15)
+ SIEEXIT __SF_SIE_CONTROL(%r15),%r13
#endif
.Lmcck_user:
- lg %r15,__LC_MCCK_STACK
+ lg %r15,__LC_MCCK_STACK(%r13)
la %r11,STACK_FRAME_OVERHEAD(%r15)
stctg %c1,%c1,__PT_CR1(%r11)
- lctlg %c1,%c1,__LC_KERNEL_ASCE
+ lctlg %c1,%c1,__LC_KERNEL_ASCE(%r13)
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
- lghi %r14,__LC_GPREGS_SAVE_AREA+64
- stmg %r0,%r7,__PT_R0(%r11)
+ lay %r14,__LC_GPREGS_SAVE_AREA(%r13)
+ mvc __PT_R0(128,%r11),0(%r14)
# clear user controlled registers to prevent speculative use
xgr %r0,%r0
xgr %r1,%r1
@@ -526,7 +519,6 @@ SYM_CODE_START(mcck_int_handler)
xgr %r6,%r6
xgr %r7,%r7
xgr %r10,%r10
- mvc __PT_R8(64,%r11),0(%r14)
stmg %r8,%r9,__PT_PSW(%r11)
xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
@@ -534,12 +526,13 @@ SYM_CODE_START(mcck_int_handler)
brasl %r14,s390_do_machine_check
lctlg %c1,%c1,__PT_CR1(%r11)
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 ?
+ mvc __LC_RETURN_MCCK_PSW(16,%r13),__PT_PSW(%r11) # move return PSW
+ tm __LC_RETURN_MCCK_PSW+1(%r13),0x01 # returning to user ?
jno 0f
BPON
- stpt __LC_EXIT_TIMER
-0: ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
+ stpt __LC_EXIT_TIMER(%r13)
+0: ALTERNATIVE "brcl 0,0", __stringify(lay %r12,__LC_LAST_BREAK_SAVE_AREA(%r13)),\
+ ALT_FACILITY(193)
LBEAR 0(%r12)
lmg %r11,%r15,__PT_R11(%r11)
LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
@@ -575,7 +568,7 @@ SYM_CODE_START(mcck_int_handler)
SYM_CODE_END(mcck_int_handler)
SYM_CODE_START(restart_int_handler)
- ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
+ ALTERNATIVE "nop", "lpp _LPP_OFFSET", ALT_FACILITY(40)
stg %r15,__LC_SAVE_AREA_RESTART
TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
jz 0f
@@ -583,15 +576,17 @@ SYM_CODE_START(restart_int_handler)
0: larl %r15,daton_psw
lpswe 0(%r15) # turn dat on, keep irqs off
.Ldaton:
- lg %r15,__LC_RESTART_STACK
+ GET_LC %r15
+ lg %r15,__LC_RESTART_STACK(%r15)
xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
- mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
- mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
+ GET_LC %r13
+ mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART(%r13)
+ mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW(%r13)
xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
- lg %r1,__LC_RESTART_FN # load fn, parm & source cpu
- lg %r2,__LC_RESTART_DATA
- lgf %r3,__LC_RESTART_SOURCE
+ lg %r1,__LC_RESTART_FN(%r13) # load fn, parm & source cpu
+ lg %r2,__LC_RESTART_DATA(%r13)
+ lgf %r3,__LC_RESTART_SOURCE(%r13)
ltgr %r3,%r3 # test source cpu address
jm 1f # negative -> skip source stop
0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu
@@ -613,7 +608,8 @@ SYM_CODE_END(restart_int_handler)
* Setup a pt_regs so that show_trace can provide a good call trace.
*/
SYM_CODE_START(stack_overflow)
- lg %r15,__LC_NODAT_STACK # change to panic stack
+ GET_LC %r15
+ lg %r15,__LC_NODAT_STACK(%r15) # change to panic stack
la %r11,STACK_FRAME_OVERHEAD(%r15)
stmg %r0,%r7,__PT_R0(%r11)
stmg %r8,%r9,__PT_PSW(%r11)
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index c46381ea04ec..0bd6adc40a34 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -7,13 +7,14 @@
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
-#include <linux/moduleloader.h>
#include <linux/hardirq.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/kmsan-checks.h>
#include <linux/kprobes.h>
+#include <linux/execmem.h>
#include <trace/syscall.h>
#include <asm/asm-offsets.h>
#include <asm/text-patching.h>
@@ -220,7 +221,7 @@ static int __init ftrace_plt_init(void)
{
const char *start, *end;
- ftrace_plt = module_alloc(PAGE_SIZE);
+ ftrace_plt = execmem_alloc(EXECMEM_FTRACE, PAGE_SIZE);
if (!ftrace_plt)
panic("cannot allocate ftrace plt\n");
@@ -296,10 +297,14 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe *p;
int bit;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
+ kmsan_unpoison_memory(fregs, sizeof(*fregs));
regs = ftrace_get_regs(fregs);
p = get_kprobe((kprobe_opcode_t *)ip);
if (!regs || unlikely(!p) || kprobe_disabled(p))
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 45413b04efc5..396034b2fe67 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/linkage.h>
+#include <asm/lowcore.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
@@ -18,14 +19,15 @@
__HEAD
SYM_CODE_START(startup_continue)
larl %r1,tod_clock_base
- mvc 0(16,%r1),__LC_BOOT_CLOCK
+ GET_LC %r2
+ mvc 0(16,%r1),__LC_BOOT_CLOCK(%r2)
#
# Setup stack
#
larl %r14,init_task
- stg %r14,__LC_CURRENT
+ stg %r14,__LC_CURRENT(%r2)
larl %r15,init_thread_union+STACK_INIT_OFFSET
- stg %r15,__LC_KERNEL_STACK
+ stg %r15,__LC_KERNEL_STACK(%r2)
brasl %r14,sclp_early_adjust_va # allow sclp_early_printk
brasl %r14,startup_init # s390 specific early init
brasl %r14,start_kernel # common init code
diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c
index e7239aaf428b..39cb8d0ae348 100644
--- a/arch/s390/kernel/idle.c
+++ b/arch/s390/kernel/idle.c
@@ -24,6 +24,7 @@ static DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
void account_idle_time_irq(void)
{
struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
+ struct lowcore *lc = get_lowcore();
unsigned long idle_time;
u64 cycles_new[8];
int i;
@@ -34,13 +35,13 @@ void account_idle_time_irq(void)
this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]);
}
- idle_time = S390_lowcore.int_clock - idle->clock_idle_enter;
+ idle_time = lc->int_clock - idle->clock_idle_enter;
- S390_lowcore.steal_timer += idle->clock_idle_enter - S390_lowcore.last_update_clock;
- S390_lowcore.last_update_clock = S390_lowcore.int_clock;
+ lc->steal_timer += idle->clock_idle_enter - lc->last_update_clock;
+ lc->last_update_clock = lc->int_clock;
- S390_lowcore.system_timer += S390_lowcore.last_update_timer - idle->timer_idle_enter;
- S390_lowcore.last_update_timer = S390_lowcore.sys_enter_timer;
+ lc->system_timer += lc->last_update_timer - idle->timer_idle_enter;
+ lc->last_update_timer = lc->sys_enter_timer;
/* Account time spent with enabled wait psw loaded as idle time. */
WRITE_ONCE(idle->idle_time, READ_ONCE(idle->idle_time) + idle_time);
@@ -57,9 +58,13 @@ void noinstr arch_cpu_idle(void)
psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT |
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
clear_cpu_flag(CIF_NOHZ_DELAY);
-
- /* psw_idle() returns with interrupts disabled. */
- psw_idle(idle, psw_mask);
+ set_cpu_flag(CIF_ENABLED_WAIT);
+ if (smp_cpu_mtid)
+ stcctm(MT_DIAG, smp_cpu_mtid, (u64 *)&idle->mt_cycles_enter);
+ idle->clock_idle_enter = get_tod_clock_fast();
+ idle->timer_idle_enter = get_cpu_timer();
+ bpon();
+ __load_psw_mask(psw_mask);
}
static ssize_t show_idle_count(struct device *dev,
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 1486350a4177..f17bb7bf9392 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -20,6 +20,7 @@
#include <linux/gfp.h>
#include <linux/crash_dump.h>
#include <linux/debug_locks.h>
+#include <linux/vmalloc.h>
#include <asm/asm-extable.h>
#include <asm/diag.h>
#include <asm/ipl.h>
@@ -266,7 +267,11 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
struct kobj_attribute *attr, \
const char *buf, size_t len) \
{ \
- strscpy(_value, buf, sizeof(_value)); \
+ if (len >= sizeof(_value)) \
+ return -E2BIG; \
+ len = strscpy(_value, buf, sizeof(_value)); \
+ if (len < 0) \
+ return len; \
strim(_value); \
return len; \
} \
@@ -275,6 +280,61 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
sys_##_prefix##_##_name##_show, \
sys_##_prefix##_##_name##_store)
+#define IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \
+static ssize_t sys_##_prefix##_scp_data_show(struct file *filp, \
+ struct kobject *kobj, \
+ struct bin_attribute *attr, \
+ char *buf, loff_t off, \
+ size_t count) \
+{ \
+ size_t size = _ipl_block.scp_data_len; \
+ void *scp_data = _ipl_block.scp_data; \
+ \
+ return memory_read_from_buffer(buf, count, &off, \
+ scp_data, size); \
+}
+
+#define IPL_ATTR_SCP_DATA_STORE_FN(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len)\
+static ssize_t sys_##_prefix##_scp_data_store(struct file *filp, \
+ struct kobject *kobj, \
+ struct bin_attribute *attr, \
+ char *buf, loff_t off, \
+ size_t count) \
+{ \
+ size_t scpdata_len = count; \
+ size_t padding; \
+ \
+ if (off) \
+ return -EINVAL; \
+ \
+ memcpy(_ipl_block.scp_data, buf, count); \
+ if (scpdata_len % 8) { \
+ padding = 8 - (scpdata_len % 8); \
+ memset(_ipl_block.scp_data + scpdata_len, \
+ 0, padding); \
+ scpdata_len += padding; \
+ } \
+ \
+ _ipl_block_hdr.len = _ipl_bp_len + scpdata_len; \
+ _ipl_block.len = _ipl_bp0_len + scpdata_len; \
+ _ipl_block.scp_data_len = scpdata_len; \
+ \
+ return count; \
+}
+
+#define DEFINE_IPL_ATTR_SCP_DATA_RO(_prefix, _ipl_block, _size) \
+IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \
+static struct bin_attribute sys_##_prefix##_scp_data_attr = \
+ __BIN_ATTR(scp_data, 0444, sys_##_prefix##_scp_data_show, \
+ NULL, _size)
+
+#define DEFINE_IPL_ATTR_SCP_DATA_RW(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len, _size)\
+IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \
+IPL_ATTR_SCP_DATA_STORE_FN(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len)\
+static struct bin_attribute sys_##_prefix##_scp_data_attr = \
+ __BIN_ATTR(scp_data, 0644, sys_##_prefix##_scp_data_show, \
+ sys_##_prefix##_scp_data_store, _size)
+
/*
* ipl section
*/
@@ -373,71 +433,38 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
static struct kobj_attribute sys_ipl_device_attr =
__ATTR(device, 0444, sys_ipl_device_show, NULL);
-static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
+static ssize_t sys_ipl_parameter_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
{
return memory_read_from_buffer(buf, count, &off, &ipl_block,
ipl_block.hdr.len);
}
-static struct bin_attribute ipl_parameter_attr =
- __BIN_ATTR(binary_parameter, 0444, ipl_parameter_read, NULL,
+static struct bin_attribute sys_ipl_parameter_attr =
+ __BIN_ATTR(binary_parameter, 0444, sys_ipl_parameter_read, NULL,
PAGE_SIZE);
-static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- unsigned int size = ipl_block.fcp.scp_data_len;
- void *scp_data = &ipl_block.fcp.scp_data;
-
- return memory_read_from_buffer(buf, count, &off, scp_data, size);
-}
-
-static ssize_t ipl_nvme_scp_data_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- unsigned int size = ipl_block.nvme.scp_data_len;
- void *scp_data = &ipl_block.nvme.scp_data;
-
- return memory_read_from_buffer(buf, count, &off, scp_data, size);
-}
-
-static ssize_t ipl_eckd_scp_data_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- unsigned int size = ipl_block.eckd.scp_data_len;
- void *scp_data = &ipl_block.eckd.scp_data;
-
- return memory_read_from_buffer(buf, count, &off, scp_data, size);
-}
-
-static struct bin_attribute ipl_scp_data_attr =
- __BIN_ATTR(scp_data, 0444, ipl_scp_data_read, NULL, PAGE_SIZE);
-
-static struct bin_attribute ipl_nvme_scp_data_attr =
- __BIN_ATTR(scp_data, 0444, ipl_nvme_scp_data_read, NULL, PAGE_SIZE);
-
-static struct bin_attribute ipl_eckd_scp_data_attr =
- __BIN_ATTR(scp_data, 0444, ipl_eckd_scp_data_read, NULL, PAGE_SIZE);
+DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_fcp, ipl_block.fcp, PAGE_SIZE);
static struct bin_attribute *ipl_fcp_bin_attrs[] = {
- &ipl_parameter_attr,
- &ipl_scp_data_attr,
+ &sys_ipl_parameter_attr,
+ &sys_ipl_fcp_scp_data_attr,
NULL,
};
+DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_nvme, ipl_block.nvme, PAGE_SIZE);
+
static struct bin_attribute *ipl_nvme_bin_attrs[] = {
- &ipl_parameter_attr,
- &ipl_nvme_scp_data_attr,
+ &sys_ipl_parameter_attr,
+ &sys_ipl_nvme_scp_data_attr,
NULL,
};
+DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_eckd, ipl_block.eckd, PAGE_SIZE);
+
static struct bin_attribute *ipl_eckd_bin_attrs[] = {
- &ipl_parameter_attr,
- &ipl_eckd_scp_data_attr,
+ &sys_ipl_parameter_attr,
+ &sys_ipl_eckd_scp_data_attr,
NULL,
};
@@ -776,44 +803,10 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
/* FCP reipl device attributes */
-static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- size_t size = reipl_block_fcp->fcp.scp_data_len;
- void *scp_data = reipl_block_fcp->fcp.scp_data;
-
- return memory_read_from_buffer(buf, count, &off, scp_data, size);
-}
-
-static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- size_t scpdata_len = count;
- size_t padding;
-
-
- if (off)
- return -EINVAL;
-
- memcpy(reipl_block_fcp->fcp.scp_data, buf, count);
- if (scpdata_len % 8) {
- padding = 8 - (scpdata_len % 8);
- memset(reipl_block_fcp->fcp.scp_data + scpdata_len,
- 0, padding);
- scpdata_len += padding;
- }
-
- reipl_block_fcp->hdr.len = IPL_BP_FCP_LEN + scpdata_len;
- reipl_block_fcp->fcp.len = IPL_BP0_FCP_LEN + scpdata_len;
- reipl_block_fcp->fcp.scp_data_len = scpdata_len;
-
- return count;
-}
-static struct bin_attribute sys_reipl_fcp_scp_data_attr =
- __BIN_ATTR(scp_data, 0644, reipl_fcp_scpdata_read,
- reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE);
+DEFINE_IPL_ATTR_SCP_DATA_RW(reipl_fcp, reipl_block_fcp->hdr,
+ reipl_block_fcp->fcp,
+ IPL_BP_FCP_LEN, IPL_BP0_FCP_LEN,
+ DIAG308_SCPDATA_SIZE);
static struct bin_attribute *reipl_fcp_bin_attrs[] = {
&sys_reipl_fcp_scp_data_attr,
@@ -934,44 +927,10 @@ static struct kobj_attribute sys_reipl_fcp_clear_attr =
/* NVME reipl device attributes */
-static ssize_t reipl_nvme_scpdata_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- size_t size = reipl_block_nvme->nvme.scp_data_len;
- void *scp_data = reipl_block_nvme->nvme.scp_data;
-
- return memory_read_from_buffer(buf, count, &off, scp_data, size);
-}
-
-static ssize_t reipl_nvme_scpdata_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- size_t scpdata_len = count;
- size_t padding;
-
- if (off)
- return -EINVAL;
-
- memcpy(reipl_block_nvme->nvme.scp_data, buf, count);
- if (scpdata_len % 8) {
- padding = 8 - (scpdata_len % 8);
- memset(reipl_block_nvme->nvme.scp_data + scpdata_len,
- 0, padding);
- scpdata_len += padding;
- }
-
- reipl_block_nvme->hdr.len = IPL_BP_FCP_LEN + scpdata_len;
- reipl_block_nvme->nvme.len = IPL_BP0_FCP_LEN + scpdata_len;
- reipl_block_nvme->nvme.scp_data_len = scpdata_len;
-
- return count;
-}
-
-static struct bin_attribute sys_reipl_nvme_scp_data_attr =
- __BIN_ATTR(scp_data, 0644, reipl_nvme_scpdata_read,
- reipl_nvme_scpdata_write, DIAG308_SCPDATA_SIZE);
+DEFINE_IPL_ATTR_SCP_DATA_RW(reipl_nvme, reipl_block_nvme->hdr,
+ reipl_block_nvme->nvme,
+ IPL_BP_NVME_LEN, IPL_BP0_NVME_LEN,
+ DIAG308_SCPDATA_SIZE);
static struct bin_attribute *reipl_nvme_bin_attrs[] = {
&sys_reipl_nvme_scp_data_attr,
@@ -1067,44 +1026,10 @@ static struct attribute_group reipl_ccw_attr_group_lpar = {
/* ECKD reipl device attributes */
-static ssize_t reipl_eckd_scpdata_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- size_t size = reipl_block_eckd->eckd.scp_data_len;
- void *scp_data = reipl_block_eckd->eckd.scp_data;
-
- return memory_read_from_buffer(buf, count, &off, scp_data, size);
-}
-
-static ssize_t reipl_eckd_scpdata_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- size_t scpdata_len = count;
- size_t padding;
-
- if (off)
- return -EINVAL;
-
- memcpy(reipl_block_eckd->eckd.scp_data, buf, count);
- if (scpdata_len % 8) {
- padding = 8 - (scpdata_len % 8);
- memset(reipl_block_eckd->eckd.scp_data + scpdata_len,
- 0, padding);
- scpdata_len += padding;
- }
-
- reipl_block_eckd->hdr.len = IPL_BP_ECKD_LEN + scpdata_len;
- reipl_block_eckd->eckd.len = IPL_BP0_ECKD_LEN + scpdata_len;
- reipl_block_eckd->eckd.scp_data_len = scpdata_len;
-
- return count;
-}
-
-static struct bin_attribute sys_reipl_eckd_scp_data_attr =
- __BIN_ATTR(scp_data, 0644, reipl_eckd_scpdata_read,
- reipl_eckd_scpdata_write, DIAG308_SCPDATA_SIZE);
+DEFINE_IPL_ATTR_SCP_DATA_RW(reipl_eckd, reipl_block_eckd->hdr,
+ reipl_block_eckd->eckd,
+ IPL_BP_ECKD_LEN, IPL_BP0_ECKD_LEN,
+ DIAG308_SCPDATA_SIZE);
static struct bin_attribute *reipl_eckd_bin_attrs[] = {
&sys_reipl_eckd_scp_data_attr,
@@ -1209,8 +1134,8 @@ static struct attribute_group reipl_nss_attr_group = {
void set_os_info_reipl_block(void)
{
- os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
- reipl_block_actual->hdr.len);
+ os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
+ reipl_block_actual->hdr.len);
}
/* reipl type */
@@ -1648,6 +1573,11 @@ DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
dump_block_fcp->fcp.devno);
+DEFINE_IPL_ATTR_SCP_DATA_RW(dump_fcp, dump_block_fcp->hdr,
+ dump_block_fcp->fcp,
+ IPL_BP_FCP_LEN, IPL_BP0_FCP_LEN,
+ DIAG308_SCPDATA_SIZE);
+
static struct attribute *dump_fcp_attrs[] = {
&sys_dump_fcp_device_attr.attr,
&sys_dump_fcp_wwpn_attr.attr,
@@ -1657,9 +1587,15 @@ static struct attribute *dump_fcp_attrs[] = {
NULL,
};
+static struct bin_attribute *dump_fcp_bin_attrs[] = {
+ &sys_dump_fcp_scp_data_attr,
+ NULL,
+};
+
static struct attribute_group dump_fcp_attr_group = {
.name = IPL_FCP_STR,
.attrs = dump_fcp_attrs,
+ .bin_attrs = dump_fcp_bin_attrs,
};
/* NVME dump device attributes */
@@ -1672,6 +1608,11 @@ DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n",
DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n",
dump_block_nvme->nvme.br_lba);
+DEFINE_IPL_ATTR_SCP_DATA_RW(dump_nvme, dump_block_nvme->hdr,
+ dump_block_nvme->nvme,
+ IPL_BP_NVME_LEN, IPL_BP0_NVME_LEN,
+ DIAG308_SCPDATA_SIZE);
+
static struct attribute *dump_nvme_attrs[] = {
&sys_dump_nvme_fid_attr.attr,
&sys_dump_nvme_nsid_attr.attr,
@@ -1680,9 +1621,15 @@ static struct attribute *dump_nvme_attrs[] = {
NULL,
};
+static struct bin_attribute *dump_nvme_bin_attrs[] = {
+ &sys_dump_nvme_scp_data_attr,
+ NULL,
+};
+
static struct attribute_group dump_nvme_attr_group = {
.name = IPL_NVME_STR,
.attrs = dump_nvme_attrs,
+ .bin_attrs = dump_nvme_bin_attrs,
};
/* ECKD dump device attributes */
@@ -1696,6 +1643,11 @@ IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd);
static struct kobj_attribute sys_dump_eckd_br_chr_attr =
__ATTR(br_chr, 0644, eckd_dump_br_chr_show, eckd_dump_br_chr_store);
+DEFINE_IPL_ATTR_SCP_DATA_RW(dump_eckd, dump_block_eckd->hdr,
+ dump_block_eckd->eckd,
+ IPL_BP_ECKD_LEN, IPL_BP0_ECKD_LEN,
+ DIAG308_SCPDATA_SIZE);
+
static struct attribute *dump_eckd_attrs[] = {
&sys_dump_eckd_device_attr.attr,
&sys_dump_eckd_bootprog_attr.attr,
@@ -1703,9 +1655,15 @@ static struct attribute *dump_eckd_attrs[] = {
NULL,
};
+static struct bin_attribute *dump_eckd_bin_attrs[] = {
+ &sys_dump_eckd_scp_data_attr,
+ NULL,
+};
+
static struct attribute_group dump_eckd_attr_group = {
.name = IPL_ECKD_STR,
.attrs = dump_eckd_attrs,
+ .bin_attrs = dump_eckd_bin_attrs,
};
/* CCW dump device attributes */
@@ -1858,9 +1816,9 @@ static int __init dump_nvme_init(void)
}
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_block_nvme->nvme.len = IPL_BP0_NVME_LEN;
+ dump_block_nvme->nvme.pbt = IPL_PBT_NVME;
+ dump_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_DUMP;
dump_capabilities |= DUMP_TYPE_NVME;
return 0;
}
@@ -1940,7 +1898,7 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
reipl_type == IPL_TYPE_NSS ||
reipl_type == IPL_TYPE_UNKNOWN)
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
- os_info_entry_add(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
+ os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
abs_lc = get_abs_lowcore();
abs_lc->ipib = __pa(reipl_block_actual);
@@ -1958,11 +1916,13 @@ static struct shutdown_action __refdata dump_reipl_action = {
* vmcmd shutdown action: Trigger vm command on shutdown.
*/
-static char vmcmd_on_reboot[128];
-static char vmcmd_on_panic[128];
-static char vmcmd_on_halt[128];
-static char vmcmd_on_poff[128];
-static char vmcmd_on_restart[128];
+#define VMCMD_MAX_SIZE 240
+
+static char vmcmd_on_reboot[VMCMD_MAX_SIZE + 1];
+static char vmcmd_on_panic[VMCMD_MAX_SIZE + 1];
+static char vmcmd_on_halt[VMCMD_MAX_SIZE + 1];
+static char vmcmd_on_poff[VMCMD_MAX_SIZE + 1];
+static char vmcmd_on_restart[VMCMD_MAX_SIZE + 1];
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
@@ -2152,7 +2112,7 @@ void do_restart(void *arg)
tracing_off();
debug_locks_off();
lgr_info_log();
- smp_call_online_cpu(__do_restart, arg);
+ smp_call_ipl_cpu(__do_restart, arg);
}
/* on halt */
@@ -2288,8 +2248,8 @@ static int __init vmcmd_on_reboot_setup(char *str)
{
if (!MACHINE_IS_VM)
return 1;
- strncpy_skip_quote(vmcmd_on_reboot, str, 127);
- vmcmd_on_reboot[127] = 0;
+ strncpy_skip_quote(vmcmd_on_reboot, str, VMCMD_MAX_SIZE);
+ vmcmd_on_reboot[VMCMD_MAX_SIZE] = 0;
on_reboot_trigger.action = &vmcmd_action;
return 1;
}
@@ -2299,8 +2259,8 @@ static int __init vmcmd_on_panic_setup(char *str)
{
if (!MACHINE_IS_VM)
return 1;
- strncpy_skip_quote(vmcmd_on_panic, str, 127);
- vmcmd_on_panic[127] = 0;
+ strncpy_skip_quote(vmcmd_on_panic, str, VMCMD_MAX_SIZE);
+ vmcmd_on_panic[VMCMD_MAX_SIZE] = 0;
on_panic_trigger.action = &vmcmd_action;
return 1;
}
@@ -2310,8 +2270,8 @@ static int __init vmcmd_on_halt_setup(char *str)
{
if (!MACHINE_IS_VM)
return 1;
- strncpy_skip_quote(vmcmd_on_halt, str, 127);
- vmcmd_on_halt[127] = 0;
+ strncpy_skip_quote(vmcmd_on_halt, str, VMCMD_MAX_SIZE);
+ vmcmd_on_halt[VMCMD_MAX_SIZE] = 0;
on_halt_trigger.action = &vmcmd_action;
return 1;
}
@@ -2321,8 +2281,8 @@ static int __init vmcmd_on_poff_setup(char *str)
{
if (!MACHINE_IS_VM)
return 1;
- strncpy_skip_quote(vmcmd_on_poff, str, 127);
- vmcmd_on_poff[127] = 0;
+ strncpy_skip_quote(vmcmd_on_poff, str, VMCMD_MAX_SIZE);
+ vmcmd_on_poff[VMCMD_MAX_SIZE] = 0;
on_poff_trigger.action = &vmcmd_action;
return 1;
}
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 6f71b0ce1068..1af5a08d72ab 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -29,6 +29,7 @@
#include <asm/hw_irq.h>
#include <asm/stacktrace.h>
#include <asm/softirq_stack.h>
+#include <asm/vtime.h>
#include "entry.h"
DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat);
@@ -99,8 +100,8 @@ static const struct irq_class irqclass_sub_desc[] = {
static void do_IRQ(struct pt_regs *regs, int irq)
{
- if (tod_after_eq(S390_lowcore.int_clock,
- S390_lowcore.clock_comparator))
+ if (tod_after_eq(get_lowcore()->int_clock,
+ get_lowcore()->clock_comparator))
/* Serve timer interrupts first. */
clock_comparator_work();
generic_handle_irq(irq);
@@ -110,7 +111,7 @@ static int on_async_stack(void)
{
unsigned long frame = current_frame_address();
- return ((S390_lowcore.async_stack ^ frame) & ~(THREAD_SIZE - 1)) == 0;
+ return ((get_lowcore()->async_stack ^ frame) & ~(THREAD_SIZE - 1)) == 0;
}
static void do_irq_async(struct pt_regs *regs, int irq)
@@ -118,7 +119,7 @@ static void do_irq_async(struct pt_regs *regs, int irq)
if (on_async_stack()) {
do_IRQ(regs, irq);
} else {
- call_on_stack(2, S390_lowcore.async_stack, void, do_IRQ,
+ call_on_stack(2, get_lowcore()->async_stack, void, do_IRQ,
struct pt_regs *, regs, int, irq);
}
}
@@ -150,9 +151,10 @@ void noinstr do_io_irq(struct pt_regs *regs)
if (from_idle)
account_idle_time_irq();
+ set_cpu_flag(CIF_NOHZ_DELAY);
do {
- regs->tpi_info = S390_lowcore.tpi_info;
- if (S390_lowcore.tpi_info.adapter_IO)
+ regs->tpi_info = get_lowcore()->tpi_info;
+ if (get_lowcore()->tpi_info.adapter_IO)
do_irq_async(regs, THIN_INTERRUPT);
else
do_irq_async(regs, IO_INTERRUPT);
@@ -181,9 +183,9 @@ void noinstr do_ext_irq(struct pt_regs *regs)
current->thread.last_break = regs->last_break;
}
- regs->int_code = S390_lowcore.ext_int_code_addr;
- regs->int_parm = S390_lowcore.ext_params;
- regs->int_parm_long = S390_lowcore.ext_params2;
+ regs->int_code = get_lowcore()->ext_int_code_addr;
+ regs->int_parm = get_lowcore()->ext_params;
+ regs->int_parm_long = get_lowcore()->ext_params2;
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
if (from_idle)
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index f0cf20d4b3c5..05c83505e979 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -9,7 +9,6 @@
#define pr_fmt(fmt) "kprobes: " fmt
-#include <linux/moduleloader.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
#include <linux/preempt.h>
@@ -21,10 +20,10 @@
#include <linux/slab.h>
#include <linux/hardirq.h>
#include <linux/ftrace.h>
+#include <linux/execmem.h>
#include <asm/set_memory.h>
#include <asm/sections.h>
#include <asm/dis.h>
-#include "kprobes.h"
#include "entry.h"
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
@@ -32,39 +31,17 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
struct kretprobe_blackpoint kretprobe_blacklist[] = { };
-static int insn_page_in_use;
-
void *alloc_insn_page(void)
{
void *page;
- page = module_alloc(PAGE_SIZE);
+ page = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE);
if (!page)
return NULL;
set_memory_rox((unsigned long)page, 1);
return page;
}
-static void *alloc_s390_insn_page(void)
-{
- if (xchg(&insn_page_in_use, 1) == 1)
- return NULL;
- return &kprobes_insn_page;
-}
-
-static void free_s390_insn_page(void *page)
-{
- xchg(&insn_page_in_use, 0);
-}
-
-struct kprobe_insn_cache kprobe_s390_insn_slots = {
- .mutex = __MUTEX_INITIALIZER(kprobe_s390_insn_slots.mutex),
- .alloc = alloc_s390_insn_page,
- .free = free_s390_insn_page,
- .pages = LIST_HEAD_INIT(kprobe_s390_insn_slots.pages),
- .insn_size = MAX_INSN_SIZE,
-};
-
static void copy_instruction(struct kprobe *p)
{
kprobe_opcode_t insn[MAX_INSN_SIZE];
@@ -78,10 +55,10 @@ static void copy_instruction(struct kprobe *p)
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.
+ * the RI2 displacement field. The insn slot for the to be
+ * patched instruction is within the same 4GB area like the
+ * original instruction. Therefore the new displacement will
+ * always fit.
*/
disp = *(s32 *)&insn[1];
addr = (u64)(unsigned long)p->addr;
@@ -93,34 +70,6 @@ static void copy_instruction(struct kprobe *p)
}
NOKPROBE_SYMBOL(copy_instruction);
-static int s390_get_insn_slot(struct kprobe *p)
-{
- /*
- * Get an insn slot that is within the same 2GB area like the original
- * instruction. That way instructions with a 32bit signed displacement
- * field can be patched and executed within the insn slot.
- */
- p->ainsn.insn = NULL;
- if (is_kernel((unsigned long)p->addr))
- p->ainsn.insn = get_s390_insn_slot();
- else if (is_module_addr(p->addr))
- p->ainsn.insn = get_insn_slot();
- return p->ainsn.insn ? 0 : -ENOMEM;
-}
-NOKPROBE_SYMBOL(s390_get_insn_slot);
-
-static void s390_free_insn_slot(struct kprobe *p)
-{
- if (!p->ainsn.insn)
- return;
- if (is_kernel((unsigned long)p->addr))
- free_s390_insn_slot(p->ainsn.insn, 0);
- else
- free_insn_slot(p->ainsn.insn, 0);
- p->ainsn.insn = NULL;
-}
-NOKPROBE_SYMBOL(s390_free_insn_slot);
-
/* Check if paddr is at an instruction boundary */
static bool can_probe(unsigned long paddr)
{
@@ -174,7 +123,8 @@ int arch_prepare_kprobe(struct kprobe *p)
/* Make sure the probe isn't going on a difficult instruction */
if (probe_is_prohibited_opcode(p->addr))
return -EINVAL;
- if (s390_get_insn_slot(p))
+ p->ainsn.insn = get_insn_slot();
+ if (!p->ainsn.insn)
return -ENOMEM;
copy_instruction(p);
return 0;
@@ -216,7 +166,10 @@ NOKPROBE_SYMBOL(arch_disarm_kprobe);
void arch_remove_kprobe(struct kprobe *p)
{
- s390_free_insn_slot(p);
+ if (!p->ainsn.insn)
+ return;
+ free_insn_slot(p->ainsn.insn, 0);
+ p->ainsn.insn = NULL;
}
NOKPROBE_SYMBOL(arch_remove_kprobe);
diff --git a/arch/s390/kernel/kprobes.h b/arch/s390/kernel/kprobes.h
deleted file mode 100644
index dc3ed5098ee7..000000000000
--- a/arch/s390/kernel/kprobes.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-#ifndef _ARCH_S390_KPROBES_H
-#define _ARCH_S390_KPROBES_H
-
-#include <linux/kprobes.h>
-
-DEFINE_INSN_CACHE_OPS(s390_insn);
-
-#endif
diff --git a/arch/s390/kernel/kprobes_insn_page.S b/arch/s390/kernel/kprobes_insn_page.S
deleted file mode 100644
index 0fe4d725e98b..000000000000
--- a/arch/s390/kernel/kprobes_insn_page.S
+++ /dev/null
@@ -1,22 +0,0 @@
-/* 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"
- .balign 4096
-SYM_CODE_START(kprobes_insn_page)
- .rept 2048
- .word 0x07fe
- .endr
-SYM_CODE_END(kprobes_insn_page)
- .previous
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 3aee98efc374..8f681ccfb83a 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -52,7 +52,7 @@ static void __do_machine_kdump(void *data)
purgatory = (purgatory_t)image->start;
/* store_status() saved the prefix register to lowcore */
- prefix = (unsigned long) S390_lowcore.prefixreg_save_area;
+ prefix = (unsigned long)get_lowcore()->prefixreg_save_area;
/* Now do the reset */
s390_reset_system();
@@ -62,7 +62,7 @@ static void __do_machine_kdump(void *data)
* This need to be done *after* s390_reset_system set the
* prefix register of this CPU to zero
*/
- memcpy(absolute_pointer(__LC_FPREGS_SAVE_AREA),
+ memcpy(absolute_pointer(get_lowcore()->floating_pt_save_area),
phys_to_virt(prefix + __LC_FPREGS_SAVE_AREA), 512);
call_nodat(1, int, purgatory, int, 1);
@@ -91,7 +91,7 @@ static noinline void __machine_kdump(void *image)
continue;
}
/* Store status of the boot CPU */
- mcesa = __va(S390_lowcore.mcesad & MCESA_ORIGIN_MASK);
+ mcesa = __va(get_lowcore()->mcesad & MCESA_ORIGIN_MASK);
if (cpu_has_vx())
save_vx_regs((__vector128 *) mcesa->vector_save_area);
if (MACHINE_HAS_GS) {
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 42215f9404af..91e207b50394 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -21,6 +21,7 @@
#include <linux/moduleloader.h>
#include <linux/bug.h>
#include <linux/memory.h>
+#include <linux/execmem.h>
#include <asm/alternative.h>
#include <asm/nospec-branch.h>
#include <asm/facility.h>
@@ -36,47 +37,10 @@
#define PLT_ENTRY_SIZE 22
-static unsigned long get_module_load_offset(void)
-{
- static DEFINE_MUTEX(module_kaslr_mutex);
- static unsigned long module_load_offset;
-
- if (!kaslr_enabled())
- return 0;
- /*
- * Calculate the module_load_offset the first time this code
- * is called. Once calculated it stays the same until reboot.
- */
- mutex_lock(&module_kaslr_mutex);
- if (!module_load_offset)
- module_load_offset = get_random_u32_inclusive(1, 1024) * PAGE_SIZE;
- mutex_unlock(&module_kaslr_mutex);
- return module_load_offset;
-}
-
-void *module_alloc(unsigned long size)
-{
- gfp_t gfp_mask = GFP_KERNEL;
- void *p;
-
- if (PAGE_ALIGN(size) > MODULES_LEN)
- return NULL;
- p = __vmalloc_node_range(size, MODULE_ALIGN,
- MODULES_VADDR + get_module_load_offset(),
- MODULES_END, gfp_mask, PAGE_KERNEL,
- VM_FLUSH_RESET_PERMS | VM_DEFER_KMEMLEAK,
- NUMA_NO_NODE, __builtin_return_address(0));
- if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
- vfree(p);
- return NULL;
- }
- return p;
-}
-
#ifdef CONFIG_FUNCTION_TRACER
void module_arch_cleanup(struct module *mod)
{
- module_memfree(mod->arch.trampolines_start);
+ execmem_free(mod->arch.trampolines_start);
}
#endif
@@ -510,7 +474,7 @@ static int module_alloc_ftrace_hotpatch_trampolines(struct module *me,
size = FTRACE_HOTPATCH_TRAMPOLINES_SIZE(s->sh_size);
numpages = DIV_ROUND_UP(size, PAGE_SIZE);
- start = module_alloc(numpages * PAGE_SIZE);
+ start = execmem_alloc(EXECMEM_FTRACE, numpages * PAGE_SIZE);
if (!start)
return -ENOMEM;
set_memory_rox((unsigned long)start, numpages);
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index c77382a67325..fbd218b6fc8e 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -31,6 +31,7 @@
#include <asm/crw.h>
#include <asm/asm-offsets.h>
#include <asm/pai.h>
+#include <asm/vtime.h>
struct mcck_struct {
unsigned int kill_task : 1;
@@ -116,6 +117,7 @@ static __always_inline char *u64_to_hex(char *dest, u64 val)
static notrace void s390_handle_damage(void)
{
+ struct lowcore *lc = get_lowcore();
union ctlreg0 cr0, cr0_new;
char message[100];
psw_t psw_save;
@@ -124,7 +126,7 @@ static notrace void s390_handle_damage(void)
smp_emergency_stop();
diag_amode31_ops.diag308_reset();
ptr = nmi_puts(message, "System stopped due to unrecoverable machine check, code: 0x");
- u64_to_hex(ptr, S390_lowcore.mcck_interruption_code);
+ u64_to_hex(ptr, lc->mcck_interruption_code);
/*
* Disable low address protection and make machine check new PSW a
@@ -134,17 +136,17 @@ static notrace void s390_handle_damage(void)
cr0_new = cr0;
cr0_new.lap = 0;
local_ctl_load(0, &cr0_new.reg);
- psw_save = S390_lowcore.mcck_new_psw;
- psw_bits(S390_lowcore.mcck_new_psw).io = 0;
- psw_bits(S390_lowcore.mcck_new_psw).ext = 0;
- psw_bits(S390_lowcore.mcck_new_psw).wait = 1;
+ psw_save = lc->mcck_new_psw;
+ psw_bits(lc->mcck_new_psw).io = 0;
+ psw_bits(lc->mcck_new_psw).ext = 0;
+ psw_bits(lc->mcck_new_psw).wait = 1;
sclp_emergency_printk(message);
/*
* Restore machine check new PSW and control register 0 to original
* values. This makes possible system dump analysis easier.
*/
- S390_lowcore.mcck_new_psw = psw_save;
+ lc->mcck_new_psw = psw_save;
local_ctl_load(0, &cr0.reg);
disabled_wait();
while (1);
@@ -225,7 +227,7 @@ static bool notrace nmi_registers_valid(union mci mci)
/*
* Set the clock comparator register to the next expected value.
*/
- set_clock_comparator(S390_lowcore.clock_comparator);
+ set_clock_comparator(get_lowcore()->clock_comparator);
if (!mci.gr || !mci.fp || !mci.fc)
return false;
/*
@@ -251,7 +253,7 @@ static bool notrace nmi_registers_valid(union mci mci)
* check handling must take care of this. The host values are saved by
* KVM and are not affected.
*/
- cr2.reg = S390_lowcore.cregs_save_area[2];
+ cr2.reg = get_lowcore()->cregs_save_area[2];
if (cr2.gse && !mci.gs && !test_cpu_flag(CIF_MCCK_GUEST))
return false;
if (!mci.ms || !mci.pm || !mci.ia)
@@ -277,11 +279,10 @@ static void notrace s390_backup_mcck_info(struct pt_regs *regs)
sie_page = container_of(sie_block, struct sie_page, sie_block);
mcck_backup = &sie_page->mcck_info;
- mcck_backup->mcic = S390_lowcore.mcck_interruption_code &
+ mcck_backup->mcic = get_lowcore()->mcck_interruption_code &
~(MCCK_CODE_CP | MCCK_CODE_EXT_DAMAGE);
- mcck_backup->ext_damage_code = S390_lowcore.external_damage_code;
- mcck_backup->failing_storage_address
- = S390_lowcore.failing_storage_address;
+ mcck_backup->ext_damage_code = get_lowcore()->external_damage_code;
+ mcck_backup->failing_storage_address = get_lowcore()->failing_storage_address;
}
NOKPROBE_SYMBOL(s390_backup_mcck_info);
@@ -301,6 +302,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
static int ipd_count;
static DEFINE_SPINLOCK(ipd_lock);
static unsigned long long last_ipd;
+ struct lowcore *lc = get_lowcore();
struct mcck_struct *mcck;
unsigned long long tmp;
irqentry_state_t irq_state;
@@ -313,7 +315,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
if (user_mode(regs))
update_timer_mcck();
inc_irq_stat(NMI_NMI);
- mci.val = S390_lowcore.mcck_interruption_code;
+ mci.val = lc->mcck_interruption_code;
mcck = this_cpu_ptr(&cpu_mcck);
/*
@@ -381,9 +383,9 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
}
if (mci.ed && mci.ec) {
/* External damage */
- if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
+ if (lc->external_damage_code & (1U << ED_STP_SYNC))
mcck->stp_queue |= stp_sync_check();
- if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
+ if (lc->external_damage_code & (1U << ED_STP_ISLAND))
mcck->stp_queue |= stp_island_check();
mcck_pending = 1;
}
diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c
index d1b16d83e49a..e11ec15960a1 100644
--- a/arch/s390/kernel/nospec-branch.c
+++ b/arch/s390/kernel/nospec-branch.c
@@ -4,6 +4,8 @@
#include <linux/cpu.h>
#include <asm/nospec-branch.h>
+int nobp = IS_ENABLED(CONFIG_KERNEL_NOBP);
+
static int __init nobp_setup_early(char *str)
{
bool enabled;
@@ -17,11 +19,11 @@ static int __init nobp_setup_early(char *str)
* The user explicitly requested nobp=1, enable it and
* disable the expoline support.
*/
- __set_facility(82, alt_stfle_fac_list);
+ nobp = 1;
if (IS_ENABLED(CONFIG_EXPOLINE))
nospec_disable = 1;
} else {
- __clear_facility(82, alt_stfle_fac_list);
+ nobp = 0;
}
return 0;
}
@@ -29,7 +31,7 @@ early_param("nobp", nobp_setup_early);
static int __init nospec_setup_early(char *str)
{
- __clear_facility(82, alt_stfle_fac_list);
+ nobp = 0;
return 0;
}
early_param("nospec", nospec_setup_early);
@@ -40,7 +42,7 @@ static int __init nospec_report(void)
pr_info("Spectre V2 mitigation: etokens\n");
if (nospec_uses_trampoline())
pr_info("Spectre V2 mitigation: execute trampolines\n");
- if (__test_facility(82, alt_stfle_fac_list))
+ if (nobp_enabled())
pr_info("Spectre V2 mitigation: limited branch prediction\n");
return 0;
}
@@ -66,14 +68,14 @@ void __init nospec_auto_detect(void)
*/
if (__is_defined(CC_USING_EXPOLINE))
nospec_disable = 1;
- __clear_facility(82, alt_stfle_fac_list);
+ nobp = 0;
} else if (__is_defined(CC_USING_EXPOLINE)) {
/*
* The kernel has been compiled with expolines.
* Keep expolines enabled and disable nobp.
*/
nospec_disable = 0;
- __clear_facility(82, alt_stfle_fac_list);
+ nobp = 0;
}
/*
* If the kernel has not been compiled with expolines the
@@ -86,7 +88,7 @@ static int __init spectre_v2_setup_early(char *str)
{
if (str && !strncmp(str, "on", 2)) {
nospec_disable = 0;
- __clear_facility(82, alt_stfle_fac_list);
+ nobp = 0;
}
if (str && !strncmp(str, "off", 3))
nospec_disable = 1;
@@ -114,10 +116,10 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
type = BRASL_EXPOLINE; /* brasl instruction */
else
continue;
- thunk = instr + (*(int *)(instr + 2)) * 2;
+ thunk = instr + (long)(*(int *)(instr + 2)) * 2;
if (thunk[0] == 0xc6 && thunk[1] == 0x00)
/* exrl %r0,<target-br> */
- br = thunk + (*(int *)(thunk + 2)) * 2;
+ br = thunk + (long)(*(int *)(thunk + 2)) * 2;
else
continue;
if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0)
diff --git a/arch/s390/kernel/nospec-sysfs.c b/arch/s390/kernel/nospec-sysfs.c
index 52d4353188ad..a95188818637 100644
--- a/arch/s390/kernel/nospec-sysfs.c
+++ b/arch/s390/kernel/nospec-sysfs.c
@@ -17,7 +17,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev,
return sprintf(buf, "Mitigation: etokens\n");
if (nospec_uses_trampoline())
return sprintf(buf, "Mitigation: execute trampolines\n");
- if (__test_facility(82, alt_stfle_fac_list))
+ if (nobp_enabled())
return sprintf(buf, "Mitigation: limited branch prediction\n");
return sprintf(buf, "Vulnerable\n");
}
diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
index a801e6bd5341..b695f980bbde 100644
--- a/arch/s390/kernel/os_info.c
+++ b/arch/s390/kernel/os_info.c
@@ -15,8 +15,10 @@
#include <asm/checksum.h>
#include <asm/abs_lowcore.h>
#include <asm/os_info.h>
+#include <asm/physmem_info.h>
#include <asm/maccess.h>
#include <asm/asm-offsets.h>
+#include <asm/ipl.h>
/*
* OS info structure has to be page aligned
@@ -43,9 +45,9 @@ void os_info_crashkernel_add(unsigned long base, unsigned long size)
}
/*
- * Add OS info entry and update checksum
+ * Add OS info data entry and update checksum
*/
-void os_info_entry_add(int nr, void *ptr, u64 size)
+void os_info_entry_add_data(int nr, void *ptr, u64 size)
{
os_info.entry[nr].addr = __pa(ptr);
os_info.entry[nr].size = size;
@@ -54,15 +56,36 @@ void os_info_entry_add(int nr, void *ptr, u64 size)
}
/*
+ * Add OS info value entry and update checksum
+ */
+void os_info_entry_add_val(int nr, u64 value)
+{
+ os_info.entry[nr].val = value;
+ os_info.entry[nr].size = 0;
+ os_info.entry[nr].csum = 0;
+ os_info.csum = os_info_csum(&os_info);
+}
+
+/*
* Initialize OS info structure and set lowcore pointer
*/
void __init os_info_init(void)
{
struct lowcore *abs_lc;
+ BUILD_BUG_ON(sizeof(struct os_info) != PAGE_SIZE);
os_info.version_major = OS_INFO_VERSION_MAJOR;
os_info.version_minor = OS_INFO_VERSION_MINOR;
os_info.magic = OS_INFO_MAGIC;
+ os_info_entry_add_val(OS_INFO_IDENTITY_BASE, __identity_base);
+ os_info_entry_add_val(OS_INFO_KASLR_OFFSET, kaslr_offset());
+ os_info_entry_add_val(OS_INFO_KASLR_OFF_PHYS, __kaslr_offset_phys);
+ os_info_entry_add_val(OS_INFO_VMEMMAP, (unsigned long)vmemmap);
+ os_info_entry_add_val(OS_INFO_AMODE31_START, AMODE31_START);
+ os_info_entry_add_val(OS_INFO_AMODE31_END, AMODE31_END);
+ os_info_entry_add_val(OS_INFO_IMAGE_START, (unsigned long)_stext);
+ os_info_entry_add_val(OS_INFO_IMAGE_END, (unsigned long)_end);
+ os_info_entry_add_val(OS_INFO_IMAGE_PHYS, __pa_symbol(_stext));
os_info.csum = os_info_csum(&os_info);
abs_lc = get_abs_lowcore();
abs_lc->os_info = __pa(&os_info);
@@ -125,7 +148,7 @@ static void os_info_old_init(void)
if (os_info_init)
return;
- if (!oldmem_data.start)
+ if (!oldmem_data.start && !is_ipl_type_dump())
goto fail;
if (copy_oldmem_kernel(&addr, __LC_OS_INFO, sizeof(addr)))
goto fail;
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index 41ed6e0f0a2a..6968be98af11 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -428,7 +428,7 @@ static void cpum_cf_make_setsize(enum cpumf_ctr_set ctrset)
case CPUMF_CTR_SET_CRYPTO:
if (cpumf_ctr_info.csvn >= 1 && cpumf_ctr_info.csvn <= 5)
ctrset_size = 16;
- else if (cpumf_ctr_info.csvn == 6 || cpumf_ctr_info.csvn == 7)
+ else if (cpumf_ctr_info.csvn >= 6)
ctrset_size = 20;
break;
case CPUMF_CTR_SET_EXT:
@@ -556,25 +556,31 @@ static int cfdiag_diffctr(struct cpu_cf_events *cpuhw, unsigned long auth)
struct cf_trailer_entry *trailer_start, *trailer_stop;
struct cf_ctrset_entry *ctrstart, *ctrstop;
size_t offset = 0;
+ int i;
- auth &= (1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1;
- do {
+ for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) {
ctrstart = (struct cf_ctrset_entry *)(cpuhw->start + offset);
ctrstop = (struct cf_ctrset_entry *)(cpuhw->stop + offset);
+ /* Counter set not authorized */
+ if (!(auth & cpumf_ctr_ctl[i]))
+ continue;
+ /* Counter set size zero was not saved */
+ if (!cpum_cf_read_setsize(i))
+ continue;
+
if (memcmp(ctrstop, ctrstart, sizeof(*ctrstop))) {
pr_err_once("cpum_cf_diag counter set compare error "
"in set %i\n", ctrstart->set);
return 0;
}
- auth &= ~cpumf_ctr_ctl[ctrstart->set];
if (ctrstart->def == CF_DIAG_CTRSET_DEF) {
cfdiag_diffctrset((u64 *)(ctrstart + 1),
(u64 *)(ctrstop + 1), ctrstart->ctr);
offset += ctrstart->ctr * sizeof(u64) +
sizeof(*ctrstart);
}
- } while (ctrstart->def && auth);
+ }
/* Save time_stamp from start of event in stop's trailer */
trailer_start = (struct cf_trailer_entry *)(cpuhw->start + offset);
diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c
index 0d64aafd158f..e4a6bfc91080 100644
--- a/arch/s390/kernel/perf_cpum_cf_events.c
+++ b/arch/s390/kernel/perf_cpum_cf_events.c
@@ -855,16 +855,11 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
}
/* Determine version specific crypto set */
- switch (ci.csvn) {
- case 1 ... 5:
+ csvn = none;
+ if (ci.csvn >= 1 && ci.csvn <= 5)
csvn = cpumcf_svn_12345_pmu_event_attr;
- break;
- case 6 ... 7:
+ else if (ci.csvn >= 6)
csvn = cpumcf_svn_67_pmu_event_attr;
- break;
- default:
- csvn = none;
- }
/* Determine model-specific counter set(s) */
get_cpu_id(&cpu_id);
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index 06efad5b4f93..736c1d9632dd 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -1022,7 +1022,7 @@ static void cpumsf_pmu_enable(struct pmu *pmu)
}
/* Load current program parameter */
- lpp(&S390_lowcore.lpp);
+ lpp(&get_lowcore()->lpp);
debug_sprintf_event(sfdbg, 6, "%s: es %i cs %i ed %i cd %i "
"interval %#lx tear %#lx dear %#lx\n", __func__,
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c
index dfa77da2fd2e..5fff629b1a89 100644
--- a/arch/s390/kernel/perf_event.c
+++ b/arch/s390/kernel/perf_event.c
@@ -218,39 +218,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
struct pt_regs *regs)
{
- struct stack_frame_user __user *sf;
- unsigned long ip, sp;
- bool first = true;
-
- if (is_compat_task())
- return;
- perf_callchain_store(entry, instruction_pointer(regs));
- sf = (void __user *)user_stack_pointer(regs);
- pagefault_disable();
- while (entry->nr < entry->max_stack) {
- if (__get_user(sp, &sf->back_chain))
- break;
- if (__get_user(ip, &sf->gprs[8]))
- break;
- if (ip & 0x1) {
- /*
- * If the instruction address is invalid, and this
- * is the first stack frame, assume r14 has not
- * been written to the stack yet. Otherwise exit.
- */
- if (first && !(regs->gprs[14] & 0x1))
- ip = regs->gprs[14];
- else
- break;
- }
- perf_callchain_store(entry, ip);
- /* Sanity check: ABI requires SP to be aligned 8 bytes. */
- if (!sp || sp & 0x7)
- break;
- sf = (void __user *)sp;
- first = false;
- }
- pagefault_enable();
+ arch_stack_walk_user_common(NULL, NULL, entry, regs, true);
}
/* Perf definitions for PMU event attributes in sysfs */
diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
index 4ad472d130a3..2f5a20e300f6 100644
--- a/arch/s390/kernel/perf_pai_crypto.c
+++ b/arch/s390/kernel/perf_pai_crypto.c
@@ -36,8 +36,8 @@ struct paicrypt_map {
struct pai_userdata *save; /* Page to store no-zero counters */
unsigned int active_events; /* # of PAI crypto users */
refcount_t refcnt; /* Reference count mapped buffers */
- enum paievt_mode mode; /* Type of event */
struct perf_event *event; /* Perf event for sampling */
+ struct list_head syswide_list; /* List system-wide sampling events */
};
struct paicrypt_mapptr {
@@ -84,20 +84,16 @@ static DEFINE_MUTEX(pai_reserve_mutex);
/* Adjust usage counters and remove allocated memory when all users are
* gone.
*/
-static void paicrypt_event_destroy(struct perf_event *event)
+static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu)
{
- struct paicrypt_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr,
- event->cpu);
+ struct paicrypt_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu);
struct paicrypt_map *cpump = mp->mapptr;
- static_branch_dec(&pai_key);
mutex_lock(&pai_reserve_mutex);
- debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
- " mode %d refcnt %u\n", __func__,
- event->attr.config, event->cpu,
- cpump->active_events, cpump->mode,
+ debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d "
+ "refcnt %u\n", __func__, event->attr.config,
+ event->cpu, cpump->active_events,
refcount_read(&cpump->refcnt));
- free_page(PAI_SAVE_AREA(event));
if (refcount_dec_and_test(&cpump->refcnt)) {
debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n",
__func__, (unsigned long)cpump->page,
@@ -111,6 +107,23 @@ static void paicrypt_event_destroy(struct perf_event *event)
mutex_unlock(&pai_reserve_mutex);
}
+static void paicrypt_event_destroy(struct perf_event *event)
+{
+ int cpu;
+
+ static_branch_dec(&pai_key);
+ free_page(PAI_SAVE_AREA(event));
+ if (event->cpu == -1) {
+ struct cpumask *mask = PAI_CPU_MASK(event);
+
+ for_each_cpu(cpu, mask)
+ paicrypt_event_destroy_cpu(event, cpu);
+ kfree(mask);
+ } else {
+ paicrypt_event_destroy_cpu(event, event->cpu);
+ }
+}
+
static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel)
{
if (kernel)
@@ -156,23 +169,15 @@ static u64 paicrypt_getall(struct perf_event *event)
return sum;
}
-/* Used to avoid races in checking concurrent access of counting and
- * sampling for crypto events
- *
- * Only one instance of event pai_crypto/CRYPTO_ALL/ for sampling is
- * allowed and when this event is running, no counting event is allowed.
- * Several counting events are allowed in parallel, but no sampling event
- * is allowed while one (or more) counting events are running.
- *
+/* Check concurrent access of counting and sampling for crypto events.
* This function is called in process context and it is save to block.
* When the event initialization functions fails, no other call back will
* be invoked.
*
* Allocate the memory for the event.
*/
-static struct paicrypt_map *paicrypt_busy(struct perf_event *event)
+static struct paicrypt_map *paicrypt_busy(struct perf_event *event, int cpu)
{
- struct perf_event_attr *a = &event->attr;
struct paicrypt_map *cpump = NULL;
struct paicrypt_mapptr *mp;
int rc;
@@ -185,7 +190,7 @@ static struct paicrypt_map *paicrypt_busy(struct perf_event *event)
goto unlock;
/* Allocate node for this event */
- mp = per_cpu_ptr(paicrypt_root.mapptr, event->cpu);
+ mp = per_cpu_ptr(paicrypt_root.mapptr, cpu);
cpump = mp->mapptr;
if (!cpump) { /* Paicrypt_map allocated? */
cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
@@ -193,25 +198,9 @@ static struct paicrypt_map *paicrypt_busy(struct perf_event *event)
rc = -ENOMEM;
goto free_root;
}
+ INIT_LIST_HEAD(&cpump->syswide_list);
}
- if (a->sample_period) { /* Sampling requested */
- if (cpump->mode != PAI_MODE_NONE)
- rc = -EBUSY; /* ... sampling/counting active */
- } else { /* Counting requested */
- if (cpump->mode == PAI_MODE_SAMPLING)
- rc = -EBUSY; /* ... and sampling active */
- }
- /*
- * This error case triggers when there is a conflict:
- * Either sampling requested and counting already active, or visa
- * versa. Therefore the struct paicrypto_map for this CPU is
- * needed or the error could not have occurred. Only adjust root
- * node refcount.
- */
- if (rc)
- goto free_root;
-
/* Allocate memory for counter page and counter extraction.
* Only the first counting event has to allocate a page.
*/
@@ -235,26 +224,58 @@ static struct paicrypt_map *paicrypt_busy(struct perf_event *event)
/* Set mode and reference count */
rc = 0;
refcount_set(&cpump->refcnt, 1);
- cpump->mode = a->sample_period ? PAI_MODE_SAMPLING : PAI_MODE_COUNTING;
mp->mapptr = cpump;
- debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx users %d"
- " mode %d refcnt %u page %#lx save %p rc %d\n",
- __func__, a->sample_period, cpump->active_events,
- cpump->mode, refcount_read(&cpump->refcnt),
+ debug_sprintf_event(cfm_dbg, 5, "%s users %d refcnt %u page %#lx "
+ "save %p rc %d\n", __func__, cpump->active_events,
+ refcount_read(&cpump->refcnt),
(unsigned long)cpump->page, cpump->save, rc);
goto unlock;
free_paicrypt_map:
+ /* Undo memory allocation */
kfree(cpump);
mp->mapptr = NULL;
free_root:
paicrypt_root_free();
-
unlock:
mutex_unlock(&pai_reserve_mutex);
return rc ? ERR_PTR(rc) : cpump;
}
+static int paicrypt_event_init_all(struct perf_event *event)
+{
+ struct paicrypt_map *cpump;
+ struct cpumask *maskptr;
+ int cpu, rc = -ENOMEM;
+
+ maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL);
+ if (!maskptr)
+ goto out;
+
+ for_each_online_cpu(cpu) {
+ cpump = paicrypt_busy(event, cpu);
+ if (IS_ERR(cpump)) {
+ for_each_cpu(cpu, maskptr)
+ paicrypt_event_destroy_cpu(event, cpu);
+ kfree(maskptr);
+ rc = PTR_ERR(cpump);
+ goto out;
+ }
+ cpumask_set_cpu(cpu, maskptr);
+ }
+
+ /*
+ * On error all cpumask are freed and all events have been destroyed.
+ * Save of which CPUs data structures have been allocated for.
+ * Release them in paicrypt_event_destroy call back function
+ * for this event.
+ */
+ PAI_CPU_MASK(event) = maskptr;
+ rc = 0;
+out:
+ return rc;
+}
+
/* Might be called on different CPU than the one the event is intended for. */
static int paicrypt_event_init(struct perf_event *event)
{
@@ -269,10 +290,7 @@ static int paicrypt_event_init(struct perf_event *event)
if (a->config < PAI_CRYPTO_BASE ||
a->config > PAI_CRYPTO_BASE + paicrypt_cnt)
return -EINVAL;
- /* Allow only CPU wide operation, no process context for now. */
- if ((event->attach_state & PERF_ATTACH_TASK) || event->cpu == -1)
- return -ENOENT;
- /* Allow only CRYPTO_ALL for sampling. */
+ /* Allow only CRYPTO_ALL for sampling */
if (a->sample_period && a->config != PAI_CRYPTO_BASE)
return -EINVAL;
/* Get a page to store last counter values for sampling */
@@ -284,13 +302,17 @@ static int paicrypt_event_init(struct perf_event *event)
}
}
- cpump = paicrypt_busy(event);
- if (IS_ERR(cpump)) {
+ if (event->cpu >= 0) {
+ cpump = paicrypt_busy(event, event->cpu);
+ if (IS_ERR(cpump))
+ rc = PTR_ERR(cpump);
+ } else {
+ rc = paicrypt_event_init_all(event);
+ }
+ if (rc) {
free_page(PAI_SAVE_AREA(event));
- rc = PTR_ERR(cpump);
goto out;
}
-
event->destroy = paicrypt_event_destroy;
if (a->sample_period) {
@@ -331,8 +353,14 @@ static void paicrypt_start(struct perf_event *event, int flags)
sum = paicrypt_getall(event); /* Get current value */
local64_set(&event->hw.prev_count, sum);
} else { /* Sampling */
- cpump->event = event;
- perf_sched_cb_inc(event->pmu);
+ memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE);
+ /* Enable context switch callback for system-wide sampling */
+ if (!(event->attach_state & PERF_ATTACH_TASK)) {
+ list_add_tail(PAI_SWLIST(event), &cpump->syswide_list);
+ perf_sched_cb_inc(event->pmu);
+ } else {
+ cpump->event = event;
+ }
}
}
@@ -344,7 +372,7 @@ static int paicrypt_add(struct perf_event *event, int flags)
if (++cpump->active_events == 1) {
ccd = virt_to_phys(cpump->page) | PAI_CRYPTO_KERNEL_OFFSET;
- WRITE_ONCE(S390_lowcore.ccd, ccd);
+ WRITE_ONCE(get_lowcore()->ccd, ccd);
local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT);
}
if (flags & PERF_EF_START)
@@ -353,6 +381,7 @@ static int paicrypt_add(struct perf_event *event, int flags)
return 0;
}
+static void paicrypt_have_sample(struct perf_event *, struct paicrypt_map *);
static void paicrypt_stop(struct perf_event *event, int flags)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
@@ -361,8 +390,13 @@ static void paicrypt_stop(struct perf_event *event, int flags)
if (!event->attr.sample_period) { /* Counting */
paicrypt_read(event);
} else { /* Sampling */
- perf_sched_cb_dec(event->pmu);
- cpump->event = NULL;
+ if (!(event->attach_state & PERF_ATTACH_TASK)) {
+ perf_sched_cb_dec(event->pmu);
+ list_del(PAI_SWLIST(event));
+ } else {
+ paicrypt_have_sample(event, cpump);
+ cpump->event = NULL;
+ }
}
event->hw.state = PERF_HES_STOPPED;
}
@@ -375,7 +409,7 @@ static void paicrypt_del(struct perf_event *event, int flags)
paicrypt_stop(event, PERF_EF_UPDATE);
if (--cpump->active_events == 0) {
local_ctl_clear_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT);
- WRITE_ONCE(S390_lowcore.ccd, 0);
+ WRITE_ONCE(get_lowcore()->ccd, 0);
}
}
@@ -455,23 +489,30 @@ static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump,
}
/* Check if there is data to be saved on schedule out of a task. */
-static int paicrypt_have_sample(void)
+static void paicrypt_have_sample(struct perf_event *event,
+ struct paicrypt_map *cpump)
{
- struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
- struct paicrypt_map *cpump = mp->mapptr;
- struct perf_event *event = cpump->event;
size_t rawsize;
- int rc = 0;
if (!event) /* No event active */
- return 0;
+ return;
rawsize = paicrypt_copy(cpump->save, cpump->page,
(unsigned long *)PAI_SAVE_AREA(event),
- cpump->event->attr.exclude_user,
- cpump->event->attr.exclude_kernel);
+ event->attr.exclude_user,
+ event->attr.exclude_kernel);
if (rawsize) /* No incremented counters */
- rc = paicrypt_push_sample(rawsize, cpump, event);
- return rc;
+ paicrypt_push_sample(rawsize, cpump, event);
+}
+
+/* Check if there is data to be saved on schedule out of a task. */
+static void paicrypt_have_samples(void)
+{
+ struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
+ struct paicrypt_map *cpump = mp->mapptr;
+ struct perf_event *event;
+
+ list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
+ paicrypt_have_sample(event, cpump);
}
/* Called on schedule-in and schedule-out. No access to event structure,
@@ -480,10 +521,10 @@ static int paicrypt_have_sample(void)
static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
{
/* We started with a clean page on event installation. So read out
- * results on schedule_out and if page was dirty, clear values.
+ * results on schedule_out and if page was dirty, save old values.
*/
if (!sched_in)
- paicrypt_have_sample();
+ paicrypt_have_samples();
}
/* Attribute definitions for paicrypt interface. As with other CPU
@@ -527,7 +568,7 @@ static const struct attribute_group *paicrypt_attr_groups[] = {
/* Performance monitoring unit for mapped counters */
static struct pmu paicrypt = {
- .task_ctx_nr = perf_invalid_context,
+ .task_ctx_nr = perf_hw_context,
.event_init = paicrypt_event_init,
.add = paicrypt_add,
.del = paicrypt_del,
diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
index a6da7e0cc7a6..6295531b39a2 100644
--- a/arch/s390/kernel/perf_pai_ext.c
+++ b/arch/s390/kernel/perf_pai_ext.c
@@ -47,11 +47,11 @@ struct paiext_cb { /* PAI extension 1 control block */
struct paiext_map {
unsigned long *area; /* Area for CPU to store counters */
struct pai_userdata *save; /* Area to store non-zero counters */
- enum paievt_mode mode; /* Type of event */
unsigned int active_events; /* # of PAI Extension users */
refcount_t refcnt;
struct perf_event *event; /* Perf event for sampling */
struct paiext_cb *paiext_cb; /* PAI extension control block area */
+ struct list_head syswide_list; /* List system-wide sampling events */
};
struct paiext_mapptr {
@@ -70,6 +70,8 @@ static void paiext_root_free(void)
free_percpu(paiext_root.mapptr);
paiext_root.mapptr = NULL;
}
+ debug_sprintf_event(paiext_dbg, 5, "%s root.refcount %d\n", __func__,
+ refcount_read(&paiext_root.refcnt));
}
/* On initialization of first event also allocate per CPU data dynamically.
@@ -115,20 +117,34 @@ static void paiext_free(struct paiext_mapptr *mp)
}
/* Release the PMU if event is the last perf event */
-static void paiext_event_destroy(struct perf_event *event)
+static void paiext_event_destroy_cpu(struct perf_event *event, int cpu)
{
- struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, event->cpu);
+ struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, cpu);
struct paiext_map *cpump = mp->mapptr;
- free_page(PAI_SAVE_AREA(event));
mutex_lock(&paiext_reserve_mutex);
if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
paiext_free(mp);
paiext_root_free();
mutex_unlock(&paiext_reserve_mutex);
- debug_sprintf_event(paiext_dbg, 4, "%s cpu %d mapptr %p\n", __func__,
- event->cpu, mp->mapptr);
+}
+
+static void paiext_event_destroy(struct perf_event *event)
+{
+ int cpu;
+
+ free_page(PAI_SAVE_AREA(event));
+ if (event->cpu == -1) {
+ struct cpumask *mask = PAI_CPU_MASK(event);
+ for_each_cpu(cpu, mask)
+ paiext_event_destroy_cpu(event, cpu);
+ kfree(mask);
+ } else {
+ paiext_event_destroy_cpu(event, event->cpu);
+ }
+ debug_sprintf_event(paiext_dbg, 4, "%s cpu %d\n", __func__,
+ event->cpu);
}
/* Used to avoid races in checking concurrent access of counting and
@@ -145,19 +161,18 @@ static void paiext_event_destroy(struct perf_event *event)
*
* Allocate the memory for the event.
*/
-static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
+static int paiext_alloc_cpu(struct perf_event *event, int cpu)
{
struct paiext_mapptr *mp;
struct paiext_map *cpump;
int rc;
mutex_lock(&paiext_reserve_mutex);
-
rc = paiext_root_alloc();
if (rc)
goto unlock;
- mp = per_cpu_ptr(paiext_root.mapptr, event->cpu);
+ mp = per_cpu_ptr(paiext_root.mapptr, cpu);
cpump = mp->mapptr;
if (!cpump) { /* Paiext_map allocated? */
rc = -ENOMEM;
@@ -185,24 +200,13 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
paiext_free(mp);
goto undo;
}
+ INIT_LIST_HEAD(&cpump->syswide_list);
refcount_set(&cpump->refcnt, 1);
- cpump->mode = a->sample_period ? PAI_MODE_SAMPLING
- : PAI_MODE_COUNTING;
+ rc = 0;
} else {
- /* Multiple invocation, check what is active.
- * Supported are multiple counter events or only one sampling
- * event concurrently at any one time.
- */
- if (cpump->mode == PAI_MODE_SAMPLING ||
- (cpump->mode == PAI_MODE_COUNTING && a->sample_period)) {
- rc = -EBUSY;
- goto undo;
- }
refcount_inc(&cpump->refcnt);
}
- rc = 0;
-
undo:
if (rc) {
/* Error in allocation of event, decrement anchor. Since
@@ -217,6 +221,38 @@ unlock:
return rc;
}
+static int paiext_alloc(struct perf_event *event)
+{
+ struct cpumask *maskptr;
+ int cpu, rc = -ENOMEM;
+
+ maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL);
+ if (!maskptr)
+ goto out;
+
+ for_each_online_cpu(cpu) {
+ rc = paiext_alloc_cpu(event, cpu);
+ if (rc) {
+ for_each_cpu(cpu, maskptr)
+ paiext_event_destroy_cpu(event, cpu);
+ kfree(maskptr);
+ goto out;
+ }
+ cpumask_set_cpu(cpu, maskptr);
+ }
+
+ /*
+ * On error all cpumask are freed and all events have been destroyed.
+ * Save of which CPUs data structures have been allocated for.
+ * Release them in paicrypt_event_destroy call back function
+ * for this event.
+ */
+ PAI_CPU_MASK(event) = maskptr;
+ rc = 0;
+out:
+ return rc;
+}
+
/* The PAI extension 1 control block supports up to 128 entries. Return
* the index within PAIE1_CB given the event number. Also validate event
* number.
@@ -246,9 +282,6 @@ static int paiext_event_init(struct perf_event *event)
rc = paiext_event_valid(event);
if (rc)
return rc;
- /* Allow only CPU wide operation, no process context for now. */
- if ((event->attach_state & PERF_ATTACH_TASK) || event->cpu == -1)
- return -ENOENT;
/* Allow only event NNPA_ALL for sampling. */
if (a->sample_period && a->config != PAI_NNPA_BASE)
return -EINVAL;
@@ -262,7 +295,10 @@ static int paiext_event_init(struct perf_event *event)
return -ENOMEM;
}
- rc = paiext_alloc(a, event);
+ if (event->cpu >= 0)
+ rc = paiext_alloc_cpu(event, event->cpu);
+ else
+ rc = paiext_alloc(event);
if (rc) {
free_page(PAI_SAVE_AREA(event));
return rc;
@@ -334,8 +370,15 @@ static void paiext_start(struct perf_event *event, int flags)
sum = paiext_getall(event); /* Get current value */
local64_set(&event->hw.prev_count, sum);
} else { /* Sampling */
- cpump->event = event;
- perf_sched_cb_inc(event->pmu);
+ memcpy((void *)PAI_SAVE_AREA(event), cpump->area,
+ PAIE1_CTRBLOCK_SZ);
+ /* Enable context switch callback for system-wide sampling */
+ if (!(event->attach_state & PERF_ATTACH_TASK)) {
+ list_add_tail(PAI_SWLIST(event), &cpump->syswide_list);
+ perf_sched_cb_inc(event->pmu);
+ } else {
+ cpump->event = event;
+ }
}
}
@@ -346,12 +389,10 @@ static int paiext_add(struct perf_event *event, int flags)
struct paiext_cb *pcb = cpump->paiext_cb;
if (++cpump->active_events == 1) {
- S390_lowcore.aicd = virt_to_phys(cpump->paiext_cb);
+ get_lowcore()->aicd = virt_to_phys(cpump->paiext_cb);
pcb->acc = virt_to_phys(cpump->area) | 0x1;
/* Enable CPU instruction lookup for PAIE1 control block */
local_ctl_set_bit(0, CR0_PAI_EXTENSION_BIT);
- debug_sprintf_event(paiext_dbg, 4, "%s 1508 %llx acc %llx\n",
- __func__, S390_lowcore.aicd, pcb->acc);
}
if (flags & PERF_EF_START)
paiext_start(event, PERF_EF_RELOAD);
@@ -359,6 +400,7 @@ static int paiext_add(struct perf_event *event, int flags)
return 0;
}
+static void paiext_have_sample(struct perf_event *, struct paiext_map *);
static void paiext_stop(struct perf_event *event, int flags)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
@@ -367,8 +409,13 @@ static void paiext_stop(struct perf_event *event, int flags)
if (!event->attr.sample_period) { /* Counting */
paiext_read(event);
} else { /* Sampling */
- perf_sched_cb_dec(event->pmu);
- cpump->event = NULL;
+ if (!(event->attach_state & PERF_ATTACH_TASK)) {
+ list_del(PAI_SWLIST(event));
+ perf_sched_cb_dec(event->pmu);
+ } else {
+ paiext_have_sample(event, cpump);
+ cpump->event = NULL;
+ }
}
event->hw.state = PERF_HES_STOPPED;
}
@@ -384,9 +431,7 @@ static void paiext_del(struct perf_event *event, int flags)
/* Disable CPU instruction lookup for PAIE1 control block */
local_ctl_clear_bit(0, CR0_PAI_EXTENSION_BIT);
pcb->acc = 0;
- S390_lowcore.aicd = 0;
- debug_sprintf_event(paiext_dbg, 4, "%s 1508 %llx acc %llx\n",
- __func__, S390_lowcore.aicd, pcb->acc);
+ get_lowcore()->aicd = 0;
}
}
@@ -470,21 +515,28 @@ static int paiext_push_sample(size_t rawsize, struct paiext_map *cpump,
}
/* Check if there is data to be saved on schedule out of a task. */
-static int paiext_have_sample(void)
+static void paiext_have_sample(struct perf_event *event,
+ struct paiext_map *cpump)
{
- struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
- struct paiext_map *cpump = mp->mapptr;
- struct perf_event *event = cpump->event;
size_t rawsize;
- int rc = 0;
if (!event)
- return 0;
+ return;
rawsize = paiext_copy(cpump->save, cpump->area,
(unsigned long *)PAI_SAVE_AREA(event));
if (rawsize) /* Incremented counters */
- rc = paiext_push_sample(rawsize, cpump, event);
- return rc;
+ paiext_push_sample(rawsize, cpump, event);
+}
+
+/* Check if there is data to be saved on schedule out of a task. */
+static void paiext_have_samples(void)
+{
+ struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
+ struct paiext_map *cpump = mp->mapptr;
+ struct perf_event *event;
+
+ list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
+ paiext_have_sample(event, cpump);
}
/* Called on schedule-in and schedule-out. No access to event structure,
@@ -493,10 +545,10 @@ static int paiext_have_sample(void)
static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
{
/* We started with a clean page on event installation. So read out
- * results on schedule_out and if page was dirty, clear values.
+ * results on schedule_out and if page was dirty, save old values.
*/
if (!sched_in)
- paiext_have_sample();
+ paiext_have_samples();
}
/* Attribute definitions for pai extension1 interface. As with other CPU
@@ -542,7 +594,7 @@ static const struct attribute_group *paiext_attr_groups[] = {
/* Performance monitoring unit for mapped counters */
static struct pmu paiext = {
- .task_ctx_nr = perf_invalid_context,
+ .task_ctx_nr = perf_hw_context,
.event_init = paiext_event_init,
.add = paiext_add,
.del = paiext_del,
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index dd456b475861..9637aee43c40 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -71,10 +71,10 @@ void flush_thread(void)
void arch_setup_new_exec(void)
{
- if (S390_lowcore.current_pid != current->pid) {
- S390_lowcore.current_pid = current->pid;
+ if (get_lowcore()->current_pid != current->pid) {
+ get_lowcore()->current_pid = current->pid;
if (test_facility(40))
- lpp(&S390_lowcore.lpp);
+ lpp(&get_lowcore()->lpp);
}
}
@@ -86,11 +86,6 @@ void arch_release_task_struct(struct task_struct *tsk)
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
- /*
- * Save the floating-point or vector register state of the current
- * task and set the TIF_FPU flag to lazy restore the FPU register
- * state when returning to user space.
- */
save_user_fpu_regs();
*dst = *src;
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 65c1464eea4f..5ce9a795a0fe 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -17,7 +17,8 @@
#include <linux/mm_types.h>
#include <linux/delay.h>
#include <linux/cpu.h>
-
+#include <linux/smp.h>
+#include <asm/text-patching.h>
#include <asm/diag.h>
#include <asm/facility.h>
#include <asm/elf.h>
@@ -79,6 +80,23 @@ void notrace stop_machine_yield(const struct cpumask *cpumask)
}
}
+static void do_sync_core(void *info)
+{
+ sync_core();
+}
+
+void text_poke_sync(void)
+{
+ on_each_cpu(do_sync_core, NULL, 1);
+}
+
+void text_poke_sync_lock(void)
+{
+ cpus_read_lock();
+ text_poke_sync();
+ cpus_read_unlock();
+}
+
/*
* cpu_init - initializes state that is per-CPU.
*/
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 88087a32ebc6..69fcaf54d5ca 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -9,6 +9,7 @@
#include <asm/asm-offsets.h>
#include <asm/nospec-insn.h>
#include <asm/sigp.h>
+#include <asm/lowcore.h>
GEN_BR_THUNK %r9
@@ -20,20 +21,15 @@
# r3 = Parameter for function
#
SYM_CODE_START(store_status)
- /* Save register one and load save area base */
- stg %r1,__LC_SAVE_AREA_RESTART
+ STMG_LC %r0,%r15,__LC_GPREGS_SAVE_AREA
/* General purpose registers */
- lghi %r1,__LC_GPREGS_SAVE_AREA
- stmg %r0,%r15,0(%r1)
- mvc 8(8,%r1),__LC_SAVE_AREA_RESTART
+ GET_LC %r13
/* Control registers */
- lghi %r1,__LC_CREGS_SAVE_AREA
- stctg %c0,%c15,0(%r1)
+ stctg %c0,%c15,__LC_CREGS_SAVE_AREA(%r13)
/* Access registers */
- lghi %r1,__LC_AREGS_SAVE_AREA
- stam %a0,%a15,0(%r1)
+ stamy %a0,%a15,__LC_AREGS_SAVE_AREA(%r13)
/* Floating point registers */
- lghi %r1,__LC_FPREGS_SAVE_AREA
+ lay %r1,__LC_FPREGS_SAVE_AREA(%r13)
std %f0, 0x00(%r1)
std %f1, 0x08(%r1)
std %f2, 0x10(%r1)
@@ -51,21 +47,21 @@ SYM_CODE_START(store_status)
std %f14,0x70(%r1)
std %f15,0x78(%r1)
/* Floating point control register */
- lghi %r1,__LC_FP_CREG_SAVE_AREA
+ lay %r1,__LC_FP_CREG_SAVE_AREA(%r13)
stfpc 0(%r1)
/* CPU timer */
- lghi %r1,__LC_CPU_TIMER_SAVE_AREA
+ lay %r1,__LC_CPU_TIMER_SAVE_AREA(%r13)
stpt 0(%r1)
/* Store prefix register */
- lghi %r1,__LC_PREFIX_SAVE_AREA
+ lay %r1,__LC_PREFIX_SAVE_AREA(%r13)
stpx 0(%r1)
/* Clock comparator - seven bytes */
- lghi %r1,__LC_CLOCK_COMP_SAVE_AREA
larl %r4,clkcmp
stckc 0(%r4)
+ lay %r1,__LC_CLOCK_COMP_SAVE_AREA(%r13)
mvc 1(7,%r1),1(%r4)
/* Program status word */
- lghi %r1,__LC_PSW_SAVE_AREA
+ lay %r1,__LC_PSW_SAVE_AREA(%r13)
epsw %r4,%r5
st %r4,0(%r1)
st %r5,4(%r1)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 24ed33f044ec..4ec99f73fa27 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -146,16 +146,15 @@ static u32 __amode31_ref *__ctl_linkage_stack = __ctl_linkage_stack_amode31;
static u32 __amode31_ref *__ctl_duct = __ctl_duct_amode31;
unsigned long __bootdata_preserved(max_mappable);
-unsigned long __bootdata(ident_map_size);
struct physmem_info __bootdata(physmem_info);
-unsigned long __bootdata_preserved(__kaslr_offset);
+struct vm_layout __bootdata_preserved(vm_layout);
+EXPORT_SYMBOL(vm_layout);
int __bootdata_preserved(__kaslr_enabled);
unsigned int __bootdata_preserved(zlib_dfltcc_support);
EXPORT_SYMBOL(zlib_dfltcc_support);
u64 __bootdata_preserved(stfle_fac_list[16]);
EXPORT_SYMBOL(stfle_fac_list);
-u64 __bootdata_preserved(alt_stfle_fac_list[16]);
struct oldmem_data __bootdata_preserved(oldmem_data);
unsigned long VMALLOC_START;
@@ -406,6 +405,7 @@ static void __init setup_lowcore(void)
panic("%s: Failed to allocate %zu bytes align=%zx\n",
__func__, sizeof(*lc), sizeof(*lc));
+ lc->pcpu = (unsigned long)per_cpu_ptr(&pcpu_devices, 0);
lc->restart_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_DAT;
lc->restart_psw.addr = __pa(restart_int_handler);
lc->external_new_psw.mask = PSW_KERNEL_BITS;
@@ -421,16 +421,16 @@ static void __init setup_lowcore(void)
lc->clock_comparator = clock_comparator_max;
lc->current_task = (unsigned long)&init_task;
lc->lpp = LPP_MAGIC;
- lc->machine_flags = S390_lowcore.machine_flags;
- lc->preempt_count = S390_lowcore.preempt_count;
+ lc->machine_flags = get_lowcore()->machine_flags;
+ lc->preempt_count = get_lowcore()->preempt_count;
nmi_alloc_mcesa_early(&lc->mcesad);
- lc->sys_enter_timer = S390_lowcore.sys_enter_timer;
- lc->exit_timer = S390_lowcore.exit_timer;
- lc->user_timer = S390_lowcore.user_timer;
- lc->system_timer = S390_lowcore.system_timer;
- lc->steal_timer = S390_lowcore.steal_timer;
- lc->last_update_timer = S390_lowcore.last_update_timer;
- lc->last_update_clock = S390_lowcore.last_update_clock;
+ lc->sys_enter_timer = get_lowcore()->sys_enter_timer;
+ lc->exit_timer = get_lowcore()->exit_timer;
+ lc->user_timer = get_lowcore()->user_timer;
+ lc->system_timer = get_lowcore()->system_timer;
+ lc->steal_timer = get_lowcore()->steal_timer;
+ lc->last_update_timer = get_lowcore()->last_update_timer;
+ lc->last_update_clock = get_lowcore()->last_update_clock;
/*
* Allocate the global restart stack which is the same for
* all CPUs in case *one* of them does a PSW restart.
@@ -439,7 +439,7 @@ static void __init setup_lowcore(void)
lc->mcck_stack = stack_alloc_early() + STACK_INIT_OFFSET;
lc->async_stack = stack_alloc_early() + STACK_INIT_OFFSET;
lc->nodat_stack = stack_alloc_early() + STACK_INIT_OFFSET;
- lc->kernel_stack = S390_lowcore.kernel_stack;
+ lc->kernel_stack = get_lowcore()->kernel_stack;
/*
* Set up PSW restart to call ipl.c:do_restart(). Copy the relevant
* restart data to the absolute zero lowcore. This is necessary if
@@ -455,8 +455,8 @@ static void __init setup_lowcore(void)
lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW);
lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW);
lc->preempt_count = PREEMPT_DISABLED;
- lc->kernel_asce = S390_lowcore.kernel_asce;
- lc->user_asce = S390_lowcore.user_asce;
+ lc->kernel_asce = get_lowcore()->kernel_asce;
+ lc->user_asce = get_lowcore()->user_asce;
system_ctlreg_init_save_area(lc);
abs_lc = get_abs_lowcore();
@@ -765,7 +765,7 @@ static void __init relocate_amode31_section(void)
unsigned long amode31_size = __eamode31 - __samode31;
long amode31_offset, *ptr;
- amode31_offset = physmem_info.reserved[RR_AMODE31].start - (unsigned long)__samode31;
+ amode31_offset = AMODE31_START - (unsigned long)__samode31;
pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size);
/* Move original AMODE31 section to the new one */
@@ -889,6 +889,9 @@ void __init setup_arch(char **cmdline_p)
else
pr_info("Linux is running as a guest in 64-bit mode\n");
+ if (have_relocated_lowcore())
+ pr_info("Lowcore relocated to 0x%px\n", get_lowcore());
+
log_component_list();
/* Have one command line that is parsed and saved in /proc/cmdline */
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 0324649aae0a..fbba37ec53cf 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -74,18 +74,15 @@ enum {
CPU_STATE_CONFIGURED,
};
-static DEFINE_PER_CPU(struct cpu *, cpu_device);
-
-struct pcpu {
- unsigned long ec_mask; /* bit mask for ec_xxx functions */
- unsigned long ec_clk; /* sigp timestamp for ec_xxx */
- signed char state; /* physical cpu state */
- signed char polarization; /* physical polarization */
- u16 address; /* physical cpu address */
-};
-
static u8 boot_core_type;
-static struct pcpu pcpu_devices[NR_CPUS];
+DEFINE_PER_CPU(struct pcpu, pcpu_devices);
+/*
+ * Pointer to the pcpu area of the boot CPU. This is required when a restart
+ * interrupt is triggered on an offline CPU. For that case accessing percpu
+ * data with the common primitives does not work, since the percpu offset is
+ * stored in a non existent lowcore.
+ */
+static struct pcpu *ipl_pcpu;
unsigned int smp_cpu_mt_shift;
EXPORT_SYMBOL(smp_cpu_mt_shift);
@@ -176,8 +173,8 @@ static struct pcpu *pcpu_find_address(const struct cpumask *mask, u16 address)
int cpu;
for_each_cpu(cpu, mask)
- if (pcpu_devices[cpu].address == address)
- return pcpu_devices + cpu;
+ if (per_cpu(pcpu_devices, cpu).address == address)
+ return &per_cpu(pcpu_devices, cpu);
return NULL;
}
@@ -203,7 +200,7 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
mcck_stack = stack_alloc();
if (!lc || !nodat_stack || !async_stack || !mcck_stack)
goto out;
- memcpy(lc, &S390_lowcore, 512);
+ memcpy(lc, get_lowcore(), 512);
memset((char *) lc + 512, 0, sizeof(*lc) - 512);
lc->async_stack = async_stack + STACK_INIT_OFFSET;
lc->nodat_stack = nodat_stack + STACK_INIT_OFFSET;
@@ -232,13 +229,11 @@ out:
return -ENOMEM;
}
-static void pcpu_free_lowcore(struct pcpu *pcpu)
+static void pcpu_free_lowcore(struct pcpu *pcpu, int cpu)
{
unsigned long async_stack, nodat_stack, mcck_stack;
struct lowcore *lc;
- int cpu;
- cpu = pcpu - pcpu_devices;
lc = lowcore_ptr[cpu];
nodat_stack = lc->nodat_stack - STACK_INIT_OFFSET;
async_stack = lc->async_stack - STACK_INIT_OFFSET;
@@ -261,13 +256,14 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
cpumask_set_cpu(cpu, &init_mm.context.cpu_attach_mask);
cpumask_set_cpu(cpu, mm_cpumask(&init_mm));
lc->cpu_nr = cpu;
+ lc->pcpu = (unsigned long)pcpu;
lc->restart_flags = RESTART_FLAG_CTLREGS;
lc->spinlock_lockval = arch_spin_lockval(cpu);
lc->spinlock_index = 0;
lc->percpu_offset = __per_cpu_offset[cpu];
- lc->kernel_asce = S390_lowcore.kernel_asce;
+ lc->kernel_asce = get_lowcore()->kernel_asce;
lc->user_asce = s390_invalid_asce;
- lc->machine_flags = S390_lowcore.machine_flags;
+ lc->machine_flags = get_lowcore()->machine_flags;
lc->user_timer = lc->system_timer =
lc->steal_timer = lc->avg_steal_timer = 0;
abs_lc = get_abs_lowcore();
@@ -279,12 +275,10 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
arch_spin_lock_setup(cpu);
}
-static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
+static void pcpu_attach_task(int cpu, struct task_struct *tsk)
{
struct lowcore *lc;
- int cpu;
- cpu = pcpu - pcpu_devices;
lc = lowcore_ptr[cpu];
lc->kernel_stack = (unsigned long)task_stack_page(tsk) + STACK_INIT_OFFSET;
lc->current_task = (unsigned long)tsk;
@@ -298,18 +292,16 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
lc->steal_timer = 0;
}
-static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data)
+static void pcpu_start_fn(int cpu, void (*func)(void *), void *data)
{
struct lowcore *lc;
- int cpu;
- cpu = pcpu - pcpu_devices;
lc = lowcore_ptr[cpu];
lc->restart_stack = lc->kernel_stack;
lc->restart_fn = (unsigned long) func;
lc->restart_data = (unsigned long) data;
lc->restart_source = -1U;
- pcpu_sigp_retry(pcpu, SIGP_RESTART, 0);
+ pcpu_sigp_retry(per_cpu_ptr(&pcpu_devices, cpu), SIGP_RESTART, 0);
}
typedef void (pcpu_delegate_fn)(void *);
@@ -322,14 +314,14 @@ static void __pcpu_delegate(pcpu_delegate_fn *func, void *data)
func(data); /* should not return */
}
-static void pcpu_delegate(struct pcpu *pcpu,
+static void pcpu_delegate(struct pcpu *pcpu, int cpu,
pcpu_delegate_fn *func,
void *data, unsigned long stack)
{
struct lowcore *lc, *abs_lc;
unsigned int source_cpu;
- lc = lowcore_ptr[pcpu - pcpu_devices];
+ lc = lowcore_ptr[cpu];
source_cpu = stap();
if (pcpu->address == source_cpu) {
@@ -379,38 +371,22 @@ static int pcpu_set_smt(unsigned int mtid)
smp_cpu_mt_shift = 0;
while (smp_cpu_mtid >= (1U << smp_cpu_mt_shift))
smp_cpu_mt_shift++;
- pcpu_devices[0].address = stap();
+ per_cpu(pcpu_devices, 0).address = stap();
}
return cc;
}
/*
- * Call function on an online CPU.
- */
-void smp_call_online_cpu(void (*func)(void *), void *data)
-{
- struct pcpu *pcpu;
-
- /* Use the current cpu if it is online. */
- pcpu = pcpu_find_address(cpu_online_mask, stap());
- if (!pcpu)
- /* Use the first online cpu. */
- pcpu = pcpu_devices + cpumask_first(cpu_online_mask);
- pcpu_delegate(pcpu, func, data, (unsigned long) restart_stack);
-}
-
-/*
* Call function on the ipl CPU.
*/
void smp_call_ipl_cpu(void (*func)(void *), void *data)
{
struct lowcore *lc = lowcore_ptr[0];
- if (pcpu_devices[0].address == stap())
- lc = &S390_lowcore;
+ if (ipl_pcpu->address == stap())
+ lc = get_lowcore();
- pcpu_delegate(&pcpu_devices[0], func, data,
- lc->nodat_stack);
+ pcpu_delegate(ipl_pcpu, 0, func, data, lc->nodat_stack);
}
int smp_find_processor_id(u16 address)
@@ -418,21 +394,21 @@ int smp_find_processor_id(u16 address)
int cpu;
for_each_present_cpu(cpu)
- if (pcpu_devices[cpu].address == address)
+ if (per_cpu(pcpu_devices, cpu).address == address)
return cpu;
return -1;
}
void schedule_mcck_handler(void)
{
- pcpu_ec_call(pcpu_devices + smp_processor_id(), ec_mcck_pending);
+ pcpu_ec_call(this_cpu_ptr(&pcpu_devices), ec_mcck_pending);
}
bool notrace arch_vcpu_is_preempted(int cpu)
{
if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
return false;
- if (pcpu_running(pcpu_devices + cpu))
+ if (pcpu_running(per_cpu_ptr(&pcpu_devices, cpu)))
return false;
return true;
}
@@ -444,7 +420,7 @@ void notrace smp_yield_cpu(int cpu)
return;
diag_stat_inc_norecursion(DIAG_STAT_X09C);
asm volatile("diag %0,0,0x9c"
- : : "d" (pcpu_devices[cpu].address));
+ : : "d" (per_cpu(pcpu_devices, cpu).address));
}
EXPORT_SYMBOL_GPL(smp_yield_cpu);
@@ -465,7 +441,7 @@ void notrace smp_emergency_stop(void)
end = get_tod_clock() + (1000000UL << 12);
for_each_cpu(cpu, &cpumask) {
- struct pcpu *pcpu = pcpu_devices + cpu;
+ struct pcpu *pcpu = per_cpu_ptr(&pcpu_devices, cpu);
set_bit(ec_stop_cpu, &pcpu->ec_mask);
while (__pcpu_sigp(pcpu->address, SIGP_EMERGENCY_SIGNAL,
0, NULL) == SIGP_CC_BUSY &&
@@ -474,7 +450,7 @@ void notrace smp_emergency_stop(void)
}
while (get_tod_clock() < end) {
for_each_cpu(cpu, &cpumask)
- if (pcpu_stopped(pcpu_devices + cpu))
+ if (pcpu_stopped(per_cpu_ptr(&pcpu_devices, cpu)))
cpumask_clear_cpu(cpu, &cpumask);
if (cpumask_empty(&cpumask))
break;
@@ -489,6 +465,7 @@ NOKPROBE_SYMBOL(smp_emergency_stop);
*/
void smp_send_stop(void)
{
+ struct pcpu *pcpu;
int cpu;
/* Disable all interrupts/machine checks */
@@ -504,8 +481,9 @@ void smp_send_stop(void)
for_each_online_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
- pcpu_sigp_retry(pcpu_devices + cpu, SIGP_STOP, 0);
- while (!pcpu_stopped(pcpu_devices + cpu))
+ pcpu = per_cpu_ptr(&pcpu_devices, cpu);
+ pcpu_sigp_retry(pcpu, SIGP_STOP, 0);
+ while (!pcpu_stopped(pcpu))
cpu_relax();
}
}
@@ -519,7 +497,7 @@ static void smp_handle_ext_call(void)
unsigned long bits;
/* handle bit signal external calls */
- bits = xchg(&pcpu_devices[smp_processor_id()].ec_mask, 0);
+ bits = this_cpu_xchg(pcpu_devices.ec_mask, 0);
if (test_bit(ec_stop_cpu, &bits))
smp_stop_cpu();
if (test_bit(ec_schedule, &bits))
@@ -544,12 +522,12 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
int cpu;
for_each_cpu(cpu, mask)
- pcpu_ec_call(pcpu_devices + cpu, ec_call_function_single);
+ pcpu_ec_call(per_cpu_ptr(&pcpu_devices, cpu), ec_call_function_single);
}
void arch_send_call_function_single_ipi(int cpu)
{
- pcpu_ec_call(pcpu_devices + cpu, ec_call_function_single);
+ pcpu_ec_call(per_cpu_ptr(&pcpu_devices, cpu), ec_call_function_single);
}
/*
@@ -559,13 +537,13 @@ void arch_send_call_function_single_ipi(int cpu)
*/
void arch_smp_send_reschedule(int cpu)
{
- pcpu_ec_call(pcpu_devices + cpu, ec_schedule);
+ pcpu_ec_call(per_cpu_ptr(&pcpu_devices, cpu), ec_schedule);
}
#ifdef CONFIG_IRQ_WORK
void arch_irq_work_raise(void)
{
- pcpu_ec_call(pcpu_devices + smp_processor_id(), ec_irq_work);
+ pcpu_ec_call(this_cpu_ptr(&pcpu_devices), ec_irq_work);
}
#endif
@@ -577,7 +555,7 @@ int smp_store_status(int cpu)
struct pcpu *pcpu;
unsigned long pa;
- pcpu = pcpu_devices + cpu;
+ pcpu = per_cpu_ptr(&pcpu_devices, cpu);
lc = lowcore_ptr[cpu];
pa = __pa(&lc->floating_pt_save_area);
if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_STATUS_AT_ADDRESS,
@@ -685,17 +663,17 @@ void __init smp_save_dump_secondary_cpus(void)
void smp_cpu_set_polarization(int cpu, int val)
{
- pcpu_devices[cpu].polarization = val;
+ per_cpu(pcpu_devices, cpu).polarization = val;
}
int smp_cpu_get_polarization(int cpu)
{
- return pcpu_devices[cpu].polarization;
+ return per_cpu(pcpu_devices, cpu).polarization;
}
int smp_cpu_get_cpu_address(int cpu)
{
- return pcpu_devices[cpu].address;
+ return per_cpu(pcpu_devices, cpu).address;
}
static void __ref smp_get_core_info(struct sclp_core_info *info, int early)
@@ -719,8 +697,6 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early)
}
}
-static int smp_add_present_cpu(int cpu);
-
static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
bool configured, bool early)
{
@@ -736,7 +712,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
for (i = 0; (i <= smp_cpu_mtid) && (cpu < nr_cpu_ids); i++) {
if (pcpu_find_address(cpu_present_mask, address + i))
continue;
- pcpu = pcpu_devices + cpu;
+ pcpu = per_cpu_ptr(&pcpu_devices, cpu);
pcpu->address = address + i;
if (configured)
pcpu->state = CPU_STATE_CONFIGURED;
@@ -744,7 +720,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
pcpu->state = CPU_STATE_STANDBY;
smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
set_cpu_present(cpu, true);
- if (!early && smp_add_present_cpu(cpu) != 0)
+ if (!early && arch_register_cpu(cpu))
set_cpu_present(cpu, false);
else
nr++;
@@ -771,7 +747,7 @@ static int __smp_rescan_cpus(struct sclp_core_info *info, bool early)
* that all SMT threads get subsequent logical CPU numbers.
*/
if (early) {
- core_id = pcpu_devices[0].address >> smp_cpu_mt_shift;
+ core_id = per_cpu(pcpu_devices, 0).address >> smp_cpu_mt_shift;
for (i = 0; i < info->configured; i++) {
core = &info->core[i];
if (core->core_id == core_id) {
@@ -831,9 +807,6 @@ void __init smp_detect_cpus(void)
s_cpus += smp_cpu_mtid + 1;
}
pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus);
-
- /* Add CPUs present at boot */
- __smp_rescan_cpus(info, true);
memblock_free(info, sizeof(*info));
}
@@ -842,15 +815,16 @@ void __init smp_detect_cpus(void)
*/
static void smp_start_secondary(void *cpuvoid)
{
+ struct lowcore *lc = get_lowcore();
int cpu = raw_smp_processor_id();
- S390_lowcore.last_update_clock = get_tod_clock();
- S390_lowcore.restart_stack = (unsigned long)restart_stack;
- S390_lowcore.restart_fn = (unsigned long)do_restart;
- S390_lowcore.restart_data = 0;
- S390_lowcore.restart_source = -1U;
- S390_lowcore.restart_flags = 0;
- restore_access_regs(S390_lowcore.access_regs_save_area);
+ lc->last_update_clock = get_tod_clock();
+ lc->restart_stack = (unsigned long)restart_stack;
+ lc->restart_fn = (unsigned long)do_restart;
+ lc->restart_data = 0;
+ lc->restart_source = -1U;
+ lc->restart_flags = 0;
+ restore_access_regs(lc->access_regs_save_area);
cpu_init();
rcutree_report_cpu_starting(cpu);
init_cpu_timer();
@@ -873,7 +847,7 @@ static void smp_start_secondary(void *cpuvoid)
/* Upping and downing of CPUs */
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
- struct pcpu *pcpu = pcpu_devices + cpu;
+ struct pcpu *pcpu = per_cpu_ptr(&pcpu_devices, cpu);
int rc;
if (pcpu->state != CPU_STATE_CONFIGURED)
@@ -891,8 +865,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
*/
system_ctlreg_lock();
pcpu_prepare_secondary(pcpu, cpu);
- pcpu_attach_task(pcpu, tidle);
- pcpu_start_fn(pcpu, smp_start_secondary, NULL);
+ pcpu_attach_task(cpu, tidle);
+ pcpu_start_fn(cpu, smp_start_secondary, NULL);
/* Wait until cpu puts itself in the online & active maps */
while (!cpu_online(cpu))
cpu_relax();
@@ -937,18 +911,19 @@ void __cpu_die(unsigned int cpu)
struct pcpu *pcpu;
/* Wait until target cpu is down */
- pcpu = pcpu_devices + cpu;
+ pcpu = per_cpu_ptr(&pcpu_devices, cpu);
while (!pcpu_stopped(pcpu))
cpu_relax();
- pcpu_free_lowcore(pcpu);
+ pcpu_free_lowcore(pcpu, cpu);
cpumask_clear_cpu(cpu, mm_cpumask(&init_mm));
cpumask_clear_cpu(cpu, &init_mm.context.cpu_attach_mask);
+ pcpu->flags = 0;
}
void __noreturn cpu_die(void)
{
idle_task_exit();
- pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0);
+ pcpu_sigp_retry(this_cpu_ptr(&pcpu_devices), SIGP_STOP, 0);
for (;;) ;
}
@@ -973,24 +948,29 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt))
panic("Couldn't request external interrupt 0x1202");
system_ctl_set_bit(0, 13);
+ smp_rescan_cpus(true);
}
void __init smp_prepare_boot_cpu(void)
{
- struct pcpu *pcpu = pcpu_devices;
+ struct lowcore *lc = get_lowcore();
WARN_ON(!cpu_present(0) || !cpu_online(0));
- pcpu->state = CPU_STATE_CONFIGURED;
- S390_lowcore.percpu_offset = __per_cpu_offset[0];
+ lc->percpu_offset = __per_cpu_offset[0];
+ ipl_pcpu = per_cpu_ptr(&pcpu_devices, 0);
+ ipl_pcpu->state = CPU_STATE_CONFIGURED;
+ lc->pcpu = (unsigned long)ipl_pcpu;
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
}
void __init smp_setup_processor_id(void)
{
- pcpu_devices[0].address = stap();
- S390_lowcore.cpu_nr = 0;
- S390_lowcore.spinlock_lockval = arch_spin_lockval(0);
- S390_lowcore.spinlock_index = 0;
+ struct lowcore *lc = get_lowcore();
+
+ lc->cpu_nr = 0;
+ per_cpu(pcpu_devices, 0).address = stap();
+ lc->spinlock_lockval = arch_spin_lockval(0);
+ lc->spinlock_index = 0;
}
/*
@@ -1010,7 +990,7 @@ static ssize_t cpu_configure_show(struct device *dev,
ssize_t count;
mutex_lock(&smp_cpu_state_mutex);
- count = sprintf(buf, "%d\n", pcpu_devices[dev->id].state);
+ count = sprintf(buf, "%d\n", per_cpu(pcpu_devices, dev->id).state);
mutex_unlock(&smp_cpu_state_mutex);
return count;
}
@@ -1036,7 +1016,7 @@ static ssize_t cpu_configure_store(struct device *dev,
for (i = 0; i <= smp_cpu_mtid; i++)
if (cpu_online(cpu + i))
goto out;
- pcpu = pcpu_devices + cpu;
+ pcpu = per_cpu_ptr(&pcpu_devices, cpu);
rc = 0;
switch (val) {
case 0:
@@ -1048,7 +1028,7 @@ static ssize_t cpu_configure_store(struct device *dev,
for (i = 0; i <= smp_cpu_mtid; i++) {
if (cpu + i >= nr_cpu_ids || !cpu_present(cpu + i))
continue;
- pcpu[i].state = CPU_STATE_STANDBY;
+ per_cpu(pcpu_devices, cpu + i).state = CPU_STATE_STANDBY;
smp_cpu_set_polarization(cpu + i,
POLARIZATION_UNKNOWN);
}
@@ -1063,7 +1043,7 @@ static ssize_t cpu_configure_store(struct device *dev,
for (i = 0; i <= smp_cpu_mtid; i++) {
if (cpu + i >= nr_cpu_ids || !cpu_present(cpu + i))
continue;
- pcpu[i].state = CPU_STATE_CONFIGURED;
+ per_cpu(pcpu_devices, cpu + i).state = CPU_STATE_CONFIGURED;
smp_cpu_set_polarization(cpu + i,
POLARIZATION_UNKNOWN);
}
@@ -1082,7 +1062,7 @@ static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
static ssize_t show_cpu_address(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", pcpu_devices[dev->id].address);
+ return sprintf(buf, "%d\n", per_cpu(pcpu_devices, dev->id).address);
}
static DEVICE_ATTR(address, 0444, show_cpu_address, NULL);
@@ -1108,35 +1088,34 @@ static struct attribute_group cpu_online_attr_group = {
static int smp_cpu_online(unsigned int cpu)
{
- struct device *s = &per_cpu(cpu_device, cpu)->dev;
+ struct cpu *c = per_cpu_ptr(&cpu_devices, cpu);
- return sysfs_create_group(&s->kobj, &cpu_online_attr_group);
+ return sysfs_create_group(&c->dev.kobj, &cpu_online_attr_group);
}
static int smp_cpu_pre_down(unsigned int cpu)
{
- struct device *s = &per_cpu(cpu_device, cpu)->dev;
+ struct cpu *c = per_cpu_ptr(&cpu_devices, cpu);
- sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
+ sysfs_remove_group(&c->dev.kobj, &cpu_online_attr_group);
return 0;
}
-static int smp_add_present_cpu(int cpu)
+bool arch_cpu_is_hotpluggable(int cpu)
+{
+ return !!cpu;
+}
+
+int arch_register_cpu(int cpu)
{
- struct device *s;
- struct cpu *c;
+ struct cpu *c = per_cpu_ptr(&cpu_devices, cpu);
int rc;
- c = kzalloc(sizeof(*c), GFP_KERNEL);
- if (!c)
- return -ENOMEM;
- per_cpu(cpu_device, cpu) = c;
- s = &c->dev;
- c->hotpluggable = !!cpu;
+ c->hotpluggable = arch_cpu_is_hotpluggable(cpu);
rc = register_cpu(c, cpu);
if (rc)
goto out;
- rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
+ rc = sysfs_create_group(&c->dev.kobj, &cpu_common_attr_group);
if (rc)
goto out_cpu;
rc = topology_cpu_init(c);
@@ -1145,14 +1124,14 @@ static int smp_add_present_cpu(int cpu)
return 0;
out_topology:
- sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
+ sysfs_remove_group(&c->dev.kobj, &cpu_common_attr_group);
out_cpu:
unregister_cpu(c);
out:
return rc;
}
-int __ref smp_rescan_cpus(void)
+int __ref smp_rescan_cpus(bool early)
{
struct sclp_core_info *info;
int nr;
@@ -1161,7 +1140,7 @@ int __ref smp_rescan_cpus(void)
if (!info)
return -ENOMEM;
smp_get_core_info(info, 0);
- nr = __smp_rescan_cpus(info, false);
+ nr = __smp_rescan_cpus(info, early);
kfree(info);
if (nr)
topology_schedule_update();
@@ -1178,7 +1157,7 @@ static ssize_t __ref rescan_store(struct device *dev,
rc = lock_device_hotplug_sysfs();
if (rc)
return rc;
- rc = smp_rescan_cpus();
+ rc = smp_rescan_cpus(false);
unlock_device_hotplug();
return rc ? rc : count;
}
@@ -1187,7 +1166,7 @@ static DEVICE_ATTR_WO(rescan);
static int __init s390_smp_init(void)
{
struct device *dev_root;
- int cpu, rc = 0;
+ int rc;
dev_root = bus_get_dev_root(&cpu_subsys);
if (dev_root) {
@@ -1196,17 +1175,9 @@ static int __init s390_smp_init(void)
if (rc)
return rc;
}
-
- for_each_present_cpu(cpu) {
- rc = smp_add_present_cpu(cpu);
- if (rc)
- goto out;
- }
-
rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "s390/smp:online",
smp_cpu_online, smp_cpu_pre_down);
rc = rc <= 0 ? rc : 0;
-out:
return rc;
}
subsys_initcall(s390_smp_init);
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 94f440e38303..640363b2a105 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -5,6 +5,7 @@
* Copyright IBM Corp. 2006
*/
+#include <linux/perf_event.h>
#include <linux/stacktrace.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
@@ -62,42 +63,121 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
return 0;
}
-void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
- const struct pt_regs *regs)
+static inline bool store_ip(stack_trace_consume_fn consume_entry, void *cookie,
+ struct perf_callchain_entry_ctx *entry, bool perf,
+ unsigned long ip)
+{
+#ifdef CONFIG_PERF_EVENTS
+ if (perf) {
+ if (perf_callchain_store(entry, ip))
+ return false;
+ return true;
+ }
+#endif
+ return consume_entry(cookie, ip);
+}
+
+static inline bool ip_invalid(unsigned long ip)
+{
+ /*
+ * Perform some basic checks if an instruction address taken
+ * from unreliable source is invalid.
+ */
+ if (ip & 1)
+ return true;
+ if (ip < mmap_min_addr)
+ return true;
+ if (ip >= current->mm->context.asce_limit)
+ return true;
+ return false;
+}
+
+static inline bool ip_within_vdso(unsigned long ip)
{
+ return in_range(ip, current->mm->context.vdso_base, vdso_text_size());
+}
+
+void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie,
+ struct perf_callchain_entry_ctx *entry,
+ const struct pt_regs *regs, bool perf)
+{
+ struct stack_frame_vdso_wrapper __user *sf_vdso;
struct stack_frame_user __user *sf;
unsigned long ip, sp;
bool first = true;
if (is_compat_task())
return;
- if (!consume_entry(cookie, instruction_pointer(regs)))
+ if (!current->mm)
+ return;
+ ip = instruction_pointer(regs);
+ if (!store_ip(consume_entry, cookie, entry, perf, ip))
return;
sf = (void __user *)user_stack_pointer(regs);
pagefault_disable();
while (1) {
if (__get_user(sp, &sf->back_chain))
break;
- if (__get_user(ip, &sf->gprs[8]))
+ /*
+ * VDSO entry code has a non-standard stack frame layout.
+ * See VDSO user wrapper code for details.
+ */
+ if (!sp && ip_within_vdso(ip)) {
+ sf_vdso = (void __user *)sf;
+ if (__get_user(ip, &sf_vdso->return_address))
+ break;
+ sp = (unsigned long)sf + STACK_FRAME_VDSO_OVERHEAD;
+ sf = (void __user *)sp;
+ if (__get_user(sp, &sf->back_chain))
+ break;
+ } else {
+ sf = (void __user *)sp;
+ if (__get_user(ip, &sf->gprs[8]))
+ break;
+ }
+ /* Sanity check: ABI requires SP to be 8 byte aligned. */
+ if (sp & 0x7)
break;
- if (ip & 0x1) {
+ if (ip_invalid(ip)) {
/*
* If the instruction address is invalid, and this
* is the first stack frame, assume r14 has not
* been written to the stack yet. Otherwise exit.
*/
- if (first && !(regs->gprs[14] & 0x1))
- ip = regs->gprs[14];
- else
+ if (!first)
+ break;
+ ip = regs->gprs[14];
+ if (ip_invalid(ip))
break;
}
- if (!consume_entry(cookie, ip))
- break;
- /* Sanity check: ABI requires SP to be aligned 8 bytes. */
- if (!sp || sp & 0x7)
- break;
- sf = (void __user *)sp;
+ if (!store_ip(consume_entry, cookie, entry, perf, ip))
+ return;
first = false;
}
pagefault_enable();
}
+
+void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
+ const struct pt_regs *regs)
+{
+ arch_stack_walk_user_common(consume_entry, cookie, NULL, regs, false);
+}
+
+unsigned long return_address(unsigned int n)
+{
+ struct unwind_state state;
+ unsigned long addr;
+
+ /* Increment to skip current stack entry */
+ n++;
+
+ unwind_for_each_frame(&state, NULL, NULL, 0) {
+ addr = unwind_get_return_address(&state);
+ if (!addr)
+ break;
+ if (!n--)
+ return addr;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/s390/kernel/sthyi.c b/arch/s390/kernel/sthyi.c
index 30bb20461db4..1cf2ad04f8e9 100644
--- a/arch/s390/kernel/sthyi.c
+++ b/arch/s390/kernel/sthyi.c
@@ -300,33 +300,56 @@ static struct diag204_x_part_block *lpar_cpu_inf(struct lpar_cpu_inf *part_inf,
return (struct diag204_x_part_block *)&block->cpus[i];
}
-static void fill_diag(struct sthyi_sctns *sctns)
+static void *diag204_get_data(bool diag204_allow_busy)
{
- int i, r, pages;
- bool this_lpar;
+ unsigned long subcode;
void *diag204_buf;
- void *diag224_buf = NULL;
- struct diag204_x_info_blk_hdr *ti_hdr;
- struct diag204_x_part_block *part_block;
- struct diag204_x_phys_block *phys_block;
- struct lpar_cpu_inf lpar_inf = {};
-
- /* Errors are handled through the validity bits in the response. */
- pages = diag204((unsigned long)DIAG204_SUBC_RSI |
- (unsigned long)DIAG204_INFO_EXT, 0, NULL);
- if (pages <= 0)
- return;
-
+ int pages, rc;
+
+ subcode = DIAG204_SUBC_RSI;
+ subcode |= DIAG204_INFO_EXT;
+ pages = diag204(subcode, 0, NULL);
+ if (pages < 0)
+ return ERR_PTR(pages);
+ if (pages == 0)
+ return ERR_PTR(-ENODATA);
diag204_buf = __vmalloc_node(array_size(pages, PAGE_SIZE),
PAGE_SIZE, GFP_KERNEL, NUMA_NO_NODE,
__builtin_return_address(0));
if (!diag204_buf)
- return;
+ return ERR_PTR(-ENOMEM);
+ subcode = DIAG204_SUBC_STIB7;
+ subcode |= DIAG204_INFO_EXT;
+ if (diag204_has_bif() && diag204_allow_busy)
+ subcode |= DIAG204_BIF_BIT;
+ rc = diag204(subcode, pages, diag204_buf);
+ if (rc < 0) {
+ vfree(diag204_buf);
+ return ERR_PTR(rc);
+ }
+ return diag204_buf;
+}
- r = diag204((unsigned long)DIAG204_SUBC_STIB7 |
- (unsigned long)DIAG204_INFO_EXT, pages, diag204_buf);
- if (r < 0)
- goto out;
+static bool is_diag204_cached(struct sthyi_sctns *sctns)
+{
+ /*
+ * Check if validity bits are set when diag204 data
+ * is gathered.
+ */
+ if (sctns->par.infpval1)
+ return true;
+ return false;
+}
+
+static void fill_diag(struct sthyi_sctns *sctns, void *diag204_buf)
+{
+ int i;
+ bool this_lpar;
+ void *diag224_buf = NULL;
+ struct diag204_x_info_blk_hdr *ti_hdr;
+ struct diag204_x_part_block *part_block;
+ struct diag204_x_phys_block *phys_block;
+ struct lpar_cpu_inf lpar_inf = {};
diag224_buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
if (!diag224_buf || diag224(diag224_buf))
@@ -392,7 +415,6 @@ static void fill_diag(struct sthyi_sctns *sctns)
out:
free_page((unsigned long)diag224_buf);
- vfree(diag204_buf);
}
static int sthyi(u64 vaddr, u64 *rc)
@@ -414,19 +436,31 @@ static int sthyi(u64 vaddr, u64 *rc)
static int fill_dst(void *dst, u64 *rc)
{
+ void *diag204_buf;
+
struct sthyi_sctns *sctns = (struct sthyi_sctns *)dst;
/*
* If the facility is on, we don't want to emulate the instruction.
* We ask the hypervisor to provide the data.
*/
- if (test_facility(74))
+ if (test_facility(74)) {
+ memset(dst, 0, PAGE_SIZE);
return sthyi((u64)dst, rc);
-
+ }
+ /*
+ * When emulating, if diag204 returns BUSY don't reset dst buffer
+ * and use cached data.
+ */
+ *rc = 0;
+ diag204_buf = diag204_get_data(is_diag204_cached(sctns));
+ if (IS_ERR(diag204_buf))
+ return PTR_ERR(diag204_buf);
+ memset(dst, 0, PAGE_SIZE);
fill_hdr(sctns);
fill_stsi(sctns);
- fill_diag(sctns);
- *rc = 0;
+ fill_diag(sctns, diag204_buf);
+ vfree(diag204_buf);
return 0;
}
@@ -445,11 +479,14 @@ static int sthyi_update_cache(u64 *rc)
{
int r;
- memset(sthyi_cache.info, 0, PAGE_SIZE);
r = fill_dst(sthyi_cache.info, rc);
- if (r)
- return r;
- sthyi_cache.end = jiffies + CACHE_VALID_JIFFIES;
+ if (r == 0) {
+ sthyi_cache.end = jiffies + CACHE_VALID_JIFFIES;
+ } else if (r == -EBUSY) {
+ /* mark as expired and return 0 to keep using cached data */
+ sthyi_cache.end = jiffies - 1;
+ r = 0;
+ }
return r;
}
diff --git a/arch/s390/kernel/syscall.c b/arch/s390/kernel/syscall.c
index dc2355c623d6..5ec28028315b 100644
--- a/arch/s390/kernel/syscall.c
+++ b/arch/s390/kernel/syscall.c
@@ -38,33 +38,6 @@
#include "entry.h"
-/*
- * Perform the mmap() system call. Linux for S/390 isn't able to handle more
- * than 5 system call parameters, so this system call uses a memory block
- * for parameter passing.
- */
-
-struct s390_mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg)
-{
- struct s390_mmap_arg_struct a;
- int error = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
- error = ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
-out:
- return error;
-}
-
#ifdef CONFIG_SYSVIPC
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls.
@@ -151,8 +124,8 @@ void noinstr __do_syscall(struct pt_regs *regs, int per_trap)
{
add_random_kstack_offset();
enter_from_user_mode(regs);
- regs->psw = S390_lowcore.svc_old_psw;
- regs->int_code = S390_lowcore.svc_int_code;
+ regs->psw = get_lowcore()->svc_old_psw;
+ regs->int_code = get_lowcore()->svc_int_code;
update_timer_sys();
if (static_branch_likely(&cpu_has_bear))
current->thread.last_break = regs->last_break;
diff --git a/arch/s390/kernel/syscalls/Makefile b/arch/s390/kernel/syscalls/Makefile
index fb85e797946d..1bb78b9468e8 100644
--- a/arch/s390/kernel/syscalls/Makefile
+++ b/arch/s390/kernel/syscalls/Makefile
@@ -4,8 +4,8 @@ gen := arch/$(ARCH)/include/generated
kapi := $(gen)/asm
uapi := $(gen)/uapi/asm
-syscall := $(srctree)/$(src)/syscall.tbl
-systbl := $(srctree)/$(src)/syscalltbl
+syscall := $(src)/syscall.tbl
+systbl := $(src)/syscalltbl
gen-y := $(kapi)/syscall_table.h
kapi-hdrs-y := $(kapi)/unistd_nr.h
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 095bb86339a7..01071182763e 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -418,7 +418,7 @@
412 32 utimensat_time64 - sys_utimensat
413 32 pselect6_time64 - compat_sys_pselect6_time64
414 32 ppoll_time64 - compat_sys_ppoll_time64
-416 32 io_pgetevents_time64 - sys_io_pgetevents
+416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64
417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64
418 32 mq_timedsend_time64 - sys_mq_timedsend
419 32 mq_timedreceive_time64 - sys_mq_timedreceive
@@ -464,3 +464,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal sys_mseal
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index fb9f31f36628..b713effe0579 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -131,7 +131,7 @@ void clock_comparator_work(void)
{
struct clock_event_device *cd;
- S390_lowcore.clock_comparator = clock_comparator_max;
+ get_lowcore()->clock_comparator = clock_comparator_max;
cd = this_cpu_ptr(&comparators);
cd->event_handler(cd);
}
@@ -139,8 +139,8 @@ void clock_comparator_work(void)
static int s390_next_event(unsigned long delta,
struct clock_event_device *evt)
{
- S390_lowcore.clock_comparator = get_tod_clock() + delta;
- set_clock_comparator(S390_lowcore.clock_comparator);
+ get_lowcore()->clock_comparator = get_tod_clock() + delta;
+ set_clock_comparator(get_lowcore()->clock_comparator);
return 0;
}
@@ -153,8 +153,8 @@ void init_cpu_timer(void)
struct clock_event_device *cd;
int cpu;
- S390_lowcore.clock_comparator = clock_comparator_max;
- set_clock_comparator(S390_lowcore.clock_comparator);
+ get_lowcore()->clock_comparator = clock_comparator_max;
+ set_clock_comparator(get_lowcore()->clock_comparator);
cpu = smp_processor_id();
cd = &per_cpu(comparators, cpu);
@@ -184,8 +184,8 @@ static void clock_comparator_interrupt(struct ext_code ext_code,
unsigned long param64)
{
inc_irq_stat(IRQEXT_CLK);
- if (S390_lowcore.clock_comparator == clock_comparator_max)
- set_clock_comparator(S390_lowcore.clock_comparator);
+ if (get_lowcore()->clock_comparator == clock_comparator_max)
+ set_clock_comparator(get_lowcore()->clock_comparator);
}
static void stp_timing_alert(struct stp_irq_parm *);
@@ -408,12 +408,12 @@ static void clock_sync_global(long delta)
static void clock_sync_local(long delta)
{
/* Add the delta to the clock comparator. */
- if (S390_lowcore.clock_comparator != clock_comparator_max) {
- S390_lowcore.clock_comparator += delta;
- set_clock_comparator(S390_lowcore.clock_comparator);
+ if (get_lowcore()->clock_comparator != clock_comparator_max) {
+ get_lowcore()->clock_comparator += delta;
+ set_clock_comparator(get_lowcore()->clock_comparator);
}
/* Adjust the last_update_clock time-stamp. */
- S390_lowcore.last_update_clock += delta;
+ get_lowcore()->last_update_clock += delta;
}
/* Single threaded workqueue used for stp sync events */
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 89e91b8ce842..22029ecae1c5 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -320,16 +320,10 @@ static int __arch_update_cpu_topology(void)
int arch_update_cpu_topology(void)
{
- struct device *dev;
- int cpu, rc;
+ int rc;
rc = __arch_update_cpu_topology();
on_each_cpu(__arch_update_dedicated_flag, NULL, 0);
- for_each_online_cpu(cpu) {
- dev = get_cpu_device(cpu);
- if (dev)
- kobject_uevent(&dev->kobj, KOBJ_CHANGE);
- }
return rc;
}
@@ -600,7 +594,7 @@ static int __init topology_setup(char *str)
}
early_param("topology", topology_setup);
-static int topology_ctl_handler(struct ctl_table *ctl, int write,
+static int topology_ctl_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
int enabled = topology_is_enabled();
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 52578b5cecbd..160b2acba8db 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -27,6 +27,7 @@
#include <linux/uaccess.h>
#include <linux/cpu.h>
#include <linux/entry-common.h>
+#include <linux/kmsan.h>
#include <asm/asm-extable.h>
#include <asm/vtime.h>
#include <asm/fpu.h>
@@ -262,6 +263,11 @@ static void monitor_event_exception(struct pt_regs *regs)
void kernel_stack_overflow(struct pt_regs *regs)
{
+ /*
+ * Normally regs are unpoisoned by the generic entry code, but
+ * kernel_stack_overflow() is a rare case that is called bypassing it.
+ */
+ kmsan_unpoison_entry_regs(regs);
bust_spinlocks(1);
printk("Kernel stack overflow.\n");
show_regs(regs);
@@ -288,15 +294,16 @@ static void __init test_monitor_call(void)
void __init trap_init(void)
{
+ struct lowcore *lc = get_lowcore();
unsigned long flags;
struct ctlreg cr0;
local_irq_save(flags);
cr0 = local_ctl_clear_bit(0, CR0_LOW_ADDRESS_PROTECTION_BIT);
- psw_bits(S390_lowcore.external_new_psw).mcheck = 1;
- psw_bits(S390_lowcore.program_new_psw).mcheck = 1;
- psw_bits(S390_lowcore.svc_new_psw).mcheck = 1;
- psw_bits(S390_lowcore.io_new_psw).mcheck = 1;
+ psw_bits(lc->external_new_psw).mcheck = 1;
+ psw_bits(lc->program_new_psw).mcheck = 1;
+ psw_bits(lc->svc_new_psw).mcheck = 1;
+ psw_bits(lc->io_new_psw).mcheck = 1;
local_ctl_load(0, &cr0);
local_irq_restore(flags);
local_mcck_enable();
@@ -307,11 +314,12 @@ static void (*pgm_check_table[128])(struct pt_regs *regs);
void noinstr __do_pgm_check(struct pt_regs *regs)
{
- unsigned int trapnr;
+ struct lowcore *lc = get_lowcore();
irqentry_state_t state;
+ unsigned int trapnr;
- regs->int_code = S390_lowcore.pgm_int_code;
- regs->int_parm_long = S390_lowcore.trans_exc_code;
+ regs->int_code = lc->pgm_int_code;
+ regs->int_parm_long = lc->trans_exc_code;
state = irqentry_enter(regs);
@@ -324,19 +332,19 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
current->thread.last_break = regs->last_break;
}
- if (S390_lowcore.pgm_code & 0x0200) {
+ if (lc->pgm_code & 0x0200) {
/* transaction abort */
- current->thread.trap_tdb = S390_lowcore.pgm_tdb;
+ current->thread.trap_tdb = lc->pgm_tdb;
}
- if (S390_lowcore.pgm_code & PGM_INT_CODE_PER) {
+ if (lc->pgm_code & PGM_INT_CODE_PER) {
if (user_mode(regs)) {
struct per_event *ev = &current->thread.per_event;
set_thread_flag(TIF_PER_TRAP);
- ev->address = S390_lowcore.per_address;
- ev->cause = S390_lowcore.per_code_combined;
- ev->paid = S390_lowcore.per_access_id;
+ ev->address = lc->per_address;
+ ev->cause = lc->per_code_combined;
+ ev->paid = lc->per_access_id;
} else {
/* PER event in kernel is kprobes */
__arch_local_irq_ssm(regs->psw.mask & ~PSW_MASK_PER);
diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c
index 0ece156fdd7c..cd44be2b6ce8 100644
--- a/arch/s390/kernel/unwind_bc.c
+++ b/arch/s390/kernel/unwind_bc.c
@@ -49,6 +49,8 @@ static inline bool is_final_pt_regs(struct unwind_state *state,
READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
}
+/* Avoid KMSAN false positives from touching uninitialized frames. */
+__no_kmsan_checks
bool unwind_next_frame(struct unwind_state *state)
{
struct stack_info *info = &state->stack_info;
@@ -118,6 +120,8 @@ out_stop:
}
EXPORT_SYMBOL_GPL(unwind_next_frame);
+/* Avoid KMSAN false positives from touching uninitialized frames. */
+__no_kmsan_checks
void __unwind_start(struct unwind_state *state, struct task_struct *task,
struct pt_regs *regs, unsigned long first_frame)
{
diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
index fc07bc39e698..36db065c7cf7 100644
--- a/arch/s390/kernel/uv.c
+++ b/arch/s390/kernel/uv.c
@@ -18,10 +18,22 @@
#include <asm/sections.h>
#include <asm/uv.h>
+#if !IS_ENABLED(CONFIG_KVM)
+unsigned long __gmap_translate(struct gmap *gmap, unsigned long gaddr)
+{
+ return 0;
+}
+
+int gmap_fault(struct gmap *gmap, unsigned long gaddr,
+ unsigned int fault_flags)
+{
+ return 0;
+}
+#endif
+
/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
-#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
int __bootdata_preserved(prot_virt_guest);
-#endif
+EXPORT_SYMBOL(prot_virt_guest);
/*
* uv_info contains both host and guest information but it's currently only
@@ -34,7 +46,6 @@ int __bootdata_preserved(prot_virt_guest);
struct uv_info __bootdata_preserved(uv_info);
EXPORT_SYMBOL(uv_info);
-#if IS_ENABLED(CONFIG_KVM)
int __bootdata_preserved(prot_virt_host);
EXPORT_SYMBOL(prot_virt_host);
@@ -109,7 +120,7 @@ EXPORT_SYMBOL_GPL(uv_pin_shared);
*
* @paddr: Absolute host address of page to be destroyed
*/
-static int uv_destroy_page(unsigned long paddr)
+static int uv_destroy(unsigned long paddr)
{
struct uv_cb_cfs uvcb = {
.header.cmd = UVC_CMD_DESTR_SEC_STOR,
@@ -130,28 +141,40 @@ static int uv_destroy_page(unsigned long paddr)
}
/*
- * The caller must already hold a reference to the page
+ * The caller must already hold a reference to the folio
*/
-int uv_destroy_owned_page(unsigned long paddr)
+int uv_destroy_folio(struct folio *folio)
{
- struct page *page = phys_to_page(paddr);
int rc;
- get_page(page);
- rc = uv_destroy_page(paddr);
+ /* See gmap_make_secure(): large folios cannot be secure */
+ if (unlikely(folio_test_large(folio)))
+ return 0;
+
+ folio_get(folio);
+ rc = uv_destroy(folio_to_phys(folio));
if (!rc)
- clear_bit(PG_arch_1, &page->flags);
- put_page(page);
+ clear_bit(PG_arch_1, &folio->flags);
+ folio_put(folio);
return rc;
}
/*
+ * The present PTE still indirectly holds a folio reference through the mapping.
+ */
+int uv_destroy_pte(pte_t pte)
+{
+ VM_WARN_ON(!pte_present(pte));
+ return uv_destroy_folio(pfn_folio(pte_pfn(pte)));
+}
+
+/*
* Requests the Ultravisor to encrypt a guest page and make it
* accessible to the host for paging (export).
*
* @paddr: Absolute host address of page to be exported
*/
-int uv_convert_from_secure(unsigned long paddr)
+static int uv_convert_from_secure(unsigned long paddr)
{
struct uv_cb_cfs uvcb = {
.header.cmd = UVC_CMD_CONV_FROM_SEC_STOR,
@@ -165,52 +188,64 @@ int uv_convert_from_secure(unsigned long paddr)
}
/*
- * The caller must already hold a reference to the page
+ * The caller must already hold a reference to the folio.
*/
-int uv_convert_owned_from_secure(unsigned long paddr)
+static int uv_convert_from_secure_folio(struct folio *folio)
{
- struct page *page = phys_to_page(paddr);
int rc;
- get_page(page);
- rc = uv_convert_from_secure(paddr);
+ /* See gmap_make_secure(): large folios cannot be secure */
+ if (unlikely(folio_test_large(folio)))
+ return 0;
+
+ folio_get(folio);
+ rc = uv_convert_from_secure(folio_to_phys(folio));
if (!rc)
- clear_bit(PG_arch_1, &page->flags);
- put_page(page);
+ clear_bit(PG_arch_1, &folio->flags);
+ folio_put(folio);
return rc;
}
/*
- * Calculate the expected ref_count for a page that would otherwise have no
+ * The present PTE still indirectly holds a folio reference through the mapping.
+ */
+int uv_convert_from_secure_pte(pte_t pte)
+{
+ VM_WARN_ON(!pte_present(pte));
+ return uv_convert_from_secure_folio(pfn_folio(pte_pfn(pte)));
+}
+
+/*
+ * Calculate the expected ref_count for a folio that would otherwise have no
* further pins. This was cribbed from similar functions in other places in
* the kernel, but with some slight modifications. We know that a secure
- * page can not be a huge page for example.
+ * folio can not be a large folio, for example.
*/
-static int expected_page_refs(struct page *page)
+static int expected_folio_refs(struct folio *folio)
{
int res;
- res = page_mapcount(page);
- if (PageSwapCache(page)) {
+ res = folio_mapcount(folio);
+ if (folio_test_swapcache(folio)) {
res++;
- } else if (page_mapping(page)) {
+ } else if (folio_mapping(folio)) {
res++;
- if (page_has_private(page))
+ if (folio->private)
res++;
}
return res;
}
-static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
+static int make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb)
{
int expected, cc = 0;
- if (PageWriteback(page))
+ if (folio_test_writeback(folio))
return -EAGAIN;
- expected = expected_page_refs(page);
- if (!page_ref_freeze(page, expected))
+ expected = expected_folio_refs(folio);
+ if (!folio_ref_freeze(folio, expected))
return -EBUSY;
- set_bit(PG_arch_1, &page->flags);
+ set_bit(PG_arch_1, &folio->flags);
/*
* If the UVC does not succeed or fail immediately, we don't want to
* loop for long, or we might get stall notifications.
@@ -220,9 +255,9 @@ static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
* -EAGAIN and we let the callers deal with it.
*/
cc = __uv_call(0, (u64)uvcb);
- page_ref_unfreeze(page, expected);
+ folio_ref_unfreeze(folio, expected);
/*
- * Return -ENXIO if the page was not mapped, -EINVAL for other errors.
+ * Return -ENXIO if the folio was not mapped, -EINVAL for other errors.
* If busy or partially completed, return -EAGAIN.
*/
if (cc == UVC_CC_OK)
@@ -266,6 +301,36 @@ static bool should_export_before_import(struct uv_cb_header *uvcb, struct mm_str
}
/*
+ * Drain LRU caches: the local one on first invocation and the ones of all
+ * CPUs on successive invocations. Returns "true" on the first invocation.
+ */
+static bool drain_lru(bool *drain_lru_called)
+{
+ /*
+ * If we have tried a local drain and the folio refcount
+ * still does not match our expected safe value, try with a
+ * system wide drain. This is needed if the pagevecs holding
+ * the page are on a different CPU.
+ */
+ if (*drain_lru_called) {
+ lru_add_drain_all();
+ /* We give up here, don't retry immediately. */
+ return false;
+ }
+ /*
+ * We are here if the folio refcount does not match the
+ * expected safe value. The main culprits are usually
+ * pagevecs. With lru_add_drain() we drain the pagevecs
+ * on the local CPU so that hopefully the refcount will
+ * reach the expected safe value.
+ */
+ lru_add_drain();
+ *drain_lru_called = true;
+ /* The caller should try again immediately */
+ return true;
+}
+
+/*
* Requests the Ultravisor to make a page accessible to a guest.
* If it's brought in the first time, it will be cleared. If
* it has been exported before, it will be decrypted and integrity
@@ -274,10 +339,10 @@ static bool should_export_before_import(struct uv_cb_header *uvcb, struct mm_str
int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb)
{
struct vm_area_struct *vma;
- bool local_drain = false;
+ bool drain_lru_called = false;
spinlock_t *ptelock;
unsigned long uaddr;
- struct page *page;
+ struct folio *folio;
pte_t *ptep;
int rc;
@@ -306,49 +371,64 @@ again:
if (!ptep)
goto out;
if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) {
- page = pte_page(*ptep);
+ folio = page_folio(pte_page(*ptep));
rc = -EAGAIN;
- if (trylock_page(page)) {
+ if (folio_test_large(folio)) {
+ rc = -E2BIG;
+ } else if (folio_trylock(folio)) {
if (should_export_before_import(uvcb, gmap->mm))
- uv_convert_from_secure(page_to_phys(page));
- rc = make_page_secure(page, uvcb);
- unlock_page(page);
+ uv_convert_from_secure(PFN_PHYS(folio_pfn(folio)));
+ rc = make_folio_secure(folio, uvcb);
+ folio_unlock(folio);
}
+
+ /*
+ * Once we drop the PTL, the folio may get unmapped and
+ * freed immediately. We need a temporary reference.
+ */
+ if (rc == -EAGAIN || rc == -E2BIG)
+ folio_get(folio);
}
pte_unmap_unlock(ptep, ptelock);
out:
mmap_read_unlock(gmap->mm);
- if (rc == -EAGAIN) {
- /*
- * If we are here because the UVC returned busy or partial
- * completion, this is just a useless check, but it is safe.
- */
- wait_on_page_writeback(page);
- } else if (rc == -EBUSY) {
- /*
- * If we have tried a local drain and the page refcount
- * still does not match our expected safe value, try with a
- * system wide drain. This is needed if the pagevecs holding
- * the page are on a different CPU.
- */
- if (local_drain) {
- lru_add_drain_all();
- /* We give up here, and let the caller try again */
+ switch (rc) {
+ case -E2BIG:
+ folio_lock(folio);
+ rc = split_folio(folio);
+ folio_unlock(folio);
+ folio_put(folio);
+
+ switch (rc) {
+ case 0:
+ /* Splitting succeeded, try again immediately. */
+ goto again;
+ case -EAGAIN:
+ /* Additional folio references. */
+ if (drain_lru(&drain_lru_called))
+ goto again;
+ return -EAGAIN;
+ case -EBUSY:
+ /* Unexpected race. */
return -EAGAIN;
}
+ WARN_ON_ONCE(1);
+ return -ENXIO;
+ case -EAGAIN:
/*
- * We are here if the page refcount does not match the
- * expected safe value. The main culprits are usually
- * pagevecs. With lru_add_drain() we drain the pagevecs
- * on the local CPU so that hopefully the refcount will
- * reach the expected safe value.
+ * If we are here because the UVC returned busy or partial
+ * completion, this is just a useless check, but it is safe.
*/
- lru_add_drain();
- local_drain = true;
- /* And now we try again immediately after draining */
- goto again;
- } else if (rc == -ENXIO) {
+ folio_wait_writeback(folio);
+ folio_put(folio);
+ return -EAGAIN;
+ case -EBUSY:
+ /* Additional folio references. */
+ if (drain_lru(&drain_lru_called))
+ goto again;
+ return -EAGAIN;
+ case -ENXIO:
if (gmap_fault(gmap, gaddr, FAULT_FLAG_WRITE))
return -EFAULT;
return -EAGAIN;
@@ -383,6 +463,7 @@ int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr)
{
struct vm_area_struct *vma;
unsigned long uaddr;
+ struct folio *folio;
struct page *page;
int rc;
@@ -406,7 +487,8 @@ int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr)
page = follow_page(vma, uaddr, FOLL_WRITE | FOLL_GET);
if (IS_ERR_OR_NULL(page))
goto out;
- rc = uv_destroy_owned_page(page_to_phys(page));
+ folio = page_folio(page);
+ rc = uv_destroy_folio(folio);
/*
* Fault handlers can race; it is possible that two CPUs will fault
* on the same secure page. One CPU can destroy the page, reboot,
@@ -417,8 +499,8 @@ int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr)
* we instead try to export the page.
*/
if (rc)
- rc = uv_convert_owned_from_secure(page_to_phys(page));
- put_page(page);
+ rc = uv_convert_from_secure_folio(folio);
+ folio_put(folio);
out:
mmap_read_unlock(gmap->mm);
return rc;
@@ -426,50 +508,51 @@ out:
EXPORT_SYMBOL_GPL(gmap_destroy_page);
/*
- * To be called with the page locked or with an extra reference! This will
- * prevent gmap_make_secure from touching the page concurrently. Having 2
- * parallel make_page_accessible is fine, as the UV calls will become a
- * no-op if the page is already exported.
+ * To be called with the folio locked or with an extra reference! This will
+ * prevent gmap_make_secure from touching the folio concurrently. Having 2
+ * parallel arch_make_folio_accessible is fine, as the UV calls will become a
+ * no-op if the folio is already exported.
*/
-int arch_make_page_accessible(struct page *page)
+int arch_make_folio_accessible(struct folio *folio)
{
int rc = 0;
- /* Hugepage cannot be protected, so nothing to do */
- if (PageHuge(page))
+ /* See gmap_make_secure(): large folios cannot be secure */
+ if (unlikely(folio_test_large(folio)))
return 0;
/*
- * PG_arch_1 is used in 3 places:
- * 1. for kernel page tables during early boot
- * 2. for storage keys of huge pages and KVM
- * 3. As an indication that this page might be secure. This can
+ * PG_arch_1 is used in 2 places:
+ * 1. for storage keys of hugetlb folios and KVM
+ * 2. As an indication that this small folio might be secure. This can
* overindicate, e.g. we set the bit before calling
* convert_to_secure.
- * As secure pages are never huge, all 3 variants can co-exists.
+ * As secure pages are never large folios, both variants can co-exists.
*/
- if (!test_bit(PG_arch_1, &page->flags))
+ if (!test_bit(PG_arch_1, &folio->flags))
return 0;
- rc = uv_pin_shared(page_to_phys(page));
+ rc = uv_pin_shared(folio_to_phys(folio));
if (!rc) {
- clear_bit(PG_arch_1, &page->flags);
+ clear_bit(PG_arch_1, &folio->flags);
return 0;
}
- rc = uv_convert_from_secure(page_to_phys(page));
+ rc = uv_convert_from_secure(folio_to_phys(folio));
if (!rc) {
- clear_bit(PG_arch_1, &page->flags);
+ clear_bit(PG_arch_1, &folio->flags);
return 0;
}
return rc;
}
-EXPORT_SYMBOL_GPL(arch_make_page_accessible);
+EXPORT_SYMBOL_GPL(arch_make_folio_accessible);
-#endif
-
-#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM)
+int arch_make_page_accessible(struct page *page)
+{
+ return arch_make_folio_accessible(page_folio(page));
+}
+EXPORT_SYMBOL_GPL(arch_make_page_accessible);
static ssize_t uv_query_facilities(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -645,24 +728,13 @@ static struct attribute_group uv_query_attr_group = {
static ssize_t uv_is_prot_virt_guest(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
- int val = 0;
-
-#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
- val = prot_virt_guest;
-#endif
- return sysfs_emit(buf, "%d\n", val);
+ return sysfs_emit(buf, "%d\n", prot_virt_guest);
}
static ssize_t uv_is_prot_virt_host(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
- int val = 0;
-
-#if IS_ENABLED(CONFIG_KVM)
- val = prot_virt_host;
-#endif
-
- return sysfs_emit(buf, "%d\n", val);
+ return sysfs_emit(buf, "%d\n", prot_virt_host);
}
static struct kobj_attribute uv_prot_virt_guest =
@@ -714,4 +786,3 @@ out_kobj:
return rc;
}
device_initcall(uv_info_init);
-#endif
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index a45b3a4c91db..2f967ac2b8e3 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -210,17 +210,22 @@ static unsigned long vdso_addr(unsigned long start, unsigned long len)
return addr;
}
-unsigned long vdso_size(void)
+unsigned long vdso_text_size(void)
{
- unsigned long size = VVAR_NR_PAGES * PAGE_SIZE;
+ unsigned long size;
if (is_compat_task())
- size += vdso32_end - vdso32_start;
+ size = vdso32_end - vdso32_start;
else
- size += vdso64_end - vdso64_start;
+ size = vdso64_end - vdso64_start;
return PAGE_ALIGN(size);
}
+unsigned long vdso_size(void)
+{
+ return vdso_text_size() + VVAR_NR_PAGES * PAGE_SIZE;
+}
+
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
unsigned long addr = VDSO_BASE;
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index b12a274cbb47..2c5afb88d298 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# List of files in the vdso
-KCOV_INSTRUMENT := n
-
# Include the generic Makefile to check the built vdso.
include $(srctree)/lib/vdso/Makefile
obj-vdso32 = vdso_user_wrapper-32.o note-32.o
@@ -19,8 +17,10 @@ KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
KBUILD_AFLAGS_32 += -m31 -s
KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
+KBUILD_CFLAGS_32 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS))
KBUILD_CFLAGS_32 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_32))
-KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin
+KBUILD_CFLAGS_32 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_32))
+KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin -fasynchronous-unwind-tables
LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \
--hash-style=both --build-id=sha1 -melf_s390 -T
@@ -32,19 +32,13 @@ obj-y += vdso32_wrapper.o
targets += vdso32.lds
CPPFLAGS_vdso32.lds += -P -C -U$(ARCH)
-# Disable gcov profiling, ubsan and kasan for VDSO code
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-
# Force dependency (incbin is bad)
$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
quiet_cmd_vdso_and_check = VDSO $@
cmd_vdso_and_check = $(cmd_ld); $(cmd_vdso_check)
-$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) FORCE
+$(obj)/vdso32.so.dbg: $(obj)/vdso32.lds $(obj-vdso32) FORCE
$(call if_changed,vdso_and_check)
# strip rule for the .so file
@@ -62,7 +56,7 @@ quiet_cmd_vdso32cc = VDSO32C $@
cmd_vdso32cc = $(CC) $(c_flags) -c -o $@ $<
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index ef9832726097..ba19c0ca7c87 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# List of files in the vdso
-KCOV_INSTRUMENT := n
-
# Include the generic Makefile to check the built vdso.
include $(srctree)/lib/vdso/Makefile
obj-vdso64 = vdso_user_wrapper.o note.o
@@ -24,9 +22,11 @@ KBUILD_AFLAGS_64 := $(filter-out -m64,$(KBUILD_AFLAGS))
KBUILD_AFLAGS_64 += -m64
KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
+KBUILD_CFLAGS_64 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_64))
KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64))
KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64))
-KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin
+KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64))
+KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
ldflags-y := -shared -soname=linux-vdso64.so.1 \
--hash-style=both --build-id=sha1 -T
@@ -37,12 +37,6 @@ obj-y += vdso64_wrapper.o
targets += vdso64.lds
CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
-# Disable gcov profiling, ubsan and kasan for VDSO code
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-
# Force dependency (incbin is bad)
$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
@@ -50,7 +44,7 @@ quiet_cmd_vdso_and_check = VDSO $@
cmd_vdso_and_check = $(cmd_ld); $(cmd_vdso_check)
# link rule for the .so file, .lds has to be first
-$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj-cvdso64) FORCE
+$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) $(obj-cvdso64) FORCE
$(call if_changed,vdso_and_check)
# strip rule for the .so file
@@ -72,7 +66,7 @@ quiet_cmd_vdso64cc = VDSO64C $@
cmd_vdso64cc = $(CC) $(c_flags) -c -o $@ $<
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+gen-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
diff --git a/arch/s390/kernel/vdso64/vdso_user_wrapper.S b/arch/s390/kernel/vdso64/vdso_user_wrapper.S
index 85247ef5a41b..e26e68675c08 100644
--- a/arch/s390/kernel/vdso64/vdso_user_wrapper.S
+++ b/arch/s390/kernel/vdso64/vdso_user_wrapper.S
@@ -6,8 +6,6 @@
#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
@@ -20,16 +18,17 @@
__ALIGN
__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)
- CFI_REL_OFFSET 14, STACK_FRAME_OVERHEAD
+ aghi %r15,-STACK_FRAME_VDSO_OVERHEAD
+ CFI_DEF_CFA_OFFSET (STACK_FRAME_USER_OVERHEAD + STACK_FRAME_VDSO_OVERHEAD)
+ CFI_VAL_OFFSET 15,-STACK_FRAME_USER_OVERHEAD
+ stg %r14,__SFVDSO_RETURN_ADDRESS(%r15)
+ CFI_REL_OFFSET 14,__SFVDSO_RETURN_ADDRESS
+ xc __SFUSER_BACKCHAIN(8,%r15),__SFUSER_BACKCHAIN(%r15)
brasl %r14,__s390_vdso_\func
- lg %r14,STACK_FRAME_OVERHEAD(%r15)
+ lg %r14,__SFVDSO_RETURN_ADDRESS(%r15)
CFI_RESTORE 14
- aghi %r15,WRAPPER_FRAME_SIZE
- CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
+ aghi %r15,STACK_FRAME_VDSO_OVERHEAD
+ CFI_DEF_CFA_OFFSET STACK_FRAME_USER_OVERHEAD
CFI_RESTORE 15
br %r14
CFI_ENDPROC
diff --git a/arch/s390/kernel/vmcore_info.c b/arch/s390/kernel/vmcore_info.c
index d296dfc22191..23f7d7619a99 100644
--- a/arch/s390/kernel/vmcore_info.c
+++ b/arch/s390/kernel/vmcore_info.c
@@ -14,7 +14,9 @@ void arch_crash_save_vmcoreinfo(void)
VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
vmcoreinfo_append_str("SAMODE31=%lx\n", (unsigned long)__samode31);
vmcoreinfo_append_str("EAMODE31=%lx\n", (unsigned long)__eamode31);
+ vmcoreinfo_append_str("IDENTITYBASE=%lx\n", __identity_base);
vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+ vmcoreinfo_append_str("KERNELOFFPHYS=%lx\n", __kaslr_offset_phys);
abs_lc = get_abs_lowcore();
abs_lc->vmcore_info = paddr_vmcoreinfo_note();
put_abs_lowcore(abs_lc);
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 48de296e8905..975c654cf5a5 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -39,7 +39,7 @@ PHDRS {
SECTIONS
{
- . = 0x100000;
+ . = __START_KERNEL;
.text : {
_stext = .; /* Start of text section */
_text = .; /* Text and read-only data */
@@ -183,39 +183,17 @@ SECTIONS
.amode31.data : {
*(.amode31.data)
}
- . = ALIGN(PAGE_SIZE);
+ . = _samode31 + AMODE31_SIZE;
_eamode31 = .;
/* early.c uses stsi, which requires page aligned data. */
. = ALIGN(PAGE_SIZE);
INIT_DATA_SECTION(0x100)
- PERCPU_SECTION(0x100)
+ RUNTIME_CONST(shift, d_hash_shift)
+ RUNTIME_CONST(ptr, dentry_hashtable)
-#ifdef CONFIG_PIE_BUILD
- .dynsym ALIGN(8) : {
- __dynsym_start = .;
- *(.dynsym)
- __dynsym_end = .;
- }
- .rela.dyn ALIGN(8) : {
- __rela_dyn_start = .;
- *(.rela*)
- __rela_dyn_end = .;
- }
- .dynamic ALIGN(8) : {
- *(.dynamic)
- }
- .dynstr ALIGN(8) : {
- *(.dynstr)
- }
-#endif
- .hash ALIGN(8) : {
- *(.hash)
- }
- .gnu.hash ALIGN(8) : {
- *(.gnu.hash)
- }
+ PERCPU_SECTION(0x100)
. = ALIGN(PAGE_SIZE);
__init_end = .; /* freed after init ends here */
@@ -230,7 +208,6 @@ SECTIONS
* it should match struct vmlinux_info
*/
.vmlinux.info 0 (INFO) : {
- QUAD(_stext) /* default_lma */
QUAD(startup_continue) /* entry */
QUAD(__bss_start - _stext) /* image_size */
QUAD(__bss_stop - __bss_start) /* bss_size */
@@ -239,18 +216,14 @@ SECTIONS
QUAD(__boot_data_preserved_start) /* bootdata_preserved_off */
QUAD(__boot_data_preserved_end -
__boot_data_preserved_start) /* bootdata_preserved_size */
-#ifdef CONFIG_PIE_BUILD
- QUAD(__dynsym_start) /* dynsym_start */
- QUAD(__rela_dyn_start) /* rela_dyn_start */
- QUAD(__rela_dyn_end) /* rela_dyn_end */
-#else
QUAD(__got_start) /* got_start */
QUAD(__got_end) /* got_end */
-#endif
QUAD(_eamode31 - _samode31) /* amode31_size */
QUAD(init_mm)
QUAD(swapper_pg_dir)
QUAD(invalid_pg_dir)
+ QUAD(__alt_instructions)
+ QUAD(__alt_instructions_end)
#ifdef CONFIG_KASAN
QUAD(kasan_early_shadow_page)
QUAD(kasan_early_shadow_pte)
@@ -282,12 +255,10 @@ SECTIONS
*(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
}
ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
-#ifndef CONFIG_PIE_BUILD
.rela.dyn : {
*(.rela.*) *(.rela_*)
}
ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
-#endif
/* Sections to be discarded */
DISCARDS
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 24a18e5ef6e8..234a0ba30510 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -33,24 +33,17 @@ static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
-static inline u64 get_vtimer(void)
-{
- u64 timer;
-
- asm volatile("stpt %0" : "=Q" (timer));
- return timer;
-}
-
static inline void set_vtimer(u64 expires)
{
+ struct lowcore *lc = get_lowcore();
u64 timer;
asm volatile(
" stpt %0\n" /* Store current cpu timer value */
" spt %1" /* Set new value imm. afterwards */
: "=Q" (timer) : "Q" (expires));
- S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer;
- S390_lowcore.last_update_timer = expires;
+ lc->system_timer += lc->last_update_timer - timer;
+ lc->last_update_timer = expires;
}
static inline int virt_timer_forward(u64 elapsed)
@@ -125,22 +118,23 @@ static void account_system_index_scaled(struct task_struct *p, u64 cputime,
static int do_account_vtime(struct task_struct *tsk)
{
u64 timer, clock, user, guest, system, hardirq, softirq;
+ struct lowcore *lc = get_lowcore();
- timer = S390_lowcore.last_update_timer;
- clock = S390_lowcore.last_update_clock;
+ timer = lc->last_update_timer;
+ clock = lc->last_update_clock;
asm volatile(
" stpt %0\n" /* Store current cpu timer value */
" stckf %1" /* Store current tod clock value */
- : "=Q" (S390_lowcore.last_update_timer),
- "=Q" (S390_lowcore.last_update_clock)
+ : "=Q" (lc->last_update_timer),
+ "=Q" (lc->last_update_clock)
: : "cc");
- clock = S390_lowcore.last_update_clock - clock;
- timer -= S390_lowcore.last_update_timer;
+ clock = lc->last_update_clock - clock;
+ timer -= lc->last_update_timer;
if (hardirq_count())
- S390_lowcore.hardirq_timer += timer;
+ lc->hardirq_timer += timer;
else
- S390_lowcore.system_timer += timer;
+ lc->system_timer += timer;
/* Update MT utilization calculation */
if (smp_cpu_mtid &&
@@ -149,16 +143,16 @@ static int do_account_vtime(struct task_struct *tsk)
/* Calculate cputime delta */
user = update_tsk_timer(&tsk->thread.user_timer,
- READ_ONCE(S390_lowcore.user_timer));
+ READ_ONCE(lc->user_timer));
guest = update_tsk_timer(&tsk->thread.guest_timer,
- READ_ONCE(S390_lowcore.guest_timer));
+ READ_ONCE(lc->guest_timer));
system = update_tsk_timer(&tsk->thread.system_timer,
- READ_ONCE(S390_lowcore.system_timer));
+ READ_ONCE(lc->system_timer));
hardirq = update_tsk_timer(&tsk->thread.hardirq_timer,
- READ_ONCE(S390_lowcore.hardirq_timer));
+ READ_ONCE(lc->hardirq_timer));
softirq = update_tsk_timer(&tsk->thread.softirq_timer,
- READ_ONCE(S390_lowcore.softirq_timer));
- S390_lowcore.steal_timer +=
+ READ_ONCE(lc->softirq_timer));
+ lc->steal_timer +=
clock - user - guest - system - hardirq - softirq;
/* Push account value */
@@ -184,17 +178,19 @@ static int do_account_vtime(struct task_struct *tsk)
void vtime_task_switch(struct task_struct *prev)
{
+ struct lowcore *lc = get_lowcore();
+
do_account_vtime(prev);
- prev->thread.user_timer = S390_lowcore.user_timer;
- prev->thread.guest_timer = S390_lowcore.guest_timer;
- prev->thread.system_timer = S390_lowcore.system_timer;
- prev->thread.hardirq_timer = S390_lowcore.hardirq_timer;
- prev->thread.softirq_timer = S390_lowcore.softirq_timer;
- S390_lowcore.user_timer = current->thread.user_timer;
- S390_lowcore.guest_timer = current->thread.guest_timer;
- S390_lowcore.system_timer = current->thread.system_timer;
- S390_lowcore.hardirq_timer = current->thread.hardirq_timer;
- S390_lowcore.softirq_timer = current->thread.softirq_timer;
+ prev->thread.user_timer = lc->user_timer;
+ prev->thread.guest_timer = lc->guest_timer;
+ prev->thread.system_timer = lc->system_timer;
+ prev->thread.hardirq_timer = lc->hardirq_timer;
+ prev->thread.softirq_timer = lc->softirq_timer;
+ lc->user_timer = current->thread.user_timer;
+ lc->guest_timer = current->thread.guest_timer;
+ lc->system_timer = current->thread.system_timer;
+ lc->hardirq_timer = current->thread.hardirq_timer;
+ lc->softirq_timer = current->thread.softirq_timer;
}
/*
@@ -204,28 +200,29 @@ void vtime_task_switch(struct task_struct *prev)
*/
void vtime_flush(struct task_struct *tsk)
{
+ struct lowcore *lc = get_lowcore();
u64 steal, avg_steal;
if (do_account_vtime(tsk))
virt_timer_expire();
- steal = S390_lowcore.steal_timer;
- avg_steal = S390_lowcore.avg_steal_timer;
+ steal = lc->steal_timer;
+ avg_steal = lc->avg_steal_timer;
if ((s64) steal > 0) {
- S390_lowcore.steal_timer = 0;
+ lc->steal_timer = 0;
account_steal_time(cputime_to_nsecs(steal));
avg_steal += steal;
}
- S390_lowcore.avg_steal_timer = avg_steal / 2;
+ lc->avg_steal_timer = avg_steal / 2;
}
static u64 vtime_delta(void)
{
- u64 timer = S390_lowcore.last_update_timer;
-
- S390_lowcore.last_update_timer = get_vtimer();
+ struct lowcore *lc = get_lowcore();
+ u64 timer = lc->last_update_timer;
- return timer - S390_lowcore.last_update_timer;
+ lc->last_update_timer = get_cpu_timer();
+ return timer - lc->last_update_timer;
}
/*
@@ -234,12 +231,13 @@ static u64 vtime_delta(void)
*/
void vtime_account_kernel(struct task_struct *tsk)
{
+ struct lowcore *lc = get_lowcore();
u64 delta = vtime_delta();
if (tsk->flags & PF_VCPU)
- S390_lowcore.guest_timer += delta;
+ lc->guest_timer += delta;
else
- S390_lowcore.system_timer += delta;
+ lc->system_timer += delta;
virt_timer_forward(delta);
}
@@ -249,7 +247,7 @@ void vtime_account_softirq(struct task_struct *tsk)
{
u64 delta = vtime_delta();
- S390_lowcore.softirq_timer += delta;
+ get_lowcore()->softirq_timer += delta;
virt_timer_forward(delta);
}
@@ -258,7 +256,7 @@ void vtime_account_hardirq(struct task_struct *tsk)
{
u64 delta = vtime_delta();
- S390_lowcore.hardirq_timer += delta;
+ get_lowcore()->hardirq_timer += delta;
virt_timer_forward(delta);
}
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index 5bf3d94e9dda..e65f597e3044 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -14,167 +14,10 @@
#include <asm/access-regs.h>
#include <asm/fault.h>
#include <asm/gmap.h>
+#include <asm/dat-bits.h>
#include "kvm-s390.h"
#include "gaccess.h"
-union asce {
- unsigned long val;
- struct {
- unsigned long origin : 52; /* Region- or Segment-Table Origin */
- unsigned long : 2;
- unsigned long g : 1; /* Subspace Group Control */
- unsigned long p : 1; /* Private Space Control */
- unsigned long s : 1; /* Storage-Alteration-Event Control */
- unsigned long x : 1; /* Space-Switch-Event Control */
- unsigned long r : 1; /* Real-Space Control */
- unsigned long : 1;
- unsigned long dt : 2; /* Designation-Type Control */
- unsigned long tl : 2; /* Region- or Segment-Table Length */
- };
-};
-
-enum {
- ASCE_TYPE_SEGMENT = 0,
- ASCE_TYPE_REGION3 = 1,
- ASCE_TYPE_REGION2 = 2,
- ASCE_TYPE_REGION1 = 3
-};
-
-union region1_table_entry {
- unsigned long val;
- struct {
- unsigned long rto: 52;/* Region-Table Origin */
- unsigned long : 2;
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long : 1;
- unsigned long tf : 2; /* Region-Second-Table Offset */
- unsigned long i : 1; /* Region-Invalid Bit */
- unsigned long : 1;
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long tl : 2; /* Region-Second-Table Length */
- };
-};
-
-union region2_table_entry {
- unsigned long val;
- struct {
- unsigned long rto: 52;/* Region-Table Origin */
- unsigned long : 2;
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long : 1;
- unsigned long tf : 2; /* Region-Third-Table Offset */
- unsigned long i : 1; /* Region-Invalid Bit */
- unsigned long : 1;
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long tl : 2; /* Region-Third-Table Length */
- };
-};
-
-struct region3_table_entry_fc0 {
- unsigned long sto: 52;/* Segment-Table Origin */
- unsigned long : 1;
- unsigned long fc : 1; /* Format-Control */
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long : 1;
- unsigned long tf : 2; /* Segment-Table Offset */
- unsigned long i : 1; /* Region-Invalid Bit */
- unsigned long cr : 1; /* Common-Region Bit */
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long tl : 2; /* Segment-Table Length */
-};
-
-struct region3_table_entry_fc1 {
- unsigned long rfaa : 33; /* Region-Frame Absolute Address */
- unsigned long : 14;
- unsigned long av : 1; /* ACCF-Validity Control */
- unsigned long acc: 4; /* Access-Control Bits */
- unsigned long f : 1; /* Fetch-Protection Bit */
- unsigned long fc : 1; /* Format-Control */
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long iep: 1; /* Instruction-Execution-Protection */
- unsigned long : 2;
- unsigned long i : 1; /* Region-Invalid Bit */
- unsigned long cr : 1; /* Common-Region Bit */
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long : 2;
-};
-
-union region3_table_entry {
- unsigned long val;
- struct region3_table_entry_fc0 fc0;
- struct region3_table_entry_fc1 fc1;
- struct {
- unsigned long : 53;
- unsigned long fc : 1; /* Format-Control */
- unsigned long : 4;
- unsigned long i : 1; /* Region-Invalid Bit */
- unsigned long cr : 1; /* Common-Region Bit */
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long : 2;
- };
-};
-
-struct segment_entry_fc0 {
- unsigned long pto: 53;/* Page-Table Origin */
- unsigned long fc : 1; /* Format-Control */
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long : 3;
- unsigned long i : 1; /* Segment-Invalid Bit */
- unsigned long cs : 1; /* Common-Segment Bit */
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long : 2;
-};
-
-struct segment_entry_fc1 {
- unsigned long sfaa : 44; /* Segment-Frame Absolute Address */
- unsigned long : 3;
- unsigned long av : 1; /* ACCF-Validity Control */
- unsigned long acc: 4; /* Access-Control Bits */
- unsigned long f : 1; /* Fetch-Protection Bit */
- unsigned long fc : 1; /* Format-Control */
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long iep: 1; /* Instruction-Execution-Protection */
- unsigned long : 2;
- unsigned long i : 1; /* Segment-Invalid Bit */
- unsigned long cs : 1; /* Common-Segment Bit */
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long : 2;
-};
-
-union segment_table_entry {
- unsigned long val;
- struct segment_entry_fc0 fc0;
- struct segment_entry_fc1 fc1;
- struct {
- unsigned long : 53;
- unsigned long fc : 1; /* Format-Control */
- unsigned long : 4;
- unsigned long i : 1; /* Segment-Invalid Bit */
- unsigned long cs : 1; /* Common-Segment Bit */
- unsigned long tt : 2; /* Table-Type Bits */
- unsigned long : 2;
- };
-};
-
-enum {
- TABLE_TYPE_SEGMENT = 0,
- TABLE_TYPE_REGION3 = 1,
- TABLE_TYPE_REGION2 = 2,
- TABLE_TYPE_REGION1 = 3
-};
-
-union page_table_entry {
- unsigned long val;
- struct {
- unsigned long pfra : 52; /* Page-Frame Real Address */
- unsigned long z : 1; /* Zero Bit */
- unsigned long i : 1; /* Page-Invalid Bit */
- unsigned long p : 1; /* DAT-Protection Bit */
- unsigned long iep: 1; /* Instruction-Execution-Protection */
- unsigned long : 8;
- };
-};
-
/*
* vaddress union in order to easily decode a virtual address into its
* region first index, region second index etc. parts.
@@ -632,7 +475,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
iep = ctlreg0.iep && test_kvm_facility(vcpu->kvm, 130);
if (asce.r)
goto real_address;
- ptr = asce.origin * PAGE_SIZE;
+ ptr = asce.rsto * PAGE_SIZE;
switch (asce.dt) {
case ASCE_TYPE_REGION1:
if (vaddr.rfx01 > asce.tl)
@@ -1379,7 +1222,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
parent = sg->parent;
vaddr.addr = saddr;
asce.val = sg->orig_asce;
- ptr = asce.origin * PAGE_SIZE;
+ ptr = asce.rsto * PAGE_SIZE;
if (asce.r) {
*fake = 1;
ptr = 0;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 5147b943a864..0fd96860fc45 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -132,6 +132,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
STATS_DESC_COUNTER(VCPU, instruction_io_other),
STATS_DESC_COUNTER(VCPU, instruction_lpsw),
STATS_DESC_COUNTER(VCPU, instruction_lpswe),
+ STATS_DESC_COUNTER(VCPU, instruction_lpswey),
STATS_DESC_COUNTER(VCPU, instruction_pfmf),
STATS_DESC_COUNTER(VCPU, instruction_ptff),
STATS_DESC_COUNTER(VCPU, instruction_sck),
@@ -587,7 +588,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
break;
case KVM_CAP_S390_HPAGE_1M:
r = 0;
- if (hpage && !kvm_is_ucontrol(kvm))
+ if (hpage && !(kvm && kvm_is_ucontrol(kvm)))
r = 1;
break;
case KVM_CAP_S390_MEM_OP:
@@ -2631,9 +2632,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
if (r)
break;
- mmap_write_lock(current->mm);
- r = gmap_mark_unmergeable();
- mmap_write_unlock(current->mm);
+ r = s390_disable_cow_sharing();
if (r)
break;
@@ -2998,14 +2997,9 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
break;
}
case KVM_CREATE_IRQCHIP: {
- struct kvm_irq_routing_entry routing;
-
r = -EINVAL;
- if (kvm->arch.use_irqchip) {
- /* Set up dummy routing. */
- memset(&routing, 0, sizeof(routing));
- r = kvm_set_irq_routing(kvm, &routing, 0, 0);
- }
+ if (kvm->arch.use_irqchip)
+ r = 0;
break;
}
case KVM_SET_DEVICE_ATTR: {
@@ -4081,7 +4075,7 @@ static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start,
bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
{
/* do not poll with more than halt_poll_max_steal percent of steal time */
- if (S390_lowcore.avg_steal_timer * 100 / (TICK_USEC << 12) >=
+ if (get_lowcore()->avg_steal_timer * 100 / (TICK_USEC << 12) >=
READ_ONCE(halt_poll_max_steal)) {
vcpu->stat.halt_no_poll_steal++;
return true;
@@ -4831,7 +4825,8 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
sizeof(sie_page->pv_grregs));
}
exit_reason = sie64a(vcpu->arch.sie_block,
- vcpu->run->s.regs.gprs);
+ vcpu->run->s.regs.gprs,
+ gmap_get_enabled()->asce);
if (kvm_s390_pv_cpu_is_protected(vcpu)) {
memcpy(vcpu->run->s.regs.gprs,
sie_page->pv_grregs,
@@ -5033,7 +5028,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
if (vcpu->kvm->arch.pv.dumping)
return -EINVAL;
- if (kvm_run->immediate_exit)
+ if (!vcpu->wants_to_run)
return -EINTR;
if (kvm_run->kvm_valid_regs & ~KVM_SYNC_S390_VALID_FIELDS ||
@@ -5750,6 +5745,9 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
{
gpa_t size;
+ if (kvm_is_ucontrol(kvm))
+ return -EINVAL;
+
/* When we are protected, we should not change the memory slots */
if (kvm_s390_pv_get_handle(kvm))
return -EINVAL;
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 111eb5c74784..bf8534218af3 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -138,6 +138,21 @@ static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu, u8 *ar)
return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2;
}
+static inline u64 kvm_s390_get_base_disp_siy(struct kvm_vcpu *vcpu, u8 *ar)
+{
+ u32 base1 = vcpu->arch.sie_block->ipb >> 28;
+ s64 disp1;
+
+ /* The displacement is a 20bit _SIGNED_ value */
+ disp1 = sign_extend64(((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) +
+ ((vcpu->arch.sie_block->ipb & 0xff00) << 4), 19);
+
+ if (ar)
+ *ar = base1;
+
+ return (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1;
+}
+
static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu,
u64 *address1, u64 *address2,
u8 *ar_b1, u8 *ar_b2)
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 1be19cc9d73c..1a49b89706f8 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -797,6 +797,36 @@ static int handle_lpswe(struct kvm_vcpu *vcpu)
return 0;
}
+static int handle_lpswey(struct kvm_vcpu *vcpu)
+{
+ psw_t new_psw;
+ u64 addr;
+ int rc;
+ u8 ar;
+
+ vcpu->stat.instruction_lpswey++;
+
+ if (!test_kvm_facility(vcpu->kvm, 193))
+ return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
+
+ if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+ return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+ addr = kvm_s390_get_base_disp_siy(vcpu, &ar);
+ if (addr & 7)
+ return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+ rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw));
+ if (rc)
+ return kvm_s390_inject_prog_cond(vcpu, rc);
+
+ vcpu->arch.sie_block->gpsw = new_psw;
+ if (!is_valid_psw(&vcpu->arch.sie_block->gpsw))
+ return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+ return 0;
+}
+
static int handle_stidp(struct kvm_vcpu *vcpu)
{
u64 stidp_data = vcpu->kvm->arch.model.cpuid;
@@ -1462,6 +1492,8 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
case 0x61:
case 0x62:
return handle_ri(vcpu);
+ case 0x71:
+ return handle_lpswey(vcpu);
default:
return -EOPNOTSUPP;
}
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
index b2c9f010f0fe..89cafea4c41f 100644
--- a/arch/s390/kvm/vsie.c
+++ b/arch/s390/kvm/vsie.c
@@ -12,6 +12,7 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/sched/signal.h>
+#include <linux/io.h>
#include <asm/gmap.h>
#include <asm/mmu_context.h>
@@ -361,7 +362,7 @@ end:
case -EACCES:
return set_validity_icpt(scb_s, 0x003CU);
}
- scb_s->crycbd = ((__u32)(__u64) &vsie_page->crycb) | CRYCB_FORMAT2;
+ scb_s->crycbd = (u32)virt_to_phys(&vsie_page->crycb) | CRYCB_FORMAT2;
return 0;
}
@@ -1005,7 +1006,7 @@ static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
if (read_guest_real(vcpu, fac, &vsie_page->fac,
stfle_size() * sizeof(u64)))
return set_validity_icpt(scb_s, 0x1090U);
- scb_s->fac = (__u32)(__u64) &vsie_page->fac;
+ scb_s->fac = (u32)virt_to_phys(&vsie_page->fac);
}
return 0;
}
@@ -1149,7 +1150,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
vcpu->arch.sie_block->prog0c |= PROG_IN_SIE;
barrier();
if (!kvm_s390_vcpu_sie_inhibited(vcpu))
- rc = sie64a(scb_s, vcpu->run->s.regs.gprs);
+ rc = sie64a(scb_s, vcpu->run->s.regs.gprs, gmap_get_enabled()->asce);
barrier();
vcpu->arch.sie_block->prog0c &= ~PROG_IN_SIE;
@@ -1303,10 +1304,24 @@ static int vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
if (rc == -EAGAIN)
rc = 0;
- if (rc || scb_s->icptcode || signal_pending(current) ||
+
+ /*
+ * Exit the loop if the guest needs to process the intercept
+ */
+ if (rc || scb_s->icptcode)
+ break;
+
+ /*
+ * Exit the loop if the host needs to process an intercept,
+ * but rewind the PSW to re-enter SIE once that's completed
+ * instead of passing a "no action" intercept to the guest.
+ */
+ if (signal_pending(current) ||
kvm_s390_vcpu_has_irq(vcpu, 0) ||
- kvm_s390_vcpu_sie_inhibited(vcpu))
+ kvm_s390_vcpu_sie_inhibited(vcpu)) {
+ kvm_s390_rewind_psw(vcpu, 4);
break;
+ }
cond_resched();
}
@@ -1425,8 +1440,10 @@ int kvm_s390_handle_vsie(struct kvm_vcpu *vcpu)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
if (signal_pending(current) || kvm_s390_vcpu_has_irq(vcpu, 0) ||
- kvm_s390_vcpu_sie_inhibited(vcpu))
+ kvm_s390_vcpu_sie_inhibited(vcpu)) {
+ kvm_s390_rewind_psw(vcpu, 4);
return 0;
+ }
vsie_page = get_vsie_page(vcpu->kvm, scb_addr);
if (IS_ERR(vsie_page))
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 90eac15ea62a..f43f897d3fc0 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -23,4 +23,4 @@ obj-$(CONFIG_S390_MODULES_SANITY_TEST_HELPERS) += test_modules_helpers.o
lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
-obj-$(CONFIG_EXPOLINE_EXTERN) += expoline/
+obj-$(CONFIG_EXPOLINE_EXTERN) += expoline.o
diff --git a/arch/s390/lib/expoline/expoline.S b/arch/s390/lib/expoline.S
index 92ed8409a7a4..92ed8409a7a4 100644
--- a/arch/s390/lib/expoline/expoline.S
+++ b/arch/s390/lib/expoline.S
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 81c53440b3e6..9f86ad8fa8b4 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -75,7 +75,7 @@ static inline int arch_load_niai4(int *lock)
int owner;
asm_inline volatile(
- ALTERNATIVE("nop", ".insn rre,0xb2fa0000,4,0", 49) /* NIAI 4 */
+ ALTERNATIVE("nop", ".insn rre,0xb2fa0000,4,0", ALT_FACILITY(49)) /* NIAI 4 */
" l %0,%1\n"
: "=d" (owner) : "Q" (*lock) : "memory");
return owner;
@@ -86,7 +86,7 @@ static inline int arch_cmpxchg_niai8(int *lock, int old, int new)
int expected = old;
asm_inline volatile(
- ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", 49) /* NIAI 8 */
+ ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", ALT_FACILITY(49)) /* NIAI 8 */
" cs %0,%3,%1\n"
: "=d" (old), "=Q" (*lock)
: "0" (old), "d" (new), "Q" (*lock)
@@ -119,7 +119,7 @@ static inline void arch_spin_lock_queued(arch_spinlock_t *lp)
struct spin_wait *node, *next;
int lockval, ix, node_id, tail_id, old, new, owner, count;
- ix = S390_lowcore.spinlock_index++;
+ ix = get_lowcore()->spinlock_index++;
barrier();
lockval = SPINLOCK_LOCKVAL; /* cpu + 1 */
node = this_cpu_ptr(&spin_wait[ix]);
@@ -205,7 +205,7 @@ static inline void arch_spin_lock_queued(arch_spinlock_t *lp)
}
out:
- S390_lowcore.spinlock_index--;
+ get_lowcore()->spinlock_index--;
}
static inline void arch_spin_lock_classic(arch_spinlock_t *lp)
diff --git a/arch/s390/lib/test_kprobes.c b/arch/s390/lib/test_kprobes.c
index 9e62d62812e5..9021298c3e8a 100644
--- a/arch/s390/lib/test_kprobes.c
+++ b/arch/s390/lib/test_kprobes.c
@@ -72,4 +72,5 @@ static struct kunit_suite kprobes_test_suite = {
kunit_test_suites(&kprobes_test_suite);
+MODULE_DESCRIPTION("KUnit tests for kprobes");
MODULE_LICENSE("GPL");
diff --git a/arch/s390/lib/test_modules.c b/arch/s390/lib/test_modules.c
index 9894009fc1f2..f96b6a3737e7 100644
--- a/arch/s390/lib/test_modules.c
+++ b/arch/s390/lib/test_modules.c
@@ -29,4 +29,5 @@ static struct kunit_suite modules_test_suite = {
kunit_test_suites(&modules_test_suite);
+MODULE_DESCRIPTION("KUnit test that modules with many relocations are loaded properly");
MODULE_LICENSE("GPL");
diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c
index 2848e3fb2ff5..8b7f981e6f34 100644
--- a/arch/s390/lib/test_unwind.c
+++ b/arch/s390/lib/test_unwind.c
@@ -356,7 +356,7 @@ static noinline int unwindme_func2(struct unwindme *u)
if (u->flags & UWM_SWITCH_STACK) {
local_irq_save(flags);
local_mcck_save(mflags);
- rc = call_on_stack(1, S390_lowcore.nodat_stack,
+ rc = call_on_stack(1, get_lowcore()->nodat_stack,
int, unwindme_func3, struct unwindme *, u);
local_mcck_restore(mflags);
local_irq_restore(flags);
@@ -519,4 +519,5 @@ static struct kunit_suite test_unwind_suite = {
kunit_test_suites(&test_unwind_suite);
+MODULE_DESCRIPTION("KUnit test for unwind_for_each_frame");
MODULE_LICENSE("GPL");
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
index 61d8dcd95bbc..c7c269d5c491 100644
--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -21,13 +21,13 @@ void debug_user_asce(int exit)
local_ctl_store(1, &cr1);
local_ctl_store(7, &cr7);
- if (cr1.val == S390_lowcore.kernel_asce.val && cr7.val == S390_lowcore.user_asce.val)
+ if (cr1.val == get_lowcore()->kernel_asce.val && cr7.val == get_lowcore()->user_asce.val)
return;
panic("incorrect ASCE on kernel %s\n"
"cr1: %016lx cr7: %016lx\n"
"kernel: %016lx user: %016lx\n",
exit ? "exit" : "entry", cr1.val, cr7.val,
- S390_lowcore.kernel_asce.val, S390_lowcore.user_asce.val);
+ get_lowcore()->kernel_asce.val, get_lowcore()->user_asce.val);
}
#endif /*CONFIG_DEBUG_ENTRY */
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index f8b13f247646..75d15bf41d97 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -243,7 +243,7 @@ static int cmm_skip_blanks(char *cp, char **endp)
return str != cp;
}
-static int cmm_pages_handler(struct ctl_table *ctl, int write,
+static int cmm_pages_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
long nr = cmm_get_pages();
@@ -262,7 +262,7 @@ static int cmm_pages_handler(struct ctl_table *ctl, int write,
return 0;
}
-static int cmm_timed_pages_handler(struct ctl_table *ctl, int write,
+static int cmm_timed_pages_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp,
loff_t *ppos)
{
@@ -282,7 +282,7 @@ static int cmm_timed_pages_handler(struct ctl_table *ctl, int write,
return 0;
}
-static int cmm_timeout_handler(struct ctl_table *ctl, int write,
+static int cmm_timeout_handler(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
char buf[64], *p;
@@ -427,4 +427,5 @@ static void __exit cmm_exit(void)
}
module_exit(cmm_exit);
+MODULE_DESCRIPTION("Cooperative memory management interface");
MODULE_LICENSE("GPL");
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
index ffd07ed7b4af..98dab3e049de 100644
--- a/arch/s390/mm/dump_pagetables.c
+++ b/arch/s390/mm/dump_pagetables.c
@@ -36,6 +36,16 @@ enum address_markers_idx {
VMEMMAP_END_NR,
VMALLOC_NR,
VMALLOC_END_NR,
+#ifdef CONFIG_KMSAN
+ KMSAN_VMALLOC_SHADOW_START_NR,
+ KMSAN_VMALLOC_SHADOW_END_NR,
+ KMSAN_VMALLOC_ORIGIN_START_NR,
+ KMSAN_VMALLOC_ORIGIN_END_NR,
+ KMSAN_MODULES_SHADOW_START_NR,
+ KMSAN_MODULES_SHADOW_END_NR,
+ KMSAN_MODULES_ORIGIN_START_NR,
+ KMSAN_MODULES_ORIGIN_END_NR,
+#endif
MODULES_NR,
MODULES_END_NR,
ABS_LOWCORE_NR,
@@ -65,6 +75,16 @@ static struct addr_marker address_markers[] = {
[VMEMMAP_END_NR] = {0, "vmemmap Area End"},
[VMALLOC_NR] = {0, "vmalloc Area Start"},
[VMALLOC_END_NR] = {0, "vmalloc Area End"},
+#ifdef CONFIG_KMSAN
+ [KMSAN_VMALLOC_SHADOW_START_NR] = {0, "Kmsan vmalloc Shadow Start"},
+ [KMSAN_VMALLOC_SHADOW_END_NR] = {0, "Kmsan vmalloc Shadow End"},
+ [KMSAN_VMALLOC_ORIGIN_START_NR] = {0, "Kmsan vmalloc Origins Start"},
+ [KMSAN_VMALLOC_ORIGIN_END_NR] = {0, "Kmsan vmalloc Origins End"},
+ [KMSAN_MODULES_SHADOW_START_NR] = {0, "Kmsan Modules Shadow Start"},
+ [KMSAN_MODULES_SHADOW_END_NR] = {0, "Kmsan Modules Shadow End"},
+ [KMSAN_MODULES_ORIGIN_START_NR] = {0, "Kmsan Modules Origins Start"},
+ [KMSAN_MODULES_ORIGIN_END_NR] = {0, "Kmsan Modules Origins End"},
+#endif
[MODULES_NR] = {0, "Modules Area Start"},
[MODULES_END_NR] = {0, "Modules Area End"},
[ABS_LOWCORE_NR] = {0, "Lowcore Area Start"},
@@ -288,7 +308,7 @@ static int pt_dump_init(void)
* kernel ASCE. We need this to keep the page table walker functions
* from accessing non-existent entries.
*/
- max_addr = (S390_lowcore.kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2;
+ max_addr = (get_lowcore()->kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2;
max_addr = 1UL << (max_addr * 11 + 31);
address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size;
address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
@@ -307,6 +327,16 @@ static int pt_dump_init(void)
address_markers[KFENCE_START_NR].start_address = kfence_start;
address_markers[KFENCE_END_NR].start_address = kfence_start + KFENCE_POOL_SIZE;
#endif
+#ifdef CONFIG_KMSAN
+ address_markers[KMSAN_VMALLOC_SHADOW_START_NR].start_address = KMSAN_VMALLOC_SHADOW_START;
+ address_markers[KMSAN_VMALLOC_SHADOW_END_NR].start_address = KMSAN_VMALLOC_SHADOW_END;
+ address_markers[KMSAN_VMALLOC_ORIGIN_START_NR].start_address = KMSAN_VMALLOC_ORIGIN_START;
+ address_markers[KMSAN_VMALLOC_ORIGIN_END_NR].start_address = KMSAN_VMALLOC_ORIGIN_END;
+ address_markers[KMSAN_MODULES_SHADOW_START_NR].start_address = KMSAN_MODULES_SHADOW_START;
+ address_markers[KMSAN_MODULES_SHADOW_END_NR].start_address = KMSAN_MODULES_SHADOW_END;
+ address_markers[KMSAN_MODULES_ORIGIN_START_NR].start_address = KMSAN_MODULES_ORIGIN_START;
+ address_markers[KMSAN_MODULES_ORIGIN_END_NR].start_address = KMSAN_MODULES_ORIGIN_END;
+#endif
sort_address_markers();
#ifdef CONFIG_PTDUMP_DEBUGFS
debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 0c66b32e0f9f..8e149ef5e89b 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -74,7 +74,7 @@ static enum fault_type get_fault_type(struct pt_regs *regs)
return USER_FAULT;
if (!IS_ENABLED(CONFIG_PGSTE))
return KERNEL_FAULT;
- gmap = (struct gmap *)S390_lowcore.gmap;
+ gmap = (struct gmap *)get_lowcore()->gmap;
if (gmap && gmap->asce == regs->cr1)
return GMAP_FAULT;
return KERNEL_FAULT;
@@ -182,15 +182,15 @@ static void dump_fault_info(struct pt_regs *regs)
pr_cont("mode while using ");
switch (get_fault_type(regs)) {
case USER_FAULT:
- asce = S390_lowcore.user_asce.val;
+ asce = get_lowcore()->user_asce.val;
pr_cont("user ");
break;
case GMAP_FAULT:
- asce = ((struct gmap *)S390_lowcore.gmap)->asce;
+ asce = ((struct gmap *)get_lowcore()->gmap)->asce;
pr_cont("gmap ");
break;
case KERNEL_FAULT:
- asce = S390_lowcore.kernel_asce.val;
+ asce = get_lowcore()->kernel_asce.val;
pr_cont("kernel ");
break;
default:
@@ -325,7 +325,8 @@ static void do_exception(struct pt_regs *regs, int access)
goto lock_mmap;
if (!(vma->vm_flags & access)) {
vma_end_read(vma);
- goto lock_mmap;
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ return handle_fault_error_nolock(regs, SEGV_ACCERR);
}
fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs);
if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
@@ -350,7 +351,7 @@ lock_mmap:
mmap_read_lock(mm);
gmap = NULL;
if (IS_ENABLED(CONFIG_PGSTE) && type == GMAP_FAULT) {
- gmap = (struct gmap *)S390_lowcore.gmap;
+ gmap = (struct gmap *)get_lowcore()->gmap;
current->thread.gmap_addr = address;
current->thread.gmap_write_flag = !!(flags & FAULT_FLAG_WRITE);
current->thread.gmap_int_code = regs->int_code & 0xffff;
@@ -432,12 +433,13 @@ error:
handle_fault_error_nolock(regs, 0);
else
do_sigsegv(regs, SEGV_MAPERR);
- } else if (fault & VM_FAULT_SIGBUS) {
+ } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) {
if (!user_mode(regs))
handle_fault_error_nolock(regs, 0);
else
do_sigbus(regs);
} else {
+ pr_emerg("Unexpected fault flags: %08x\n", fault);
BUG();
}
}
@@ -491,6 +493,7 @@ void do_secure_storage_access(struct pt_regs *regs)
unsigned long addr = get_fault_address(regs);
struct vm_area_struct *vma;
struct mm_struct *mm;
+ struct folio *folio;
struct page *page;
struct gmap *gmap;
int rc;
@@ -520,7 +523,7 @@ void do_secure_storage_access(struct pt_regs *regs)
switch (get_fault_type(regs)) {
case GMAP_FAULT:
mm = current->mm;
- gmap = (struct gmap *)S390_lowcore.gmap;
+ gmap = (struct gmap *)get_lowcore()->gmap;
mmap_read_lock(mm);
addr = __gmap_translate(gmap, addr);
mmap_read_unlock(mm);
@@ -538,17 +541,18 @@ void do_secure_storage_access(struct pt_regs *regs)
mmap_read_unlock(mm);
break;
}
- if (arch_make_page_accessible(page))
+ folio = page_folio(page);
+ if (arch_make_folio_accessible(folio))
send_sig(SIGSEGV, current, 0);
- put_page(page);
+ folio_put(folio);
mmap_read_unlock(mm);
break;
case KERNEL_FAULT:
- page = phys_to_page(addr);
- if (unlikely(!try_get_page(page)))
+ folio = phys_to_folio(addr);
+ if (unlikely(!folio_try_get(folio)))
break;
- rc = arch_make_page_accessible(page);
- put_page(page);
+ rc = arch_make_folio_accessible(folio);
+ folio_put(folio);
if (rc)
BUG();
break;
@@ -560,7 +564,7 @@ NOKPROBE_SYMBOL(do_secure_storage_access);
void do_non_secure_storage_access(struct pt_regs *regs)
{
- struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
+ struct gmap *gmap = (struct gmap *)get_lowcore()->gmap;
unsigned long gaddr = get_fault_address(regs);
if (WARN_ON_ONCE(get_fault_type(regs) != GMAP_FAULT))
@@ -572,7 +576,7 @@ NOKPROBE_SYMBOL(do_non_secure_storage_access);
void do_secure_storage_violation(struct pt_regs *regs)
{
- struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
+ struct gmap *gmap = (struct gmap *)get_lowcore()->gmap;
unsigned long gaddr = get_fault_address(regs);
/*
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 12d22a7fa32f..eb0b51a36be0 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -287,7 +287,7 @@ EXPORT_SYMBOL_GPL(gmap_remove);
*/
void gmap_enable(struct gmap *gmap)
{
- S390_lowcore.gmap = (unsigned long) gmap;
+ get_lowcore()->gmap = (unsigned long)gmap;
}
EXPORT_SYMBOL_GPL(gmap_enable);
@@ -297,7 +297,7 @@ EXPORT_SYMBOL_GPL(gmap_enable);
*/
void gmap_disable(struct gmap *gmap)
{
- S390_lowcore.gmap = 0UL;
+ get_lowcore()->gmap = 0UL;
}
EXPORT_SYMBOL_GPL(gmap_disable);
@@ -308,7 +308,7 @@ EXPORT_SYMBOL_GPL(gmap_disable);
*/
struct gmap *gmap_get_enabled(void)
{
- return (struct gmap *) S390_lowcore.gmap;
+ return (struct gmap *)get_lowcore()->gmap;
}
EXPORT_SYMBOL_GPL(gmap_get_enabled);
@@ -2550,41 +2550,6 @@ static inline void thp_split_mm(struct mm_struct *mm)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
/*
- * Remove all empty zero pages from the mapping for lazy refaulting
- * - This must be called after mm->context.has_pgste is set, to avoid
- * future creation of zero pages
- * - This must be called after THP was disabled.
- *
- * mm contracts with s390, that even if mm were to remove a page table,
- * racing with the loop below and so causing pte_offset_map_lock() to fail,
- * it will never insert a page table containing empty zero pages once
- * mm_forbids_zeropage(mm) i.e. mm->context.has_pgste is set.
- */
-static int __zap_zero_pages(pmd_t *pmd, unsigned long start,
- unsigned long end, struct mm_walk *walk)
-{
- unsigned long addr;
-
- for (addr = start; addr != end; addr += PAGE_SIZE) {
- pte_t *ptep;
- spinlock_t *ptl;
-
- ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
- if (!ptep)
- break;
- if (is_zero_pfn(pte_pfn(*ptep)))
- ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID));
- pte_unmap_unlock(ptep, ptl);
- }
- return 0;
-}
-
-static const struct mm_walk_ops zap_zero_walk_ops = {
- .pmd_entry = __zap_zero_pages,
- .walk_lock = PGWALK_WRLOCK,
-};
-
-/*
* switch on pgstes for its userspace process (for kvm)
*/
int s390_enable_sie(void)
@@ -2601,22 +2566,142 @@ int s390_enable_sie(void)
mm->context.has_pgste = 1;
/* split thp mappings and disable thp for future mappings */
thp_split_mm(mm);
- walk_page_range(mm, 0, TASK_SIZE, &zap_zero_walk_ops, NULL);
mmap_write_unlock(mm);
return 0;
}
EXPORT_SYMBOL_GPL(s390_enable_sie);
-int gmap_mark_unmergeable(void)
+static int find_zeropage_pte_entry(pte_t *pte, unsigned long addr,
+ unsigned long end, struct mm_walk *walk)
+{
+ unsigned long *found_addr = walk->private;
+
+ /* Return 1 of the page is a zeropage. */
+ if (is_zero_pfn(pte_pfn(*pte))) {
+ /*
+ * Shared zeropage in e.g., a FS DAX mapping? We cannot do the
+ * right thing and likely don't care: FAULT_FLAG_UNSHARE
+ * currently only works in COW mappings, which is also where
+ * mm_forbids_zeropage() is checked.
+ */
+ if (!is_cow_mapping(walk->vma->vm_flags))
+ return -EFAULT;
+
+ *found_addr = addr;
+ return 1;
+ }
+ return 0;
+}
+
+static const struct mm_walk_ops find_zeropage_ops = {
+ .pte_entry = find_zeropage_pte_entry,
+ .walk_lock = PGWALK_WRLOCK,
+};
+
+/*
+ * Unshare all shared zeropages, replacing them by anonymous pages. Note that
+ * we cannot simply zap all shared zeropages, because this could later
+ * trigger unexpected userfaultfd missing events.
+ *
+ * This must be called after mm->context.allow_cow_sharing was
+ * set to 0, to avoid future mappings of shared zeropages.
+ *
+ * mm contracts with s390, that even if mm were to remove a page table,
+ * and racing with walk_page_range_vma() calling pte_offset_map_lock()
+ * would fail, it will never insert a page table containing empty zero
+ * pages once mm_forbids_zeropage(mm) i.e.
+ * mm->context.allow_cow_sharing is set to 0.
+ */
+static int __s390_unshare_zeropages(struct mm_struct *mm)
+{
+ struct vm_area_struct *vma;
+ VMA_ITERATOR(vmi, mm, 0);
+ unsigned long addr;
+ vm_fault_t fault;
+ int rc;
+
+ for_each_vma(vmi, vma) {
+ /*
+ * We could only look at COW mappings, but it's more future
+ * proof to catch unexpected zeropages in other mappings and
+ * fail.
+ */
+ if ((vma->vm_flags & VM_PFNMAP) || is_vm_hugetlb_page(vma))
+ continue;
+ addr = vma->vm_start;
+
+retry:
+ rc = walk_page_range_vma(vma, addr, vma->vm_end,
+ &find_zeropage_ops, &addr);
+ if (rc < 0)
+ return rc;
+ else if (!rc)
+ continue;
+
+ /* addr was updated by find_zeropage_pte_entry() */
+ fault = handle_mm_fault(vma, addr,
+ FAULT_FLAG_UNSHARE | FAULT_FLAG_REMOTE,
+ NULL);
+ if (fault & VM_FAULT_OOM)
+ return -ENOMEM;
+ /*
+ * See break_ksm(): even after handle_mm_fault() returned 0, we
+ * must start the lookup from the current address, because
+ * handle_mm_fault() may back out if there's any difficulty.
+ *
+ * VM_FAULT_SIGBUS and VM_FAULT_SIGSEGV are unexpected but
+ * maybe they could trigger in the future on concurrent
+ * truncation. In that case, the shared zeropage would be gone
+ * and we can simply retry and make progress.
+ */
+ cond_resched();
+ goto retry;
+ }
+
+ return 0;
+}
+
+static int __s390_disable_cow_sharing(struct mm_struct *mm)
{
+ int rc;
+
+ if (!mm->context.allow_cow_sharing)
+ return 0;
+
+ mm->context.allow_cow_sharing = 0;
+
+ /* Replace all shared zeropages by anonymous pages. */
+ rc = __s390_unshare_zeropages(mm);
/*
* Make sure to disable KSM (if enabled for the whole process or
* individual VMAs). Note that nothing currently hinders user space
* from re-enabling it.
*/
- return ksm_disable(current->mm);
+ if (!rc)
+ rc = ksm_disable(mm);
+ if (rc)
+ mm->context.allow_cow_sharing = 1;
+ return rc;
+}
+
+/*
+ * Disable most COW-sharing of memory pages for the whole process:
+ * (1) Disable KSM and unmerge/unshare any KSM pages.
+ * (2) Disallow shared zeropages and unshare any zerpages that are mapped.
+ *
+ * Not that we currently don't bother with COW-shared pages that are shared
+ * with parent/child processes due to fork().
+ */
+int s390_disable_cow_sharing(void)
+{
+ int rc;
+
+ mmap_write_lock(current->mm);
+ rc = __s390_disable_cow_sharing(current->mm);
+ mmap_write_unlock(current->mm);
+ return rc;
}
-EXPORT_SYMBOL_GPL(gmap_mark_unmergeable);
+EXPORT_SYMBOL_GPL(s390_disable_cow_sharing);
/*
* Enable storage key handling from now on and initialize the storage
@@ -2648,7 +2733,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
{
pmd_t *pmd = (pmd_t *)pte;
unsigned long start, end;
- struct page *page = pmd_page(*pmd);
+ struct folio *folio = page_folio(pmd_page(*pmd));
/*
* The write check makes sure we do not set a key on shared
@@ -2663,7 +2748,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
start = pmd_val(*pmd) & HPAGE_MASK;
end = start + HPAGE_SIZE;
__storage_key_init_range(start, end);
- set_bit(PG_arch_1, &page->flags);
+ set_bit(PG_arch_1, &folio->flags);
cond_resched();
return 0;
}
@@ -2685,7 +2770,7 @@ int s390_enable_skey(void)
goto out_up;
mm->context.uses_skeys = 1;
- rc = gmap_mark_unmergeable();
+ rc = __s390_disable_cow_sharing(mm);
if (rc) {
mm->context.uses_skeys = 0;
goto out_up;
@@ -2756,13 +2841,15 @@ static const struct mm_walk_ops gather_pages_ops = {
*/
void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns)
{
+ struct folio *folio;
unsigned long i;
for (i = 0; i < count; i++) {
+ folio = pfn_folio(pfns[i]);
/* we always have an extra reference */
- uv_destroy_owned_page(pfn_to_phys(pfns[i]));
+ uv_destroy_folio(folio);
/* get rid of the extra reference */
- put_page(pfn_to_page(pfns[i]));
+ folio_put(folio);
cond_resched();
}
}
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index dc3db86e13ff..ded0eff58a19 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -121,7 +121,7 @@ static inline pte_t __rste_to_pte(unsigned long rste)
static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
{
- struct page *page;
+ struct folio *folio;
unsigned long size, paddr;
if (!mm_uses_skeys(mm) ||
@@ -129,16 +129,16 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
return;
if ((rste & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) {
- page = pud_page(__pud(rste));
+ folio = page_folio(pud_page(__pud(rste)));
size = PUD_SIZE;
paddr = rste & PUD_MASK;
} else {
- page = pmd_page(__pmd(rste));
+ folio = page_folio(pmd_page(__pmd(rste)));
size = PMD_SIZE;
paddr = rste & PMD_MASK;
}
- if (!test_and_set_bit(PG_arch_1, &page->flags))
+ if (!test_and_set_bit(PG_arch_1, &folio->flags))
__storage_key_init_range(paddr, paddr + size);
}
@@ -169,7 +169,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
__set_huge_pte_at(mm, addr, ptep, pte);
}
-pte_t huge_ptep_get(pte_t *ptep)
+pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
return __rste_to_pte(pte_val(*ptep));
}
@@ -177,7 +177,7 @@ pte_t huge_ptep_get(pte_t *ptep)
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
- pte_t pte = huge_ptep_get(ptep);
+ pte_t pte = huge_ptep_get(mm, addr, ptep);
pmd_t *pmdp = (pmd_t *) ptep;
pud_t *pudp = (pud_t *) ptep;
@@ -233,16 +233,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
return (pte_t *) pmdp;
}
-int pmd_huge(pmd_t pmd)
-{
- return pmd_leaf(pmd);
-}
-
-int pud_huge(pud_t pud)
-{
- return pud_leaf(pud);
-}
-
bool __init arch_hugetlb_valid_size(unsigned long size)
{
if (MACHINE_HAS_EDAT1 && size == PMD_SIZE)
@@ -258,14 +248,12 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
- info.flags = 0;
info.length = len;
info.low_limit = current->mm->mmap_base;
info.high_limit = TASK_SIZE;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- info.align_offset = 0;
return vm_unmapped_area(&info);
}
@@ -274,7 +262,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
unsigned long addr;
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
@@ -282,7 +270,6 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
info.low_limit = PAGE_SIZE;
info.high_limit = current->mm->mmap_base;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- info.align_offset = 0;
addr = vm_unmapped_area(&info);
/*
@@ -328,7 +315,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
goto check_asce_limit;
}
- if (mm->get_unmapped_area == arch_get_unmapped_area)
+ if (!test_bit(MMF_TOPDOWN, &mm->flags))
addr = hugetlb_get_unmapped_area_bottomup(file, addr, len,
pgoff, flags);
else
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index f6391442c0c2..ddcd39ef4346 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -49,6 +49,7 @@
#include <asm/uv.h>
#include <linux/virtio_anchor.h>
#include <linux/virtio_config.h>
+#include <linux/execmem.h>
pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(".bss..swapper_pg_dir");
pgd_t invalid_pg_dir[PTRS_PER_PGD] __section(".bss..invalid_pg_dir");
@@ -61,6 +62,7 @@ EXPORT_SYMBOL(zero_page_mask);
static void __init setup_zero_pages(void)
{
+ unsigned long total_pages = PHYS_PFN(memblock_phys_mem_size() - memblock_reserved_size());
unsigned int order;
struct page *page;
int i;
@@ -69,7 +71,7 @@ static void __init setup_zero_pages(void)
order = 7;
/* Limit number of empty zero pages for small memory sizes */
- while (order > 2 && (totalram_pages() >> 10) < (1UL << order))
+ while (order > 2 && (total_pages >> 10) < (1UL << order))
order--;
empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
@@ -302,3 +304,32 @@ void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
vmem_remove_mapping(start, size);
}
#endif /* CONFIG_MEMORY_HOTPLUG */
+
+#ifdef CONFIG_EXECMEM
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ unsigned long module_load_offset = 0;
+ unsigned long start;
+
+ if (kaslr_enabled())
+ module_load_offset = get_random_u32_inclusive(1, 1024) * PAGE_SIZE;
+
+ start = MODULES_VADDR + module_load_offset;
+
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .flags = EXECMEM_KASAN_SHADOW,
+ .start = start,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = MODULE_ALIGN,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 632c3a55feed..28a18c42ba99 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -48,7 +48,7 @@ static notrace long s390_kernel_write_odd(void *dst, const void *src, size_t siz
}
/*
- * s390_kernel_write - write to kernel memory bypassing DAT
+ * __s390_kernel_write - write to kernel memory bypassing DAT
* @dst: destination address
* @src: source address
* @size: number of bytes to copy
@@ -61,7 +61,7 @@ static notrace long s390_kernel_write_odd(void *dst, const void *src, size_t siz
*/
static DEFINE_SPINLOCK(s390_kernel_write_lock);
-notrace void *s390_kernel_write(void *dst, const void *src, size_t size)
+notrace void *__s390_kernel_write(void *dst, const void *src, size_t size)
{
void *tmp = dst;
unsigned long flags;
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index b14fc0887654..206756946589 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -86,7 +86,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (len > TASK_SIZE - mmap_min_addr)
return -ENOMEM;
@@ -102,7 +102,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
goto check_asce_limit;
}
- info.flags = 0;
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
@@ -122,7 +121,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/* requested length too big for entire address space */
if (len > TASK_SIZE - mmap_min_addr)
@@ -185,10 +184,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
*/
if (mmap_is_legacy(rlim_stack)) {
mm->mmap_base = mmap_base_legacy(random_factor);
- mm->get_unmapped_area = arch_get_unmapped_area;
+ clear_bit(MMF_TOPDOWN, &mm->flags);
} else {
mm->mmap_base = mmap_base(random_factor, rlim_stack);
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ set_bit(MMF_TOPDOWN, &mm->flags);
}
}
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 01bc8fad64d6..5f805ad42d4c 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -75,7 +75,7 @@ static void pgt_set(unsigned long *old, unsigned long new, unsigned long addr,
break;
}
table = (unsigned long *)((unsigned long)old & mask);
- crdte(*old, new, table, dtt, addr, S390_lowcore.kernel_asce.val);
+ crdte(*old, new, table, dtt, addr, get_lowcore()->kernel_asce.val);
} else if (MACHINE_HAS_IDTE) {
cspg(old, *old, new);
} else {
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
index abb629d7e131..f691e0fb66a2 100644
--- a/arch/s390/mm/pgalloc.c
+++ b/arch/s390/mm/pgalloc.c
@@ -55,6 +55,8 @@ unsigned long *crst_table_alloc(struct mm_struct *mm)
void crst_table_free(struct mm_struct *mm, unsigned long *table)
{
+ if (!table)
+ return;
pagetable_free(virt_to_ptdesc(table));
}
@@ -64,8 +66,8 @@ static void __crst_table_upgrade(void *arg)
/* change all active ASCEs to avoid the creation of new TLBs */
if (current->active_mm == mm) {
- S390_lowcore.user_asce.val = mm->context.asce;
- local_ctl_load(7, &S390_lowcore.user_asce);
+ get_lowcore()->user_asce.val = mm->context.asce;
+ local_ctl_load(7, &get_lowcore()->user_asce);
}
__tlb_flush_local();
}
@@ -262,6 +264,8 @@ static unsigned long *base_crst_alloc(unsigned long val)
static void base_crst_free(unsigned long *table)
{
+ if (!table)
+ return;
pagetable_free(virt_to_ptdesc(table));
}
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 85cddf904cb2..41c714e21292 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -13,7 +13,9 @@
#include <linux/slab.h>
#include <linux/sort.h>
#include <asm/page-states.h>
+#include <asm/abs_lowcore.h>
#include <asm/cacheflush.h>
+#include <asm/maccess.h>
#include <asm/nospec-branch.h>
#include <asm/ctlreg.h>
#include <asm/pgalloc.h>
@@ -21,6 +23,7 @@
#include <asm/tlbflush.h>
#include <asm/sections.h>
#include <asm/set_memory.h>
+#include <asm/physmem_info.h>
static DEFINE_MUTEX(vmem_mutex);
@@ -436,7 +439,7 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add,
if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end)))
return -EINVAL;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
- if (WARN_ON_ONCE(end > VMALLOC_START))
+ if (WARN_ON_ONCE(end > __abs_lowcore))
return -EINVAL;
for (addr = start; addr < end; addr = next) {
next = pgd_addr_end(addr, end);
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 5af0402e94b8..9d440a0b729e 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -31,11 +31,12 @@
#include <asm/nospec-branch.h>
#include <asm/set_memory.h>
#include <asm/text-patching.h>
+#include <asm/unwind.h>
#include "bpf_jit.h"
struct bpf_jit {
u32 seen; /* Flags to remember seen eBPF instructions */
- u32 seen_reg[16]; /* Array to remember which registers are used */
+ u16 seen_regs; /* Mask to remember which registers are used */
u32 *addrs; /* Array with relative instruction addresses */
u8 *prg_buf; /* Start of program */
int size; /* Size of program and literal pool */
@@ -53,6 +54,8 @@ struct bpf_jit {
int excnt; /* Number of exception table entries */
int prologue_plt_ret; /* Return address for prologue hotpatch PLT */
int prologue_plt; /* Start of prologue hotpatch PLT */
+ int kern_arena; /* Pool offset of kernel arena address */
+ u64 user_arena; /* User arena address */
};
#define SEEN_MEM BIT(0) /* use mem[] for temporary storage */
@@ -60,6 +63,8 @@ struct bpf_jit {
#define SEEN_FUNC BIT(2) /* calls C functions */
#define SEEN_STACK (SEEN_FUNC | SEEN_MEM)
+#define NVREGS 0xffc0 /* %r6-%r15 */
+
/*
* s390 registers
*/
@@ -118,8 +123,8 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
{
u32 r1 = reg2hex[b1];
- if (r1 >= 6 && r1 <= 15 && !jit->seen_reg[r1])
- jit->seen_reg[r1] = 1;
+ if (r1 >= 6 && r1 <= 15)
+ jit->seen_regs |= (1 << r1);
}
#define REG_SET_SEEN(b1) \
@@ -127,8 +132,6 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
reg_set_seen(jit, b1); \
})
-#define REG_SEEN(b1) jit->seen_reg[reg2hex[(b1)]]
-
/*
* EMIT macros for code generation
*/
@@ -436,12 +439,12 @@ static void restore_regs(struct bpf_jit *jit, u32 rs, u32 re, u32 stack_depth)
/*
* Return first seen register (from start)
*/
-static int get_start(struct bpf_jit *jit, int start)
+static int get_start(u16 seen_regs, int start)
{
int i;
for (i = start; i <= 15; i++) {
- if (jit->seen_reg[i])
+ if (seen_regs & (1 << i))
return i;
}
return 0;
@@ -450,15 +453,15 @@ static int get_start(struct bpf_jit *jit, int start)
/*
* Return last seen register (from start) (gap >= 2)
*/
-static int get_end(struct bpf_jit *jit, int start)
+static int get_end(u16 seen_regs, int start)
{
int i;
for (i = start; i < 15; i++) {
- if (!jit->seen_reg[i] && !jit->seen_reg[i + 1])
+ if (!(seen_regs & (3 << i)))
return i - 1;
}
- return jit->seen_reg[15] ? 15 : 14;
+ return (seen_regs & (1 << 15)) ? 15 : 14;
}
#define REGS_SAVE 1
@@ -467,8 +470,10 @@ static int get_end(struct bpf_jit *jit, int start)
* Save and restore clobbered registers (6-15) on stack.
* We save/restore registers in chunks with gap >= 2 registers.
*/
-static void save_restore_regs(struct bpf_jit *jit, int op, u32 stack_depth)
+static void save_restore_regs(struct bpf_jit *jit, int op, u32 stack_depth,
+ u16 extra_regs)
{
+ u16 seen_regs = jit->seen_regs | extra_regs;
const int last = 15, save_restore_size = 6;
int re = 6, rs;
@@ -482,10 +487,10 @@ static void save_restore_regs(struct bpf_jit *jit, int op, u32 stack_depth)
}
do {
- rs = get_start(jit, re);
+ rs = get_start(seen_regs, re);
if (!rs)
break;
- re = get_end(jit, rs + 1);
+ re = get_end(seen_regs, rs + 1);
if (op == REGS_SAVE)
save_regs(jit, rs, re);
else
@@ -570,8 +575,21 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp,
}
/* Tail calls have to skip above initialization */
jit->tail_call_start = jit->prg;
- /* Save registers */
- save_restore_regs(jit, REGS_SAVE, stack_depth);
+ if (fp->aux->exception_cb) {
+ /*
+ * Switch stack, the new address is in the 2nd parameter.
+ *
+ * Arrange the restoration of %r6-%r15 in the epilogue.
+ * Do not restore them now, the prog does not need them.
+ */
+ /* lgr %r15,%r3 */
+ EMIT4(0xb9040000, REG_15, REG_3);
+ jit->seen_regs |= NVREGS;
+ } else {
+ /* Save registers */
+ save_restore_regs(jit, REGS_SAVE, stack_depth,
+ fp->aux->exception_boundary ? NVREGS : 0);
+ }
/* Setup literal pool */
if (is_first_pass(jit) || (jit->seen & SEEN_LITERAL)) {
if (!is_first_pass(jit) &&
@@ -647,7 +665,7 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)
/* Load exit code: lgr %r2,%b0 */
EMIT4(0xb9040000, REG_2, BPF_REG_0);
/* Restore registers */
- save_restore_regs(jit, REGS_RESTORE, stack_depth);
+ save_restore_regs(jit, REGS_RESTORE, stack_depth, 0);
if (nospec_uses_trampoline()) {
jit->r14_thunk_ip = jit->prg;
/* Generate __s390_indirect_jump_r14 thunk */
@@ -667,50 +685,111 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)
jit->prg += sizeof(struct bpf_plt);
}
-static int get_probe_mem_regno(const u8 *insn)
-{
- /*
- * insn must point to llgc, llgh, llgf, lg, lgb, lgh or lgf, which have
- * destination register at the same position.
- */
- if (insn[0] != 0xe3) /* common prefix */
- return -1;
- if (insn[5] != 0x90 && /* llgc */
- insn[5] != 0x91 && /* llgh */
- insn[5] != 0x16 && /* llgf */
- insn[5] != 0x04 && /* lg */
- insn[5] != 0x77 && /* lgb */
- insn[5] != 0x15 && /* lgh */
- insn[5] != 0x14) /* lgf */
- return -1;
- return insn[1] >> 4;
-}
-
bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs)
{
regs->psw.addr = extable_fixup(x);
- regs->gprs[x->data] = 0;
+ if (x->data != -1)
+ regs->gprs[x->data] = 0;
return true;
}
-static int bpf_jit_probe_mem(struct bpf_jit *jit, struct bpf_prog *fp,
- int probe_prg, int nop_prg)
+/*
+ * A single BPF probe instruction
+ */
+struct bpf_jit_probe {
+ int prg; /* JITed instruction offset */
+ int nop_prg; /* JITed nop offset */
+ int reg; /* Register to clear on exception */
+ int arena_reg; /* Register to use for arena addressing */
+};
+
+static void bpf_jit_probe_init(struct bpf_jit_probe *probe)
+{
+ probe->prg = -1;
+ probe->nop_prg = -1;
+ probe->reg = -1;
+ probe->arena_reg = REG_0;
+}
+
+/*
+ * Handlers of certain exceptions leave psw.addr pointing to the instruction
+ * directly after the failing one. Therefore, create two exception table
+ * entries and also add a nop in case two probing instructions come directly
+ * after each other.
+ */
+static void bpf_jit_probe_emit_nop(struct bpf_jit *jit,
+ struct bpf_jit_probe *probe)
+{
+ if (probe->prg == -1 || probe->nop_prg != -1)
+ /* The probe is not armed or nop is already emitted. */
+ return;
+
+ probe->nop_prg = jit->prg;
+ /* bcr 0,%0 */
+ _EMIT2(0x0700);
+}
+
+static void bpf_jit_probe_load_pre(struct bpf_jit *jit, struct bpf_insn *insn,
+ struct bpf_jit_probe *probe)
+{
+ if (BPF_MODE(insn->code) != BPF_PROBE_MEM &&
+ BPF_MODE(insn->code) != BPF_PROBE_MEMSX &&
+ BPF_MODE(insn->code) != BPF_PROBE_MEM32)
+ return;
+
+ if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
+ /* lgrl %r1,kern_arena */
+ EMIT6_PCREL_RILB(0xc4080000, REG_W1, jit->kern_arena);
+ probe->arena_reg = REG_W1;
+ }
+ probe->prg = jit->prg;
+ probe->reg = reg2hex[insn->dst_reg];
+}
+
+static void bpf_jit_probe_store_pre(struct bpf_jit *jit, struct bpf_insn *insn,
+ struct bpf_jit_probe *probe)
+{
+ if (BPF_MODE(insn->code) != BPF_PROBE_MEM32)
+ return;
+
+ /* lgrl %r1,kern_arena */
+ EMIT6_PCREL_RILB(0xc4080000, REG_W1, jit->kern_arena);
+ probe->arena_reg = REG_W1;
+ probe->prg = jit->prg;
+}
+
+static void bpf_jit_probe_atomic_pre(struct bpf_jit *jit,
+ struct bpf_insn *insn,
+ struct bpf_jit_probe *probe)
+{
+ if (BPF_MODE(insn->code) != BPF_PROBE_ATOMIC)
+ return;
+
+ /* lgrl %r1,kern_arena */
+ EMIT6_PCREL_RILB(0xc4080000, REG_W1, jit->kern_arena);
+ /* agr %r1,%dst */
+ EMIT4(0xb9080000, REG_W1, insn->dst_reg);
+ probe->arena_reg = REG_W1;
+ probe->prg = jit->prg;
+}
+
+static int bpf_jit_probe_post(struct bpf_jit *jit, struct bpf_prog *fp,
+ struct bpf_jit_probe *probe)
{
struct exception_table_entry *ex;
- int reg, prg;
+ int i, prg;
s64 delta;
u8 *insn;
- int i;
+ if (probe->prg == -1)
+ /* The probe is not armed. */
+ return 0;
+ bpf_jit_probe_emit_nop(jit, probe);
if (!fp->aux->extable)
/* Do nothing during early JIT passes. */
return 0;
- insn = jit->prg_buf + probe_prg;
- reg = get_probe_mem_regno(insn);
- if (WARN_ON_ONCE(reg < 0))
- /* JIT bug - unexpected probe instruction. */
- return -1;
- if (WARN_ON_ONCE(probe_prg + insn_length(*insn) != nop_prg))
+ insn = jit->prg_buf + probe->prg;
+ if (WARN_ON_ONCE(probe->prg + insn_length(*insn) != probe->nop_prg))
/* JIT bug - gap between probe and nop instructions. */
return -1;
for (i = 0; i < 2; i++) {
@@ -719,23 +798,24 @@ static int bpf_jit_probe_mem(struct bpf_jit *jit, struct bpf_prog *fp,
return -1;
ex = &fp->aux->extable[jit->excnt];
/* Add extable entries for probe and nop instructions. */
- prg = i == 0 ? probe_prg : nop_prg;
+ prg = i == 0 ? probe->prg : probe->nop_prg;
delta = jit->prg_buf + prg - (u8 *)&ex->insn;
if (WARN_ON_ONCE(delta < INT_MIN || delta > INT_MAX))
/* JIT bug - code and extable must be close. */
return -1;
ex->insn = delta;
/*
- * Always land on the nop. Note that extable infrastructure
- * ignores fixup field, it is handled by ex_handler_bpf().
+ * Land on the current instruction. Note that the extable
+ * infrastructure ignores the fixup field; it is handled by
+ * ex_handler_bpf().
*/
- delta = jit->prg_buf + nop_prg - (u8 *)&ex->fixup;
+ delta = jit->prg_buf + jit->prg - (u8 *)&ex->fixup;
if (WARN_ON_ONCE(delta < INT_MIN || delta > INT_MAX))
/* JIT bug - landing pad and extable must be close. */
return -1;
ex->fixup = delta;
ex->type = EX_TYPE_BPF;
- ex->data = reg;
+ ex->data = probe->reg;
jit->excnt++;
}
return 0;
@@ -782,19 +862,15 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
s32 branch_oc_off = insn->off;
u32 dst_reg = insn->dst_reg;
u32 src_reg = insn->src_reg;
+ struct bpf_jit_probe probe;
int last, insn_count = 1;
u32 *addrs = jit->addrs;
s32 imm = insn->imm;
s16 off = insn->off;
- int probe_prg = -1;
unsigned int mask;
- int nop_prg;
int err;
- if (BPF_CLASS(insn->code) == BPF_LDX &&
- (BPF_MODE(insn->code) == BPF_PROBE_MEM ||
- BPF_MODE(insn->code) == BPF_PROBE_MEMSX))
- probe_prg = jit->prg;
+ bpf_jit_probe_init(&probe);
switch (insn->code) {
/*
@@ -823,6 +899,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
}
break;
case BPF_ALU64 | BPF_MOV | BPF_X:
+ if (insn_is_cast_user(insn)) {
+ int patch_brc;
+
+ /* ltgr %dst,%src */
+ EMIT4(0xb9020000, dst_reg, src_reg);
+ /* brc 8,0f */
+ patch_brc = jit->prg;
+ EMIT4_PCREL_RIC(0xa7040000, 8, 0);
+ /* iihf %dst,user_arena>>32 */
+ EMIT6_IMM(0xc0080000, dst_reg, jit->user_arena >> 32);
+ /* 0: */
+ if (jit->prg_buf)
+ *(u16 *)(jit->prg_buf + patch_brc + 2) =
+ (jit->prg - patch_brc) >> 1;
+ break;
+ }
switch (insn->off) {
case 0: /* DST = SRC */
/* lgr %dst,%src */
@@ -1366,51 +1458,99 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
* BPF_ST(X)
*/
case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src_reg */
- /* stcy %src,off(%dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0072, src_reg, dst_reg, REG_0, off);
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* stcy %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0072, src_reg, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_STX | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = src */
- /* sthy %src,off(%dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0070, src_reg, dst_reg, REG_0, off);
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* sthy %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0070, src_reg, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_STX | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = src */
- /* sty %src,off(%dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0050, src_reg, dst_reg, REG_0, off);
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_W:
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* sty %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0050, src_reg, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_STX | BPF_MEM | BPF_DW: /* (u64 *)(dst + off) = src */
- /* stg %src,off(%dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0024, src_reg, dst_reg, REG_0, off);
+ case BPF_STX | BPF_PROBE_MEM32 | BPF_DW:
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* stg %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0024, src_reg, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_ST | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = imm */
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_B:
/* lhi %w0,imm */
EMIT4_IMM(0xa7080000, REG_W0, (u8) imm);
- /* stcy %w0,off(dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0072, REG_W0, dst_reg, REG_0, off);
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* stcy %w0,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0072, REG_W0, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_ST | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = imm */
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_H:
/* lhi %w0,imm */
EMIT4_IMM(0xa7080000, REG_W0, (u16) imm);
- /* sthy %w0,off(dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0070, REG_W0, dst_reg, REG_0, off);
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* sthy %w0,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0070, REG_W0, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_ST | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = imm */
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_W:
/* llilf %w0,imm */
EMIT6_IMM(0xc00f0000, REG_W0, (u32) imm);
- /* sty %w0,off(%dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0050, REG_W0, dst_reg, REG_0, off);
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* sty %w0,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0050, REG_W0, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_ST | BPF_MEM | BPF_DW: /* *(u64 *)(dst + off) = imm */
+ case BPF_ST | BPF_PROBE_MEM32 | BPF_DW:
/* lgfi %w0,imm */
EMIT6_IMM(0xc0010000, REG_W0, imm);
- /* stg %w0,off(%dst) */
- EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W0, dst_reg, REG_0, off);
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+ /* stg %w0,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W0, dst_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
/*
@@ -1418,17 +1558,36 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
*/
case BPF_STX | BPF_ATOMIC | BPF_DW:
case BPF_STX | BPF_ATOMIC | BPF_W:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_DW:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_W:
{
bool is32 = BPF_SIZE(insn->code) == BPF_W;
+ /*
+ * Unlike loads and stores, atomics have only a base register,
+ * but no index register. For the non-arena case, simply use
+ * %dst as a base. For the arena case, use the work register
+ * %r1: first, load the arena base into it, and then add %dst
+ * to it.
+ */
+ probe.arena_reg = dst_reg;
+
switch (insn->imm) {
-/* {op32|op64} {%w0|%src},%src,off(%dst) */
#define EMIT_ATOMIC(op32, op64) do { \
+ bpf_jit_probe_atomic_pre(jit, insn, &probe); \
+ /* {op32|op64} {%w0|%src},%src,off(%arena) */ \
EMIT6_DISP_LH(0xeb000000, is32 ? (op32) : (op64), \
(insn->imm & BPF_FETCH) ? src_reg : REG_W0, \
- src_reg, dst_reg, off); \
- if (is32 && (insn->imm & BPF_FETCH)) \
- EMIT_ZERO(src_reg); \
+ src_reg, probe.arena_reg, off); \
+ err = bpf_jit_probe_post(jit, fp, &probe); \
+ if (err < 0) \
+ return err; \
+ if (insn->imm & BPF_FETCH) { \
+ /* bcr 14,0 - see atomic_fetch_{add,and,or,xor}() */ \
+ _EMIT2(0x07e0); \
+ if (is32) \
+ EMIT_ZERO(src_reg); \
+ } \
} while (0)
case BPF_ADD:
case BPF_ADD | BPF_FETCH:
@@ -1451,25 +1610,50 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT_ATOMIC(0x00f7, 0x00e7);
break;
#undef EMIT_ATOMIC
- case BPF_XCHG:
- /* {ly|lg} %w0,off(%dst) */
+ case BPF_XCHG: {
+ struct bpf_jit_probe load_probe = probe;
+ int loop_start;
+
+ bpf_jit_probe_atomic_pre(jit, insn, &load_probe);
+ /* {ly|lg} %w0,off(%arena) */
EMIT6_DISP_LH(0xe3000000,
is32 ? 0x0058 : 0x0004, REG_W0, REG_0,
- dst_reg, off);
- /* 0: {csy|csg} %w0,%src,off(%dst) */
+ load_probe.arena_reg, off);
+ bpf_jit_probe_emit_nop(jit, &load_probe);
+ /* Reuse {ly|lg}'s arena_reg for {csy|csg}. */
+ if (load_probe.prg != -1) {
+ probe.prg = jit->prg;
+ probe.arena_reg = load_probe.arena_reg;
+ }
+ loop_start = jit->prg;
+ /* 0: {csy|csg} %w0,%src,off(%arena) */
EMIT6_DISP_LH(0xeb000000, is32 ? 0x0014 : 0x0030,
- REG_W0, src_reg, dst_reg, off);
+ REG_W0, src_reg, probe.arena_reg, off);
+ bpf_jit_probe_emit_nop(jit, &probe);
/* brc 4,0b */
- EMIT4_PCREL_RIC(0xa7040000, 4, jit->prg - 6);
+ EMIT4_PCREL_RIC(0xa7040000, 4, loop_start);
/* {llgfr|lgr} %src,%w0 */
EMIT4(is32 ? 0xb9160000 : 0xb9040000, src_reg, REG_W0);
+ /* Both probes should land here on exception. */
+ err = bpf_jit_probe_post(jit, fp, &load_probe);
+ if (err < 0)
+ return err;
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
if (is32 && insn_is_zext(&insn[1]))
insn_count = 2;
break;
+ }
case BPF_CMPXCHG:
- /* 0: {csy|csg} %b0,%src,off(%dst) */
+ bpf_jit_probe_atomic_pre(jit, insn, &probe);
+ /* 0: {csy|csg} %b0,%src,off(%arena) */
EMIT6_DISP_LH(0xeb000000, is32 ? 0x0014 : 0x0030,
- BPF_REG_0, src_reg, dst_reg, off);
+ BPF_REG_0, src_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
break;
default:
pr_err("Unknown atomic operation %02x\n", insn->imm);
@@ -1484,51 +1668,87 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
*/
case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
- /* llgc %dst,0(off,%src) */
- EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg, REG_0, off);
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_B:
+ bpf_jit_probe_load_pre(jit, insn, &probe);
+ /* llgc %dst,off(%src,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
if (insn_is_zext(&insn[1]))
insn_count = 2;
break;
case BPF_LDX | BPF_MEMSX | BPF_B: /* dst = *(s8 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
- /* lgb %dst,0(off,%src) */
+ bpf_jit_probe_load_pre(jit, insn, &probe);
+ /* lgb %dst,off(%src) */
EMIT6_DISP_LH(0xe3000000, 0x0077, dst_reg, src_reg, REG_0, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
- /* llgh %dst,0(off,%src) */
- EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg, REG_0, off);
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_H:
+ bpf_jit_probe_load_pre(jit, insn, &probe);
+ /* llgh %dst,off(%src,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
if (insn_is_zext(&insn[1]))
insn_count = 2;
break;
case BPF_LDX | BPF_MEMSX | BPF_H: /* dst = *(s16 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
- /* lgh %dst,0(off,%src) */
+ bpf_jit_probe_load_pre(jit, insn, &probe);
+ /* lgh %dst,off(%src) */
EMIT6_DISP_LH(0xe3000000, 0x0015, dst_reg, src_reg, REG_0, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
jit->seen |= SEEN_MEM;
break;
case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_W:
+ bpf_jit_probe_load_pre(jit, insn, &probe);
/* llgf %dst,off(%src) */
jit->seen |= SEEN_MEM;
- EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg, REG_0, off);
+ EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
if (insn_is_zext(&insn[1]))
insn_count = 2;
break;
case BPF_LDX | BPF_MEMSX | BPF_W: /* dst = *(s32 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
+ bpf_jit_probe_load_pre(jit, insn, &probe);
/* lgf %dst,off(%src) */
jit->seen |= SEEN_MEM;
EMIT6_DISP_LH(0xe3000000, 0x0014, dst_reg, src_reg, REG_0, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
break;
case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
- /* lg %dst,0(off,%src) */
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW:
+ bpf_jit_probe_load_pre(jit, insn, &probe);
+ /* lg %dst,off(%src,%arena) */
jit->seen |= SEEN_MEM;
- EMIT6_DISP_LH(0xe3000000, 0x0004, dst_reg, src_reg, REG_0, off);
+ EMIT6_DISP_LH(0xe3000000, 0x0004, dst_reg, src_reg,
+ probe.arena_reg, off);
+ err = bpf_jit_probe_post(jit, fp, &probe);
+ if (err < 0)
+ return err;
break;
/*
* BPF_JMP / CALL
@@ -1643,7 +1863,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
/*
* Restore registers before calling function
*/
- save_restore_regs(jit, REGS_RESTORE, stack_depth);
+ save_restore_regs(jit, REGS_RESTORE, stack_depth, 0);
/*
* goto *(prog->bpf_func + tail_call_start);
@@ -1893,22 +2113,6 @@ branch_oc:
return -1;
}
- if (probe_prg != -1) {
- /*
- * Handlers of certain exceptions leave psw.addr pointing to
- * the instruction directly after the failing one. Therefore,
- * create two exception table entries and also add a nop in
- * case two probing instructions come directly after each
- * other.
- */
- nop_prg = jit->prg;
- /* bcr 0,%0 */
- _EMIT2(0x0700);
- err = bpf_jit_probe_mem(jit, fp, probe_prg, nop_prg);
- if (err < 0)
- return err;
- }
-
return insn_count;
}
@@ -1954,12 +2158,18 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp,
bool extra_pass, u32 stack_depth)
{
int i, insn_count, lit32_size, lit64_size;
+ u64 kern_arena;
jit->lit32 = jit->lit32_start;
jit->lit64 = jit->lit64_start;
jit->prg = 0;
jit->excnt = 0;
+ kern_arena = bpf_arena_get_kern_vm_start(fp->aux->arena);
+ if (kern_arena)
+ jit->kern_arena = _EMIT_CONST_U64(kern_arena);
+ jit->user_arena = bpf_arena_get_user_vm_start(fp->aux->arena);
+
bpf_jit_prologue(jit, fp, stack_depth);
if (bpf_set_addr(jit, 0) < 0)
return -1;
@@ -2007,9 +2217,25 @@ static struct bpf_binary_header *bpf_jit_alloc(struct bpf_jit *jit,
struct bpf_prog *fp)
{
struct bpf_binary_header *header;
+ struct bpf_insn *insn;
u32 extable_size;
u32 code_size;
+ int i;
+
+ for (i = 0; i < fp->len; i++) {
+ insn = &fp->insnsi[i];
+ if (BPF_CLASS(insn->code) == BPF_STX &&
+ BPF_MODE(insn->code) == BPF_PROBE_ATOMIC &&
+ (BPF_SIZE(insn->code) == BPF_DW ||
+ BPF_SIZE(insn->code) == BPF_W) &&
+ insn->imm == BPF_XCHG)
+ /*
+ * bpf_jit_insn() emits a load and a compare-and-swap,
+ * both of which need to be probed.
+ */
+ fp->aux->num_exentries += 1;
+ }
/* We need two entries per insn. */
fp->aux->num_exentries *= 2;
@@ -2108,7 +2334,11 @@ skip_init_ctx:
print_fn_code(jit.prg_buf, jit.size_prg);
}
if (!fp->is_func || extra_pass) {
- bpf_jit_binary_lock_ro(header);
+ if (bpf_jit_binary_lock_ro(header)) {
+ bpf_jit_binary_free(header);
+ fp = orig_fp;
+ goto free_addrs;
+ }
} else {
jit_data->header = header;
jit_data->ctx = jit;
@@ -2681,3 +2911,52 @@ bool bpf_jit_supports_subprog_tailcalls(void)
{
return true;
}
+
+bool bpf_jit_supports_arena(void)
+{
+ return true;
+}
+
+bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
+{
+ /*
+ * Currently the verifier uses this function only to check which
+ * atomic stores to arena are supported, and they all are.
+ */
+ return true;
+}
+
+bool bpf_jit_supports_exceptions(void)
+{
+ /*
+ * Exceptions require unwinding support, which is always available,
+ * because the kernel is always built with backchain.
+ */
+ return true;
+}
+
+void arch_bpf_stack_walk(bool (*consume_fn)(void *, u64, u64, u64),
+ void *cookie)
+{
+ unsigned long addr, prev_addr = 0;
+ struct unwind_state state;
+
+ unwind_for_each_frame(&state, NULL, NULL, 0) {
+ addr = unwind_get_return_address(&state);
+ if (!addr)
+ break;
+ /*
+ * addr is a return address and state.sp is the value of %r15
+ * at this address. exception_cb needs %r15 at entry to the
+ * function containing addr, so take the next state.sp.
+ *
+ * There is no bp, and the exception_cb prog does not need one
+ * to perform a quasi-longjmp. The common code requires a
+ * non-zero bp, so pass sp there as well.
+ */
+ if (prev_addr && !consume_fn(cookie, prev_addr, state.sp,
+ state.sp))
+ break;
+ prev_addr = addr;
+ }
+}
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 26afde0d1ed3..cff4838fad21 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -250,12 +250,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
return 0;
}
-/* combine single writes by using store-block insn */
-void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
-{
- zpci_memcpy_toio(to, from, count * 8);
-}
-
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
unsigned long prot)
{
@@ -1070,7 +1064,7 @@ char * __init pcibios_setup(char *str)
return NULL;
}
if (!strcmp(str, "nomio")) {
- S390_lowcore.machine_flags &= ~MACHINE_FLAG_PCI_MIO;
+ get_lowcore()->machine_flags &= ~MACHINE_FLAG_PCI_MIO;
return NULL;
}
if (!strcmp(str, "force_floating")) {
diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c
index ff8f24854c64..84482a921332 100644
--- a/arch/s390/pci/pci_irq.c
+++ b/arch/s390/pci/pci_irq.c
@@ -268,33 +268,20 @@ static void zpci_floating_irq_handler(struct airq_struct *airq,
}
}
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+static int __alloc_airq(struct zpci_dev *zdev, int msi_vecs,
+ unsigned long *bit)
{
- struct zpci_dev *zdev = to_zpci(pdev);
- unsigned int hwirq, msi_vecs, cpu;
- unsigned long bit;
- struct msi_desc *msi;
- struct msi_msg msg;
- int cpu_addr;
- int rc, irq;
-
- zdev->aisb = -1UL;
- zdev->msi_first_bit = -1U;
- if (type == PCI_CAP_ID_MSI && nvec > 1)
- return 1;
- msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
-
if (irq_delivery == DIRECTED) {
/* Allocate cpu vector bits */
- bit = airq_iv_alloc(zpci_ibv[0], msi_vecs);
- if (bit == -1UL)
+ *bit = airq_iv_alloc(zpci_ibv[0], msi_vecs);
+ if (*bit == -1UL)
return -EIO;
} else {
/* Allocate adapter summary indicator bit */
- bit = airq_iv_alloc_bit(zpci_sbv);
- if (bit == -1UL)
+ *bit = airq_iv_alloc_bit(zpci_sbv);
+ if (*bit == -1UL)
return -EIO;
- zdev->aisb = bit;
+ zdev->aisb = *bit;
/* Create adapter interrupt vector */
zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK, NULL);
@@ -302,27 +289,66 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return -ENOMEM;
/* Wire up shortcut pointer */
- zpci_ibv[bit] = zdev->aibv;
+ zpci_ibv[*bit] = zdev->aibv;
/* Each function has its own interrupt vector */
- bit = 0;
+ *bit = 0;
}
+ return 0;
+}
- /* Request MSI interrupts */
+int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+ unsigned int hwirq, msi_vecs, irqs_per_msi, i, cpu;
+ struct zpci_dev *zdev = to_zpci(pdev);
+ struct msi_desc *msi;
+ struct msi_msg msg;
+ unsigned long bit;
+ int cpu_addr;
+ int rc, irq;
+
+ zdev->aisb = -1UL;
+ zdev->msi_first_bit = -1U;
+
+ msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
+ if (msi_vecs < nvec) {
+ pr_info("%s requested %d irqs, allocate system limit of %d",
+ pci_name(pdev), nvec, zdev->max_msi);
+ }
+
+ rc = __alloc_airq(zdev, msi_vecs, &bit);
+ if (rc < 0)
+ return rc;
+
+ /*
+ * Request MSI interrupts:
+ * When using MSI, nvec_used interrupt sources and their irq
+ * descriptors are controlled through one msi descriptor.
+ * Thus the outer loop over msi descriptors shall run only once,
+ * while two inner loops iterate over the interrupt vectors.
+ * When using MSI-X, each interrupt vector/irq descriptor
+ * is bound to exactly one msi descriptor (nvec_used is one).
+ * So the inner loops are executed once, while the outer iterates
+ * over the MSI-X descriptors.
+ */
hwirq = bit;
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
- rc = -EIO;
if (hwirq - bit >= msi_vecs)
break;
- irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE,
- (irq_delivery == DIRECTED) ?
- msi->affinity : NULL);
+ irqs_per_msi = min_t(unsigned int, msi_vecs, msi->nvec_used);
+ irq = __irq_alloc_descs(-1, 0, irqs_per_msi, 0, THIS_MODULE,
+ (irq_delivery == DIRECTED) ?
+ msi->affinity : NULL);
if (irq < 0)
return -ENOMEM;
- rc = irq_set_msi_desc(irq, msi);
- if (rc)
- return rc;
- irq_set_chip_and_handler(irq, &zpci_irq_chip,
- handle_percpu_irq);
+
+ for (i = 0; i < irqs_per_msi; i++) {
+ rc = irq_set_msi_desc_off(irq, i, msi);
+ if (rc)
+ return rc;
+ irq_set_chip_and_handler(irq + i, &zpci_irq_chip,
+ handle_percpu_irq);
+ }
+
msg.data = hwirq - bit;
if (irq_delivery == DIRECTED) {
if (msi->affinity)
@@ -335,31 +361,35 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
msg.address_lo |= (cpu_addr << 8);
for_each_possible_cpu(cpu) {
- airq_iv_set_data(zpci_ibv[cpu], hwirq, irq);
+ for (i = 0; i < irqs_per_msi; i++)
+ airq_iv_set_data(zpci_ibv[cpu],
+ hwirq + i, irq + i);
}
} else {
msg.address_lo = zdev->msi_addr & 0xffffffff;
- airq_iv_set_data(zdev->aibv, hwirq, irq);
+ for (i = 0; i < irqs_per_msi; i++)
+ airq_iv_set_data(zdev->aibv, hwirq + i, irq + i);
}
msg.address_hi = zdev->msi_addr >> 32;
pci_write_msi_msg(irq, &msg);
- hwirq++;
+ hwirq += irqs_per_msi;
}
zdev->msi_first_bit = bit;
- zdev->msi_nr_irqs = msi_vecs;
+ zdev->msi_nr_irqs = hwirq - bit;
rc = zpci_set_irq(zdev);
if (rc)
return rc;
- return (msi_vecs == nvec) ? 0 : msi_vecs;
+ return (zdev->msi_nr_irqs == nvec) ? 0 : zdev->msi_nr_irqs;
}
void arch_teardown_msi_irqs(struct pci_dev *pdev)
{
struct zpci_dev *zdev = to_zpci(pdev);
struct msi_desc *msi;
+ unsigned int i;
int rc;
/* Disable interrupts */
@@ -369,8 +399,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
/* Release MSI interrupts */
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_ASSOCIATED) {
- irq_set_msi_desc(msi->irq, NULL);
- irq_free_desc(msi->irq);
+ for (i = 0; i < msi->nvec_used; i++) {
+ irq_set_msi_desc(msi->irq + i, NULL);
+ irq_free_desc(msi->irq + i);
+ }
msi->msg.address_lo = 0;
msi->msg.address_hi = 0;
msi->msg.data = 0;
@@ -410,7 +442,7 @@ static void __init cpu_enable_directed_irq(void *unused)
union zpci_sic_iib iib = {{0}};
union zpci_sic_iib ziib = {{0}};
- iib.cdiib.dibv_addr = (u64) zpci_ibv[smp_processor_id()]->vector;
+ iib.cdiib.dibv_addr = virt_to_phys(zpci_ibv[smp_processor_id()]->vector);
zpci_set_irq_ctrl(SIC_IRQ_MODE_SET_CPU, 0, &iib);
zpci_set_irq_ctrl(SIC_IRQ_MODE_D_SINGLE, PCI_ISC, &ziib);
diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
index a90499c087f0..5398729bfe1b 100644
--- a/arch/s390/pci/pci_mmio.c
+++ b/arch/s390/pci/pci_mmio.c
@@ -169,7 +169,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
if (!(vma->vm_flags & VM_WRITE))
goto out_unlock_mmap;
- ret = follow_pte(vma->vm_mm, mmio_addr, &ptep, &ptl);
+ ret = follow_pte(vma, mmio_addr, &ptep, &ptl);
if (ret)
goto out_unlock_mmap;
@@ -308,7 +308,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
if (!(vma->vm_flags & VM_WRITE))
goto out_unlock_mmap;
- ret = follow_pte(vma->vm_mm, mmio_addr, &ptep, &ptl);
+ ret = follow_pte(vma, mmio_addr, &ptep, &ptl);
if (ret)
goto out_unlock_mmap;
diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c
index a0b872b74fe3..0f4f1e8fc480 100644
--- a/arch/s390/pci/pci_sysfs.c
+++ b/arch/s390/pci/pci_sysfs.c
@@ -172,7 +172,6 @@ static ssize_t uid_is_unique_show(struct device *dev,
}
static DEVICE_ATTR_RO(uid_is_unique);
-#ifndef CONFIG_DMI
/* analogous to smbios index */
static ssize_t index_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -202,7 +201,6 @@ static struct attribute_group zpci_ident_attr_group = {
.attrs = zpci_ident_attrs,
.is_visible = zpci_index_is_visible,
};
-#endif
static struct bin_attribute *zpci_bin_attrs[] = {
&bin_attr_util_string,
@@ -245,8 +243,6 @@ static struct attribute_group pfip_attr_group = {
const struct attribute_group *zpci_attr_groups[] = {
&zpci_attr_group,
&pfip_attr_group,
-#ifndef CONFIG_DMI
&zpci_ident_attr_group,
-#endif
NULL,
};
diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile
index 4e930f566878..24eccaa29337 100644
--- a/arch/s390/purgatory/Makefile
+++ b/arch/s390/purgatory/Makefile
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-OBJECT_FILES_NON_STANDARD := y
-
purgatory-y := head.o purgatory.o string.o sha256.o mem.o
targets += $(purgatory-y) purgatory.lds purgatory purgatory.chk purgatory.ro
@@ -15,12 +13,6 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY
$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE
$(call if_changed_rule,as_o_S)
-KCOV_INSTRUMENT := n
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-
KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
diff --git a/arch/s390/tools/relocs.c b/arch/s390/tools/relocs.c
index 30a732c808f3..a74dbd5c9896 100644
--- a/arch/s390/tools/relocs.c
+++ b/arch/s390/tools/relocs.c
@@ -280,7 +280,7 @@ static int do_reloc(struct section *sec, Elf_Rel *rel)
case R_390_GOTOFF64:
break;
case R_390_64:
- add_reloc(&relocs64, offset);
+ add_reloc(&relocs64, offset - ehdr.e_entry);
break;
default:
die("Unsupported relocation type: %d\n", r_type);
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 2ad3e29f0ebe..1aa3c4a0c5b2 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -3,8 +3,6 @@ config SUPERH
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_CACHE_ALIASING
- select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM && MMU
- select ARCH_ENABLE_MEMORY_HOTREMOVE if SPARSEMEM && MMU
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_CPU_FINALIZE_INIT
@@ -38,7 +36,7 @@ config SUPERH
select HAVE_DEBUG_BUGVERBOSE
select HAVE_DEBUG_KMEMLEAK
select HAVE_DYNAMIC_FTRACE
- select HAVE_FAST_GUP if MMU
+ select HAVE_GUP_FAST if MMU
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
@@ -125,7 +123,8 @@ config ARCH_HAS_ILOG2_U64
config NO_IOPORT_MAP
def_bool !PCI
- depends on !SH_SHMIN && !SH_HP6XX && !SH_SOLUTION_ENGINE
+ depends on !SH_SHMIN && !SH_HP6XX && !SH_SOLUTION_ENGINE && \
+ !SH_DREAMCAST
config IO_TRAPPED
bool
@@ -709,7 +708,6 @@ config ROMIMAGE_MMCIF
choice
prompt "Kernel command line"
- optional
default CMDLINE_OVERWRITE
help
Setting this option allows the kernel command line arguments
@@ -727,6 +725,11 @@ config CMDLINE_EXTEND
Given string will be concatenated with arguments passed in
by a bootloader.
+config CMDLINE_FROM_BOOTLOADER
+ bool "Use bootloader kernel arguments"
+ help
+ Uses the command-line options passed by the boot loader.
+
endchoice
config CMDLINE
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
index f39c8196efdf..bca54e489e11 100644
--- a/arch/sh/boards/board-sh7757lcr.c
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -14,9 +14,9 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/io.h>
-#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/platform_data/sh_mmcif.h>
+#include <linux/platform_data/tmio.h>
#include <linux/sh_eth.h>
#include <linux/sh_intc.h>
#include <linux/usb/renesas_usbhs.h>
@@ -569,7 +569,7 @@ static int __init sh7757lcr_devices_setup(void)
arch_initcall(sh7757lcr_devices_setup);
/* Initialize IRQ setting */
-void __init init_sh7757lcr_IRQ(void)
+static void __init init_sh7757lcr_IRQ(void)
{
plat_irq_setup_pins(IRQ_MODE_IRQ7654);
plat_irq_setup_pins(IRQ_MODE_IRQ3210);
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index 77dad1e511b4..25c4968f0d8b 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -295,7 +295,7 @@ static int __init sh7785lcr_devices_setup(void)
device_initcall(sh7785lcr_devices_setup);
/* Initialize IRQ setting */
-void __init init_sh7785lcr_IRQ(void)
+static void __init init_sh7785lcr_IRQ(void)
{
plat_irq_setup_pins(IRQ_MODE_IRQ7654);
plat_irq_setup_pins(IRQ_MODE_IRQ3210);
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 645cccf3da88..bb5004a8ac02 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -24,10 +24,10 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/sh_flctl.h>
+#include <linux/platform_data/tmio.h>
#include <linux/platform_device.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index 2d966c1c2cc1..daa8455549fa 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -25,10 +25,13 @@
#include <asm/irq.h>
#include <asm/rtc.h>
#include <asm/machvec.h>
+#include <cpu/addrspace.h>
#include <mach/sysasic.h>
static void __init dreamcast_setup(char **cmdline_p)
{
+ /* GAPS PCI bridge assumes P2 area relative addresses. */
+ __set_io_port_base(P2SEG);
}
static struct sh_machine_vector mv_dreamcast __initmv = {
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 30d117f9ad7e..6f13557eecd6 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -17,13 +17,13 @@
#include <linux/input/sh_keysc.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/platform_data/sh_mmcif.h>
#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/platform_data/gpio_backlight.h>
+#include <linux/platform_data/tmio.h>
#include <linux/platform_data/tsc2007.h>
#include <linux/platform_device.h>
#include <linux/regulator/fixed.h>
diff --git a/arch/sh/boards/mach-highlander/pinmux-r7785rp.c b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c
index 703179faf652..689bd8732d9e 100644
--- a/arch/sh/boards/mach-highlander/pinmux-r7785rp.c
+++ b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c
@@ -5,6 +5,7 @@
#include <linux/init.h>
#include <linux/gpio.h>
#include <cpu/sh7785.h>
+#include <mach/highlander.h>
void __init highlander_plat_pinmux_setup(void)
{
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 6b775eae85c0..70236859919d 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -22,10 +22,10 @@
#include <linux/input/sh_keysc.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_data/lv5207lp.h>
+#include <linux/platform_data/tmio.h>
#include <linux/platform_device.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 773ee767d0c4..1853e6319a66 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -7,6 +7,7 @@
#include <linux/clkdev.h>
#include <linux/dma-map-ops.h>
#include <linux/init.h>
+#include <linux/platform_data/tmio.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/input.h>
@@ -14,7 +15,6 @@
#include <linux/memblock.h>
#include <linux/mmc/host.h>
#include <linux/mtd/physmap.h>
-#include <linux/mfd/tmio.h>
#include <linux/mtd/platnand.h>
#include <linux/i2c.h>
#include <linux/regulator/fixed.h>
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 787ddd3c627a..e500feb91053 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -21,9 +21,9 @@
#include <linux/input/sh_keysc.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mtd/physmap.h>
+#include <linux/platform_data/tmio.h>
#include <linux/platform_device.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c
index 7fb474844a2d..bc6cf995128c 100644
--- a/arch/sh/boards/mach-sh03/rtc.c
+++ b/arch/sh/boards/mach-sh03/rtc.c
@@ -120,7 +120,7 @@ static int set_rtc_mmss(struct rtc_time *tm)
return retval;
}
-int sh03_rtc_settimeofday(struct device *dev, struct rtc_time *tm)
+static int sh03_rtc_settimeofday(struct device *dev, struct rtc_time *tm)
{
return set_rtc_mmss(tm);
}
diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index f7f3e618e85b..cc88cb8908cc 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -10,6 +10,8 @@
#include <linux/of_fdt.h>
#include <linux/clocksource.h>
#include <linux/irqchip.h>
+
+#include <asm/clock.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 6c6c791a1d06..8bc319ff54bf 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -5,15 +5,12 @@
# create a compressed vmlinux image from the original vmlinux
#
-OBJECTS := head_32.o misc.o cache.o piggy.o \
+OBJECTS := head_32.o misc.o piggy.o \
ashiftrt.o ashldi3.o ashrsi3.o ashlsi3.o lshrsi3.o
targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo $(OBJECTS)
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
-
#
# IMAGE_OFFSET is the load offset of the compression loader
#
diff --git a/arch/sh/boot/compressed/cache.c b/arch/sh/boot/compressed/cache.c
deleted file mode 100644
index 31e04ff4841e..000000000000
--- a/arch/sh/boot/compressed/cache.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-int cache_control(unsigned int command)
-{
- volatile unsigned int *p = (volatile unsigned int *) 0x80000000;
- int i;
-
- for (i = 0; i < (32 * 1024); i += 32) {
- (void)*p;
- p += (32 / sizeof(int));
- }
-
- return 0;
-}
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
index ca05c99a3d5b..3690379cc86b 100644
--- a/arch/sh/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc.c
@@ -16,6 +16,8 @@
#include <asm/addrspace.h>
#include <asm/page.h>
+#include "misc.h"
+
/*
* gzip declarations
*/
@@ -26,11 +28,6 @@
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
-/* cache.c */
-#define CACHE_ENABLE 0
-#define CACHE_DISABLE 1
-int cache_control(unsigned int command);
-
extern char input_data[];
extern int input_len;
static unsigned char *output;
@@ -139,8 +136,6 @@ void decompress_kernel(void)
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
puts("Uncompressing Linux... ");
- cache_control(CACHE_ENABLE);
__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
- cache_control(CACHE_DISABLE);
puts("Ok, booting the kernel.\n");
}
diff --git a/arch/sh/boot/compressed/misc.h b/arch/sh/boot/compressed/misc.h
new file mode 100644
index 000000000000..2b4534faa305
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef MISC_H
+#define MISC_H
+
+void arch_ftrace_ops_list_func(void);
+void decompress_kernel(void);
+void ftrace_stub(void);
+
+#endif /* MISC_H */
diff --git a/arch/sh/boot/dts/j2_mimas_v2.dts b/arch/sh/boot/dts/j2_mimas_v2.dts
index fa9562f78d53..faf884f53804 100644
--- a/arch/sh/boot/dts/j2_mimas_v2.dts
+++ b/arch/sh/boot/dts/j2_mimas_v2.dts
@@ -71,8 +71,6 @@
#address-cells = <1>;
#size-cells = <0>;
- spi-max-frequency = <25000000>;
-
reg = <0x40 0x8>;
sdcard@0 {
diff --git a/arch/sh/configs/apsh4a3a_defconfig b/arch/sh/configs/apsh4a3a_defconfig
index cc909f347877..9c2644443c4d 100644
--- a/arch/sh/configs/apsh4a3a_defconfig
+++ b/arch/sh/configs/apsh4a3a_defconfig
@@ -15,6 +15,7 @@ CONFIG_MEMORY_START=0x0C000000
CONFIG_FLATMEM_MANUAL=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_SH_APSH4A3A=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_KEXEC=y
CONFIG_PREEMPT=y
diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig
index 64558bf60e10..137573610ec4 100644
--- a/arch/sh/configs/apsh4ad0a_defconfig
+++ b/arch/sh/configs/apsh4ad0a_defconfig
@@ -24,8 +24,6 @@ CONFIG_BFQ_GROUP_IOSCHED=y
CONFIG_CPU_SUBTYPE_SH7786=y
CONFIG_MEMORY_SIZE=0x10000000
CONFIG_HUGETLB_PAGE_SIZE_1MB=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_SH_APSH4AD0A=y
@@ -42,6 +40,7 @@ CONFIG_SECCOMP=y
CONFIG_PREEMPT=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM=y
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
index 9ee35269bee2..296ed768cbbb 100644
--- a/arch/sh/configs/edosk7705_defconfig
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -6,7 +6,7 @@
# CONFIG_PRINTK is not set
# CONFIG_BUG is not set
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
@@ -19,6 +19,7 @@
CONFIG_CPU_SUBTYPE_SH7705=y
CONFIG_SH_EDOSK7705=y
CONFIG_SH_PCLK_FREQ=31250000
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 0c45f2a0f9bd..77e3185f63e4 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -15,6 +15,7 @@ CONFIG_SH_DMA_API=y
CONFIG_HD64461_ENABLER=y
CONFIG_PCCARD=y
CONFIG_PM=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_APM_EMULATION=y
# CONFIG_STANDALONE is not set
CONFIG_BLK_DEV_SD=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index 541082090918..0311380160f4 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -15,6 +15,7 @@ CONFIG_KEXEC=y
CONFIG_PCI=y
CONFIG_PCCARD=y
CONFIG_YENTA=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 52937f9cc2ab..8d443749550e 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -22,6 +22,7 @@ CONFIG_SH_PCLK_FREQ=24000000
CONFIG_SH_DMA=y
CONFIG_SH_DMA_API=y
CONFIG_HEARTBEAT=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/sh/configs/rsk7264_defconfig b/arch/sh/configs/rsk7264_defconfig
index a88cb3b77957..e4ef259425c4 100644
--- a/arch/sh/configs/rsk7264_defconfig
+++ b/arch/sh/configs/rsk7264_defconfig
@@ -21,6 +21,7 @@ CONFIG_MEMORY_START=0x0c000000
CONFIG_FLATMEM_MANUAL=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_SH_RSK=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_SH_TIMER_MTU2 is not set
CONFIG_BINFMT_FLAT=y
CONFIG_NET=y
diff --git a/arch/sh/configs/rsk7269_defconfig b/arch/sh/configs/rsk7269_defconfig
index d9a7ce783c9b..e0d1560b2bfd 100644
--- a/arch/sh/configs/rsk7269_defconfig
+++ b/arch/sh/configs/rsk7269_defconfig
@@ -10,6 +10,7 @@ CONFIG_MEMORY_SIZE=0x02000000
CONFIG_FLATMEM_MANUAL=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_SH_RSK=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_SH_TIMER_MTU2 is not set
CONFIG_SH_PCLK_FREQ=66700000
CONFIG_BINFMT_FLAT=y
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig
index 7b427c17fbfe..07894f13441e 100644
--- a/arch/sh/configs/sdk7786_defconfig
+++ b/arch/sh/configs/sdk7786_defconfig
@@ -43,8 +43,6 @@ CONFIG_MEMORY_SIZE=0x20000000
CONFIG_PMB=y
CONFIG_NUMA=y
CONFIG_HUGETLB_PAGE_SIZE_64MB=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_SPECULATIVE_EXECUTION=y
diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig
index 14d0f5ead502..b5ab945f205e 100644
--- a/arch/sh/configs/se7619_defconfig
+++ b/arch/sh/configs/se7619_defconfig
@@ -4,7 +4,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_KALLSYMS is not set
# CONFIG_HOTPLUG is not set
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_VM_EVENT_COUNTERS is not set
@@ -14,6 +14,7 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_SH_7619_SOLUTION_ENGINE=y
CONFIG_HZ_100=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
# CONFIG_STANDALONE is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 16a0f72f0822..1752ddc2694a 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -13,6 +13,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SH_ADC is not set
CONFIG_SH_SOLUTION_ENGINE=y
CONFIG_HEARTBEAT=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_PREEMPT=y
CONFIG_NET=y
CONFIG_PACKET=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index dc854293da43..20f07aee5bde 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -7,7 +7,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_KALLSYMS_ALL=y
# CONFIG_BUG is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_SHMEM is not set
CONFIG_MODULES=y
# CONFIG_BLK_DEV_BSG is not set
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index c891945b8a90..00862d3c030d 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -7,7 +7,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_KALLSYMS_ALL=y
# CONFIG_BUG is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_SHMEM is not set
CONFIG_MODULES=y
# CONFIG_BLK_DEV_BSG is not set
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index 09e455817447..5327a2f70980 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -17,6 +17,7 @@ CONFIG_SH_7722_SOLUTION_ENGINE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_HEARTBEAT=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_KEXEC=y
CONFIG_PREEMPT=y
CONFIG_NET=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index 5fa6239ae4ea..a1e25d7de8a6 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -15,6 +15,7 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_SH_SOLUTION_ENGINE=y
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_HEARTBEAT=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/sh/configs/secureedge5410_defconfig b/arch/sh/configs/secureedge5410_defconfig
index 120176afe3f6..2f77b60e9540 100644
--- a/arch/sh/configs/secureedge5410_defconfig
+++ b/arch/sh/configs/secureedge5410_defconfig
@@ -10,6 +10,7 @@ CONFIG_SH_SECUREEDGE5410=y
CONFIG_SH_DMA=y
CONFIG_SH_DMA_API=y
CONFIG_PCI=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_NET=y
CONFIG_INET=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index 7f742729df69..99a5d0760532 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -15,6 +15,7 @@ CONFIG_MEMORY_SIZE=0x00800000
CONFIG_FLATMEM_MANUAL=y
# CONFIG_SH_ADC is not set
CONFIG_SH_PCLK_FREQ=32768000
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig
index cbc9389a89a8..5440bd0ca4ed 100644
--- a/arch/sh/configs/sh7724_generic_defconfig
+++ b/arch/sh/configs/sh7724_generic_defconfig
@@ -12,6 +12,7 @@ CONFIG_CPU_FREQ=y
CONFIG_SH_CPU_FREQ=y
CONFIG_KEXEC=y
CONFIG_KEXEC_JUMP=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_HIBERNATION=y
CONFIG_CPU_IDLE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig
index ee2357deba0f..4338af8d02d0 100644
--- a/arch/sh/configs/sh7770_generic_defconfig
+++ b/arch/sh/configs/sh7770_generic_defconfig
@@ -14,6 +14,7 @@ CONFIG_SH_CPU_FREQ=y
CONFIG_KEXEC=y
CONFIG_KEXEC_JUMP=y
CONFIG_PM=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_HIBERNATION=y
CONFIG_CPU_IDLE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
index 59262f42abe6..44f9b2317f09 100644
--- a/arch/sh/configs/sh7785lcr_32bit_defconfig
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -32,6 +32,7 @@ CONFIG_PREEMPT=y
CONFIG_INTC_USERIMASK=y
CONFIG_PCI=y
CONFIG_PCI_DEBUG=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_PM=y
CONFIG_CPU_IDLE=y
CONFIG_NET=y
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index 94381f8268ff..aec74b0e7003 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -17,6 +17,7 @@ CONFIG_HEARTBEAT=y
CONFIG_KEXEC=y
CONFIG_PREEMPT=y
CONFIG_PCI=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index e078b193a78a..bfeb004f130e 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -5,7 +5,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
# CONFIG_BUG is not set
# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
+CONFIG_BASE_SMALL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SHMEM is not set
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index aa353dff7f19..9a0df5ea3866 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -31,8 +31,6 @@ CONFIG_CPU_SUBTYPE_SHX3=y
CONFIG_MEMORY_START=0x0c000000
CONFIG_NUMA=y
CONFIG_PAGE_SIZE_64KB=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_SH_X3PROTO=y
CONFIG_NO_HZ=y
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig
index 445bb451a5ec..00ef62133b04 100644
--- a/arch/sh/configs/urquell_defconfig
+++ b/arch/sh/configs/urquell_defconfig
@@ -34,6 +34,7 @@ CONFIG_PCIEPORTBUS=y
CONFIG_PCIEASPM_DEBUG=y
CONFIG_PCI_DEBUG=y
CONFIG_BINFMT_MISC=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_PM=y
CONFIG_CPU_IDLE=y
CONFIG_NET=y
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index 89cd4a3b4cca..87e5a8928873 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -41,21 +41,6 @@ struct dma_info *get_dma_info(unsigned int chan)
}
EXPORT_SYMBOL(get_dma_info);
-struct dma_info *get_dma_info_by_name(const char *dmac_name)
-{
- struct dma_info *info;
-
- list_for_each_entry(info, &registered_dmac_list, list) {
- if (dmac_name && (strcmp(dmac_name, info->name) != 0))
- continue;
- else
- return info;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(get_dma_info_by_name);
-
static unsigned int get_nr_channels(void)
{
struct dma_info *info;
@@ -101,93 +86,6 @@ int get_dma_residue(unsigned int chan)
}
EXPORT_SYMBOL(get_dma_residue);
-static int search_cap(const char **haystack, const char *needle)
-{
- const char **p;
-
- for (p = haystack; *p; p++)
- if (strcmp(*p, needle) == 0)
- return 1;
-
- return 0;
-}
-
-/**
- * request_dma_bycap - Allocate a DMA channel based on its capabilities
- * @dmac: List of DMA controllers to search
- * @caps: List of capabilities
- *
- * Search all channels of all DMA controllers to find a channel which
- * matches the requested capabilities. The result is the channel
- * number if a match is found, or %-ENODEV if no match is found.
- *
- * Note that not all DMA controllers export capabilities, in which
- * case they can never be allocated using this API, and so
- * request_dma() must be used specifying the channel number.
- */
-int request_dma_bycap(const char **dmac, const char **caps, const char *dev_id)
-{
- unsigned int found = 0;
- struct dma_info *info;
- const char **p;
- int i;
-
- BUG_ON(!dmac || !caps);
-
- list_for_each_entry(info, &registered_dmac_list, list)
- if (strcmp(*dmac, info->name) == 0) {
- found = 1;
- break;
- }
-
- if (!found)
- return -ENODEV;
-
- for (i = 0; i < info->nr_channels; i++) {
- struct dma_channel *channel = &info->channels[i];
-
- if (unlikely(!channel->caps))
- continue;
-
- for (p = caps; *p; p++) {
- if (!search_cap(channel->caps, *p))
- break;
- if (request_dma(channel->chan, dev_id) == 0)
- return channel->chan;
- }
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL(request_dma_bycap);
-
-int dmac_search_free_channel(const char *dev_id)
-{
- struct dma_channel *channel = { 0 };
- struct dma_info *info = get_dma_info(0);
- int i;
-
- for (i = 0; i < info->nr_channels; i++) {
- channel = &info->channels[i];
- if (unlikely(!channel))
- return -ENODEV;
-
- if (atomic_read(&channel->busy) == 0)
- break;
- }
-
- if (info->ops->request) {
- int result = info->ops->request(channel);
- if (result)
- return result;
-
- atomic_set(&channel->busy, 1);
- return channel->chan;
- }
-
- return -ENOSYS;
-}
-
int request_dma(unsigned int chan, const char *dev_id)
{
struct dma_channel *channel = { 0 };
@@ -240,35 +138,6 @@ void dma_wait_for_completion(unsigned int chan)
}
EXPORT_SYMBOL(dma_wait_for_completion);
-int register_chan_caps(const char *dmac, struct dma_chan_caps *caps)
-{
- struct dma_info *info;
- unsigned int found = 0;
- int i;
-
- list_for_each_entry(info, &registered_dmac_list, list)
- if (strcmp(dmac, info->name) == 0) {
- found = 1;
- break;
- }
-
- if (unlikely(!found))
- return -ENODEV;
-
- for (i = 0; i < info->nr_channels; i++, caps++) {
- struct dma_channel *channel;
-
- if ((info->first_channel_nr + i) != caps->ch_num)
- return -EINVAL;
-
- channel = &info->channels[i];
- channel->caps = caps->caplist;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(register_chan_caps);
-
void dma_configure_channel(unsigned int chan, unsigned long flags)
{
struct dma_info *info = get_dma_info(chan);
@@ -294,18 +163,6 @@ int dma_xfer(unsigned int chan, unsigned long from,
}
EXPORT_SYMBOL(dma_xfer);
-int dma_extend(unsigned int chan, unsigned long op, void *param)
-{
- struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
-
- if (info->ops->extend)
- return info->ops->extend(channel, op, param);
-
- return -ENOSYS;
-}
-EXPORT_SYMBOL(dma_extend);
-
static int dma_proc_show(struct seq_file *m, void *v)
{
struct dma_info *info = v;
diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c
index 6ecba5f521eb..1dea43381b5a 100644
--- a/arch/sh/drivers/push-switch.c
+++ b/arch/sh/drivers/push-switch.c
@@ -91,7 +91,7 @@ err:
return ret;
}
-static int switch_drv_remove(struct platform_device *pdev)
+static void switch_drv_remove(struct platform_device *pdev)
{
struct push_switch *psw = platform_get_drvdata(pdev);
struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
@@ -106,13 +106,11 @@ static int switch_drv_remove(struct platform_device *pdev)
free_irq(irq, pdev);
kfree(psw);
-
- return 0;
}
static struct platform_driver switch_driver = {
.probe = switch_drv_probe,
- .remove = switch_drv_remove,
+ .remove_new = switch_drv_remove,
.driver = {
.name = DRV_NAME,
},
@@ -133,4 +131,5 @@ module_exit(switch_exit);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("Paul Mundt");
+MODULE_DESCRIPTION("Generic push-switch framework");
MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 51112f54552b..e6642ff14889 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -104,6 +104,18 @@ void kunmap_coherent(void *kvaddr);
void cpu_cache_init(void);
+void __weak l2_cache_init(void);
+
+void __weak j2_cache_init(void);
+void __weak sh2_cache_init(void);
+void __weak sh2a_cache_init(void);
+void __weak sh3_cache_init(void);
+void __weak shx3_cache_init(void);
+void __weak sh4_cache_init(void);
+void __weak sh7705_cache_init(void);
+
+void __weak sh4__flush_region_init(void);
+
static inline void *sh_cacheop_vaddr(void *vaddr)
{
if (__in_29bit_mode())
diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
index c8bee3f985a2..6b6d409956d1 100644
--- a/arch/sh/include/asm/dma.h
+++ b/arch/sh/include/asm/dma.h
@@ -56,7 +56,6 @@ struct dma_ops {
int (*get_residue)(struct dma_channel *chan);
int (*xfer)(struct dma_channel *chan);
int (*configure)(struct dma_channel *chan, unsigned long flags);
- int (*extend)(struct dma_channel *chan, unsigned long op, void *param);
};
struct dma_channel {
@@ -118,8 +117,6 @@ extern int dma_xfer(unsigned int chan, unsigned long from,
#define dma_read_page(chan, from, to) \
dma_read(chan, from, to, PAGE_SIZE)
-extern int request_dma_bycap(const char **dmac, const char **caps,
- const char *dev_id);
extern int get_dma_residue(unsigned int chan);
extern struct dma_info *get_dma_info(unsigned int chan);
extern struct dma_channel *get_dma_channel(unsigned int chan);
@@ -128,10 +125,6 @@ extern void dma_configure_channel(unsigned int chan, unsigned long flags);
extern int register_dmac(struct dma_info *info);
extern void unregister_dmac(struct dma_info *info);
-extern struct dma_info *get_dma_info_by_name(const char *dmac_name);
-
-extern int dma_extend(unsigned int chan, unsigned long op, void *param);
-extern int register_chan_caps(const char *dmac, struct dma_chan_caps *capslist);
/* arch/sh/drivers/dma/dma-sysfs.c */
extern int dma_create_sysfs_files(struct dma_channel *, struct dma_info *);
diff --git a/arch/sh/include/asm/fb.h b/arch/sh/include/asm/fb.h
deleted file mode 100644
index 19df13ee9ca7..000000000000
--- a/arch/sh/include/asm/fb.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h
index 04584be8986c..0379f4cce5ed 100644
--- a/arch/sh/include/asm/fpu.h
+++ b/arch/sh/include/asm/fpu.h
@@ -64,6 +64,9 @@ static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
preempt_enable();
}
+void float_raise(unsigned int flags);
+int float_rounding_mode(void);
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_FPU_H */
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index b1c1dc0cc261..1c10e1066390 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -33,6 +33,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
return addr;
}
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr);
+
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_FUNCTION_TRACER */
@@ -43,6 +45,14 @@ extern void *return_address(unsigned int);
#define ftrace_return_address(n) return_address(n)
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void arch_ftrace_nmi_enter(void);
+extern void arch_ftrace_nmi_exit(void);
+#else
+static inline void arch_ftrace_nmi_enter(void) { }
+static inline void arch_ftrace_nmi_exit(void) { }
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_FTRACE_H */
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
index 4d3ba39e681c..75028bd568ba 100644
--- a/arch/sh/include/asm/hugetlb.h
+++ b/arch/sh/include/asm/hugetlb.h
@@ -27,11 +27,11 @@ static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
return *ptep;
}
-static inline void arch_clear_hugepage_flags(struct page *page)
+static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
- clear_bit(PG_dcache_clean, &page->flags);
+ clear_bit(PG_dcache_clean, &folio->flags);
}
-#define arch_clear_hugepage_flags arch_clear_hugepage_flags
+#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
#include <asm-generic/hugetlb.h>
diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h
index 361a0f57bdeb..74a438cea655 100644
--- a/arch/sh/include/asm/hw_breakpoint.h
+++ b/arch/sh/include/asm/hw_breakpoint.h
@@ -52,6 +52,8 @@ struct pmu;
/* arch/sh/kernel/hw_breakpoint.c */
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
+extern int arch_bp_generic_fields(int sh_len, int sh_type, int *gen_len,
+ int *gen_type);
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
const struct perf_event_attr *attr,
struct arch_hw_breakpoint *hw);
diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h
index fc807011187f..84bb23a771f3 100644
--- a/arch/sh/include/asm/setup.h
+++ b/arch/sh/include/asm/setup.h
@@ -21,5 +21,6 @@
void sh_mv_setup(void);
void check_for_initrd(void);
void per_cpu_trap_init(void);
+void sh_fdt_init(phys_addr_t dt_phys);
#endif /* _SH_SETUP_H */
diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h
index 387105316d28..39240e06e8aa 100644
--- a/arch/sh/include/asm/syscalls.h
+++ b/arch/sh/include/asm/syscalls.h
@@ -8,6 +8,7 @@ asmlinkage int old_mmap(unsigned long addr, unsigned long len,
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
+asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op);
#include <asm/syscalls_32.h>
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index aeb8915e9254..ddf324bfb9a0 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -24,6 +24,10 @@ static inline void tlb_unwire_entry(void)
BUG();
}
#endif /* CONFIG_CPU_SH4 */
+
+asmlinkage int handle_tlbmiss(struct pt_regs *regs, unsigned long error_code,
+ unsigned long address);
+
#endif /* CONFIG_MMU */
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_TLB_H */
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h
index d6e126250136..3d7f35650a13 100644
--- a/arch/sh/include/asm/unistd.h
+++ b/arch/sh/include/asm/unistd.h
@@ -28,4 +28,6 @@
# define __ARCH_WANT_SYS_VFORK
# define __ARCH_WANT_SYS_CLONE
+#define __ARCH_BROKEN_SYS_CLONE3
+
#include <uapi/asm/unistd.h>
diff --git a/arch/sh/kernel/cpu/sh2a/opcode_helper.c b/arch/sh/kernel/cpu/sh2a/opcode_helper.c
index c509081d90b9..fcf53f5827eb 100644
--- a/arch/sh/kernel/cpu/sh2a/opcode_helper.c
+++ b/arch/sh/kernel/cpu/sh2a/opcode_helper.c
@@ -8,6 +8,8 @@
*/
#include <linux/kernel.h>
+#include <asm/processor.h>
+
/*
* Instructions on SH are generally fixed at 16-bits, however, SH-2A
* introduces some 32-bit instructions. Since there are no real
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 83ae1ad4a86e..d64d28c4f059 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -14,9 +14,12 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/io.h>
+
+#include <asm/cacheflush.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
+
#include <cpu/sh7723.h>
/* Serial */
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 0d990ab1ba2a..ef4b26a4b3d6 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/notifier.h>
+#include <asm/cacheflush.h>
#include <asm/suspend.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 67e330b7ea46..2ad19a0c5e04 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -17,8 +17,11 @@
#include <linux/sh_dma.h>
#include <linux/sh_intc.h>
#include <linux/usb/ohci_pdriver.h>
+
#include <cpu/dma-register.h>
#include <cpu/sh7757.h>
+
+#include <asm/mmzone.h>
#include <asm/platform_early.h>
static struct plat_sci_port scif2_platform_data = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 74620f30b19b..c048842d8a58 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -400,20 +400,6 @@ static struct platform_device *sh7786_devices[] __initdata = {
&usb_ohci_device,
};
-/*
- * Please call this function if your platform board
- * use external clock for USB
- * */
-#define USBCTL0 0xffe70858
-#define CLOCK_MODE_MASK 0xffffff7f
-#define EXT_CLOCK_MODE 0x00000080
-
-void __init sh7786_usb_use_exclock(void)
-{
- u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK;
- __raw_writel(val | EXT_CLOCK_MODE, USBCTL0);
-}
-
#define USBINITREG1 0xffe70094
#define USBINITREG2 0xffe7009c
#define USBINITVAL1 0x00ff0040
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index bf8682e71830..45c8ae20d109 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -344,7 +344,7 @@ out:
* dwarf_lookup_fde - locate the FDE that covers pc
* @pc: the program counter
*/
-struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
+static struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
{
struct rb_node **rb_node = &fde_root.rb_node;
struct dwarf_fde *fde = NULL;
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index aed1ea8e2c2f..49c4ffd782d6 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -39,22 +39,17 @@ static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2);
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
- kprobe_opcode_t opcode = *(kprobe_opcode_t *) (p->addr);
+ kprobe_opcode_t opcode = *p->addr;
if (OPCODE_RTE(opcode))
return -EFAULT; /* Bad breakpoint */
+ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
p->opcode = opcode;
return 0;
}
-void __kprobes arch_copy_kprobe(struct kprobe *p)
-{
- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
- p->opcode = *p->addr;
-}
-
void __kprobes arch_arm_kprobe(struct kprobe *p)
{
*p->addr = BREAKPOINT_INSTRUCTION;
@@ -253,7 +248,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
p = get_kprobe(addr);
if (!p) {
/* Not one of ours: let kernel handle it */
- if (*(kprobe_opcode_t *)addr != BREAKPOINT_INSTRUCTION) {
+ if (*addr != BREAKPOINT_INSTRUCTION) {
/*
* The breakpoint instruction was removed right
* after we hit it. Another cpu has removed
@@ -301,7 +296,7 @@ static void __used kretprobe_trampoline_holder(void)
/*
* Called when we hit the probe point at __kretprobe_trampoline
*/
-int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
regs->pc = __kretprobe_trampoline_handler(regs, NULL);
diff --git a/arch/sh/kernel/return_address.c b/arch/sh/kernel/return_address.c
index 8838094c9ff9..2ce22f11eab3 100644
--- a/arch/sh/kernel/return_address.c
+++ b/arch/sh/kernel/return_address.c
@@ -7,7 +7,9 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
+
#include <asm/dwarf.h>
+#include <asm/ftrace.h>
#ifdef CONFIG_DWARF_UNWINDER
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 5cf35a774dc7..108d808767fa 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -21,6 +21,8 @@
#include <linux/sched/hotplug.h>
#include <linux/atomic.h>
#include <linux/clockchips.h>
+#include <linux/profile.h>
+
#include <asm/processor.h>
#include <asm/mmu_context.h>
#include <asm/smp.h>
@@ -170,7 +172,7 @@ void native_play_dead(void)
}
#endif
-asmlinkage void start_secondary(void)
+static asmlinkage void start_secondary(void)
{
unsigned int cpu = smp_processor_id();
struct mm_struct *mm = &init_mm;
@@ -320,11 +322,13 @@ void smp_message_recv(unsigned int msg)
}
}
+#ifdef CONFIG_PROFILING
/* Not really SMP stuff ... */
int setup_profiling_timer(unsigned int multiplier)
{
return 0;
}
+#endif
#ifdef CONFIG_MMU
diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c
index 9dca568509a5..d6f4afcb0e87 100644
--- a/arch/sh/kernel/sys_sh32.c
+++ b/arch/sh/kernel/sys_sh32.c
@@ -59,3 +59,14 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
(u64)len0 << 32 | len1, advice);
#endif
}
+
+/*
+ * swap the arguments the way that libc wants them instead of
+ * moving flags ahead of the 64-bit nbytes argument
+ */
+SYSCALL_DEFINE6(sh_sync_file_range6, int, fd, SC_ARG64(offset),
+ SC_ARG64(nbytes), unsigned int, flags)
+{
+ return ksys_sync_file_range(fd, SC_VAL64(loff_t, offset),
+ SC_VAL64(loff_t, nbytes), flags);
+}
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index 86fe269f0220..c55fd7696d40 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -321,7 +321,7 @@
311 common set_robust_list sys_set_robust_list
312 common get_robust_list sys_get_robust_list
313 common splice sys_splice
-314 common sync_file_range sys_sync_file_range
+314 common sync_file_range sys_sh_sync_file_range6
315 common tee sys_tee
316 common vmsplice sys_vmsplice
317 common move_pages sys_move_pages
@@ -395,6 +395,7 @@
385 common pkey_alloc sys_pkey_alloc
386 common pkey_free sys_pkey_free
387 common rseq sys_rseq
+388 common sync_file_range2 sys_sync_file_range2
# room for arch specific syscalls
393 common semget sys_semget
394 common semctl sys_semctl
@@ -464,3 +465,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 01884054aeb2..4339c4cafa79 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -15,6 +15,8 @@
#include <linux/extable.h>
#include <linux/module.h> /* print_modules */
+
+#include <asm/ftrace.h>
#include <asm/unwinder.h>
#include <asm/traps.h>
@@ -170,14 +172,6 @@ BUILD_TRAP_HANDLER(bug)
force_sig(SIGTRAP);
}
-#ifdef CONFIG_DYNAMIC_FTRACE
-extern void arch_ftrace_nmi_enter(void);
-extern void arch_ftrace_nmi_exit(void);
-#else
-static inline void arch_ftrace_nmi_enter(void) { }
-static inline void arch_ftrace_nmi_exit(void) { }
-#endif
-
BUILD_TRAP_HANDLER(nmi)
{
TRAP_HANDLER_DECL;
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 6cdda3a621a1..1271b839a107 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -27,6 +27,7 @@
#include <asm/alignment.h>
#include <asm/fpu.h>
#include <asm/kprobes.h>
+#include <asm/setup.h>
#include <asm/traps.h>
#include <asm/bl_bit.h>
@@ -568,7 +569,7 @@ uspace_segv:
/*
* SH-DSP support gerg@snapgear.com.
*/
-int is_dsp_inst(struct pt_regs *regs)
+static int is_dsp_inst(struct pt_regs *regs)
{
unsigned short inst = 0;
@@ -590,7 +591,7 @@ int is_dsp_inst(struct pt_regs *regs)
return 0;
}
#else
-#define is_dsp_inst(regs) (0)
+static inline int is_dsp_inst(struct pt_regs *regs) { return 0; }
#endif /* CONFIG_SH_DSP */
#ifdef CONFIG_CPU_SH2A
diff --git a/arch/sh/kernel/vsyscall/Makefile b/arch/sh/kernel/vsyscall/Makefile
index 118744d349e2..cb4f0bb80c38 100644
--- a/arch/sh/kernel/vsyscall/Makefile
+++ b/arch/sh/kernel/vsyscall/Makefile
@@ -19,14 +19,14 @@ vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 -Wl,--hash-style=sysv
SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags)
$(obj)/vsyscall-trapa.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
+$(obj)/vsyscall-%.so: $(obj)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
$(call if_changed,syscall)
# We also create a special relocatable object that should mirror the symbol
# table and layout of the linked DSO. With ld -R we can then refer to
# these symbols in the kernel code rather than hand-coded addresses.
SYSCFLAGS_vsyscall-dummy.o = -r
-$(obj)/vsyscall-dummy.o: $(src)/vsyscall.lds \
+$(obj)/vsyscall-dummy.o: $(obj)/vsyscall.lds \
$(obj)/vsyscall-trapa.o $(obj)/vsyscall-note.o FORCE
$(call if_changed,syscall)
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index 3e07074e0098..06fed5a21e8b 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -33,7 +33,8 @@
*/
/*
- * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum);
+ * unsigned int csum_partial(const unsigned char *buf, int len,
+ * unsigned int sum);
*/
.text
@@ -45,31 +46,11 @@ ENTRY(csum_partial)
* Fortunately, it is easy to convert 2-byte alignment to 4-byte
* alignment for the unrolled loop.
*/
+ mov r5, r1
mov r4, r0
- tst #3, r0 ! Check alignment.
- bt/s 2f ! Jump if alignment is ok.
- mov r4, r7 ! Keep a copy to check for alignment
+ tst #2, r0 ! Check alignment.
+ bt 2f ! Jump if alignment is ok.
!
- tst #1, r0 ! Check alignment.
- bt 21f ! Jump if alignment is boundary of 2bytes.
-
- ! buf is odd
- tst r5, r5
- add #-1, r5
- bt 9f
- mov.b @r4+, r0
- extu.b r0, r0
- addc r0, r6 ! t=0 from previous tst
- mov r6, r0
- shll8 r6
- shlr16 r0
- shlr8 r0
- or r0, r6
- mov r4, r0
- tst #2, r0
- bt 2f
-21:
- ! buf is 2 byte aligned (len could be 0)
add #-2, r5 ! Alignment uses up two bytes.
cmp/pz r5 !
bt/s 1f ! Jump if we had at least two bytes.
@@ -77,17 +58,16 @@ ENTRY(csum_partial)
bra 6f
add #2, r5 ! r5 was < 2. Deal with it.
1:
+ mov r5, r1 ! Save new len for later use.
mov.w @r4+, r0
extu.w r0, r0
addc r0, r6
bf 2f
add #1, r6
2:
- ! buf is 4 byte aligned (len could be 0)
- mov r5, r1
mov #-5, r0
- shld r0, r1
- tst r1, r1
+ shld r0, r5
+ tst r5, r5
bt/s 4f ! if it's =0, go to 4f
clrt
.align 2
@@ -109,31 +89,30 @@ ENTRY(csum_partial)
addc r0, r6
addc r2, r6
movt r0
- dt r1
+ dt r5
bf/s 3b
cmp/eq #1, r0
- ! here, we know r1==0
- addc r1, r6 ! add carry to r6
+ ! here, we know r5==0
+ addc r5, r6 ! add carry to r6
4:
- mov r5, r0
+ mov r1, r0
and #0x1c, r0
tst r0, r0
- bt 6f
- ! 4 bytes or more remaining
- mov r0, r1
- shlr2 r1
+ bt/s 6f
+ mov r0, r5
+ shlr2 r5
mov #0, r2
5:
addc r2, r6
mov.l @r4+, r2
movt r0
- dt r1
+ dt r5
bf/s 5b
cmp/eq #1, r0
addc r2, r6
- addc r1, r6 ! r1==0 here, so it means add carry-bit
+ addc r5, r6 ! r5==0 here, so it means add carry-bit
6:
- ! 3 bytes or less remaining
+ mov r1, r5
mov #3, r0
and r0, r5
tst r5, r5
@@ -159,16 +138,6 @@ ENTRY(csum_partial)
mov #0, r0
addc r0, r6
9:
- ! Check if the buffer was misaligned, if so realign sum
- mov r7, r0
- tst #1, r0
- bt 10f
- mov r6, r0
- shll8 r6
- shlr16 r0
- shlr8 r0
- or r0, r6
-10:
rts
mov r6, r0
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index cdaef6501d76..b65703e06573 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -15,6 +15,8 @@
#include <linux/perf_event.h>
#include <linux/uaccess.h>
+
+#include <asm/fpu.h>
#include <asm/processor.h>
#include <asm/io.h>
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index f32a1963ff0c..1862411665ab 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -144,10 +144,6 @@ config ARCH_SPARSEMEM_DEFAULT
config ARCH_SELECT_MEMORY_MODEL
def_bool y
-config ARCH_MEMORY_PROBE
- def_bool y
- depends on MEMORY_HOTPLUG
-
config IOREMAP_FIXED
def_bool y
depends on X2TLB
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 862046f26981..46393b00137e 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -241,13 +241,14 @@ static void sh4_flush_cache_page(void *args)
if ((vma->vm_mm == current->active_mm))
vaddr = NULL;
else {
+ struct folio *folio = page_folio(page);
/*
* Use kmap_coherent or kmap_atomic to do flushes for
* another ASID than the current one.
*/
map_coherent = (current_cpu_data.dcache.n_aliases &&
- test_bit(PG_dcache_clean, &page->flags) &&
- page_mapcount(page));
+ test_bit(PG_dcache_clean, folio_flags(folio, 0)) &&
+ page_mapped(page));
if (map_coherent)
vaddr = kmap_coherent(page, address);
else
@@ -376,8 +377,6 @@ static void __flush_cache_one(unsigned long addr, unsigned long phys,
} while (--way_count != 0);
}
-extern void __weak sh4__flush_region_init(void);
-
/*
* SH-4 has virtually indexed and physically tagged cache.
*/
diff --git a/arch/sh/mm/cache-shx3.c b/arch/sh/mm/cache-shx3.c
index 24c58b7dc022..dec039a75664 100644
--- a/arch/sh/mm/cache-shx3.c
+++ b/arch/sh/mm/cache-shx3.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/cache.h>
+#include <asm/cacheflush.h>
#define CCR_CACHE_SNM 0x40000 /* Hardware-assisted synonym avoidance */
#define CCR_CACHE_IBE 0x1000000 /* ICBI broadcast */
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 9bcaa5619eab..6ebdeaff3021 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -84,7 +84,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
{
struct folio *folio = page_folio(page);
- if (boot_cpu_data.dcache.n_aliases && page_mapcount(page) &&
+ if (boot_cpu_data.dcache.n_aliases && folio_mapped(folio) &&
test_bit(PG_dcache_clean, &folio->flags)) {
void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
@@ -320,30 +320,20 @@ void __init cpu_cache_init(void)
goto skip;
if (boot_cpu_data.type == CPU_J2) {
- extern void __weak j2_cache_init(void);
-
j2_cache_init();
} else if (boot_cpu_data.family == CPU_FAMILY_SH2) {
- extern void __weak sh2_cache_init(void);
-
sh2_cache_init();
}
if (boot_cpu_data.family == CPU_FAMILY_SH2A) {
- extern void __weak sh2a_cache_init(void);
-
sh2a_cache_init();
}
if (boot_cpu_data.family == CPU_FAMILY_SH3) {
- extern void __weak sh3_cache_init(void);
-
sh3_cache_init();
if ((boot_cpu_data.type == CPU_SH7705) &&
(boot_cpu_data.dcache.sets == 512)) {
- extern void __weak sh7705_cache_init(void);
-
sh7705_cache_init();
}
}
@@ -351,14 +341,10 @@ void __init cpu_cache_init(void)
if ((boot_cpu_data.family == CPU_FAMILY_SH4) ||
(boot_cpu_data.family == CPU_FAMILY_SH4A) ||
(boot_cpu_data.family == CPU_FAMILY_SH4AL_DSP)) {
- extern void __weak sh4_cache_init(void);
-
sh4_cache_init();
if ((boot_cpu_data.type == CPU_SH7786) ||
(boot_cpu_data.type == CPU_SHX3)) {
- extern void __weak shx3_cache_init(void);
-
shx3_cache_init();
}
}
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 6cb0ad73dbb9..ff209b55285a 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -70,13 +70,3 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
return pte;
}
-
-int pmd_huge(pmd_t pmd)
-{
- return 0;
-}
-
-int pud_huge(pud_t pud)
-{
- return 0;
-}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index bf1b54055316..d1fe90b2f5ff 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -395,31 +395,3 @@ void __init mem_init(void)
mem_init_done = 1;
}
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size,
- struct mhp_params *params)
-{
- unsigned long start_pfn = PFN_DOWN(start);
- unsigned long nr_pages = size >> PAGE_SHIFT;
- int ret;
-
- if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot))
- return -EINVAL;
-
- /* We only have ZONE_NORMAL, so this is easy.. */
- ret = __add_pages(nid, start_pfn, nr_pages, params);
- if (unlikely(ret))
- printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
-
- return ret;
-}
-
-void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
-{
- unsigned long start_pfn = PFN_DOWN(start);
- unsigned long nr_pages = size >> PAGE_SHIFT;
-
- __remove_pages(start_pfn, nr_pages, altmap);
-}
-#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index b82199878b45..bee329d4149a 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
int do_colour_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -88,7 +88,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- info.flags = 0;
info.length = len;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = TASK_SIZE;
@@ -106,7 +105,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
int do_colour_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c
index 78c4b6e6d33b..fa3dc9428a73 100644
--- a/arch/sh/mm/nommu.c
+++ b/arch/sh/mm/nommu.c
@@ -10,6 +10,8 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/mm.h>
+
+#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
#include <linux/uaccess.h>
diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c
index cf7ce4b57359..3a4085ea0161 100644
--- a/arch/sh/mm/pgtable.c
+++ b/arch/sh/mm/pgtable.c
@@ -2,12 +2,14 @@
#include <linux/mm.h>
#include <linux/slab.h>
+#include <asm/pgalloc.h>
+
static struct kmem_cache *pgd_cachep;
#if PAGETABLE_LEVELS > 2
static struct kmem_cache *pmd_cachep;
#endif
-void pgd_ctor(void *x)
+static void pgd_ctor(void *x)
{
pgd_t *pgd = x;
diff --git a/arch/sh/mm/tlbex_32.c b/arch/sh/mm/tlbex_32.c
index 1c53868632ee..7d58578c15f4 100644
--- a/arch/sh/mm/tlbex_32.c
+++ b/arch/sh/mm/tlbex_32.c
@@ -14,6 +14,7 @@
#include <linux/kdebug.h>
#include <asm/mmu_context.h>
#include <asm/thread_info.h>
+#include <asm/tlb.h>
/*
* Called with interrupts disabled.
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 2a03daa68f28..757451c3ea1d 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -59,8 +59,8 @@ endif
libs-y += arch/sparc/prom/
libs-y += arch/sparc/lib/
-drivers-$(CONFIG_PM) += arch/sparc/power/
-drivers-$(CONFIG_FB_CORE) += arch/sparc/video/
+drivers-$(CONFIG_PM) += arch/sparc/power/
+drivers-$(CONFIG_VIDEO) += arch/sparc/video/
boot := arch/sparc/boot
diff --git a/arch/sparc/boot/install.sh b/arch/sparc/boot/install.sh
index 4f130f3f30d6..68de67c5621e 100755
--- a/arch/sparc/boot/install.sh
+++ b/arch/sparc/boot/install.sh
@@ -16,6 +16,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
fi
diff --git a/arch/sparc/include/asm/asm-prototypes.h b/arch/sparc/include/asm/asm-prototypes.h
index 4987c735ff56..08810808ca6d 100644
--- a/arch/sparc/include/asm/asm-prototypes.h
+++ b/arch/sparc/include/asm/asm-prototypes.h
@@ -3,15 +3,18 @@
* Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
*/
-#include <asm/xor.h>
-#include <asm/checksum.h>
-#include <asm/trap_block.h>
+#include <linux/atomic.h>
#include <linux/uaccess.h>
+
#include <asm/atomic.h>
-#include <asm/ftrace.h>
#include <asm/cacheflush.h>
+#include <asm/checksum.h>
+#include <asm/delay.h>
+#include <asm/ftrace.h>
#include <asm/oplib.h>
-#include <linux/atomic.h>
+#include <asm/pgtable.h>
+#include <asm/trap_block.h>
+#include <asm/xor.h>
void *__memscan_zero(void *, size_t);
void *__memscan_generic(void *, int, size_t);
@@ -23,3 +26,7 @@ void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
typedef int TItype __attribute__((mode(TI)));
TItype __multi3(TItype a, TItype b);
+
+s64 __ashldi3(s64, int);
+s64 __lshrdi3(s64, int);
+s64 __ashrdi3(s64, int);
diff --git a/arch/sparc/include/asm/cmpxchg_32.h b/arch/sparc/include/asm/cmpxchg_32.h
index d0af82c240b7..8c1a3ca34eeb 100644
--- a/arch/sparc/include/asm/cmpxchg_32.h
+++ b/arch/sparc/include/asm/cmpxchg_32.h
@@ -38,21 +38,19 @@ static __always_inline unsigned long __arch_xchg(unsigned long x, __volatile__ v
/* bug catcher for when unsupported size is used - won't link */
void __cmpxchg_called_with_bad_pointer(void);
-/* we only need to support cmpxchg of a u32 on sparc */
-unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+u8 __cmpxchg_u8(volatile u8 *m, u8 old, u8 new_);
+u16 __cmpxchg_u16(volatile u16 *m, u16 old, u16 new_);
+u32 __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
/* don't worry...optimizer will get rid of most of this */
static inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
{
- switch (size) {
- case 4:
- return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
- default:
- __cmpxchg_called_with_bad_pointer();
- break;
- }
- return old;
+ return
+ size == 1 ? __cmpxchg_u8(ptr, old, new_) :
+ size == 2 ? __cmpxchg_u16(ptr, old, new_) :
+ size == 4 ? __cmpxchg_u32(ptr, old, new_) :
+ (__cmpxchg_called_with_bad_pointer(), old);
}
#define arch_cmpxchg(ptr, o, n) \
@@ -63,7 +61,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
(unsigned long)_n_, sizeof(*(ptr))); \
})
-u64 __cmpxchg_u64(u64 *ptr, u64 old, u64 new);
+u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new);
#define arch_cmpxchg64(ptr, old, new) __cmpxchg_u64(ptr, old, new)
#include <asm-generic/cmpxchg-local.h>
diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h
index 6efeb24b0a92..b0f633ce3518 100644
--- a/arch/sparc/include/asm/floppy_64.h
+++ b/arch/sparc/include/asm/floppy_64.h
@@ -197,7 +197,7 @@ static void sun_fd_enable_dma(void)
pdma_areasize = pdma_size;
}
-irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
+static irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
{
if (likely(doing_pdma)) {
void __iomem *stat = (void __iomem *) fdc_status;
@@ -434,7 +434,8 @@ static int sun_pci_fd_eject(int drive)
return -EINVAL;
}
-void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
+static void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event,
+ void *cookie)
{
floppy_interrupt(0, NULL);
}
@@ -704,9 +705,7 @@ static unsigned long __init sun_floppy_init(void)
ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
ns87303_modify(config, FCR, 0, FCR_LDE);
- config = sun_floppy_types[0];
- sun_floppy_types[0] = sun_floppy_types[1];
- sun_floppy_types[1] = config;
+ swap(sun_floppy_types[0], sun_floppy_types[1]);
if (sun_pci_broken_drive != -1) {
sun_pci_broken_drive = 1 - sun_pci_broken_drive;
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index a67abebd4359..1b86d02a8455 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -247,6 +247,7 @@ void prom_sun4v_guest_soft_state(void);
int prom_ihandle2path(int handle, char *buffer, int bufsize);
/* Client interface level routines. */
+void prom_cif_init(void *cif_handler);
void p1275_cmd_direct(unsigned long *);
#endif /* !(__SPARC64_OPLIB_H) */
diff --git a/arch/sparc/include/asm/parport_64.h b/arch/sparc/include/asm/parport_64.h
index 0a7ffcfd59cd..4f530a270760 100644
--- a/arch/sparc/include/asm/parport_64.h
+++ b/arch/sparc/include/asm/parport_64.h
@@ -196,7 +196,7 @@ out_err:
return err;
}
-static int ecpp_remove(struct platform_device *op)
+static void ecpp_remove(struct platform_device *op)
{
struct parport *p = dev_get_drvdata(&op->dev);
int slot = p->dma;
@@ -216,8 +216,6 @@ static int ecpp_remove(struct platform_device *op)
d_len);
clear_bit(slot, dma_slot_map);
}
-
- return 0;
}
static const struct of_device_id ecpp_match[] = {
@@ -245,7 +243,7 @@ static struct platform_driver ecpp_driver = {
.of_match_table = ecpp_match,
},
.probe = ecpp_probe,
- .remove = ecpp_remove,
+ .remove_new = ecpp_remove,
};
static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 9e85d57ac3f2..62bcafe38b1f 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -432,6 +432,8 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
#define VMALLOC_START _AC(0xfe600000,UL)
#define VMALLOC_END _AC(0xffc00000,UL)
+#define MODULES_VADDR VMALLOC_START
+#define MODULES_END VMALLOC_END
/* We provide our own get_unmapped_area to cope with VA holes for userland */
#define HAVE_ARCH_UNMAPPED_AREA
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 4d1bafaba942..3fe429d73a65 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -875,6 +875,7 @@ static inline bool pud_leaf(pud_t pud)
return pte_val(pte) & _PAGE_PMD_HUGE;
}
+#define pud_pfn pud_pfn
static inline unsigned long pud_pfn(pud_t pud)
{
pte_t pte = __pte(pud_val(pud));
@@ -956,7 +957,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
#ifdef DCACHE_ALIASING_POSSIBLE
#define __HAVE_ARCH_MOVE_PTE
-#define move_pte(pte, prot, old_addr, new_addr) \
+#define move_pte(pte, old_addr, new_addr) \
({ \
pte_t newpte = (pte); \
if (tlb_type != hypervisor && pte_present(pte)) { \
diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h
index 505b6700805d..0964fede0b2c 100644
--- a/arch/sparc/include/asm/smp_64.h
+++ b/arch/sparc/include/asm/smp_64.h
@@ -47,7 +47,6 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask);
int hard_smp_processor_id(void);
#define raw_smp_processor_id() (current_thread_info()->cpu)
-void smp_fill_in_cpu_possible_map(void);
void smp_fill_in_sib_core_maps(void);
void __noreturn cpu_play_dead(void);
@@ -77,7 +76,6 @@ void __cpu_die(unsigned int cpu);
#define smp_fill_in_sib_core_maps() do { } while (0)
#define smp_fetch_global_regs() do { } while (0)
#define smp_fetch_global_pmu() do { } while (0)
-#define smp_fill_in_cpu_possible_map() do { } while (0)
#define smp_init_cpu_poke() do { } while (0)
#define scheduler_poke() do { } while (0)
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 9fd6c53644b6..43284b6ec46a 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -95,7 +95,8 @@ __asm__ __volatile__( \
".section .fixup,#alloc,#execinstr\n\t" \
".align 4\n" \
"3:\n\t" \
- "b 2b\n\t" \
+ "sethi %%hi(2b), %0\n\t" \
+ "jmpl %0 + %%lo(2b), %%g0\n\t" \
" mov %3, %0\n\t" \
".previous\n\n\t" \
".section __ex_table,#alloc\n\t" \
@@ -163,8 +164,9 @@ __asm__ __volatile__( \
".section .fixup,#alloc,#execinstr\n\t" \
".align 4\n" \
"3:\n\t" \
+ "sethi %%hi(2b), %0\n\t" \
"clr %1\n\t" \
- "b 2b\n\t" \
+ "jmpl %0 + %%lo(2b), %%g0\n\t" \
" mov %3, %0\n\n\t" \
".previous\n\t" \
".section __ex_table,#alloc\n\t" \
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index d6bc76706a7a..3380411a4537 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -49,6 +49,8 @@
#define __ARCH_WANT_COMPAT_STAT
#endif
+#define __ARCH_BROKEN_SYS_CLONE3
+
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
* it never had the plain ones and there is no value to adding those
diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/video.h
index 24440c0fda49..a6f48f52db58 100644
--- a/arch/sparc/include/asm/fb.h
+++ b/arch/sparc/include/asm/video.h
@@ -1,12 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _SPARC_FB_H_
-#define _SPARC_FB_H_
+#ifndef _SPARC_VIDEO_H_
+#define _SPARC_VIDEO_H_
#include <linux/io.h>
+#include <linux/types.h>
#include <asm/page.h>
-struct fb_info;
+struct device;
#ifdef CONFIG_SPARC32
static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
@@ -18,8 +19,8 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
#define pgprot_framebuffer pgprot_framebuffer
#endif
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
+bool video_is_primary_device(struct device *dev);
+#define video_is_primary_device video_is_primary_device
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
{
@@ -39,6 +40,6 @@ static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
}
#define fb_memset fb_memset_io
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
-#endif /* _SPARC_FB_H_ */
+#endif /* _SPARC_VIDEO_H_ */
diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h
index 587fb7841096..0ca8c3463166 100644
--- a/arch/sparc/include/asm/vio.h
+++ b/arch/sparc/include/asm/vio.h
@@ -483,11 +483,7 @@ int __vio_register_driver(struct vio_driver *drv, struct module *owner,
__vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
void vio_unregister_driver(struct vio_driver *drv);
-static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
-{
- return container_of(drv, struct vio_driver, driver);
-}
-
+#define to_vio_driver(__drv) container_of_const(__drv, struct vio_driver, driver)
#define to_vio_dev(__dev) container_of_const(__dev, struct vio_dev, dev)
int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
index 4321322701fc..0da2b1adc0f5 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -10,16 +10,6 @@ typedef unsigned int tcflag_t;
typedef unsigned long tcflag_t;
#endif
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
#define NCCS 17
struct termios {
tcflag_t c_iflag; /* input mode flags */
diff --git a/arch/sparc/include/uapi/asm/termios.h b/arch/sparc/include/uapi/asm/termios.h
index ee86f4093d83..cceb32260881 100644
--- a/arch/sparc/include/uapi/asm/termios.h
+++ b/arch/sparc/include/uapi/asm/termios.h
@@ -40,5 +40,14 @@ struct winsize {
unsigned short ws_ypixel;
};
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
#endif /* _UAPI_SPARC_TERMIOS_H */
diff --git a/arch/sparc/kernel/adi_64.c b/arch/sparc/kernel/adi_64.c
index ce332942de2d..e0e4fc527b24 100644
--- a/arch/sparc/kernel/adi_64.c
+++ b/arch/sparc/kernel/adi_64.c
@@ -121,9 +121,9 @@ adi_not_found:
mdesc_release(hp);
}
-tag_storage_desc_t *find_tag_store(struct mm_struct *mm,
- struct vm_area_struct *vma,
- unsigned long addr)
+static tag_storage_desc_t *find_tag_store(struct mm_struct *mm,
+ struct vm_area_struct *vma,
+ unsigned long addr)
{
tag_storage_desc_t *tag_desc = NULL;
unsigned long i, max_desc, flags;
@@ -153,9 +153,9 @@ tag_storage_desc_t *find_tag_store(struct mm_struct *mm,
return tag_desc;
}
-tag_storage_desc_t *alloc_tag_store(struct mm_struct *mm,
- struct vm_area_struct *vma,
- unsigned long addr)
+static tag_storage_desc_t *alloc_tag_store(struct mm_struct *mm,
+ struct vm_area_struct *vma,
+ unsigned long addr)
{
unsigned char *tags;
unsigned long i, size, max_desc, flags;
@@ -296,7 +296,7 @@ out:
return tag_desc;
}
-void del_tag_store(tag_storage_desc_t *tag_desc, struct mm_struct *mm)
+static void del_tag_store(tag_storage_desc_t *tag_desc, struct mm_struct *mm)
{
unsigned long flags;
unsigned char *tags = NULL;
diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c
index 00e571c30bb5..e02074062001 100644
--- a/arch/sparc/kernel/chmc.c
+++ b/arch/sparc/kernel/chmc.c
@@ -788,7 +788,7 @@ static void jbusmc_destroy(struct platform_device *op, struct jbusmc *p)
kfree(p);
}
-static int us3mc_remove(struct platform_device *op)
+static void us3mc_remove(struct platform_device *op)
{
void *p = dev_get_drvdata(&op->dev);
@@ -798,7 +798,6 @@ static int us3mc_remove(struct platform_device *op)
else if (mc_type == MC_TYPE_JBUS)
jbusmc_destroy(op, p);
}
- return 0;
}
static const struct of_device_id us3mc_match[] = {
@@ -815,7 +814,7 @@ static struct platform_driver us3mc_driver = {
.of_match_table = us3mc_match,
},
.probe = us3mc_probe,
- .remove = us3mc_remove,
+ .remove_new = us3mc_remove,
};
static inline bool us3mc_platform(void)
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 964c61b5cd03..38345460d542 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -118,9 +118,12 @@ current_pc:
mov %o7, %g3
tst %o0
- be no_sun4u_here
+ bne 2f
mov %g4, %o7 /* Previous %o7. */
-
+ sethi %hi(no_sun4u_here), %l1
+ jmpl %l1 + %lo(no_sun4u_here), %g0
+ nop
+2:
mov %o0, %l0 ! stash away romvec
mov %o0, %g7 ! put it here too
mov %o1, %l1 ! stash away debug_vec too
@@ -195,7 +198,8 @@ halt_notsup:
sub %o0, %l6, %o0
call %o1
nop
- ba halt_me
+ sethi %hi(halt_me), %o0
+ jmpl %o0 + %lo(halt_me), %g0
nop
not_a_sun4:
@@ -431,8 +435,11 @@ leon_init:
#ifdef CONFIG_SMP
ldub [%g2 + %lo(boot_cpu_id)], %g1
cmp %g1, 0xff ! unset means first CPU
- bne leon_smp_cpu_startup ! continue only with master
+ be 1f
+ sethi %hi(leon_smp_cpu_startup), %g1
+ jmpl %g1 + %lo(leon_smp_cpu_startup), %g0
nop
+1:
#endif
/* Get CPU-ID from most significant 4-bit of ASR17 */
rd %asr17, %g1
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 5280e325d4d6..01ee800efde3 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -349,17 +349,13 @@ static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid)
#ifdef CONFIG_SMP
static int irq_choose_cpu(unsigned int irq, const struct cpumask *affinity)
{
- cpumask_t mask;
int cpuid;
- cpumask_copy(&mask, affinity);
- if (cpumask_equal(&mask, cpu_online_mask)) {
+ if (cpumask_equal(affinity, cpu_online_mask)) {
cpuid = map_to_cpu(irq);
} else {
- cpumask_t tmp;
-
- cpumask_and(&tmp, cpu_online_mask, &mask);
- cpuid = cpumask_empty(&tmp) ? map_to_cpu(irq) : cpumask_first(&tmp);
+ cpuid = cpumask_first_and(affinity, cpu_online_mask);
+ cpuid = cpuid < nr_cpu_ids ? cpuid : map_to_cpu(irq);
}
return cpuid;
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index a8fb7c0bf053..8328a3b78a44 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -40,6 +40,10 @@ int handle_popc(u32 insn, struct pt_regs *regs);
void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr);
void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr);
+/* uprobes.c */
+asmlinkage void uprobe_trap(struct pt_regs *regs,
+ unsigned long trap_level);
+
/* smp_64.c */
void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs);
void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs);
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 4c61da491fee..a43cf794bb1e 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -106,13 +106,12 @@ unsigned long leon_get_irqmask(unsigned int irq)
#ifdef CONFIG_SMP
static int irq_choose_cpu(const struct cpumask *affinity)
{
- cpumask_t mask;
+ unsigned int cpu = cpumask_first_and(affinity, cpu_online_mask);
- cpumask_and(&mask, cpu_online_mask, affinity);
- if (cpumask_equal(&mask, cpu_online_mask) || cpumask_empty(&mask))
+ if (cpumask_subset(cpu_online_mask, affinity) || cpu >= nr_cpu_ids)
return boot_cpu_id;
else
- return cpumask_first(&mask);
+ return cpu;
}
#else
#define irq_choose_cpu(affinity) boot_cpu_id
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 66c45a2764bc..b8c51cc23d96 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -21,36 +21,6 @@
#include "entry.h"
-#ifdef CONFIG_SPARC64
-
-#include <linux/jump_label.h>
-
-static void *module_map(unsigned long size)
-{
- if (PAGE_ALIGN(size) > MODULES_LEN)
- return NULL;
- return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-#else
-static void *module_map(unsigned long size)
-{
- return vmalloc(size);
-}
-#endif /* CONFIG_SPARC64 */
-
-void *module_alloc(unsigned long size)
-{
- void *ret;
-
- ret = module_map(size);
- if (ret)
- memset(ret, 0, size);
-
- return ret;
-}
-
/* Make generic code ignore STT_REGISTER dummy undefined symbols. */
int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index c350c58c7f69..f98c2901f335 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -624,10 +624,7 @@ static unsigned int __init build_one_device_irq(struct platform_device *op,
out:
nid = of_node_to_nid(dp);
if (nid != -1) {
- cpumask_t numa_mask;
-
- cpumask_copy(&numa_mask, cpumask_of_node(nid));
- irq_set_affinity(irq, &numa_mask);
+ irq_set_affinity(irq, cpumask_of_node(nid));
}
return irq;
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c
index fc7402948b7b..acb2f83a1d5c 100644
--- a/arch/sparc/kernel/pci_msi.c
+++ b/arch/sparc/kernel/pci_msi.c
@@ -287,10 +287,7 @@ static int bringup_one_msi_queue(struct pci_pbm_info *pbm,
nid = pbm->numa_node;
if (nid != -1) {
- cpumask_t numa_mask;
-
- cpumask_copy(&numa_mask, cpumask_of_node(nid));
- irq_set_affinity(irq, &numa_mask);
+ irq_set_affinity(irq, cpumask_of_node(nid));
}
err = request_irq(irq, sparc64_msiq_interrupt, 0,
"MSIQ",
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 083e5f05a7f0..b720b21ccfbd 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -256,9 +256,9 @@ range_alloc_fail:
return NULL;
}
-unsigned long dma_4v_iotsb_bind(unsigned long devhandle,
- unsigned long iotsb_num,
- struct pci_bus *bus_dev)
+static unsigned long dma_4v_iotsb_bind(unsigned long devhandle,
+ unsigned long iotsb_num,
+ struct pci_bus *bus_dev)
{
struct pci_dev *pdev;
unsigned long err;
diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
index 998aa693d491..ba82884cb92a 100644
--- a/arch/sparc/kernel/prom_64.c
+++ b/arch/sparc/kernel/prom_64.c
@@ -483,7 +483,9 @@ static void *record_one_cpu(struct device_node *dp, int cpuid, int arg)
ncpus_probed++;
#ifdef CONFIG_SMP
set_cpu_present(cpuid, true);
- set_cpu_possible(cpuid, true);
+
+ if (num_possible_cpus() < nr_cpu_ids)
+ set_cpu_possible(cpuid, true);
#endif
return NULL;
}
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 6a4797dec34b..63615f5c99b4 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -599,7 +599,7 @@ static void __init init_sparc64_elf_hwcap(void)
pause_patch();
}
-void __init alloc_irqstack_bootmem(void)
+static void __init alloc_irqstack_bootmem(void)
{
unsigned int i, node;
@@ -671,7 +671,6 @@ void __init setup_arch(char **cmdline_p)
paging_init();
init_sparc64_elf_hwcap();
- smp_fill_in_cpu_possible_map();
/*
* Once the OF device tree and MDESC have been setup and nr_cpus has
* been parsed, we know the list of possible cpus. Therefore we can
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index a0cc9bb41a92..e40c395db202 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1216,20 +1216,6 @@ void __init smp_setup_processor_id(void)
xcall_deliver_impl = hypervisor_xcall_deliver;
}
-void __init smp_fill_in_cpu_possible_map(void)
-{
- int possible_cpus = num_possible_cpus();
- int i;
-
- if (possible_cpus > nr_cpu_ids)
- possible_cpus = nr_cpu_ids;
-
- for (i = 0; i < possible_cpus; i++)
- set_cpu_possible(i, true);
- for (; i < NR_CPUS; i++)
- set_cpu_possible(i, false);
-}
-
void smp_fill_in_sib_core_maps(void)
{
unsigned int i;
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index a45f0f31fe51..a3d308f2043e 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -18,224 +18,3 @@ sys32_mmap2:
sethi %hi(sys_mmap), %g1
jmpl %g1 + %lo(sys_mmap), %g0
sllx %o5, 12, %o5
-
- .align 32
- .globl sys32_socketcall
-sys32_socketcall: /* %o0=call, %o1=args */
- cmp %o0, 1
- bl,pn %xcc, do_einval
- cmp %o0, 18
- bg,pn %xcc, do_einval
- sub %o0, 1, %o0
- sllx %o0, 5, %o0
- sethi %hi(__socketcall_table_begin), %g2
- or %g2, %lo(__socketcall_table_begin), %g2
- jmpl %g2 + %o0, %g0
- nop
-do_einval:
- retl
- mov -EINVAL, %o0
-
- .align 32
-__socketcall_table_begin:
-
- /* Each entry is exactly 32 bytes. */
-do_sys_socket: /* sys_socket(int, int, int) */
-1: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_socket), %g1
-2: ldswa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(sys_socket), %g0
-3: ldswa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */
-4: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_bind), %g1
-5: ldswa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(sys_bind), %g0
-6: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */
-7: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_connect), %g1
-8: ldswa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(sys_connect), %g0
-9: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_listen: /* sys_listen(int, int) */
-10: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_listen), %g1
- jmpl %g1 + %lo(sys_listen), %g0
-11: ldswa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
- nop
-do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */
-12: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_accept), %g1
-13: lduwa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(sys_accept), %g0
-14: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */
-15: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_getsockname), %g1
-16: lduwa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(sys_getsockname), %g0
-17: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */
-18: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_getpeername), %g1
-19: lduwa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(sys_getpeername), %g0
-20: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */
-21: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_socketpair), %g1
-22: ldswa [%o1 + 0x8] %asi, %o2
-23: lduwa [%o1 + 0xc] %asi, %o3
- jmpl %g1 + %lo(sys_socketpair), %g0
-24: ldswa [%o1 + 0x4] %asi, %o1
- nop
- nop
-do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */
-25: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_send), %g1
-26: lduwa [%o1 + 0x8] %asi, %o2
-27: lduwa [%o1 + 0xc] %asi, %o3
- jmpl %g1 + %lo(sys_send), %g0
-28: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
-do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */
-29: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_recv), %g1
-30: lduwa [%o1 + 0x8] %asi, %o2
-31: lduwa [%o1 + 0xc] %asi, %o3
- jmpl %g1 + %lo(sys_recv), %g0
-32: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
-do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
-33: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_sendto), %g1
-34: lduwa [%o1 + 0x8] %asi, %o2
-35: lduwa [%o1 + 0xc] %asi, %o3
-36: lduwa [%o1 + 0x10] %asi, %o4
-37: ldswa [%o1 + 0x14] %asi, %o5
- jmpl %g1 + %lo(sys_sendto), %g0
-38: lduwa [%o1 + 0x4] %asi, %o1
-do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
-39: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_recvfrom), %g1
-40: lduwa [%o1 + 0x8] %asi, %o2
-41: lduwa [%o1 + 0xc] %asi, %o3
-42: lduwa [%o1 + 0x10] %asi, %o4
-43: lduwa [%o1 + 0x14] %asi, %o5
- jmpl %g1 + %lo(sys_recvfrom), %g0
-44: lduwa [%o1 + 0x4] %asi, %o1
-do_sys_shutdown: /* sys_shutdown(int, int) */
-45: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_shutdown), %g1
- jmpl %g1 + %lo(sys_shutdown), %g0
-46: ldswa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
- nop
-do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */
-47: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_setsockopt), %g1
-48: ldswa [%o1 + 0x8] %asi, %o2
-49: lduwa [%o1 + 0xc] %asi, %o3
-50: ldswa [%o1 + 0x10] %asi, %o4
- jmpl %g1 + %lo(sys_setsockopt), %g0
-51: ldswa [%o1 + 0x4] %asi, %o1
- nop
-do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */
-52: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_getsockopt), %g1
-53: ldswa [%o1 + 0x8] %asi, %o2
-54: lduwa [%o1 + 0xc] %asi, %o3
-55: lduwa [%o1 + 0x10] %asi, %o4
- jmpl %g1 + %lo(sys_getsockopt), %g0
-56: ldswa [%o1 + 0x4] %asi, %o1
- nop
-do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
-57: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(compat_sys_sendmsg), %g1
-58: lduwa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(compat_sys_sendmsg), %g0
-59: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
-60: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(compat_sys_recvmsg), %g1
-61: lduwa [%o1 + 0x8] %asi, %o2
- jmpl %g1 + %lo(compat_sys_recvmsg), %g0
-62: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
- nop
-do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */
-63: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(sys_accept4), %g1
-64: lduwa [%o1 + 0x8] %asi, %o2
-65: ldswa [%o1 + 0xc] %asi, %o3
- jmpl %g1 + %lo(sys_accept4), %g0
-66: lduwa [%o1 + 0x4] %asi, %o1
- nop
- nop
-
- .section __ex_table,"a"
- .align 4
- .word 1b, __retl_efault, 2b, __retl_efault
- .word 3b, __retl_efault, 4b, __retl_efault
- .word 5b, __retl_efault, 6b, __retl_efault
- .word 7b, __retl_efault, 8b, __retl_efault
- .word 9b, __retl_efault, 10b, __retl_efault
- .word 11b, __retl_efault, 12b, __retl_efault
- .word 13b, __retl_efault, 14b, __retl_efault
- .word 15b, __retl_efault, 16b, __retl_efault
- .word 17b, __retl_efault, 18b, __retl_efault
- .word 19b, __retl_efault, 20b, __retl_efault
- .word 21b, __retl_efault, 22b, __retl_efault
- .word 23b, __retl_efault, 24b, __retl_efault
- .word 25b, __retl_efault, 26b, __retl_efault
- .word 27b, __retl_efault, 28b, __retl_efault
- .word 29b, __retl_efault, 30b, __retl_efault
- .word 31b, __retl_efault, 32b, __retl_efault
- .word 33b, __retl_efault, 34b, __retl_efault
- .word 35b, __retl_efault, 36b, __retl_efault
- .word 37b, __retl_efault, 38b, __retl_efault
- .word 39b, __retl_efault, 40b, __retl_efault
- .word 41b, __retl_efault, 42b, __retl_efault
- .word 43b, __retl_efault, 44b, __retl_efault
- .word 45b, __retl_efault, 46b, __retl_efault
- .word 47b, __retl_efault, 48b, __retl_efault
- .word 49b, __retl_efault, 50b, __retl_efault
- .word 51b, __retl_efault, 52b, __retl_efault
- .word 53b, __retl_efault, 54b, __retl_efault
- .word 55b, __retl_efault, 56b, __retl_efault
- .word 57b, __retl_efault, 58b, __retl_efault
- .word 59b, __retl_efault, 60b, __retl_efault
- .word 61b, __retl_efault, 62b, __retl_efault
- .word 63b, __retl_efault, 64b, __retl_efault
- .word 65b, __retl_efault, 66b, __retl_efault
- .previous
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 082a551897ed..08a19727795c 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -41,7 +41,7 @@ SYSCALL_DEFINE0(getpagesize)
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -59,7 +59,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
if (!addr)
addr = TASK_UNMAPPED_BASE;
- info.flags = 0;
info.length = len;
info.low_limit = addr;
info.high_limit = TASK_SIZE;
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 1e9a9e016237..d9c3b34ca744 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -93,7 +93,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
struct vm_area_struct * vma;
unsigned long task_size = TASK_SIZE;
int do_color_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -126,7 +126,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
return addr;
}
- info.flags = 0;
info.length = len;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = min(task_size, VA_EXCLUDE_START);
@@ -154,7 +153,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long task_size = STACK_TOP32;
unsigned long addr = addr0;
int do_color_align;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/* This should only ever run for 32-bit processes. */
BUG_ON(!test_thread_flag(TIF_32BIT));
@@ -218,14 +217,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
unsigned long align_goal, addr = -ENOMEM;
- unsigned long (*get_area)(struct file *, unsigned long,
- unsigned long, unsigned long, unsigned long);
-
- get_area = current->mm->get_unmapped_area;
if (flags & MAP_FIXED) {
/* Ok, don't mess with it. */
- return get_area(NULL, orig_addr, len, pgoff, flags);
+ return mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags);
}
flags &= ~MAP_SHARED;
@@ -238,7 +233,8 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
align_goal = (64UL * 1024);
do {
- addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
+ addr = mm_get_unmapped_area(current->mm, NULL, orig_addr,
+ len + (align_goal - PAGE_SIZE), pgoff, flags);
if (!(addr & ~PAGE_MASK)) {
addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
break;
@@ -256,7 +252,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
* be obtained.
*/
if (addr & ~PAGE_MASK)
- addr = get_area(NULL, orig_addr, len, pgoff, flags);
+ addr = mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags);
return addr;
}
@@ -292,7 +288,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
gap == RLIM_INFINITY ||
sysctl_legacy_va_layout) {
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
- mm->get_unmapped_area = arch_get_unmapped_area;
+ clear_bit(MMF_TOPDOWN, &mm->flags);
} else {
/* We know it's 32-bit */
unsigned long task_size = STACK_TOP32;
@@ -303,7 +299,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
gap = (task_size / 6 * 5);
mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ set_bit(MMF_TOPDOWN, &mm->flags);
}
}
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index b23d59313589..cfdfb3707c16 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -117,7 +117,7 @@
90 common dup2 sys_dup2
91 32 setfsuid32 sys_setfsuid
92 common fcntl sys_fcntl compat_sys_fcntl
-93 common select sys_select
+93 common select sys_select compat_sys_select
94 32 setfsgid32 sys_setfsgid
95 common fsync sys_fsync
96 common setpriority sys_setpriority
@@ -155,7 +155,7 @@
123 32 fchown sys_fchown16
123 64 fchown sys_fchown
124 common fchmod sys_fchmod
-125 common recvfrom sys_recvfrom
+125 common recvfrom sys_recvfrom compat_sys_recvfrom
126 32 setreuid sys_setreuid16
126 64 setreuid sys_setreuid
127 32 setregid sys_setregid16
@@ -247,7 +247,7 @@
204 32 readdir sys_old_readdir compat_sys_old_readdir
204 64 readdir sys_nis_syscall
205 common readahead sys_readahead compat_sys_readahead
-206 common socketcall sys_socketcall sys32_socketcall
+206 common socketcall sys_socketcall compat_sys_socketcall
207 common syslog sys_syslog
208 common lookup_dcookie sys_ni_syscall
209 common fadvise64 sys_fadvise64 compat_sys_fadvise64
@@ -461,7 +461,7 @@
412 32 utimensat_time64 sys_utimensat sys_utimensat
413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64
-416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents
+416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64
417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend
419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive
@@ -507,3 +507,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 89fb05f90609..60f1c8cc5363 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -33,6 +33,7 @@
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/platform_device.h>
+#include <linux/sched/clock.h>
#include <linux/ftrace.h>
#include <asm/oplib.h>
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index dd048023bff5..28cb0d66ab40 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -250,7 +250,7 @@ void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u
sun4v_insn_access_exception(regs, addr, type_ctx);
}
-bool is_no_fault_exception(struct pt_regs *regs)
+static bool is_no_fault_exception(struct pt_regs *regs)
{
unsigned char asi;
u32 insn;
@@ -2032,7 +2032,7 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent,
/* Handle memory corruption detected error which is vectored in
* through resumable error trap.
*/
-void do_mcd_err(struct pt_regs *regs, struct sun4v_error_entry ent)
+static void do_mcd_err(struct pt_regs *regs, struct sun4v_error_entry ent)
{
if (notify_die(DIE_TRAP, "MCD error", regs, 0, 0x34,
SIGSEGV) == NOTIFY_STOP)
@@ -2150,9 +2150,9 @@ static unsigned long sun4v_get_vaddr(struct pt_regs *regs)
/* Attempt to handle non-resumable errors generated from userspace.
* Returns true if the signal was handled, false otherwise.
*/
-bool sun4v_nonresum_error_user_handled(struct pt_regs *regs,
- struct sun4v_error_entry *ent) {
-
+static bool sun4v_nonresum_error_user_handled(struct pt_regs *regs,
+ struct sun4v_error_entry *ent)
+{
unsigned int attrs = ent->err_attrs;
if (attrs & SUN4V_ERR_ATTRS_MEMORY) {
diff --git a/arch/sparc/kernel/uprobes.c b/arch/sparc/kernel/uprobes.c
index 1a0600206bf5..305017bec164 100644
--- a/arch/sparc/kernel/uprobes.c
+++ b/arch/sparc/kernel/uprobes.c
@@ -18,6 +18,8 @@
#include <asm/cacheflush.h>
+#include "kernel.h"
+
/* Compute the address of the breakpoint instruction and return it.
*
* Note that uprobe_get_swbp_addr is defined as a weak symbol in
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c
index 846a55f942d4..07933d75ac81 100644
--- a/arch/sparc/kernel/vio.c
+++ b/arch/sparc/kernel/vio.c
@@ -54,10 +54,10 @@ static int vio_hotplug(const struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-static int vio_bus_match(struct device *dev, struct device_driver *drv)
+static int vio_bus_match(struct device *dev, const struct device_driver *drv)
{
struct vio_dev *vio_dev = to_vio_dev(dev);
- struct vio_driver *vio_drv = to_vio_driver(drv);
+ const struct vio_driver *vio_drv = to_vio_driver(drv);
const struct vio_device_id *matches = vio_drv->id_table;
if (!matches)
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index cf80d1ae352b..8ae880ebf07a 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -159,32 +159,27 @@ unsigned long sp32___change_bit(unsigned long *addr, unsigned long mask)
}
EXPORT_SYMBOL(sp32___change_bit);
-unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
-{
- unsigned long flags;
- u32 prev;
-
- spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
- if ((prev = *ptr) == old)
- *ptr = new;
- spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
-
- return (unsigned long)prev;
-}
+#define CMPXCHG(T) \
+ T __cmpxchg_##T(volatile T *ptr, T old, T new) \
+ { \
+ unsigned long flags; \
+ T prev; \
+ \
+ spin_lock_irqsave(ATOMIC_HASH(ptr), flags); \
+ if ((prev = *ptr) == old) \
+ *ptr = new; \
+ spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);\
+ \
+ return prev; \
+ }
+
+CMPXCHG(u8)
+CMPXCHG(u16)
+CMPXCHG(u32)
+CMPXCHG(u64)
+EXPORT_SYMBOL(__cmpxchg_u8);
+EXPORT_SYMBOL(__cmpxchg_u16);
EXPORT_SYMBOL(__cmpxchg_u32);
-
-u64 __cmpxchg_u64(u64 *ptr, u64 old, u64 new)
-{
- unsigned long flags;
- u64 prev;
-
- spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
- if ((prev = *ptr) == old)
- *ptr = new;
- spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
-
- return prev;
-}
EXPORT_SYMBOL(__cmpxchg_u64);
unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 809d993f6d88..2d1752108d77 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -14,3 +14,5 @@ obj-$(CONFIG_SPARC32) += leon_mm.o
# Only used by sparc64
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+
+obj-$(CONFIG_EXECMEM) += execmem.o
diff --git a/arch/sparc/mm/execmem.c b/arch/sparc/mm/execmem.c
new file mode 100644
index 000000000000..0fac97dd5728
--- /dev/null
+++ b/arch/sparc/mm/execmem.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/mm.h>
+#include <linux/execmem.h>
+
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .start = MODULES_VADDR,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index b432500c13a5..cc91ca7a1e18 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -31,17 +31,15 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
{
struct hstate *h = hstate_file(filp);
unsigned long task_size = TASK_SIZE;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
if (test_thread_flag(TIF_32BIT))
task_size = STACK_TOP32;
- info.flags = 0;
info.length = len;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = min(task_size, VA_EXCLUDE_START);
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- info.align_offset = 0;
addr = vm_unmapped_area(&info);
if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
@@ -63,7 +61,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct hstate *h = hstate_file(filp);
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/* This should only ever run for 32-bit processes. */
BUG_ON(!test_thread_flag(TIF_32BIT));
@@ -73,7 +71,6 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- info.align_offset = 0;
addr = vm_unmapped_area(&info);
/*
@@ -123,7 +120,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
(!vma || addr + len <= vm_start_gap(vma)))
return addr;
}
- if (mm->get_unmapped_area == arch_get_unmapped_area)
+ if (!test_bit(MMF_TOPDOWN, &mm->flags))
return hugetlb_get_unmapped_area_bottomup(file, addr, len,
pgoff, flags);
else
@@ -407,18 +404,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
return entry;
}
-int pmd_huge(pmd_t pmd)
-{
- return !pmd_none(pmd) &&
- (pmd_val(pmd) & (_PAGE_VALID|_PAGE_PMD_HUGE)) != _PAGE_VALID;
-}
-
-int pud_huge(pud_t pud)
-{
- return !pud_none(pud) &&
- (pud_val(pud) & (_PAGE_VALID|_PAGE_PUD_HUGE)) != _PAGE_VALID;
-}
-
static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
unsigned long addr)
{
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 1ca9054d9b97..53d7cb5bbffe 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -490,7 +490,7 @@ void flush_dcache_folio(struct folio *folio)
}
set_dcache_dirty(folio, this_cpu);
} else {
- /* We could delay the flush for the !page_mapping
+ /* We could delay the flush for the !folio_mapping
* case too. But that case is for exec env/arg
* pages and those are %99 certainly going to get
* faulted into the tlb (and thus flushed) anyways.
@@ -2640,11 +2640,6 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
return 0;
}
-
-void vmemmap_free(unsigned long start, unsigned long end,
- struct vmem_altmap *altmap)
-{
-}
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
/* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 852085ada368..9df51a62333d 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1653,13 +1653,15 @@ static void smp_flush_tlb_all(void)
local_ops->tlb_all();
}
+static bool any_other_mm_cpus(struct mm_struct *mm)
+{
+ return cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids;
+}
+
static void smp_flush_cache_mm(struct mm_struct *mm)
{
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
+ if (any_other_mm_cpus(mm))
xc1(local_ops->cache_mm, (unsigned long)mm);
local_ops->cache_mm(mm);
}
@@ -1668,10 +1670,7 @@ static void smp_flush_cache_mm(struct mm_struct *mm)
static void smp_flush_tlb_mm(struct mm_struct *mm)
{
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask)) {
+ if (any_other_mm_cpus(mm)) {
xc1(local_ops->tlb_mm, (unsigned long)mm);
if (atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
cpumask_copy(mm_cpumask(mm),
@@ -1688,10 +1687,7 @@ static void smp_flush_cache_range(struct vm_area_struct *vma,
struct mm_struct *mm = vma->vm_mm;
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
+ if (any_other_mm_cpus(mm))
xc3(local_ops->cache_range, (unsigned long)vma, start,
end);
local_ops->cache_range(vma, start, end);
@@ -1705,10 +1701,7 @@ static void smp_flush_tlb_range(struct vm_area_struct *vma,
struct mm_struct *mm = vma->vm_mm;
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
+ if (any_other_mm_cpus(mm))
xc3(local_ops->tlb_range, (unsigned long)vma, start,
end);
local_ops->tlb_range(vma, start, end);
@@ -1720,10 +1713,7 @@ static void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
struct mm_struct *mm = vma->vm_mm;
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
+ if (any_other_mm_cpus(mm))
xc2(local_ops->cache_page, (unsigned long)vma, page);
local_ops->cache_page(vma, page);
}
@@ -1734,10 +1724,7 @@ static void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
struct mm_struct *mm = vma->vm_mm;
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
+ if (any_other_mm_cpus(mm))
xc2(local_ops->tlb_page, (unsigned long)vma, page);
local_ops->tlb_page(vma, page);
}
@@ -1759,10 +1746,7 @@ static void smp_flush_page_to_ram(unsigned long page)
static void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
{
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
+ if (any_other_mm_cpus(mm))
xc2(local_ops->sig_insns, (unsigned long)mm, insn_addr);
local_ops->sig_insns(mm, insn_addr);
}
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index b44d79d778c7..8648a50afe88 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -183,12 +183,12 @@ static void __set_pmd_acct(struct mm_struct *mm, unsigned long addr,
* hugetlb_pte_count.
*/
if (pmd_val(pmd) & _PAGE_PMD_HUGE) {
- if (is_huge_zero_page(pmd_page(pmd)))
+ if (is_huge_zero_pmd(pmd))
mm->context.hugetlb_pte_count++;
else
mm->context.thp_pte_count++;
} else {
- if (is_huge_zero_page(pmd_page(orig)))
+ if (is_huge_zero_pmd(orig))
mm->context.hugetlb_pte_count--;
else
mm->context.thp_pte_count--;
@@ -249,6 +249,7 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
{
pmd_t old, entry;
+ VM_WARN_ON_ONCE(!pmd_present(*pmdp));
entry = __pmd(pmd_val(*pmdp) & ~_PAGE_VALID);
old = pmdp_establish(vma, address, pmdp, entry);
flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
@@ -259,7 +260,7 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
* Sanity check pmd before doing the actual decrement.
*/
if ((pmd_val(entry) & _PAGE_PMD_HUGE) &&
- !is_huge_zero_page(pmd_page(entry)))
+ !is_huge_zero_pmd(entry))
(vma->vm_mm)->context.thp_pte_count--;
return old;
diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c
index da2df1e84ed4..bda2dbd3f4c5 100644
--- a/arch/sparc/net/bpf_jit_comp_32.c
+++ b/arch/sparc/net/bpf_jit_comp_32.c
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/moduleloader.h>
#include <linux/workqueue.h>
#include <linux/netdevice.h>
#include <linux/filter.h>
#include <linux/cache.h>
#include <linux/if_vlan.h>
+#include <linux/execmem.h>
#include <asm/cacheflush.h>
#include <asm/ptrace.h>
@@ -713,7 +713,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
if (unlikely(proglen + ilen > oldproglen)) {
pr_err("bpb_jit_compile fatal error\n");
kfree(addrs);
- module_memfree(image);
+ execmem_free(image);
return;
}
memcpy(image + proglen, temp, ilen);
@@ -736,7 +736,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
break;
}
if (proglen == oldproglen) {
- image = module_alloc(proglen);
+ image = execmem_alloc(EXECMEM_BPF, proglen);
if (!image)
goto out;
}
@@ -758,7 +758,7 @@ out:
void bpf_jit_free(struct bpf_prog *fp)
{
if (fp->jited)
- module_memfree(fp->bpf_func);
+ execmem_free(fp->bpf_func);
bpf_prog_unlock_free(fp);
}
diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
index fa0759bfe498..73bf0aea8baf 100644
--- a/arch/sparc/net/bpf_jit_comp_64.c
+++ b/arch/sparc/net/bpf_jit_comp_64.c
@@ -1602,7 +1602,11 @@ skip_init_ctx:
bpf_flush_icache(header, (u8 *)header + header->size);
if (!prog->is_func || extra_pass) {
- bpf_jit_binary_lock_ro(header);
+ if (bpf_jit_binary_lock_ro(header)) {
+ bpf_jit_binary_free(header);
+ prog = orig_prog;
+ goto out_off;
+ }
} else {
jit_data->ctx = ctx;
jit_data->image = image_ptr;
diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c
index 47b06f4af1f9..da8e2bc2e516 100644
--- a/arch/sparc/power/hibernate.c
+++ b/arch/sparc/power/hibernate.c
@@ -5,6 +5,7 @@
* Copyright (C) 2013 Kirill V Tkhai (tkhai@yandex.ru)
*/
+#include <linux/suspend.h>
#include <linux/mm.h>
#include <asm/hibernate.h>
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c
index 103aa9104318..f7b8a1a865b8 100644
--- a/arch/sparc/prom/init_64.c
+++ b/arch/sparc/prom/init_64.c
@@ -26,9 +26,6 @@ phandle prom_chosen_node;
* routines in the prom library.
* It gets passed the pointer to the PROM vector.
*/
-
-extern void prom_cif_init(void *);
-
void __init prom_init(void *cif_handler)
{
phandle node;
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index aed94cd4a1e7..3792736ff21f 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -162,7 +162,7 @@ unsigned char prom_get_idprom(char *idbuf, int num_bytes)
return 0xff;
}
-int prom_get_mmu_ihandle(void)
+static int prom_get_mmu_ihandle(void)
{
phandle node;
int ret;
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c
index 889aa602f8d8..51c3f984bbf7 100644
--- a/arch/sparc/prom/p1275.c
+++ b/arch/sparc/prom/p1275.c
@@ -49,7 +49,7 @@ void p1275_cmd_direct(unsigned long *args)
local_irq_restore(flags);
}
-void prom_cif_init(void *cif_handler, void *cif_stack)
+void prom_cif_init(void *cif_handler)
{
p1275buf.prom_cif_handler = (void (*)(long *))cif_handler;
}
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 989e7992d629..88793e5b0ab5 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -332,7 +332,7 @@ prom_setprop(phandle node, const char *pname, char *value, int size)
if (size == 0)
return 0;
- if ((pname == 0) || (value == 0))
+ if ((pname == NULL) || (value == NULL))
return 0;
#ifdef CONFIG_SUN_LDOMS
diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
index e8aef2c8ae99..243dbfc4609d 100644
--- a/arch/sparc/vdso/Makefile
+++ b/arch/sparc/vdso/Makefile
@@ -2,7 +2,6 @@
#
# Building vDSO images for sparc.
#
-UBSAN_SANITIZE := n
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o
@@ -103,7 +102,6 @@ quiet_cmd_vdso = VDSO $@
cmd_vdso = $(LD) -nostdlib -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-T $(filter %.lds,$^) $(filter %.o,$^) && \
- sh $(srctree)/$(src)/checkundef.sh '$(OBJDUMP)' '$@'
+ sh $(src)/checkundef.sh '$(OBJDUMP)' '$@'
VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic
-GCOV_PROFILE := n
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index 1bbf4335de45..bab7a59575e8 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -243,8 +243,9 @@ static int stick_patch(const struct vdso_image *image, struct vdso_elfinfo *e, b
* Allocate pages for the vdso and vvar, and copy in the vdso text from the
* kernel image.
*/
-int __init init_vdso_image(const struct vdso_image *image,
- struct vm_special_mapping *vdso_mapping, bool elf64)
+static int __init init_vdso_image(const struct vdso_image *image,
+ struct vm_special_mapping *vdso_mapping,
+ bool elf64)
{
int cnpages = (image->size) / PAGE_SIZE;
struct page *dp, **dpp = NULL;
diff --git a/arch/sparc/video/Makefile b/arch/sparc/video/Makefile
index d4d83f1702c6..dcfbe7a5912c 100644
--- a/arch/sparc/video/Makefile
+++ b/arch/sparc/video/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_FB_CORE) += fbdev.o
+obj-y += video-common.o
diff --git a/arch/sparc/video/fbdev.c b/arch/sparc/video/fbdev.c
deleted file mode 100644
index bff66dd1909a..000000000000
--- a/arch/sparc/video/fbdev.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <linux/console.h>
-#include <linux/fb.h>
-#include <linux/module.h>
-
-#include <asm/prom.h>
-
-int fb_is_primary_device(struct fb_info *info)
-{
- struct device *dev = info->device;
- struct device_node *node;
-
- if (console_set_on_cmdline)
- return 0;
-
- node = dev->of_node;
- if (node && node == of_console_device)
- return 1;
-
- return 0;
-}
-EXPORT_SYMBOL(fb_is_primary_device);
-
-MODULE_DESCRIPTION("Sparc fbdev helpers");
-MODULE_LICENSE("GPL");
diff --git a/arch/sparc/video/video-common.c b/arch/sparc/video/video-common.c
new file mode 100644
index 000000000000..2414380caadc
--- /dev/null
+++ b/arch/sparc/video/video-common.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/console.h>
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include <asm/prom.h>
+#include <asm/video.h>
+
+bool video_is_primary_device(struct device *dev)
+{
+ struct device_node *node = dev->of_node;
+
+ if (console_set_on_cmdline)
+ return false;
+
+ if (node && node == of_console_device)
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(video_is_primary_device);
+
+MODULE_DESCRIPTION("Sparc video helpers");
+MODULE_LICENSE("GPL");
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 93a5a8999b07..dca84fd6d00a 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -11,7 +11,7 @@ config UML
select ARCH_HAS_KCOV
select ARCH_HAS_STRNCPY_FROM_USER
select ARCH_HAS_STRNLEN_USER
- select ARCH_NO_PREEMPT
+ select ARCH_NO_PREEMPT_DYNAMIC
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_KASAN if X86_64
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
@@ -31,7 +31,8 @@ config UML
select TRACE_IRQFLAGS_SUPPORT
select TTY # Needed for line.c
select HAVE_ARCH_VMAP_STACK
- select HAVE_RUST if X86_64
+ select HAVE_RUST
+ select ARCH_HAS_UBSAN
config MMU
bool
@@ -48,12 +49,13 @@ config NO_IOMEM
config UML_IOMEM_EMULATION
bool
select INDIRECT_IOMEM
+ select HAS_IOPORT
select GENERIC_PCI_IOMAP
select GENERIC_IOMAP
select NO_GENERIC_PCI_IOPORT_MAP
config NO_IOPORT_MAP
- def_bool y
+ def_bool !UML_IOMEM_EMULATION
config ISA
bool
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 34957dcb88b9..00b63bac5eff 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -20,7 +20,7 @@ endif
ARCH_DIR := arch/um
# We require bash because the vmlinux link and loader script cpp use bash
# features.
-SHELL := /bin/bash
+SHELL := bash
MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/shared/skas
diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig
index b94b2618e7d8..ede40a160c5e 100644
--- a/arch/um/drivers/Kconfig
+++ b/arch/um/drivers/Kconfig
@@ -297,26 +297,6 @@ config UML_NET_MCAST
If unsure, say N.
-config UML_NET_PCAP
- bool "pcap transport (obsolete)"
- depends on UML_NET
- depends on !MODVERSIONS
- 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
- UML act as a network monitor for the host. You must have libcap
- installed in order to build the pcap transport into UML.
-
- For more information, see
- <http://user-mode-linux.sourceforge.net/old/networking.html> That site
- has examples of the UML command line to use to enable this option.
-
- NOTE: THIS TRANSPORT IS DEPRECATED AND WILL BE REMOVED SOON!!! Please
- migrate to UML_NET_VECTOR.
-
- If unsure, say N.
-
config UML_NET_SLIRP
bool "SLiRP transport (obsolete)"
depends on UML_NET
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 0e6af81096fd..57882e6bc215 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -20,14 +20,9 @@ harddog-objs := harddog_kern.o
harddog-builtin-$(CONFIG_UML_WATCHDOG) := harddog_user.o harddog_user_exp.o
rtc-objs := rtc_kern.o rtc_user.o
-LDFLAGS_pcap.o = $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libpcap.a)
-
LDFLAGS_vde.o = $(shell $(CC) $(CFLAGS) -print-file-name=libvdeplug.a)
-targets := pcap_kern.o pcap_user.o vde_kern.o vde_user.o
-
-$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
- $(LD) -r -dp -o $@ $^ $(ld_flags)
+targets := vde_kern.o vde_user.o
$(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o
$(LD) -r -dp -o $@ $^ $(ld_flags)
@@ -49,7 +44,6 @@ obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
obj-$(CONFIG_UML_NET_VECTOR) += vector.o
obj-$(CONFIG_UML_NET_VDE) += vde.o
obj-$(CONFIG_UML_NET_MCAST) += umcast.o
-obj-$(CONFIG_UML_NET_PCAP) += pcap.o
obj-$(CONFIG_UML_NET) += net.o
obj-$(CONFIG_MCONSOLE) += mconsole.o
obj-$(CONFIG_MMAPPER) += mmapper_kern.o
@@ -69,7 +63,7 @@ obj-$(CONFIG_UML_RTC) += rtc.o
obj-$(CONFIG_UML_PCI_OVER_VIRTIO) += virt-pci.o
# pcap_user.o must be added explicitly.
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o vector_user.o
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o vde_user.o vector_user.o
CFLAGS_null.o = -DDEV_NULL=$(DEV_NULL_PATH)
CFLAGS_xterm.o += '-DCONFIG_XTERM_CHAN_DEFAULT_EMULATOR="$(CONFIG_XTERM_CHAN_DEFAULT_EMULATOR)"'
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h
index e14b9cdf7a33..5a61db512ffb 100644
--- a/arch/um/drivers/chan.h
+++ b/arch/um/drivers/chan.h
@@ -22,7 +22,8 @@ struct chan {
unsigned int output:1;
unsigned int opened:1;
unsigned int enabled:1;
- int fd;
+ int fd_in;
+ int fd_out; /* only different to fd_in if blocking output is needed */
const struct chan_ops *ops;
void *data;
};
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 37538b4168da..e78a99816c86 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -81,6 +81,12 @@ static const struct chan_ops not_configged_ops = {
};
#endif /* CONFIG_NOCONFIG_CHAN */
+static inline bool need_output_blocking(void)
+{
+ return time_travel_mode == TT_MODE_INFCPU ||
+ time_travel_mode == TT_MODE_EXTERNAL;
+}
+
static int open_one_chan(struct chan *chan)
{
int fd, err;
@@ -96,15 +102,43 @@ static int open_one_chan(struct chan *chan)
return fd;
err = os_set_fd_block(fd, 0);
- if (err) {
- (*chan->ops->close)(fd, chan->data);
- return err;
- }
+ if (err)
+ goto out_close;
+
+ chan->fd_in = fd;
+ chan->fd_out = fd;
+
+ /*
+ * In time-travel modes infinite-CPU and external we need to guarantee
+ * that any writes to the output succeed immdiately from the point of
+ * the VM. The best way to do this is to put the FD in blocking mode
+ * and simply wait/retry until everything is written.
+ * As every write is guaranteed to complete, we also do not need to
+ * request an IRQ for the output.
+ *
+ * Note that input cannot happen in a time synchronized way. We permit
+ * it, but time passes very quickly if anything waits for a read.
+ */
+ if (chan->output && need_output_blocking()) {
+ err = os_dup_file(chan->fd_out);
+ if (err < 0)
+ goto out_close;
- chan->fd = fd;
+ chan->fd_out = err;
+
+ err = os_set_fd_block(chan->fd_out, 1);
+ if (err) {
+ os_close_file(chan->fd_out);
+ goto out_close;
+ }
+ }
chan->opened = 1;
return 0;
+
+out_close:
+ (*chan->ops->close)(fd, chan->data);
+ return err;
}
static int open_chan(struct list_head *chans)
@@ -125,7 +159,7 @@ static int open_chan(struct list_head *chans)
void chan_enable_winch(struct chan *chan, struct tty_port *port)
{
if (chan && chan->primary && chan->ops->winch)
- register_winch(chan->fd, port);
+ register_winch(chan->fd_in, port);
}
static void line_timer_cb(struct work_struct *work)
@@ -156,8 +190,9 @@ int enable_chan(struct line *line)
if (chan->enabled)
continue;
- err = line_setup_irq(chan->fd, chan->input, chan->output, line,
- chan);
+ err = line_setup_irq(chan->fd_in, chan->input,
+ chan->output && !need_output_blocking(),
+ line, chan);
if (err)
goto out_close;
@@ -196,7 +231,8 @@ void free_irqs(void)
if (chan->input && chan->enabled)
um_free_irq(chan->line->read_irq, chan);
- if (chan->output && chan->enabled)
+ if (chan->output && chan->enabled &&
+ !need_output_blocking())
um_free_irq(chan->line->write_irq, chan);
chan->enabled = 0;
}
@@ -216,15 +252,19 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
} else {
if (chan->input && chan->enabled)
um_free_irq(chan->line->read_irq, chan);
- if (chan->output && chan->enabled)
+ if (chan->output && chan->enabled &&
+ !need_output_blocking())
um_free_irq(chan->line->write_irq, chan);
chan->enabled = 0;
}
+ if (chan->fd_out != chan->fd_in)
+ os_close_file(chan->fd_out);
if (chan->ops->close != NULL)
- (*chan->ops->close)(chan->fd, chan->data);
+ (*chan->ops->close)(chan->fd_in, chan->data);
chan->opened = 0;
- chan->fd = -1;
+ chan->fd_in = -1;
+ chan->fd_out = -1;
}
void close_chan(struct line *line)
@@ -244,7 +284,7 @@ void close_chan(struct line *line)
void deactivate_chan(struct chan *chan, int irq)
{
if (chan && chan->enabled)
- deactivate_fd(chan->fd, irq);
+ deactivate_fd(chan->fd_in, irq);
}
int write_chan(struct chan *chan, const u8 *buf, size_t len, int write_irq)
@@ -254,7 +294,7 @@ int write_chan(struct chan *chan, const u8 *buf, size_t len, int write_irq)
if (len == 0 || !chan || !chan->ops->write)
return 0;
- n = chan->ops->write(chan->fd, buf, len, chan->data);
+ n = chan->ops->write(chan->fd_out, buf, len, chan->data);
if (chan->primary) {
ret = n;
}
@@ -268,7 +308,7 @@ int console_write_chan(struct chan *chan, const char *buf, int len)
if (!chan || !chan->ops->console_write)
return 0;
- n = chan->ops->console_write(chan->fd, buf, len);
+ n = chan->ops->console_write(chan->fd_out, buf, len);
if (chan->primary)
ret = n;
return ret;
@@ -296,14 +336,14 @@ int chan_window_size(struct line *line, unsigned short *rows_out,
if (chan && chan->primary) {
if (chan->ops->window_size == NULL)
return 0;
- return chan->ops->window_size(chan->fd, chan->data,
+ return chan->ops->window_size(chan->fd_in, chan->data,
rows_out, cols_out);
}
chan = line->chan_out;
if (chan && chan->primary) {
if (chan->ops->window_size == NULL)
return 0;
- return chan->ops->window_size(chan->fd, chan->data,
+ return chan->ops->window_size(chan->fd_in, chan->data,
rows_out, cols_out);
}
return 0;
@@ -319,7 +359,7 @@ static void free_one_chan(struct chan *chan)
(*chan->ops->free)(chan->data);
if (chan->primary && chan->output)
- ignore_sigio_fd(chan->fd);
+ ignore_sigio_fd(chan->fd_in);
kfree(chan);
}
@@ -478,7 +518,8 @@ static struct chan *parse_chan(struct line *line, char *str, int device,
.output = 0,
.opened = 0,
.enabled = 0,
- .fd = -1,
+ .fd_in = -1,
+ .fd_out = -1,
.ops = ops,
.data = data });
return chan;
@@ -549,7 +590,7 @@ void chan_interrupt(struct line *line, int irq)
schedule_delayed_work(&line->task, 1);
goto out;
}
- err = chan->ops->read(chan->fd, &c, chan->data);
+ err = chan->ops->read(chan->fd_in, &c, chan->data);
if (err > 0)
tty_insert_flip_char(port, c, TTY_NORMAL);
} while (err > 0);
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index ec04e47b9d79..a66e556012c4 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -23,7 +23,7 @@ int generic_read(int fd, __u8 *c_out, void *unused)
{
int n;
- n = read(fd, c_out, sizeof(*c_out));
+ CATCH_EINTR(n = read(fd, c_out, sizeof(*c_out)));
if (n > 0)
return n;
else if (n == 0)
@@ -37,11 +37,23 @@ int generic_read(int fd, __u8 *c_out, void *unused)
int generic_write(int fd, const __u8 *buf, size_t n, void *unused)
{
+ int written = 0;
int err;
- err = write(fd, buf, n);
- if (err > 0)
- return err;
+ /* The FD may be in blocking mode, as such, need to retry short writes,
+ * they may have been interrupted by a signal.
+ */
+ do {
+ errno = 0;
+ err = write(fd, buf + written, n - written);
+ if (err > 0) {
+ written += err;
+ continue;
+ }
+ } while (err < 0 && errno == EINTR);
+
+ if (written > 0)
+ return written;
else if (errno == EAGAIN)
return 0;
else if (err == 0)
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 60d1c6cab8a9..99a7144b229f 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -49,6 +49,7 @@
#include "mconsole.h"
#include "harddog.h"
+MODULE_DESCRIPTION("UML hardware watchdog");
MODULE_LICENSE("GPL");
static DEFINE_MUTEX(harddog_mutex);
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index ffc5cb92fa36..43d8959cc746 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -383,6 +383,7 @@ int setup_one_line(struct line *lines, int n, char *init,
parse_chan_pair(NULL, line, n, opts, error_out);
err = 0;
}
+ *error_out = "configured as 'none'";
} else {
char *new = kstrdup(init, GFP_KERNEL);
if (!new) {
@@ -406,6 +407,7 @@ int setup_one_line(struct line *lines, int n, char *init,
}
}
if (err) {
+ *error_out = "failed to parse channel pair";
line->init_str = NULL;
line->valid = 0;
kfree(new);
@@ -676,24 +678,26 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
goto cleanup;
}
- *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
- .fd = fd,
+ *winch = ((struct winch) { .fd = fd,
.tty_fd = tty_fd,
.pid = pid,
.port = port,
.stack = stack });
+ spin_lock(&winch_handler_lock);
+ list_add(&winch->list, &winch_handlers);
+ spin_unlock(&winch_handler_lock);
+
if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
IRQF_SHARED, "winch", winch) < 0) {
printk(KERN_ERR "register_winch_irq - failed to register "
"IRQ\n");
+ spin_lock(&winch_handler_lock);
+ list_del(&winch->list);
+ spin_unlock(&winch_handler_lock);
goto out_free;
}
- spin_lock(&winch_handler_lock);
- list_add(&winch->list, &winch_handlers);
- spin_unlock(&winch_handler_lock);
-
return;
out_free:
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
deleted file mode 100644
index 25ee2c97ca21..000000000000
--- a/arch/um/drivers/pcap_kern.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <net_kern.h>
-#include "pcap_user.h"
-
-struct pcap_init {
- char *host_if;
- int promisc;
- int optimize;
- char *filter;
-};
-
-void pcap_init_kern(struct net_device *dev, void *data)
-{
- struct uml_net_private *pri;
- struct pcap_data *ppri;
- struct pcap_init *init = data;
-
- pri = netdev_priv(dev);
- ppri = (struct pcap_data *) pri->user;
- ppri->host_if = init->host_if;
- ppri->promisc = init->promisc;
- ppri->optimize = init->optimize;
- ppri->filter = init->filter;
-
- printk("pcap backend, host interface %s\n", ppri->host_if);
-}
-
-static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
- return pcap_user_read(fd, skb_mac_header(skb),
- skb->dev->mtu + ETH_HEADER_OTHER,
- (struct pcap_data *) &lp->user);
-}
-
-static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
- return -EPERM;
-}
-
-static const struct net_kern_info pcap_kern_info = {
- .init = pcap_init_kern,
- .protocol = eth_protocol,
- .read = pcap_read,
- .write = pcap_write,
-};
-
-int pcap_setup(char *str, char **mac_out, void *data)
-{
- struct pcap_init *init = data;
- char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
- int i;
-
- *init = ((struct pcap_init)
- { .host_if = "eth0",
- .promisc = 1,
- .optimize = 0,
- .filter = NULL });
-
- remain = split_if_spec(str, &host_if, &init->filter,
- &options[0], &options[1], mac_out, NULL);
- if (remain != NULL) {
- printk(KERN_ERR "pcap_setup - Extra garbage on "
- "specification : '%s'\n", remain);
- return 0;
- }
-
- if (host_if != NULL)
- init->host_if = host_if;
-
- for (i = 0; i < ARRAY_SIZE(options); i++) {
- if (options[i] == NULL)
- continue;
- if (!strcmp(options[i], "promisc"))
- init->promisc = 1;
- else if (!strcmp(options[i], "nopromisc"))
- init->promisc = 0;
- else if (!strcmp(options[i], "optimize"))
- init->optimize = 1;
- else if (!strcmp(options[i], "nooptimize"))
- init->optimize = 0;
- else {
- printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
- options[i]);
- return 0;
- }
- }
-
- return 1;
-}
-
-static struct transport pcap_transport = {
- .list = LIST_HEAD_INIT(pcap_transport.list),
- .name = "pcap",
- .setup = pcap_setup,
- .user = &pcap_user_info,
- .kern = &pcap_kern_info,
- .private_size = sizeof(struct pcap_data),
- .setup_size = sizeof(struct pcap_init),
-};
-
-static int register_pcap(void)
-{
- register_transport(&pcap_transport);
- return 0;
-}
-
-late_initcall(register_pcap);
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
deleted file mode 100644
index 52ddda3e3b10..000000000000
--- a/arch/um/drivers/pcap_user.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#include <errno.h>
-#include <pcap.h>
-#include <string.h>
-#include <asm/types.h>
-#include <net_user.h>
-#include "pcap_user.h"
-#include <um_malloc.h>
-
-#define PCAP_FD(p) (*(int *)(p))
-
-static int pcap_user_init(void *data, void *dev)
-{
- struct pcap_data *pri = data;
- pcap_t *p;
- char errors[PCAP_ERRBUF_SIZE];
-
- p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
- pri->promisc, 0, errors);
- if (p == NULL) {
- printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
- "'%s'\n", errors);
- return -EINVAL;
- }
-
- pri->dev = dev;
- pri->pcap = p;
- return 0;
-}
-
-static int pcap_user_open(void *data)
-{
- struct pcap_data *pri = data;
- __u32 netmask;
- int err;
-
- if (pri->pcap == NULL)
- return -ENODEV;
-
- if (pri->filter != NULL) {
- err = dev_netmask(pri->dev, &netmask);
- if (err < 0) {
- 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_user_open : kmalloc failed\n");
- return -ENOMEM;
- }
-
- err = pcap_compile(pri->pcap,
- (struct bpf_program *) pri->compiled,
- pri->filter, pri->optimize, netmask);
- if (err < 0) {
- 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_user_open : pcap_setfilter "
- "failed - '%s'\n", pcap_geterr(pri->pcap));
- goto out;
- }
- }
-
- return PCAP_FD(pri->pcap);
-
- out:
- kfree(pri->compiled);
- return -EIO;
-}
-
-static void pcap_remove(void *data)
-{
- struct pcap_data *pri = data;
-
- if (pri->compiled != NULL)
- pcap_freecode(pri->compiled);
-
- if (pri->pcap != NULL)
- pcap_close(pri->pcap);
-}
-
-struct pcap_handler_data {
- char *buffer;
- int len;
-};
-
-static void handler(u_char *data, const struct pcap_pkthdr *header,
- const u_char *packet)
-{
- int len;
-
- struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
-
- len = hdata->len < header->caplen ? hdata->len : header->caplen;
- memcpy(hdata->buffer, packet, len);
- hdata->len = len;
-}
-
-int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
-{
- struct pcap_handler_data hdata = ((struct pcap_handler_data)
- { .buffer = buffer,
- .len = len });
- int n;
-
- n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
- if (n < 0) {
- printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
- pcap_geterr(pri->pcap));
- return -EIO;
- }
- else if (n == 0)
- return 0;
- return hdata.len;
-}
-
-const struct net_user_info pcap_user_info = {
- .init = pcap_user_init,
- .open = pcap_user_open,
- .close = NULL,
- .remove = pcap_remove,
- .add_address = NULL,
- .delete_address = NULL,
- .mtu = ETH_MAX_PACKET,
- .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
-};
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
deleted file mode 100644
index 216246f5f09b..000000000000
--- a/arch/um/drivers/pcap_user.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- */
-
-#include <net_user.h>
-
-struct pcap_data {
- char *host_if;
- int promisc;
- int optimize;
- char *filter;
- void *compiled;
- void *pcap;
- void *dev;
-};
-
-extern const struct net_user_info pcap_user_info;
-
-extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
-
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index c52b3ff3c092..a4508470df78 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -45,15 +45,17 @@ struct connection {
static irqreturn_t pipe_interrupt(int irq, void *data)
{
struct connection *conn = data;
- int fd;
+ int n_fds = 1, fd = -1;
+ ssize_t ret;
- fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
- if (fd < 0) {
- if (fd == -EAGAIN)
+ ret = os_rcv_fd_msg(conn->socket[0], &fd, n_fds, &conn->helper_pid,
+ sizeof(conn->helper_pid));
+ if (ret != sizeof(conn->helper_pid)) {
+ if (ret == -EAGAIN)
return IRQ_NONE;
- printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
- -fd);
+ printk(KERN_ERR "pipe_interrupt : os_rcv_fd_msg returned %zd\n",
+ ret);
os_close_file(conn->fd);
}
diff --git a/arch/um/drivers/rtc_kern.c b/arch/um/drivers/rtc_kern.c
index 97ceb205cfe6..3a1582219c4b 100644
--- a/arch/um/drivers/rtc_kern.c
+++ b/arch/um/drivers/rtc_kern.c
@@ -168,16 +168,15 @@ cleanup:
return err;
}
-static int uml_rtc_remove(struct platform_device *pdev)
+static void uml_rtc_remove(struct platform_device *pdev)
{
device_init_wakeup(&pdev->dev, 0);
uml_rtc_cleanup();
- return 0;
}
static struct platform_driver uml_rtc_driver = {
.probe = uml_rtc_probe,
- .remove = uml_rtc_remove,
+ .remove_new = uml_rtc_remove,
.driver = {
.name = "uml-rtc",
},
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 8f633e2e5f3d..97228aa080cb 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -49,7 +49,7 @@ static int slirp_tramp(char **argv, int fd)
static int slirp_open(void *data)
{
struct slirp_data *pri = data;
- int fds[2], pid, err;
+ int fds[2], err;
err = os_pipe(fds, 1, 1);
if (err)
@@ -60,7 +60,6 @@ static int slirp_open(void *data)
printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err);
goto out;
}
- pid = err;
pri->slave = fds[1];
pri->slip.pos = 0;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 63fc062add70..7f28ec1929dc 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -36,7 +36,6 @@
#include <linux/vmalloc.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
-#include <asm/tlbflush.h>
#include <kern_util.h>
#include "mconsole_kern.h"
#include <init.h>
@@ -106,7 +105,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
#define DRIVER_NAME "uml-blkdev"
static DEFINE_MUTEX(ubd_lock);
-static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */
static int ubd_ioctl(struct block_device *bdev, blk_mode_t mode,
unsigned int cmd, unsigned long arg);
@@ -447,43 +445,31 @@ static int bulk_req_safe_read(
return n;
}
-/* Called without dev->lock held, and only in interrupt context. */
-static void ubd_handler(void)
+static void ubd_end_request(struct io_thread_req *io_req)
{
- int n;
- int count;
-
- while(1){
- n = bulk_req_safe_read(
- thread_fd,
- irq_req_buffer,
- &irq_remainder,
- &irq_remainder_size,
- UBD_REQ_BUFFER_SIZE
- );
- if (n < 0) {
- if(n == -EAGAIN)
- break;
- printk(KERN_ERR "spurious interrupt in ubd_handler, "
- "err = %d\n", -n);
- return;
- }
- for (count = 0; count < n/sizeof(struct io_thread_req *); count++) {
- struct io_thread_req *io_req = (*irq_req_buffer)[count];
-
- if ((io_req->error == BLK_STS_NOTSUPP) && (req_op(io_req->req) == REQ_OP_DISCARD)) {
- blk_queue_max_discard_sectors(io_req->req->q, 0);
- blk_queue_max_write_zeroes_sectors(io_req->req->q, 0);
- }
- blk_mq_end_request(io_req->req, io_req->error);
- kfree(io_req);
- }
+ if (io_req->error == BLK_STS_NOTSUPP) {
+ if (req_op(io_req->req) == REQ_OP_DISCARD)
+ blk_queue_disable_discard(io_req->req->q);
+ else if (req_op(io_req->req) == REQ_OP_WRITE_ZEROES)
+ blk_queue_disable_write_zeroes(io_req->req->q);
}
+ blk_mq_end_request(io_req->req, io_req->error);
+ kfree(io_req);
}
static irqreturn_t ubd_intr(int irq, void *dev)
{
- ubd_handler();
+ int len, i;
+
+ while ((len = bulk_req_safe_read(thread_fd, irq_req_buffer,
+ &irq_remainder, &irq_remainder_size,
+ UBD_REQ_BUFFER_SIZE)) >= 0) {
+ for (i = 0; i < len / sizeof(struct io_thread_req *); i++)
+ ubd_end_request((*irq_req_buffer)[i]);
+ }
+
+ if (len < 0 && len != -EAGAIN)
+ pr_err("spurious interrupt in %s, err = %d\n", __func__, len);
return IRQ_HANDLED;
}
@@ -771,7 +757,6 @@ static int ubd_open_dev(struct ubd *ubd_dev)
printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
goto error;
}
- flush_tlb_kernel_vm();
err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
ubd_dev->cow.bitmap_offset,
@@ -847,6 +832,7 @@ static int ubd_add(int n, char **error_out)
struct queue_limits lim = {
.max_segments = MAX_SG,
.seg_boundary_mask = PAGE_SIZE - 1,
+ .features = BLK_FEAT_WRITE_CACHE,
};
struct gendisk *disk;
int err = 0;
@@ -893,8 +879,6 @@ static int ubd_add(int n, char **error_out)
goto out_cleanup_tags;
}
- blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
- blk_queue_write_cache(disk->queue, true, false);
disk->major = UBD_MAJOR;
disk->first_minor = n << UBD_SHIFT;
disk->minors = 1 << UBD_SHIFT;
@@ -1092,7 +1076,7 @@ static int __init ubd_init(void)
if (irq_req_buffer == NULL) {
printk(KERN_ERR "Failed to initialize ubd buffering\n");
- return -1;
+ return -ENOMEM;
}
io_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE,
sizeof(struct io_thread_req *),
@@ -1103,7 +1087,7 @@ static int __init ubd_init(void)
if (io_req_buffer == NULL) {
printk(KERN_ERR "Failed to initialize ubd buffering\n");
- return -1;
+ return -ENOMEM;
}
platform_driver_register(&ubd_driver);
mutex_lock(&ubd_lock);
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index a1afe414ce48..b4f8b8e60564 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -23,7 +23,7 @@
#include <os.h>
#include <poll.h>
-struct pollfd kernel_pollfd;
+static struct pollfd kernel_pollfd;
int start_io_thread(unsigned long sp, int *fd_out)
{
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index dc2feae789cb..2d473282ab51 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -141,7 +141,7 @@ static bool get_bpf_flash(struct arglist *def)
if (allow != NULL) {
if (kstrtoul(allow, 10, &result) == 0)
- return (allow > 0);
+ return result > 0;
}
return false;
}
@@ -712,11 +712,9 @@ static struct vector_device *find_device(int n)
static int vector_parse(char *str, int *index_out, char **str_out,
char **error_out)
{
- int n, len, err;
+ int n, err;
char *start = str;
- len = strlen(str);
-
while ((*str != ':') && (strlen(str) > 1))
str++;
if (*str != ':') {
@@ -1117,11 +1115,12 @@ static int irq_rr;
static int vector_net_close(struct net_device *dev)
{
struct vector_private *vp = netdev_priv(dev);
- unsigned long flags;
netif_stop_queue(dev);
del_timer(&vp->tl);
+ vp->opened = false;
+
if (vp->fds == NULL)
return 0;
@@ -1160,10 +1159,7 @@ static int vector_net_close(struct net_device *dev)
destroy_queue(vp->tx_queue);
kfree(vp->fds);
vp->fds = NULL;
- spin_lock_irqsave(&vp->lock, flags);
- vp->opened = false;
vp->in_error = false;
- spin_unlock_irqrestore(&vp->lock, flags);
return 0;
}
@@ -1205,17 +1201,12 @@ static void vector_reset_tx(struct work_struct *work)
static int vector_net_open(struct net_device *dev)
{
struct vector_private *vp = netdev_priv(dev);
- unsigned long flags;
int err = -EINVAL;
struct vector_device *vdevice;
- spin_lock_irqsave(&vp->lock, flags);
- if (vp->opened) {
- spin_unlock_irqrestore(&vp->lock, flags);
+ if (vp->opened)
return -ENXIO;
- }
vp->opened = true;
- spin_unlock_irqrestore(&vp->lock, flags);
vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));
@@ -1389,8 +1380,6 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
return -1;
}
- spin_lock(&vp->lock);
-
if (vp->bpf != NULL) {
if (vp->opened)
uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
@@ -1419,15 +1408,12 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
if (vp->opened)
result = uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
- spin_unlock(&vp->lock);
-
return result;
free_buffer:
release_firmware(fw);
flash_fail:
- spin_unlock(&vp->lock);
if (vp->bpf != NULL)
kfree(vp->bpf->filter);
kfree(vp->bpf);
@@ -1633,7 +1619,6 @@ static void vector_eth_configure(
INIT_WORK(&vp->reset_tx, vector_reset_tx);
timer_setup(&vp->tl, vector_timer_expire, 0);
- spin_lock_init(&vp->lock);
/* FIXME */
dev->netdev_ops = &vector_netdev_ops;
diff --git a/arch/um/drivers/vector_kern.h b/arch/um/drivers/vector_kern.h
index 2a1fa8e0f3e1..806df551be0b 100644
--- a/arch/um/drivers/vector_kern.h
+++ b/arch/um/drivers/vector_kern.h
@@ -71,7 +71,6 @@ struct vector_estats {
struct vector_private {
struct list_head list;
- spinlock_t lock;
struct net_device *dev;
struct napi_struct napi ____cacheline_aligned;
diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
index 97a37c062997..6100819681b5 100644
--- a/arch/um/drivers/virt-pci.c
+++ b/arch/um/drivers/virt-pci.c
@@ -567,12 +567,14 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
static int um_pci_init_vqs(struct um_pci_device *dev)
{
+ struct virtqueue_info vqs_info[] = {
+ { "cmd", um_pci_cmd_vq_cb },
+ { "irq", um_pci_irq_vq_cb },
+ };
struct virtqueue *vqs[2];
- static const char *const names[2] = { "cmd", "irq" };
- vq_callback_t *cbs[2] = { um_pci_cmd_vq_cb, um_pci_irq_vq_cb };
int err, i;
- err = virtio_find_vqs(dev->vdev, 2, vqs, cbs, names, NULL);
+ err = virtio_find_vqs(dev->vdev, 2, vqs, vqs_info, NULL);
if (err)
return err;
@@ -752,7 +754,6 @@ MODULE_DEVICE_TABLE(virtio, id_table);
static struct virtio_driver um_pci_virtio_driver = {
.driver.name = "virtio-pci",
- .driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = um_pci_virtio_probe,
.remove = um_pci_virtio_remove,
@@ -987,6 +988,11 @@ static struct resource virt_platform_resource = {
static int __init um_pci_init(void)
{
+ struct irq_domain_info inner_domain_info = {
+ .size = MAX_MSI_VECTORS,
+ .hwirq_max = MAX_MSI_VECTORS,
+ .ops = &um_pci_inner_domain_ops,
+ };
int err, i;
WARN_ON(logic_iomem_add_region(&virt_cfgspace_resource,
@@ -1016,11 +1022,10 @@ static int __init um_pci_init(void)
goto free;
}
- um_pci_inner_domain = __irq_domain_add(um_pci_fwnode, MAX_MSI_VECTORS,
- MAX_MSI_VECTORS, 0,
- &um_pci_inner_domain_ops, NULL);
- if (!um_pci_inner_domain) {
- err = -ENOMEM;
+ inner_domain_info.fwnode = um_pci_fwnode;
+ um_pci_inner_domain = irq_domain_instantiate(&inner_domain_info);
+ if (IS_ERR(um_pci_inner_domain)) {
+ err = PTR_ERR(um_pci_inner_domain);
goto free;
}
@@ -1057,7 +1062,7 @@ static int __init um_pci_init(void)
goto free;
return 0;
free:
- if (um_pci_inner_domain)
+ if (!IS_ERR_OR_NULL(um_pci_inner_domain))
irq_domain_remove(um_pci_inner_domain);
if (um_pci_fwnode)
irq_domain_free_fwnode(um_pci_fwnode);
diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 8adca2000e51..2b6e701776b6 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -1014,8 +1014,8 @@ error_kzalloc:
}
static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
- struct virtqueue *vqs[], vq_callback_t *callbacks[],
- const char * const names[], const bool *ctx,
+ struct virtqueue *vqs[],
+ struct virtqueue_info vqs_info[],
struct irq_affinity *desc)
{
struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
@@ -1031,13 +1031,15 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
return rc;
for (i = 0; i < nvqs; ++i) {
- if (!names[i]) {
+ struct virtqueue_info *vqi = &vqs_info[i];
+
+ if (!vqi->name) {
vqs[i] = NULL;
continue;
}
- vqs[i] = vu_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
- ctx ? ctx[i] : false);
+ vqs[i] = vu_setup_vq(vdev, queue_idx++, vqi->callback,
+ vqi->name, vqi->ctx);
if (IS_ERR(vqs[i])) {
rc = PTR_ERR(vqs[i]);
goto error_setup;
@@ -1241,12 +1243,11 @@ error_free:
return rc;
}
-static int virtio_uml_remove(struct platform_device *pdev)
+static void virtio_uml_remove(struct platform_device *pdev)
{
struct virtio_uml_device *vu_dev = platform_get_drvdata(pdev);
unregister_virtio_device(&vu_dev->vdev);
- return 0;
}
/* Command line device list */
@@ -1445,7 +1446,7 @@ static int virtio_uml_resume(struct platform_device *pdev)
static struct platform_driver virtio_uml_driver = {
.probe = virtio_uml_probe,
- .remove = virtio_uml_remove,
+ .remove_new = virtio_uml_remove,
.driver = {
.name = "virtio-uml",
.of_match_table = virtio_uml_match,
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 6918de5e2956..e4316c7981e8 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -156,7 +156,7 @@ static int xterm_open(int input, int output, int primary, void *d,
new = xterm_fd(fd, &data->helper_pid);
if (new < 0) {
err = new;
- printk(UM_KERN_ERR "xterm_open : os_rcv_fd failed, err = %d\n",
+ printk(UM_KERN_ERR "xterm_open : xterm_fd failed, err = %d\n",
-err);
goto out_kill;
}
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index 8011e51993d5..3971252cb1a6 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -21,12 +21,19 @@ struct xterm_wait {
static irqreturn_t xterm_interrupt(int irq, void *data)
{
struct xterm_wait *xterm = data;
- int fd;
+ int fd = -1, n_fds = 1;
+ ssize_t ret;
- fd = os_rcv_fd(xterm->fd, &xterm->pid);
- if (fd == -EAGAIN)
+ ret = os_rcv_fd_msg(xterm->fd, &fd, n_fds,
+ &xterm->pid, sizeof(xterm->pid));
+ if (ret == -EAGAIN)
return IRQ_NONE;
+ if (ret < 0)
+ fd = ret;
+ else if (ret != sizeof(xterm->pid))
+ fd = -EMSGSIZE;
+
xterm->new_fd = fd;
complete(&xterm->ready);
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index b2d834a29f3a..18f902da8e99 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-generic-y += bpf_perf_event.h
generic-y += bug.h
generic-y += compat.h
generic-y += current.h
@@ -8,7 +7,6 @@ generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += extable.h
-generic-y += fb.h
generic-y += ftrace.h
generic-y += hw_irq.h
generic-y += irq_regs.h
@@ -21,6 +19,7 @@ generic-y += param.h
generic-y += parport.h
generic-y += percpu.h
generic-y += preempt.h
+generic-y += runtime-const.h
generic-y += softirq_stack.h
generic-y += switch_to.h
generic-y += topology.h
@@ -28,3 +27,4 @@ generic-y += trace_clock.h
generic-y += kprobes.h
generic-y += mm_hooks.h
generic-y += vga.h
+generic-y += video.h
diff --git a/arch/um/include/asm/bpf_perf_event.h b/arch/um/include/asm/bpf_perf_event.h
new file mode 100644
index 000000000000..287221342d2c
--- /dev/null
+++ b/arch/um/include/asm/bpf_perf_event.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * asm-generic/bpf_perf_event.h is part of the uapi headers, but since
+ * arch/um has no uapi of its on, we can't use the "generic-y"
+ * Kbuild rule to generate the wrapper
+ */
+
+#include <asm-generic/bpf_perf_event.h>
diff --git a/arch/um/include/asm/cpufeature.h b/arch/um/include/asm/cpufeature.h
index 66fe06db872f..1eb8b834fbec 100644
--- a/arch/um/include/asm/cpufeature.h
+++ b/arch/um/include/asm/cpufeature.h
@@ -38,8 +38,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define this_cpu_has(bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
- x86_this_cpu_test_bit(bit, \
- (unsigned long __percpu *)&cpu_info.x86_capability))
+ x86_this_cpu_test_bit(bit, cpu_info.x86_capability))
/*
* This macro is for detection of features which need kernel
diff --git a/arch/um/include/asm/kasan.h b/arch/um/include/asm/kasan.h
index 0d6547f4ec85..f97bb1f7b851 100644
--- a/arch/um/include/asm/kasan.h
+++ b/arch/um/include/asm/kasan.h
@@ -24,7 +24,6 @@
#ifdef CONFIG_KASAN
void kasan_init(void);
-void kasan_map_memory(void *start, unsigned long len);
extern int kasan_um_is_ready;
#ifdef CONFIG_STATIC_LINK
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
index a7555e43ed14..a3eaca41ff61 100644
--- a/arch/um/include/asm/mmu.h
+++ b/arch/um/include/asm/mmu.h
@@ -7,17 +7,13 @@
#define __ARCH_UM_MMU_H
#include <mm_id.h>
-#include <asm/mm_context.h>
typedef struct mm_context {
struct mm_id id;
- struct uml_arch_mm_context arch;
-} mm_context_t;
-
-extern void __switch_mm(struct mm_id * mm_idp);
-/* Avoid tangled inclusion with asm/ldt.h */
-extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm);
-extern void free_ldt(struct mm_context *mm);
+ /* Address range in need of a TLB sync */
+ unsigned long sync_tlb_range_from;
+ unsigned long sync_tlb_range_to;
+} mm_context_t;
#endif
diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h
index 68e2eb9cfb47..23dcc914d44e 100644
--- a/arch/um/include/asm/mmu_context.h
+++ b/arch/um/include/asm/mmu_context.h
@@ -13,8 +13,6 @@
#include <asm/mm_hooks.h>
#include <asm/mmu.h>
-extern void force_flush_all(void);
-
#define activate_mm activate_mm
static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
{
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index e1ece21dbe3f..5bb397b65efb 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -244,6 +244,38 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
#define PFN_PTE_SHIFT PAGE_SHIFT
+static inline void um_tlb_mark_sync(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ if (!mm->context.sync_tlb_range_to) {
+ mm->context.sync_tlb_range_from = start;
+ mm->context.sync_tlb_range_to = end;
+ } else {
+ if (start < mm->context.sync_tlb_range_from)
+ mm->context.sync_tlb_range_from = start;
+ if (end > mm->context.sync_tlb_range_to)
+ mm->context.sync_tlb_range_to = end;
+ }
+}
+
+#define set_ptes set_ptes
+static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, int nr)
+{
+ /* Basically the default implementation */
+ size_t length = nr * PAGE_SIZE;
+
+ for (;;) {
+ set_pte(ptep, pte);
+ if (--nr == 0)
+ break;
+ ptep++;
+ pte = __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
+ }
+
+ um_tlb_mark_sync(mm, addr, addr + length);
+}
+
#define __HAVE_ARCH_PTE_SAME
static inline int pte_same(pte_t pte_a, pte_t pte_b)
{
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index 6c3779541845..5a7c05275aa7 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -94,7 +94,6 @@ extern struct cpuinfo_um boot_cpu_data;
#define current_cpu_data boot_cpu_data
#define cache_line_size() (boot_cpu_data.cache_alignment)
-extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
extern unsigned long __get_wchan(struct task_struct *p);
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index adf91ef553ae..4696f24d1492 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -36,6 +36,9 @@ extern long subarch_ptrace(struct task_struct *child, long request,
extern unsigned long getreg(struct task_struct *child, int regno);
extern int putreg(struct task_struct *child, int regno, unsigned long value);
+extern int poke_user(struct task_struct *child, long addr, long data);
+extern int peek_user(struct task_struct *child, long addr, long data);
+
extern int arch_set_tls(struct task_struct *new, unsigned long tls);
extern void clear_flushed_tls(struct task_struct *task);
extern int syscall_trace_enter(struct pt_regs *regs);
diff --git a/arch/um/include/asm/tlbflush.h b/arch/um/include/asm/tlbflush.h
index a5bda890390d..db997976b6ea 100644
--- a/arch/um/include/asm/tlbflush.h
+++ b/arch/um/include/asm/tlbflush.h
@@ -9,23 +9,51 @@
#include <linux/mm.h>
/*
- * TLB flushing:
+ * In UML, we need to sync the TLB over by using mmap/munmap/mprotect syscalls
+ * from the process handling the MM (which can be the kernel itself).
+ *
+ * To track updates, we can hook into set_ptes and flush_tlb_*. With set_ptes
+ * we catch all PTE transitions where memory that was unusable becomes usable.
+ * While with flush_tlb_* we can track any memory that becomes unusable and
+ * even if a higher layer of the page table was modified.
+ *
+ * So, we simply track updates using both methods and mark the memory area to
+ * be synced later on. The only special case is that flush_tlb_kern_* needs to
+ * be executed immediately as there is no good synchronization point in that
+ * case. In contrast, in the set_ptes case we can wait for the next kernel
+ * segfault before we do the synchornization.
*
- * - flush_tlb() flushes the current mm struct TLBs
* - flush_tlb_all() flushes all processes TLBs
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
- * - flush_tlb_kernel_vm() flushes the kernel vm area
* - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
*/
+extern int um_tlb_sync(struct mm_struct *mm);
+
extern void flush_tlb_all(void);
extern void flush_tlb_mm(struct mm_struct *mm);
-extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end);
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long address);
-extern void flush_tlb_kernel_vm(void);
-extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
-extern void __flush_tlb_one(unsigned long addr);
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long address)
+{
+ um_tlb_mark_sync(vma->vm_mm, address, address + PAGE_SIZE);
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ um_tlb_mark_sync(vma->vm_mm, start, end);
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start,
+ unsigned long end)
+{
+ um_tlb_mark_sync(&init_mm, start, end);
+
+ /* Kernel needs to be synced immediately */
+ um_tlb_sync(&init_mm);
+}
#endif
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index 9ec3015bc5e2..06292fca5a4d 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -23,7 +23,7 @@
#define STUB_START stub_start
#define STUB_CODE STUB_START
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
-#define STUB_DATA_PAGES 1 /* must be a power of two */
+#define STUB_DATA_PAGES 2 /* must be a power of two */
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
#ifndef __ASSEMBLY__
@@ -31,7 +31,6 @@
#include <sysdep/ptrace.h>
struct cpu_task {
- int pid;
void *task;
};
diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h
index 96195483fbd0..579ed946a3a9 100644
--- a/arch/um/include/shared/common-offsets.h
+++ b/arch/um/include/shared/common-offsets.h
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* for use by sys-$SUBARCH/kernel-offsets.c */
-#include <stub-data.h>
DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
@@ -30,7 +29,3 @@ DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT);
DEFINE(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT, CONFIG_UML_TIME_TRAVEL_SUPPORT);
#endif
-/* for stub */
-DEFINE(UML_STUB_FIELD_OFFSET, offsetof(struct stub_data, offset));
-DEFINE(UML_STUB_FIELD_CHILD_ERR, offsetof(struct stub_data, child_err));
-DEFINE(UML_STUB_FIELD_FD, offsetof(struct stub_data, fd));
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h
index 789b83013f35..d8ffd2db168e 100644
--- a/arch/um/include/shared/kern_util.h
+++ b/arch/um/include/shared/kern_util.h
@@ -13,7 +13,6 @@ struct siginfo;
extern int uml_exitcode;
-extern int ncpus;
extern int kmalloc_ok;
#define UML_ROUND_UP(addr) \
@@ -41,6 +40,7 @@ extern void uml_pm_wake(void);
extern int start_uml(void);
extern void paging_init(void);
+extern int parse_iomem(char *str, int *add);
extern void uml_cleanup(void);
extern void do_uml_exitcalls(void);
@@ -66,4 +66,6 @@ extern void fatal_sigsegv(void) __attribute__ ((noreturn));
void um_idle_sleep(void);
+void kasan_map_memory(void *start, size_t len);
+
#endif
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index aff8906304ea..9a039d6f1f74 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -163,8 +163,10 @@ extern int os_set_fd_block(int fd, int blocking);
extern int os_accept_connection(int fd);
extern int os_create_unix_socket(const char *file, int len, int close_on_exec);
extern int os_shutdown_socket(int fd, int r, int w);
+extern int os_dup_file(int fd);
extern void os_close_file(int fd);
-extern int os_rcv_fd(int fd, int *helper_pid_out);
+ssize_t os_rcv_fd_msg(int fd, int *fds, unsigned int n_fds,
+ void *data, size_t data_len);
extern int os_connect_socket(const char *name);
extern int os_file_type(char *file);
extern int os_file_mode(const char *file, struct openflags *mode_out);
@@ -179,6 +181,8 @@ extern int os_eventfd(unsigned int initval, int flags);
extern int os_sendmsg_fds(int fd, const void *buf, unsigned int len,
const int *fds, unsigned int fds_num);
int os_poll(unsigned int n, const int *fds);
+void *os_mmap_rw_shared(int fd, size_t size);
+void *os_mremap_rw_shared(void *old_addr, size_t old_size, size_t new_size);
/* start_up.c */
extern void os_early_checks(void);
@@ -191,6 +195,9 @@ extern void get_host_cpu_features(
/* mem.c */
extern int create_mem_file(unsigned long long len);
+/* tlb.c */
+extern void report_enomem(void);
+
/* process.c */
extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid);
@@ -268,24 +275,20 @@ extern long long os_persistent_clock_emulation(void);
extern long long os_nsecs(void);
/* skas/mem.c */
-extern long run_syscall_stub(struct mm_id * mm_idp,
- int syscall, unsigned long *args, long expected,
- void **addr, int done);
-extern long syscall_stub_data(struct mm_id * mm_idp,
- unsigned long *data, int data_count,
- void **addr, void **stub_addr);
-extern int map(struct mm_id * mm_idp, unsigned long virt,
- unsigned long len, int prot, int phys_fd,
- unsigned long long offset, int done, void **data);
-extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
- int done, void **data);
-extern int protect(struct mm_id * mm_idp, unsigned long addr,
- unsigned long len, unsigned int prot, int done, void **data);
+int syscall_stub_flush(struct mm_id *mm_idp);
+struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp);
+void syscall_stub_dump_error(struct mm_id *mm_idp);
+
+int map(struct mm_id *mm_idp, unsigned long virt,
+ unsigned long len, int prot, int phys_fd,
+ unsigned long long offset);
+int unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len);
+int protect(struct mm_id *mm_idp, unsigned long addr,
+ unsigned long len, unsigned int prot);
/* skas/process.c */
extern int is_skas_winch(int pid, int fd, void *data);
extern int start_userspace(unsigned long stub_stack);
-extern int copy_context_skas0(unsigned long stack, int pid);
extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs);
extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
extern void switch_threads(jmp_buf *me, jmp_buf *you);
diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h
index e82e203f5f41..1e76ba40feba 100644
--- a/arch/um/include/shared/skas/mm_id.h
+++ b/arch/um/include/shared/skas/mm_id.h
@@ -12,7 +12,9 @@ struct mm_id {
int pid;
} u;
unsigned long stack;
- int kill;
+ int syscall_data_len;
};
+void __switch_mm(struct mm_id *mm_idp);
+
#endif
diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h
index c93d2cbc8f32..ebaa116de30b 100644
--- a/arch/um/include/shared/skas/skas.h
+++ b/arch/um/include/shared/skas/skas.h
@@ -15,5 +15,7 @@ extern void new_thread_handler(void);
extern void handle_syscall(struct uml_pt_regs *regs);
extern long execute_syscall_skas(void *r);
extern unsigned long current_stub_stack(void);
+extern struct mm_id *current_mm_id(void);
+extern void current_mm_sync(void);
#endif
diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h
index 5e3ade3fb38b..2b6b44759dfa 100644
--- a/arch/um/include/shared/skas/stub-data.h
+++ b/arch/um/include/shared/skas/stub-data.h
@@ -8,10 +8,42 @@
#ifndef __STUB_DATA_H
#define __STUB_DATA_H
+#include <linux/compiler_types.h>
+#include <as-layout.h>
+#include <sysdep/tls.h>
+
+#define STUB_NEXT_SYSCALL(s) \
+ ((struct stub_syscall *) (((unsigned long) s) + (s)->cmd_len))
+
+enum stub_syscall_type {
+ STUB_SYSCALL_UNSET = 0,
+ STUB_SYSCALL_MMAP,
+ STUB_SYSCALL_MUNMAP,
+ STUB_SYSCALL_MPROTECT,
+};
+
+struct stub_syscall {
+ struct {
+ unsigned long addr;
+ unsigned long length;
+ unsigned long offset;
+ int fd;
+ int prot;
+ } mem;
+
+ enum stub_syscall_type syscall;
+};
+
struct stub_data {
unsigned long offset;
- int fd;
- long parent_err, child_err;
+ long err, child_err;
+
+ int syscall_data_len;
+ /* 128 leaves enough room for additional fields in the struct */
+ struct stub_syscall syscall_data[(UM_KERN_PAGE_SIZE - 128) / sizeof(struct stub_syscall)] __aligned(16);
+
+ /* Stack for our signal handlers and for calling into . */
+ unsigned char sigstack[UM_KERN_PAGE_SIZE] __aligned(UM_KERN_PAGE_SIZE);
};
#endif
diff --git a/arch/um/include/shared/timetravel.h b/arch/um/include/shared/timetravel.h
index e5c3d69f1b69..c8db2f213dba 100644
--- a/arch/um/include/shared/timetravel.h
+++ b/arch/um/include/shared/timetravel.h
@@ -15,8 +15,17 @@ enum time_travel_mode {
#if defined(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT) || \
defined(CONFIG_UML_TIME_TRAVEL_SUPPORT)
extern enum time_travel_mode time_travel_mode;
+extern int time_travel_should_print_bc_msg;
#else
#define time_travel_mode TT_MODE_OFF
+#define time_travel_should_print_bc_msg 0
#endif /* (UML_)CONFIG_UML_TIME_TRAVEL_SUPPORT */
+void _time_travel_print_bc_msg(void);
+static inline void time_travel_print_bc_msg(void)
+{
+ if (time_travel_should_print_bc_msg)
+ _time_travel_print_bc_msg();
+}
+
#endif /* _UM_TIME_TRAVEL_H_ */
diff --git a/arch/um/include/shared/um_malloc.h b/arch/um/include/shared/um_malloc.h
index 13da93284c2c..815dd03e8707 100644
--- a/arch/um/include/shared/um_malloc.h
+++ b/arch/um/include/shared/um_malloc.h
@@ -11,8 +11,9 @@
extern void *uml_kmalloc(int size, int flags);
extern void kfree(const void *ptr);
-extern void *vmalloc(unsigned long size);
-extern void vfree(void *ptr);
+extern void *vmalloc_noprof(unsigned long size);
+#define vmalloc(...) vmalloc_noprof(__VA_ARGS__)
+extern void vfree(const void *ptr);
#endif /* __UM_MALLOC_H__ */
diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h
index 326e52450e41..bbab79c0c074 100644
--- a/arch/um/include/shared/user.h
+++ b/arch/um/include/shared/user.h
@@ -42,11 +42,19 @@ extern void panic(const char *fmt, ...)
#define printk(...) _printk(__VA_ARGS__)
extern int _printk(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
+extern void print_hex_dump(const char *level, const char *prefix_str,
+ int prefix_type, int rowsize, int groupsize,
+ const void *buf, size_t len, _Bool ascii);
#else
static inline int printk(const char *fmt, ...)
{
return 0;
}
+static inline void print_hex_dump(const char *level, const char *prefix_str,
+ int prefix_type, int rowsize, int groupsize,
+ const void *buf, size_t len, _Bool ascii)
+{
+}
#endif
extern int in_aton(char *str);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 811188be954c..f8567b933ffa 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -47,7 +47,7 @@ $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE
$(call if_changed,quote2)
quiet_cmd_mkcapflags = MKCAP $@
- cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/../../x86/kernel/cpu/mkcapflags.sh $@ $^
+ cmd_mkcapflags = $(CONFIG_SHELL) $(src)/../../x86/kernel/cpu/mkcapflags.sh $@ $^
cpufeature = $(src)/../../x86/include/asm/cpufeatures.h
vmxfeature = $(src)/../../x86/include/asm/vmxfeatures.h
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 827a0d3fa589..2c15bb2c104c 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -22,17 +22,8 @@
void flush_thread(void)
{
- void *data = NULL;
- int ret;
-
arch_flush_thread(&current->thread.arch);
- ret = unmap(&current->mm->context.id, 0, TASK_SIZE, 1, &data);
- if (ret) {
- printk(KERN_ERR "%s - clearing address space failed, err = %d\n",
- __func__, ret);
- force_sig(SIGKILL);
- }
get_safe_registers(current_pt_regs()->regs.gp,
current_pt_regs()->regs.fp);
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 635d44606bfe..534e91797f89 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -37,7 +37,7 @@ struct irq_reg {
bool pending;
bool wakeup;
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
- bool pending_on_resume;
+ bool pending_event;
void (*timetravel_handler)(int, int, void *,
struct time_travel_event *);
struct time_travel_event event;
@@ -56,6 +56,9 @@ static DEFINE_SPINLOCK(irq_lock);
static LIST_HEAD(active_fds);
static DECLARE_BITMAP(irqs_allocated, UM_LAST_SIGNAL_IRQ);
static bool irqs_suspended;
+#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
+static bool irqs_pending;
+#endif
static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs)
{
@@ -84,9 +87,12 @@ static void irq_event_handler(struct time_travel_event *ev)
{
struct irq_reg *reg = container_of(ev, struct irq_reg, event);
- /* do nothing if suspended - just to cause a wakeup */
- if (irqs_suspended)
+ /* do nothing if suspended; just cause a wakeup and mark as pending */
+ if (irqs_suspended) {
+ irqs_pending = true;
+ reg->pending_event = true;
return;
+ }
generic_handle_irq(reg->irq);
}
@@ -110,16 +116,47 @@ static bool irq_do_timetravel_handler(struct irq_entry *entry,
if (!reg->event.pending)
return false;
- if (irqs_suspended)
- reg->pending_on_resume = true;
return true;
}
+
+static void irq_do_pending_events(bool timetravel_handlers_only)
+{
+ struct irq_entry *entry;
+
+ if (!irqs_pending || timetravel_handlers_only)
+ return;
+
+ irqs_pending = false;
+
+ list_for_each_entry(entry, &active_fds, list) {
+ enum um_irq_type t;
+
+ for (t = 0; t < NUM_IRQ_TYPES; t++) {
+ struct irq_reg *reg = &entry->reg[t];
+
+ /*
+ * Any timetravel_handler was invoked already, just
+ * directly run the IRQ.
+ */
+ if (reg->pending_event) {
+ irq_enter();
+ generic_handle_irq(reg->irq);
+ irq_exit();
+ reg->pending_event = false;
+ }
+ }
+ }
+}
#else
static bool irq_do_timetravel_handler(struct irq_entry *entry,
enum um_irq_type t)
{
return false;
}
+
+static void irq_do_pending_events(bool timetravel_handlers_only)
+{
+}
#endif
static void sigio_reg_handler(int idx, struct irq_entry *entry, enum um_irq_type t,
@@ -145,6 +182,8 @@ static void sigio_reg_handler(int idx, struct irq_entry *entry, enum um_irq_type
*/
if (timetravel_handlers_only) {
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
+ reg->pending_event = true;
+ irqs_pending = true;
mark_sigio_pending();
#endif
return;
@@ -162,6 +201,10 @@ static void _sigio_handler(struct uml_pt_regs *regs,
if (timetravel_handlers_only && !um_irq_timetravel_handler_used())
return;
+ /* Flush out pending events that were ignored due to time-travel. */
+ if (!irqs_suspended)
+ irq_do_pending_events(timetravel_handlers_only);
+
while (1) {
/* This is now lockless - epoll keeps back-referencesto the irqs
* which have trigger it so there is no need to walk the irq
@@ -195,7 +238,9 @@ static void _sigio_handler(struct uml_pt_regs *regs,
void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
+ preempt_disable();
_sigio_handler(regs, irqs_suspended);
+ preempt_enable();
}
static struct irq_entry *get_irq_entry_by_fd(int fd)
@@ -543,30 +588,7 @@ void um_irqs_resume(void)
unsigned long flags;
- local_irq_save(flags);
-#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
- /*
- * We don't need to lock anything here since we're in resume
- * and nothing else is running, but have disabled IRQs so we
- * don't try anything else with the interrupt list from there.
- */
- list_for_each_entry(entry, &active_fds, list) {
- enum um_irq_type t;
-
- for (t = 0; t < NUM_IRQ_TYPES; t++) {
- struct irq_reg *reg = &entry->reg[t];
-
- if (reg->pending_on_resume) {
- irq_enter();
- generic_handle_irq(reg->irq);
- irq_exit();
- reg->pending_on_resume = false;
- }
- }
- }
-#endif
-
- spin_lock(&irq_lock);
+ spin_lock_irqsave(&irq_lock, flags);
list_for_each_entry(entry, &active_fds, list) {
if (entry->suspended) {
int err = os_set_fd_async(entry->fd);
diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
index 427dd5a61a38..4382cf02a6d1 100644
--- a/arch/um/kernel/kmsg_dump.c
+++ b/arch/um/kernel/kmsg_dump.c
@@ -57,7 +57,7 @@ static struct kmsg_dumper kmsg_dumper = {
.dump = kmsg_dumper_stdout
};
-int __init kmsg_dumper_stdout_init(void)
+static int __init kmsg_dumper_stdout_init(void)
{
return kmsg_dump_register(&kmsg_dumper);
}
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 3a85bde3e173..f2fb77da08cf 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -33,7 +33,7 @@ EXPORT_SYMBOL(os_shutdown_socket);
EXPORT_SYMBOL(os_create_unix_socket);
EXPORT_SYMBOL(os_connect_socket);
EXPORT_SYMBOL(os_accept_connection);
-EXPORT_SYMBOL(os_rcv_fd);
+EXPORT_SYMBOL(os_rcv_fd_msg);
EXPORT_SYMBOL(run_helper);
EXPORT_SYMBOL(os_major);
EXPORT_SYMBOL(os_minor);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 38d5a71a579b..a5b4fe2ad931 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -12,12 +12,14 @@
#include <linux/slab.h>
#include <asm/fixmap.h>
#include <asm/page.h>
+#include <asm/pgalloc.h>
#include <as-layout.h>
#include <init.h>
#include <kern.h>
#include <kern_util.h>
#include <mem_user.h>
#include <os.h>
+#include <um_malloc.h>
#include <linux/sched/task.h>
#ifdef CONFIG_KASAN
@@ -71,7 +73,6 @@ void __init mem_init(void)
/* this will put all low memory onto the freelists */
memblock_free_all();
- max_low_pfn = totalram_pages();
max_pfn = max_low_pfn;
kmalloc_ok = 1;
}
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 91485119ae67..fb2adfb49945 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -12,6 +12,7 @@
#include <as-layout.h>
#include <init.h>
#include <kern.h>
+#include <kern_util.h>
#include <mem_user.h>
#include <os.h>
@@ -161,8 +162,6 @@ __uml_setup("mem=", uml_mem_setup,
" Example: mem=64M\n\n"
);
-extern int __init parse_iomem(char *str, int *add);
-
__uml_setup("iomem=", parse_iomem,
"iomem=<name>,<file>\n"
" Configure <file> as an IO memory region named <name>.\n\n"
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index ab95648e93e1..f36b63f53bab 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -15,6 +15,7 @@
#include <linux/proc_fs.h>
#include <linux/ptrace.h>
#include <linux/random.h>
+#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
@@ -26,6 +27,8 @@
#include <linux/resume_user_mode.h>
#include <asm/current.h>
#include <asm/mmu_context.h>
+#include <asm/switch_to.h>
+#include <asm/exec.h>
#include <linux/uaccess.h>
#include <as-layout.h>
#include <kern_util.h>
@@ -40,24 +43,7 @@
* cares about its entry, so it's OK if another processor is modifying its
* entry.
*/
-struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
-
-static inline int external_pid(void)
-{
- /* FIXME: Need to look up userspace_pid by cpu */
- return userspace_pid[0];
-}
-
-int pid_to_processor_id(int pid)
-{
- int i;
-
- for (i = 0; i < ncpus; i++) {
- if (cpu_tasks[i].pid == pid)
- return i;
- }
- return -1;
-}
+struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { NULL } };
void free_stack(unsigned long stack, int order)
{
@@ -78,13 +64,10 @@ unsigned long alloc_stack(int order, int atomic)
static inline void set_current(struct task_struct *task)
{
- cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
- { external_pid(), task });
+ cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) { task });
}
-extern void arch_switch_to(struct task_struct *to);
-
-void *__switch_to(struct task_struct *from, struct task_struct *to)
+struct task_struct *__switch_to(struct task_struct *from, struct task_struct *to)
{
to->thread.prev_sched = from;
set_current(to);
@@ -119,7 +102,7 @@ int get_current_pid(void)
*/
void new_thread_handler(void)
{
- int (*fn)(void *), n;
+ int (*fn)(void *);
void *arg;
if (current->thread.prev_sched != NULL)
@@ -132,15 +115,13 @@ void new_thread_handler(void)
/*
* callback returns only if the kernel thread execs a process
*/
- n = fn(arg);
+ fn(arg);
userspace(&current->thread.regs.regs, current_thread_info()->aux_fp_regs);
}
/* Called magically, see new_thread_handler above */
-void fork_handler(void)
+static void fork_handler(void)
{
- force_flush_all();
-
schedule_tail(current->thread.prev_sched);
/*
@@ -216,7 +197,6 @@ void um_idle_sleep(void)
void arch_cpu_idle(void)
{
- cpu_tasks[current_thread_info()->cpu].pid = os_getpid();
um_idle_sleep();
}
@@ -250,88 +230,11 @@ char *uml_strdup(const char *string)
}
EXPORT_SYMBOL(uml_strdup);
-int copy_to_user_proc(void __user *to, void *from, int size)
-{
- return copy_to_user(to, from, size);
-}
-
int copy_from_user_proc(void *to, void __user *from, int size)
{
return copy_from_user(to, from, size);
}
-int clear_user_proc(void __user *buf, int size)
-{
- return clear_user(buf, size);
-}
-
-static atomic_t using_sysemu = ATOMIC_INIT(0);
-int sysemu_supported;
-
-void set_using_sysemu(int value)
-{
- if (value > sysemu_supported)
- return;
- atomic_set(&using_sysemu, value);
-}
-
-int get_using_sysemu(void)
-{
- return atomic_read(&using_sysemu);
-}
-
-static int sysemu_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", get_using_sysemu());
- return 0;
-}
-
-static int sysemu_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, sysemu_proc_show, NULL);
-}
-
-static ssize_t sysemu_proc_write(struct file *file, const char __user *buf,
- size_t count, loff_t *pos)
-{
- char tmp[2];
-
- if (copy_from_user(tmp, buf, 1))
- return -EFAULT;
-
- if (tmp[0] >= '0' && tmp[0] <= '2')
- set_using_sysemu(tmp[0] - '0');
- /* We use the first char, but pretend to write everything */
- return count;
-}
-
-static const struct proc_ops sysemu_proc_ops = {
- .proc_open = sysemu_proc_open,
- .proc_read = seq_read,
- .proc_lseek = seq_lseek,
- .proc_release = single_release,
- .proc_write = sysemu_proc_write,
-};
-
-int __init make_proc_sysemu(void)
-{
- struct proc_dir_entry *ent;
- if (!sysemu_supported)
- return 0;
-
- ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_ops);
-
- if (ent == NULL)
- {
- printk(KERN_WARNING "Failed to register /proc/sysemu\n");
- return 0;
- }
-
- return 0;
-}
-
-late_initcall(make_proc_sysemu);
-
int singlestepping(void)
{
return test_thread_flag(TIF_SINGLESTEP);
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 6600a2782796..2124624b7817 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -35,9 +35,6 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
-extern int peek_user(struct task_struct * child, long addr, long data);
-extern int poke_user(struct task_struct * child, long addr, long data);
-
long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 48c0610d506e..3736bca626ba 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/oom.h>
+#include <linux/reboot.h>
#include <kern_util.h>
#include <os.h>
#include <skas.h>
@@ -58,3 +59,18 @@ void machine_halt(void)
{
machine_power_off();
}
+
+static int sys_power_off_handler(struct sys_off_data *data)
+{
+ machine_power_off();
+ return 0;
+}
+
+static int register_power_off(void)
+{
+ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+ SYS_OFF_PRIO_DEFAULT,
+ sys_power_off_handler, NULL);
+ return 0;
+}
+__initcall(register_power_off);
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index f93972a25765..6f86d53e3d69 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -3,15 +3,14 @@
# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
#
-obj-y := clone.o mmu.o process.o syscall.o uaccess.o
+obj-y := stub.o mmu.o process.o syscall.o uaccess.o
-# clone.o is in the stub, so it can't be built with profiling
+# stub.o is in the stub, so it can't be built with profiling
# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
# disable it
-CFLAGS_clone.o := $(CFLAGS_NO_HARDENING)
-UNPROFILE_OBJS := clone.o
-
+CFLAGS_stub.o := $(CFLAGS_NO_HARDENING)
+UNPROFILE_OBJS := stub.o
KCOV_INSTRUMENT := n
include $(srctree)/arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
deleted file mode 100644
index 62435187dda4..000000000000
--- a/arch/um/kernel/skas/clone.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
- * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#include <signal.h>
-#include <sched.h>
-#include <asm/unistd.h>
-#include <sys/time.h>
-#include <as-layout.h>
-#include <ptrace_user.h>
-#include <stub-data.h>
-#include <sysdep/stub.h>
-
-/*
- * This is in a separate file because it needs to be compiled with any
- * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
- *
- * Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize
- * on some systems.
- */
-
-void __attribute__ ((__section__ (".__syscall_stub")))
-stub_clone_handler(void)
-{
- struct stub_data *data = get_stub_data();
- long err;
-
- err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
- (unsigned long)data +
- STUB_DATA_PAGES * UM_KERN_PAGE_SIZE / 2);
- if (err) {
- data->parent_err = err;
- goto done;
- }
-
- err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
- if (err) {
- data->child_err = err;
- goto done;
- }
-
- remap_stack_and_trap();
-
- done:
- trap_myself();
-}
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 656fe16c9b63..47f98d87ea3c 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -10,14 +10,18 @@
#include <asm/pgalloc.h>
#include <asm/sections.h>
+#include <asm/mmu_context.h>
#include <as-layout.h>
#include <os.h>
#include <skas.h>
+#include <stub-data.h>
+
+/* Ensure the stub_data struct covers the allocated area */
+static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
int init_new_context(struct task_struct *task, struct mm_struct *mm)
{
- struct mm_context *from_mm = NULL;
- struct mm_context *to_mm = &mm->context;
+ struct mm_id *new_id = &mm->context.id;
unsigned long stack = 0;
int ret = -ENOMEM;
@@ -25,34 +29,46 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
if (stack == 0)
goto out;
- to_mm->id.stack = stack;
- if (current->mm != NULL && current->mm != &init_mm)
- from_mm = &current->mm->context;
+ new_id->stack = stack;
block_signals_trace();
- if (from_mm)
- to_mm->id.u.pid = copy_context_skas0(stack,
- from_mm->id.u.pid);
- else to_mm->id.u.pid = start_userspace(stack);
+ new_id->u.pid = start_userspace(stack);
unblock_signals_trace();
- if (to_mm->id.u.pid < 0) {
- ret = to_mm->id.u.pid;
+ if (new_id->u.pid < 0) {
+ ret = new_id->u.pid;
goto out_free;
}
- ret = init_new_ldt(to_mm, from_mm);
- if (ret < 0) {
- printk(KERN_ERR "init_new_context_skas - init_ldt"
- " failed, errno = %d\n", ret);
- goto out_free;
- }
+ /*
+ * Ensure the new MM is clean and nothing unwanted is mapped.
+ *
+ * TODO: We should clear the memory up to STUB_START to ensure there is
+ * nothing mapped there, i.e. we (currently) have:
+ *
+ * |- user memory -|- unused -|- stub -|- unused -|
+ * ^ TASK_SIZE ^ STUB_START
+ *
+ * Meaning we have two unused areas where we may still have valid
+ * mappings from our internal clone(). That isn't really a problem as
+ * userspace is not going to access them, but it is definitely not
+ * correct.
+ *
+ * However, we are "lucky" and if rseq is configured, then on 32 bit
+ * it will fall into the first empty range while on 64 bit it is going
+ * to use an anonymous mapping in the second range. As such, things
+ * continue to work for now as long as we don't start unmapping these
+ * areas.
+ *
+ * Change this to STUB_START once we have a clean userspace.
+ */
+ unmap(new_id, 0, TASK_SIZE);
return 0;
out_free:
- if (to_mm->id.stack != 0)
- free_pages(to_mm->id.stack, ilog2(STUB_DATA_PAGES));
+ if (new_id->stack != 0)
+ free_pages(new_id->stack, ilog2(STUB_DATA_PAGES));
out:
return ret;
}
@@ -75,5 +91,4 @@ void destroy_context(struct mm_struct *mm)
os_kill_ptraced_process(mmu->id.u.pid, 1);
free_pages(mmu->id.stack, ilog2(STUB_DATA_PAGES));
- free_ldt(mmu);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index f2ac134c9752..5f9c1c5f36e2 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -8,21 +8,20 @@
#include <linux/sched/task_stack.h>
#include <linux/sched/task.h>
+#include <asm/tlbflush.h>
+
#include <as-layout.h>
#include <kern.h>
#include <os.h>
#include <skas.h>
+#include <kern_util.h>
extern void start_kernel(void);
static int __init start_kernel_proc(void *unused)
{
- int pid;
-
block_signals_trace();
- pid = os_getpid();
- cpu_tasks[0].pid = pid;
cpu_tasks[0].task = current;
start_kernel();
@@ -53,3 +52,19 @@ unsigned long current_stub_stack(void)
return current->mm->context.id.stack;
}
+
+struct mm_id *current_mm_id(void)
+{
+ if (current->mm == NULL)
+ return NULL;
+
+ return &current->mm->context.id;
+}
+
+void current_mm_sync(void)
+{
+ if (current->mm == NULL)
+ return;
+
+ um_tlb_sync(current->mm);
+}
diff --git a/arch/um/kernel/skas/stub.c b/arch/um/kernel/skas/stub.c
new file mode 100644
index 000000000000..5d52ffa682dc
--- /dev/null
+++ b/arch/um/kernel/skas/stub.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Benjamin Berg <benjamin@sipsolutions.net>
+ */
+
+#include <sysdep/stub.h>
+
+static __always_inline int syscall_handler(struct stub_data *d)
+{
+ int i;
+ unsigned long res;
+
+ for (i = 0; i < d->syscall_data_len; i++) {
+ struct stub_syscall *sc = &d->syscall_data[i];
+
+ switch (sc->syscall) {
+ case STUB_SYSCALL_MMAP:
+ res = stub_syscall6(STUB_MMAP_NR,
+ sc->mem.addr, sc->mem.length,
+ sc->mem.prot,
+ MAP_SHARED | MAP_FIXED,
+ sc->mem.fd, sc->mem.offset);
+ if (res != sc->mem.addr) {
+ d->err = res;
+ d->syscall_data_len = i;
+ return -1;
+ }
+ break;
+ case STUB_SYSCALL_MUNMAP:
+ res = stub_syscall2(__NR_munmap,
+ sc->mem.addr, sc->mem.length);
+ if (res) {
+ d->err = res;
+ d->syscall_data_len = i;
+ return -1;
+ }
+ break;
+ case STUB_SYSCALL_MPROTECT:
+ res = stub_syscall3(__NR_mprotect,
+ sc->mem.addr, sc->mem.length,
+ sc->mem.prot);
+ if (res) {
+ d->err = res;
+ d->syscall_data_len = i;
+ return -1;
+ }
+ break;
+ default:
+ d->err = -95; /* EOPNOTSUPP */
+ d->syscall_data_len = i;
+ return -1;
+ }
+ }
+
+ d->err = 0;
+ d->syscall_data_len = 0;
+
+ return 0;
+}
+
+void __section(".__syscall_stub")
+stub_syscall_handler(void)
+{
+ struct stub_data *d = get_stub_data();
+
+ syscall_handler(d);
+
+ trap_myself();
+}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 3e270da6b6f6..47b9f5e63566 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -19,6 +19,7 @@
#include <asm/param.h>
#include <kern_util.h>
#include <os.h>
+#include <linux/delay.h>
#include <linux/time-internal.h>
#include <linux/um_timetravel.h>
#include <shared/init.h>
@@ -30,6 +31,7 @@ EXPORT_SYMBOL_GPL(time_travel_mode);
static bool time_travel_start_set;
static unsigned long long time_travel_start;
static unsigned long long time_travel_time;
+static unsigned long long time_travel_shm_offset;
static LIST_HEAD(time_travel_events);
static LIST_HEAD(time_travel_irqs);
static unsigned long long time_travel_timer_interval;
@@ -39,8 +41,11 @@ static int time_travel_ext_fd = -1;
static unsigned int time_travel_ext_waiting;
static bool time_travel_ext_prev_request_valid;
static unsigned long long time_travel_ext_prev_request;
-static bool time_travel_ext_free_until_valid;
-static unsigned long long time_travel_ext_free_until;
+static unsigned long long *time_travel_ext_free_until;
+static unsigned long long _time_travel_ext_free_until;
+static u16 time_travel_shm_id;
+static struct um_timetravel_schedshm *time_travel_shm;
+static union um_timetravel_schedshm_client *time_travel_shm_client;
static void time_travel_set_time(unsigned long long ns)
{
@@ -57,8 +62,52 @@ enum time_travel_message_handling {
TTMH_IDLE,
TTMH_POLL,
TTMH_READ,
+ TTMH_READ_START_ACK,
};
+static u64 bc_message;
+int time_travel_should_print_bc_msg;
+
+void _time_travel_print_bc_msg(void)
+{
+ time_travel_should_print_bc_msg = 0;
+ printk(KERN_INFO "time-travel: received broadcast 0x%llx\n", bc_message);
+}
+
+static void time_travel_setup_shm(int fd, u16 id)
+{
+ u32 len;
+
+ time_travel_shm = os_mmap_rw_shared(fd, sizeof(*time_travel_shm));
+
+ if (!time_travel_shm)
+ goto out;
+
+ len = time_travel_shm->len;
+
+ if (time_travel_shm->version != UM_TIMETRAVEL_SCHEDSHM_VERSION ||
+ len < struct_size(time_travel_shm, clients, id + 1)) {
+ os_unmap_memory(time_travel_shm, sizeof(*time_travel_shm));
+ time_travel_shm = NULL;
+ goto out;
+ }
+
+ time_travel_shm = os_mremap_rw_shared(time_travel_shm,
+ sizeof(*time_travel_shm),
+ len);
+ if (!time_travel_shm)
+ goto out;
+
+ time_travel_shm_offset = time_travel_shm->current_time;
+ time_travel_shm_client = &time_travel_shm->clients[id];
+ time_travel_shm_client->capa |= UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE;
+ time_travel_shm_id = id;
+ /* always look at that free_until from now on */
+ time_travel_ext_free_until = &time_travel_shm->free_until;
+out:
+ os_close_file(fd);
+}
+
static void time_travel_handle_message(struct um_timetravel_msg *msg,
enum time_travel_message_handling mode)
{
@@ -79,7 +128,20 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg,
}
}
- ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg));
+ if (unlikely(mode == TTMH_READ_START_ACK)) {
+ int fd[UM_TIMETRAVEL_SHARED_MAX_FDS];
+
+ ret = os_rcv_fd_msg(time_travel_ext_fd, fd,
+ ARRAY_SIZE(fd), msg, sizeof(*msg));
+ if (ret == sizeof(*msg)) {
+ time_travel_setup_shm(fd[UM_TIMETRAVEL_SHARED_MEMFD],
+ msg->time & UM_TIMETRAVEL_START_ACK_ID);
+ /* we don't use the logging for now */
+ os_close_file(fd[UM_TIMETRAVEL_SHARED_LOGFD]);
+ }
+ } else {
+ ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg));
+ }
if (ret == 0)
panic("time-travel external link is broken\n");
@@ -95,10 +157,24 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg,
return;
case UM_TIMETRAVEL_RUN:
time_travel_set_time(msg->time);
+ if (time_travel_shm) {
+ /* no request right now since we're running */
+ time_travel_shm_client->flags &=
+ ~UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN;
+ /* no ack for shared memory RUN */
+ return;
+ }
break;
case UM_TIMETRAVEL_FREE_UNTIL:
- time_travel_ext_free_until_valid = true;
- time_travel_ext_free_until = msg->time;
+ /* not supposed to get this with shm, but ignore it */
+ if (time_travel_shm)
+ break;
+ time_travel_ext_free_until = &_time_travel_ext_free_until;
+ _time_travel_ext_free_until = msg->time;
+ break;
+ case UM_TIMETRAVEL_BROADCAST:
+ bc_message = msg->time;
+ time_travel_should_print_bc_msg = 1;
break;
}
@@ -135,8 +211,15 @@ static u64 time_travel_ext_req(u32 op, u64 time)
block_signals_hard();
os_write_file(time_travel_ext_fd, &msg, sizeof(msg));
+ /* no ACK expected for WAIT in shared memory mode */
+ if (msg.op == UM_TIMETRAVEL_WAIT && time_travel_shm)
+ goto done;
+
while (msg.op != UM_TIMETRAVEL_ACK)
- time_travel_handle_message(&msg, TTMH_READ);
+ time_travel_handle_message(&msg,
+ op == UM_TIMETRAVEL_START ?
+ TTMH_READ_START_ACK :
+ TTMH_READ);
if (msg.seq != mseq)
panic("time-travel: ACK message has different seqno! op=%d, seq=%d != %d time=%lld\n",
@@ -144,6 +227,7 @@ static u64 time_travel_ext_req(u32 op, u64 time)
if (op == UM_TIMETRAVEL_GET)
time_travel_set_time(msg.time);
+done:
unblock_signals_hard();
return msg.time;
@@ -179,13 +263,33 @@ static void time_travel_ext_update_request(unsigned long long time)
/*
* if we're running and are allowed to run past the request
* then we don't need to update it either
+ *
+ * Note for shm we ignore FREE_UNTIL messages and leave the pointer
+ * to shared memory, and for non-shm the offset is 0.
*/
- if (!time_travel_ext_waiting && time_travel_ext_free_until_valid &&
- time < time_travel_ext_free_until)
+ if (!time_travel_ext_waiting && time_travel_ext_free_until &&
+ time < (*time_travel_ext_free_until - time_travel_shm_offset))
return;
time_travel_ext_prev_request = time;
time_travel_ext_prev_request_valid = true;
+
+ if (time_travel_shm) {
+ union um_timetravel_schedshm_client *running;
+
+ running = &time_travel_shm->clients[time_travel_shm->running_id];
+
+ if (running->capa & UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE) {
+ time_travel_shm_client->flags |=
+ UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN;
+ time += time_travel_shm_offset;
+ time_travel_shm_client->req_time = time;
+ if (time < time_travel_shm->free_until)
+ time_travel_shm->free_until = time;
+ return;
+ }
+ }
+
time_travel_ext_req(UM_TIMETRAVEL_REQUEST, time);
}
@@ -193,6 +297,14 @@ void __time_travel_propagate_time(void)
{
static unsigned long long last_propagated;
+ if (time_travel_shm) {
+ if (time_travel_shm->running_id != time_travel_shm_id)
+ panic("time-travel: setting time while not running\n");
+ time_travel_shm->current_time = time_travel_time +
+ time_travel_shm_offset;
+ return;
+ }
+
if (last_propagated == time_travel_time)
return;
@@ -208,9 +320,12 @@ static bool time_travel_ext_request(unsigned long long time)
* If we received an external sync point ("free until") then we
* don't have to request/wait for anything until then, unless
* we're already waiting.
+ *
+ * Note for shm we ignore FREE_UNTIL messages and leave the pointer
+ * to shared memory, and for non-shm the offset is 0.
*/
- if (!time_travel_ext_waiting && time_travel_ext_free_until_valid &&
- time < time_travel_ext_free_until)
+ if (!time_travel_ext_waiting && time_travel_ext_free_until &&
+ time < (*time_travel_ext_free_until - time_travel_shm_offset))
return false;
time_travel_ext_update_request(time);
@@ -224,7 +339,8 @@ static void time_travel_ext_wait(bool idle)
};
time_travel_ext_prev_request_valid = false;
- time_travel_ext_free_until_valid = false;
+ if (!time_travel_shm)
+ time_travel_ext_free_until = NULL;
time_travel_ext_waiting++;
time_travel_ext_req(UM_TIMETRAVEL_WAIT, -1);
@@ -247,7 +363,11 @@ static void time_travel_ext_wait(bool idle)
static void time_travel_ext_get_time(void)
{
- time_travel_ext_req(UM_TIMETRAVEL_GET, -1);
+ if (time_travel_shm)
+ time_travel_set_time(time_travel_shm->current_time -
+ time_travel_shm_offset);
+ else
+ time_travel_ext_req(UM_TIMETRAVEL_GET, -1);
}
static void __time_travel_update_time(unsigned long long ns, bool idle)
@@ -319,7 +439,7 @@ void time_travel_add_event_rel(struct time_travel_event *e,
time_travel_add_event(e, time_travel_time + delay_ns);
}
-void time_travel_periodic_timer(struct time_travel_event *e)
+static void time_travel_periodic_timer(struct time_travel_event *e)
{
time_travel_add_event(&time_travel_timer_event,
time_travel_time + time_travel_timer_interval);
@@ -812,7 +932,7 @@ unsigned long calibrate_delay_is_known(void)
return 0;
}
-int setup_time_travel(char *str)
+static int setup_time_travel(char *str)
{
if (strcmp(str, "=inf-cpu") == 0) {
time_travel_mode = TT_MODE_INFCPU;
@@ -862,7 +982,7 @@ __uml_help(setup_time_travel,
"devices using it, assuming the device has the right capabilities.\n"
"The optional ID is a 64-bit integer that's sent to the central scheduler.\n");
-int setup_time_travel_start(char *str)
+static int setup_time_travel_start(char *str)
{
int err;
@@ -874,9 +994,49 @@ int setup_time_travel_start(char *str)
return 1;
}
-__setup("time-travel-start", setup_time_travel_start);
+__setup("time-travel-start=", setup_time_travel_start);
__uml_help(setup_time_travel_start,
-"time-travel-start=<seconds>\n"
+"time-travel-start=<nanoseconds>\n"
"Configure the UML instance's wall clock to start at this value rather than\n"
"the host's wall clock at the time of UML boot.\n");
+static struct kobject *bc_time_kobject;
+
+static ssize_t bc_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0x%llx", bc_message);
+}
+
+static ssize_t bc_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ u64 user_bc_message;
+
+ ret = kstrtou64(buf, 0, &user_bc_message);
+ if (ret)
+ return ret;
+
+ bc_message = user_bc_message;
+
+ time_travel_ext_req(UM_TIMETRAVEL_BROADCAST, bc_message);
+ pr_info("um: time: sent broadcast message: 0x%llx\n", bc_message);
+ return count;
+}
+
+static struct kobj_attribute bc_attribute = __ATTR(bc-message, 0660, bc_show, bc_store);
+
+static int __init um_bc_start(void)
+{
+ if (time_travel_mode != TT_MODE_EXTERNAL)
+ return 0;
+
+ bc_time_kobject = kobject_create_and_add("um-ext-time", kernel_kobj);
+ if (!bc_time_kobject)
+ return 0;
+
+ if (sysfs_create_file(bc_time_kobject, &bc_attribute.attr))
+ pr_debug("failed to create the bc file in /sys/kernel/um_time");
+
+ return 0;
+}
+late_initcall(um_bc_start);
#endif
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 7d050ab0f78a..44c6fc697f3a 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -8,215 +8,61 @@
#include <linux/sched/signal.h>
#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
#include <as-layout.h>
#include <mem_user.h>
#include <os.h>
#include <skas.h>
#include <kern_util.h>
-struct host_vm_change {
- struct host_vm_op {
- enum { NONE, MMAP, MUNMAP, MPROTECT } type;
- union {
- struct {
- unsigned long addr;
- unsigned long len;
- unsigned int prot;
- int fd;
- __u64 offset;
- } mmap;
- struct {
- unsigned long addr;
- unsigned long len;
- } munmap;
- struct {
- unsigned long addr;
- unsigned long len;
- unsigned int prot;
- } mprotect;
- } u;
- } ops[1];
- int userspace;
- int index;
- struct mm_struct *mm;
- void *data;
- int force;
+struct vm_ops {
+ struct mm_id *mm_idp;
+
+ int (*mmap)(struct mm_id *mm_idp,
+ unsigned long virt, unsigned long len, int prot,
+ int phys_fd, unsigned long long offset);
+ int (*unmap)(struct mm_id *mm_idp,
+ unsigned long virt, unsigned long len);
+ int (*mprotect)(struct mm_id *mm_idp,
+ unsigned long virt, unsigned long len,
+ unsigned int prot);
};
-#define INIT_HVC(mm, force, userspace) \
- ((struct host_vm_change) \
- { .ops = { { .type = NONE } }, \
- .mm = mm, \
- .data = NULL, \
- .userspace = userspace, \
- .index = 0, \
- .force = force })
-
-static void report_enomem(void)
+static int kern_map(struct mm_id *mm_idp,
+ unsigned long virt, unsigned long len, int prot,
+ int phys_fd, unsigned long long offset)
{
- printk(KERN_ERR "UML ran out of memory on the host side! "
- "This can happen due to a memory limitation or "
- "vm.max_map_count has been reached.\n");
-}
-
-static int do_ops(struct host_vm_change *hvc, int end,
- int finished)
-{
- struct host_vm_op *op;
- int i, ret = 0;
-
- for (i = 0; i < end && !ret; i++) {
- op = &hvc->ops[i];
- switch (op->type) {
- case MMAP:
- if (hvc->userspace)
- ret = map(&hvc->mm->context.id, op->u.mmap.addr,
- op->u.mmap.len, op->u.mmap.prot,
- op->u.mmap.fd,
- op->u.mmap.offset, finished,
- &hvc->data);
- else
- map_memory(op->u.mmap.addr, op->u.mmap.offset,
- op->u.mmap.len, 1, 1, 1);
- break;
- case MUNMAP:
- if (hvc->userspace)
- ret = unmap(&hvc->mm->context.id,
- op->u.munmap.addr,
- op->u.munmap.len, finished,
- &hvc->data);
- else
- ret = os_unmap_memory(
- (void *) op->u.munmap.addr,
- op->u.munmap.len);
-
- break;
- case MPROTECT:
- if (hvc->userspace)
- ret = protect(&hvc->mm->context.id,
- op->u.mprotect.addr,
- op->u.mprotect.len,
- op->u.mprotect.prot,
- finished, &hvc->data);
- else
- ret = os_protect_memory(
- (void *) op->u.mprotect.addr,
- op->u.mprotect.len,
- 1, 1, 1);
- break;
- default:
- printk(KERN_ERR "Unknown op type %d in do_ops\n",
- op->type);
- BUG();
- break;
- }
- }
-
- if (ret == -ENOMEM)
- report_enomem();
-
- return ret;
+ /* TODO: Why is executable needed to be always set in the kernel? */
+ return os_map_memory((void *)virt, phys_fd, offset, len,
+ prot & UM_PROT_READ, prot & UM_PROT_WRITE,
+ 1);
}
-static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
- unsigned int prot, struct host_vm_change *hvc)
+static int kern_unmap(struct mm_id *mm_idp,
+ unsigned long virt, unsigned long len)
{
- __u64 offset;
- struct host_vm_op *last;
- int fd = -1, ret = 0;
-
- if (hvc->userspace)
- fd = phys_mapping(phys, &offset);
- else
- offset = phys;
- if (hvc->index != 0) {
- last = &hvc->ops[hvc->index - 1];
- if ((last->type == MMAP) &&
- (last->u.mmap.addr + last->u.mmap.len == virt) &&
- (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) &&
- (last->u.mmap.offset + last->u.mmap.len == offset)) {
- last->u.mmap.len += len;
- return 0;
- }
- }
-
- if (hvc->index == ARRAY_SIZE(hvc->ops)) {
- ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
- hvc->index = 0;
- }
-
- hvc->ops[hvc->index++] = ((struct host_vm_op)
- { .type = MMAP,
- .u = { .mmap = { .addr = virt,
- .len = len,
- .prot = prot,
- .fd = fd,
- .offset = offset }
- } });
- return ret;
+ return os_unmap_memory((void *)virt, len);
}
-static int add_munmap(unsigned long addr, unsigned long len,
- struct host_vm_change *hvc)
+static int kern_mprotect(struct mm_id *mm_idp,
+ unsigned long virt, unsigned long len,
+ unsigned int prot)
{
- struct host_vm_op *last;
- int ret = 0;
-
- if (hvc->index != 0) {
- last = &hvc->ops[hvc->index - 1];
- if ((last->type == MUNMAP) &&
- (last->u.munmap.addr + last->u.mmap.len == addr)) {
- last->u.munmap.len += len;
- return 0;
- }
- }
-
- if (hvc->index == ARRAY_SIZE(hvc->ops)) {
- ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
- hvc->index = 0;
- }
-
- hvc->ops[hvc->index++] = ((struct host_vm_op)
- { .type = MUNMAP,
- .u = { .munmap = { .addr = addr,
- .len = len } } });
- return ret;
+ return os_protect_memory((void *)virt, len,
+ prot & UM_PROT_READ, prot & UM_PROT_WRITE,
+ 1);
}
-static int add_mprotect(unsigned long addr, unsigned long len,
- unsigned int prot, struct host_vm_change *hvc)
+void report_enomem(void)
{
- struct host_vm_op *last;
- int ret = 0;
-
- if (hvc->index != 0) {
- last = &hvc->ops[hvc->index - 1];
- if ((last->type == MPROTECT) &&
- (last->u.mprotect.addr + last->u.mprotect.len == addr) &&
- (last->u.mprotect.prot == prot)) {
- last->u.mprotect.len += len;
- return 0;
- }
- }
-
- if (hvc->index == ARRAY_SIZE(hvc->ops)) {
- ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
- hvc->index = 0;
- }
-
- hvc->ops[hvc->index++] = ((struct host_vm_op)
- { .type = MPROTECT,
- .u = { .mprotect = { .addr = addr,
- .len = len,
- .prot = prot } } });
- return ret;
+ printk(KERN_ERR "UML ran out of memory on the host side! "
+ "This can happen due to a memory limitation or "
+ "vm.max_map_count has been reached.\n");
}
-#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
-
static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
unsigned long end,
- struct host_vm_change *hvc)
+ struct vm_ops *ops)
{
pte_t *pte;
int r, w, x, prot, ret = 0;
@@ -234,15 +80,22 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
(x ? UM_PROT_EXEC : 0));
- if (hvc->force || pte_newpage(*pte)) {
+ if (pte_newpage(*pte)) {
if (pte_present(*pte)) {
- if (pte_newpage(*pte))
- ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
- PAGE_SIZE, prot, hvc);
+ if (pte_newpage(*pte)) {
+ __u64 offset;
+ unsigned long phys =
+ pte_val(*pte) & PAGE_MASK;
+ int fd = phys_mapping(phys, &offset);
+
+ ret = ops->mmap(ops->mm_idp, addr,
+ PAGE_SIZE, prot, fd,
+ offset);
+ }
} else
- ret = add_munmap(addr, PAGE_SIZE, hvc);
+ ret = ops->unmap(ops->mm_idp, addr, PAGE_SIZE);
} else if (pte_newprot(*pte))
- ret = add_mprotect(addr, PAGE_SIZE, prot, hvc);
+ ret = ops->mprotect(ops->mm_idp, addr, PAGE_SIZE, prot);
*pte = pte_mkuptodate(*pte);
} while (pte++, addr += PAGE_SIZE, ((addr < end) && !ret));
return ret;
@@ -250,7 +103,7 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
static inline int update_pmd_range(pud_t *pud, unsigned long addr,
unsigned long end,
- struct host_vm_change *hvc)
+ struct vm_ops *ops)
{
pmd_t *pmd;
unsigned long next;
@@ -260,19 +113,20 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr,
do {
next = pmd_addr_end(addr, end);
if (!pmd_present(*pmd)) {
- if (hvc->force || pmd_newpage(*pmd)) {
- ret = add_munmap(addr, next - addr, hvc);
+ if (pmd_newpage(*pmd)) {
+ ret = ops->unmap(ops->mm_idp, addr,
+ next - addr);
pmd_mkuptodate(*pmd);
}
}
- else ret = update_pte_range(pmd, addr, next, hvc);
+ else ret = update_pte_range(pmd, addr, next, ops);
} while (pmd++, addr = next, ((addr < end) && !ret));
return ret;
}
static inline int update_pud_range(p4d_t *p4d, unsigned long addr,
unsigned long end,
- struct host_vm_change *hvc)
+ struct vm_ops *ops)
{
pud_t *pud;
unsigned long next;
@@ -282,19 +136,20 @@ static inline int update_pud_range(p4d_t *p4d, unsigned long addr,
do {
next = pud_addr_end(addr, end);
if (!pud_present(*pud)) {
- if (hvc->force || pud_newpage(*pud)) {
- ret = add_munmap(addr, next - addr, hvc);
+ if (pud_newpage(*pud)) {
+ ret = ops->unmap(ops->mm_idp, addr,
+ next - addr);
pud_mkuptodate(*pud);
}
}
- else ret = update_pmd_range(pud, addr, next, hvc);
+ else ret = update_pmd_range(pud, addr, next, ops);
} while (pud++, addr = next, ((addr < end) && !ret));
return ret;
}
static inline int update_p4d_range(pgd_t *pgd, unsigned long addr,
unsigned long end,
- struct host_vm_change *hvc)
+ struct vm_ops *ops)
{
p4d_t *p4d;
unsigned long next;
@@ -304,227 +159,59 @@ static inline int update_p4d_range(pgd_t *pgd, unsigned long addr,
do {
next = p4d_addr_end(addr, end);
if (!p4d_present(*p4d)) {
- if (hvc->force || p4d_newpage(*p4d)) {
- ret = add_munmap(addr, next - addr, hvc);
+ if (p4d_newpage(*p4d)) {
+ ret = ops->unmap(ops->mm_idp, addr,
+ next - addr);
p4d_mkuptodate(*p4d);
}
} else
- ret = update_pud_range(p4d, addr, next, hvc);
+ ret = update_pud_range(p4d, addr, next, ops);
} while (p4d++, addr = next, ((addr < end) && !ret));
return ret;
}
-static void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force)
+int um_tlb_sync(struct mm_struct *mm)
{
pgd_t *pgd;
- struct host_vm_change hvc;
- unsigned long addr = start_addr, next;
- int ret = 0, userspace = 1;
+ struct vm_ops ops;
+ unsigned long addr = mm->context.sync_tlb_range_from, next;
+ int ret = 0;
+
+ if (mm->context.sync_tlb_range_to == 0)
+ return 0;
+
+ ops.mm_idp = &mm->context.id;
+ if (mm == &init_mm) {
+ ops.mmap = kern_map;
+ ops.unmap = kern_unmap;
+ ops.mprotect = kern_mprotect;
+ } else {
+ ops.mmap = map;
+ ops.unmap = unmap;
+ ops.mprotect = protect;
+ }
- hvc = INIT_HVC(mm, force, userspace);
pgd = pgd_offset(mm, addr);
do {
- next = pgd_addr_end(addr, end_addr);
+ next = pgd_addr_end(addr, mm->context.sync_tlb_range_to);
if (!pgd_present(*pgd)) {
- if (force || pgd_newpage(*pgd)) {
- ret = add_munmap(addr, next - addr, &hvc);
+ if (pgd_newpage(*pgd)) {
+ ret = ops.unmap(ops.mm_idp, addr,
+ next - addr);
pgd_mkuptodate(*pgd);
}
} else
- ret = update_p4d_range(pgd, addr, next, &hvc);
- } while (pgd++, addr = next, ((addr < end_addr) && !ret));
-
- if (!ret)
- ret = do_ops(&hvc, hvc.index, 1);
-
- /* This is not an else because ret is modified above */
- if (ret) {
- struct mm_id *mm_idp = &current->mm->context.id;
-
- printk(KERN_ERR "fix_range_common: failed, killing current "
- "process: %d\n", task_tgid_vnr(current));
- mm_idp->kill = 1;
- }
-}
-
-static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
-{
- struct mm_struct *mm;
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long addr, last;
- int updated = 0, err = 0, force = 0, userspace = 0;
- struct host_vm_change hvc;
-
- mm = &init_mm;
- hvc = INIT_HVC(mm, force, userspace);
- for (addr = start; addr < end;) {
- pgd = pgd_offset(mm, addr);
- if (!pgd_present(*pgd)) {
- last = ADD_ROUND(addr, PGDIR_SIZE);
- if (last > end)
- last = end;
- if (pgd_newpage(*pgd)) {
- updated = 1;
- err = add_munmap(addr, last - addr, &hvc);
- if (err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
-
- p4d = p4d_offset(pgd, addr);
- if (!p4d_present(*p4d)) {
- last = ADD_ROUND(addr, P4D_SIZE);
- if (last > end)
- last = end;
- if (p4d_newpage(*p4d)) {
- updated = 1;
- err = add_munmap(addr, last - addr, &hvc);
- if (err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
+ ret = update_p4d_range(pgd, addr, next, &ops);
+ } while (pgd++, addr = next,
+ ((addr < mm->context.sync_tlb_range_to) && !ret));
- pud = pud_offset(p4d, addr);
- if (!pud_present(*pud)) {
- last = ADD_ROUND(addr, PUD_SIZE);
- if (last > end)
- last = end;
- if (pud_newpage(*pud)) {
- updated = 1;
- err = add_munmap(addr, last - addr, &hvc);
- if (err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
-
- pmd = pmd_offset(pud, addr);
- if (!pmd_present(*pmd)) {
- last = ADD_ROUND(addr, PMD_SIZE);
- if (last > end)
- last = end;
- if (pmd_newpage(*pmd)) {
- updated = 1;
- err = add_munmap(addr, last - addr, &hvc);
- if (err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
-
- pte = pte_offset_kernel(pmd, addr);
- if (!pte_present(*pte) || pte_newpage(*pte)) {
- updated = 1;
- err = add_munmap(addr, PAGE_SIZE, &hvc);
- if (err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- if (pte_present(*pte))
- err = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
- PAGE_SIZE, 0, &hvc);
- }
- else if (pte_newprot(*pte)) {
- updated = 1;
- err = add_mprotect(addr, PAGE_SIZE, 0, &hvc);
- }
- addr += PAGE_SIZE;
- }
- if (!err)
- err = do_ops(&hvc, hvc.index, 1);
-
- if (err < 0)
- panic("flush_tlb_kernel failed, errno = %d\n", err);
- return updated;
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
-{
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- struct mm_struct *mm = vma->vm_mm;
- void *flush = NULL;
- int r, w, x, prot, err = 0;
- struct mm_id *mm_id;
-
- address &= PAGE_MASK;
-
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
- goto kill;
-
- p4d = p4d_offset(pgd, address);
- if (!p4d_present(*p4d))
- goto kill;
-
- pud = pud_offset(p4d, address);
- if (!pud_present(*pud))
- goto kill;
-
- pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd))
- goto kill;
-
- pte = pte_offset_kernel(pmd, address);
-
- r = pte_read(*pte);
- w = pte_write(*pte);
- x = pte_exec(*pte);
- if (!pte_young(*pte)) {
- r = 0;
- w = 0;
- } else if (!pte_dirty(*pte)) {
- w = 0;
- }
-
- mm_id = &mm->context.id;
- prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
- (x ? UM_PROT_EXEC : 0));
- if (pte_newpage(*pte)) {
- if (pte_present(*pte)) {
- unsigned long long offset;
- int fd;
-
- fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
- err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
- 1, &flush);
- }
- else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
- }
- else if (pte_newprot(*pte))
- err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
-
- if (err) {
- if (err == -ENOMEM)
- report_enomem();
-
- goto kill;
- }
-
- *pte = pte_mkuptodate(*pte);
+ if (ret == -ENOMEM)
+ report_enomem();
- return;
+ mm->context.sync_tlb_range_from = 0;
+ mm->context.sync_tlb_range_to = 0;
-kill:
- printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address);
- force_sig(SIGKILL);
+ return ret;
}
void flush_tlb_all(void)
@@ -539,66 +226,11 @@ void flush_tlb_all(void)
flush_tlb_mm(current->mm);
}
-void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- flush_tlb_kernel_range_common(start, end);
-}
-
-void flush_tlb_kernel_vm(void)
-{
- flush_tlb_kernel_range_common(start_vm, end_vm);
-}
-
-void __flush_tlb_one(unsigned long addr)
-{
- flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE);
-}
-
-static void fix_range(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force)
-{
- /*
- * Don't bother flushing if this address space is about to be
- * destroyed.
- */
- if (atomic_read(&mm->mm_users) == 0)
- return;
-
- fix_range_common(mm, start_addr, end_addr, force);
-}
-
-void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- if (vma->vm_mm == NULL)
- flush_tlb_kernel_range_common(start, end);
- else fix_range(vma->vm_mm, start, end, 0);
-}
-EXPORT_SYMBOL(flush_tlb_range);
-
-void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
- unsigned long end)
-{
- fix_range(mm, start, end, 0);
-}
-
void flush_tlb_mm(struct mm_struct *mm)
{
struct vm_area_struct *vma;
VMA_ITERATOR(vmi, mm, 0);
for_each_vma(vmi, vma)
- fix_range(mm, vma->vm_start, vma->vm_end, 0);
-}
-
-void force_flush_all(void)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- VMA_ITERATOR(vmi, mm, 0);
-
- mmap_read_lock(mm);
- for_each_vma(vmi, vma)
- fix_range(mm, vma->vm_start, vma->vm_end, 1);
- mmap_read_unlock(mm);
+ um_tlb_mark_sync(mm, vma->vm_start, vma->vm_end);
}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 6d8ae86ae978..97c8df9c4401 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -113,7 +113,7 @@ good_area:
#if 0
WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
#endif
- flush_tlb_page(vma, address);
+
out:
mmap_read_unlock(mm);
out_nosemaphore:
@@ -210,8 +210,17 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
if (!is_user && regs)
current->thread.segv_regs = container_of(regs, struct pt_regs, regs);
- if (!is_user && (address >= start_vm) && (address < end_vm)) {
- flush_tlb_kernel_vm();
+ if (!is_user && init_mm.context.sync_tlb_range_to) {
+ /*
+ * Kernel has pending updates from set_ptes that were not
+ * flushed yet. Syncing them should fix the pagefault (if not
+ * we'll get here again and panic).
+ */
+ err = um_tlb_sync(&init_mm);
+ if (err == -ENOMEM)
+ report_enomem();
+ if (err)
+ panic("Failed to sync kernel TLBs: %d", err);
goto out;
}
else if (current->mm == NULL) {
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 7a9820797eae..8e594cda6d77 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -23,6 +23,7 @@
#include <asm/cpufeature.h>
#include <asm/sections.h>
#include <asm/setup.h>
+#include <asm/text-patching.h>
#include <as-layout.h>
#include <arch.h>
#include <init.h>
@@ -125,9 +126,6 @@ unsigned long uml_reserved; /* Also modified in mem_init */
unsigned long start_vm;
unsigned long end_vm;
-/* Set in uml_ncpus_setup */
-int ncpus = 1;
-
/* Set in early boot */
static int have_root __initdata;
static int have_console __initdata;
diff --git a/arch/um/kernel/um_arch.h b/arch/um/kernel/um_arch.h
index 1e07fb7ee35e..46e731ab9dfc 100644
--- a/arch/um/kernel/um_arch.h
+++ b/arch/um/kernel/um_arch.h
@@ -11,4 +11,6 @@ extern void __init uml_dtb_init(void);
static inline void uml_dtb_init(void) { }
#endif
+extern int __init read_initrd(void);
+
#endif
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 3182e759d8de..5e5ee40680ce 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -63,7 +63,7 @@ const struct net_kern_info ethertap_kern_info = {
.write = etap_write,
};
-int ethertap_setup(char *str, char **mac_out, void *data)
+static int ethertap_setup(char *str, char **mac_out, void *data)
{
struct ethertap_init *init = data;
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index adcb6717be6f..ff022d9cf0dd 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -53,7 +53,7 @@ const struct net_kern_info tuntap_kern_info = {
.write = tuntap_write,
};
-int tuntap_setup(char *str, char **mac_out, void *data)
+static int tuntap_setup(char *str, char **mac_out, void *data)
{
struct tuntap_init *init = data;
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 344ac403fb5d..0a0f91cf4d6d 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -13,6 +13,7 @@
#include <init.h>
#include <elf_user.h>
#include <mem_user.h>
+#include "internal.h"
typedef Elf32_auxv_t elf_auxv_t;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index fc4450db59bd..5adf8f630049 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -17,6 +17,7 @@
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/un.h>
+#include <sys/mman.h>
#include <sys/types.h>
#include <sys/eventfd.h>
#include <poll.h>
@@ -240,6 +241,16 @@ out:
return err;
}
+int os_dup_file(int fd)
+{
+ int new_fd = dup(fd);
+
+ if (new_fd < 0)
+ return -errno;
+
+ return new_fd;
+}
+
void os_close_file(int fd)
{
close(fd);
@@ -502,44 +513,47 @@ int os_shutdown_socket(int fd, int r, int w)
return 0;
}
-int os_rcv_fd(int fd, int *helper_pid_out)
+/**
+ * os_rcv_fd_msg - receive message with (optional) FDs
+ * @fd: the FD to receive from
+ * @fds: the array for FDs to write to
+ * @n_fds: number of FDs to receive (@fds array size)
+ * @data: the message buffer
+ * @data_len: the size of the message to receive
+ *
+ * Receive a message with FDs.
+ *
+ * Returns: the size of the received message, or an error code
+ */
+ssize_t os_rcv_fd_msg(int fd, int *fds, unsigned int n_fds,
+ void *data, size_t data_len)
{
- int new, n;
- char buf[CMSG_SPACE(sizeof(new))];
- struct msghdr msg;
+ char buf[CMSG_SPACE(sizeof(*fds) * n_fds)];
struct cmsghdr *cmsg;
- struct iovec iov;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- iov = ((struct iovec) { .iov_base = helper_pid_out,
- .iov_len = sizeof(*helper_pid_out) });
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- msg.msg_flags = 0;
+ struct iovec iov = {
+ .iov_base = data,
+ .iov_len = data_len,
+ };
+ struct msghdr msg = {
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = buf,
+ .msg_controllen = sizeof(buf),
+ };
+ int n;
n = recvmsg(fd, &msg, 0);
if (n < 0)
return -errno;
- else if (n != iov.iov_len)
- *helper_pid_out = -1;
cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg == NULL) {
- printk(UM_KERN_ERR "rcv_fd didn't receive anything, "
- "error = %d\n", errno);
- return -1;
- }
- if ((cmsg->cmsg_level != SOL_SOCKET) ||
- (cmsg->cmsg_type != SCM_RIGHTS)) {
- printk(UM_KERN_ERR "rcv_fd didn't receive a descriptor\n");
- return -1;
- }
+ if (!cmsg ||
+ cmsg->cmsg_level != SOL_SOCKET ||
+ cmsg->cmsg_type != SCM_RIGHTS)
+ return n;
- new = ((int *) CMSG_DATA(cmsg))[0];
- return new;
+ memcpy(fds, CMSG_DATA(cmsg), cmsg->cmsg_len);
+ return n;
}
int os_create_unix_socket(const char *file, int len, int close_on_exec)
@@ -705,3 +719,25 @@ int os_poll(unsigned int n, const int *fds)
return -EIO;
}
+
+void *os_mmap_rw_shared(int fd, size_t size)
+{
+ void *res = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if (res == MAP_FAILED)
+ return NULL;
+
+ return res;
+}
+
+void *os_mremap_rw_shared(void *old_addr, size_t old_size, size_t new_size)
+{
+ void *res;
+
+ res = mremap(old_addr, old_size, new_size, MREMAP_MAYMOVE, NULL);
+
+ if (res == MAP_FAILED)
+ return NULL;
+
+ return res;
+}
diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h
new file mode 100644
index 000000000000..317fca190c2b
--- /dev/null
+++ b/arch/um/os-Linux/internal.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_OS_LINUX_INTERNAL_H
+#define __UM_OS_LINUX_INTERNAL_H
+
+/*
+ * elf_aux.c
+ */
+void scan_elf_aux(char **envp);
+
+/*
+ * mem.c
+ */
+void check_tmpexec(void);
+
+/*
+ * skas/process.c
+ */
+void wait_stub_done(int pid);
+
+#endif /* __UM_OS_LINUX_INTERNAL_H */
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index c8a42ecbd7a2..f98ff79cdbf7 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -16,6 +16,7 @@
#include <kern_util.h>
#include <os.h>
#include <um_malloc.h>
+#include "internal.h"
#define PGD_BOUND (4 * 1024 * 1024)
#define STACKSIZE (8 * 1024 * 1024)
@@ -102,8 +103,6 @@ static void setup_env_path(void)
}
}
-extern void scan_elf_aux( char **envp);
-
int __init main(int argc, char **argv, char **envp)
{
char **new_argv;
@@ -184,6 +183,11 @@ int __init main(int argc, char **argv, char **envp)
extern void *__real_malloc(int);
+/* workaround for -Wmissing-prototypes warnings */
+void *__wrap_malloc(int size);
+void *__wrap_calloc(int n, int size);
+void __wrap_free(void *ptr);
+
void *__wrap_malloc(int size)
{
void *ret;
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 8530b2e08604..cf44d386f23c 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -15,7 +15,9 @@
#include <sys/vfs.h>
#include <linux/magic.h>
#include <init.h>
+#include <kern_util.h>
#include <os.h>
+#include "internal.h"
/*
* kasan_map_memory - maps memory from @start with a size of @len.
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 24a403a70a02..b11ed66c8bb0 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
@@ -65,25 +66,36 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
int signals_enabled;
#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
-static int signals_blocked;
-#else
-#define signals_blocked 0
+static int signals_blocked, signals_blocked_pending;
#endif
static unsigned int signals_pending;
static unsigned int signals_active = 0;
-void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
+static void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
{
int enabled = signals_enabled;
- if ((signals_blocked || !enabled) && (sig == SIGIO)) {
+#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
+ if ((signals_blocked ||
+ __atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) &&
+ (sig == SIGIO)) {
+ /* increment so unblock will do another round */
+ __atomic_add_fetch(&signals_blocked_pending, 1,
+ __ATOMIC_SEQ_CST);
+ return;
+ }
+#endif
+
+ if (!enabled && (sig == SIGIO)) {
/*
* In TT_MODE_EXTERNAL, need to still call time-travel
- * handlers unless signals are also blocked for the
- * external time message processing. This will mark
- * signals_pending by itself (only if necessary.)
+ * handlers. This will mark signals_pending by itself
+ * (only if necessary.)
+ * Note we won't get here if signals are hard-blocked
+ * (which is handled above), in that case the hard-
+ * unblock will handle things.
*/
- if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL)
+ if (time_travel_mode == TT_MODE_EXTERNAL)
sigio_run_timetravel_handlers();
else
signals_pending |= SIGIO_MASK;
@@ -108,7 +120,7 @@ static void timer_real_alarm_handler(mcontext_t *mc)
timer_handler(SIGALRM, NULL, &regs);
}
-void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
+static void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
{
int enabled;
@@ -380,33 +392,99 @@ int um_set_signals_trace(int enable)
#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
void mark_sigio_pending(void)
{
+ /*
+ * It would seem that this should be atomic so
+ * it isn't a read-modify-write with a signal
+ * that could happen in the middle, losing the
+ * value set by the signal.
+ *
+ * However, this function is only called when in
+ * time-travel=ext simulation mode, in which case
+ * the only signal ever pending is SIGIO, which
+ * is blocked while this can be called, and the
+ * timer signal (SIGALRM) cannot happen.
+ */
signals_pending |= SIGIO_MASK;
}
void block_signals_hard(void)
{
- if (signals_blocked)
- return;
- signals_blocked = 1;
+ signals_blocked++;
barrier();
}
void unblock_signals_hard(void)
{
+ static bool unblocking;
+
if (!signals_blocked)
+ panic("unblocking signals while not blocked");
+
+ if (--signals_blocked)
return;
- /* Must be set to 0 before we check the pending bits etc. */
- signals_blocked = 0;
+ /*
+ * Must be set to 0 before we check pending so the
+ * SIGIO handler will run as normal unless we're still
+ * going to process signals_blocked_pending.
+ */
barrier();
- if (signals_pending && signals_enabled) {
- /* this is a bit inefficient, but that's not really important */
- block_signals();
- unblock_signals();
- } else if (signals_pending & SIGIO_MASK) {
- /* we need to run time-travel handlers even if not enabled */
- sigio_run_timetravel_handlers();
+ /*
+ * Note that block_signals_hard()/unblock_signals_hard() can be called
+ * within the unblock_signals()/sigio_run_timetravel_handlers() below.
+ * This would still be prone to race conditions since it's actually a
+ * call _within_ e.g. vu_req_read_message(), where we observed this
+ * issue, which loops. Thus, if the inner call handles the recorded
+ * pending signals, we can get out of the inner call with the real
+ * signal hander no longer blocked, and still have a race. Thus don't
+ * handle unblocking in the inner call, if it happens, but only in
+ * the outermost call - 'unblocking' serves as an ownership for the
+ * signals_blocked_pending decrement.
+ */
+ if (unblocking)
+ return;
+ unblocking = true;
+
+ while (__atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) {
+ if (signals_enabled) {
+ /* signals are enabled so we can touch this */
+ signals_pending |= SIGIO_MASK;
+ /*
+ * this is a bit inefficient, but that's
+ * not really important
+ */
+ block_signals();
+ unblock_signals();
+ } else {
+ /*
+ * we need to run time-travel handlers even
+ * if not enabled
+ */
+ sigio_run_timetravel_handlers();
+ }
+
+ /*
+ * The decrement of signals_blocked_pending must be atomic so
+ * that the signal handler will either happen before or after
+ * the decrement, not during a read-modify-write:
+ * - If it happens before, it can increment it and we'll
+ * decrement it and do another round in the loop.
+ * - If it happens after it'll see 0 for both signals_blocked
+ * and signals_blocked_pending and thus run the handler as
+ * usual (subject to signals_enabled, but that's unrelated.)
+ *
+ * Note that a call to unblock_signals_hard() within the calls
+ * to unblock_signals() or sigio_run_timetravel_handlers() above
+ * will do nothing due to the 'unblocking' state, so this cannot
+ * underflow as the only one decrementing will be the outermost
+ * one.
+ */
+ if (__atomic_sub_fetch(&signals_blocked_pending, 1,
+ __ATOMIC_SEQ_CST) < 0)
+ panic("signals_blocked_pending underflow");
}
+
+ unblocking = false;
}
#endif
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 953fb10f3f93..c55430775efd 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
+ * Copyright (C) 2021 Benjamin Berg <benjamin@sipsolutions.net>
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
@@ -17,10 +18,32 @@
#include <skas.h>
#include <sysdep/ptrace.h>
#include <sysdep/stub.h>
+#include "../internal.h"
-extern char batch_syscall_stub[], __syscall_stub_start[];
+extern char __syscall_stub_start[];
-extern void wait_stub_done(int pid);
+void syscall_stub_dump_error(struct mm_id *mm_idp)
+{
+ struct stub_data *proc_data = (void *)mm_idp->stack;
+ struct stub_syscall *sc;
+
+ if (proc_data->syscall_data_len < 0 ||
+ proc_data->syscall_data_len >= ARRAY_SIZE(proc_data->syscall_data))
+ panic("Syscall data was corrupted by stub (len is: %d, expected maximum: %d)!",
+ proc_data->syscall_data_len,
+ mm_idp->syscall_data_len);
+
+ sc = &proc_data->syscall_data[proc_data->syscall_data_len];
+
+ printk(UM_KERN_ERR "%s : length = %d, last offset = %d",
+ __func__, mm_idp->syscall_data_len,
+ proc_data->syscall_data_len);
+ printk(UM_KERN_ERR "%s : stub syscall type %d failed, return value = 0x%lx\n",
+ __func__, sc->syscall, proc_data->err);
+
+ print_hex_dump(UM_KERN_ERR, " syscall data: ", 0,
+ 16, 4, sc, sizeof(*sc), 0);
+}
static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
unsigned long *stack)
@@ -37,22 +60,24 @@ static unsigned long syscall_regs[MAX_REG_NR];
static int __init init_syscall_regs(void)
{
get_safe_registers(syscall_regs, NULL);
+
syscall_regs[REGS_IP_INDEX] = STUB_CODE +
- ((unsigned long) batch_syscall_stub -
+ ((unsigned long) stub_syscall_handler -
(unsigned long) __syscall_stub_start);
- syscall_regs[REGS_SP_INDEX] = STUB_DATA;
+ syscall_regs[REGS_SP_INDEX] = STUB_DATA +
+ offsetof(struct stub_data, sigstack) +
+ sizeof(((struct stub_data *) 0)->sigstack) -
+ sizeof(void *);
return 0;
}
__initcall(init_syscall_regs);
-static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
+static inline long do_syscall_stub(struct mm_id *mm_idp)
{
+ struct stub_data *proc_data = (void *)mm_idp->stack;
int n, i;
- long ret, offset;
- unsigned long * data;
- unsigned long * syscall;
int err, pid = mm_idp->u.pid;
n = ptrace_setregs(pid, syscall_regs);
@@ -64,6 +89,9 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
__func__, -n);
}
+ /* Inform process how much we have filled in. */
+ proc_data->syscall_data_len = mm_idp->syscall_data_len;
+
err = ptrace(PTRACE_CONT, pid, 0, 0);
if (err)
panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
@@ -72,135 +100,141 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
wait_stub_done(pid);
/*
- * When the stub stops, we find the following values on the
- * beginning of the stack:
- * (long )return_value
- * (long )offset to failed sycall-data (0, if no error)
+ * proc_data->err will be non-zero if there was an (unexpected) error.
+ * In that case, syscall_data_len points to the last executed syscall,
+ * otherwise it will be zero (but we do not need to rely on that).
*/
- ret = *((unsigned long *) mm_idp->stack);
- offset = *((unsigned long *) mm_idp->stack + 1);
- if (offset) {
- data = (unsigned long *)(mm_idp->stack + offset - STUB_DATA);
- printk(UM_KERN_ERR "%s : ret = %ld, offset = %ld, data = %p\n",
- __func__, ret, offset, data);
- syscall = (unsigned long *)((unsigned long)data + data[0]);
- printk(UM_KERN_ERR "%s: syscall %ld failed, return value = 0x%lx, expected return value = 0x%lx\n",
- __func__, syscall[0], ret, syscall[7]);
- printk(UM_KERN_ERR " syscall parameters: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
- syscall[1], syscall[2], syscall[3],
- syscall[4], syscall[5], syscall[6]);
- for (n = 1; n < data[0]/sizeof(long); n++) {
- if (n == 1)
- printk(UM_KERN_ERR " additional syscall data:");
- if (n % 4 == 1)
- printk("\n" UM_KERN_ERR " ");
- printk(" 0x%lx", data[n]);
- }
- if (n > 1)
- printk("\n");
- }
- else ret = 0;
+ if (proc_data->err < 0) {
+ syscall_stub_dump_error(mm_idp);
- *addr = check_init_stack(mm_idp, NULL);
+ /* Store error code in case someone tries to add more syscalls */
+ mm_idp->syscall_data_len = proc_data->err;
+ } else {
+ mm_idp->syscall_data_len = 0;
+ }
- return ret;
+ return mm_idp->syscall_data_len;
}
-long run_syscall_stub(struct mm_id * mm_idp, int syscall,
- unsigned long *args, long expected, void **addr,
- int done)
+int syscall_stub_flush(struct mm_id *mm_idp)
{
- unsigned long *stack = check_init_stack(mm_idp, *addr);
-
- *stack += sizeof(long);
- stack += *stack / sizeof(long);
-
- *stack++ = syscall;
- *stack++ = args[0];
- *stack++ = args[1];
- *stack++ = args[2];
- *stack++ = args[3];
- *stack++ = args[4];
- *stack++ = args[5];
- *stack++ = expected;
- *stack = 0;
-
- if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
- UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {
- *addr = stack;
+ int res;
+
+ if (mm_idp->syscall_data_len == 0)
return 0;
+
+ /* If an error happened already, report it and reset the state. */
+ if (mm_idp->syscall_data_len < 0) {
+ res = mm_idp->syscall_data_len;
+ mm_idp->syscall_data_len = 0;
+ return res;
}
- return do_syscall_stub(mm_idp, addr);
+ res = do_syscall_stub(mm_idp);
+ mm_idp->syscall_data_len = 0;
+
+ return res;
}
-long syscall_stub_data(struct mm_id * mm_idp,
- unsigned long *data, int data_count,
- void **addr, void **stub_addr)
+struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp)
{
- unsigned long *stack;
- int ret = 0;
-
- /*
- * If *addr still is uninitialized, it *must* contain NULL.
- * Thus in this case do_syscall_stub correctly won't be called.
- */
- if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
- UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {
- ret = do_syscall_stub(mm_idp, addr);
- /* in case of error, don't overwrite data on stack */
- if (ret)
- return ret;
+ struct stub_syscall *sc;
+ struct stub_data *proc_data = (struct stub_data *) mm_idp->stack;
+
+ if (mm_idp->syscall_data_len > 0 &&
+ mm_idp->syscall_data_len == ARRAY_SIZE(proc_data->syscall_data))
+ do_syscall_stub(mm_idp);
+
+ if (mm_idp->syscall_data_len < 0) {
+ /* Return dummy to retain error state. */
+ sc = &proc_data->syscall_data[0];
+ } else {
+ sc = &proc_data->syscall_data[mm_idp->syscall_data_len];
+ mm_idp->syscall_data_len += 1;
}
+ memset(sc, 0, sizeof(*sc));
- stack = check_init_stack(mm_idp, *addr);
- *addr = stack;
+ return sc;
+}
- *stack = data_count * sizeof(long);
+static struct stub_syscall *syscall_stub_get_previous(struct mm_id *mm_idp,
+ int syscall_type,
+ unsigned long virt)
+{
+ if (mm_idp->syscall_data_len > 0) {
+ struct stub_data *proc_data = (void *) mm_idp->stack;
+ struct stub_syscall *sc;
- memcpy(stack + 1, data, data_count * sizeof(long));
+ sc = &proc_data->syscall_data[mm_idp->syscall_data_len - 1];
- *stub_addr = (void *)(((unsigned long)(stack + 1) &
- ~UM_KERN_PAGE_MASK) + STUB_DATA);
+ if (sc->syscall == syscall_type &&
+ sc->mem.addr + sc->mem.length == virt)
+ return sc;
+ }
- return 0;
+ return NULL;
}
-int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
- int phys_fd, unsigned long long offset, int done, void **data)
+int map(struct mm_id *mm_idp, unsigned long virt, unsigned long len, int prot,
+ int phys_fd, unsigned long long offset)
{
- int ret;
- unsigned long args[] = { virt, len, prot,
- MAP_SHARED | MAP_FIXED, phys_fd,
- MMAP_OFFSET(offset) };
+ struct stub_syscall *sc;
- ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,
- data, done);
+ /* Compress with previous syscall if that is possible */
+ sc = syscall_stub_get_previous(mm_idp, STUB_SYSCALL_MMAP, virt);
+ if (sc && sc->mem.prot == prot && sc->mem.fd == phys_fd &&
+ sc->mem.offset == MMAP_OFFSET(offset - sc->mem.length)) {
+ sc->mem.length += len;
+ return 0;
+ }
- return ret;
+ sc = syscall_stub_alloc(mm_idp);
+ sc->syscall = STUB_SYSCALL_MMAP;
+ sc->mem.addr = virt;
+ sc->mem.length = len;
+ sc->mem.prot = prot;
+ sc->mem.fd = phys_fd;
+ sc->mem.offset = MMAP_OFFSET(offset);
+
+ return 0;
}
-int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
- int done, void **data)
+int unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len)
{
- int ret;
- unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
- 0 };
+ struct stub_syscall *sc;
- ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,
- data, done);
+ /* Compress with previous syscall if that is possible */
+ sc = syscall_stub_get_previous(mm_idp, STUB_SYSCALL_MUNMAP, addr);
+ if (sc) {
+ sc->mem.length += len;
+ return 0;
+ }
- return ret;
+ sc = syscall_stub_alloc(mm_idp);
+ sc->syscall = STUB_SYSCALL_MUNMAP;
+ sc->mem.addr = addr;
+ sc->mem.length = len;
+
+ return 0;
}
-int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
- unsigned int prot, int done, void **data)
+int protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len,
+ unsigned int prot)
{
- int ret;
- unsigned long args[] = { addr, len, prot, 0, 0, 0 };
+ struct stub_syscall *sc;
- ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,
- data, done);
+ /* Compress with previous syscall if that is possible */
+ sc = syscall_stub_get_previous(mm_idp, STUB_SYSCALL_MPROTECT, addr);
+ if (sc && sc->mem.prot == prot) {
+ sc->mem.length += len;
+ return 0;
+ }
- return ret;
+ sc = syscall_stub_alloc(mm_idp);
+ sc->syscall = STUB_SYSCALL_MPROTECT;
+ sc->mem.addr = addr;
+ sc->mem.length = len;
+ sc->mem.prot = prot;
+
+ return 0;
}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 1f5c3f2523d1..f7088345b3fc 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -23,6 +23,8 @@
#include <skas.h>
#include <sysdep/stub.h>
#include <linux/threads.h>
+#include <timetravel.h>
+#include "../internal.h"
int is_skas_winch(int pid, int fd, void *data)
{
@@ -252,7 +254,6 @@ static int userspace_tramp(void *stack)
}
int userspace_pid[NR_CPUS];
-int kill_userspace_mm[NR_CPUS];
/**
* start_userspace() - prepare a new userspace process
@@ -344,8 +345,20 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
interrupt_end();
while (1) {
- if (kill_userspace_mm[0])
+ time_travel_print_bc_msg();
+
+ current_mm_sync();
+
+ /* Flush out any pending syscalls */
+ err = syscall_stub_flush(current_mm_id());
+ if (err) {
+ if (err == -ENOMEM)
+ report_enomem();
+
+ printk(UM_KERN_ERR "%s - Error flushing stub syscalls: %d",
+ __func__, -err);
fatal_sigsegv();
+ }
/*
* This can legitimately fail if the process loads a
@@ -460,113 +473,6 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
}
}
-static unsigned long thread_regs[MAX_REG_NR];
-static unsigned long thread_fp_regs[FP_SIZE];
-
-static int __init init_thread_regs(void)
-{
- get_safe_registers(thread_regs, thread_fp_regs);
- /* Set parent's instruction pointer to start of clone-stub */
- thread_regs[REGS_IP_INDEX] = STUB_CODE +
- (unsigned long) stub_clone_handler -
- (unsigned long) __syscall_stub_start;
- thread_regs[REGS_SP_INDEX] = STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE -
- sizeof(void *);
-#ifdef __SIGNAL_FRAMESIZE
- thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
-#endif
- return 0;
-}
-
-__initcall(init_thread_regs);
-
-int copy_context_skas0(unsigned long new_stack, int pid)
-{
- int err;
- unsigned long current_stack = current_stub_stack();
- struct stub_data *data = (struct stub_data *) current_stack;
- struct stub_data *child_data = (struct stub_data *) new_stack;
- unsigned long long new_offset;
- int new_fd = phys_mapping(uml_to_phys((void *)new_stack), &new_offset);
-
- /*
- * prepare offset and fd of child's stack as argument for parent's
- * and child's mmap2 calls
- */
- *data = ((struct stub_data) {
- .offset = MMAP_OFFSET(new_offset),
- .fd = new_fd,
- .parent_err = -ESRCH,
- .child_err = 0,
- });
-
- *child_data = ((struct stub_data) {
- .child_err = -ESRCH,
- });
-
- err = ptrace_setregs(pid, thread_regs);
- if (err < 0) {
- err = -errno;
- printk(UM_KERN_ERR "%s : PTRACE_SETREGS failed, pid = %d, errno = %d\n",
- __func__, pid, -err);
- return err;
- }
-
- err = put_fp_registers(pid, thread_fp_regs);
- if (err < 0) {
- printk(UM_KERN_ERR "%s : put_fp_registers failed, pid = %d, err = %d\n",
- __func__, pid, err);
- return err;
- }
-
- /*
- * Wait, until parent has finished its work: read child's pid from
- * parent's stack, and check, if bad result.
- */
- err = ptrace(PTRACE_CONT, pid, 0, 0);
- if (err) {
- err = -errno;
- printk(UM_KERN_ERR "Failed to continue new process, pid = %d, errno = %d\n",
- pid, errno);
- return err;
- }
-
- wait_stub_done(pid);
-
- pid = data->parent_err;
- if (pid < 0) {
- printk(UM_KERN_ERR "%s - stub-parent reports error %d\n",
- __func__, -pid);
- return pid;
- }
-
- /*
- * Wait, until child has finished too: read child's result from
- * child's stack and check it.
- */
- wait_stub_done(pid);
- if (child_data->child_err != STUB_DATA) {
- printk(UM_KERN_ERR "%s - stub-child %d reports error %ld\n",
- __func__, pid, data->child_err);
- err = data->child_err;
- goto out_kill;
- }
-
- if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
- (void *)PTRACE_O_TRACESYSGOOD) < 0) {
- err = -errno;
- printk(UM_KERN_ERR "%s : PTRACE_SETOPTIONS failed, errno = %d\n",
- __func__, errno);
- goto out_kill;
- }
-
- return pid;
-
- out_kill:
- os_kill_ptraced_process(pid, 1);
- return err;
-}
-
void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
{
(*buf)[0].JB_IP = (unsigned long) handler;
@@ -683,5 +589,4 @@ void reboot_skas(void)
void __switch_mm(struct mm_id *mm_idp)
{
userspace_pid[0] = mm_idp->u.pid;
- kill_userspace_mm[0] = mm_idp->kill;
}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 8b0e98ab842c..93fc82c01aba 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -17,13 +17,16 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <asm/ldt.h>
#include <asm/unistd.h>
#include <init.h>
#include <os.h>
+#include <kern_util.h>
#include <mem_user.h>
#include <ptrace_user.h>
#include <registers.h>
#include <skas.h>
+#include "internal.h"
static void ptrace_child(void)
{
@@ -221,8 +224,6 @@ static void __init check_ptrace(void)
check_sysemu();
}
-extern void check_tmpexec(void);
-
static void __init check_coredump_limit(void)
{
struct rlimit lim;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 928820e61cb5..007bab9f2a0e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -34,6 +34,7 @@ config X86_64
select SWIOTLB
select ARCH_HAS_ELFCORE_COMPAT
select ZONE_DMA32
+ select EXECMEM if DYNAMIC_FTRACE
config FORCE_DYNAMIC_FTRACE
def_bool y
@@ -84,6 +85,7 @@ config X86
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_KCOV if X86_64
+ select ARCH_HAS_KERNEL_FPU_SUPPORT
select ARCH_HAS_MEM_ENCRYPT
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
@@ -169,6 +171,7 @@ config X86
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_TIME_NS
+ select GENERIC_VDSO_OVERFLOW_PROTECT
select GUP_GET_PXX_LOW_HIGH if X86_PAE
select HARDIRQS_SW_RESEND
select HARDLOCKUP_CHECK_TIMESTAMP if X86_64
@@ -222,7 +225,7 @@ config X86
select HAVE_EFFICIENT_UNALIGNED_ACCESS
select HAVE_EISA
select HAVE_EXIT_THREAD
- select HAVE_FAST_GUP
+ select HAVE_GUP_FAST
select HAVE_FENTRY if X86_64 || DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
@@ -284,6 +287,7 @@ config X86
select HAVE_UNSTABLE_SCHED_CLOCK
select HAVE_USER_RETURN_NOTIFIER
select HAVE_GENERIC_VDSO
+ select VDSO_GETRANDOM if X86_64
select HOTPLUG_PARALLEL if SMP && X86_64
select HOTPLUG_SMT if SMP
select HOTPLUG_SPLIT_STARTUP if SMP && X86_32
@@ -465,6 +469,17 @@ config X86_X2APIC
If you don't know what to do here, say N.
+config X86_POSTED_MSI
+ bool "Enable MSI and MSI-x delivery by posted interrupts"
+ depends on X86_64 && IRQ_REMAP
+ help
+ This enables MSIs that are under interrupt remapping to be delivered as
+ posted interrupts to the host kernel. Interrupt throughput can
+ potentially be improved by coalescing CPU notifications during high
+ frequency bursts.
+
+ If you don't know what to do here, say N.
+
config X86_MPPARSE
bool "Enable MPS table" if ACPI
default y
@@ -501,12 +516,11 @@ config X86_FRED
When enabled, try to use Flexible Return and Event Delivery
instead of the legacy SYSCALL/SYSENTER/IDT architecture for
ring transitions and exception/interrupt handling if the
- system supports.
+ system supports it.
-if X86_32
config X86_BIGSMP
bool "Support for big SMP systems with more than 8 CPUs"
- depends on SMP
+ depends on SMP && X86_32
help
This option is needed for the systems that have more than 8 CPUs.
@@ -519,7 +533,10 @@ config X86_EXTENDED_PLATFORM
systems out there.)
If you enable this option then you'll be able to select support
- for the following (non-PC) 32 bit x86 platforms:
+ for the following non-PC x86 platforms, depending on the value of
+ CONFIG_64BIT.
+
+ 32-bit platforms (CONFIG_64BIT=n):
Goldfish (Android emulator)
AMD Elan
RDC R-321x SoC
@@ -527,28 +544,14 @@ config X86_EXTENDED_PLATFORM
STA2X11-based (e.g. Northville)
Moorestown MID devices
- If you have one of these systems, or if you want to build a
- generic distribution kernel, say Y here - otherwise say N.
-endif # X86_32
-
-if X86_64
-config X86_EXTENDED_PLATFORM
- bool "Support for extended (non-PC) x86 platforms"
- default y
- help
- If you disable this option then the kernel will only support
- standard PC platforms. (which covers the vast majority of
- systems out there.)
-
- If you enable this option then you'll be able to select support
- for the following (non-PC) 64 bit x86 platforms:
+ 64-bit platforms (CONFIG_64BIT=y):
Numascale NumaChip
ScaleMP vSMP
SGI Ultraviolet
If you have one of these systems, or if you want to build a
generic distribution kernel, say Y here - otherwise say N.
-endif # X86_64
+
# This is an alphabetically sorted list of 64 bit extended platforms
# Please maintain the alphabetic order if and when there are additions
config X86_NUMACHIP
@@ -1116,6 +1119,13 @@ config X86_LOCAL_APIC
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI
select IRQ_DOMAIN_HIERARCHY
+config ACPI_MADT_WAKEUP
+ def_bool y
+ depends on X86_64
+ depends on ACPI
+ depends on SMP
+ depends on X86_LOCAL_APIC
+
config X86_IO_APIC
def_bool y
depends on X86_LOCAL_APIC || X86_UP_IOAPIC
@@ -2036,26 +2046,6 @@ config EFI_MIXED
If unsure, say N.
-config EFI_FAKE_MEMMAP
- bool "Enable EFI fake memory map"
- depends on EFI
- help
- Saying Y here will enable "efi_fake_mem" boot option. By specifying
- this parameter, you can add arbitrary attribute to specific memory
- range by updating original (firmware provided) EFI memmap. This is
- useful for debugging of EFI memmap related feature, e.g., Address
- Range Mirroring feature.
-
-config EFI_MAX_FAKE_MEM
- int "maximum allowable number of ranges in efi_fake_mem boot option"
- depends on EFI_FAKE_MEMMAP
- range 1 128
- default 8
- help
- Maximum allowable number of ranges in efi_fake_mem boot option.
- Ranges can be set up to this value using comma-separated list.
- The default value is 8.
-
config EFI_RUNTIME_MAP
bool "Export EFI runtime maps to sysfs" if EXPERT
depends on EFI
@@ -2425,23 +2415,35 @@ config STRICT_SIGALTSTACK_SIZE
Say 'N' unless you want to really enforce this check.
+config CFI_AUTO_DEFAULT
+ bool "Attempt to use FineIBT by default at boot time"
+ depends on FINEIBT
+ default y
+ help
+ Attempt to use FineIBT by default at boot time. If enabled,
+ this is the same as booting with "cfi=auto". If disabled,
+ this is the same as booting with "cfi=kcfi".
+
source "kernel/livepatch/Kconfig"
endmenu
config CC_HAS_NAMED_AS
- def_bool CC_IS_GCC && GCC_VERSION >= 120100
+ def_bool $(success,echo 'int __seg_fs fs; int __seg_gs gs;' | $(CC) -x c - -S -o /dev/null)
+ depends on CC_IS_GCC
+
+config CC_HAS_NAMED_AS_FIXED_SANITIZERS
+ def_bool CC_IS_GCC && GCC_VERSION >= 130300
config USE_X86_SEG_SUPPORT
def_bool y
depends on CC_HAS_NAMED_AS
#
- # -fsanitize=kernel-address (KASAN) is at the moment incompatible
- # with named address spaces - see GCC PR sanitizer/111736.
+ # -fsanitize=kernel-address (KASAN) and -fsanitize=thread
+ # (KCSAN) are incompatible with named address spaces with
+ # GCC < 13.3 - see GCC PR sanitizer/111736.
#
- depends on !KASAN
- # -fsanitize=thread (KCSAN) is also incompatible.
- depends on !KCSAN
+ depends on !(KASAN || KCSAN) || CC_HAS_NAMED_AS_FIXED_SANITIZERS
config CC_HAS_SLS
def_bool $(cc-option,-mharden-sls=all)
diff --git a/arch/x86/Kconfig.assembler b/arch/x86/Kconfig.assembler
index 8ad41da301e5..6d20a6ce0507 100644
--- a/arch/x86/Kconfig.assembler
+++ b/arch/x86/Kconfig.assembler
@@ -25,7 +25,17 @@ config AS_GFNI
help
Supported by binutils >= 2.30 and LLVM integrated assembler
+config AS_VAES
+ def_bool $(as-instr,vaesenc %ymm0$(comma)%ymm1$(comma)%ymm2)
+ help
+ Supported by binutils >= 2.30 and LLVM integrated assembler
+
+config AS_VPCLMULQDQ
+ def_bool $(as-instr,vpclmulqdq \$0x10$(comma)%ymm0$(comma)%ymm1$(comma)%ymm2)
+ help
+ Supported by binutils >= 2.30 and LLVM integrated assembler
+
config AS_WRUSS
- def_bool $(as-instr,wrussq %rax$(comma)(%rbx))
+ def_bool $(as-instr64,wrussq %rax$(comma)(%rbx))
help
Supported by binutils >= 2.31 and LLVM integrated assembler
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index c5d614d28a75..74777a97e394 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -248,6 +248,7 @@ config UNWINDER_ORC
config UNWINDER_FRAME_POINTER
bool "Frame pointer unwinder"
+ select ARCH_WANT_FRAME_POINTERS
select FRAME_POINTER
help
This option enables the frame pointer unwinder for unwinding kernel
@@ -271,7 +272,3 @@ config UNWINDER_GUESS
overhead.
endchoice
-
-config FRAME_POINTER
- depends on !UNWINDER_ORC && !UNWINDER_GUESS
- bool
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 5ab93fcdd691..801fd85c3ef6 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -74,6 +74,26 @@ KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2
+#
+# CFLAGS for compiling floating point code inside the kernel.
+#
+CC_FLAGS_FPU := -msse -msse2
+ifdef CONFIG_CC_IS_GCC
+# Stack alignment mismatch, proceed with caution.
+# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
+# (8B stack alignment).
+# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383
+#
+# The "-msse" in the first argument is there so that the
+# -mpreferred-stack-boundary=3 build error:
+#
+# -mpreferred-stack-boundary=3 is not between 4 and 12
+#
+# can be triggered. Otherwise gcc doesn't complain.
+CC_FLAGS_FPU += -mhard-float
+CC_FLAGS_FPU += $(call cc-option,-msse -mpreferred-stack-boundary=3,-mpreferred-stack-boundary=4)
+endif
+
ifeq ($(CONFIG_X86_KERNEL_IBT),y)
#
# Kernel IBT has S_CET.NOTRACK_EN=0, as such the compilers must not generate
@@ -258,7 +278,7 @@ drivers-$(CONFIG_PCI) += arch/x86/pci/
# suspend and hibernation support
drivers-$(CONFIG_PM) += arch/x86/power/
-drivers-$(CONFIG_FB_CORE) += arch/x86/video/
+drivers-$(CONFIG_VIDEO) += arch/x86/video/
####
# boot loader support. Several targets are kept for legacy purposes
diff --git a/arch/x86/Makefile.um b/arch/x86/Makefile.um
index 2106a2bd152b..a46b1397ad01 100644
--- a/arch/x86/Makefile.um
+++ b/arch/x86/Makefile.um
@@ -9,6 +9,7 @@ core-y += arch/x86/crypto/
#
ifeq ($(CONFIG_CC_IS_CLANG),y)
KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
+KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2
endif
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 3cece19b7473..9cc0ff6e9067 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -9,19 +9,6 @@
# Changed by many, many contributors over the years.
#
-# Sanitizer runtimes are unavailable and cannot be linked for early boot code.
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-KMSAN_SANITIZE := n
-OBJECT_FILES_NON_STANDARD := y
-
-# Kernel does not boot with kcov instrumentation here.
-# One of the problems observed was insertion of __sanitizer_cov_trace_pc()
-# callback into middle of per-cpu data enabling code. Thus the callback observed
-# inconsistent state and crashed. We are interested mostly in syscall coverage,
-# so boot code is not interesting anyway.
-KCOV_INSTRUMENT := n
-
# If you want to preset the SVGA mode, uncomment the next line and
# set SVGA_MODE to whatever number you want.
# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
@@ -69,8 +56,7 @@ KBUILD_CFLAGS := $(REALMODE_CFLAGS) -D_SETUP
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
+KBUILD_CFLAGS += $(CONFIG_CC_IMPLICIT_FALLTHROUGH)
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
@@ -129,7 +115,7 @@ targets += mtools.conf
# genimage.sh requires bash, but it also has a bunch of other
# external dependencies.
quiet_cmd_genimage = GENIMAGE $3
-cmd_genimage = $(BASH) $(srctree)/$(src)/genimage.sh $2 $3 $(obj)/bzImage \
+ cmd_genimage = $(BASH) $(src)/genimage.sh $2 $3 $(obj)/bzImage \
$(obj)/mtools.conf '$(FDARGS)' $(FDINITRD)
PHONY += bzdisk fdimage fdimage144 fdimage288 hdimage isoimage
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index e9522c6893be..f2051644de94 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -17,15 +17,6 @@
# (see scripts/Makefile.lib size_append)
# compressed vmlinux.bin.all + u32 size of vmlinux.bin.all
-# Sanitizer runtimes are unavailable and cannot be linked for early boot code.
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-KMSAN_SANITIZE := n
-OBJECT_FILES_NON_STANDARD := y
-
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-
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
@@ -59,8 +50,6 @@ KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
CFLAGS_sev.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)
@@ -116,9 +105,9 @@ vmlinux-objs-$(CONFIG_UNACCEPTED_MEMORY) += $(obj)/mem.o
vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o
-vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
+vmlinux-libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
-$(obj)/vmlinux: $(vmlinux-objs-y) FORCE
+$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
$(call if_changed,ld)
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index bf4a10a5794f..1dcb794c5479 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -398,6 +398,11 @@ SYM_CODE_START(startup_64)
call sev_enable
#endif
+ /* Preserve only the CR4 bits that must be preserved, and clear the rest */
+ movq %cr4, %rax
+ andl $(X86_CR4_PAE | X86_CR4_MCE | X86_CR4_LA57), %eax
+ movq %rax, %cr4
+
/*
* configure_5level_paging() updates the number of paging levels using
* a trampoline in 32-bit addressable memory if the current number does
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index dec961c6d16a..f4d82379bf44 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -119,13 +119,8 @@ char *skip_spaces(const char *str)
#include "../../../../lib/ctype.c"
#include "../../../../lib/cmdline.c"
-enum parse_mode {
- PARSE_MEMMAP,
- PARSE_EFI,
-};
-
static int
-parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode)
+parse_memmap(char *p, u64 *start, u64 *size)
{
char *oldp;
@@ -148,29 +143,11 @@ parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode)
*start = memparse(p + 1, &p);
return 0;
case '@':
- if (mode == PARSE_MEMMAP) {
- /*
- * memmap=nn@ss specifies usable region, should
- * be skipped
- */
- *size = 0;
- } else {
- u64 flags;
-
- /*
- * efi_fake_mem=nn@ss:attr the attr specifies
- * flags that might imply a soft-reservation.
- */
- *start = memparse(p + 1, &p);
- if (p && *p == ':') {
- p++;
- if (kstrtoull(p, 0, &flags) < 0)
- *size = 0;
- else if (flags & EFI_MEMORY_SP)
- return 0;
- }
- *size = 0;
- }
+ /*
+ * memmap=nn@ss specifies usable region, should
+ * be skipped
+ */
+ *size = 0;
fallthrough;
default:
/*
@@ -185,7 +162,7 @@ parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode)
return -EINVAL;
}
-static void mem_avoid_memmap(enum parse_mode mode, char *str)
+static void mem_avoid_memmap(char *str)
{
static int i;
@@ -200,7 +177,7 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str)
if (k)
*k++ = 0;
- rc = parse_memmap(str, &start, &size, mode);
+ rc = parse_memmap(str, &start, &size);
if (rc < 0)
break;
str = k;
@@ -281,7 +258,7 @@ static void handle_mem_options(void)
break;
if (!strcmp(param, "memmap")) {
- mem_avoid_memmap(PARSE_MEMMAP, val);
+ mem_avoid_memmap(val);
} else if (IS_ENABLED(CONFIG_X86_64) && strstr(param, "hugepages")) {
parse_gb_huge_pages(param, val);
} else if (!strcmp(param, "mem")) {
@@ -295,8 +272,6 @@ static void handle_mem_options(void)
if (mem_size < mem_limit)
mem_limit = mem_size;
- } else if (!strcmp(param, "efi_fake_mem")) {
- mem_avoid_memmap(PARSE_EFI, val);
}
}
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index b70e4a21c15f..944454306ef4 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -531,8 +531,3 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
return output + entry_offset;
}
-
-void __fortify_panic(const u8 reason, size_t avail, size_t size)
-{
- error("detected buffer overflow");
-}
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index ec71846d28c9..cd44e120fe53 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -127,7 +127,35 @@ static bool fault_in_kernel_space(unsigned long address)
#include "../../lib/insn.c"
/* Include code for early handlers */
-#include "../../kernel/sev-shared.c"
+#include "../../coco/sev/shared.c"
+
+static struct svsm_ca *svsm_get_caa(void)
+{
+ return boot_svsm_caa;
+}
+
+static u64 svsm_get_caa_pa(void)
+{
+ return boot_svsm_caa_pa;
+}
+
+static int svsm_perform_call_protocol(struct svsm_call *call)
+{
+ struct ghcb *ghcb;
+ int ret;
+
+ if (boot_ghcb)
+ ghcb = boot_ghcb;
+ else
+ ghcb = NULL;
+
+ do {
+ ret = ghcb ? svsm_perform_ghcb_protocol(ghcb, call)
+ : svsm_perform_msr_protocol(call);
+ } while (ret == -EAGAIN);
+
+ return ret;
+}
bool sev_snp_enabled(void)
{
@@ -145,8 +173,8 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
* If private -> shared then invalidate the page before requesting the
* state change in the RMP table.
*/
- if (op == SNP_PAGE_STATE_SHARED && pvalidate(paddr, RMP_PG_SIZE_4K, 0))
- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
+ if (op == SNP_PAGE_STATE_SHARED)
+ pvalidate_4k_page(paddr, paddr, false);
/* Issue VMGEXIT to change the page state in RMP table. */
sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op));
@@ -161,8 +189,8 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
* Now that page state is changed in the RMP table, validate it so that it is
* consistent with the RMP entry.
*/
- if (op == SNP_PAGE_STATE_PRIVATE && pvalidate(paddr, RMP_PG_SIZE_4K, 1))
- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
+ if (op == SNP_PAGE_STATE_PRIVATE)
+ pvalidate_4k_page(paddr, paddr, true);
}
void snp_set_page_private(unsigned long paddr)
@@ -256,6 +284,16 @@ void sev_es_shutdown_ghcb(void)
error("SEV-ES CPU Features missing.");
/*
+ * This denotes whether to use the GHCB MSR protocol or the GHCB
+ * shared page to perform a GHCB request. Since the GHCB page is
+ * being changed to encrypted, it can't be used to perform GHCB
+ * requests. Clear the boot_ghcb variable so that the GHCB MSR
+ * protocol is used to change the GHCB page over to an encrypted
+ * page.
+ */
+ boot_ghcb = NULL;
+
+ /*
* 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.
@@ -335,26 +373,6 @@ finish:
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
}
-static void enforce_vmpl0(void)
-{
- u64 attrs;
- int err;
-
- /*
- * RMPADJUST modifies RMP permissions of a lesser-privileged (numerically
- * higher) privilege level. Here, clear the VMPL1 permission mask of the
- * GHCB page. If the guest is not running at VMPL0, this will fail.
- *
- * If the guest is running at VMPL0, it will succeed. Even if that operation
- * modifies permission bits, it is still ok to do so currently because Linux
- * SNP guests are supported only on VMPL0 so VMPL1 or higher permission masks
- * changing is a don't-care.
- */
- attrs = 1;
- if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, attrs))
- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
-}
-
/*
* SNP_FEATURES_IMPL_REQ is the mask of SNP features that will need
* guest side implementation for proper functioning of the guest. If any
@@ -413,6 +431,92 @@ void snp_check_features(void)
}
}
+/* Search for Confidential Computing blob in the EFI config table. */
+static struct cc_blob_sev_info *find_cc_blob_efi(struct boot_params *bp)
+{
+ unsigned long cfg_table_pa;
+ unsigned int cfg_table_len;
+ int ret;
+
+ ret = efi_get_conf_table(bp, &cfg_table_pa, &cfg_table_len);
+ if (ret)
+ return NULL;
+
+ return (struct cc_blob_sev_info *)efi_find_vendor_table(bp, cfg_table_pa,
+ cfg_table_len,
+ EFI_CC_BLOB_GUID);
+}
+
+/*
+ * Initial set up of SNP relies on information provided by the
+ * Confidential Computing blob, which can be passed to the boot kernel
+ * by firmware/bootloader in the following ways:
+ *
+ * - via an entry in the EFI config table
+ * - via a setup_data structure, as defined by the Linux Boot Protocol
+ *
+ * Scan for the blob in that order.
+ */
+static struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
+{
+ struct cc_blob_sev_info *cc_info;
+
+ cc_info = find_cc_blob_efi(bp);
+ if (cc_info)
+ goto found_cc_info;
+
+ cc_info = find_cc_blob_setup_data(bp);
+ if (!cc_info)
+ return NULL;
+
+found_cc_info:
+ if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC)
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+
+ return cc_info;
+}
+
+/*
+ * Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks
+ * will verify the SNP CPUID/MSR bits.
+ */
+static bool early_snp_init(struct boot_params *bp)
+{
+ struct cc_blob_sev_info *cc_info;
+
+ if (!bp)
+ return false;
+
+ cc_info = find_cc_blob(bp);
+ if (!cc_info)
+ return false;
+
+ /*
+ * If a SNP-specific Confidential Computing blob is present, then
+ * firmware/bootloader have indicated SNP support. Verifying this
+ * involves CPUID checks which will be more reliable if the SNP
+ * CPUID table is used. See comments over snp_setup_cpuid_table() for
+ * more details.
+ */
+ setup_cpuid_table(cc_info);
+
+ /*
+ * Record the SVSM Calling Area (CA) address if the guest is not
+ * running at VMPL0. The CA will be used to communicate with the
+ * SVSM and request its services.
+ */
+ svsm_setup_ca(cc_info);
+
+ /*
+ * Pass run-time kernel a pointer to CC info via boot_params so EFI
+ * config table doesn't need to be searched again during early startup
+ * phase.
+ */
+ bp->cc_blob_address = (u32)(unsigned long)cc_info;
+
+ return true;
+}
+
/*
* sev_check_cpu_support - Check for SEV support in the CPU capabilities
*
@@ -463,7 +567,7 @@ void sev_enable(struct boot_params *bp)
bp->cc_blob_address = 0;
/*
- * Do an initial SEV capability check before snp_init() which
+ * Do an initial SEV capability check before early_snp_init() which
* loads the CPUID page and the same checks afterwards are done
* without the hypervisor and are trustworthy.
*
@@ -478,7 +582,7 @@ void sev_enable(struct boot_params *bp)
* Setup/preliminary detection of SNP. This will be sanity-checked
* against CPUID/MSR values later.
*/
- snp = snp_init(bp);
+ snp = early_snp_init(bp);
/* Now repeat the checks with the SNP CPUID table. */
@@ -506,10 +610,32 @@ void sev_enable(struct boot_params *bp)
* features.
*/
if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) {
- if (!(get_hv_features() & GHCB_HV_FT_SNP))
+ u64 hv_features;
+ int ret;
+
+ hv_features = get_hv_features();
+ if (!(hv_features & GHCB_HV_FT_SNP))
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
- enforce_vmpl0();
+ /*
+ * Enforce running at VMPL0 or with an SVSM.
+ *
+ * Use RMPADJUST (see the rmpadjust() function for a description of
+ * what the instruction does) to update the VMPL1 permissions of a
+ * page. If the guest is running at VMPL0, this will succeed. If the
+ * guest is running at any other VMPL, this will fail. Linux SNP guests
+ * only ever run at a single VMPL level so permission mask changes of a
+ * lesser-privileged VMPL are a don't-care.
+ */
+ ret = rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, 1);
+
+ /*
+ * Running at VMPL0 is not required if an SVSM is present and the hypervisor
+ * supports the required SVSM GHCB events.
+ */
+ if (ret &&
+ !(snp_vmpl && (hv_features & GHCB_HV_FT_SNP_MULTI_VMPL)))
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
}
if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
@@ -535,85 +661,6 @@ u64 sev_get_status(void)
return m.q;
}
-/* Search for Confidential Computing blob in the EFI config table. */
-static struct cc_blob_sev_info *find_cc_blob_efi(struct boot_params *bp)
-{
- unsigned long cfg_table_pa;
- unsigned int cfg_table_len;
- int ret;
-
- ret = efi_get_conf_table(bp, &cfg_table_pa, &cfg_table_len);
- if (ret)
- return NULL;
-
- return (struct cc_blob_sev_info *)efi_find_vendor_table(bp, cfg_table_pa,
- cfg_table_len,
- EFI_CC_BLOB_GUID);
-}
-
-/*
- * Initial set up of SNP relies on information provided by the
- * Confidential Computing blob, which can be passed to the boot kernel
- * by firmware/bootloader in the following ways:
- *
- * - via an entry in the EFI config table
- * - via a setup_data structure, as defined by the Linux Boot Protocol
- *
- * Scan for the blob in that order.
- */
-static struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
-{
- struct cc_blob_sev_info *cc_info;
-
- cc_info = find_cc_blob_efi(bp);
- if (cc_info)
- goto found_cc_info;
-
- cc_info = find_cc_blob_setup_data(bp);
- if (!cc_info)
- return NULL;
-
-found_cc_info:
- if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC)
- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
-
- return cc_info;
-}
-
-/*
- * Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks
- * will verify the SNP CPUID/MSR bits.
- */
-bool snp_init(struct boot_params *bp)
-{
- struct cc_blob_sev_info *cc_info;
-
- if (!bp)
- return false;
-
- cc_info = find_cc_blob(bp);
- if (!cc_info)
- return false;
-
- /*
- * If a SNP-specific Confidential Computing blob is present, then
- * firmware/bootloader have indicated SNP support. Verifying this
- * involves CPUID checks which will be more reliable if the SNP
- * CPUID table is used. See comments over snp_setup_cpuid_table() for
- * more details.
- */
- setup_cpuid_table(cc_info);
-
- /*
- * Pass run-time kernel a pointer to CC info via boot_params so EFI
- * config table doesn't need to be searched again during early startup
- * phase.
- */
- bp->cc_blob_address = (u32)(unsigned long)cc_info;
-
- return true;
-}
-
void sev_prep_identity_maps(unsigned long top_level_pgt)
{
/*
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index fed8d13ce252..0aae4d4ed615 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -203,7 +203,7 @@ int check_knl_erratum(void)
*/
if (!is_intel() ||
cpu.family != 6 ||
- cpu.model != INTEL_FAM6_XEON_PHI_KNL)
+ cpu.model != 0x57 /*INTEL_XEON_PHI_KNL*/)
return 0;
/*
diff --git a/arch/x86/boot/install.sh b/arch/x86/boot/install.sh
index 0849f4b42745..93784abcd66d 100755
--- a/arch/x86/boot/install.sh
+++ b/arch/x86/boot/install.sh
@@ -16,6 +16,8 @@
# $3 - kernel map file
# $4 - default install path (blank if root directory)
+set -e
+
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
fi
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index c4ea5258ab55..9d0fea18d3c8 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -27,34 +27,32 @@ char *heap_end = _end; /* Default end of heap = no heap */
* screws up the old-style command line protocol, adjust by
* filling in the new-style command line pointer instead.
*/
-
static void copy_boot_params(void)
{
struct old_cmdline {
u16 cl_magic;
u16 cl_offset;
};
- const struct old_cmdline * const oldcmd =
- absolute_pointer(OLD_CL_ADDRESS);
+ const struct old_cmdline * const oldcmd = absolute_pointer(OLD_CL_ADDRESS);
BUILD_BUG_ON(sizeof(boot_params) != 4096);
memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
- if (!boot_params.hdr.cmd_line_ptr &&
- oldcmd->cl_magic == OLD_CL_MAGIC) {
- /* Old-style command line protocol. */
+ if (!boot_params.hdr.cmd_line_ptr && oldcmd->cl_magic == OLD_CL_MAGIC) {
+ /* Old-style command line protocol */
u16 cmdline_seg;
- /* Figure out if the command line falls in the region
- of memory that an old kernel would have copied up
- to 0x90000... */
+ /*
+ * Figure out if the command line falls in the region
+ * of memory that an old kernel would have copied up
+ * to 0x90000...
+ */
if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
cmdline_seg = ds();
else
cmdline_seg = 0x9000;
- boot_params.hdr.cmd_line_ptr =
- (cmdline_seg << 4) + oldcmd->cl_offset;
+ boot_params.hdr.cmd_line_ptr = (cmdline_seg << 4) + oldcmd->cl_offset;
}
}
@@ -66,6 +64,7 @@ static void copy_boot_params(void)
static void keyboard_init(void)
{
struct biosregs ireg, oreg;
+
initregs(&ireg);
ireg.ah = 0x02; /* Get keyboard status */
@@ -83,8 +82,10 @@ static void query_ist(void)
{
struct biosregs ireg, oreg;
- /* Some older BIOSes apparently crash on this call, so filter
- it from machines too old to have SpeedStep at all. */
+ /*
+ * Some older BIOSes apparently crash on this call, so filter
+ * it from machines too old to have SpeedStep at all.
+ */
if (cpu.level < 6)
return;
@@ -119,17 +120,13 @@ static void init_heap(void)
char *stack_end;
if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
- asm("leal %P1(%%esp),%0"
- : "=r" (stack_end) : "i" (-STACK_SIZE));
-
- heap_end = (char *)
- ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
+ stack_end = (char *) (current_stack_pointer - STACK_SIZE);
+ heap_end = (char *) ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
if (heap_end > stack_end)
heap_end = stack_end;
} else {
/* Boot protocol 2.00 only, no heap available */
- puts("WARNING: Ancient bootloader, some functionality "
- "may be limited!\n");
+ puts("WARNING: Ancient bootloader, some functionality may be limited!\n");
}
}
@@ -150,12 +147,11 @@ void main(void)
/* Make sure we have all the proper CPU support */
if (validate_cpu()) {
- puts("Unable to boot - please use a kernel appropriate "
- "for your CPU.\n");
+ puts("Unable to boot - please use a kernel appropriate for your CPU.\n");
die();
}
- /* Tell the BIOS what CPU mode we intend to run in. */
+ /* Tell the BIOS what CPU mode we intend to run in */
set_bios_mode();
/* Detect memory layout */
diff --git a/arch/x86/boot/printf.c b/arch/x86/boot/printf.c
index 1237beeb9540..51dc14b714f6 100644
--- a/arch/x86/boot/printf.c
+++ b/arch/x86/boot/printf.c
@@ -246,6 +246,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
case 'x':
flags |= SMALL;
+ fallthrough;
case 'X':
base = 16;
break;
@@ -253,6 +254,8 @@ int vsprintf(char *buf, const char *fmt, va_list args)
case 'd':
case 'i':
flags |= SIGN;
+ break;
+
case 'u':
break;
diff --git a/arch/x86/coco/Makefile b/arch/x86/coco/Makefile
index c816acf78b6a..eabdc7486538 100644
--- a/arch/x86/coco/Makefile
+++ b/arch/x86/coco/Makefile
@@ -6,3 +6,4 @@ CFLAGS_core.o += -fno-stack-protector
obj-y += core.o
obj-$(CONFIG_INTEL_TDX_GUEST) += tdx/
+obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev/
diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index b31ef2424d19..0f81f70aca82 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -29,7 +29,6 @@ static bool noinstr intel_cc_platform_has(enum cc_attr attr)
{
switch (attr) {
case CC_ATTR_GUEST_UNROLL_STRING_IO:
- case CC_ATTR_HOTPLUG_DISABLED:
case CC_ATTR_GUEST_MEM_ENCRYPT:
case CC_ATTR_MEM_ENCRYPT:
return true;
diff --git a/arch/x86/coco/sev/Makefile b/arch/x86/coco/sev/Makefile
new file mode 100644
index 000000000000..4e375e7305ac
--- /dev/null
+++ b/arch/x86/coco/sev/Makefile
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += core.o
+
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_core.o = -pg
+endif
+
+KASAN_SANITIZE_core.o := n
+KMSAN_SANITIZE_core.o := n
+KCOV_INSTRUMENT_core.o := n
+
+# With some compiler versions the generated code results in boot hangs, caused
+# by several compilation units. To be safe, disable all instrumentation.
+KCSAN_SANITIZE := n
diff --git a/arch/x86/kernel/sev.c b/arch/x86/coco/sev/core.c
index 38ad066179d8..082d61d85dfc 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/coco/sev/core.c
@@ -133,16 +133,20 @@ struct ghcb_state {
struct ghcb *ghcb;
};
+/* For early boot SVSM communication */
+static struct svsm_ca boot_svsm_ca_page __aligned(PAGE_SIZE);
+
static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data);
static DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
+static DEFINE_PER_CPU(struct svsm_ca *, svsm_caa);
+static DEFINE_PER_CPU(u64, svsm_caa_pa);
struct sev_config {
__u64 debug : 1,
/*
- * A flag used by __set_pages_state() that indicates when the
- * per-CPU GHCB has been created and registered and thus can be
- * used by the BSP instead of the early boot GHCB.
+ * Indicates when the per-CPU GHCB has been created and registered
+ * and thus can be used by the BSP instead of the early boot GHCB.
*
* For APs, the per-CPU GHCB is created before they are started
* and registered upon startup, so this flag can be used globally
@@ -150,6 +154,15 @@ struct sev_config {
*/
ghcbs_initialized : 1,
+ /*
+ * Indicates when the per-CPU SVSM CA is to be used instead of the
+ * boot SVSM CA.
+ *
+ * For APs, the per-CPU SVSM CA is created as part of the AP
+ * bringup, so this flag can be used globally for the BSP and APs.
+ */
+ use_cas : 1,
+
__reserved : 62;
};
@@ -572,8 +585,61 @@ fault:
return ES_EXCEPTION;
}
+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_PF:
+ write_cr2(ctxt->fi.cr2);
+ exc_page_fault(ctxt->regs, error_code);
+ 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();
+ }
+}
+
/* Include code shared with pre-decompression boot stage */
-#include "sev-shared.c"
+#include "shared.c"
+
+static inline struct svsm_ca *svsm_get_caa(void)
+{
+ /*
+ * Use rIP-relative references when called early in the boot. If
+ * ->use_cas is set, then it is late in the boot and no need
+ * to worry about rIP-relative references.
+ */
+ if (RIP_REL_REF(sev_cfg).use_cas)
+ return this_cpu_read(svsm_caa);
+ else
+ return RIP_REL_REF(boot_svsm_caa);
+}
+
+static u64 svsm_get_caa_pa(void)
+{
+ /*
+ * Use rIP-relative references when called early in the boot. If
+ * ->use_cas is set, then it is late in the boot and no need
+ * to worry about rIP-relative references.
+ */
+ if (RIP_REL_REF(sev_cfg).use_cas)
+ return this_cpu_read(svsm_caa_pa);
+ else
+ return RIP_REL_REF(boot_svsm_caa_pa);
+}
static noinstr void __sev_put_ghcb(struct ghcb_state *state)
{
@@ -600,6 +666,44 @@ static noinstr void __sev_put_ghcb(struct ghcb_state *state)
}
}
+static int svsm_perform_call_protocol(struct svsm_call *call)
+{
+ struct ghcb_state state;
+ unsigned long flags;
+ struct ghcb *ghcb;
+ int ret;
+
+ /*
+ * This can be called very early in the boot, use native functions in
+ * order to avoid paravirt issues.
+ */
+ flags = native_local_irq_save();
+
+ /*
+ * Use rip-relative references when called early in the boot. If
+ * ghcbs_initialized is set, then it is late in the boot and no need
+ * to worry about rip-relative references in called functions.
+ */
+ if (RIP_REL_REF(sev_cfg).ghcbs_initialized)
+ ghcb = __sev_get_ghcb(&state);
+ else if (RIP_REL_REF(boot_ghcb))
+ ghcb = RIP_REL_REF(boot_ghcb);
+ else
+ ghcb = NULL;
+
+ do {
+ ret = ghcb ? svsm_perform_ghcb_protocol(ghcb, call)
+ : svsm_perform_msr_protocol(call);
+ } while (ret == -EAGAIN);
+
+ if (RIP_REL_REF(sev_cfg).ghcbs_initialized)
+ __sev_put_ghcb(&state);
+
+ native_local_irq_restore(flags);
+
+ return ret;
+}
+
void noinstr __sev_es_nmi_complete(void)
{
struct ghcb_state state;
@@ -648,7 +752,7 @@ static u64 __init get_secrets_page(void)
static u64 __init get_snp_jump_table_addr(void)
{
- struct snp_secrets_page_layout *layout;
+ struct snp_secrets_page *secrets;
void __iomem *mem;
u64 pa, addr;
@@ -662,9 +766,9 @@ static u64 __init get_snp_jump_table_addr(void)
return 0;
}
- layout = (__force struct snp_secrets_page_layout *)mem;
+ secrets = (__force struct snp_secrets_page *)mem;
- addr = layout->os_area.ap_jump_table_pa;
+ addr = secrets->os_area.ap_jump_table_pa;
iounmap(mem);
return addr;
@@ -709,7 +813,6 @@ early_set_pages_state(unsigned long vaddr, unsigned long paddr,
{
unsigned long paddr_end;
u64 val;
- int ret;
vaddr = vaddr & PAGE_MASK;
@@ -717,12 +820,9 @@ early_set_pages_state(unsigned long vaddr, unsigned long paddr,
paddr_end = paddr + (npages << PAGE_SHIFT);
while (paddr < paddr_end) {
- if (op == SNP_PAGE_STATE_SHARED) {
- /* Page validation must be rescinded before changing to shared */
- ret = pvalidate(vaddr, RMP_PG_SIZE_4K, false);
- if (WARN(ret, "Failed to validate address 0x%lx ret %d", paddr, ret))
- goto e_term;
- }
+ /* Page validation must be rescinded before changing to shared */
+ if (op == SNP_PAGE_STATE_SHARED)
+ pvalidate_4k_page(vaddr, paddr, false);
/*
* Use the MSR protocol because this function can be called before
@@ -744,12 +844,9 @@ early_set_pages_state(unsigned long vaddr, unsigned long paddr,
paddr, GHCB_MSR_PSC_RESP_VAL(val)))
goto e_term;
- if (op == SNP_PAGE_STATE_PRIVATE) {
- /* Page validation must be performed after changing to private */
- ret = pvalidate(vaddr, RMP_PG_SIZE_4K, true);
- if (WARN(ret, "Failed to validate address 0x%lx ret %d", paddr, ret))
- goto e_term;
- }
+ /* Page validation must be performed after changing to private */
+ if (op == SNP_PAGE_STATE_PRIVATE)
+ pvalidate_4k_page(vaddr, paddr, true);
vaddr += PAGE_SIZE;
paddr += PAGE_SIZE;
@@ -913,22 +1010,49 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end)
set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE);
}
-static int snp_set_vmsa(void *va, bool vmsa)
+static int snp_set_vmsa(void *va, void *caa, int apic_id, bool make_vmsa)
{
- u64 attrs;
+ int ret;
- /*
- * Running at VMPL0 allows the kernel to change the VMSA bit for a page
- * using the RMPADJUST instruction. However, for the instruction to
- * succeed it must target the permissions of a lesser privileged
- * (higher numbered) VMPL level, so use VMPL1 (refer to the RMPADJUST
- * instruction in the AMD64 APM Volume 3).
- */
- attrs = 1;
- if (vmsa)
- attrs |= RMPADJUST_VMSA_PAGE_BIT;
+ if (snp_vmpl) {
+ struct svsm_call call = {};
+ unsigned long flags;
+
+ local_irq_save(flags);
- return rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs);
+ call.caa = this_cpu_read(svsm_caa);
+ call.rcx = __pa(va);
+
+ if (make_vmsa) {
+ /* Protocol 0, Call ID 2 */
+ call.rax = SVSM_CORE_CALL(SVSM_CORE_CREATE_VCPU);
+ call.rdx = __pa(caa);
+ call.r8 = apic_id;
+ } else {
+ /* Protocol 0, Call ID 3 */
+ call.rax = SVSM_CORE_CALL(SVSM_CORE_DELETE_VCPU);
+ }
+
+ ret = svsm_perform_call_protocol(&call);
+
+ local_irq_restore(flags);
+ } else {
+ /*
+ * If the kernel runs at VMPL0, it can change the VMSA
+ * bit for a page using the RMPADJUST instruction.
+ * However, for the instruction to succeed it must
+ * target the permissions of a lesser privileged (higher
+ * numbered) VMPL level, so use VMPL1.
+ */
+ u64 attrs = 1;
+
+ if (make_vmsa)
+ attrs |= RMPADJUST_VMSA_PAGE_BIT;
+
+ ret = rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs);
+ }
+
+ return ret;
}
#define __ATTR_BASE (SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK)
@@ -938,7 +1062,7 @@ static int snp_set_vmsa(void *va, bool vmsa)
#define INIT_LDTR_ATTRIBS (SVM_SELECTOR_P_MASK | 2)
#define INIT_TR_ATTRIBS (SVM_SELECTOR_P_MASK | 3)
-static void *snp_alloc_vmsa_page(void)
+static void *snp_alloc_vmsa_page(int cpu)
{
struct page *p;
@@ -950,7 +1074,7 @@ static void *snp_alloc_vmsa_page(void)
*
* Allocate an 8k page which is also 8k-aligned.
*/
- p = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO, 1);
+ p = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL_ACCOUNT | __GFP_ZERO, 1);
if (!p)
return NULL;
@@ -962,11 +1086,11 @@ static void *snp_alloc_vmsa_page(void)
return page_address(p + 1);
}
-static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
+static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa, int apic_id)
{
int err;
- err = snp_set_vmsa(vmsa, false);
+ err = snp_set_vmsa(vmsa, NULL, apic_id, false);
if (err)
pr_err("clear VMSA page failed (%u), leaking page\n", err);
else
@@ -977,6 +1101,7 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
{
struct sev_es_save_area *cur_vmsa, *vmsa;
struct ghcb_state state;
+ struct svsm_ca *caa;
unsigned long flags;
struct ghcb *ghcb;
u8 sipi_vector;
@@ -1019,10 +1144,13 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
* #VMEXIT of that vCPU would wipe out all of the settings being done
* here.
*/
- vmsa = (struct sev_es_save_area *)snp_alloc_vmsa_page();
+ vmsa = (struct sev_es_save_area *)snp_alloc_vmsa_page(cpu);
if (!vmsa)
return -ENOMEM;
+ /* If an SVSM is present, the SVSM per-CPU CAA will be !NULL */
+ caa = per_cpu(svsm_caa, cpu);
+
/* CR4 should maintain the MCE value */
cr4 = native_read_cr4() & X86_CR4_MCE;
@@ -1070,11 +1198,11 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
* VMPL level
* SEV_FEATURES (matches the SEV STATUS MSR right shifted 2 bits)
*/
- vmsa->vmpl = 0;
+ vmsa->vmpl = snp_vmpl;
vmsa->sev_features = sev_status >> 2;
/* Switch the page over to a VMSA page now that it is initialized */
- ret = snp_set_vmsa(vmsa, true);
+ ret = snp_set_vmsa(vmsa, caa, apic_id, true);
if (ret) {
pr_err("set VMSA page failed (%u)\n", ret);
free_page((unsigned long)vmsa);
@@ -1090,7 +1218,10 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
vc_ghcb_invalidate(ghcb);
ghcb_set_rax(ghcb, vmsa->sev_features);
ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_CREATION);
- ghcb_set_sw_exit_info_1(ghcb, ((u64)apic_id << 32) | SVM_VMGEXIT_AP_CREATE);
+ ghcb_set_sw_exit_info_1(ghcb,
+ ((u64)apic_id << 32) |
+ ((u64)snp_vmpl << 16) |
+ SVM_VMGEXIT_AP_CREATE);
ghcb_set_sw_exit_info_2(ghcb, __pa(vmsa));
sev_es_wr_ghcb_msr(__pa(ghcb));
@@ -1108,13 +1239,13 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
/* Perform cleanup if there was an error */
if (ret) {
- snp_cleanup_vmsa(vmsa);
+ snp_cleanup_vmsa(vmsa, apic_id);
vmsa = NULL;
}
/* Free up any previous VMSA page */
if (cur_vmsa)
- snp_cleanup_vmsa(cur_vmsa);
+ snp_cleanup_vmsa(cur_vmsa, apic_id);
/* Record the current VMSA page */
per_cpu(sev_vmsa, cpu) = vmsa;
@@ -1209,6 +1340,17 @@ static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
/* Is it a WRMSR? */
exit_info_1 = (ctxt->insn.opcode.bytes[1] == 0x30) ? 1 : 0;
+ if (regs->cx == MSR_SVSM_CAA) {
+ /* Writes to the SVSM CAA msr are ignored */
+ if (exit_info_1)
+ return ES_OK;
+
+ regs->ax = lower_32_bits(this_cpu_read(svsm_caa_pa));
+ regs->dx = upper_32_bits(this_cpu_read(svsm_caa_pa));
+
+ return ES_OK;
+ }
+
ghcb_set_rcx(ghcb, regs->cx);
if (exit_info_1) {
ghcb_set_rax(ghcb, regs->ax);
@@ -1341,11 +1483,23 @@ static void __init alloc_runtime_data(int cpu)
{
struct sev_es_runtime_data *data;
- data = memblock_alloc(sizeof(*data), PAGE_SIZE);
+ data = memblock_alloc_node(sizeof(*data), PAGE_SIZE, cpu_to_node(cpu));
if (!data)
panic("Can't allocate SEV-ES runtime data");
per_cpu(runtime_data, cpu) = data;
+
+ if (snp_vmpl) {
+ struct svsm_ca *caa;
+
+ /* Allocate the SVSM CA page if an SVSM is present */
+ caa = memblock_alloc(sizeof(*caa), PAGE_SIZE);
+ if (!caa)
+ panic("Can't allocate SVSM CA page\n");
+
+ per_cpu(svsm_caa, cpu) = caa;
+ per_cpu(svsm_caa_pa, cpu) = __pa(caa);
+ }
}
static void __init init_ghcb(int cpu)
@@ -1395,6 +1549,32 @@ void __init sev_es_init_vc_handling(void)
init_ghcb(cpu);
}
+ /* If running under an SVSM, switch to the per-cpu CA */
+ if (snp_vmpl) {
+ struct svsm_call call = {};
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+
+ /*
+ * SVSM_CORE_REMAP_CA call:
+ * RAX = 0 (Protocol=0, CallID=0)
+ * RCX = New CA GPA
+ */
+ call.caa = svsm_get_caa();
+ call.rax = SVSM_CORE_CALL(SVSM_CORE_REMAP_CA);
+ call.rcx = this_cpu_read(svsm_caa_pa);
+ ret = svsm_perform_call_protocol(&call);
+ if (ret)
+ panic("Can't remap the SVSM CA, ret=%d, rax_out=0x%llx\n",
+ ret, call.rax_out);
+
+ sev_cfg.use_cas = true;
+
+ local_irq_restore(flags);
+ }
+
sev_es_setup_play_dead();
/* Secondary CPUs use the runtime #VC handler */
@@ -1819,33 +1999,6 @@ static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt,
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_PF:
- write_cr2(ctxt->fi.cr2);
- exc_page_fault(ctxt->regs, error_code);
- 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 is_vc2_stack(unsigned long sp)
{
return (sp >= __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_va(VC2));
@@ -2095,6 +2248,47 @@ found_cc_info:
return cc_info;
}
+static __head void svsm_setup(struct cc_blob_sev_info *cc_info)
+{
+ struct svsm_call call = {};
+ int ret;
+ u64 pa;
+
+ /*
+ * Record the SVSM Calling Area address (CAA) if the guest is not
+ * running at VMPL0. The CA will be used to communicate with the
+ * SVSM to perform the SVSM services.
+ */
+ if (!svsm_setup_ca(cc_info))
+ return;
+
+ /*
+ * It is very early in the boot and the kernel is running identity
+ * mapped but without having adjusted the pagetables to where the
+ * kernel was loaded (physbase), so the get the CA address using
+ * RIP-relative addressing.
+ */
+ pa = (u64)&RIP_REL_REF(boot_svsm_ca_page);
+
+ /*
+ * Switch over to the boot SVSM CA while the current CA is still
+ * addressable. There is no GHCB at this point so use the MSR protocol.
+ *
+ * SVSM_CORE_REMAP_CA call:
+ * RAX = 0 (Protocol=0, CallID=0)
+ * RCX = New CA GPA
+ */
+ call.caa = svsm_get_caa();
+ call.rax = SVSM_CORE_CALL(SVSM_CORE_REMAP_CA);
+ call.rcx = pa;
+ ret = svsm_perform_call_protocol(&call);
+ if (ret)
+ panic("Can't remap the SVSM CA, ret=%d, rax_out=0x%llx\n", ret, call.rax_out);
+
+ RIP_REL_REF(boot_svsm_caa) = (struct svsm_ca *)pa;
+ RIP_REL_REF(boot_svsm_caa_pa) = pa;
+}
+
bool __head snp_init(struct boot_params *bp)
{
struct cc_blob_sev_info *cc_info;
@@ -2108,6 +2302,8 @@ bool __head snp_init(struct boot_params *bp)
setup_cpuid_table(cc_info);
+ svsm_setup(cc_info);
+
/*
* The CC blob will be used later to access the secrets page. Cache
* it here like the boot kernel does.
@@ -2156,23 +2352,27 @@ static void dump_cpuid_table(void)
* expected, but that initialization happens too early in boot to print any
* sort of indicator, and there's not really any other good place to do it,
* so do it here.
+ *
+ * If running as an SNP guest, report the current VM privilege level (VMPL).
*/
-static int __init report_cpuid_table(void)
+static int __init report_snp_info(void)
{
const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
- if (!cpuid_table->count)
- return 0;
+ if (cpuid_table->count) {
+ pr_info("Using SNP CPUID table, %d entries present.\n",
+ cpuid_table->count);
- pr_info("Using SNP CPUID table, %d entries present.\n",
- cpuid_table->count);
+ if (sev_cfg.debug)
+ dump_cpuid_table();
+ }
- if (sev_cfg.debug)
- dump_cpuid_table();
+ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+ pr_info("SNP running at VMPL%u.\n", snp_vmpl);
return 0;
}
-arch_initcall(report_cpuid_table);
+arch_initcall(report_snp_info);
static int __init init_sev_config(char *str)
{
@@ -2191,6 +2391,56 @@ static int __init init_sev_config(char *str)
}
__setup("sev=", init_sev_config);
+static void update_attest_input(struct svsm_call *call, struct svsm_attest_call *input)
+{
+ /* If (new) lengths have been returned, propagate them up */
+ if (call->rcx_out != call->rcx)
+ input->manifest_buf.len = call->rcx_out;
+
+ if (call->rdx_out != call->rdx)
+ input->certificates_buf.len = call->rdx_out;
+
+ if (call->r8_out != call->r8)
+ input->report_buf.len = call->r8_out;
+}
+
+int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call,
+ struct svsm_attest_call *input)
+{
+ struct svsm_attest_call *ac;
+ unsigned long flags;
+ u64 attest_call_pa;
+ int ret;
+
+ if (!snp_vmpl)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ call->caa = svsm_get_caa();
+
+ ac = (struct svsm_attest_call *)call->caa->svsm_buffer;
+ attest_call_pa = svsm_get_caa_pa() + offsetof(struct svsm_ca, svsm_buffer);
+
+ *ac = *input;
+
+ /*
+ * Set input registers for the request and set RDX and R8 to known
+ * values in order to detect length values being returned in them.
+ */
+ call->rax = call_id;
+ call->rcx = attest_call_pa;
+ call->rdx = -1;
+ call->r8 = -1;
+ ret = svsm_perform_call_protocol(call);
+ update_attest_input(call, input);
+
+ local_irq_restore(flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snp_issue_svsm_attest_req);
+
int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio)
{
struct ghcb_state state;
@@ -2299,3 +2549,58 @@ void sev_show_status(void)
}
pr_cont("\n");
}
+
+void __init snp_update_svsm_ca(void)
+{
+ if (!snp_vmpl)
+ return;
+
+ /* Update the CAA to a proper kernel address */
+ boot_svsm_caa = &boot_svsm_ca_page;
+}
+
+#ifdef CONFIG_SYSFS
+static ssize_t vmpl_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", snp_vmpl);
+}
+
+static struct kobj_attribute vmpl_attr = __ATTR_RO(vmpl);
+
+static struct attribute *vmpl_attrs[] = {
+ &vmpl_attr.attr,
+ NULL
+};
+
+static struct attribute_group sev_attr_group = {
+ .attrs = vmpl_attrs,
+};
+
+static int __init sev_sysfs_init(void)
+{
+ struct kobject *sev_kobj;
+ struct device *dev_root;
+ int ret;
+
+ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+ return -ENODEV;
+
+ dev_root = bus_get_dev_root(&cpu_subsys);
+ if (!dev_root)
+ return -ENODEV;
+
+ sev_kobj = kobject_create_and_add("sev", &dev_root->kobj);
+ put_device(dev_root);
+
+ if (!sev_kobj)
+ return -ENOMEM;
+
+ ret = sysfs_create_group(sev_kobj, &sev_attr_group);
+ if (ret)
+ kobject_put(sev_kobj);
+
+ return ret;
+}
+arch_initcall(sev_sysfs_init);
+#endif // CONFIG_SYSFS
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/coco/sev/shared.c
index b4f8fa0f722c..71de53194089 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/coco/sev/shared.c
@@ -21,8 +21,30 @@
#define WARN(condition, format...) (!!(condition))
#define sev_printk(fmt, ...)
#define sev_printk_rtl(fmt, ...)
+#undef vc_forward_exception
+#define vc_forward_exception(c) panic("SNP: Hypervisor requested exception\n")
#endif
+/*
+ * SVSM related information:
+ * When running under an SVSM, the VMPL that Linux is executing at must be
+ * non-zero. The VMPL is therefore used to indicate the presence of an SVSM.
+ *
+ * During boot, the page tables are set up as identity mapped and later
+ * changed to use kernel virtual addresses. Maintain separate virtual and
+ * physical addresses for the CAA to allow SVSM functions to be used during
+ * early boot, both with identity mapped virtual addresses and proper kernel
+ * virtual addresses.
+ */
+u8 snp_vmpl __ro_after_init;
+EXPORT_SYMBOL_GPL(snp_vmpl);
+static struct svsm_ca *boot_svsm_caa __ro_after_init;
+static u64 boot_svsm_caa_pa __ro_after_init;
+
+static struct svsm_ca *svsm_get_caa(void);
+static u64 svsm_get_caa_pa(void);
+static int svsm_perform_call_protocol(struct svsm_call *call);
+
/* I/O parameters for CPUID-related helpers */
struct cpuid_leaf {
u32 fn;
@@ -229,6 +251,126 @@ static enum es_result verify_exception_info(struct ghcb *ghcb, struct es_em_ctxt
return ES_VMM_ERROR;
}
+static inline int svsm_process_result_codes(struct svsm_call *call)
+{
+ switch (call->rax_out) {
+ case SVSM_SUCCESS:
+ return 0;
+ case SVSM_ERR_INCOMPLETE:
+ case SVSM_ERR_BUSY:
+ return -EAGAIN;
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * Issue a VMGEXIT to call the SVSM:
+ * - Load the SVSM register state (RAX, RCX, RDX, R8 and R9)
+ * - Set the CA call pending field to 1
+ * - Issue VMGEXIT
+ * - Save the SVSM return register state (RAX, RCX, RDX, R8 and R9)
+ * - Perform atomic exchange of the CA call pending field
+ *
+ * - See the "Secure VM Service Module for SEV-SNP Guests" specification for
+ * details on the calling convention.
+ * - The calling convention loosely follows the Microsoft X64 calling
+ * convention by putting arguments in RCX, RDX, R8 and R9.
+ * - RAX specifies the SVSM protocol/callid as input and the return code
+ * as output.
+ */
+static __always_inline void svsm_issue_call(struct svsm_call *call, u8 *pending)
+{
+ register unsigned long rax asm("rax") = call->rax;
+ register unsigned long rcx asm("rcx") = call->rcx;
+ register unsigned long rdx asm("rdx") = call->rdx;
+ register unsigned long r8 asm("r8") = call->r8;
+ register unsigned long r9 asm("r9") = call->r9;
+
+ call->caa->call_pending = 1;
+
+ asm volatile("rep; vmmcall\n\t"
+ : "+r" (rax), "+r" (rcx), "+r" (rdx), "+r" (r8), "+r" (r9)
+ : : "memory");
+
+ *pending = xchg(&call->caa->call_pending, *pending);
+
+ call->rax_out = rax;
+ call->rcx_out = rcx;
+ call->rdx_out = rdx;
+ call->r8_out = r8;
+ call->r9_out = r9;
+}
+
+static int svsm_perform_msr_protocol(struct svsm_call *call)
+{
+ u8 pending = 0;
+ u64 val, resp;
+
+ /*
+ * When using the MSR protocol, be sure to save and restore
+ * the current MSR value.
+ */
+ val = sev_es_rd_ghcb_msr();
+
+ sev_es_wr_ghcb_msr(GHCB_MSR_VMPL_REQ_LEVEL(0));
+
+ svsm_issue_call(call, &pending);
+
+ resp = sev_es_rd_ghcb_msr();
+
+ sev_es_wr_ghcb_msr(val);
+
+ if (pending)
+ return -EINVAL;
+
+ if (GHCB_RESP_CODE(resp) != GHCB_MSR_VMPL_RESP)
+ return -EINVAL;
+
+ if (GHCB_MSR_VMPL_RESP_VAL(resp))
+ return -EINVAL;
+
+ return svsm_process_result_codes(call);
+}
+
+static int svsm_perform_ghcb_protocol(struct ghcb *ghcb, struct svsm_call *call)
+{
+ struct es_em_ctxt ctxt;
+ u8 pending = 0;
+
+ vc_ghcb_invalidate(ghcb);
+
+ /*
+ * Fill in protocol and format specifiers. This can be called very early
+ * in the boot, so use rip-relative references as needed.
+ */
+ ghcb->protocol_version = RIP_REL_REF(ghcb_version);
+ ghcb->ghcb_usage = GHCB_DEFAULT_USAGE;
+
+ ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_SNP_RUN_VMPL);
+ ghcb_set_sw_exit_info_1(ghcb, 0);
+ ghcb_set_sw_exit_info_2(ghcb, 0);
+
+ sev_es_wr_ghcb_msr(__pa(ghcb));
+
+ svsm_issue_call(call, &pending);
+
+ if (pending)
+ return -EINVAL;
+
+ switch (verify_exception_info(ghcb, &ctxt)) {
+ case ES_OK:
+ break;
+ case ES_EXCEPTION:
+ vc_forward_exception(&ctxt);
+ fallthrough;
+ default:
+ return -EINVAL;
+ }
+
+ return svsm_process_result_codes(call);
+}
+
static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
struct es_em_ctxt *ctxt,
u64 exit_code, u64 exit_info_1,
@@ -1079,38 +1221,268 @@ static void __head setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
}
}
-static void pvalidate_pages(struct snp_psc_desc *desc)
+static inline void __pval_terminate(u64 pfn, bool action, unsigned int page_size,
+ int ret, u64 svsm_ret)
+{
+ WARN(1, "PVALIDATE failure: pfn: 0x%llx, action: %u, size: %u, ret: %d, svsm_ret: 0x%llx\n",
+ pfn, action, page_size, ret, svsm_ret);
+
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
+}
+
+static void svsm_pval_terminate(struct svsm_pvalidate_call *pc, int ret, u64 svsm_ret)
+{
+ unsigned int page_size;
+ bool action;
+ u64 pfn;
+
+ pfn = pc->entry[pc->cur_index].pfn;
+ action = pc->entry[pc->cur_index].action;
+ page_size = pc->entry[pc->cur_index].page_size;
+
+ __pval_terminate(pfn, action, page_size, ret, svsm_ret);
+}
+
+static void svsm_pval_4k_page(unsigned long paddr, bool validate)
+{
+ struct svsm_pvalidate_call *pc;
+ struct svsm_call call = {};
+ unsigned long flags;
+ u64 pc_pa;
+ int ret;
+
+ /*
+ * This can be called very early in the boot, use native functions in
+ * order to avoid paravirt issues.
+ */
+ flags = native_local_irq_save();
+
+ call.caa = svsm_get_caa();
+
+ pc = (struct svsm_pvalidate_call *)call.caa->svsm_buffer;
+ pc_pa = svsm_get_caa_pa() + offsetof(struct svsm_ca, svsm_buffer);
+
+ pc->num_entries = 1;
+ pc->cur_index = 0;
+ pc->entry[0].page_size = RMP_PG_SIZE_4K;
+ pc->entry[0].action = validate;
+ pc->entry[0].ignore_cf = 0;
+ pc->entry[0].pfn = paddr >> PAGE_SHIFT;
+
+ /* Protocol 0, Call ID 1 */
+ call.rax = SVSM_CORE_CALL(SVSM_CORE_PVALIDATE);
+ call.rcx = pc_pa;
+
+ ret = svsm_perform_call_protocol(&call);
+ if (ret)
+ svsm_pval_terminate(pc, ret, call.rax_out);
+
+ native_local_irq_restore(flags);
+}
+
+static void pvalidate_4k_page(unsigned long vaddr, unsigned long paddr, bool validate)
+{
+ int ret;
+
+ /*
+ * This can be called very early during boot, so use rIP-relative
+ * references as needed.
+ */
+ if (RIP_REL_REF(snp_vmpl)) {
+ svsm_pval_4k_page(paddr, validate);
+ } else {
+ ret = pvalidate(vaddr, RMP_PG_SIZE_4K, validate);
+ if (ret)
+ __pval_terminate(PHYS_PFN(paddr), validate, RMP_PG_SIZE_4K, ret, 0);
+ }
+}
+
+static void pval_pages(struct snp_psc_desc *desc)
{
struct psc_entry *e;
unsigned long vaddr;
unsigned int size;
unsigned int i;
bool validate;
+ u64 pfn;
int rc;
for (i = 0; i <= desc->hdr.end_entry; i++) {
e = &desc->entries[i];
- vaddr = (unsigned long)pfn_to_kaddr(e->gfn);
+ pfn = e->gfn;
+ vaddr = (unsigned long)pfn_to_kaddr(pfn);
size = e->pagesize ? RMP_PG_SIZE_2M : RMP_PG_SIZE_4K;
validate = e->operation == SNP_PAGE_STATE_PRIVATE;
rc = pvalidate(vaddr, size, validate);
+ if (!rc)
+ continue;
+
if (rc == PVALIDATE_FAIL_SIZEMISMATCH && size == RMP_PG_SIZE_2M) {
unsigned long vaddr_end = vaddr + PMD_SIZE;
- for (; vaddr < vaddr_end; vaddr += PAGE_SIZE) {
+ for (; vaddr < vaddr_end; vaddr += PAGE_SIZE, pfn++) {
rc = pvalidate(vaddr, RMP_PG_SIZE_4K, validate);
if (rc)
- break;
+ __pval_terminate(pfn, validate, RMP_PG_SIZE_4K, rc, 0);
}
+ } else {
+ __pval_terminate(pfn, validate, size, rc, 0);
}
+ }
+}
+
+static u64 svsm_build_ca_from_pfn_range(u64 pfn, u64 pfn_end, bool action,
+ struct svsm_pvalidate_call *pc)
+{
+ struct svsm_pvalidate_entry *pe;
+
+ /* Nothing in the CA yet */
+ pc->num_entries = 0;
+ pc->cur_index = 0;
+
+ pe = &pc->entry[0];
+
+ while (pfn < pfn_end) {
+ pe->page_size = RMP_PG_SIZE_4K;
+ pe->action = action;
+ pe->ignore_cf = 0;
+ pe->pfn = pfn;
+
+ pe++;
+ pfn++;
+
+ pc->num_entries++;
+ if (pc->num_entries == SVSM_PVALIDATE_MAX_COUNT)
+ break;
+ }
+
+ return pfn;
+}
+
+static int svsm_build_ca_from_psc_desc(struct snp_psc_desc *desc, unsigned int desc_entry,
+ struct svsm_pvalidate_call *pc)
+{
+ struct svsm_pvalidate_entry *pe;
+ struct psc_entry *e;
+
+ /* Nothing in the CA yet */
+ pc->num_entries = 0;
+ pc->cur_index = 0;
+
+ pe = &pc->entry[0];
+ e = &desc->entries[desc_entry];
+
+ while (desc_entry <= desc->hdr.end_entry) {
+ pe->page_size = e->pagesize ? RMP_PG_SIZE_2M : RMP_PG_SIZE_4K;
+ pe->action = e->operation == SNP_PAGE_STATE_PRIVATE;
+ pe->ignore_cf = 0;
+ pe->pfn = e->gfn;
+
+ pe++;
+ e++;
+
+ desc_entry++;
+ pc->num_entries++;
+ if (pc->num_entries == SVSM_PVALIDATE_MAX_COUNT)
+ break;
+ }
+
+ return desc_entry;
+}
+
+static void svsm_pval_pages(struct snp_psc_desc *desc)
+{
+ struct svsm_pvalidate_entry pv_4k[VMGEXIT_PSC_MAX_ENTRY];
+ unsigned int i, pv_4k_count = 0;
+ struct svsm_pvalidate_call *pc;
+ struct svsm_call call = {};
+ unsigned long flags;
+ bool action;
+ u64 pc_pa;
+ int ret;
+
+ /*
+ * This can be called very early in the boot, use native functions in
+ * order to avoid paravirt issues.
+ */
+ flags = native_local_irq_save();
+
+ /*
+ * The SVSM calling area (CA) can support processing 510 entries at a
+ * time. Loop through the Page State Change descriptor until the CA is
+ * full or the last entry in the descriptor is reached, at which time
+ * the SVSM is invoked. This repeats until all entries in the descriptor
+ * are processed.
+ */
+ call.caa = svsm_get_caa();
+
+ pc = (struct svsm_pvalidate_call *)call.caa->svsm_buffer;
+ pc_pa = svsm_get_caa_pa() + offsetof(struct svsm_ca, svsm_buffer);
+
+ /* Protocol 0, Call ID 1 */
+ call.rax = SVSM_CORE_CALL(SVSM_CORE_PVALIDATE);
+ call.rcx = pc_pa;
+
+ for (i = 0; i <= desc->hdr.end_entry;) {
+ i = svsm_build_ca_from_psc_desc(desc, i, pc);
+
+ do {
+ ret = svsm_perform_call_protocol(&call);
+ if (!ret)
+ continue;
+
+ /*
+ * Check if the entry failed because of an RMP mismatch (a
+ * PVALIDATE at 2M was requested, but the page is mapped in
+ * the RMP as 4K).
+ */
- if (rc) {
- WARN(1, "Failed to validate address 0x%lx ret %d", vaddr, rc);
- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
+ if (call.rax_out == SVSM_PVALIDATE_FAIL_SIZEMISMATCH &&
+ pc->entry[pc->cur_index].page_size == RMP_PG_SIZE_2M) {
+ /* Save this entry for post-processing at 4K */
+ pv_4k[pv_4k_count++] = pc->entry[pc->cur_index];
+
+ /* Skip to the next one unless at the end of the list */
+ pc->cur_index++;
+ if (pc->cur_index < pc->num_entries)
+ ret = -EAGAIN;
+ else
+ ret = 0;
+ }
+ } while (ret == -EAGAIN);
+
+ if (ret)
+ svsm_pval_terminate(pc, ret, call.rax_out);
+ }
+
+ /* Process any entries that failed to be validated at 2M and validate them at 4K */
+ for (i = 0; i < pv_4k_count; i++) {
+ u64 pfn, pfn_end;
+
+ action = pv_4k[i].action;
+ pfn = pv_4k[i].pfn;
+ pfn_end = pfn + 512;
+
+ while (pfn < pfn_end) {
+ pfn = svsm_build_ca_from_pfn_range(pfn, pfn_end, action, pc);
+
+ ret = svsm_perform_call_protocol(&call);
+ if (ret)
+ svsm_pval_terminate(pc, ret, call.rax_out);
}
}
+
+ native_local_irq_restore(flags);
+}
+
+static void pvalidate_pages(struct snp_psc_desc *desc)
+{
+ if (snp_vmpl)
+ svsm_pval_pages(desc);
+ else
+ pval_pages(desc);
}
static int vmgexit_psc(struct ghcb *ghcb, struct snp_psc_desc *desc)
@@ -1269,3 +1641,77 @@ static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt,
return ES_UNSUPPORTED;
}
+
+/*
+ * Maintain the GPA of the SVSM Calling Area (CA) in order to utilize the SVSM
+ * services needed when not running in VMPL0.
+ */
+static bool __head svsm_setup_ca(const struct cc_blob_sev_info *cc_info)
+{
+ struct snp_secrets_page *secrets_page;
+ struct snp_cpuid_table *cpuid_table;
+ unsigned int i;
+ u64 caa;
+
+ BUILD_BUG_ON(sizeof(*secrets_page) != PAGE_SIZE);
+
+ /*
+ * Check if running at VMPL0.
+ *
+ * Use RMPADJUST (see the rmpadjust() function for a description of what
+ * the instruction does) to update the VMPL1 permissions of a page. If
+ * the guest is running at VMPL0, this will succeed and implies there is
+ * no SVSM. If the guest is running at any other VMPL, this will fail.
+ * Linux SNP guests only ever run at a single VMPL level so permission mask
+ * changes of a lesser-privileged VMPL are a don't-care.
+ *
+ * Use a rip-relative reference to obtain the proper address, since this
+ * routine is running identity mapped when called, both by the decompressor
+ * code and the early kernel code.
+ */
+ if (!rmpadjust((unsigned long)&RIP_REL_REF(boot_ghcb_page), RMP_PG_SIZE_4K, 1))
+ return false;
+
+ /*
+ * Not running at VMPL0, ensure everything has been properly supplied
+ * for running under an SVSM.
+ */
+ if (!cc_info || !cc_info->secrets_phys || cc_info->secrets_len != PAGE_SIZE)
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SECRETS_PAGE);
+
+ secrets_page = (struct snp_secrets_page *)cc_info->secrets_phys;
+ if (!secrets_page->svsm_size)
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NO_SVSM);
+
+ if (!secrets_page->svsm_guest_vmpl)
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SVSM_VMPL0);
+
+ RIP_REL_REF(snp_vmpl) = secrets_page->svsm_guest_vmpl;
+
+ caa = secrets_page->svsm_caa;
+
+ /*
+ * An open-coded PAGE_ALIGNED() in order to avoid including
+ * kernel-proper headers into the decompressor.
+ */
+ if (caa & (PAGE_SIZE - 1))
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SVSM_CAA);
+
+ /*
+ * The CA is identity mapped when this routine is called, both by the
+ * decompressor code and the early kernel code.
+ */
+ RIP_REL_REF(boot_svsm_caa) = (struct svsm_ca *)caa;
+ RIP_REL_REF(boot_svsm_caa_pa) = caa;
+
+ /* Advertise the SVSM presence via CPUID. */
+ cpuid_table = (struct snp_cpuid_table *)snp_cpuid_get_table();
+ for (i = 0; i < cpuid_table->count; i++) {
+ struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
+
+ if (fn->eax_in == 0x8000001f)
+ fn->eax |= BIT(28);
+ }
+
+ return true;
+}
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index c1cb90369915..078e2bac2553 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -7,6 +7,7 @@
#include <linux/cpufeature.h>
#include <linux/export.h>
#include <linux/io.h>
+#include <linux/kexec.h>
#include <asm/coco.h>
#include <asm/tdx.h>
#include <asm/vmx.h>
@@ -14,6 +15,7 @@
#include <asm/insn.h>
#include <asm/insn-eval.h>
#include <asm/pgtable.h>
+#include <asm/set_memory.h>
/* MMIO direction */
#define EPT_READ 0
@@ -38,6 +40,8 @@
#define TDREPORT_SUBTYPE_0 0
+static atomic_long_t nr_shared;
+
/* Called from __tdx_hypercall() for unrecoverable failure */
noinstr void __noreturn __tdx_hypercall_failed(void)
{
@@ -798,28 +802,124 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
return true;
}
-static bool tdx_enc_status_change_prepare(unsigned long vaddr, int numpages,
- bool enc)
+static int tdx_enc_status_change_prepare(unsigned long vaddr, int numpages,
+ bool enc)
{
/*
* Only handle shared->private conversion here.
* See the comment in tdx_early_init().
*/
- if (enc)
- return tdx_enc_status_changed(vaddr, numpages, enc);
- return true;
+ if (enc && !tdx_enc_status_changed(vaddr, numpages, enc))
+ return -EIO;
+
+ return 0;
}
-static bool tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
+static int tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
bool enc)
{
/*
* Only handle private->shared conversion here.
* See the comment in tdx_early_init().
*/
- if (!enc)
- return tdx_enc_status_changed(vaddr, numpages, enc);
- return true;
+ if (!enc && !tdx_enc_status_changed(vaddr, numpages, enc))
+ return -EIO;
+
+ if (enc)
+ atomic_long_sub(numpages, &nr_shared);
+ else
+ atomic_long_add(numpages, &nr_shared);
+
+ return 0;
+}
+
+/* Stop new private<->shared conversions */
+static void tdx_kexec_begin(void)
+{
+ if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ return;
+
+ /*
+ * Crash kernel reaches here with interrupts disabled: can't wait for
+ * conversions to finish.
+ *
+ * If race happened, just report and proceed.
+ */
+ if (!set_memory_enc_stop_conversion())
+ pr_warn("Failed to stop shared<->private conversions\n");
+}
+
+/* Walk direct mapping and convert all shared memory back to private */
+static void tdx_kexec_finish(void)
+{
+ unsigned long addr, end;
+ long found = 0, shared;
+
+ if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ return;
+
+ lockdep_assert_irqs_disabled();
+
+ addr = PAGE_OFFSET;
+ end = PAGE_OFFSET + get_max_mapped();
+
+ while (addr < end) {
+ unsigned long size;
+ unsigned int level;
+ pte_t *pte;
+
+ pte = lookup_address(addr, &level);
+ size = page_level_size(level);
+
+ if (pte && pte_decrypted(*pte)) {
+ int pages = size / PAGE_SIZE;
+
+ /*
+ * Touching memory with shared bit set triggers implicit
+ * conversion to shared.
+ *
+ * Make sure nobody touches the shared range from
+ * now on.
+ */
+ set_pte(pte, __pte(0));
+
+ /*
+ * Memory encryption state persists across kexec.
+ * If tdx_enc_status_changed() fails in the first
+ * kernel, it leaves memory in an unknown state.
+ *
+ * If that memory remains shared, accessing it in the
+ * *next* kernel through a private mapping will result
+ * in an unrecoverable guest shutdown.
+ *
+ * The kdump kernel boot is not impacted as it uses
+ * a pre-reserved memory range that is always private.
+ * However, gathering crash information could lead to
+ * a crash if it accesses unconverted memory through
+ * a private mapping which is possible when accessing
+ * that memory through /proc/vmcore, for example.
+ *
+ * In all cases, print error info in order to leave
+ * enough bread crumbs for debugging.
+ */
+ if (!tdx_enc_status_changed(addr, pages, true)) {
+ pr_err("Failed to unshare range %#lx-%#lx\n",
+ addr, addr + size);
+ }
+
+ found += pages;
+ }
+
+ addr += size;
+ }
+
+ __flush_tlb_all();
+
+ shared = atomic_long_read(&nr_shared);
+ if (shared != found) {
+ pr_err("shared page accounting is off\n");
+ pr_err("nr_shared = %ld, nr_found = %ld\n", shared, found);
+ }
}
void __init tdx_early_init(void)
@@ -881,6 +981,9 @@ void __init tdx_early_init(void)
x86_platform.guest.enc_cache_flush_required = tdx_cache_flush_required;
x86_platform.guest.enc_tlb_flush_required = tdx_tlb_flush_required;
+ x86_platform.guest.enc_kexec_begin = tdx_kexec_begin;
+ x86_platform.guest.enc_kexec_finish = tdx_kexec_finish;
+
/*
* TDX intercepts the RDMSR to read the X2APIC ID in the parallel
* bringup low level code. That raises #VE which cannot be handled
diff --git a/arch/x86/configs/hardening.config b/arch/x86/configs/hardening.config
index 7b497f3b7bc3..de319852a1e9 100644
--- a/arch/x86/configs/hardening.config
+++ b/arch/x86/configs/hardening.config
@@ -10,5 +10,8 @@ CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_SVM=y
CONFIG_AMD_IOMMU=y
+# Enforce CET Indirect Branch Tracking in the kernel.
+CONFIG_X86_KERNEL_IBT=y
+
# Enable CET Shadow Stack for userspace.
CONFIG_X86_USER_SHADOW_STACK=y
diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index c9e59589a1ce..24875e6295f2 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -18,6 +18,7 @@ config CRYPTO_AES_NI_INTEL
depends on X86
select CRYPTO_AEAD
select CRYPTO_LIB_AES
+ select CRYPTO_LIB_GF128MUL
select CRYPTO_ALGAPI
select CRYPTO_SKCIPHER
select CRYPTO_SIMD
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 9aa46093c91b..53b4a277809e 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -48,7 +48,12 @@ chacha-x86_64-$(CONFIG_AS_AVX512) += chacha-avx512vl-x86_64.o
obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
-aesni-intel-$(CONFIG_64BIT) += aesni-intel_avx-x86_64.o aes_ctrby8_avx-x86_64.o
+aesni-intel-$(CONFIG_64BIT) += aes_ctrby8_avx-x86_64.o \
+ aes-gcm-aesni-x86_64.o \
+ aes-xts-avx-x86_64.o
+ifeq ($(CONFIG_AS_VAES)$(CONFIG_AS_VPCLMULQDQ),yy)
+aesni-intel-$(CONFIG_64BIT) += aes-gcm-avx10-x86_64.o
+endif
obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
sha1-ssse3-y := sha1_avx2_x86_64_asm.o sha1_ssse3_asm.o sha1_ssse3_glue.o
diff --git a/arch/x86/crypto/aes-gcm-aesni-x86_64.S b/arch/x86/crypto/aes-gcm-aesni-x86_64.S
new file mode 100644
index 000000000000..45940e2883a0
--- /dev/null
+++ b/arch/x86/crypto/aes-gcm-aesni-x86_64.S
@@ -0,0 +1,1128 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// AES-NI optimized AES-GCM for x86_64
+//
+// Copyright 2024 Google LLC
+//
+// Author: Eric Biggers <ebiggers@google.com>
+//
+//------------------------------------------------------------------------------
+//
+// This file is dual-licensed, meaning that you can use it under your choice of
+// either of the following two licenses:
+//
+// Licensed under the Apache License 2.0 (the "License"). You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// or
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//------------------------------------------------------------------------------
+//
+// This file implements AES-GCM (Galois/Counter Mode) for x86_64 CPUs that
+// support the original set of AES instructions, i.e. AES-NI. Two
+// implementations are provided, one that uses AVX and one that doesn't. They
+// are very similar, being generated by the same macros. The only difference is
+// that the AVX implementation takes advantage of VEX-coded instructions in some
+// places to avoid some 'movdqu' and 'movdqa' instructions. The AVX
+// implementation does *not* use 256-bit vectors, as AES is not supported on
+// 256-bit vectors until the VAES feature (which this file doesn't target).
+//
+// The specific CPU feature prerequisites are AES-NI and PCLMULQDQ, plus SSE4.1
+// for the *_aesni functions or AVX for the *_aesni_avx ones. (But it seems
+// there are no CPUs that support AES-NI without also PCLMULQDQ and SSE4.1.)
+//
+// The design generally follows that of aes-gcm-avx10-x86_64.S, and that file is
+// more thoroughly commented. This file has the following notable changes:
+//
+// - The vector length is fixed at 128-bit, i.e. xmm registers. This means
+// there is only one AES block (and GHASH block) per register.
+//
+// - Without AVX512 / AVX10, only 16 SIMD registers are available instead of
+// 32. We work around this by being much more careful about using
+// registers, relying heavily on loads to load values as they are needed.
+//
+// - Masking is not available either. We work around this by implementing
+// partial block loads and stores using overlapping scalar loads and stores
+// combined with shifts and SSE4.1 insertion and extraction instructions.
+//
+// - The main loop is organized differently due to the different design
+// constraints. First, with just one AES block per SIMD register, on some
+// CPUs 4 registers don't saturate the 'aesenc' throughput. We therefore
+// do an 8-register wide loop. Considering that and the fact that we have
+// just 16 SIMD registers to work with, it's not feasible to cache AES
+// round keys and GHASH key powers in registers across loop iterations.
+// That's not ideal, but also not actually that bad, since loads can run in
+// parallel with other instructions. Significantly, this also makes it
+// possible to roll up the inner loops, relying on hardware loop unrolling
+// instead of software loop unrolling, greatly reducing code size.
+//
+// - We implement the GHASH multiplications in the main loop using Karatsuba
+// multiplication instead of schoolbook multiplication. This saves one
+// pclmulqdq instruction per block, at the cost of one 64-bit load, one
+// pshufd, and 0.25 pxors per block. (This is without the three-argument
+// XOR support that would be provided by AVX512 / AVX10, which would be
+// more beneficial to schoolbook than Karatsuba.)
+//
+// As a rough approximation, we can assume that Karatsuba multiplication is
+// faster than schoolbook multiplication in this context if one pshufd and
+// 0.25 pxors are cheaper than a pclmulqdq. (We assume that the 64-bit
+// load is "free" due to running in parallel with arithmetic instructions.)
+// This is true on AMD CPUs, including all that support pclmulqdq up to at
+// least Zen 3. It's also true on older Intel CPUs: Westmere through
+// Haswell on the Core side, and Silvermont through Goldmont Plus on the
+// low-power side. On some of these CPUs, pclmulqdq is quite slow, and the
+// benefit of Karatsuba should be substantial. On newer Intel CPUs,
+// schoolbook multiplication should be faster, but only marginally.
+//
+// Not all these CPUs were available to be tested. However, benchmarks on
+// available CPUs suggest that this approximation is plausible. Switching
+// to Karatsuba showed negligible change (< 1%) on Intel Broadwell,
+// Skylake, and Cascade Lake, but it improved AMD Zen 1-3 by 6-7%.
+// Considering that and the fact that Karatsuba should be even more
+// beneficial on older Intel CPUs, it seems like the right choice here.
+//
+// An additional 0.25 pclmulqdq per block (2 per 8 blocks) could be
+// saved by using a multiplication-less reduction method. We don't do that
+// because it would require a large number of shift and xor instructions,
+// making it less worthwhile and likely harmful on newer CPUs.
+//
+// It does make sense to sometimes use a different reduction optimization
+// that saves a pclmulqdq, though: precompute the hash key times x^64, and
+// multiply the low half of the data block by the hash key with the extra
+// factor of x^64. This eliminates one step of the reduction. However,
+// this is incompatible with Karatsuba multiplication. Therefore, for
+// multi-block processing we use Karatsuba multiplication with a regular
+// reduction. For single-block processing, we use the x^64 optimization.
+
+#include <linux/linkage.h>
+
+.section .rodata
+.p2align 4
+.Lbswap_mask:
+ .octa 0x000102030405060708090a0b0c0d0e0f
+.Lgfpoly:
+ .quad 0xc200000000000000
+.Lone:
+ .quad 1
+.Lgfpoly_and_internal_carrybit:
+ .octa 0xc2000000000000010000000000000001
+ // Loading 16 bytes from '.Lzeropad_mask + 16 - len' produces a mask of
+ // 'len' 0xff bytes and the rest zeroes.
+.Lzeropad_mask:
+ .octa 0xffffffffffffffffffffffffffffffff
+ .octa 0
+
+// Offsets in struct aes_gcm_key_aesni
+#define OFFSETOF_AESKEYLEN 480
+#define OFFSETOF_H_POWERS 496
+#define OFFSETOF_H_POWERS_XORED 624
+#define OFFSETOF_H_TIMES_X64 688
+
+.text
+
+// Do a vpclmulqdq, or fall back to a movdqa and a pclmulqdq. The fallback
+// assumes that all operands are distinct and that any mem operand is aligned.
+.macro _vpclmulqdq imm, src1, src2, dst
+.if USE_AVX
+ vpclmulqdq \imm, \src1, \src2, \dst
+.else
+ movdqa \src2, \dst
+ pclmulqdq \imm, \src1, \dst
+.endif
+.endm
+
+// Do a vpshufb, or fall back to a movdqa and a pshufb. The fallback assumes
+// that all operands are distinct and that any mem operand is aligned.
+.macro _vpshufb src1, src2, dst
+.if USE_AVX
+ vpshufb \src1, \src2, \dst
+.else
+ movdqa \src2, \dst
+ pshufb \src1, \dst
+.endif
+.endm
+
+// Do a vpand, or fall back to a movdqu and a pand. The fallback assumes that
+// all operands are distinct.
+.macro _vpand src1, src2, dst
+.if USE_AVX
+ vpand \src1, \src2, \dst
+.else
+ movdqu \src1, \dst
+ pand \src2, \dst
+.endif
+.endm
+
+// XOR the unaligned memory operand \mem into the xmm register \reg. \tmp must
+// be a temporary xmm register.
+.macro _xor_mem_to_reg mem, reg, tmp
+.if USE_AVX
+ vpxor \mem, \reg, \reg
+.else
+ movdqu \mem, \tmp
+ pxor \tmp, \reg
+.endif
+.endm
+
+// Test the unaligned memory operand \mem against the xmm register \reg. \tmp
+// must be a temporary xmm register.
+.macro _test_mem mem, reg, tmp
+.if USE_AVX
+ vptest \mem, \reg
+.else
+ movdqu \mem, \tmp
+ ptest \tmp, \reg
+.endif
+.endm
+
+// Load 1 <= %ecx <= 15 bytes from the pointer \src into the xmm register \dst
+// and zeroize any remaining bytes. Clobbers %rax, %rcx, and \tmp{64,32}.
+.macro _load_partial_block src, dst, tmp64, tmp32
+ sub $8, %ecx // LEN - 8
+ jle .Lle8\@
+
+ // Load 9 <= LEN <= 15 bytes.
+ movq (\src), \dst // Load first 8 bytes
+ mov (\src, %rcx), %rax // Load last 8 bytes
+ neg %ecx
+ shl $3, %ecx
+ shr %cl, %rax // Discard overlapping bytes
+ pinsrq $1, %rax, \dst
+ jmp .Ldone\@
+
+.Lle8\@:
+ add $4, %ecx // LEN - 4
+ jl .Llt4\@
+
+ // Load 4 <= LEN <= 8 bytes.
+ mov (\src), %eax // Load first 4 bytes
+ mov (\src, %rcx), \tmp32 // Load last 4 bytes
+ jmp .Lcombine\@
+
+.Llt4\@:
+ // Load 1 <= LEN <= 3 bytes.
+ add $2, %ecx // LEN - 2
+ movzbl (\src), %eax // Load first byte
+ jl .Lmovq\@
+ movzwl (\src, %rcx), \tmp32 // Load last 2 bytes
+.Lcombine\@:
+ shl $3, %ecx
+ shl %cl, \tmp64
+ or \tmp64, %rax // Combine the two parts
+.Lmovq\@:
+ movq %rax, \dst
+.Ldone\@:
+.endm
+
+// Store 1 <= %ecx <= 15 bytes from the xmm register \src to the pointer \dst.
+// Clobbers %rax, %rcx, and %rsi.
+.macro _store_partial_block src, dst
+ sub $8, %ecx // LEN - 8
+ jl .Llt8\@
+
+ // Store 8 <= LEN <= 15 bytes.
+ pextrq $1, \src, %rax
+ mov %ecx, %esi
+ shl $3, %ecx
+ ror %cl, %rax
+ mov %rax, (\dst, %rsi) // Store last LEN - 8 bytes
+ movq \src, (\dst) // Store first 8 bytes
+ jmp .Ldone\@
+
+.Llt8\@:
+ add $4, %ecx // LEN - 4
+ jl .Llt4\@
+
+ // Store 4 <= LEN <= 7 bytes.
+ pextrd $1, \src, %eax
+ mov %ecx, %esi
+ shl $3, %ecx
+ ror %cl, %eax
+ mov %eax, (\dst, %rsi) // Store last LEN - 4 bytes
+ movd \src, (\dst) // Store first 4 bytes
+ jmp .Ldone\@
+
+.Llt4\@:
+ // Store 1 <= LEN <= 3 bytes.
+ pextrb $0, \src, 0(\dst)
+ cmp $-2, %ecx // LEN - 4 == -2, i.e. LEN == 2?
+ jl .Ldone\@
+ pextrb $1, \src, 1(\dst)
+ je .Ldone\@
+ pextrb $2, \src, 2(\dst)
+.Ldone\@:
+.endm
+
+// Do one step of GHASH-multiplying \a by \b and storing the reduced product in
+// \b. To complete all steps, this must be invoked with \i=0 through \i=9.
+// \a_times_x64 must contain \a * x^64 in reduced form, \gfpoly must contain the
+// .Lgfpoly constant, and \t0-\t1 must be temporary registers.
+.macro _ghash_mul_step i, a, a_times_x64, b, gfpoly, t0, t1
+
+ // MI = (a_L * b_H) + ((a*x^64)_L * b_L)
+.if \i == 0
+ _vpclmulqdq $0x01, \a, \b, \t0
+.elseif \i == 1
+ _vpclmulqdq $0x00, \a_times_x64, \b, \t1
+.elseif \i == 2
+ pxor \t1, \t0
+
+ // HI = (a_H * b_H) + ((a*x^64)_H * b_L)
+.elseif \i == 3
+ _vpclmulqdq $0x11, \a, \b, \t1
+.elseif \i == 4
+ pclmulqdq $0x10, \a_times_x64, \b
+.elseif \i == 5
+ pxor \t1, \b
+.elseif \i == 6
+
+ // Fold MI into HI.
+ pshufd $0x4e, \t0, \t1 // Swap halves of MI
+.elseif \i == 7
+ pclmulqdq $0x00, \gfpoly, \t0 // MI_L*(x^63 + x^62 + x^57)
+.elseif \i == 8
+ pxor \t1, \b
+.elseif \i == 9
+ pxor \t0, \b
+.endif
+.endm
+
+// GHASH-multiply \a by \b and store the reduced product in \b.
+// See _ghash_mul_step for details.
+.macro _ghash_mul a, a_times_x64, b, gfpoly, t0, t1
+.irp i, 0,1,2,3,4,5,6,7,8,9
+ _ghash_mul_step \i, \a, \a_times_x64, \b, \gfpoly, \t0, \t1
+.endr
+.endm
+
+// GHASH-multiply \a by \b and add the unreduced product to \lo, \mi, and \hi.
+// This does Karatsuba multiplication and must be paired with _ghash_reduce. On
+// the first call, \lo, \mi, and \hi must be zero. \a_xored must contain the
+// two halves of \a XOR'd together, i.e. a_L + a_H. \b is clobbered.
+.macro _ghash_mul_noreduce a, a_xored, b, lo, mi, hi, t0
+
+ // LO += a_L * b_L
+ _vpclmulqdq $0x00, \a, \b, \t0
+ pxor \t0, \lo
+
+ // b_L + b_H
+ pshufd $0x4e, \b, \t0
+ pxor \b, \t0
+
+ // HI += a_H * b_H
+ pclmulqdq $0x11, \a, \b
+ pxor \b, \hi
+
+ // MI += (a_L + a_H) * (b_L + b_H)
+ pclmulqdq $0x00, \a_xored, \t0
+ pxor \t0, \mi
+.endm
+
+// Reduce the product from \lo, \mi, and \hi, and store the result in \dst.
+// This assumes that _ghash_mul_noreduce was used.
+.macro _ghash_reduce lo, mi, hi, dst, t0
+
+ movq .Lgfpoly(%rip), \t0
+
+ // MI += LO + HI (needed because we used Karatsuba multiplication)
+ pxor \lo, \mi
+ pxor \hi, \mi
+
+ // Fold LO into MI.
+ pshufd $0x4e, \lo, \dst
+ pclmulqdq $0x00, \t0, \lo
+ pxor \dst, \mi
+ pxor \lo, \mi
+
+ // Fold MI into HI.
+ pshufd $0x4e, \mi, \dst
+ pclmulqdq $0x00, \t0, \mi
+ pxor \hi, \dst
+ pxor \mi, \dst
+.endm
+
+// Do the first step of the GHASH update of a set of 8 ciphertext blocks.
+//
+// The whole GHASH update does:
+//
+// GHASH_ACC = (blk0+GHASH_ACC)*H^8 + blk1*H^7 + blk2*H^6 + blk3*H^5 +
+// blk4*H^4 + blk5*H^3 + blk6*H^2 + blk7*H^1
+//
+// This macro just does the first step: it does the unreduced multiplication
+// (blk0+GHASH_ACC)*H^8 and starts gathering the unreduced product in the xmm
+// registers LO, MI, and GHASH_ACC a.k.a. HI. It also zero-initializes the
+// inner block counter in %rax, which is a value that counts up by 8 for each
+// block in the set of 8 and is used later to index by 8*blknum and 16*blknum.
+//
+// To reduce the number of pclmulqdq instructions required, both this macro and
+// _ghash_update_continue_8x use Karatsuba multiplication instead of schoolbook
+// multiplication. See the file comment for more details about this choice.
+//
+// Both macros expect the ciphertext blocks blk[0-7] to be available at DST if
+// encrypting, or SRC if decrypting. They also expect the precomputed hash key
+// powers H^i and their XOR'd-together halves to be available in the struct
+// pointed to by KEY. Both macros clobber TMP[0-2].
+.macro _ghash_update_begin_8x enc
+
+ // Initialize the inner block counter.
+ xor %eax, %eax
+
+ // Load the highest hash key power, H^8.
+ movdqa OFFSETOF_H_POWERS(KEY), TMP0
+
+ // Load the first ciphertext block and byte-reflect it.
+.if \enc
+ movdqu (DST), TMP1
+.else
+ movdqu (SRC), TMP1
+.endif
+ pshufb BSWAP_MASK, TMP1
+
+ // Add the GHASH accumulator to the ciphertext block to get the block
+ // 'b' that needs to be multiplied with the hash key power 'a'.
+ pxor TMP1, GHASH_ACC
+
+ // b_L + b_H
+ pshufd $0x4e, GHASH_ACC, MI
+ pxor GHASH_ACC, MI
+
+ // LO = a_L * b_L
+ _vpclmulqdq $0x00, TMP0, GHASH_ACC, LO
+
+ // HI = a_H * b_H
+ pclmulqdq $0x11, TMP0, GHASH_ACC
+
+ // MI = (a_L + a_H) * (b_L + b_H)
+ pclmulqdq $0x00, OFFSETOF_H_POWERS_XORED(KEY), MI
+.endm
+
+// Continue the GHASH update of 8 ciphertext blocks as described above by doing
+// an unreduced multiplication of the next ciphertext block by the next lowest
+// key power and accumulating the result into LO, MI, and GHASH_ACC a.k.a. HI.
+.macro _ghash_update_continue_8x enc
+ add $8, %eax
+
+ // Load the next lowest key power.
+ movdqa OFFSETOF_H_POWERS(KEY,%rax,2), TMP0
+
+ // Load the next ciphertext block and byte-reflect it.
+.if \enc
+ movdqu (DST,%rax,2), TMP1
+.else
+ movdqu (SRC,%rax,2), TMP1
+.endif
+ pshufb BSWAP_MASK, TMP1
+
+ // LO += a_L * b_L
+ _vpclmulqdq $0x00, TMP0, TMP1, TMP2
+ pxor TMP2, LO
+
+ // b_L + b_H
+ pshufd $0x4e, TMP1, TMP2
+ pxor TMP1, TMP2
+
+ // HI += a_H * b_H
+ pclmulqdq $0x11, TMP0, TMP1
+ pxor TMP1, GHASH_ACC
+
+ // MI += (a_L + a_H) * (b_L + b_H)
+ movq OFFSETOF_H_POWERS_XORED(KEY,%rax), TMP1
+ pclmulqdq $0x00, TMP1, TMP2
+ pxor TMP2, MI
+.endm
+
+// Reduce LO, MI, and GHASH_ACC a.k.a. HI into GHASH_ACC. This is similar to
+// _ghash_reduce, but it's hardcoded to use the registers of the main loop and
+// it uses the same register for HI and the destination. It's also divided into
+// two steps. TMP1 must be preserved across steps.
+//
+// One pshufd could be saved by shuffling MI and XOR'ing LO into it, instead of
+// shuffling LO, XOR'ing LO into MI, and shuffling MI. However, this would
+// increase the critical path length, and it seems to slightly hurt performance.
+.macro _ghash_update_end_8x_step i
+.if \i == 0
+ movq .Lgfpoly(%rip), TMP1
+ pxor LO, MI
+ pxor GHASH_ACC, MI
+ pshufd $0x4e, LO, TMP2
+ pclmulqdq $0x00, TMP1, LO
+ pxor TMP2, MI
+ pxor LO, MI
+.elseif \i == 1
+ pshufd $0x4e, MI, TMP2
+ pclmulqdq $0x00, TMP1, MI
+ pxor TMP2, GHASH_ACC
+ pxor MI, GHASH_ACC
+.endif
+.endm
+
+// void aes_gcm_precompute_##suffix(struct aes_gcm_key_aesni *key);
+//
+// Given the expanded AES key, derive the GHASH subkey and initialize the GHASH
+// related fields in the key struct.
+.macro _aes_gcm_precompute
+
+ // Function arguments
+ .set KEY, %rdi
+
+ // Additional local variables.
+ // %xmm0-%xmm1 and %rax are used as temporaries.
+ .set RNDKEYLAST_PTR, %rsi
+ .set H_CUR, %xmm2
+ .set H_POW1, %xmm3 // H^1
+ .set H_POW1_X64, %xmm4 // H^1 * x^64
+ .set GFPOLY, %xmm5
+
+ // Encrypt an all-zeroes block to get the raw hash subkey.
+ movl OFFSETOF_AESKEYLEN(KEY), %eax
+ lea 6*16(KEY,%rax,4), RNDKEYLAST_PTR
+ movdqa (KEY), H_POW1 // Zero-th round key XOR all-zeroes block
+ lea 16(KEY), %rax
+1:
+ aesenc (%rax), H_POW1
+ add $16, %rax
+ cmp %rax, RNDKEYLAST_PTR
+ jne 1b
+ aesenclast (RNDKEYLAST_PTR), H_POW1
+
+ // Preprocess the raw hash subkey as needed to operate on GHASH's
+ // bit-reflected values directly: reflect its bytes, then multiply it by
+ // x^-1 (using the backwards interpretation of polynomial coefficients
+ // from the GCM spec) or equivalently x^1 (using the alternative,
+ // natural interpretation of polynomial coefficients).
+ pshufb .Lbswap_mask(%rip), H_POW1
+ movdqa H_POW1, %xmm0
+ pshufd $0xd3, %xmm0, %xmm0
+ psrad $31, %xmm0
+ paddq H_POW1, H_POW1
+ pand .Lgfpoly_and_internal_carrybit(%rip), %xmm0
+ pxor %xmm0, H_POW1
+
+ // Store H^1.
+ movdqa H_POW1, OFFSETOF_H_POWERS+7*16(KEY)
+
+ // Compute and store H^1 * x^64.
+ movq .Lgfpoly(%rip), GFPOLY
+ pshufd $0x4e, H_POW1, %xmm0
+ _vpclmulqdq $0x00, H_POW1, GFPOLY, H_POW1_X64
+ pxor %xmm0, H_POW1_X64
+ movdqa H_POW1_X64, OFFSETOF_H_TIMES_X64(KEY)
+
+ // Compute and store the halves of H^1 XOR'd together.
+ pxor H_POW1, %xmm0
+ movq %xmm0, OFFSETOF_H_POWERS_XORED+7*8(KEY)
+
+ // Compute and store the remaining key powers H^2 through H^8.
+ movdqa H_POW1, H_CUR
+ mov $6*8, %eax
+.Lprecompute_next\@:
+ // Compute H^i = H^{i-1} * H^1.
+ _ghash_mul H_POW1, H_POW1_X64, H_CUR, GFPOLY, %xmm0, %xmm1
+ // Store H^i.
+ movdqa H_CUR, OFFSETOF_H_POWERS(KEY,%rax,2)
+ // Compute and store the halves of H^i XOR'd together.
+ pshufd $0x4e, H_CUR, %xmm0
+ pxor H_CUR, %xmm0
+ movq %xmm0, OFFSETOF_H_POWERS_XORED(KEY,%rax)
+ sub $8, %eax
+ jge .Lprecompute_next\@
+
+ RET
+.endm
+
+// void aes_gcm_aad_update_aesni(const struct aes_gcm_key_aesni *key,
+// u8 ghash_acc[16], const u8 *aad, int aadlen);
+//
+// This function processes the AAD (Additional Authenticated Data) in GCM.
+// Using the key |key|, it updates the GHASH accumulator |ghash_acc| with the
+// data given by |aad| and |aadlen|. On the first call, |ghash_acc| must be all
+// zeroes. |aadlen| must be a multiple of 16, except on the last call where it
+// can be any length. The caller must do any buffering needed to ensure this.
+.macro _aes_gcm_aad_update
+
+ // Function arguments
+ .set KEY, %rdi
+ .set GHASH_ACC_PTR, %rsi
+ .set AAD, %rdx
+ .set AADLEN, %ecx
+ // Note: _load_partial_block relies on AADLEN being in %ecx.
+
+ // Additional local variables.
+ // %rax, %r10, and %xmm0-%xmm1 are used as temporary registers.
+ .set BSWAP_MASK, %xmm2
+ .set GHASH_ACC, %xmm3
+ .set H_POW1, %xmm4 // H^1
+ .set H_POW1_X64, %xmm5 // H^1 * x^64
+ .set GFPOLY, %xmm6
+
+ movdqa .Lbswap_mask(%rip), BSWAP_MASK
+ movdqu (GHASH_ACC_PTR), GHASH_ACC
+ movdqa OFFSETOF_H_POWERS+7*16(KEY), H_POW1
+ movdqa OFFSETOF_H_TIMES_X64(KEY), H_POW1_X64
+ movq .Lgfpoly(%rip), GFPOLY
+
+ // Process the AAD one full block at a time.
+ sub $16, AADLEN
+ jl .Laad_loop_1x_done\@
+.Laad_loop_1x\@:
+ movdqu (AAD), %xmm0
+ pshufb BSWAP_MASK, %xmm0
+ pxor %xmm0, GHASH_ACC
+ _ghash_mul H_POW1, H_POW1_X64, GHASH_ACC, GFPOLY, %xmm0, %xmm1
+ add $16, AAD
+ sub $16, AADLEN
+ jge .Laad_loop_1x\@
+.Laad_loop_1x_done\@:
+ // Check whether there is a partial block at the end.
+ add $16, AADLEN
+ jz .Laad_done\@
+
+ // Process a partial block of length 1 <= AADLEN <= 15.
+ // _load_partial_block assumes that %ecx contains AADLEN.
+ _load_partial_block AAD, %xmm0, %r10, %r10d
+ pshufb BSWAP_MASK, %xmm0
+ pxor %xmm0, GHASH_ACC
+ _ghash_mul H_POW1, H_POW1_X64, GHASH_ACC, GFPOLY, %xmm0, %xmm1
+
+.Laad_done\@:
+ movdqu GHASH_ACC, (GHASH_ACC_PTR)
+ RET
+.endm
+
+// Increment LE_CTR eight times to generate eight little-endian counter blocks,
+// swap each to big-endian, and store them in AESDATA[0-7]. Also XOR them with
+// the zero-th AES round key. Clobbers TMP0 and TMP1.
+.macro _ctr_begin_8x
+ movq .Lone(%rip), TMP0
+ movdqa (KEY), TMP1 // zero-th round key
+.irp i, 0,1,2,3,4,5,6,7
+ _vpshufb BSWAP_MASK, LE_CTR, AESDATA\i
+ pxor TMP1, AESDATA\i
+ paddd TMP0, LE_CTR
+.endr
+.endm
+
+// Do a non-last round of AES on AESDATA[0-7] using \round_key.
+.macro _aesenc_8x round_key
+.irp i, 0,1,2,3,4,5,6,7
+ aesenc \round_key, AESDATA\i
+.endr
+.endm
+
+// Do the last round of AES on AESDATA[0-7] using \round_key.
+.macro _aesenclast_8x round_key
+.irp i, 0,1,2,3,4,5,6,7
+ aesenclast \round_key, AESDATA\i
+.endr
+.endm
+
+// XOR eight blocks from SRC with the keystream blocks in AESDATA[0-7], and
+// store the result to DST. Clobbers TMP0.
+.macro _xor_data_8x
+.irp i, 0,1,2,3,4,5,6,7
+ _xor_mem_to_reg \i*16(SRC), AESDATA\i, tmp=TMP0
+.endr
+.irp i, 0,1,2,3,4,5,6,7
+ movdqu AESDATA\i, \i*16(DST)
+.endr
+.endm
+
+// void aes_gcm_{enc,dec}_update_##suffix(const struct aes_gcm_key_aesni *key,
+// const u32 le_ctr[4], u8 ghash_acc[16],
+// const u8 *src, u8 *dst, int datalen);
+//
+// This macro generates a GCM encryption or decryption update function with the
+// above prototype (with \enc selecting which one).
+//
+// This function computes the next portion of the CTR keystream, XOR's it with
+// |datalen| bytes from |src|, and writes the resulting encrypted or decrypted
+// data to |dst|. It also updates the GHASH accumulator |ghash_acc| using the
+// next |datalen| ciphertext bytes.
+//
+// |datalen| must be a multiple of 16, except on the last call where it can be
+// any length. The caller must do any buffering needed to ensure this. Both
+// in-place and out-of-place en/decryption are supported.
+//
+// |le_ctr| must give the current counter in little-endian format. For a new
+// message, the low word of the counter must be 2. This function loads the
+// counter from |le_ctr| and increments the loaded counter as needed, but it
+// does *not* store the updated counter back to |le_ctr|. The caller must
+// update |le_ctr| if any more data segments follow. Internally, only the low
+// 32-bit word of the counter is incremented, following the GCM standard.
+.macro _aes_gcm_update enc
+
+ // Function arguments
+ .set KEY, %rdi
+ .set LE_CTR_PTR, %rsi // Note: overlaps with usage as temp reg
+ .set GHASH_ACC_PTR, %rdx
+ .set SRC, %rcx
+ .set DST, %r8
+ .set DATALEN, %r9d
+ .set DATALEN64, %r9 // Zero-extend DATALEN before using!
+ // Note: the code setting up for _load_partial_block assumes that SRC is
+ // in %rcx (and that DATALEN is *not* in %rcx).
+
+ // Additional local variables
+
+ // %rax and %rsi are used as temporary registers. Note: %rsi overlaps
+ // with LE_CTR_PTR, which is used only at the beginning.
+
+ .set AESKEYLEN, %r10d // AES key length in bytes
+ .set AESKEYLEN64, %r10
+ .set RNDKEYLAST_PTR, %r11 // Pointer to last AES round key
+
+ // Put the most frequently used values in %xmm0-%xmm7 to reduce code
+ // size. (%xmm0-%xmm7 take fewer bytes to encode than %xmm8-%xmm15.)
+ .set TMP0, %xmm0
+ .set TMP1, %xmm1
+ .set TMP2, %xmm2
+ .set LO, %xmm3 // Low part of unreduced product
+ .set MI, %xmm4 // Middle part of unreduced product
+ .set GHASH_ACC, %xmm5 // GHASH accumulator; in main loop also
+ // the high part of unreduced product
+ .set BSWAP_MASK, %xmm6 // Shuffle mask for reflecting bytes
+ .set LE_CTR, %xmm7 // Little-endian counter value
+ .set AESDATA0, %xmm8
+ .set AESDATA1, %xmm9
+ .set AESDATA2, %xmm10
+ .set AESDATA3, %xmm11
+ .set AESDATA4, %xmm12
+ .set AESDATA5, %xmm13
+ .set AESDATA6, %xmm14
+ .set AESDATA7, %xmm15
+
+ movdqa .Lbswap_mask(%rip), BSWAP_MASK
+ movdqu (GHASH_ACC_PTR), GHASH_ACC
+ movdqu (LE_CTR_PTR), LE_CTR
+
+ movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN
+ lea 6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR
+
+ // If there are at least 8*16 bytes of data, then continue into the main
+ // loop, which processes 8*16 bytes of data per iteration.
+ //
+ // The main loop interleaves AES and GHASH to improve performance on
+ // CPUs that can execute these instructions in parallel. When
+ // decrypting, the GHASH input (the ciphertext) is immediately
+ // available. When encrypting, we instead encrypt a set of 8 blocks
+ // first and then GHASH those blocks while encrypting the next set of 8,
+ // repeat that as needed, and finally GHASH the last set of 8 blocks.
+ //
+ // Code size optimization: Prefer adding or subtracting -8*16 over 8*16,
+ // as this makes the immediate fit in a signed byte, saving 3 bytes.
+ add $-8*16, DATALEN
+ jl .Lcrypt_loop_8x_done\@
+.if \enc
+ // Encrypt the first 8 plaintext blocks.
+ _ctr_begin_8x
+ lea 16(KEY), %rsi
+ .p2align 4
+1:
+ movdqa (%rsi), TMP0
+ _aesenc_8x TMP0
+ add $16, %rsi
+ cmp %rsi, RNDKEYLAST_PTR
+ jne 1b
+ movdqa (%rsi), TMP0
+ _aesenclast_8x TMP0
+ _xor_data_8x
+ // Don't increment DST until the ciphertext blocks have been hashed.
+ sub $-8*16, SRC
+ add $-8*16, DATALEN
+ jl .Lghash_last_ciphertext_8x\@
+.endif
+
+ .p2align 4
+.Lcrypt_loop_8x\@:
+
+ // Generate the next set of 8 counter blocks and start encrypting them.
+ _ctr_begin_8x
+ lea 16(KEY), %rsi
+
+ // Do a round of AES, and start the GHASH update of 8 ciphertext blocks
+ // by doing the unreduced multiplication for the first ciphertext block.
+ movdqa (%rsi), TMP0
+ add $16, %rsi
+ _aesenc_8x TMP0
+ _ghash_update_begin_8x \enc
+
+ // Do 7 more rounds of AES, and continue the GHASH update by doing the
+ // unreduced multiplication for the remaining ciphertext blocks.
+ .p2align 4
+1:
+ movdqa (%rsi), TMP0
+ add $16, %rsi
+ _aesenc_8x TMP0
+ _ghash_update_continue_8x \enc
+ cmp $7*8, %eax
+ jne 1b
+
+ // Do the remaining AES rounds.
+ .p2align 4
+1:
+ movdqa (%rsi), TMP0
+ add $16, %rsi
+ _aesenc_8x TMP0
+ cmp %rsi, RNDKEYLAST_PTR
+ jne 1b
+
+ // Do the GHASH reduction and the last round of AES.
+ movdqa (RNDKEYLAST_PTR), TMP0
+ _ghash_update_end_8x_step 0
+ _aesenclast_8x TMP0
+ _ghash_update_end_8x_step 1
+
+ // XOR the data with the AES-CTR keystream blocks.
+.if \enc
+ sub $-8*16, DST
+.endif
+ _xor_data_8x
+ sub $-8*16, SRC
+.if !\enc
+ sub $-8*16, DST
+.endif
+ add $-8*16, DATALEN
+ jge .Lcrypt_loop_8x\@
+
+.if \enc
+.Lghash_last_ciphertext_8x\@:
+ // Update GHASH with the last set of 8 ciphertext blocks.
+ _ghash_update_begin_8x \enc
+ .p2align 4
+1:
+ _ghash_update_continue_8x \enc
+ cmp $7*8, %eax
+ jne 1b
+ _ghash_update_end_8x_step 0
+ _ghash_update_end_8x_step 1
+ sub $-8*16, DST
+.endif
+
+.Lcrypt_loop_8x_done\@:
+
+ sub $-8*16, DATALEN
+ jz .Ldone\@
+
+ // Handle the remainder of length 1 <= DATALEN < 8*16 bytes. We keep
+ // things simple and keep the code size down by just going one block at
+ // a time, again taking advantage of hardware loop unrolling. Since
+ // there are enough key powers available for all remaining data, we do
+ // the GHASH multiplications unreduced, and only reduce at the very end.
+
+ .set HI, TMP2
+ .set H_POW, AESDATA0
+ .set H_POW_XORED, AESDATA1
+ .set ONE, AESDATA2
+
+ movq .Lone(%rip), ONE
+
+ // Start collecting the unreduced GHASH intermediate value LO, MI, HI.
+ pxor LO, LO
+ pxor MI, MI
+ pxor HI, HI
+
+ // Set up a block counter %rax to contain 8*(8-n), where n is the number
+ // of blocks that remain, counting any partial block. This will be used
+ // to access the key powers H^n through H^1.
+ mov DATALEN, %eax
+ neg %eax
+ and $~15, %eax
+ sar $1, %eax
+ add $64, %eax
+
+ sub $16, DATALEN
+ jl .Lcrypt_loop_1x_done\@
+
+ // Process the data one full block at a time.
+.Lcrypt_loop_1x\@:
+
+ // Encrypt the next counter block.
+ _vpshufb BSWAP_MASK, LE_CTR, TMP0
+ paddd ONE, LE_CTR
+ pxor (KEY), TMP0
+ lea -6*16(RNDKEYLAST_PTR), %rsi // Reduce code size
+ cmp $24, AESKEYLEN
+ jl 128f // AES-128?
+ je 192f // AES-192?
+ // AES-256
+ aesenc -7*16(%rsi), TMP0
+ aesenc -6*16(%rsi), TMP0
+192:
+ aesenc -5*16(%rsi), TMP0
+ aesenc -4*16(%rsi), TMP0
+128:
+.irp i, -3,-2,-1,0,1,2,3,4,5
+ aesenc \i*16(%rsi), TMP0
+.endr
+ aesenclast (RNDKEYLAST_PTR), TMP0
+
+ // Load the next key power H^i.
+ movdqa OFFSETOF_H_POWERS(KEY,%rax,2), H_POW
+ movq OFFSETOF_H_POWERS_XORED(KEY,%rax), H_POW_XORED
+
+ // XOR the keystream block that was just generated in TMP0 with the next
+ // source data block and store the resulting en/decrypted data to DST.
+.if \enc
+ _xor_mem_to_reg (SRC), TMP0, tmp=TMP1
+ movdqu TMP0, (DST)
+.else
+ movdqu (SRC), TMP1
+ pxor TMP1, TMP0
+ movdqu TMP0, (DST)
+.endif
+
+ // Update GHASH with the ciphertext block.
+.if \enc
+ pshufb BSWAP_MASK, TMP0
+ pxor TMP0, GHASH_ACC
+.else
+ pshufb BSWAP_MASK, TMP1
+ pxor TMP1, GHASH_ACC
+.endif
+ _ghash_mul_noreduce H_POW, H_POW_XORED, GHASH_ACC, LO, MI, HI, TMP0
+ pxor GHASH_ACC, GHASH_ACC
+
+ add $8, %eax
+ add $16, SRC
+ add $16, DST
+ sub $16, DATALEN
+ jge .Lcrypt_loop_1x\@
+.Lcrypt_loop_1x_done\@:
+ // Check whether there is a partial block at the end.
+ add $16, DATALEN
+ jz .Lghash_reduce\@
+
+ // Process a partial block of length 1 <= DATALEN <= 15.
+
+ // Encrypt a counter block for the last time.
+ pshufb BSWAP_MASK, LE_CTR
+ pxor (KEY), LE_CTR
+ lea 16(KEY), %rsi
+1:
+ aesenc (%rsi), LE_CTR
+ add $16, %rsi
+ cmp %rsi, RNDKEYLAST_PTR
+ jne 1b
+ aesenclast (RNDKEYLAST_PTR), LE_CTR
+
+ // Load the lowest key power, H^1.
+ movdqa OFFSETOF_H_POWERS(KEY,%rax,2), H_POW
+ movq OFFSETOF_H_POWERS_XORED(KEY,%rax), H_POW_XORED
+
+ // Load and zero-pad 1 <= DATALEN <= 15 bytes of data from SRC. SRC is
+ // in %rcx, but _load_partial_block needs DATALEN in %rcx instead.
+ // RNDKEYLAST_PTR is no longer needed, so reuse it for SRC.
+ mov SRC, RNDKEYLAST_PTR
+ mov DATALEN, %ecx
+ _load_partial_block RNDKEYLAST_PTR, TMP0, %rsi, %esi
+
+ // XOR the keystream block that was just generated in LE_CTR with the
+ // source data block and store the resulting en/decrypted data to DST.
+ pxor TMP0, LE_CTR
+ mov DATALEN, %ecx
+ _store_partial_block LE_CTR, DST
+
+ // If encrypting, zero-pad the final ciphertext block for GHASH. (If
+ // decrypting, this was already done by _load_partial_block.)
+.if \enc
+ lea .Lzeropad_mask+16(%rip), %rax
+ sub DATALEN64, %rax
+ _vpand (%rax), LE_CTR, TMP0
+.endif
+
+ // Update GHASH with the final ciphertext block.
+ pshufb BSWAP_MASK, TMP0
+ pxor TMP0, GHASH_ACC
+ _ghash_mul_noreduce H_POW, H_POW_XORED, GHASH_ACC, LO, MI, HI, TMP0
+
+.Lghash_reduce\@:
+ // Finally, do the GHASH reduction.
+ _ghash_reduce LO, MI, HI, GHASH_ACC, TMP0
+
+.Ldone\@:
+ // Store the updated GHASH accumulator back to memory.
+ movdqu GHASH_ACC, (GHASH_ACC_PTR)
+
+ RET
+.endm
+
+// void aes_gcm_enc_final_##suffix(const struct aes_gcm_key_aesni *key,
+// const u32 le_ctr[4], u8 ghash_acc[16],
+// u64 total_aadlen, u64 total_datalen);
+// bool aes_gcm_dec_final_##suffix(const struct aes_gcm_key_aesni *key,
+// const u32 le_ctr[4], const u8 ghash_acc[16],
+// u64 total_aadlen, u64 total_datalen,
+// const u8 tag[16], int taglen);
+//
+// This macro generates one of the above two functions (with \enc selecting
+// which one). Both functions finish computing the GCM authentication tag by
+// updating GHASH with the lengths block and encrypting the GHASH accumulator.
+// |total_aadlen| and |total_datalen| must be the total length of the additional
+// authenticated data and the en/decrypted data in bytes, respectively.
+//
+// The encryption function then stores the full-length (16-byte) computed
+// authentication tag to |ghash_acc|. The decryption function instead loads the
+// expected authentication tag (the one that was transmitted) from the 16-byte
+// buffer |tag|, compares the first 4 <= |taglen| <= 16 bytes of it to the
+// computed tag in constant time, and returns true if and only if they match.
+.macro _aes_gcm_final enc
+
+ // Function arguments
+ .set KEY, %rdi
+ .set LE_CTR_PTR, %rsi
+ .set GHASH_ACC_PTR, %rdx
+ .set TOTAL_AADLEN, %rcx
+ .set TOTAL_DATALEN, %r8
+ .set TAG, %r9
+ .set TAGLEN, %r10d // Originally at 8(%rsp)
+ .set TAGLEN64, %r10
+
+ // Additional local variables.
+ // %rax and %xmm0-%xmm2 are used as temporary registers.
+ .set AESKEYLEN, %r11d
+ .set AESKEYLEN64, %r11
+ .set BSWAP_MASK, %xmm3
+ .set GHASH_ACC, %xmm4
+ .set H_POW1, %xmm5 // H^1
+ .set H_POW1_X64, %xmm6 // H^1 * x^64
+ .set GFPOLY, %xmm7
+
+ movdqa .Lbswap_mask(%rip), BSWAP_MASK
+ movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN
+
+ // Set up a counter block with 1 in the low 32-bit word. This is the
+ // counter that produces the ciphertext needed to encrypt the auth tag.
+ movdqu (LE_CTR_PTR), %xmm0
+ mov $1, %eax
+ pinsrd $0, %eax, %xmm0
+
+ // Build the lengths block and XOR it into the GHASH accumulator.
+ movq TOTAL_DATALEN, GHASH_ACC
+ pinsrq $1, TOTAL_AADLEN, GHASH_ACC
+ psllq $3, GHASH_ACC // Bytes to bits
+ _xor_mem_to_reg (GHASH_ACC_PTR), GHASH_ACC, %xmm1
+
+ movdqa OFFSETOF_H_POWERS+7*16(KEY), H_POW1
+ movdqa OFFSETOF_H_TIMES_X64(KEY), H_POW1_X64
+ movq .Lgfpoly(%rip), GFPOLY
+
+ // Make %rax point to the 6th from last AES round key. (Using signed
+ // byte offsets -7*16 through 6*16 decreases code size.)
+ lea (KEY,AESKEYLEN64,4), %rax
+
+ // AES-encrypt the counter block and also multiply GHASH_ACC by H^1.
+ // Interleave the AES and GHASH instructions to improve performance.
+ pshufb BSWAP_MASK, %xmm0
+ pxor (KEY), %xmm0
+ cmp $24, AESKEYLEN
+ jl 128f // AES-128?
+ je 192f // AES-192?
+ // AES-256
+ aesenc -7*16(%rax), %xmm0
+ aesenc -6*16(%rax), %xmm0
+192:
+ aesenc -5*16(%rax), %xmm0
+ aesenc -4*16(%rax), %xmm0
+128:
+.irp i, 0,1,2,3,4,5,6,7,8
+ aesenc (\i-3)*16(%rax), %xmm0
+ _ghash_mul_step \i, H_POW1, H_POW1_X64, GHASH_ACC, GFPOLY, %xmm1, %xmm2
+.endr
+ aesenclast 6*16(%rax), %xmm0
+ _ghash_mul_step 9, H_POW1, H_POW1_X64, GHASH_ACC, GFPOLY, %xmm1, %xmm2
+
+ // Undo the byte reflection of the GHASH accumulator.
+ pshufb BSWAP_MASK, GHASH_ACC
+
+ // Encrypt the GHASH accumulator.
+ pxor %xmm0, GHASH_ACC
+
+.if \enc
+ // Return the computed auth tag.
+ movdqu GHASH_ACC, (GHASH_ACC_PTR)
+.else
+ .set ZEROPAD_MASK_PTR, TOTAL_AADLEN // Reusing TOTAL_AADLEN!
+
+ // Verify the auth tag in constant time by XOR'ing the transmitted and
+ // computed auth tags together and using the ptest instruction to check
+ // whether the first TAGLEN bytes of the result are zero.
+ _xor_mem_to_reg (TAG), GHASH_ACC, tmp=%xmm0
+ movl 8(%rsp), TAGLEN
+ lea .Lzeropad_mask+16(%rip), ZEROPAD_MASK_PTR
+ sub TAGLEN64, ZEROPAD_MASK_PTR
+ xor %eax, %eax
+ _test_mem (ZEROPAD_MASK_PTR), GHASH_ACC, tmp=%xmm0
+ sete %al
+.endif
+ RET
+.endm
+
+.set USE_AVX, 0
+SYM_FUNC_START(aes_gcm_precompute_aesni)
+ _aes_gcm_precompute
+SYM_FUNC_END(aes_gcm_precompute_aesni)
+SYM_FUNC_START(aes_gcm_aad_update_aesni)
+ _aes_gcm_aad_update
+SYM_FUNC_END(aes_gcm_aad_update_aesni)
+SYM_FUNC_START(aes_gcm_enc_update_aesni)
+ _aes_gcm_update 1
+SYM_FUNC_END(aes_gcm_enc_update_aesni)
+SYM_FUNC_START(aes_gcm_dec_update_aesni)
+ _aes_gcm_update 0
+SYM_FUNC_END(aes_gcm_dec_update_aesni)
+SYM_FUNC_START(aes_gcm_enc_final_aesni)
+ _aes_gcm_final 1
+SYM_FUNC_END(aes_gcm_enc_final_aesni)
+SYM_FUNC_START(aes_gcm_dec_final_aesni)
+ _aes_gcm_final 0
+SYM_FUNC_END(aes_gcm_dec_final_aesni)
+
+.set USE_AVX, 1
+SYM_FUNC_START(aes_gcm_precompute_aesni_avx)
+ _aes_gcm_precompute
+SYM_FUNC_END(aes_gcm_precompute_aesni_avx)
+SYM_FUNC_START(aes_gcm_aad_update_aesni_avx)
+ _aes_gcm_aad_update
+SYM_FUNC_END(aes_gcm_aad_update_aesni_avx)
+SYM_FUNC_START(aes_gcm_enc_update_aesni_avx)
+ _aes_gcm_update 1
+SYM_FUNC_END(aes_gcm_enc_update_aesni_avx)
+SYM_FUNC_START(aes_gcm_dec_update_aesni_avx)
+ _aes_gcm_update 0
+SYM_FUNC_END(aes_gcm_dec_update_aesni_avx)
+SYM_FUNC_START(aes_gcm_enc_final_aesni_avx)
+ _aes_gcm_final 1
+SYM_FUNC_END(aes_gcm_enc_final_aesni_avx)
+SYM_FUNC_START(aes_gcm_dec_final_aesni_avx)
+ _aes_gcm_final 0
+SYM_FUNC_END(aes_gcm_dec_final_aesni_avx)
diff --git a/arch/x86/crypto/aes-gcm-avx10-x86_64.S b/arch/x86/crypto/aes-gcm-avx10-x86_64.S
new file mode 100644
index 000000000000..97e0ee515fc5
--- /dev/null
+++ b/arch/x86/crypto/aes-gcm-avx10-x86_64.S
@@ -0,0 +1,1222 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// VAES and VPCLMULQDQ optimized AES-GCM for x86_64
+//
+// Copyright 2024 Google LLC
+//
+// Author: Eric Biggers <ebiggers@google.com>
+//
+//------------------------------------------------------------------------------
+//
+// This file is dual-licensed, meaning that you can use it under your choice of
+// either of the following two licenses:
+//
+// Licensed under the Apache License 2.0 (the "License"). You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// or
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//------------------------------------------------------------------------------
+//
+// This file implements AES-GCM (Galois/Counter Mode) for x86_64 CPUs that
+// support VAES (vector AES), VPCLMULQDQ (vector carryless multiplication), and
+// either AVX512 or AVX10. Some of the functions, notably the encryption and
+// decryption update functions which are the most performance-critical, are
+// provided in two variants generated from a macro: one using 256-bit vectors
+// (suffix: vaes_avx10_256) and one using 512-bit vectors (vaes_avx10_512). The
+// other, "shared" functions (vaes_avx10) use at most 256-bit vectors.
+//
+// The functions that use 512-bit vectors are intended for CPUs that support
+// 512-bit vectors *and* where using them doesn't cause significant
+// downclocking. They require the following CPU features:
+//
+// VAES && VPCLMULQDQ && BMI2 && ((AVX512BW && AVX512VL) || AVX10/512)
+//
+// The other functions require the following CPU features:
+//
+// VAES && VPCLMULQDQ && BMI2 && ((AVX512BW && AVX512VL) || AVX10/256)
+//
+// All functions use the "System V" ABI. The Windows ABI is not supported.
+//
+// Note that we use "avx10" in the names of the functions as a shorthand to
+// really mean "AVX10 or a certain set of AVX512 features". Due to Intel's
+// introduction of AVX512 and then its replacement by AVX10, there doesn't seem
+// to be a simple way to name things that makes sense on all CPUs.
+//
+// Note that the macros that support both 256-bit and 512-bit vectors could
+// fairly easily be changed to support 128-bit too. However, this would *not*
+// be sufficient to allow the code to run on CPUs without AVX512 or AVX10,
+// because the code heavily uses several features of these extensions other than
+// the vector length: the increase in the number of SIMD registers from 16 to
+// 32, masking support, and new instructions such as vpternlogd (which can do a
+// three-argument XOR). These features are very useful for AES-GCM.
+
+#include <linux/linkage.h>
+
+.section .rodata
+.p2align 6
+
+ // A shuffle mask that reflects the bytes of 16-byte blocks
+.Lbswap_mask:
+ .octa 0x000102030405060708090a0b0c0d0e0f
+
+ // This is the GHASH reducing polynomial without its constant term, i.e.
+ // x^128 + x^7 + x^2 + x, represented using the backwards mapping
+ // between bits and polynomial coefficients.
+ //
+ // Alternatively, it can be interpreted as the naturally-ordered
+ // representation of the polynomial x^127 + x^126 + x^121 + 1, i.e. the
+ // "reversed" GHASH reducing polynomial without its x^128 term.
+.Lgfpoly:
+ .octa 0xc2000000000000000000000000000001
+
+ // Same as above, but with the (1 << 64) bit set.
+.Lgfpoly_and_internal_carrybit:
+ .octa 0xc2000000000000010000000000000001
+
+ // The below constants are used for incrementing the counter blocks.
+ // ctr_pattern points to the four 128-bit values [0, 1, 2, 3].
+ // inc_2blocks and inc_4blocks point to the single 128-bit values 2 and
+ // 4. Note that the same '2' is reused in ctr_pattern and inc_2blocks.
+.Lctr_pattern:
+ .octa 0
+ .octa 1
+.Linc_2blocks:
+ .octa 2
+ .octa 3
+.Linc_4blocks:
+ .octa 4
+
+// Number of powers of the hash key stored in the key struct. The powers are
+// stored from highest (H^NUM_H_POWERS) to lowest (H^1).
+#define NUM_H_POWERS 16
+
+// Offset to AES key length (in bytes) in the key struct
+#define OFFSETOF_AESKEYLEN 480
+
+// Offset to start of hash key powers array in the key struct
+#define OFFSETOF_H_POWERS 512
+
+// Offset to end of hash key powers array in the key struct.
+//
+// This is immediately followed by three zeroized padding blocks, which are
+// included so that partial vectors can be handled more easily. E.g. if VL=64
+// and two blocks remain, we load the 4 values [H^2, H^1, 0, 0]. The most
+// padding blocks needed is 3, which occurs if [H^1, 0, 0, 0] is loaded.
+#define OFFSETOFEND_H_POWERS (OFFSETOF_H_POWERS + (NUM_H_POWERS * 16))
+
+.text
+
+// Set the vector length in bytes. This sets the VL variable and defines
+// register aliases V0-V31 that map to the ymm or zmm registers.
+.macro _set_veclen vl
+ .set VL, \vl
+.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+.if VL == 32
+ .set V\i, %ymm\i
+.elseif VL == 64
+ .set V\i, %zmm\i
+.else
+ .error "Unsupported vector length"
+.endif
+.endr
+.endm
+
+// The _ghash_mul_step macro does one step of GHASH multiplication of the
+// 128-bit lanes of \a by the corresponding 128-bit lanes of \b and storing the
+// reduced products in \dst. \t0, \t1, and \t2 are temporary registers of the
+// same size as \a and \b. To complete all steps, this must invoked with \i=0
+// through \i=9. The division into steps allows users of this macro to
+// optionally interleave the computation with other instructions. Users of this
+// macro must preserve the parameter registers across steps.
+//
+// The multiplications are done in GHASH's representation of the finite field
+// GF(2^128). Elements of GF(2^128) are represented as binary polynomials
+// (i.e. polynomials whose coefficients are bits) modulo a reducing polynomial
+// G. The GCM specification uses G = x^128 + x^7 + x^2 + x + 1. Addition is
+// just XOR, while multiplication is more complex and has two parts: (a) do
+// carryless multiplication of two 128-bit input polynomials to get a 256-bit
+// intermediate product polynomial, and (b) reduce the intermediate product to
+// 128 bits by adding multiples of G that cancel out terms in it. (Adding
+// multiples of G doesn't change which field element the polynomial represents.)
+//
+// Unfortunately, the GCM specification maps bits to/from polynomial
+// coefficients backwards from the natural order. In each byte it specifies the
+// highest bit to be the lowest order polynomial coefficient, *not* the highest!
+// This makes it nontrivial to work with the GHASH polynomials. We could
+// reflect the bits, but x86 doesn't have an instruction that does that.
+//
+// Instead, we operate on the values without bit-reflecting them. This *mostly*
+// just works, since XOR and carryless multiplication are symmetric with respect
+// to bit order, but it has some consequences. First, due to GHASH's byte
+// order, by skipping bit reflection, *byte* reflection becomes necessary to
+// give the polynomial terms a consistent order. E.g., considering an N-bit
+// value interpreted using the G = x^128 + x^7 + x^2 + x + 1 convention, bits 0
+// through N-1 of the byte-reflected value represent the coefficients of x^(N-1)
+// through x^0, whereas bits 0 through N-1 of the non-byte-reflected value
+// represent x^7...x^0, x^15...x^8, ..., x^(N-1)...x^(N-8) which can't be worked
+// with. Fortunately, x86's vpshufb instruction can do byte reflection.
+//
+// Second, forgoing the bit reflection causes an extra multiple of x (still
+// using the G = x^128 + x^7 + x^2 + x + 1 convention) to be introduced by each
+// multiplication. This is because an M-bit by N-bit carryless multiplication
+// really produces a (M+N-1)-bit product, but in practice it's zero-extended to
+// M+N bits. In the G = x^128 + x^7 + x^2 + x + 1 convention, which maps bits
+// to polynomial coefficients backwards, this zero-extension actually changes
+// the product by introducing an extra factor of x. Therefore, users of this
+// macro must ensure that one of the inputs has an extra factor of x^-1, i.e.
+// the multiplicative inverse of x, to cancel out the extra x.
+//
+// Third, the backwards coefficients convention is just confusing to work with,
+// since it makes "low" and "high" in the polynomial math mean the opposite of
+// their normal meaning in computer programming. This can be solved by using an
+// alternative interpretation: the polynomial coefficients are understood to be
+// in the natural order, and the multiplication is actually \a * \b * x^-128 mod
+// x^128 + x^127 + x^126 + x^121 + 1. This doesn't change the inputs, outputs,
+// or the implementation at all; it just changes the mathematical interpretation
+// of what each instruction is doing. Starting from here, we'll use this
+// alternative interpretation, as it's easier to understand the code that way.
+//
+// Moving onto the implementation, the vpclmulqdq instruction does 64 x 64 =>
+// 128-bit carryless multiplication, so we break the 128 x 128 multiplication
+// into parts as follows (the _L and _H suffixes denote low and high 64 bits):
+//
+// LO = a_L * b_L
+// MI = (a_L * b_H) + (a_H * b_L)
+// HI = a_H * b_H
+//
+// The 256-bit product is x^128*HI + x^64*MI + LO. LO, MI, and HI are 128-bit.
+// Note that MI "overlaps" with LO and HI. We don't consolidate MI into LO and
+// HI right away, since the way the reduction works makes that unnecessary.
+//
+// For the reduction, we cancel out the low 128 bits by adding multiples of G =
+// x^128 + x^127 + x^126 + x^121 + 1. This is done by two iterations, each of
+// which cancels out the next lowest 64 bits. Consider a value x^64*A + B,
+// where A and B are 128-bit. Adding B_L*G to that value gives:
+//
+// x^64*A + B + B_L*G
+// = x^64*A + x^64*B_H + B_L + B_L*(x^128 + x^127 + x^126 + x^121 + 1)
+// = x^64*A + x^64*B_H + B_L + x^128*B_L + x^64*B_L*(x^63 + x^62 + x^57) + B_L
+// = x^64*A + x^64*B_H + x^128*B_L + x^64*B_L*(x^63 + x^62 + x^57) + B_L + B_L
+// = x^64*(A + B_H + x^64*B_L + B_L*(x^63 + x^62 + x^57))
+//
+// So: if we sum A, B with its halves swapped, and the low half of B times x^63
+// + x^62 + x^57, we get a 128-bit value C where x^64*C is congruent to the
+// original value x^64*A + B. I.e., the low 64 bits got canceled out.
+//
+// We just need to apply this twice: first to fold LO into MI, and second to
+// fold the updated MI into HI.
+//
+// The needed three-argument XORs are done using the vpternlogd instruction with
+// immediate 0x96, since this is faster than two vpxord instructions.
+//
+// A potential optimization, assuming that b is fixed per-key (if a is fixed
+// per-key it would work the other way around), is to use one iteration of the
+// reduction described above to precompute a value c such that x^64*c = b mod G,
+// and then multiply a_L by c (and implicitly by x^64) instead of by b:
+//
+// MI = (a_L * c_L) + (a_H * b_L)
+// HI = (a_L * c_H) + (a_H * b_H)
+//
+// This would eliminate the LO part of the intermediate product, which would
+// eliminate the need to fold LO into MI. This would save two instructions,
+// including a vpclmulqdq. However, we currently don't use this optimization
+// because it would require twice as many per-key precomputed values.
+//
+// Using Karatsuba multiplication instead of "schoolbook" multiplication
+// similarly would save a vpclmulqdq but does not seem to be worth it.
+.macro _ghash_mul_step i, a, b, dst, gfpoly, t0, t1, t2
+.if \i == 0
+ vpclmulqdq $0x00, \a, \b, \t0 // LO = a_L * b_L
+ vpclmulqdq $0x01, \a, \b, \t1 // MI_0 = a_L * b_H
+.elseif \i == 1
+ vpclmulqdq $0x10, \a, \b, \t2 // MI_1 = a_H * b_L
+.elseif \i == 2
+ vpxord \t2, \t1, \t1 // MI = MI_0 + MI_1
+.elseif \i == 3
+ vpclmulqdq $0x01, \t0, \gfpoly, \t2 // LO_L*(x^63 + x^62 + x^57)
+.elseif \i == 4
+ vpshufd $0x4e, \t0, \t0 // Swap halves of LO
+.elseif \i == 5
+ vpternlogd $0x96, \t2, \t0, \t1 // Fold LO into MI
+.elseif \i == 6
+ vpclmulqdq $0x11, \a, \b, \dst // HI = a_H * b_H
+.elseif \i == 7
+ vpclmulqdq $0x01, \t1, \gfpoly, \t0 // MI_L*(x^63 + x^62 + x^57)
+.elseif \i == 8
+ vpshufd $0x4e, \t1, \t1 // Swap halves of MI
+.elseif \i == 9
+ vpternlogd $0x96, \t0, \t1, \dst // Fold MI into HI
+.endif
+.endm
+
+// GHASH-multiply the 128-bit lanes of \a by the 128-bit lanes of \b and store
+// the reduced products in \dst. See _ghash_mul_step for full explanation.
+.macro _ghash_mul a, b, dst, gfpoly, t0, t1, t2
+.irp i, 0,1,2,3,4,5,6,7,8,9
+ _ghash_mul_step \i, \a, \b, \dst, \gfpoly, \t0, \t1, \t2
+.endr
+.endm
+
+// GHASH-multiply the 128-bit lanes of \a by the 128-bit lanes of \b and add the
+// *unreduced* products to \lo, \mi, and \hi.
+.macro _ghash_mul_noreduce a, b, lo, mi, hi, t0, t1, t2, t3
+ vpclmulqdq $0x00, \a, \b, \t0 // a_L * b_L
+ vpclmulqdq $0x01, \a, \b, \t1 // a_L * b_H
+ vpclmulqdq $0x10, \a, \b, \t2 // a_H * b_L
+ vpclmulqdq $0x11, \a, \b, \t3 // a_H * b_H
+ vpxord \t0, \lo, \lo
+ vpternlogd $0x96, \t2, \t1, \mi
+ vpxord \t3, \hi, \hi
+.endm
+
+// Reduce the unreduced products from \lo, \mi, and \hi and store the 128-bit
+// reduced products in \hi. See _ghash_mul_step for explanation of reduction.
+.macro _ghash_reduce lo, mi, hi, gfpoly, t0
+ vpclmulqdq $0x01, \lo, \gfpoly, \t0
+ vpshufd $0x4e, \lo, \lo
+ vpternlogd $0x96, \t0, \lo, \mi
+ vpclmulqdq $0x01, \mi, \gfpoly, \t0
+ vpshufd $0x4e, \mi, \mi
+ vpternlogd $0x96, \t0, \mi, \hi
+.endm
+
+// void aes_gcm_precompute_##suffix(struct aes_gcm_key_avx10 *key);
+//
+// Given the expanded AES key |key->aes_key|, this function derives the GHASH
+// subkey and initializes |key->ghash_key_powers| with powers of it.
+//
+// The number of key powers initialized is NUM_H_POWERS, and they are stored in
+// the order H^NUM_H_POWERS to H^1. The zeroized padding blocks after the key
+// powers themselves are also initialized.
+//
+// This macro supports both VL=32 and VL=64. _set_veclen must have been invoked
+// with the desired length. In the VL=32 case, the function computes twice as
+// many key powers than are actually used by the VL=32 GCM update functions.
+// This is done to keep the key format the same regardless of vector length.
+.macro _aes_gcm_precompute
+
+ // Function arguments
+ .set KEY, %rdi
+
+ // Additional local variables. V0-V2 and %rax are used as temporaries.
+ .set POWERS_PTR, %rsi
+ .set RNDKEYLAST_PTR, %rdx
+ .set H_CUR, V3
+ .set H_CUR_YMM, %ymm3
+ .set H_CUR_XMM, %xmm3
+ .set H_INC, V4
+ .set H_INC_YMM, %ymm4
+ .set H_INC_XMM, %xmm4
+ .set GFPOLY, V5
+ .set GFPOLY_YMM, %ymm5
+ .set GFPOLY_XMM, %xmm5
+
+ // Get pointer to lowest set of key powers (located at end of array).
+ lea OFFSETOFEND_H_POWERS-VL(KEY), POWERS_PTR
+
+ // Encrypt an all-zeroes block to get the raw hash subkey.
+ movl OFFSETOF_AESKEYLEN(KEY), %eax
+ lea 6*16(KEY,%rax,4), RNDKEYLAST_PTR
+ vmovdqu (KEY), %xmm0 // Zero-th round key XOR all-zeroes block
+ add $16, KEY
+1:
+ vaesenc (KEY), %xmm0, %xmm0
+ add $16, KEY
+ cmp KEY, RNDKEYLAST_PTR
+ jne 1b
+ vaesenclast (RNDKEYLAST_PTR), %xmm0, %xmm0
+
+ // Reflect the bytes of the raw hash subkey.
+ vpshufb .Lbswap_mask(%rip), %xmm0, H_CUR_XMM
+
+ // Zeroize the padding blocks.
+ vpxor %xmm0, %xmm0, %xmm0
+ vmovdqu %ymm0, VL(POWERS_PTR)
+ vmovdqu %xmm0, VL+2*16(POWERS_PTR)
+
+ // Finish preprocessing the first key power, H^1. Since this GHASH
+ // implementation operates directly on values with the backwards bit
+ // order specified by the GCM standard, it's necessary to preprocess the
+ // raw key as follows. First, reflect its bytes. Second, multiply it
+ // by x^-1 mod x^128 + x^7 + x^2 + x + 1 (if using the backwards
+ // interpretation of polynomial coefficients), which can also be
+ // interpreted as multiplication by x mod x^128 + x^127 + x^126 + x^121
+ // + 1 using the alternative, natural interpretation of polynomial
+ // coefficients. For details, see the comment above _ghash_mul_step.
+ //
+ // Either way, for the multiplication the concrete operation performed
+ // is a left shift of the 128-bit value by 1 bit, then an XOR with (0xc2
+ // << 120) | 1 if a 1 bit was carried out. However, there's no 128-bit
+ // wide shift instruction, so instead double each of the two 64-bit
+ // halves and incorporate the internal carry bit into the value XOR'd.
+ vpshufd $0xd3, H_CUR_XMM, %xmm0
+ vpsrad $31, %xmm0, %xmm0
+ vpaddq H_CUR_XMM, H_CUR_XMM, H_CUR_XMM
+ vpand .Lgfpoly_and_internal_carrybit(%rip), %xmm0, %xmm0
+ vpxor %xmm0, H_CUR_XMM, H_CUR_XMM
+
+ // Load the gfpoly constant.
+ vbroadcasti32x4 .Lgfpoly(%rip), GFPOLY
+
+ // Square H^1 to get H^2.
+ //
+ // Note that as with H^1, all higher key powers also need an extra
+ // factor of x^-1 (or x using the natural interpretation). Nothing
+ // special needs to be done to make this happen, though: H^1 * H^1 would
+ // end up with two factors of x^-1, but the multiplication consumes one.
+ // So the product H^2 ends up with the desired one factor of x^-1.
+ _ghash_mul H_CUR_XMM, H_CUR_XMM, H_INC_XMM, GFPOLY_XMM, \
+ %xmm0, %xmm1, %xmm2
+
+ // Create H_CUR_YMM = [H^2, H^1] and H_INC_YMM = [H^2, H^2].
+ vinserti128 $1, H_CUR_XMM, H_INC_YMM, H_CUR_YMM
+ vinserti128 $1, H_INC_XMM, H_INC_YMM, H_INC_YMM
+
+.if VL == 64
+ // Create H_CUR = [H^4, H^3, H^2, H^1] and H_INC = [H^4, H^4, H^4, H^4].
+ _ghash_mul H_INC_YMM, H_CUR_YMM, H_INC_YMM, GFPOLY_YMM, \
+ %ymm0, %ymm1, %ymm2
+ vinserti64x4 $1, H_CUR_YMM, H_INC, H_CUR
+ vshufi64x2 $0, H_INC, H_INC, H_INC
+.endif
+
+ // Store the lowest set of key powers.
+ vmovdqu8 H_CUR, (POWERS_PTR)
+
+ // Compute and store the remaining key powers. With VL=32, repeatedly
+ // multiply [H^(i+1), H^i] by [H^2, H^2] to get [H^(i+3), H^(i+2)].
+ // With VL=64, repeatedly multiply [H^(i+3), H^(i+2), H^(i+1), H^i] by
+ // [H^4, H^4, H^4, H^4] to get [H^(i+7), H^(i+6), H^(i+5), H^(i+4)].
+ mov $(NUM_H_POWERS*16/VL) - 1, %eax
+.Lprecompute_next\@:
+ sub $VL, POWERS_PTR
+ _ghash_mul H_INC, H_CUR, H_CUR, GFPOLY, V0, V1, V2
+ vmovdqu8 H_CUR, (POWERS_PTR)
+ dec %eax
+ jnz .Lprecompute_next\@
+
+ vzeroupper // This is needed after using ymm or zmm registers.
+ RET
+.endm
+
+// XOR together the 128-bit lanes of \src (whose low lane is \src_xmm) and store
+// the result in \dst_xmm. This implicitly zeroizes the other lanes of dst.
+.macro _horizontal_xor src, src_xmm, dst_xmm, t0_xmm, t1_xmm, t2_xmm
+ vextracti32x4 $1, \src, \t0_xmm
+.if VL == 32
+ vpxord \t0_xmm, \src_xmm, \dst_xmm
+.elseif VL == 64
+ vextracti32x4 $2, \src, \t1_xmm
+ vextracti32x4 $3, \src, \t2_xmm
+ vpxord \t0_xmm, \src_xmm, \dst_xmm
+ vpternlogd $0x96, \t1_xmm, \t2_xmm, \dst_xmm
+.else
+ .error "Unsupported vector length"
+.endif
+.endm
+
+// Do one step of the GHASH update of the data blocks given in the vector
+// registers GHASHDATA[0-3]. \i specifies the step to do, 0 through 9. The
+// division into steps allows users of this macro to optionally interleave the
+// computation with other instructions. This macro uses the vector register
+// GHASH_ACC as input/output; GHASHDATA[0-3] as inputs that are clobbered;
+// H_POW[4-1], GFPOLY, and BSWAP_MASK as inputs that aren't clobbered; and
+// GHASHTMP[0-2] as temporaries. This macro handles the byte-reflection of the
+// data blocks. The parameter registers must be preserved across steps.
+//
+// The GHASH update does: GHASH_ACC = H_POW4*(GHASHDATA0 + GHASH_ACC) +
+// H_POW3*GHASHDATA1 + H_POW2*GHASHDATA2 + H_POW1*GHASHDATA3, where the
+// operations are vectorized operations on vectors of 16-byte blocks. E.g.,
+// with VL=32 there are 2 blocks per vector and the vectorized terms correspond
+// to the following non-vectorized terms:
+//
+// H_POW4*(GHASHDATA0 + GHASH_ACC) => H^8*(blk0 + GHASH_ACC_XMM) and H^7*(blk1 + 0)
+// H_POW3*GHASHDATA1 => H^6*blk2 and H^5*blk3
+// H_POW2*GHASHDATA2 => H^4*blk4 and H^3*blk5
+// H_POW1*GHASHDATA3 => H^2*blk6 and H^1*blk7
+//
+// With VL=64, we use 4 blocks/vector, H^16 through H^1, and blk0 through blk15.
+//
+// More concretely, this code does:
+// - Do vectorized "schoolbook" multiplications to compute the intermediate
+// 256-bit product of each block and its corresponding hash key power.
+// There are 4*VL/16 of these intermediate products.
+// - Sum (XOR) the intermediate 256-bit products across vectors. This leaves
+// VL/16 256-bit intermediate values.
+// - Do a vectorized reduction of these 256-bit intermediate values to
+// 128-bits each. This leaves VL/16 128-bit intermediate values.
+// - Sum (XOR) these values and store the 128-bit result in GHASH_ACC_XMM.
+//
+// See _ghash_mul_step for the full explanation of the operations performed for
+// each individual finite field multiplication and reduction.
+.macro _ghash_step_4x i
+.if \i == 0
+ vpshufb BSWAP_MASK, GHASHDATA0, GHASHDATA0
+ vpxord GHASH_ACC, GHASHDATA0, GHASHDATA0
+ vpshufb BSWAP_MASK, GHASHDATA1, GHASHDATA1
+ vpshufb BSWAP_MASK, GHASHDATA2, GHASHDATA2
+.elseif \i == 1
+ vpshufb BSWAP_MASK, GHASHDATA3, GHASHDATA3
+ vpclmulqdq $0x00, H_POW4, GHASHDATA0, GHASH_ACC // LO_0
+ vpclmulqdq $0x00, H_POW3, GHASHDATA1, GHASHTMP0 // LO_1
+ vpclmulqdq $0x00, H_POW2, GHASHDATA2, GHASHTMP1 // LO_2
+.elseif \i == 2
+ vpxord GHASHTMP0, GHASH_ACC, GHASH_ACC // sum(LO_{1,0})
+ vpclmulqdq $0x00, H_POW1, GHASHDATA3, GHASHTMP2 // LO_3
+ vpternlogd $0x96, GHASHTMP2, GHASHTMP1, GHASH_ACC // LO = sum(LO_{3,2,1,0})
+ vpclmulqdq $0x01, H_POW4, GHASHDATA0, GHASHTMP0 // MI_0
+.elseif \i == 3
+ vpclmulqdq $0x01, H_POW3, GHASHDATA1, GHASHTMP1 // MI_1
+ vpclmulqdq $0x01, H_POW2, GHASHDATA2, GHASHTMP2 // MI_2
+ vpternlogd $0x96, GHASHTMP2, GHASHTMP1, GHASHTMP0 // sum(MI_{2,1,0})
+ vpclmulqdq $0x01, H_POW1, GHASHDATA3, GHASHTMP1 // MI_3
+.elseif \i == 4
+ vpclmulqdq $0x10, H_POW4, GHASHDATA0, GHASHTMP2 // MI_4
+ vpternlogd $0x96, GHASHTMP2, GHASHTMP1, GHASHTMP0 // sum(MI_{4,3,2,1,0})
+ vpclmulqdq $0x10, H_POW3, GHASHDATA1, GHASHTMP1 // MI_5
+ vpclmulqdq $0x10, H_POW2, GHASHDATA2, GHASHTMP2 // MI_6
+.elseif \i == 5
+ vpternlogd $0x96, GHASHTMP2, GHASHTMP1, GHASHTMP0 // sum(MI_{6,5,4,3,2,1,0})
+ vpclmulqdq $0x01, GHASH_ACC, GFPOLY, GHASHTMP2 // LO_L*(x^63 + x^62 + x^57)
+ vpclmulqdq $0x10, H_POW1, GHASHDATA3, GHASHTMP1 // MI_7
+ vpxord GHASHTMP1, GHASHTMP0, GHASHTMP0 // MI = sum(MI_{7,6,5,4,3,2,1,0})
+.elseif \i == 6
+ vpshufd $0x4e, GHASH_ACC, GHASH_ACC // Swap halves of LO
+ vpclmulqdq $0x11, H_POW4, GHASHDATA0, GHASHDATA0 // HI_0
+ vpclmulqdq $0x11, H_POW3, GHASHDATA1, GHASHDATA1 // HI_1
+ vpclmulqdq $0x11, H_POW2, GHASHDATA2, GHASHDATA2 // HI_2
+.elseif \i == 7
+ vpternlogd $0x96, GHASHTMP2, GHASH_ACC, GHASHTMP0 // Fold LO into MI
+ vpclmulqdq $0x11, H_POW1, GHASHDATA3, GHASHDATA3 // HI_3
+ vpternlogd $0x96, GHASHDATA2, GHASHDATA1, GHASHDATA0 // sum(HI_{2,1,0})
+ vpclmulqdq $0x01, GHASHTMP0, GFPOLY, GHASHTMP1 // MI_L*(x^63 + x^62 + x^57)
+.elseif \i == 8
+ vpxord GHASHDATA3, GHASHDATA0, GHASH_ACC // HI = sum(HI_{3,2,1,0})
+ vpshufd $0x4e, GHASHTMP0, GHASHTMP0 // Swap halves of MI
+ vpternlogd $0x96, GHASHTMP1, GHASHTMP0, GHASH_ACC // Fold MI into HI
+.elseif \i == 9
+ _horizontal_xor GHASH_ACC, GHASH_ACC_XMM, GHASH_ACC_XMM, \
+ GHASHDATA0_XMM, GHASHDATA1_XMM, GHASHDATA2_XMM
+.endif
+.endm
+
+// Do one non-last round of AES encryption on the counter blocks in V0-V3 using
+// the round key that has been broadcast to all 128-bit lanes of \round_key.
+.macro _vaesenc_4x round_key
+ vaesenc \round_key, V0, V0
+ vaesenc \round_key, V1, V1
+ vaesenc \round_key, V2, V2
+ vaesenc \round_key, V3, V3
+.endm
+
+// Start the AES encryption of four vectors of counter blocks.
+.macro _ctr_begin_4x
+
+ // Increment LE_CTR four times to generate four vectors of little-endian
+ // counter blocks, swap each to big-endian, and store them in V0-V3.
+ vpshufb BSWAP_MASK, LE_CTR, V0
+ vpaddd LE_CTR_INC, LE_CTR, LE_CTR
+ vpshufb BSWAP_MASK, LE_CTR, V1
+ vpaddd LE_CTR_INC, LE_CTR, LE_CTR
+ vpshufb BSWAP_MASK, LE_CTR, V2
+ vpaddd LE_CTR_INC, LE_CTR, LE_CTR
+ vpshufb BSWAP_MASK, LE_CTR, V3
+ vpaddd LE_CTR_INC, LE_CTR, LE_CTR
+
+ // AES "round zero": XOR in the zero-th round key.
+ vpxord RNDKEY0, V0, V0
+ vpxord RNDKEY0, V1, V1
+ vpxord RNDKEY0, V2, V2
+ vpxord RNDKEY0, V3, V3
+.endm
+
+// void aes_gcm_{enc,dec}_update_##suffix(const struct aes_gcm_key_avx10 *key,
+// const u32 le_ctr[4], u8 ghash_acc[16],
+// const u8 *src, u8 *dst, int datalen);
+//
+// This macro generates a GCM encryption or decryption update function with the
+// above prototype (with \enc selecting which one). This macro supports both
+// VL=32 and VL=64. _set_veclen must have been invoked with the desired length.
+//
+// This function computes the next portion of the CTR keystream, XOR's it with
+// |datalen| bytes from |src|, and writes the resulting encrypted or decrypted
+// data to |dst|. It also updates the GHASH accumulator |ghash_acc| using the
+// next |datalen| ciphertext bytes.
+//
+// |datalen| must be a multiple of 16, except on the last call where it can be
+// any length. The caller must do any buffering needed to ensure this. Both
+// in-place and out-of-place en/decryption are supported.
+//
+// |le_ctr| must give the current counter in little-endian format. For a new
+// message, the low word of the counter must be 2. This function loads the
+// counter from |le_ctr| and increments the loaded counter as needed, but it
+// does *not* store the updated counter back to |le_ctr|. The caller must
+// update |le_ctr| if any more data segments follow. Internally, only the low
+// 32-bit word of the counter is incremented, following the GCM standard.
+.macro _aes_gcm_update enc
+
+ // Function arguments
+ .set KEY, %rdi
+ .set LE_CTR_PTR, %rsi
+ .set GHASH_ACC_PTR, %rdx
+ .set SRC, %rcx
+ .set DST, %r8
+ .set DATALEN, %r9d
+ .set DATALEN64, %r9 // Zero-extend DATALEN before using!
+
+ // Additional local variables
+
+ // %rax and %k1 are used as temporary registers. LE_CTR_PTR is also
+ // available as a temporary register after the counter is loaded.
+
+ // AES key length in bytes
+ .set AESKEYLEN, %r10d
+ .set AESKEYLEN64, %r10
+
+ // Pointer to the last AES round key for the chosen AES variant
+ .set RNDKEYLAST_PTR, %r11
+
+ // In the main loop, V0-V3 are used as AES input and output. Elsewhere
+ // they are used as temporary registers.
+
+ // GHASHDATA[0-3] hold the ciphertext blocks and GHASH input data.
+ .set GHASHDATA0, V4
+ .set GHASHDATA0_XMM, %xmm4
+ .set GHASHDATA1, V5
+ .set GHASHDATA1_XMM, %xmm5
+ .set GHASHDATA2, V6
+ .set GHASHDATA2_XMM, %xmm6
+ .set GHASHDATA3, V7
+
+ // BSWAP_MASK is the shuffle mask for byte-reflecting 128-bit values
+ // using vpshufb, copied to all 128-bit lanes.
+ .set BSWAP_MASK, V8
+
+ // RNDKEY temporarily holds the next AES round key.
+ .set RNDKEY, V9
+
+ // GHASH_ACC is the accumulator variable for GHASH. When fully reduced,
+ // only the lowest 128-bit lane can be nonzero. When not fully reduced,
+ // more than one lane may be used, and they need to be XOR'd together.
+ .set GHASH_ACC, V10
+ .set GHASH_ACC_XMM, %xmm10
+
+ // LE_CTR_INC is the vector of 32-bit words that need to be added to a
+ // vector of little-endian counter blocks to advance it forwards.
+ .set LE_CTR_INC, V11
+
+ // LE_CTR contains the next set of little-endian counter blocks.
+ .set LE_CTR, V12
+
+ // RNDKEY0, RNDKEYLAST, and RNDKEY_M[9-5] contain cached AES round keys,
+ // copied to all 128-bit lanes. RNDKEY0 is the zero-th round key,
+ // RNDKEYLAST the last, and RNDKEY_M\i the one \i-th from the last.
+ .set RNDKEY0, V13
+ .set RNDKEYLAST, V14
+ .set RNDKEY_M9, V15
+ .set RNDKEY_M8, V16
+ .set RNDKEY_M7, V17
+ .set RNDKEY_M6, V18
+ .set RNDKEY_M5, V19
+
+ // RNDKEYLAST[0-3] temporarily store the last AES round key XOR'd with
+ // the corresponding block of source data. This is useful because
+ // vaesenclast(key, a) ^ b == vaesenclast(key ^ b, a), and key ^ b can
+ // be computed in parallel with the AES rounds.
+ .set RNDKEYLAST0, V20
+ .set RNDKEYLAST1, V21
+ .set RNDKEYLAST2, V22
+ .set RNDKEYLAST3, V23
+
+ // GHASHTMP[0-2] are temporary variables used by _ghash_step_4x. These
+ // cannot coincide with anything used for AES encryption, since for
+ // performance reasons GHASH and AES encryption are interleaved.
+ .set GHASHTMP0, V24
+ .set GHASHTMP1, V25
+ .set GHASHTMP2, V26
+
+ // H_POW[4-1] contain the powers of the hash key H^(4*VL/16)...H^1. The
+ // descending numbering reflects the order of the key powers.
+ .set H_POW4, V27
+ .set H_POW3, V28
+ .set H_POW2, V29
+ .set H_POW1, V30
+
+ // GFPOLY contains the .Lgfpoly constant, copied to all 128-bit lanes.
+ .set GFPOLY, V31
+
+ // Load some constants.
+ vbroadcasti32x4 .Lbswap_mask(%rip), BSWAP_MASK
+ vbroadcasti32x4 .Lgfpoly(%rip), GFPOLY
+
+ // Load the GHASH accumulator and the starting counter.
+ vmovdqu (GHASH_ACC_PTR), GHASH_ACC_XMM
+ vbroadcasti32x4 (LE_CTR_PTR), LE_CTR
+
+ // Load the AES key length in bytes.
+ movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN
+
+ // Make RNDKEYLAST_PTR point to the last AES round key. This is the
+ // round key with index 10, 12, or 14 for AES-128, AES-192, or AES-256
+ // respectively. Then load the zero-th and last round keys.
+ lea 6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR
+ vbroadcasti32x4 (KEY), RNDKEY0
+ vbroadcasti32x4 (RNDKEYLAST_PTR), RNDKEYLAST
+
+ // Finish initializing LE_CTR by adding [0, 1, ...] to its low words.
+ vpaddd .Lctr_pattern(%rip), LE_CTR, LE_CTR
+
+ // Initialize LE_CTR_INC to contain VL/16 in all 128-bit lanes.
+.if VL == 32
+ vbroadcasti32x4 .Linc_2blocks(%rip), LE_CTR_INC
+.elseif VL == 64
+ vbroadcasti32x4 .Linc_4blocks(%rip), LE_CTR_INC
+.else
+ .error "Unsupported vector length"
+.endif
+
+ // If there are at least 4*VL bytes of data, then continue into the loop
+ // that processes 4*VL bytes of data at a time. Otherwise skip it.
+ //
+ // Pre-subtracting 4*VL from DATALEN saves an instruction from the main
+ // loop and also ensures that at least one write always occurs to
+ // DATALEN, zero-extending it and allowing DATALEN64 to be used later.
+ sub $4*VL, DATALEN
+ jl .Lcrypt_loop_4x_done\@
+
+ // Load powers of the hash key.
+ vmovdqu8 OFFSETOFEND_H_POWERS-4*VL(KEY), H_POW4
+ vmovdqu8 OFFSETOFEND_H_POWERS-3*VL(KEY), H_POW3
+ vmovdqu8 OFFSETOFEND_H_POWERS-2*VL(KEY), H_POW2
+ vmovdqu8 OFFSETOFEND_H_POWERS-1*VL(KEY), H_POW1
+
+ // Main loop: en/decrypt and hash 4 vectors at a time.
+ //
+ // When possible, interleave the AES encryption of the counter blocks
+ // with the GHASH update of the ciphertext blocks. This improves
+ // performance on many CPUs because the execution ports used by the VAES
+ // instructions often differ from those used by vpclmulqdq and other
+ // instructions used in GHASH. For example, many Intel CPUs dispatch
+ // vaesenc to ports 0 and 1 and vpclmulqdq to port 5.
+ //
+ // The interleaving is easiest to do during decryption, since during
+ // decryption the ciphertext blocks are immediately available. For
+ // encryption, instead encrypt the first set of blocks, then hash those
+ // blocks while encrypting the next set of blocks, repeat that as
+ // needed, and finally hash the last set of blocks.
+
+.if \enc
+ // Encrypt the first 4 vectors of plaintext blocks. Leave the resulting
+ // ciphertext in GHASHDATA[0-3] for GHASH.
+ _ctr_begin_4x
+ lea 16(KEY), %rax
+1:
+ vbroadcasti32x4 (%rax), RNDKEY
+ _vaesenc_4x RNDKEY
+ add $16, %rax
+ cmp %rax, RNDKEYLAST_PTR
+ jne 1b
+ vpxord 0*VL(SRC), RNDKEYLAST, RNDKEYLAST0
+ vpxord 1*VL(SRC), RNDKEYLAST, RNDKEYLAST1
+ vpxord 2*VL(SRC), RNDKEYLAST, RNDKEYLAST2
+ vpxord 3*VL(SRC), RNDKEYLAST, RNDKEYLAST3
+ vaesenclast RNDKEYLAST0, V0, GHASHDATA0
+ vaesenclast RNDKEYLAST1, V1, GHASHDATA1
+ vaesenclast RNDKEYLAST2, V2, GHASHDATA2
+ vaesenclast RNDKEYLAST3, V3, GHASHDATA3
+ vmovdqu8 GHASHDATA0, 0*VL(DST)
+ vmovdqu8 GHASHDATA1, 1*VL(DST)
+ vmovdqu8 GHASHDATA2, 2*VL(DST)
+ vmovdqu8 GHASHDATA3, 3*VL(DST)
+ add $4*VL, SRC
+ add $4*VL, DST
+ sub $4*VL, DATALEN
+ jl .Lghash_last_ciphertext_4x\@
+.endif
+
+ // Cache as many additional AES round keys as possible.
+.irp i, 9,8,7,6,5
+ vbroadcasti32x4 -\i*16(RNDKEYLAST_PTR), RNDKEY_M\i
+.endr
+
+.Lcrypt_loop_4x\@:
+
+ // If decrypting, load more ciphertext blocks into GHASHDATA[0-3]. If
+ // encrypting, GHASHDATA[0-3] already contain the previous ciphertext.
+.if !\enc
+ vmovdqu8 0*VL(SRC), GHASHDATA0
+ vmovdqu8 1*VL(SRC), GHASHDATA1
+ vmovdqu8 2*VL(SRC), GHASHDATA2
+ vmovdqu8 3*VL(SRC), GHASHDATA3
+.endif
+
+ // Start the AES encryption of the counter blocks.
+ _ctr_begin_4x
+ cmp $24, AESKEYLEN
+ jl 128f // AES-128?
+ je 192f // AES-192?
+ // AES-256
+ vbroadcasti32x4 -13*16(RNDKEYLAST_PTR), RNDKEY
+ _vaesenc_4x RNDKEY
+ vbroadcasti32x4 -12*16(RNDKEYLAST_PTR), RNDKEY
+ _vaesenc_4x RNDKEY
+192:
+ vbroadcasti32x4 -11*16(RNDKEYLAST_PTR), RNDKEY
+ _vaesenc_4x RNDKEY
+ vbroadcasti32x4 -10*16(RNDKEYLAST_PTR), RNDKEY
+ _vaesenc_4x RNDKEY
+128:
+
+ // XOR the source data with the last round key, saving the result in
+ // RNDKEYLAST[0-3]. This reduces latency by taking advantage of the
+ // property vaesenclast(key, a) ^ b == vaesenclast(key ^ b, a).
+.if \enc
+ vpxord 0*VL(SRC), RNDKEYLAST, RNDKEYLAST0
+ vpxord 1*VL(SRC), RNDKEYLAST, RNDKEYLAST1
+ vpxord 2*VL(SRC), RNDKEYLAST, RNDKEYLAST2
+ vpxord 3*VL(SRC), RNDKEYLAST, RNDKEYLAST3
+.else
+ vpxord GHASHDATA0, RNDKEYLAST, RNDKEYLAST0
+ vpxord GHASHDATA1, RNDKEYLAST, RNDKEYLAST1
+ vpxord GHASHDATA2, RNDKEYLAST, RNDKEYLAST2
+ vpxord GHASHDATA3, RNDKEYLAST, RNDKEYLAST3
+.endif
+
+ // Finish the AES encryption of the counter blocks in V0-V3, interleaved
+ // with the GHASH update of the ciphertext blocks in GHASHDATA[0-3].
+.irp i, 9,8,7,6,5
+ _vaesenc_4x RNDKEY_M\i
+ _ghash_step_4x (9 - \i)
+.endr
+.irp i, 4,3,2,1
+ vbroadcasti32x4 -\i*16(RNDKEYLAST_PTR), RNDKEY
+ _vaesenc_4x RNDKEY
+ _ghash_step_4x (9 - \i)
+.endr
+ _ghash_step_4x 9
+
+ // Do the last AES round. This handles the XOR with the source data
+ // too, as per the optimization described above.
+ vaesenclast RNDKEYLAST0, V0, GHASHDATA0
+ vaesenclast RNDKEYLAST1, V1, GHASHDATA1
+ vaesenclast RNDKEYLAST2, V2, GHASHDATA2
+ vaesenclast RNDKEYLAST3, V3, GHASHDATA3
+
+ // Store the en/decrypted data to DST.
+ vmovdqu8 GHASHDATA0, 0*VL(DST)
+ vmovdqu8 GHASHDATA1, 1*VL(DST)
+ vmovdqu8 GHASHDATA2, 2*VL(DST)
+ vmovdqu8 GHASHDATA3, 3*VL(DST)
+
+ add $4*VL, SRC
+ add $4*VL, DST
+ sub $4*VL, DATALEN
+ jge .Lcrypt_loop_4x\@
+
+.if \enc
+.Lghash_last_ciphertext_4x\@:
+ // Update GHASH with the last set of ciphertext blocks.
+.irp i, 0,1,2,3,4,5,6,7,8,9
+ _ghash_step_4x \i
+.endr
+.endif
+
+.Lcrypt_loop_4x_done\@:
+
+ // Undo the extra subtraction by 4*VL and check whether data remains.
+ add $4*VL, DATALEN
+ jz .Ldone\@
+
+ // The data length isn't a multiple of 4*VL. Process the remaining data
+ // of length 1 <= DATALEN < 4*VL, up to one vector (VL bytes) at a time.
+ // Going one vector at a time may seem inefficient compared to having
+ // separate code paths for each possible number of vectors remaining.
+ // However, using a loop keeps the code size down, and it performs
+ // surprising well; modern CPUs will start executing the next iteration
+ // before the previous one finishes and also predict the number of loop
+ // iterations. For a similar reason, we roll up the AES rounds.
+ //
+ // On the last iteration, the remaining length may be less than VL.
+ // Handle this using masking.
+ //
+ // Since there are enough key powers available for all remaining data,
+ // there is no need to do a GHASH reduction after each iteration.
+ // Instead, multiply each remaining block by its own key power, and only
+ // do a GHASH reduction at the very end.
+
+ // Make POWERS_PTR point to the key powers [H^N, H^(N-1), ...] where N
+ // is the number of blocks that remain.
+ .set POWERS_PTR, LE_CTR_PTR // LE_CTR_PTR is free to be reused.
+ mov DATALEN, %eax
+ neg %rax
+ and $~15, %rax // -round_up(DATALEN, 16)
+ lea OFFSETOFEND_H_POWERS(KEY,%rax), POWERS_PTR
+
+ // Start collecting the unreduced GHASH intermediate value LO, MI, HI.
+ .set LO, GHASHDATA0
+ .set LO_XMM, GHASHDATA0_XMM
+ .set MI, GHASHDATA1
+ .set MI_XMM, GHASHDATA1_XMM
+ .set HI, GHASHDATA2
+ .set HI_XMM, GHASHDATA2_XMM
+ vpxor LO_XMM, LO_XMM, LO_XMM
+ vpxor MI_XMM, MI_XMM, MI_XMM
+ vpxor HI_XMM, HI_XMM, HI_XMM
+
+.Lcrypt_loop_1x\@:
+
+ // Select the appropriate mask for this iteration: all 1's if
+ // DATALEN >= VL, otherwise DATALEN 1's. Do this branchlessly using the
+ // bzhi instruction from BMI2. (This relies on DATALEN <= 255.)
+.if VL < 64
+ mov $-1, %eax
+ bzhi DATALEN, %eax, %eax
+ kmovd %eax, %k1
+.else
+ mov $-1, %rax
+ bzhi DATALEN64, %rax, %rax
+ kmovq %rax, %k1
+.endif
+
+ // Encrypt a vector of counter blocks. This does not need to be masked.
+ vpshufb BSWAP_MASK, LE_CTR, V0
+ vpaddd LE_CTR_INC, LE_CTR, LE_CTR
+ vpxord RNDKEY0, V0, V0
+ lea 16(KEY), %rax
+1:
+ vbroadcasti32x4 (%rax), RNDKEY
+ vaesenc RNDKEY, V0, V0
+ add $16, %rax
+ cmp %rax, RNDKEYLAST_PTR
+ jne 1b
+ vaesenclast RNDKEYLAST, V0, V0
+
+ // XOR the data with the appropriate number of keystream bytes.
+ vmovdqu8 (SRC), V1{%k1}{z}
+ vpxord V1, V0, V0
+ vmovdqu8 V0, (DST){%k1}
+
+ // Update GHASH with the ciphertext block(s), without reducing.
+ //
+ // In the case of DATALEN < VL, the ciphertext is zero-padded to VL.
+ // (If decrypting, it's done by the above masked load. If encrypting,
+ // it's done by the below masked register-to-register move.) Note that
+ // if DATALEN <= VL - 16, there will be additional padding beyond the
+ // padding of the last block specified by GHASH itself; i.e., there may
+ // be whole block(s) that get processed by the GHASH multiplication and
+ // reduction instructions but should not actually be included in the
+ // GHASH. However, any such blocks are all-zeroes, and the values that
+ // they're multiplied with are also all-zeroes. Therefore they just add
+ // 0 * 0 = 0 to the final GHASH result, which makes no difference.
+ vmovdqu8 (POWERS_PTR), H_POW1
+.if \enc
+ vmovdqu8 V0, V1{%k1}{z}
+.endif
+ vpshufb BSWAP_MASK, V1, V0
+ vpxord GHASH_ACC, V0, V0
+ _ghash_mul_noreduce H_POW1, V0, LO, MI, HI, GHASHDATA3, V1, V2, V3
+ vpxor GHASH_ACC_XMM, GHASH_ACC_XMM, GHASH_ACC_XMM
+
+ add $VL, POWERS_PTR
+ add $VL, SRC
+ add $VL, DST
+ sub $VL, DATALEN
+ jg .Lcrypt_loop_1x\@
+
+ // Finally, do the GHASH reduction.
+ _ghash_reduce LO, MI, HI, GFPOLY, V0
+ _horizontal_xor HI, HI_XMM, GHASH_ACC_XMM, %xmm0, %xmm1, %xmm2
+
+.Ldone\@:
+ // Store the updated GHASH accumulator back to memory.
+ vmovdqu GHASH_ACC_XMM, (GHASH_ACC_PTR)
+
+ vzeroupper // This is needed after using ymm or zmm registers.
+ RET
+.endm
+
+// void aes_gcm_enc_final_vaes_avx10(const struct aes_gcm_key_avx10 *key,
+// const u32 le_ctr[4], u8 ghash_acc[16],
+// u64 total_aadlen, u64 total_datalen);
+// bool aes_gcm_dec_final_vaes_avx10(const struct aes_gcm_key_avx10 *key,
+// const u32 le_ctr[4],
+// const u8 ghash_acc[16],
+// u64 total_aadlen, u64 total_datalen,
+// const u8 tag[16], int taglen);
+//
+// This macro generates one of the above two functions (with \enc selecting
+// which one). Both functions finish computing the GCM authentication tag by
+// updating GHASH with the lengths block and encrypting the GHASH accumulator.
+// |total_aadlen| and |total_datalen| must be the total length of the additional
+// authenticated data and the en/decrypted data in bytes, respectively.
+//
+// The encryption function then stores the full-length (16-byte) computed
+// authentication tag to |ghash_acc|. The decryption function instead loads the
+// expected authentication tag (the one that was transmitted) from the 16-byte
+// buffer |tag|, compares the first 4 <= |taglen| <= 16 bytes of it to the
+// computed tag in constant time, and returns true if and only if they match.
+.macro _aes_gcm_final enc
+
+ // Function arguments
+ .set KEY, %rdi
+ .set LE_CTR_PTR, %rsi
+ .set GHASH_ACC_PTR, %rdx
+ .set TOTAL_AADLEN, %rcx
+ .set TOTAL_DATALEN, %r8
+ .set TAG, %r9
+ .set TAGLEN, %r10d // Originally at 8(%rsp)
+
+ // Additional local variables.
+ // %rax, %xmm0-%xmm3, and %k1 are used as temporary registers.
+ .set AESKEYLEN, %r11d
+ .set AESKEYLEN64, %r11
+ .set GFPOLY, %xmm4
+ .set BSWAP_MASK, %xmm5
+ .set LE_CTR, %xmm6
+ .set GHASH_ACC, %xmm7
+ .set H_POW1, %xmm8
+
+ // Load some constants.
+ vmovdqa .Lgfpoly(%rip), GFPOLY
+ vmovdqa .Lbswap_mask(%rip), BSWAP_MASK
+
+ // Load the AES key length in bytes.
+ movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN
+
+ // Set up a counter block with 1 in the low 32-bit word. This is the
+ // counter that produces the ciphertext needed to encrypt the auth tag.
+ // GFPOLY has 1 in the low word, so grab the 1 from there using a blend.
+ vpblendd $0xe, (LE_CTR_PTR), GFPOLY, LE_CTR
+
+ // Build the lengths block and XOR it with the GHASH accumulator.
+ // Although the lengths block is defined as the AAD length followed by
+ // the en/decrypted data length, both in big-endian byte order, a byte
+ // reflection of the full block is needed because of the way we compute
+ // GHASH (see _ghash_mul_step). By using little-endian values in the
+ // opposite order, we avoid having to reflect any bytes here.
+ vmovq TOTAL_DATALEN, %xmm0
+ vpinsrq $1, TOTAL_AADLEN, %xmm0, %xmm0
+ vpsllq $3, %xmm0, %xmm0 // Bytes to bits
+ vpxor (GHASH_ACC_PTR), %xmm0, GHASH_ACC
+
+ // Load the first hash key power (H^1), which is stored last.
+ vmovdqu8 OFFSETOFEND_H_POWERS-16(KEY), H_POW1
+
+.if !\enc
+ // Prepare a mask of TAGLEN one bits.
+ movl 8(%rsp), TAGLEN
+ mov $-1, %eax
+ bzhi TAGLEN, %eax, %eax
+ kmovd %eax, %k1
+.endif
+
+ // Make %rax point to the last AES round key for the chosen AES variant.
+ lea 6*16(KEY,AESKEYLEN64,4), %rax
+
+ // Start the AES encryption of the counter block by swapping the counter
+ // block to big-endian and XOR-ing it with the zero-th AES round key.
+ vpshufb BSWAP_MASK, LE_CTR, %xmm0
+ vpxor (KEY), %xmm0, %xmm0
+
+ // Complete the AES encryption and multiply GHASH_ACC by H^1.
+ // Interleave the AES and GHASH instructions to improve performance.
+ cmp $24, AESKEYLEN
+ jl 128f // AES-128?
+ je 192f // AES-192?
+ // AES-256
+ vaesenc -13*16(%rax), %xmm0, %xmm0
+ vaesenc -12*16(%rax), %xmm0, %xmm0
+192:
+ vaesenc -11*16(%rax), %xmm0, %xmm0
+ vaesenc -10*16(%rax), %xmm0, %xmm0
+128:
+.irp i, 0,1,2,3,4,5,6,7,8
+ _ghash_mul_step \i, H_POW1, GHASH_ACC, GHASH_ACC, GFPOLY, \
+ %xmm1, %xmm2, %xmm3
+ vaesenc (\i-9)*16(%rax), %xmm0, %xmm0
+.endr
+ _ghash_mul_step 9, H_POW1, GHASH_ACC, GHASH_ACC, GFPOLY, \
+ %xmm1, %xmm2, %xmm3
+
+ // Undo the byte reflection of the GHASH accumulator.
+ vpshufb BSWAP_MASK, GHASH_ACC, GHASH_ACC
+
+ // Do the last AES round and XOR the resulting keystream block with the
+ // GHASH accumulator to produce the full computed authentication tag.
+ //
+ // Reduce latency by taking advantage of the property vaesenclast(key,
+ // a) ^ b == vaesenclast(key ^ b, a). I.e., XOR GHASH_ACC into the last
+ // round key, instead of XOR'ing the final AES output with GHASH_ACC.
+ //
+ // enc_final then returns the computed auth tag, while dec_final
+ // compares it with the transmitted one and returns a bool. To compare
+ // the tags, dec_final XORs them together and uses vptest to check
+ // whether the result is all-zeroes. This should be constant-time.
+ // dec_final applies the vaesenclast optimization to this additional
+ // value XOR'd too, using vpternlogd to XOR the last round key, GHASH
+ // accumulator, and transmitted auth tag together in one instruction.
+.if \enc
+ vpxor (%rax), GHASH_ACC, %xmm1
+ vaesenclast %xmm1, %xmm0, GHASH_ACC
+ vmovdqu GHASH_ACC, (GHASH_ACC_PTR)
+.else
+ vmovdqu (TAG), %xmm1
+ vpternlogd $0x96, (%rax), GHASH_ACC, %xmm1
+ vaesenclast %xmm1, %xmm0, %xmm0
+ xor %eax, %eax
+ vmovdqu8 %xmm0, %xmm0{%k1}{z} // Truncate to TAGLEN bytes
+ vptest %xmm0, %xmm0
+ sete %al
+.endif
+ // No need for vzeroupper here, since only used xmm registers were used.
+ RET
+.endm
+
+_set_veclen 32
+SYM_FUNC_START(aes_gcm_precompute_vaes_avx10_256)
+ _aes_gcm_precompute
+SYM_FUNC_END(aes_gcm_precompute_vaes_avx10_256)
+SYM_FUNC_START(aes_gcm_enc_update_vaes_avx10_256)
+ _aes_gcm_update 1
+SYM_FUNC_END(aes_gcm_enc_update_vaes_avx10_256)
+SYM_FUNC_START(aes_gcm_dec_update_vaes_avx10_256)
+ _aes_gcm_update 0
+SYM_FUNC_END(aes_gcm_dec_update_vaes_avx10_256)
+
+_set_veclen 64
+SYM_FUNC_START(aes_gcm_precompute_vaes_avx10_512)
+ _aes_gcm_precompute
+SYM_FUNC_END(aes_gcm_precompute_vaes_avx10_512)
+SYM_FUNC_START(aes_gcm_enc_update_vaes_avx10_512)
+ _aes_gcm_update 1
+SYM_FUNC_END(aes_gcm_enc_update_vaes_avx10_512)
+SYM_FUNC_START(aes_gcm_dec_update_vaes_avx10_512)
+ _aes_gcm_update 0
+SYM_FUNC_END(aes_gcm_dec_update_vaes_avx10_512)
+
+// void aes_gcm_aad_update_vaes_avx10(const struct aes_gcm_key_avx10 *key,
+// u8 ghash_acc[16],
+// const u8 *aad, int aadlen);
+//
+// This function processes the AAD (Additional Authenticated Data) in GCM.
+// Using the key |key|, it updates the GHASH accumulator |ghash_acc| with the
+// data given by |aad| and |aadlen|. |key->ghash_key_powers| must have been
+// initialized. On the first call, |ghash_acc| must be all zeroes. |aadlen|
+// must be a multiple of 16, except on the last call where it can be any length.
+// The caller must do any buffering needed to ensure this.
+//
+// AES-GCM is almost always used with small amounts of AAD, less than 32 bytes.
+// Therefore, for AAD processing we currently only provide this implementation
+// which uses 256-bit vectors (ymm registers) and only has a 1x-wide loop. This
+// keeps the code size down, and it enables some micro-optimizations, e.g. using
+// VEX-coded instructions instead of EVEX-coded to save some instruction bytes.
+// To optimize for large amounts of AAD, we could implement a 4x-wide loop and
+// provide a version using 512-bit vectors, but that doesn't seem to be useful.
+SYM_FUNC_START(aes_gcm_aad_update_vaes_avx10)
+
+ // Function arguments
+ .set KEY, %rdi
+ .set GHASH_ACC_PTR, %rsi
+ .set AAD, %rdx
+ .set AADLEN, %ecx
+ .set AADLEN64, %rcx // Zero-extend AADLEN before using!
+
+ // Additional local variables.
+ // %rax, %ymm0-%ymm3, and %k1 are used as temporary registers.
+ .set BSWAP_MASK, %ymm4
+ .set GFPOLY, %ymm5
+ .set GHASH_ACC, %ymm6
+ .set GHASH_ACC_XMM, %xmm6
+ .set H_POW1, %ymm7
+
+ // Load some constants.
+ vbroadcasti128 .Lbswap_mask(%rip), BSWAP_MASK
+ vbroadcasti128 .Lgfpoly(%rip), GFPOLY
+
+ // Load the GHASH accumulator.
+ vmovdqu (GHASH_ACC_PTR), GHASH_ACC_XMM
+
+ // Update GHASH with 32 bytes of AAD at a time.
+ //
+ // Pre-subtracting 32 from AADLEN saves an instruction from the loop and
+ // also ensures that at least one write always occurs to AADLEN,
+ // zero-extending it and allowing AADLEN64 to be used later.
+ sub $32, AADLEN
+ jl .Laad_loop_1x_done
+ vmovdqu8 OFFSETOFEND_H_POWERS-32(KEY), H_POW1 // [H^2, H^1]
+.Laad_loop_1x:
+ vmovdqu (AAD), %ymm0
+ vpshufb BSWAP_MASK, %ymm0, %ymm0
+ vpxor %ymm0, GHASH_ACC, GHASH_ACC
+ _ghash_mul H_POW1, GHASH_ACC, GHASH_ACC, GFPOLY, \
+ %ymm0, %ymm1, %ymm2
+ vextracti128 $1, GHASH_ACC, %xmm0
+ vpxor %xmm0, GHASH_ACC_XMM, GHASH_ACC_XMM
+ add $32, AAD
+ sub $32, AADLEN
+ jge .Laad_loop_1x
+.Laad_loop_1x_done:
+ add $32, AADLEN
+ jz .Laad_done
+
+ // Update GHASH with the remaining 1 <= AADLEN < 32 bytes of AAD.
+ mov $-1, %eax
+ bzhi AADLEN, %eax, %eax
+ kmovd %eax, %k1
+ vmovdqu8 (AAD), %ymm0{%k1}{z}
+ neg AADLEN64
+ and $~15, AADLEN64 // -round_up(AADLEN, 16)
+ vmovdqu8 OFFSETOFEND_H_POWERS(KEY,AADLEN64), H_POW1
+ vpshufb BSWAP_MASK, %ymm0, %ymm0
+ vpxor %ymm0, GHASH_ACC, GHASH_ACC
+ _ghash_mul H_POW1, GHASH_ACC, GHASH_ACC, GFPOLY, \
+ %ymm0, %ymm1, %ymm2
+ vextracti128 $1, GHASH_ACC, %xmm0
+ vpxor %xmm0, GHASH_ACC_XMM, GHASH_ACC_XMM
+
+.Laad_done:
+ // Store the updated GHASH accumulator back to memory.
+ vmovdqu GHASH_ACC_XMM, (GHASH_ACC_PTR)
+
+ vzeroupper // This is needed after using ymm or zmm registers.
+ RET
+SYM_FUNC_END(aes_gcm_aad_update_vaes_avx10)
+
+SYM_FUNC_START(aes_gcm_enc_final_vaes_avx10)
+ _aes_gcm_final 1
+SYM_FUNC_END(aes_gcm_enc_final_vaes_avx10)
+SYM_FUNC_START(aes_gcm_dec_final_vaes_avx10)
+ _aes_gcm_final 0
+SYM_FUNC_END(aes_gcm_dec_final_vaes_avx10)
diff --git a/arch/x86/crypto/aes-xts-avx-x86_64.S b/arch/x86/crypto/aes-xts-avx-x86_64.S
new file mode 100644
index 000000000000..48f97b79f7a9
--- /dev/null
+++ b/arch/x86/crypto/aes-xts-avx-x86_64.S
@@ -0,0 +1,845 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * AES-XTS for modern x86_64 CPUs
+ *
+ * Copyright 2024 Google LLC
+ *
+ * Author: Eric Biggers <ebiggers@google.com>
+ */
+
+/*
+ * This file implements AES-XTS for modern x86_64 CPUs. To handle the
+ * complexities of coding for x86 SIMD, e.g. where every vector length needs
+ * different code, it uses a macro to generate several implementations that
+ * share similar source code but are targeted at different CPUs, listed below:
+ *
+ * AES-NI + AVX
+ * - 128-bit vectors (1 AES block per vector)
+ * - VEX-coded instructions
+ * - xmm0-xmm15
+ * - This is for older CPUs that lack VAES but do have AVX.
+ *
+ * VAES + VPCLMULQDQ + AVX2
+ * - 256-bit vectors (2 AES blocks per vector)
+ * - VEX-coded instructions
+ * - ymm0-ymm15
+ * - This is for CPUs that have VAES but lack AVX512 or AVX10,
+ * e.g. Intel's Alder Lake and AMD's Zen 3.
+ *
+ * VAES + VPCLMULQDQ + AVX10/256 + BMI2
+ * - 256-bit vectors (2 AES blocks per vector)
+ * - EVEX-coded instructions
+ * - ymm0-ymm31
+ * - This is for CPUs that have AVX512 but where using zmm registers causes
+ * downclocking, and for CPUs that have AVX10/256 but not AVX10/512.
+ * - By "AVX10/256" we really mean (AVX512BW + AVX512VL) || AVX10/256.
+ * To avoid confusion with 512-bit, we just write AVX10/256.
+ *
+ * VAES + VPCLMULQDQ + AVX10/512 + BMI2
+ * - Same as the previous one, but upgrades to 512-bit vectors
+ * (4 AES blocks per vector) in zmm0-zmm31.
+ * - This is for CPUs that have good AVX512 or AVX10/512 support.
+ *
+ * This file doesn't have an implementation for AES-NI alone (without AVX), as
+ * the lack of VEX would make all the assembly code different.
+ *
+ * When we use VAES, we also use VPCLMULQDQ to parallelize the computation of
+ * the XTS tweaks. This avoids a bottleneck. Currently there don't seem to be
+ * any CPUs that support VAES but not VPCLMULQDQ. If that changes, we might
+ * need to start also providing an implementation using VAES alone.
+ *
+ * The AES-XTS implementations in this file support everything required by the
+ * crypto API, including support for arbitrary input lengths and multi-part
+ * processing. However, they are most heavily optimized for the common case of
+ * power-of-2 length inputs that are processed in a single part (disk sectors).
+ */
+
+#include <linux/linkage.h>
+#include <linux/cfi_types.h>
+
+.section .rodata
+.p2align 4
+.Lgf_poly:
+ // The low 64 bits of this value represent the polynomial x^7 + x^2 + x
+ // + 1. It is the value that must be XOR'd into the low 64 bits of the
+ // tweak each time a 1 is carried out of the high 64 bits.
+ //
+ // The high 64 bits of this value is just the internal carry bit that
+ // exists when there's a carry out of the low 64 bits of the tweak.
+ .quad 0x87, 1
+
+ // This table contains constants for vpshufb and vpblendvb, used to
+ // handle variable byte shifts and blending during ciphertext stealing
+ // on CPUs that don't support AVX10-style masking.
+.Lcts_permute_table:
+ .byte 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+ .byte 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+ .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+ .byte 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ .byte 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+ .byte 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+.text
+
+// Function parameters
+.set KEY, %rdi // Initially points to crypto_aes_ctx, then is
+ // advanced to point to 7th-from-last round key
+.set SRC, %rsi // Pointer to next source data
+.set DST, %rdx // Pointer to next destination data
+.set LEN, %ecx // Remaining length in bytes
+.set LEN8, %cl
+.set LEN64, %rcx
+.set TWEAK, %r8 // Pointer to next tweak
+
+// %rax holds the AES key length in bytes.
+.set KEYLEN, %eax
+.set KEYLEN64, %rax
+
+// %r9-r11 are available as temporaries.
+
+.macro _define_Vi i
+.if VL == 16
+ .set V\i, %xmm\i
+.elseif VL == 32
+ .set V\i, %ymm\i
+.elseif VL == 64
+ .set V\i, %zmm\i
+.else
+ .error "Unsupported Vector Length (VL)"
+.endif
+.endm
+
+.macro _define_aliases
+ // Define register aliases V0-V15, or V0-V31 if all 32 SIMD registers
+ // are available, that map to the xmm, ymm, or zmm registers according
+ // to the selected Vector Length (VL).
+ _define_Vi 0
+ _define_Vi 1
+ _define_Vi 2
+ _define_Vi 3
+ _define_Vi 4
+ _define_Vi 5
+ _define_Vi 6
+ _define_Vi 7
+ _define_Vi 8
+ _define_Vi 9
+ _define_Vi 10
+ _define_Vi 11
+ _define_Vi 12
+ _define_Vi 13
+ _define_Vi 14
+ _define_Vi 15
+.if USE_AVX10
+ _define_Vi 16
+ _define_Vi 17
+ _define_Vi 18
+ _define_Vi 19
+ _define_Vi 20
+ _define_Vi 21
+ _define_Vi 22
+ _define_Vi 23
+ _define_Vi 24
+ _define_Vi 25
+ _define_Vi 26
+ _define_Vi 27
+ _define_Vi 28
+ _define_Vi 29
+ _define_Vi 30
+ _define_Vi 31
+.endif
+
+ // V0-V3 hold the data blocks during the main loop, or temporary values
+ // otherwise. V4-V5 hold temporary values.
+
+ // V6-V9 hold XTS tweaks. Each 128-bit lane holds one tweak.
+ .set TWEAK0_XMM, %xmm6
+ .set TWEAK0, V6
+ .set TWEAK1_XMM, %xmm7
+ .set TWEAK1, V7
+ .set TWEAK2, V8
+ .set TWEAK3, V9
+
+ // V10-V13 are used for computing the next values of TWEAK[0-3].
+ .set NEXT_TWEAK0, V10
+ .set NEXT_TWEAK1, V11
+ .set NEXT_TWEAK2, V12
+ .set NEXT_TWEAK3, V13
+
+ // V14 holds the constant from .Lgf_poly, copied to all 128-bit lanes.
+ .set GF_POLY_XMM, %xmm14
+ .set GF_POLY, V14
+
+ // V15 holds the key for AES "round 0", copied to all 128-bit lanes.
+ .set KEY0_XMM, %xmm15
+ .set KEY0, V15
+
+ // If 32 SIMD registers are available, then V16-V29 hold the remaining
+ // AES round keys, copied to all 128-bit lanes.
+ //
+ // AES-128, AES-192, and AES-256 use different numbers of round keys.
+ // To allow handling all three variants efficiently, we align the round
+ // keys to the *end* of this register range. I.e., AES-128 uses
+ // KEY5-KEY14, AES-192 uses KEY3-KEY14, and AES-256 uses KEY1-KEY14.
+ // (All also use KEY0 for the XOR-only "round" at the beginning.)
+.if USE_AVX10
+ .set KEY1_XMM, %xmm16
+ .set KEY1, V16
+ .set KEY2_XMM, %xmm17
+ .set KEY2, V17
+ .set KEY3_XMM, %xmm18
+ .set KEY3, V18
+ .set KEY4_XMM, %xmm19
+ .set KEY4, V19
+ .set KEY5_XMM, %xmm20
+ .set KEY5, V20
+ .set KEY6_XMM, %xmm21
+ .set KEY6, V21
+ .set KEY7_XMM, %xmm22
+ .set KEY7, V22
+ .set KEY8_XMM, %xmm23
+ .set KEY8, V23
+ .set KEY9_XMM, %xmm24
+ .set KEY9, V24
+ .set KEY10_XMM, %xmm25
+ .set KEY10, V25
+ .set KEY11_XMM, %xmm26
+ .set KEY11, V26
+ .set KEY12_XMM, %xmm27
+ .set KEY12, V27
+ .set KEY13_XMM, %xmm28
+ .set KEY13, V28
+ .set KEY14_XMM, %xmm29
+ .set KEY14, V29
+.endif
+ // V30-V31 are currently unused.
+.endm
+
+// Move a vector between memory and a register.
+.macro _vmovdqu src, dst
+.if VL < 64
+ vmovdqu \src, \dst
+.else
+ vmovdqu8 \src, \dst
+.endif
+.endm
+
+// Broadcast a 128-bit value into a vector.
+.macro _vbroadcast128 src, dst
+.if VL == 16 && !USE_AVX10
+ vmovdqu \src, \dst
+.elseif VL == 32 && !USE_AVX10
+ vbroadcasti128 \src, \dst
+.else
+ vbroadcasti32x4 \src, \dst
+.endif
+.endm
+
+// XOR two vectors together.
+.macro _vpxor src1, src2, dst
+.if USE_AVX10
+ vpxord \src1, \src2, \dst
+.else
+ vpxor \src1, \src2, \dst
+.endif
+.endm
+
+// XOR three vectors together.
+.macro _xor3 src1, src2, src3_and_dst
+.if USE_AVX10
+ // vpternlogd with immediate 0x96 is a three-argument XOR.
+ vpternlogd $0x96, \src1, \src2, \src3_and_dst
+.else
+ vpxor \src1, \src3_and_dst, \src3_and_dst
+ vpxor \src2, \src3_and_dst, \src3_and_dst
+.endif
+.endm
+
+// Given a 128-bit XTS tweak in the xmm register \src, compute the next tweak
+// (by multiplying by the polynomial 'x') and write it to \dst.
+.macro _next_tweak src, tmp, dst
+ vpshufd $0x13, \src, \tmp
+ vpaddq \src, \src, \dst
+ vpsrad $31, \tmp, \tmp
+ vpand GF_POLY_XMM, \tmp, \tmp
+ vpxor \tmp, \dst, \dst
+.endm
+
+// Given the XTS tweak(s) in the vector \src, compute the next vector of
+// tweak(s) (by multiplying by the polynomial 'x^(VL/16)') and write it to \dst.
+//
+// If VL > 16, then there are multiple tweaks, and we use vpclmulqdq to compute
+// all tweaks in the vector in parallel. If VL=16, we just do the regular
+// computation without vpclmulqdq, as it's the faster method for a single tweak.
+.macro _next_tweakvec src, tmp1, tmp2, dst
+.if VL == 16
+ _next_tweak \src, \tmp1, \dst
+.else
+ vpsrlq $64 - VL/16, \src, \tmp1
+ vpclmulqdq $0x01, GF_POLY, \tmp1, \tmp2
+ vpslldq $8, \tmp1, \tmp1
+ vpsllq $VL/16, \src, \dst
+ _xor3 \tmp1, \tmp2, \dst
+.endif
+.endm
+
+// Given the first XTS tweak at (TWEAK), compute the first set of tweaks and
+// store them in the vector registers TWEAK0-TWEAK3. Clobbers V0-V5.
+.macro _compute_first_set_of_tweaks
+ vmovdqu (TWEAK), TWEAK0_XMM
+ _vbroadcast128 .Lgf_poly(%rip), GF_POLY
+.if VL == 16
+ // With VL=16, multiplying by x serially is fastest.
+ _next_tweak TWEAK0, %xmm0, TWEAK1
+ _next_tweak TWEAK1, %xmm0, TWEAK2
+ _next_tweak TWEAK2, %xmm0, TWEAK3
+.else
+.if VL == 32
+ // Compute the second block of TWEAK0.
+ _next_tweak TWEAK0_XMM, %xmm0, %xmm1
+ vinserti128 $1, %xmm1, TWEAK0, TWEAK0
+.elseif VL == 64
+ // Compute the remaining blocks of TWEAK0.
+ _next_tweak TWEAK0_XMM, %xmm0, %xmm1
+ _next_tweak %xmm1, %xmm0, %xmm2
+ _next_tweak %xmm2, %xmm0, %xmm3
+ vinserti32x4 $1, %xmm1, TWEAK0, TWEAK0
+ vinserti32x4 $2, %xmm2, TWEAK0, TWEAK0
+ vinserti32x4 $3, %xmm3, TWEAK0, TWEAK0
+.endif
+ // Compute TWEAK[1-3] from TWEAK0.
+ vpsrlq $64 - 1*VL/16, TWEAK0, V0
+ vpsrlq $64 - 2*VL/16, TWEAK0, V2
+ vpsrlq $64 - 3*VL/16, TWEAK0, V4
+ vpclmulqdq $0x01, GF_POLY, V0, V1
+ vpclmulqdq $0x01, GF_POLY, V2, V3
+ vpclmulqdq $0x01, GF_POLY, V4, V5
+ vpslldq $8, V0, V0
+ vpslldq $8, V2, V2
+ vpslldq $8, V4, V4
+ vpsllq $1*VL/16, TWEAK0, TWEAK1
+ vpsllq $2*VL/16, TWEAK0, TWEAK2
+ vpsllq $3*VL/16, TWEAK0, TWEAK3
+.if USE_AVX10
+ vpternlogd $0x96, V0, V1, TWEAK1
+ vpternlogd $0x96, V2, V3, TWEAK2
+ vpternlogd $0x96, V4, V5, TWEAK3
+.else
+ vpxor V0, TWEAK1, TWEAK1
+ vpxor V2, TWEAK2, TWEAK2
+ vpxor V4, TWEAK3, TWEAK3
+ vpxor V1, TWEAK1, TWEAK1
+ vpxor V3, TWEAK2, TWEAK2
+ vpxor V5, TWEAK3, TWEAK3
+.endif
+.endif
+.endm
+
+// Do one step in computing the next set of tweaks using the method of just
+// multiplying by x repeatedly (the same method _next_tweak uses).
+.macro _tweak_step_mulx i
+.if \i == 0
+ .set PREV_TWEAK, TWEAK3
+ .set NEXT_TWEAK, NEXT_TWEAK0
+.elseif \i == 5
+ .set PREV_TWEAK, NEXT_TWEAK0
+ .set NEXT_TWEAK, NEXT_TWEAK1
+.elseif \i == 10
+ .set PREV_TWEAK, NEXT_TWEAK1
+ .set NEXT_TWEAK, NEXT_TWEAK2
+.elseif \i == 15
+ .set PREV_TWEAK, NEXT_TWEAK2
+ .set NEXT_TWEAK, NEXT_TWEAK3
+.endif
+.if \i >= 0 && \i < 20 && \i % 5 == 0
+ vpshufd $0x13, PREV_TWEAK, V5
+.elseif \i >= 0 && \i < 20 && \i % 5 == 1
+ vpaddq PREV_TWEAK, PREV_TWEAK, NEXT_TWEAK
+.elseif \i >= 0 && \i < 20 && \i % 5 == 2
+ vpsrad $31, V5, V5
+.elseif \i >= 0 && \i < 20 && \i % 5 == 3
+ vpand GF_POLY, V5, V5
+.elseif \i >= 0 && \i < 20 && \i % 5 == 4
+ vpxor V5, NEXT_TWEAK, NEXT_TWEAK
+.elseif \i == 1000
+ vmovdqa NEXT_TWEAK0, TWEAK0
+ vmovdqa NEXT_TWEAK1, TWEAK1
+ vmovdqa NEXT_TWEAK2, TWEAK2
+ vmovdqa NEXT_TWEAK3, TWEAK3
+.endif
+.endm
+
+// Do one step in computing the next set of tweaks using the VPCLMULQDQ method
+// (the same method _next_tweakvec uses for VL > 16). This means multiplying
+// each tweak by x^(4*VL/16) independently. Since 4*VL/16 is a multiple of 8
+// when VL > 16 (which it is here), the needed shift amounts are byte-aligned,
+// which allows the use of vpsrldq and vpslldq to do 128-bit wide shifts.
+.macro _tweak_step_pclmul i
+.if \i == 0
+ vpsrldq $(128 - 4*VL/16) / 8, TWEAK0, NEXT_TWEAK0
+.elseif \i == 2
+ vpsrldq $(128 - 4*VL/16) / 8, TWEAK1, NEXT_TWEAK1
+.elseif \i == 4
+ vpsrldq $(128 - 4*VL/16) / 8, TWEAK2, NEXT_TWEAK2
+.elseif \i == 6
+ vpsrldq $(128 - 4*VL/16) / 8, TWEAK3, NEXT_TWEAK3
+.elseif \i == 8
+ vpclmulqdq $0x00, GF_POLY, NEXT_TWEAK0, NEXT_TWEAK0
+.elseif \i == 10
+ vpclmulqdq $0x00, GF_POLY, NEXT_TWEAK1, NEXT_TWEAK1
+.elseif \i == 12
+ vpclmulqdq $0x00, GF_POLY, NEXT_TWEAK2, NEXT_TWEAK2
+.elseif \i == 14
+ vpclmulqdq $0x00, GF_POLY, NEXT_TWEAK3, NEXT_TWEAK3
+.elseif \i == 1000
+ vpslldq $(4*VL/16) / 8, TWEAK0, TWEAK0
+ vpslldq $(4*VL/16) / 8, TWEAK1, TWEAK1
+ vpslldq $(4*VL/16) / 8, TWEAK2, TWEAK2
+ vpslldq $(4*VL/16) / 8, TWEAK3, TWEAK3
+ _vpxor NEXT_TWEAK0, TWEAK0, TWEAK0
+ _vpxor NEXT_TWEAK1, TWEAK1, TWEAK1
+ _vpxor NEXT_TWEAK2, TWEAK2, TWEAK2
+ _vpxor NEXT_TWEAK3, TWEAK3, TWEAK3
+.endif
+.endm
+
+// _tweak_step does one step of the computation of the next set of tweaks from
+// TWEAK[0-3]. To complete all steps, this is invoked with increasing values of
+// \i that include at least 0 through 19, then 1000 which signals the last step.
+//
+// This is used to interleave the computation of the next set of tweaks with the
+// AES en/decryptions, which increases performance in some cases.
+.macro _tweak_step i
+.if VL == 16
+ _tweak_step_mulx \i
+.else
+ _tweak_step_pclmul \i
+.endif
+.endm
+
+.macro _setup_round_keys enc
+
+ // Select either the encryption round keys or the decryption round keys.
+.if \enc
+ .set OFFS, 0
+.else
+ .set OFFS, 240
+.endif
+
+ // Load the round key for "round 0".
+ _vbroadcast128 OFFS(KEY), KEY0
+
+ // Increment KEY to make it so that 7*16(KEY) is the last round key.
+ // For AES-128, increment by 3*16, resulting in the 10 round keys (not
+ // counting the zero-th round key which was just loaded into KEY0) being
+ // -2*16(KEY) through 7*16(KEY). For AES-192, increment by 5*16 and use
+ // 12 round keys -4*16(KEY) through 7*16(KEY). For AES-256, increment
+ // by 7*16 and use 14 round keys -6*16(KEY) through 7*16(KEY).
+ //
+ // This rebasing provides two benefits. First, it makes the offset to
+ // any round key be in the range [-96, 112], fitting in a signed byte.
+ // This shortens VEX-encoded instructions that access the later round
+ // keys which otherwise would need 4-byte offsets. Second, it makes it
+ // easy to do AES-128 and AES-192 by skipping irrelevant rounds at the
+ // beginning. Skipping rounds at the end doesn't work as well because
+ // the last round needs different instructions.
+ //
+ // An alternative approach would be to roll up all the round loops. We
+ // don't do that because it isn't compatible with caching the round keys
+ // in registers which we do when possible (see below), and also because
+ // it seems unwise to rely *too* heavily on the CPU's branch predictor.
+ lea OFFS-16(KEY, KEYLEN64, 4), KEY
+
+ // If all 32 SIMD registers are available, cache all the round keys.
+.if USE_AVX10
+ cmp $24, KEYLEN
+ jl .Laes128\@
+ je .Laes192\@
+ _vbroadcast128 -6*16(KEY), KEY1
+ _vbroadcast128 -5*16(KEY), KEY2
+.Laes192\@:
+ _vbroadcast128 -4*16(KEY), KEY3
+ _vbroadcast128 -3*16(KEY), KEY4
+.Laes128\@:
+ _vbroadcast128 -2*16(KEY), KEY5
+ _vbroadcast128 -1*16(KEY), KEY6
+ _vbroadcast128 0*16(KEY), KEY7
+ _vbroadcast128 1*16(KEY), KEY8
+ _vbroadcast128 2*16(KEY), KEY9
+ _vbroadcast128 3*16(KEY), KEY10
+ _vbroadcast128 4*16(KEY), KEY11
+ _vbroadcast128 5*16(KEY), KEY12
+ _vbroadcast128 6*16(KEY), KEY13
+ _vbroadcast128 7*16(KEY), KEY14
+.endif
+.endm
+
+// Do a single round of AES encryption (if \enc==1) or decryption (if \enc==0)
+// on the block(s) in \data using the round key(s) in \key. The register length
+// determines the number of AES blocks en/decrypted.
+.macro _vaes enc, last, key, data
+.if \enc
+.if \last
+ vaesenclast \key, \data, \data
+.else
+ vaesenc \key, \data, \data
+.endif
+.else
+.if \last
+ vaesdeclast \key, \data, \data
+.else
+ vaesdec \key, \data, \data
+.endif
+.endif
+.endm
+
+// Do a single round of AES en/decryption on the block(s) in \data, using the
+// same key for all block(s). The round key is loaded from the appropriate
+// register or memory location for round \i. May clobber V4.
+.macro _vaes_1x enc, last, i, xmm_suffix, data
+.if USE_AVX10
+ _vaes \enc, \last, KEY\i\xmm_suffix, \data
+.else
+.ifnb \xmm_suffix
+ _vaes \enc, \last, (\i-7)*16(KEY), \data
+.else
+ _vbroadcast128 (\i-7)*16(KEY), V4
+ _vaes \enc, \last, V4, \data
+.endif
+.endif
+.endm
+
+// Do a single round of AES en/decryption on the blocks in registers V0-V3,
+// using the same key for all blocks. The round key is loaded from the
+// appropriate register or memory location for round \i. In addition, does two
+// steps of the computation of the next set of tweaks. May clobber V4.
+.macro _vaes_4x enc, last, i
+.if USE_AVX10
+ _tweak_step (2*(\i-5))
+ _vaes \enc, \last, KEY\i, V0
+ _vaes \enc, \last, KEY\i, V1
+ _tweak_step (2*(\i-5) + 1)
+ _vaes \enc, \last, KEY\i, V2
+ _vaes \enc, \last, KEY\i, V3
+.else
+ _vbroadcast128 (\i-7)*16(KEY), V4
+ _tweak_step (2*(\i-5))
+ _vaes \enc, \last, V4, V0
+ _vaes \enc, \last, V4, V1
+ _tweak_step (2*(\i-5) + 1)
+ _vaes \enc, \last, V4, V2
+ _vaes \enc, \last, V4, V3
+.endif
+.endm
+
+// Do tweaked AES en/decryption (i.e., XOR with \tweak, then AES en/decrypt,
+// then XOR with \tweak again) of the block(s) in \data. To process a single
+// block, use xmm registers and set \xmm_suffix=_XMM. To process a vector of
+// length VL, use V* registers and leave \xmm_suffix empty. May clobber V4.
+.macro _aes_crypt enc, xmm_suffix, tweak, data
+ _xor3 KEY0\xmm_suffix, \tweak, \data
+ cmp $24, KEYLEN
+ jl .Laes128\@
+ je .Laes192\@
+ _vaes_1x \enc, 0, 1, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 2, \xmm_suffix, \data
+.Laes192\@:
+ _vaes_1x \enc, 0, 3, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 4, \xmm_suffix, \data
+.Laes128\@:
+ _vaes_1x \enc, 0, 5, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 6, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 7, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 8, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 9, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 10, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 11, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 12, \xmm_suffix, \data
+ _vaes_1x \enc, 0, 13, \xmm_suffix, \data
+ _vaes_1x \enc, 1, 14, \xmm_suffix, \data
+ _vpxor \tweak, \data, \data
+.endm
+
+.macro _aes_xts_crypt enc
+ _define_aliases
+
+.if !\enc
+ // When decrypting a message whose length isn't a multiple of the AES
+ // block length, exclude the last full block from the main loop by
+ // subtracting 16 from LEN. This is needed because ciphertext stealing
+ // decryption uses the last two tweaks in reverse order. We'll handle
+ // the last full block and the partial block specially at the end.
+ lea -16(LEN), %eax
+ test $15, LEN8
+ cmovnz %eax, LEN
+.endif
+
+ // Load the AES key length: 16 (AES-128), 24 (AES-192), or 32 (AES-256).
+ movl 480(KEY), KEYLEN
+
+ // Setup the pointer to the round keys and cache as many as possible.
+ _setup_round_keys \enc
+
+ // Compute the first set of tweaks TWEAK[0-3].
+ _compute_first_set_of_tweaks
+
+ sub $4*VL, LEN
+ jl .Lhandle_remainder\@
+
+.Lmain_loop\@:
+ // This is the main loop, en/decrypting 4*VL bytes per iteration.
+
+ // XOR each source block with its tweak and the zero-th round key.
+.if USE_AVX10
+ vmovdqu8 0*VL(SRC), V0
+ vmovdqu8 1*VL(SRC), V1
+ vmovdqu8 2*VL(SRC), V2
+ vmovdqu8 3*VL(SRC), V3
+ vpternlogd $0x96, TWEAK0, KEY0, V0
+ vpternlogd $0x96, TWEAK1, KEY0, V1
+ vpternlogd $0x96, TWEAK2, KEY0, V2
+ vpternlogd $0x96, TWEAK3, KEY0, V3
+.else
+ vpxor 0*VL(SRC), KEY0, V0
+ vpxor 1*VL(SRC), KEY0, V1
+ vpxor 2*VL(SRC), KEY0, V2
+ vpxor 3*VL(SRC), KEY0, V3
+ vpxor TWEAK0, V0, V0
+ vpxor TWEAK1, V1, V1
+ vpxor TWEAK2, V2, V2
+ vpxor TWEAK3, V3, V3
+.endif
+ cmp $24, KEYLEN
+ jl .Laes128\@
+ je .Laes192\@
+ // Do all the AES rounds on the data blocks, interleaved with
+ // the computation of the next set of tweaks.
+ _vaes_4x \enc, 0, 1
+ _vaes_4x \enc, 0, 2
+.Laes192\@:
+ _vaes_4x \enc, 0, 3
+ _vaes_4x \enc, 0, 4
+.Laes128\@:
+ _vaes_4x \enc, 0, 5
+ _vaes_4x \enc, 0, 6
+ _vaes_4x \enc, 0, 7
+ _vaes_4x \enc, 0, 8
+ _vaes_4x \enc, 0, 9
+ _vaes_4x \enc, 0, 10
+ _vaes_4x \enc, 0, 11
+ _vaes_4x \enc, 0, 12
+ _vaes_4x \enc, 0, 13
+ _vaes_4x \enc, 1, 14
+
+ // XOR in the tweaks again.
+ _vpxor TWEAK0, V0, V0
+ _vpxor TWEAK1, V1, V1
+ _vpxor TWEAK2, V2, V2
+ _vpxor TWEAK3, V3, V3
+
+ // Store the destination blocks.
+ _vmovdqu V0, 0*VL(DST)
+ _vmovdqu V1, 1*VL(DST)
+ _vmovdqu V2, 2*VL(DST)
+ _vmovdqu V3, 3*VL(DST)
+
+ // Finish computing the next set of tweaks.
+ _tweak_step 1000
+
+ add $4*VL, SRC
+ add $4*VL, DST
+ sub $4*VL, LEN
+ jge .Lmain_loop\@
+
+ // Check for the uncommon case where the data length isn't a multiple of
+ // 4*VL. Handle it out-of-line in order to optimize for the common
+ // case. In the common case, just fall through to the ret.
+ test $4*VL-1, LEN8
+ jnz .Lhandle_remainder\@
+.Ldone\@:
+ // Store the next tweak back to *TWEAK to support continuation calls.
+ vmovdqu TWEAK0_XMM, (TWEAK)
+.if VL > 16
+ vzeroupper
+.endif
+ RET
+
+.Lhandle_remainder\@:
+
+ // En/decrypt any remaining full blocks, one vector at a time.
+.if VL > 16
+ add $3*VL, LEN // Undo extra sub of 4*VL, then sub VL.
+ jl .Lvec_at_a_time_done\@
+.Lvec_at_a_time\@:
+ _vmovdqu (SRC), V0
+ _aes_crypt \enc, , TWEAK0, V0
+ _vmovdqu V0, (DST)
+ _next_tweakvec TWEAK0, V0, V1, TWEAK0
+ add $VL, SRC
+ add $VL, DST
+ sub $VL, LEN
+ jge .Lvec_at_a_time\@
+.Lvec_at_a_time_done\@:
+ add $VL-16, LEN // Undo extra sub of VL, then sub 16.
+.else
+ add $4*VL-16, LEN // Undo extra sub of 4*VL, then sub 16.
+.endif
+
+ // En/decrypt any remaining full blocks, one at a time.
+ jl .Lblock_at_a_time_done\@
+.Lblock_at_a_time\@:
+ vmovdqu (SRC), %xmm0
+ _aes_crypt \enc, _XMM, TWEAK0_XMM, %xmm0
+ vmovdqu %xmm0, (DST)
+ _next_tweak TWEAK0_XMM, %xmm0, TWEAK0_XMM
+ add $16, SRC
+ add $16, DST
+ sub $16, LEN
+ jge .Lblock_at_a_time\@
+.Lblock_at_a_time_done\@:
+ add $16, LEN // Undo the extra sub of 16.
+ // Now 0 <= LEN <= 15. If LEN is zero, we're done.
+ jz .Ldone\@
+
+ // Otherwise 1 <= LEN <= 15, but the real remaining length is 16 + LEN.
+ // Do ciphertext stealing to process the last 16 + LEN bytes.
+
+.if \enc
+ // If encrypting, the main loop already encrypted the last full block to
+ // create the CTS intermediate ciphertext. Prepare for the rest of CTS
+ // by rewinding the pointers and loading the intermediate ciphertext.
+ sub $16, SRC
+ sub $16, DST
+ vmovdqu (DST), %xmm0
+.else
+ // If decrypting, the main loop didn't decrypt the last full block
+ // because CTS decryption uses the last two tweaks in reverse order.
+ // Do it now by advancing the tweak and decrypting the last full block.
+ _next_tweak TWEAK0_XMM, %xmm0, TWEAK1_XMM
+ vmovdqu (SRC), %xmm0
+ _aes_crypt \enc, _XMM, TWEAK1_XMM, %xmm0
+.endif
+
+.if USE_AVX10
+ // Create a mask that has the first LEN bits set.
+ mov $-1, %r9d
+ bzhi LEN, %r9d, %r9d
+ kmovd %r9d, %k1
+
+ // Swap the first LEN bytes of the en/decryption of the last full block
+ // with the partial block. Note that to support in-place en/decryption,
+ // the load from the src partial block must happen before the store to
+ // the dst partial block.
+ vmovdqa %xmm0, %xmm1
+ vmovdqu8 16(SRC), %xmm0{%k1}
+ vmovdqu8 %xmm1, 16(DST){%k1}
+.else
+ lea .Lcts_permute_table(%rip), %r9
+
+ // Load the src partial block, left-aligned. Note that to support
+ // in-place en/decryption, this must happen before the store to the dst
+ // partial block.
+ vmovdqu (SRC, LEN64, 1), %xmm1
+
+ // Shift the first LEN bytes of the en/decryption of the last full block
+ // to the end of a register, then store it to DST+LEN. This stores the
+ // dst partial block. It also writes to the second part of the dst last
+ // full block, but that part is overwritten later.
+ vpshufb (%r9, LEN64, 1), %xmm0, %xmm2
+ vmovdqu %xmm2, (DST, LEN64, 1)
+
+ // Make xmm3 contain [16-LEN,16-LEN+1,...,14,15,0x80,0x80,...].
+ sub LEN64, %r9
+ vmovdqu 32(%r9), %xmm3
+
+ // Shift the src partial block to the beginning of its register.
+ vpshufb %xmm3, %xmm1, %xmm1
+
+ // Do a blend to generate the src partial block followed by the second
+ // part of the en/decryption of the last full block.
+ vpblendvb %xmm3, %xmm0, %xmm1, %xmm0
+.endif
+ // En/decrypt again and store the last full block.
+ _aes_crypt \enc, _XMM, TWEAK0_XMM, %xmm0
+ vmovdqu %xmm0, (DST)
+ jmp .Ldone\@
+.endm
+
+// void aes_xts_encrypt_iv(const struct crypto_aes_ctx *tweak_key,
+// u8 iv[AES_BLOCK_SIZE]);
+SYM_TYPED_FUNC_START(aes_xts_encrypt_iv)
+ vmovdqu (%rsi), %xmm0
+ vpxor (%rdi), %xmm0, %xmm0
+ movl 480(%rdi), %eax // AES key length
+ lea -16(%rdi, %rax, 4), %rdi
+ cmp $24, %eax
+ jl .Lencrypt_iv_aes128
+ je .Lencrypt_iv_aes192
+ vaesenc -6*16(%rdi), %xmm0, %xmm0
+ vaesenc -5*16(%rdi), %xmm0, %xmm0
+.Lencrypt_iv_aes192:
+ vaesenc -4*16(%rdi), %xmm0, %xmm0
+ vaesenc -3*16(%rdi), %xmm0, %xmm0
+.Lencrypt_iv_aes128:
+ vaesenc -2*16(%rdi), %xmm0, %xmm0
+ vaesenc -1*16(%rdi), %xmm0, %xmm0
+ vaesenc 0*16(%rdi), %xmm0, %xmm0
+ vaesenc 1*16(%rdi), %xmm0, %xmm0
+ vaesenc 2*16(%rdi), %xmm0, %xmm0
+ vaesenc 3*16(%rdi), %xmm0, %xmm0
+ vaesenc 4*16(%rdi), %xmm0, %xmm0
+ vaesenc 5*16(%rdi), %xmm0, %xmm0
+ vaesenc 6*16(%rdi), %xmm0, %xmm0
+ vaesenclast 7*16(%rdi), %xmm0, %xmm0
+ vmovdqu %xmm0, (%rsi)
+ RET
+SYM_FUNC_END(aes_xts_encrypt_iv)
+
+// Below are the actual AES-XTS encryption and decryption functions,
+// instantiated from the above macro. They all have the following prototype:
+//
+// void (*xts_asm_func)(const struct crypto_aes_ctx *key,
+// const u8 *src, u8 *dst, unsigned int len,
+// u8 tweak[AES_BLOCK_SIZE]);
+//
+// |key| is the data key. |tweak| contains the next tweak; the encryption of
+// the original IV with the tweak key was already done. This function supports
+// incremental computation, but |len| must always be >= 16 (AES_BLOCK_SIZE), and
+// |len| must be a multiple of 16 except on the last call. If |len| is a
+// multiple of 16, then this function updates |tweak| to contain the next tweak.
+
+.set VL, 16
+.set USE_AVX10, 0
+SYM_TYPED_FUNC_START(aes_xts_encrypt_aesni_avx)
+ _aes_xts_crypt 1
+SYM_FUNC_END(aes_xts_encrypt_aesni_avx)
+SYM_TYPED_FUNC_START(aes_xts_decrypt_aesni_avx)
+ _aes_xts_crypt 0
+SYM_FUNC_END(aes_xts_decrypt_aesni_avx)
+
+#if defined(CONFIG_AS_VAES) && defined(CONFIG_AS_VPCLMULQDQ)
+.set VL, 32
+.set USE_AVX10, 0
+SYM_TYPED_FUNC_START(aes_xts_encrypt_vaes_avx2)
+ _aes_xts_crypt 1
+SYM_FUNC_END(aes_xts_encrypt_vaes_avx2)
+SYM_TYPED_FUNC_START(aes_xts_decrypt_vaes_avx2)
+ _aes_xts_crypt 0
+SYM_FUNC_END(aes_xts_decrypt_vaes_avx2)
+
+.set VL, 32
+.set USE_AVX10, 1
+SYM_TYPED_FUNC_START(aes_xts_encrypt_vaes_avx10_256)
+ _aes_xts_crypt 1
+SYM_FUNC_END(aes_xts_encrypt_vaes_avx10_256)
+SYM_TYPED_FUNC_START(aes_xts_decrypt_vaes_avx10_256)
+ _aes_xts_crypt 0
+SYM_FUNC_END(aes_xts_decrypt_vaes_avx10_256)
+
+.set VL, 64
+.set USE_AVX10, 1
+SYM_TYPED_FUNC_START(aes_xts_encrypt_vaes_avx10_512)
+ _aes_xts_crypt 1
+SYM_FUNC_END(aes_xts_encrypt_vaes_avx10_512)
+SYM_TYPED_FUNC_START(aes_xts_decrypt_vaes_avx10_512)
+ _aes_xts_crypt 0
+SYM_FUNC_END(aes_xts_decrypt_vaes_avx10_512)
+#endif /* CONFIG_AS_VAES && CONFIG_AS_VPCLMULQDQ */
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index 411d8c83e88a..eb153eff9331 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -10,16 +10,7 @@
* Vinodh Gopal <vinodh.gopal@intel.com>
* Kahraman Akdemir
*
- * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD
- * interface for 64-bit kernels.
- * Authors: Erdinc Ozturk (erdinc.ozturk@intel.com)
- * Aidan O'Mahony (aidan.o.mahony@intel.com)
- * Adrian Hoban <adrian.hoban@intel.com>
- * James Guilford (james.guilford@intel.com)
- * Gabriele Paoloni <gabriele.paoloni@intel.com>
- * Tadeusz Struk (tadeusz.struk@intel.com)
- * Wajdi Feghali (wajdi.k.feghali@intel.com)
- * Copyright (c) 2010, Intel Corporation.
+ * Copyright (c) 2010, Intel Corporation.
*
* Ported x86_64 version to x86:
* Author: Mathias Krause <minipli@googlemail.com>
@@ -27,103 +18,6 @@
#include <linux/linkage.h>
#include <asm/frame.h>
-#include <asm/nospec-branch.h>
-
-/*
- * The following macros are used to move an (un)aligned 16 byte value to/from
- * an XMM register. This can done for either FP or integer values, for FP use
- * movaps (move aligned packed single) or integer use movdqa (move double quad
- * aligned). It doesn't make a performance difference which instruction is used
- * since Nehalem (original Core i7) was released. However, the movaps is a byte
- * shorter, so that is the one we'll use for now. (same for unaligned).
- */
-#define MOVADQ movaps
-#define MOVUDQ movups
-
-#ifdef __x86_64__
-
-# constants in mergeable sections, linker can reorder and merge
-.section .rodata.cst16.POLY, "aM", @progbits, 16
-.align 16
-POLY: .octa 0xC2000000000000000000000000000001
-.section .rodata.cst16.TWOONE, "aM", @progbits, 16
-.align 16
-TWOONE: .octa 0x00000001000000000000000000000001
-
-.section .rodata.cst16.SHUF_MASK, "aM", @progbits, 16
-.align 16
-SHUF_MASK: .octa 0x000102030405060708090A0B0C0D0E0F
-.section .rodata.cst16.MASK1, "aM", @progbits, 16
-.align 16
-MASK1: .octa 0x0000000000000000ffffffffffffffff
-.section .rodata.cst16.MASK2, "aM", @progbits, 16
-.align 16
-MASK2: .octa 0xffffffffffffffff0000000000000000
-.section .rodata.cst16.ONE, "aM", @progbits, 16
-.align 16
-ONE: .octa 0x00000000000000000000000000000001
-.section .rodata.cst16.F_MIN_MASK, "aM", @progbits, 16
-.align 16
-F_MIN_MASK: .octa 0xf1f2f3f4f5f6f7f8f9fafbfcfdfeff0
-.section .rodata.cst16.dec, "aM", @progbits, 16
-.align 16
-dec: .octa 0x1
-.section .rodata.cst16.enc, "aM", @progbits, 16
-.align 16
-enc: .octa 0x2
-
-# order of these constants should not change.
-# more specifically, ALL_F should follow SHIFT_MASK,
-# and zero should follow ALL_F
-.section .rodata, "a", @progbits
-.align 16
-SHIFT_MASK: .octa 0x0f0e0d0c0b0a09080706050403020100
-ALL_F: .octa 0xffffffffffffffffffffffffffffffff
- .octa 0x00000000000000000000000000000000
-
-.text
-
-
-#define STACK_OFFSET 8*3
-
-#define AadHash 16*0
-#define AadLen 16*1
-#define InLen (16*1)+8
-#define PBlockEncKey 16*2
-#define OrigIV 16*3
-#define CurCount 16*4
-#define PBlockLen 16*5
-#define HashKey 16*6 // store HashKey <<1 mod poly here
-#define HashKey_2 16*7 // store HashKey^2 <<1 mod poly here
-#define HashKey_3 16*8 // store HashKey^3 <<1 mod poly here
-#define HashKey_4 16*9 // store HashKey^4 <<1 mod poly here
-#define HashKey_k 16*10 // store XOR of High 64 bits and Low 64
- // bits of HashKey <<1 mod poly here
- //(for Karatsuba purposes)
-#define HashKey_2_k 16*11 // store XOR of High 64 bits and Low 64
- // bits of HashKey^2 <<1 mod poly here
- // (for Karatsuba purposes)
-#define HashKey_3_k 16*12 // store XOR of High 64 bits and Low 64
- // bits of HashKey^3 <<1 mod poly here
- // (for Karatsuba purposes)
-#define HashKey_4_k 16*13 // store XOR of High 64 bits and Low 64
- // bits of HashKey^4 <<1 mod poly here
- // (for Karatsuba purposes)
-
-#define arg1 rdi
-#define arg2 rsi
-#define arg3 rdx
-#define arg4 rcx
-#define arg5 r8
-#define arg6 r9
-#define arg7 STACK_OFFSET+8(%rsp)
-#define arg8 STACK_OFFSET+16(%rsp)
-#define arg9 STACK_OFFSET+24(%rsp)
-#define arg10 STACK_OFFSET+32(%rsp)
-#define arg11 STACK_OFFSET+40(%rsp)
-#define keysize 2*15*16(%arg1)
-#endif
-
#define STATE1 %xmm0
#define STATE2 %xmm4
@@ -170,1587 +64,6 @@ ALL_F: .octa 0xffffffffffffffffffffffffffffffff
#define TKEYP T1
#endif
-.macro FUNC_SAVE
- push %r12
- push %r13
- push %r14
-#
-# states of %xmm registers %xmm6:%xmm15 not saved
-# all %xmm registers are clobbered
-#
-.endm
-
-
-.macro FUNC_RESTORE
- pop %r14
- pop %r13
- pop %r12
-.endm
-
-# Precompute hashkeys.
-# Input: Hash subkey.
-# Output: HashKeys stored in gcm_context_data. Only needs to be called
-# once per key.
-# clobbers r12, and tmp xmm registers.
-.macro PRECOMPUTE SUBKEY TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 TMP7
- mov \SUBKEY, %r12
- movdqu (%r12), \TMP3
- movdqa SHUF_MASK(%rip), \TMP2
- pshufb \TMP2, \TMP3
-
- # precompute HashKey<<1 mod poly from the HashKey (required for GHASH)
-
- movdqa \TMP3, \TMP2
- psllq $1, \TMP3
- psrlq $63, \TMP2
- movdqa \TMP2, \TMP1
- pslldq $8, \TMP2
- psrldq $8, \TMP1
- por \TMP2, \TMP3
-
- # reduce HashKey<<1
-
- pshufd $0x24, \TMP1, \TMP2
- pcmpeqd TWOONE(%rip), \TMP2
- pand POLY(%rip), \TMP2
- pxor \TMP2, \TMP3
- movdqu \TMP3, HashKey(%arg2)
-
- movdqa \TMP3, \TMP5
- pshufd $78, \TMP3, \TMP1
- pxor \TMP3, \TMP1
- movdqu \TMP1, HashKey_k(%arg2)
-
- GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
-# TMP5 = HashKey^2<<1 (mod poly)
- movdqu \TMP5, HashKey_2(%arg2)
-# HashKey_2 = HashKey^2<<1 (mod poly)
- pshufd $78, \TMP5, \TMP1
- pxor \TMP5, \TMP1
- movdqu \TMP1, HashKey_2_k(%arg2)
-
- GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
-# TMP5 = HashKey^3<<1 (mod poly)
- movdqu \TMP5, HashKey_3(%arg2)
- pshufd $78, \TMP5, \TMP1
- pxor \TMP5, \TMP1
- movdqu \TMP1, HashKey_3_k(%arg2)
-
- GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
-# TMP5 = HashKey^3<<1 (mod poly)
- movdqu \TMP5, HashKey_4(%arg2)
- pshufd $78, \TMP5, \TMP1
- pxor \TMP5, \TMP1
- movdqu \TMP1, HashKey_4_k(%arg2)
-.endm
-
-# GCM_INIT initializes a gcm_context struct to prepare for encoding/decoding.
-# Clobbers rax, r10-r13 and xmm0-xmm6, %xmm13
-.macro GCM_INIT Iv SUBKEY AAD AADLEN
- mov \AADLEN, %r11
- mov %r11, AadLen(%arg2) # ctx_data.aad_length = aad_length
- xor %r11d, %r11d
- mov %r11, InLen(%arg2) # ctx_data.in_length = 0
- mov %r11, PBlockLen(%arg2) # ctx_data.partial_block_length = 0
- mov %r11, PBlockEncKey(%arg2) # ctx_data.partial_block_enc_key = 0
- mov \Iv, %rax
- movdqu (%rax), %xmm0
- movdqu %xmm0, OrigIV(%arg2) # ctx_data.orig_IV = iv
-
- movdqa SHUF_MASK(%rip), %xmm2
- pshufb %xmm2, %xmm0
- movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv
-
- PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7
- movdqu HashKey(%arg2), %xmm13
-
- CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \
- %xmm4, %xmm5, %xmm6
-.endm
-
-# GCM_ENC_DEC Encodes/Decodes given data. Assumes that the passed gcm_context
-# struct has been initialized by GCM_INIT.
-# Requires the input data be at least 1 byte long because of READ_PARTIAL_BLOCK
-# Clobbers rax, r10-r13, and xmm0-xmm15
-.macro GCM_ENC_DEC operation
- movdqu AadHash(%arg2), %xmm8
- movdqu HashKey(%arg2), %xmm13
- add %arg5, InLen(%arg2)
-
- xor %r11d, %r11d # initialise the data pointer offset as zero
- PARTIAL_BLOCK %arg3 %arg4 %arg5 %r11 %xmm8 \operation
-
- sub %r11, %arg5 # sub partial block data used
- mov %arg5, %r13 # save the number of bytes
-
- and $-16, %r13 # %r13 = %r13 - (%r13 mod 16)
- mov %r13, %r12
- # Encrypt/Decrypt first few blocks
-
- and $(3<<4), %r12
- jz .L_initial_num_blocks_is_0_\@
- cmp $(2<<4), %r12
- jb .L_initial_num_blocks_is_1_\@
- je .L_initial_num_blocks_is_2_\@
-.L_initial_num_blocks_is_3_\@:
- INITIAL_BLOCKS_ENC_DEC %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
-%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, \operation
- sub $48, %r13
- jmp .L_initial_blocks_\@
-.L_initial_num_blocks_is_2_\@:
- INITIAL_BLOCKS_ENC_DEC %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
-%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, \operation
- sub $32, %r13
- jmp .L_initial_blocks_\@
-.L_initial_num_blocks_is_1_\@:
- INITIAL_BLOCKS_ENC_DEC %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
-%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, \operation
- sub $16, %r13
- jmp .L_initial_blocks_\@
-.L_initial_num_blocks_is_0_\@:
- INITIAL_BLOCKS_ENC_DEC %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
-%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, \operation
-.L_initial_blocks_\@:
-
- # Main loop - Encrypt/Decrypt remaining blocks
-
- test %r13, %r13
- je .L_zero_cipher_left_\@
- sub $64, %r13
- je .L_four_cipher_left_\@
-.L_crypt_by_4_\@:
- GHASH_4_ENCRYPT_4_PARALLEL_\operation %xmm9, %xmm10, %xmm11, %xmm12, \
- %xmm13, %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, \
- %xmm7, %xmm8, enc
- add $64, %r11
- sub $64, %r13
- jne .L_crypt_by_4_\@
-.L_four_cipher_left_\@:
- GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \
-%xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8
-.L_zero_cipher_left_\@:
- movdqu %xmm8, AadHash(%arg2)
- movdqu %xmm0, CurCount(%arg2)
-
- mov %arg5, %r13
- and $15, %r13 # %r13 = arg5 (mod 16)
- je .L_multiple_of_16_bytes_\@
-
- mov %r13, PBlockLen(%arg2)
-
- # Handle the last <16 Byte block separately
- paddd ONE(%rip), %xmm0 # INCR CNT to get Yn
- movdqu %xmm0, CurCount(%arg2)
- movdqa SHUF_MASK(%rip), %xmm10
- pshufb %xmm10, %xmm0
-
- ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn)
- movdqu %xmm0, PBlockEncKey(%arg2)
-
- cmp $16, %arg5
- jge .L_large_enough_update_\@
-
- lea (%arg4,%r11,1), %r10
- mov %r13, %r12
- READ_PARTIAL_BLOCK %r10 %r12 %xmm2 %xmm1
- jmp .L_data_read_\@
-
-.L_large_enough_update_\@:
- sub $16, %r11
- add %r13, %r11
-
- # receive the last <16 Byte block
- movdqu (%arg4, %r11, 1), %xmm1
-
- sub %r13, %r11
- add $16, %r11
-
- lea SHIFT_MASK+16(%rip), %r12
- # adjust the shuffle mask pointer to be able to shift 16-r13 bytes
- # (r13 is the number of bytes in plaintext mod 16)
- sub %r13, %r12
- # get the appropriate shuffle mask
- movdqu (%r12), %xmm2
- # shift right 16-r13 bytes
- pshufb %xmm2, %xmm1
-
-.L_data_read_\@:
- lea ALL_F+16(%rip), %r12
- sub %r13, %r12
-
-.ifc \operation, dec
- movdqa %xmm1, %xmm2
-.endif
- pxor %xmm1, %xmm0 # XOR Encrypt(K, Yn)
- movdqu (%r12), %xmm1
- # get the appropriate mask to mask out top 16-r13 bytes of xmm0
- pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0
-.ifc \operation, dec
- pand %xmm1, %xmm2
- movdqa SHUF_MASK(%rip), %xmm10
- pshufb %xmm10 ,%xmm2
-
- pxor %xmm2, %xmm8
-.else
- movdqa SHUF_MASK(%rip), %xmm10
- pshufb %xmm10,%xmm0
-
- pxor %xmm0, %xmm8
-.endif
-
- movdqu %xmm8, AadHash(%arg2)
-.ifc \operation, enc
- # GHASH computation for the last <16 byte block
- movdqa SHUF_MASK(%rip), %xmm10
- # shuffle xmm0 back to output as ciphertext
- pshufb %xmm10, %xmm0
-.endif
-
- # Output %r13 bytes
- movq %xmm0, %rax
- cmp $8, %r13
- jle .L_less_than_8_bytes_left_\@
- mov %rax, (%arg3 , %r11, 1)
- add $8, %r11
- psrldq $8, %xmm0
- movq %xmm0, %rax
- sub $8, %r13
-.L_less_than_8_bytes_left_\@:
- mov %al, (%arg3, %r11, 1)
- add $1, %r11
- shr $8, %rax
- sub $1, %r13
- jne .L_less_than_8_bytes_left_\@
-.L_multiple_of_16_bytes_\@:
-.endm
-
-# GCM_COMPLETE Finishes update of tag of last partial block
-# Output: Authorization Tag (AUTH_TAG)
-# Clobbers rax, r10-r12, and xmm0, xmm1, xmm5-xmm15
-.macro GCM_COMPLETE AUTHTAG AUTHTAGLEN
- movdqu AadHash(%arg2), %xmm8
- movdqu HashKey(%arg2), %xmm13
-
- mov PBlockLen(%arg2), %r12
-
- test %r12, %r12
- je .L_partial_done\@
-
- GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6
-
-.L_partial_done\@:
- mov AadLen(%arg2), %r12 # %r13 = aadLen (number of bytes)
- shl $3, %r12 # convert into number of bits
- movd %r12d, %xmm15 # len(A) in %xmm15
- mov InLen(%arg2), %r12
- shl $3, %r12 # len(C) in bits (*128)
- movq %r12, %xmm1
-
- pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
- pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C)
- pxor %xmm15, %xmm8
- GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6
- # final GHASH computation
- movdqa SHUF_MASK(%rip), %xmm10
- pshufb %xmm10, %xmm8
-
- movdqu OrigIV(%arg2), %xmm0 # %xmm0 = Y0
- ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Y0)
- pxor %xmm8, %xmm0
-.L_return_T_\@:
- mov \AUTHTAG, %r10 # %r10 = authTag
- mov \AUTHTAGLEN, %r11 # %r11 = auth_tag_len
- cmp $16, %r11
- je .L_T_16_\@
- cmp $8, %r11
- jl .L_T_4_\@
-.L_T_8_\@:
- movq %xmm0, %rax
- mov %rax, (%r10)
- add $8, %r10
- sub $8, %r11
- psrldq $8, %xmm0
- test %r11, %r11
- je .L_return_T_done_\@
-.L_T_4_\@:
- movd %xmm0, %eax
- mov %eax, (%r10)
- add $4, %r10
- sub $4, %r11
- psrldq $4, %xmm0
- test %r11, %r11
- je .L_return_T_done_\@
-.L_T_123_\@:
- movd %xmm0, %eax
- cmp $2, %r11
- jl .L_T_1_\@
- mov %ax, (%r10)
- cmp $2, %r11
- je .L_return_T_done_\@
- add $2, %r10
- sar $16, %eax
-.L_T_1_\@:
- mov %al, (%r10)
- jmp .L_return_T_done_\@
-.L_T_16_\@:
- movdqu %xmm0, (%r10)
-.L_return_T_done_\@:
-.endm
-
-#ifdef __x86_64__
-/* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0)
-*
-*
-* Input: A and B (128-bits each, bit-reflected)
-* Output: C = A*B*x mod poly, (i.e. >>1 )
-* To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input
-* GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly.
-*
-*/
-.macro GHASH_MUL GH HK TMP1 TMP2 TMP3 TMP4 TMP5
- movdqa \GH, \TMP1
- pshufd $78, \GH, \TMP2
- pshufd $78, \HK, \TMP3
- pxor \GH, \TMP2 # TMP2 = a1+a0
- pxor \HK, \TMP3 # TMP3 = b1+b0
- pclmulqdq $0x11, \HK, \TMP1 # TMP1 = a1*b1
- pclmulqdq $0x00, \HK, \GH # GH = a0*b0
- pclmulqdq $0x00, \TMP3, \TMP2 # TMP2 = (a0+a1)*(b1+b0)
- pxor \GH, \TMP2
- pxor \TMP1, \TMP2 # TMP2 = (a0*b0)+(a1*b0)
- movdqa \TMP2, \TMP3
- pslldq $8, \TMP3 # left shift TMP3 2 DWs
- psrldq $8, \TMP2 # right shift TMP2 2 DWs
- pxor \TMP3, \GH
- pxor \TMP2, \TMP1 # TMP2:GH holds the result of GH*HK
-
- # first phase of the reduction
-
- movdqa \GH, \TMP2
- movdqa \GH, \TMP3
- movdqa \GH, \TMP4 # copy GH into TMP2,TMP3 and TMP4
- # in in order to perform
- # independent shifts
- pslld $31, \TMP2 # packed right shift <<31
- pslld $30, \TMP3 # packed right shift <<30
- pslld $25, \TMP4 # packed right shift <<25
- pxor \TMP3, \TMP2 # xor the shifted versions
- pxor \TMP4, \TMP2
- movdqa \TMP2, \TMP5
- psrldq $4, \TMP5 # right shift TMP5 1 DW
- pslldq $12, \TMP2 # left shift TMP2 3 DWs
- pxor \TMP2, \GH
-
- # second phase of the reduction
-
- movdqa \GH,\TMP2 # copy GH into TMP2,TMP3 and TMP4
- # in in order to perform
- # independent shifts
- movdqa \GH,\TMP3
- movdqa \GH,\TMP4
- psrld $1,\TMP2 # packed left shift >>1
- psrld $2,\TMP3 # packed left shift >>2
- psrld $7,\TMP4 # packed left shift >>7
- pxor \TMP3,\TMP2 # xor the shifted versions
- pxor \TMP4,\TMP2
- pxor \TMP5, \TMP2
- pxor \TMP2, \GH
- pxor \TMP1, \GH # result is in TMP1
-.endm
-
-# Reads DLEN bytes starting at DPTR and stores in XMMDst
-# where 0 < DLEN < 16
-# Clobbers %rax, DLEN and XMM1
-.macro READ_PARTIAL_BLOCK DPTR DLEN XMM1 XMMDst
- cmp $8, \DLEN
- jl .L_read_lt8_\@
- mov (\DPTR), %rax
- movq %rax, \XMMDst
- sub $8, \DLEN
- jz .L_done_read_partial_block_\@
- xor %eax, %eax
-.L_read_next_byte_\@:
- shl $8, %rax
- mov 7(\DPTR, \DLEN, 1), %al
- dec \DLEN
- jnz .L_read_next_byte_\@
- movq %rax, \XMM1
- pslldq $8, \XMM1
- por \XMM1, \XMMDst
- jmp .L_done_read_partial_block_\@
-.L_read_lt8_\@:
- xor %eax, %eax
-.L_read_next_byte_lt8_\@:
- shl $8, %rax
- mov -1(\DPTR, \DLEN, 1), %al
- dec \DLEN
- jnz .L_read_next_byte_lt8_\@
- movq %rax, \XMMDst
-.L_done_read_partial_block_\@:
-.endm
-
-# CALC_AAD_HASH: Calculates the hash of the data which will not be encrypted.
-# clobbers r10-11, xmm14
-.macro CALC_AAD_HASH HASHKEY AAD AADLEN TMP1 TMP2 TMP3 TMP4 TMP5 \
- TMP6 TMP7
- MOVADQ SHUF_MASK(%rip), %xmm14
- mov \AAD, %r10 # %r10 = AAD
- mov \AADLEN, %r11 # %r11 = aadLen
- pxor \TMP7, \TMP7
- pxor \TMP6, \TMP6
-
- cmp $16, %r11
- jl .L_get_AAD_rest\@
-.L_get_AAD_blocks\@:
- movdqu (%r10), \TMP7
- pshufb %xmm14, \TMP7 # byte-reflect the AAD data
- pxor \TMP7, \TMP6
- GHASH_MUL \TMP6, \HASHKEY, \TMP1, \TMP2, \TMP3, \TMP4, \TMP5
- add $16, %r10
- sub $16, %r11
- cmp $16, %r11
- jge .L_get_AAD_blocks\@
-
- movdqu \TMP6, \TMP7
-
- /* read the last <16B of AAD */
-.L_get_AAD_rest\@:
- test %r11, %r11
- je .L_get_AAD_done\@
-
- READ_PARTIAL_BLOCK %r10, %r11, \TMP1, \TMP7
- pshufb %xmm14, \TMP7 # byte-reflect the AAD data
- pxor \TMP6, \TMP7
- GHASH_MUL \TMP7, \HASHKEY, \TMP1, \TMP2, \TMP3, \TMP4, \TMP5
- movdqu \TMP7, \TMP6
-
-.L_get_AAD_done\@:
- movdqu \TMP6, AadHash(%arg2)
-.endm
-
-# PARTIAL_BLOCK: Handles encryption/decryption and the tag partial blocks
-# between update calls.
-# Requires the input data be at least 1 byte long due to READ_PARTIAL_BLOCK
-# Outputs encrypted bytes, and updates hash and partial info in gcm_data_context
-# Clobbers rax, r10, r12, r13, xmm0-6, xmm9-13
-.macro PARTIAL_BLOCK CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \
- AAD_HASH operation
- mov PBlockLen(%arg2), %r13
- test %r13, %r13
- je .L_partial_block_done_\@ # Leave Macro if no partial blocks
- # Read in input data without over reading
- cmp $16, \PLAIN_CYPH_LEN
- jl .L_fewer_than_16_bytes_\@
- movups (\PLAIN_CYPH_IN), %xmm1 # If more than 16 bytes, just fill xmm
- jmp .L_data_read_\@
-
-.L_fewer_than_16_bytes_\@:
- lea (\PLAIN_CYPH_IN, \DATA_OFFSET, 1), %r10
- mov \PLAIN_CYPH_LEN, %r12
- READ_PARTIAL_BLOCK %r10 %r12 %xmm0 %xmm1
-
- mov PBlockLen(%arg2), %r13
-
-.L_data_read_\@: # Finished reading in data
-
- movdqu PBlockEncKey(%arg2), %xmm9
- movdqu HashKey(%arg2), %xmm13
-
- lea SHIFT_MASK(%rip), %r12
-
- # adjust the shuffle mask pointer to be able to shift r13 bytes
- # r16-r13 is the number of bytes in plaintext mod 16)
- add %r13, %r12
- movdqu (%r12), %xmm2 # get the appropriate shuffle mask
- pshufb %xmm2, %xmm9 # shift right r13 bytes
-
-.ifc \operation, dec
- movdqa %xmm1, %xmm3
- pxor %xmm1, %xmm9 # Ciphertext XOR E(K, Yn)
-
- mov \PLAIN_CYPH_LEN, %r10
- add %r13, %r10
- # Set r10 to be the amount of data left in CYPH_PLAIN_IN after filling
- sub $16, %r10
- # Determine if partial block is not being filled and
- # shift mask accordingly
- jge .L_no_extra_mask_1_\@
- sub %r10, %r12
-.L_no_extra_mask_1_\@:
-
- movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
- # get the appropriate mask to mask out bottom r13 bytes of xmm9
- pand %xmm1, %xmm9 # mask out bottom r13 bytes of xmm9
-
- pand %xmm1, %xmm3
- movdqa SHUF_MASK(%rip), %xmm10
- pshufb %xmm10, %xmm3
- pshufb %xmm2, %xmm3
- pxor %xmm3, \AAD_HASH
-
- test %r10, %r10
- jl .L_partial_incomplete_1_\@
-
- # GHASH computation for the last <16 Byte block
- GHASH_MUL \AAD_HASH, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
- xor %eax, %eax
-
- mov %rax, PBlockLen(%arg2)
- jmp .L_dec_done_\@
-.L_partial_incomplete_1_\@:
- add \PLAIN_CYPH_LEN, PBlockLen(%arg2)
-.L_dec_done_\@:
- movdqu \AAD_HASH, AadHash(%arg2)
-.else
- pxor %xmm1, %xmm9 # Plaintext XOR E(K, Yn)
-
- mov \PLAIN_CYPH_LEN, %r10
- add %r13, %r10
- # Set r10 to be the amount of data left in CYPH_PLAIN_IN after filling
- sub $16, %r10
- # Determine if partial block is not being filled and
- # shift mask accordingly
- jge .L_no_extra_mask_2_\@
- sub %r10, %r12
-.L_no_extra_mask_2_\@:
-
- movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
- # get the appropriate mask to mask out bottom r13 bytes of xmm9
- pand %xmm1, %xmm9
-
- movdqa SHUF_MASK(%rip), %xmm1
- pshufb %xmm1, %xmm9
- pshufb %xmm2, %xmm9
- pxor %xmm9, \AAD_HASH
-
- test %r10, %r10
- jl .L_partial_incomplete_2_\@
-
- # GHASH computation for the last <16 Byte block
- GHASH_MUL \AAD_HASH, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
- xor %eax, %eax
-
- mov %rax, PBlockLen(%arg2)
- jmp .L_encode_done_\@
-.L_partial_incomplete_2_\@:
- add \PLAIN_CYPH_LEN, PBlockLen(%arg2)
-.L_encode_done_\@:
- movdqu \AAD_HASH, AadHash(%arg2)
-
- movdqa SHUF_MASK(%rip), %xmm10
- # shuffle xmm9 back to output as ciphertext
- pshufb %xmm10, %xmm9
- pshufb %xmm2, %xmm9
-.endif
- # output encrypted Bytes
- test %r10, %r10
- jl .L_partial_fill_\@
- mov %r13, %r12
- mov $16, %r13
- # Set r13 to be the number of bytes to write out
- sub %r12, %r13
- jmp .L_count_set_\@
-.L_partial_fill_\@:
- mov \PLAIN_CYPH_LEN, %r13
-.L_count_set_\@:
- movdqa %xmm9, %xmm0
- movq %xmm0, %rax
- cmp $8, %r13
- jle .L_less_than_8_bytes_left_\@
-
- mov %rax, (\CYPH_PLAIN_OUT, \DATA_OFFSET, 1)
- add $8, \DATA_OFFSET
- psrldq $8, %xmm0
- movq %xmm0, %rax
- sub $8, %r13
-.L_less_than_8_bytes_left_\@:
- movb %al, (\CYPH_PLAIN_OUT, \DATA_OFFSET, 1)
- add $1, \DATA_OFFSET
- shr $8, %rax
- sub $1, %r13
- jne .L_less_than_8_bytes_left_\@
-.L_partial_block_done_\@:
-.endm # PARTIAL_BLOCK
-
-/*
-* if a = number of total plaintext bytes
-* b = floor(a/16)
-* num_initial_blocks = b mod 4
-* encrypt the initial num_initial_blocks blocks and apply ghash on
-* the ciphertext
-* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
-* are clobbered
-* arg1, %arg2, %arg3 are used as a pointer only, not modified
-*/
-
-
-.macro INITIAL_BLOCKS_ENC_DEC TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \
- XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
- MOVADQ SHUF_MASK(%rip), %xmm14
-
- movdqu AadHash(%arg2), %xmm\i # XMM0 = Y0
-
- # start AES for num_initial_blocks blocks
-
- movdqu CurCount(%arg2), \XMM0 # XMM0 = Y0
-
-.if (\i == 5) || (\i == 6) || (\i == 7)
-
- MOVADQ ONE(%RIP),\TMP1
- MOVADQ 0(%arg1),\TMP2
-.irpc index, \i_seq
- paddd \TMP1, \XMM0 # INCR Y0
-.ifc \operation, dec
- movdqa \XMM0, %xmm\index
-.else
- MOVADQ \XMM0, %xmm\index
-.endif
- pshufb %xmm14, %xmm\index # perform a 16 byte swap
- pxor \TMP2, %xmm\index
-.endr
- lea 0x10(%arg1),%r10
- mov keysize,%eax
- shr $2,%eax # 128->4, 192->6, 256->8
- add $5,%eax # 128->9, 192->11, 256->13
-
-.Laes_loop_initial_\@:
- MOVADQ (%r10),\TMP1
-.irpc index, \i_seq
- aesenc \TMP1, %xmm\index
-.endr
- add $16,%r10
- sub $1,%eax
- jnz .Laes_loop_initial_\@
-
- MOVADQ (%r10), \TMP1
-.irpc index, \i_seq
- aesenclast \TMP1, %xmm\index # Last Round
-.endr
-.irpc index, \i_seq
- movdqu (%arg4 , %r11, 1), \TMP1
- pxor \TMP1, %xmm\index
- movdqu %xmm\index, (%arg3 , %r11, 1)
- # write back plaintext/ciphertext for num_initial_blocks
- add $16, %r11
-
-.ifc \operation, dec
- movdqa \TMP1, %xmm\index
-.endif
- pshufb %xmm14, %xmm\index
-
- # prepare plaintext/ciphertext for GHASH computation
-.endr
-.endif
-
- # apply GHASH on num_initial_blocks blocks
-
-.if \i == 5
- pxor %xmm5, %xmm6
- GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
- pxor %xmm6, %xmm7
- GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
- pxor %xmm7, %xmm8
- GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
-.elseif \i == 6
- pxor %xmm6, %xmm7
- GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
- pxor %xmm7, %xmm8
- GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
-.elseif \i == 7
- pxor %xmm7, %xmm8
- GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
-.endif
- cmp $64, %r13
- jl .L_initial_blocks_done\@
- # no need for precomputed values
-/*
-*
-* Precomputations for HashKey parallel with encryption of first 4 blocks.
-* Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
-*/
- MOVADQ ONE(%RIP),\TMP1
- paddd \TMP1, \XMM0 # INCR Y0
- MOVADQ \XMM0, \XMM1
- pshufb %xmm14, \XMM1 # perform a 16 byte swap
-
- paddd \TMP1, \XMM0 # INCR Y0
- MOVADQ \XMM0, \XMM2
- pshufb %xmm14, \XMM2 # perform a 16 byte swap
-
- paddd \TMP1, \XMM0 # INCR Y0
- MOVADQ \XMM0, \XMM3
- pshufb %xmm14, \XMM3 # perform a 16 byte swap
-
- paddd \TMP1, \XMM0 # INCR Y0
- MOVADQ \XMM0, \XMM4
- pshufb %xmm14, \XMM4 # perform a 16 byte swap
-
- MOVADQ 0(%arg1),\TMP1
- pxor \TMP1, \XMM1
- pxor \TMP1, \XMM2
- pxor \TMP1, \XMM3
- pxor \TMP1, \XMM4
-.irpc index, 1234 # do 4 rounds
- movaps 0x10*\index(%arg1), \TMP1
- aesenc \TMP1, \XMM1
- aesenc \TMP1, \XMM2
- aesenc \TMP1, \XMM3
- aesenc \TMP1, \XMM4
-.endr
-.irpc index, 56789 # do next 5 rounds
- movaps 0x10*\index(%arg1), \TMP1
- aesenc \TMP1, \XMM1
- aesenc \TMP1, \XMM2
- aesenc \TMP1, \XMM3
- aesenc \TMP1, \XMM4
-.endr
- lea 0xa0(%arg1),%r10
- mov keysize,%eax
- shr $2,%eax # 128->4, 192->6, 256->8
- sub $4,%eax # 128->0, 192->2, 256->4
- jz .Laes_loop_pre_done\@
-
-.Laes_loop_pre_\@:
- MOVADQ (%r10),\TMP2
-.irpc index, 1234
- aesenc \TMP2, %xmm\index
-.endr
- add $16,%r10
- sub $1,%eax
- jnz .Laes_loop_pre_\@
-
-.Laes_loop_pre_done\@:
- MOVADQ (%r10), \TMP2
- aesenclast \TMP2, \XMM1
- aesenclast \TMP2, \XMM2
- aesenclast \TMP2, \XMM3
- aesenclast \TMP2, \XMM4
- movdqu 16*0(%arg4 , %r11 , 1), \TMP1
- pxor \TMP1, \XMM1
-.ifc \operation, dec
- movdqu \XMM1, 16*0(%arg3 , %r11 , 1)
- movdqa \TMP1, \XMM1
-.endif
- movdqu 16*1(%arg4 , %r11 , 1), \TMP1
- pxor \TMP1, \XMM2
-.ifc \operation, dec
- movdqu \XMM2, 16*1(%arg3 , %r11 , 1)
- movdqa \TMP1, \XMM2
-.endif
- movdqu 16*2(%arg4 , %r11 , 1), \TMP1
- pxor \TMP1, \XMM3
-.ifc \operation, dec
- movdqu \XMM3, 16*2(%arg3 , %r11 , 1)
- movdqa \TMP1, \XMM3
-.endif
- movdqu 16*3(%arg4 , %r11 , 1), \TMP1
- pxor \TMP1, \XMM4
-.ifc \operation, dec
- movdqu \XMM4, 16*3(%arg3 , %r11 , 1)
- movdqa \TMP1, \XMM4
-.else
- movdqu \XMM1, 16*0(%arg3 , %r11 , 1)
- movdqu \XMM2, 16*1(%arg3 , %r11 , 1)
- movdqu \XMM3, 16*2(%arg3 , %r11 , 1)
- movdqu \XMM4, 16*3(%arg3 , %r11 , 1)
-.endif
-
- add $64, %r11
- pshufb %xmm14, \XMM1 # perform a 16 byte swap
- pxor \XMMDst, \XMM1
-# combine GHASHed value with the corresponding ciphertext
- pshufb %xmm14, \XMM2 # perform a 16 byte swap
- pshufb %xmm14, \XMM3 # perform a 16 byte swap
- pshufb %xmm14, \XMM4 # perform a 16 byte swap
-
-.L_initial_blocks_done\@:
-
-.endm
-
-/*
-* encrypt 4 blocks at a time
-* ghash the 4 previously encrypted ciphertext blocks
-* arg1, %arg3, %arg4 are used as pointers only, not modified
-* %r11 is the data offset value
-*/
-.macro GHASH_4_ENCRYPT_4_PARALLEL_enc TMP1 TMP2 TMP3 TMP4 TMP5 \
-TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
-
- movdqa \XMM1, \XMM5
- movdqa \XMM2, \XMM6
- movdqa \XMM3, \XMM7
- movdqa \XMM4, \XMM8
-
- movdqa SHUF_MASK(%rip), %xmm15
- # multiply TMP5 * HashKey using karatsuba
-
- movdqa \XMM5, \TMP4
- pshufd $78, \XMM5, \TMP6
- pxor \XMM5, \TMP6
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqu HashKey_4(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP4 # TMP4 = a1*b1
- movdqa \XMM0, \XMM1
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqa \XMM0, \XMM2
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqa \XMM0, \XMM3
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqa \XMM0, \XMM4
- pshufb %xmm15, \XMM1 # perform a 16 byte swap
- pclmulqdq $0x00, \TMP5, \XMM5 # XMM5 = a0*b0
- pshufb %xmm15, \XMM2 # perform a 16 byte swap
- pshufb %xmm15, \XMM3 # perform a 16 byte swap
- pshufb %xmm15, \XMM4 # perform a 16 byte swap
-
- pxor (%arg1), \XMM1
- pxor (%arg1), \XMM2
- pxor (%arg1), \XMM3
- pxor (%arg1), \XMM4
- movdqu HashKey_4_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
- movaps 0x10(%arg1), \TMP1
- aesenc \TMP1, \XMM1 # Round 1
- aesenc \TMP1, \XMM2
- aesenc \TMP1, \XMM3
- aesenc \TMP1, \XMM4
- movaps 0x20(%arg1), \TMP1
- aesenc \TMP1, \XMM1 # Round 2
- aesenc \TMP1, \XMM2
- aesenc \TMP1, \XMM3
- aesenc \TMP1, \XMM4
- movdqa \XMM6, \TMP1
- pshufd $78, \XMM6, \TMP2
- pxor \XMM6, \TMP2
- movdqu HashKey_3(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
- movaps 0x30(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 3
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pclmulqdq $0x00, \TMP5, \XMM6 # XMM6 = a0*b0
- movaps 0x40(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 4
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- movdqu HashKey_3_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movaps 0x50(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 5
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pxor \TMP1, \TMP4
-# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
- pxor \XMM6, \XMM5
- pxor \TMP2, \TMP6
- movdqa \XMM7, \TMP1
- pshufd $78, \XMM7, \TMP2
- pxor \XMM7, \TMP2
- movdqu HashKey_2(%arg2), \TMP5
-
- # Multiply TMP5 * HashKey using karatsuba
-
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- movaps 0x60(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 6
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pclmulqdq $0x00, \TMP5, \XMM7 # XMM7 = a0*b0
- movaps 0x70(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 7
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- movdqu HashKey_2_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movaps 0x80(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 8
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pxor \TMP1, \TMP4
-# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
- pxor \XMM7, \XMM5
- pxor \TMP2, \TMP6
-
- # Multiply XMM8 * HashKey
- # XMM8 and TMP5 hold the values for the two operands
-
- movdqa \XMM8, \TMP1
- pshufd $78, \XMM8, \TMP2
- pxor \XMM8, \TMP2
- movdqu HashKey(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- movaps 0x90(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 9
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pclmulqdq $0x00, \TMP5, \XMM8 # XMM8 = a0*b0
- lea 0xa0(%arg1),%r10
- mov keysize,%eax
- shr $2,%eax # 128->4, 192->6, 256->8
- sub $4,%eax # 128->0, 192->2, 256->4
- jz .Laes_loop_par_enc_done\@
-
-.Laes_loop_par_enc\@:
- MOVADQ (%r10),\TMP3
-.irpc index, 1234
- aesenc \TMP3, %xmm\index
-.endr
- add $16,%r10
- sub $1,%eax
- jnz .Laes_loop_par_enc\@
-
-.Laes_loop_par_enc_done\@:
- MOVADQ (%r10), \TMP3
- aesenclast \TMP3, \XMM1 # Round 10
- aesenclast \TMP3, \XMM2
- aesenclast \TMP3, \XMM3
- aesenclast \TMP3, \XMM4
- movdqu HashKey_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movdqu (%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
- movdqu 16(%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK
- movdqu 32(%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK
- movdqu 48(%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK
- movdqu \XMM1, (%arg3,%r11,1) # Write to the ciphertext buffer
- movdqu \XMM2, 16(%arg3,%r11,1) # Write to the ciphertext buffer
- movdqu \XMM3, 32(%arg3,%r11,1) # Write to the ciphertext buffer
- movdqu \XMM4, 48(%arg3,%r11,1) # Write to the ciphertext buffer
- pshufb %xmm15, \XMM1 # perform a 16 byte swap
- pshufb %xmm15, \XMM2 # perform a 16 byte swap
- pshufb %xmm15, \XMM3 # perform a 16 byte swap
- pshufb %xmm15, \XMM4 # perform a 16 byte swap
-
- pxor \TMP4, \TMP1
- pxor \XMM8, \XMM5
- pxor \TMP6, \TMP2
- pxor \TMP1, \TMP2
- pxor \XMM5, \TMP2
- movdqa \TMP2, \TMP3
- pslldq $8, \TMP3 # left shift TMP3 2 DWs
- psrldq $8, \TMP2 # right shift TMP2 2 DWs
- pxor \TMP3, \XMM5
- pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5
-
- # first phase of reduction
-
- movdqa \XMM5, \TMP2
- movdqa \XMM5, \TMP3
- movdqa \XMM5, \TMP4
-# move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently
- pslld $31, \TMP2 # packed right shift << 31
- pslld $30, \TMP3 # packed right shift << 30
- pslld $25, \TMP4 # packed right shift << 25
- pxor \TMP3, \TMP2 # xor the shifted versions
- pxor \TMP4, \TMP2
- movdqa \TMP2, \TMP5
- psrldq $4, \TMP5 # right shift T5 1 DW
- pslldq $12, \TMP2 # left shift T2 3 DWs
- pxor \TMP2, \XMM5
-
- # second phase of reduction
-
- movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4
- movdqa \XMM5,\TMP3
- movdqa \XMM5,\TMP4
- psrld $1, \TMP2 # packed left shift >>1
- psrld $2, \TMP3 # packed left shift >>2
- psrld $7, \TMP4 # packed left shift >>7
- pxor \TMP3,\TMP2 # xor the shifted versions
- pxor \TMP4,\TMP2
- pxor \TMP5, \TMP2
- pxor \TMP2, \XMM5
- pxor \TMP1, \XMM5 # result is in TMP1
-
- pxor \XMM5, \XMM1
-.endm
-
-/*
-* decrypt 4 blocks at a time
-* ghash the 4 previously decrypted ciphertext blocks
-* arg1, %arg3, %arg4 are used as pointers only, not modified
-* %r11 is the data offset value
-*/
-.macro GHASH_4_ENCRYPT_4_PARALLEL_dec TMP1 TMP2 TMP3 TMP4 TMP5 \
-TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
-
- movdqa \XMM1, \XMM5
- movdqa \XMM2, \XMM6
- movdqa \XMM3, \XMM7
- movdqa \XMM4, \XMM8
-
- movdqa SHUF_MASK(%rip), %xmm15
- # multiply TMP5 * HashKey using karatsuba
-
- movdqa \XMM5, \TMP4
- pshufd $78, \XMM5, \TMP6
- pxor \XMM5, \TMP6
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqu HashKey_4(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP4 # TMP4 = a1*b1
- movdqa \XMM0, \XMM1
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqa \XMM0, \XMM2
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqa \XMM0, \XMM3
- paddd ONE(%rip), \XMM0 # INCR CNT
- movdqa \XMM0, \XMM4
- pshufb %xmm15, \XMM1 # perform a 16 byte swap
- pclmulqdq $0x00, \TMP5, \XMM5 # XMM5 = a0*b0
- pshufb %xmm15, \XMM2 # perform a 16 byte swap
- pshufb %xmm15, \XMM3 # perform a 16 byte swap
- pshufb %xmm15, \XMM4 # perform a 16 byte swap
-
- pxor (%arg1), \XMM1
- pxor (%arg1), \XMM2
- pxor (%arg1), \XMM3
- pxor (%arg1), \XMM4
- movdqu HashKey_4_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
- movaps 0x10(%arg1), \TMP1
- aesenc \TMP1, \XMM1 # Round 1
- aesenc \TMP1, \XMM2
- aesenc \TMP1, \XMM3
- aesenc \TMP1, \XMM4
- movaps 0x20(%arg1), \TMP1
- aesenc \TMP1, \XMM1 # Round 2
- aesenc \TMP1, \XMM2
- aesenc \TMP1, \XMM3
- aesenc \TMP1, \XMM4
- movdqa \XMM6, \TMP1
- pshufd $78, \XMM6, \TMP2
- pxor \XMM6, \TMP2
- movdqu HashKey_3(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
- movaps 0x30(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 3
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pclmulqdq $0x00, \TMP5, \XMM6 # XMM6 = a0*b0
- movaps 0x40(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 4
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- movdqu HashKey_3_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movaps 0x50(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 5
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pxor \TMP1, \TMP4
-# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
- pxor \XMM6, \XMM5
- pxor \TMP2, \TMP6
- movdqa \XMM7, \TMP1
- pshufd $78, \XMM7, \TMP2
- pxor \XMM7, \TMP2
- movdqu HashKey_2(%arg2), \TMP5
-
- # Multiply TMP5 * HashKey using karatsuba
-
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- movaps 0x60(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 6
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pclmulqdq $0x00, \TMP5, \XMM7 # XMM7 = a0*b0
- movaps 0x70(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 7
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- movdqu HashKey_2_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movaps 0x80(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 8
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pxor \TMP1, \TMP4
-# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
- pxor \XMM7, \XMM5
- pxor \TMP2, \TMP6
-
- # Multiply XMM8 * HashKey
- # XMM8 and TMP5 hold the values for the two operands
-
- movdqa \XMM8, \TMP1
- pshufd $78, \XMM8, \TMP2
- pxor \XMM8, \TMP2
- movdqu HashKey(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- movaps 0x90(%arg1), \TMP3
- aesenc \TMP3, \XMM1 # Round 9
- aesenc \TMP3, \XMM2
- aesenc \TMP3, \XMM3
- aesenc \TMP3, \XMM4
- pclmulqdq $0x00, \TMP5, \XMM8 # XMM8 = a0*b0
- lea 0xa0(%arg1),%r10
- mov keysize,%eax
- shr $2,%eax # 128->4, 192->6, 256->8
- sub $4,%eax # 128->0, 192->2, 256->4
- jz .Laes_loop_par_dec_done\@
-
-.Laes_loop_par_dec\@:
- MOVADQ (%r10),\TMP3
-.irpc index, 1234
- aesenc \TMP3, %xmm\index
-.endr
- add $16,%r10
- sub $1,%eax
- jnz .Laes_loop_par_dec\@
-
-.Laes_loop_par_dec_done\@:
- MOVADQ (%r10), \TMP3
- aesenclast \TMP3, \XMM1 # last round
- aesenclast \TMP3, \XMM2
- aesenclast \TMP3, \XMM3
- aesenclast \TMP3, \XMM4
- movdqu HashKey_k(%arg2), \TMP5
- pclmulqdq $0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movdqu (%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
- movdqu \XMM1, (%arg3,%r11,1) # Write to plaintext buffer
- movdqa \TMP3, \XMM1
- movdqu 16(%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK
- movdqu \XMM2, 16(%arg3,%r11,1) # Write to plaintext buffer
- movdqa \TMP3, \XMM2
- movdqu 32(%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK
- movdqu \XMM3, 32(%arg3,%r11,1) # Write to plaintext buffer
- movdqa \TMP3, \XMM3
- movdqu 48(%arg4,%r11,1), \TMP3
- pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK
- movdqu \XMM4, 48(%arg3,%r11,1) # Write to plaintext buffer
- movdqa \TMP3, \XMM4
- pshufb %xmm15, \XMM1 # perform a 16 byte swap
- pshufb %xmm15, \XMM2 # perform a 16 byte swap
- pshufb %xmm15, \XMM3 # perform a 16 byte swap
- pshufb %xmm15, \XMM4 # perform a 16 byte swap
-
- pxor \TMP4, \TMP1
- pxor \XMM8, \XMM5
- pxor \TMP6, \TMP2
- pxor \TMP1, \TMP2
- pxor \XMM5, \TMP2
- movdqa \TMP2, \TMP3
- pslldq $8, \TMP3 # left shift TMP3 2 DWs
- psrldq $8, \TMP2 # right shift TMP2 2 DWs
- pxor \TMP3, \XMM5
- pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5
-
- # first phase of reduction
-
- movdqa \XMM5, \TMP2
- movdqa \XMM5, \TMP3
- movdqa \XMM5, \TMP4
-# move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently
- pslld $31, \TMP2 # packed right shift << 31
- pslld $30, \TMP3 # packed right shift << 30
- pslld $25, \TMP4 # packed right shift << 25
- pxor \TMP3, \TMP2 # xor the shifted versions
- pxor \TMP4, \TMP2
- movdqa \TMP2, \TMP5
- psrldq $4, \TMP5 # right shift T5 1 DW
- pslldq $12, \TMP2 # left shift T2 3 DWs
- pxor \TMP2, \XMM5
-
- # second phase of reduction
-
- movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4
- movdqa \XMM5,\TMP3
- movdqa \XMM5,\TMP4
- psrld $1, \TMP2 # packed left shift >>1
- psrld $2, \TMP3 # packed left shift >>2
- psrld $7, \TMP4 # packed left shift >>7
- pxor \TMP3,\TMP2 # xor the shifted versions
- pxor \TMP4,\TMP2
- pxor \TMP5, \TMP2
- pxor \TMP2, \XMM5
- pxor \TMP1, \XMM5 # result is in TMP1
-
- pxor \XMM5, \XMM1
-.endm
-
-/* GHASH the last 4 ciphertext blocks. */
-.macro GHASH_LAST_4 TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 \
-TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
-
- # Multiply TMP6 * HashKey (using Karatsuba)
-
- movdqa \XMM1, \TMP6
- pshufd $78, \XMM1, \TMP2
- pxor \XMM1, \TMP2
- movdqu HashKey_4(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP6 # TMP6 = a1*b1
- pclmulqdq $0x00, \TMP5, \XMM1 # XMM1 = a0*b0
- movdqu HashKey_4_k(%arg2), \TMP4
- pclmulqdq $0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- movdqa \XMM1, \XMMDst
- movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1
-
- # Multiply TMP1 * HashKey (using Karatsuba)
-
- movdqa \XMM2, \TMP1
- pshufd $78, \XMM2, \TMP2
- pxor \XMM2, \TMP2
- movdqu HashKey_3(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- pclmulqdq $0x00, \TMP5, \XMM2 # XMM2 = a0*b0
- movdqu HashKey_3_k(%arg2), \TMP4
- pclmulqdq $0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- pxor \TMP1, \TMP6
- pxor \XMM2, \XMMDst
- pxor \TMP2, \XMM1
-# results accumulated in TMP6, XMMDst, XMM1
-
- # Multiply TMP1 * HashKey (using Karatsuba)
-
- movdqa \XMM3, \TMP1
- pshufd $78, \XMM3, \TMP2
- pxor \XMM3, \TMP2
- movdqu HashKey_2(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- pclmulqdq $0x00, \TMP5, \XMM3 # XMM3 = a0*b0
- movdqu HashKey_2_k(%arg2), \TMP4
- pclmulqdq $0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- pxor \TMP1, \TMP6
- pxor \XMM3, \XMMDst
- pxor \TMP2, \XMM1 # results accumulated in TMP6, XMMDst, XMM1
-
- # Multiply TMP1 * HashKey (using Karatsuba)
- movdqa \XMM4, \TMP1
- pshufd $78, \XMM4, \TMP2
- pxor \XMM4, \TMP2
- movdqu HashKey(%arg2), \TMP5
- pclmulqdq $0x11, \TMP5, \TMP1 # TMP1 = a1*b1
- pclmulqdq $0x00, \TMP5, \XMM4 # XMM4 = a0*b0
- movdqu HashKey_k(%arg2), \TMP4
- pclmulqdq $0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
- pxor \TMP1, \TMP6
- pxor \XMM4, \XMMDst
- pxor \XMM1, \TMP2
- pxor \TMP6, \TMP2
- pxor \XMMDst, \TMP2
- # middle section of the temp results combined as in karatsuba algorithm
- movdqa \TMP2, \TMP4
- pslldq $8, \TMP4 # left shift TMP4 2 DWs
- psrldq $8, \TMP2 # right shift TMP2 2 DWs
- pxor \TMP4, \XMMDst
- pxor \TMP2, \TMP6
-# TMP6:XMMDst holds the result of the accumulated carry-less multiplications
- # first phase of the reduction
- movdqa \XMMDst, \TMP2
- movdqa \XMMDst, \TMP3
- movdqa \XMMDst, \TMP4
-# move XMMDst into TMP2, TMP3, TMP4 in order to perform 3 shifts independently
- pslld $31, \TMP2 # packed right shifting << 31
- pslld $30, \TMP3 # packed right shifting << 30
- pslld $25, \TMP4 # packed right shifting << 25
- pxor \TMP3, \TMP2 # xor the shifted versions
- pxor \TMP4, \TMP2
- movdqa \TMP2, \TMP7
- psrldq $4, \TMP7 # right shift TMP7 1 DW
- pslldq $12, \TMP2 # left shift TMP2 3 DWs
- pxor \TMP2, \XMMDst
-
- # second phase of the reduction
- movdqa \XMMDst, \TMP2
- # make 3 copies of XMMDst for doing 3 shift operations
- movdqa \XMMDst, \TMP3
- movdqa \XMMDst, \TMP4
- psrld $1, \TMP2 # packed left shift >> 1
- psrld $2, \TMP3 # packed left shift >> 2
- psrld $7, \TMP4 # packed left shift >> 7
- pxor \TMP3, \TMP2 # xor the shifted versions
- pxor \TMP4, \TMP2
- pxor \TMP7, \TMP2
- pxor \TMP2, \XMMDst
- pxor \TMP6, \XMMDst # reduced result is in XMMDst
-.endm
-
-
-/* Encryption of a single block
-* uses eax & r10
-*/
-
-.macro ENCRYPT_SINGLE_BLOCK XMM0 TMP1
-
- pxor (%arg1), \XMM0
- mov keysize,%eax
- shr $2,%eax # 128->4, 192->6, 256->8
- add $5,%eax # 128->9, 192->11, 256->13
- lea 16(%arg1), %r10 # get first expanded key address
-
-_esb_loop_\@:
- MOVADQ (%r10),\TMP1
- aesenc \TMP1,\XMM0
- add $16,%r10
- sub $1,%eax
- jnz _esb_loop_\@
-
- MOVADQ (%r10),\TMP1
- aesenclast \TMP1,\XMM0
-.endm
-/*****************************************************************************
-* void aesni_gcm_dec(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
-* struct gcm_context_data *data
-* // Context data
-* u8 *out, // Plaintext output. Encrypt in-place is allowed.
-* const u8 *in, // Ciphertext input
-* u64 plaintext_len, // Length of data in bytes for decryption.
-* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association)
-* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload)
-* // concatenated with 0x00000001. 16-byte aligned pointer.
-* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary.
-* const u8 *aad, // Additional Authentication Data (AAD)
-* u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes
-* u8 *auth_tag, // Authenticated Tag output. The driver will compare this to the
-* // given authentication tag and only return the plaintext if they match.
-* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16
-* // (most likely), 12 or 8.
-*
-* Assumptions:
-*
-* keys:
-* keys are pre-expanded and aligned to 16 bytes. we are using the first
-* set of 11 keys in the data structure void *aes_ctx
-*
-* iv:
-* 0 1 2 3
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | Salt (From the SA) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | Initialization Vector |
-* | (This is the sequence number from IPSec header) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 0x1 |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*
-*
-*
-* AAD:
-* AAD padded to 128 bits with 0
-* for example, assume AAD is a u32 vector
-*
-* if AAD is 8 bytes:
-* AAD[3] = {A0, A1};
-* padded AAD in xmm register = {A1 A0 0 0}
-*
-* 0 1 2 3
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | SPI (A1) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 32-bit Sequence Number (A0) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 0x0 |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*
-* AAD Format with 32-bit Sequence Number
-*
-* if AAD is 12 bytes:
-* AAD[3] = {A0, A1, A2};
-* padded AAD in xmm register = {A2 A1 A0 0}
-*
-* 0 1 2 3
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | SPI (A2) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 64-bit Extended Sequence Number {A1,A0} |
-* | |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 0x0 |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*
-* AAD Format with 64-bit Extended Sequence Number
-*
-* poly = x^128 + x^127 + x^126 + x^121 + 1
-*
-*****************************************************************************/
-SYM_FUNC_START(aesni_gcm_dec)
- FUNC_SAVE
-
- GCM_INIT %arg6, arg7, arg8, arg9
- GCM_ENC_DEC dec
- GCM_COMPLETE arg10, arg11
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_dec)
-
-
-/*****************************************************************************
-* void aesni_gcm_enc(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
-* struct gcm_context_data *data
-* // Context data
-* u8 *out, // Ciphertext output. Encrypt in-place is allowed.
-* const u8 *in, // Plaintext input
-* u64 plaintext_len, // Length of data in bytes for encryption.
-* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association)
-* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload)
-* // concatenated with 0x00000001. 16-byte aligned pointer.
-* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary.
-* const u8 *aad, // Additional Authentication Data (AAD)
-* u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes
-* u8 *auth_tag, // Authenticated Tag output.
-* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 (most likely),
-* // 12 or 8.
-*
-* Assumptions:
-*
-* keys:
-* keys are pre-expanded and aligned to 16 bytes. we are using the
-* first set of 11 keys in the data structure void *aes_ctx
-*
-*
-* iv:
-* 0 1 2 3
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | Salt (From the SA) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | Initialization Vector |
-* | (This is the sequence number from IPSec header) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 0x1 |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*
-*
-*
-* AAD:
-* AAD padded to 128 bits with 0
-* for example, assume AAD is a u32 vector
-*
-* if AAD is 8 bytes:
-* AAD[3] = {A0, A1};
-* padded AAD in xmm register = {A1 A0 0 0}
-*
-* 0 1 2 3
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | SPI (A1) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 32-bit Sequence Number (A0) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 0x0 |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*
-* AAD Format with 32-bit Sequence Number
-*
-* if AAD is 12 bytes:
-* AAD[3] = {A0, A1, A2};
-* padded AAD in xmm register = {A2 A1 A0 0}
-*
-* 0 1 2 3
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | SPI (A2) |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 64-bit Extended Sequence Number {A1,A0} |
-* | |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-* | 0x0 |
-* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*
-* AAD Format with 64-bit Extended Sequence Number
-*
-* poly = x^128 + x^127 + x^126 + x^121 + 1
-***************************************************************************/
-SYM_FUNC_START(aesni_gcm_enc)
- FUNC_SAVE
-
- GCM_INIT %arg6, arg7, arg8, arg9
- GCM_ENC_DEC enc
-
- GCM_COMPLETE arg10, arg11
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_enc)
-
-/*****************************************************************************
-* void aesni_gcm_init(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
-* struct gcm_context_data *data,
-* // context data
-* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association)
-* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload)
-* // concatenated with 0x00000001. 16-byte aligned pointer.
-* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary.
-* const u8 *aad, // Additional Authentication Data (AAD)
-* u64 aad_len) // Length of AAD in bytes.
-*/
-SYM_FUNC_START(aesni_gcm_init)
- FUNC_SAVE
- GCM_INIT %arg3, %arg4,%arg5, %arg6
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_init)
-
-/*****************************************************************************
-* void aesni_gcm_enc_update(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
-* struct gcm_context_data *data,
-* // context data
-* u8 *out, // Ciphertext output. Encrypt in-place is allowed.
-* const u8 *in, // Plaintext input
-* u64 plaintext_len, // Length of data in bytes for encryption.
-*/
-SYM_FUNC_START(aesni_gcm_enc_update)
- FUNC_SAVE
- GCM_ENC_DEC enc
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_enc_update)
-
-/*****************************************************************************
-* void aesni_gcm_dec_update(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
-* struct gcm_context_data *data,
-* // context data
-* u8 *out, // Ciphertext output. Encrypt in-place is allowed.
-* const u8 *in, // Plaintext input
-* u64 plaintext_len, // Length of data in bytes for encryption.
-*/
-SYM_FUNC_START(aesni_gcm_dec_update)
- FUNC_SAVE
- GCM_ENC_DEC dec
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_dec_update)
-
-/*****************************************************************************
-* void aesni_gcm_finalize(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
-* struct gcm_context_data *data,
-* // context data
-* u8 *auth_tag, // Authenticated Tag output.
-* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 (most likely),
-* // 12 or 8.
-*/
-SYM_FUNC_START(aesni_gcm_finalize)
- FUNC_SAVE
- GCM_COMPLETE %arg3 %arg4
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_finalize)
-
-#endif
-
SYM_FUNC_START_LOCAL(_key_expansion_256a)
pshufd $0b11111111, %xmm1, %xmm1
shufps $0b00010000, %xmm0, %xmm4
@@ -1820,8 +133,8 @@ SYM_FUNC_START_LOCAL(_key_expansion_256b)
SYM_FUNC_END(_key_expansion_256b)
/*
- * int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
- * unsigned int key_len)
+ * void aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ * unsigned int key_len)
*/
SYM_FUNC_START(aesni_set_key)
FRAME_BEGIN
@@ -1926,7 +239,6 @@ SYM_FUNC_START(aesni_set_key)
sub $0x10, UKEYP
cmp TKEYP, KEYP
jb .Ldec_key_loop
- xor AREG, AREG
#ifndef __x86_64__
popl KEYP
#endif
@@ -2826,28 +1138,24 @@ SYM_FUNC_END(aesni_ctr_enc)
.previous
/*
- * _aesni_gf128mul_x_ble: internal ABI
- * Multiply in GF(2^128) for XTS IVs
+ * _aesni_gf128mul_x_ble: Multiply in GF(2^128) for XTS IVs
* input:
* IV: current IV
* GF128MUL_MASK == mask with 0x87 and 0x01
* output:
* IV: next IV
* changed:
- * CTR: == temporary value
+ * KEY: == temporary value
*/
-#define _aesni_gf128mul_x_ble() \
- pshufd $0x13, IV, KEY; \
- paddq IV, IV; \
- psrad $31, KEY; \
- pand GF128MUL_MASK, KEY; \
- pxor KEY, IV;
+.macro _aesni_gf128mul_x_ble
+ pshufd $0x13, IV, KEY
+ paddq IV, IV
+ psrad $31, KEY
+ pand GF128MUL_MASK, KEY
+ pxor KEY, IV
+.endm
-/*
- * void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst,
- * const u8 *src, unsigned int len, le128 *iv)
- */
-SYM_FUNC_START(aesni_xts_encrypt)
+.macro _aesni_xts_crypt enc
FRAME_BEGIN
#ifndef __x86_64__
pushl IVP
@@ -2866,35 +1174,46 @@ SYM_FUNC_START(aesni_xts_encrypt)
movups (IVP), IV
mov 480(KEYP), KLEN
+.if !\enc
+ add $240, KEYP
+
+ test $15, LEN
+ jz .Lxts_loop4\@
+ sub $16, LEN
+.endif
-.Lxts_enc_loop4:
+.Lxts_loop4\@:
sub $64, LEN
- jl .Lxts_enc_1x
+ jl .Lxts_1x\@
movdqa IV, STATE1
movdqu 0x00(INP), IN
pxor IN, STATE1
movdqu IV, 0x00(OUTP)
- _aesni_gf128mul_x_ble()
+ _aesni_gf128mul_x_ble
movdqa IV, STATE2
movdqu 0x10(INP), IN
pxor IN, STATE2
movdqu IV, 0x10(OUTP)
- _aesni_gf128mul_x_ble()
+ _aesni_gf128mul_x_ble
movdqa IV, STATE3
movdqu 0x20(INP), IN
pxor IN, STATE3
movdqu IV, 0x20(OUTP)
- _aesni_gf128mul_x_ble()
+ _aesni_gf128mul_x_ble
movdqa IV, STATE4
movdqu 0x30(INP), IN
pxor IN, STATE4
movdqu IV, 0x30(OUTP)
+.if \enc
call _aesni_enc4
+.else
+ call _aesni_dec4
+.endif
movdqu 0x00(OUTP), IN
pxor IN, STATE1
@@ -2912,17 +1231,17 @@ SYM_FUNC_START(aesni_xts_encrypt)
pxor IN, STATE4
movdqu STATE4, 0x30(OUTP)
- _aesni_gf128mul_x_ble()
+ _aesni_gf128mul_x_ble
add $64, INP
add $64, OUTP
test LEN, LEN
- jnz .Lxts_enc_loop4
+ jnz .Lxts_loop4\@
-.Lxts_enc_ret_iv:
+.Lxts_ret_iv\@:
movups IV, (IVP)
-.Lxts_enc_ret:
+.Lxts_ret\@:
#ifndef __x86_64__
popl KLEN
popl KEYP
@@ -2932,201 +1251,60 @@ SYM_FUNC_START(aesni_xts_encrypt)
FRAME_END
RET
-.Lxts_enc_1x:
+.Lxts_1x\@:
add $64, LEN
- jz .Lxts_enc_ret_iv
+ jz .Lxts_ret_iv\@
+.if \enc
sub $16, LEN
- jl .Lxts_enc_cts4
+ jl .Lxts_cts4\@
+.endif
-.Lxts_enc_loop1:
+.Lxts_loop1\@:
movdqu (INP), STATE
+.if \enc
pxor IV, STATE
call _aesni_enc1
- pxor IV, STATE
- _aesni_gf128mul_x_ble()
-
- test LEN, LEN
- jz .Lxts_enc_out
-
+.else
add $16, INP
sub $16, LEN
- jl .Lxts_enc_cts1
-
- movdqu STATE, (OUTP)
- add $16, OUTP
- jmp .Lxts_enc_loop1
-
-.Lxts_enc_out:
- movdqu STATE, (OUTP)
- jmp .Lxts_enc_ret_iv
-
-.Lxts_enc_cts4:
- movdqa STATE4, STATE
- sub $16, OUTP
-
-.Lxts_enc_cts1:
-#ifndef __x86_64__
- lea .Lcts_permute_table, T1
-#else
- lea .Lcts_permute_table(%rip), T1
-#endif
- add LEN, INP /* rewind input pointer */
- add $16, LEN /* # bytes in final block */
- movups (INP), IN1
-
- mov T1, IVP
- add $32, IVP
- add LEN, T1
- sub LEN, IVP
- add OUTP, LEN
-
- movups (T1), %xmm4
- movaps STATE, IN2
- pshufb %xmm4, STATE
- movups STATE, (LEN)
-
- movups (IVP), %xmm0
- pshufb %xmm0, IN1
- pblendvb IN2, IN1
- movaps IN1, STATE
-
+ jl .Lxts_cts1\@
pxor IV, STATE
- call _aesni_enc1
+ call _aesni_dec1
+.endif
pxor IV, STATE
+ _aesni_gf128mul_x_ble
- movups STATE, (OUTP)
- jmp .Lxts_enc_ret
-SYM_FUNC_END(aesni_xts_encrypt)
-
-/*
- * void aesni_xts_decrypt(const struct crypto_aes_ctx *ctx, u8 *dst,
- * const u8 *src, unsigned int len, le128 *iv)
- */
-SYM_FUNC_START(aesni_xts_decrypt)
- FRAME_BEGIN
-#ifndef __x86_64__
- pushl IVP
- pushl LEN
- pushl KEYP
- pushl KLEN
- movl (FRAME_OFFSET+20)(%esp), KEYP # ctx
- movl (FRAME_OFFSET+24)(%esp), OUTP # dst
- movl (FRAME_OFFSET+28)(%esp), INP # src
- movl (FRAME_OFFSET+32)(%esp), LEN # len
- movl (FRAME_OFFSET+36)(%esp), IVP # iv
- movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK
-#else
- movdqa .Lgf128mul_x_ble_mask(%rip), GF128MUL_MASK
-#endif
- movups (IVP), IV
-
- mov 480(KEYP), KLEN
- add $240, KEYP
-
- test $15, LEN
- jz .Lxts_dec_loop4
- sub $16, LEN
-
-.Lxts_dec_loop4:
- sub $64, LEN
- jl .Lxts_dec_1x
-
- movdqa IV, STATE1
- movdqu 0x00(INP), IN
- pxor IN, STATE1
- movdqu IV, 0x00(OUTP)
-
- _aesni_gf128mul_x_ble()
- movdqa IV, STATE2
- movdqu 0x10(INP), IN
- pxor IN, STATE2
- movdqu IV, 0x10(OUTP)
-
- _aesni_gf128mul_x_ble()
- movdqa IV, STATE3
- movdqu 0x20(INP), IN
- pxor IN, STATE3
- movdqu IV, 0x20(OUTP)
-
- _aesni_gf128mul_x_ble()
- movdqa IV, STATE4
- movdqu 0x30(INP), IN
- pxor IN, STATE4
- movdqu IV, 0x30(OUTP)
-
- call _aesni_dec4
-
- movdqu 0x00(OUTP), IN
- pxor IN, STATE1
- movdqu STATE1, 0x00(OUTP)
-
- movdqu 0x10(OUTP), IN
- pxor IN, STATE2
- movdqu STATE2, 0x10(OUTP)
-
- movdqu 0x20(OUTP), IN
- pxor IN, STATE3
- movdqu STATE3, 0x20(OUTP)
-
- movdqu 0x30(OUTP), IN
- pxor IN, STATE4
- movdqu STATE4, 0x30(OUTP)
-
- _aesni_gf128mul_x_ble()
-
- add $64, INP
- add $64, OUTP
test LEN, LEN
- jnz .Lxts_dec_loop4
-
-.Lxts_dec_ret_iv:
- movups IV, (IVP)
-
-.Lxts_dec_ret:
-#ifndef __x86_64__
- popl KLEN
- popl KEYP
- popl LEN
- popl IVP
-#endif
- FRAME_END
- RET
-
-.Lxts_dec_1x:
- add $64, LEN
- jz .Lxts_dec_ret_iv
-
-.Lxts_dec_loop1:
- movdqu (INP), STATE
+ jz .Lxts_out\@
+.if \enc
add $16, INP
sub $16, LEN
- jl .Lxts_dec_cts1
-
- pxor IV, STATE
- call _aesni_dec1
- pxor IV, STATE
- _aesni_gf128mul_x_ble()
-
- test LEN, LEN
- jz .Lxts_dec_out
+ jl .Lxts_cts1\@
+.endif
movdqu STATE, (OUTP)
add $16, OUTP
- jmp .Lxts_dec_loop1
+ jmp .Lxts_loop1\@
-.Lxts_dec_out:
+.Lxts_out\@:
movdqu STATE, (OUTP)
- jmp .Lxts_dec_ret_iv
+ jmp .Lxts_ret_iv\@
-.Lxts_dec_cts1:
+.if \enc
+.Lxts_cts4\@:
+ movdqa STATE4, STATE
+ sub $16, OUTP
+.Lxts_cts1\@:
+.else
+.Lxts_cts1\@:
movdqa IV, STATE4
- _aesni_gf128mul_x_ble()
+ _aesni_gf128mul_x_ble
pxor IV, STATE
call _aesni_dec1
pxor IV, STATE
-
+.endif
#ifndef __x86_64__
lea .Lcts_permute_table, T1
#else
@@ -3152,10 +1330,32 @@ SYM_FUNC_START(aesni_xts_decrypt)
pblendvb IN2, IN1
movaps IN1, STATE
+.if \enc
+ pxor IV, STATE
+ call _aesni_enc1
+ pxor IV, STATE
+.else
pxor STATE4, STATE
call _aesni_dec1
pxor STATE4, STATE
+.endif
movups STATE, (OUTP)
- jmp .Lxts_dec_ret
-SYM_FUNC_END(aesni_xts_decrypt)
+ jmp .Lxts_ret\@
+.endm
+
+/*
+ * void aesni_xts_enc(const struct crypto_aes_ctx *ctx, u8 *dst,
+ * const u8 *src, unsigned int len, le128 *iv)
+ */
+SYM_FUNC_START(aesni_xts_enc)
+ _aesni_xts_crypt 1
+SYM_FUNC_END(aesni_xts_enc)
+
+/*
+ * void aesni_xts_dec(const struct crypto_aes_ctx *ctx, u8 *dst,
+ * const u8 *src, unsigned int len, le128 *iv)
+ */
+SYM_FUNC_START(aesni_xts_dec)
+ _aesni_xts_crypt 0
+SYM_FUNC_END(aesni_xts_dec)
diff --git a/arch/x86/crypto/aesni-intel_avx-x86_64.S b/arch/x86/crypto/aesni-intel_avx-x86_64.S
deleted file mode 100644
index 8c9749ed0651..000000000000
--- a/arch/x86/crypto/aesni-intel_avx-x86_64.S
+++ /dev/null
@@ -1,2804 +0,0 @@
-########################################################################
-# Copyright (c) 2013, Intel Corporation
-#
-# This software is available to you under a choice of one of two
-# licenses. You may choose to be licensed under the terms of the GNU
-# General Public License (GPL) Version 2, available from the file
-# COPYING in the main directory of this source tree, or the
-# OpenIB.org BSD license below:
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the
-# distribution.
-#
-# * Neither the name of the Intel Corporation nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-#
-# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES# LOSS OF USE, DATA, OR
-# PROFITS# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-########################################################################
-##
-## Authors:
-## Erdinc Ozturk <erdinc.ozturk@intel.com>
-## Vinodh Gopal <vinodh.gopal@intel.com>
-## James Guilford <james.guilford@intel.com>
-## Tim Chen <tim.c.chen@linux.intel.com>
-##
-## References:
-## This code was derived and highly optimized from the code described in paper:
-## Vinodh Gopal et. al. Optimized Galois-Counter-Mode Implementation
-## on Intel Architecture Processors. August, 2010
-## The details of the implementation is explained in:
-## Erdinc Ozturk et. al. Enabling High-Performance Galois-Counter-Mode
-## on Intel Architecture Processors. October, 2012.
-##
-## Assumptions:
-##
-##
-##
-## iv:
-## 0 1 2 3
-## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | Salt (From the SA) |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | Initialization Vector |
-## | (This is the sequence number from IPSec header) |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | 0x1 |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-##
-##
-##
-## AAD:
-## AAD padded to 128 bits with 0
-## for example, assume AAD is a u32 vector
-##
-## if AAD is 8 bytes:
-## AAD[3] = {A0, A1}#
-## padded AAD in xmm register = {A1 A0 0 0}
-##
-## 0 1 2 3
-## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | SPI (A1) |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | 32-bit Sequence Number (A0) |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | 0x0 |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-##
-## AAD Format with 32-bit Sequence Number
-##
-## if AAD is 12 bytes:
-## AAD[3] = {A0, A1, A2}#
-## padded AAD in xmm register = {A2 A1 A0 0}
-##
-## 0 1 2 3
-## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | SPI (A2) |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | 64-bit Extended Sequence Number {A1,A0} |
-## | |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-## | 0x0 |
-## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-##
-## AAD Format with 64-bit Extended Sequence Number
-##
-##
-## aadLen:
-## from the definition of the spec, aadLen can only be 8 or 12 bytes.
-## The code additionally supports aadLen of length 16 bytes.
-##
-## TLen:
-## from the definition of the spec, TLen can only be 8, 12 or 16 bytes.
-##
-## poly = x^128 + x^127 + x^126 + x^121 + 1
-## throughout the code, one tab and two tab indentations are used. one tab is
-## for GHASH part, two tabs is for AES part.
-##
-
-#include <linux/linkage.h>
-
-# constants in mergeable sections, linker can reorder and merge
-.section .rodata.cst16.POLY, "aM", @progbits, 16
-.align 16
-POLY: .octa 0xC2000000000000000000000000000001
-
-.section .rodata.cst16.POLY2, "aM", @progbits, 16
-.align 16
-POLY2: .octa 0xC20000000000000000000001C2000000
-
-.section .rodata.cst16.TWOONE, "aM", @progbits, 16
-.align 16
-TWOONE: .octa 0x00000001000000000000000000000001
-
-.section .rodata.cst16.SHUF_MASK, "aM", @progbits, 16
-.align 16
-SHUF_MASK: .octa 0x000102030405060708090A0B0C0D0E0F
-
-.section .rodata.cst16.ONE, "aM", @progbits, 16
-.align 16
-ONE: .octa 0x00000000000000000000000000000001
-
-.section .rodata.cst16.ONEf, "aM", @progbits, 16
-.align 16
-ONEf: .octa 0x01000000000000000000000000000000
-
-# order of these constants should not change.
-# more specifically, ALL_F should follow SHIFT_MASK, and zero should follow ALL_F
-.section .rodata, "a", @progbits
-.align 16
-SHIFT_MASK: .octa 0x0f0e0d0c0b0a09080706050403020100
-ALL_F: .octa 0xffffffffffffffffffffffffffffffff
- .octa 0x00000000000000000000000000000000
-
-.text
-
-
-#define AadHash 16*0
-#define AadLen 16*1
-#define InLen (16*1)+8
-#define PBlockEncKey 16*2
-#define OrigIV 16*3
-#define CurCount 16*4
-#define PBlockLen 16*5
-
-HashKey = 16*6 # store HashKey <<1 mod poly here
-HashKey_2 = 16*7 # store HashKey^2 <<1 mod poly here
-HashKey_3 = 16*8 # store HashKey^3 <<1 mod poly here
-HashKey_4 = 16*9 # store HashKey^4 <<1 mod poly here
-HashKey_5 = 16*10 # store HashKey^5 <<1 mod poly here
-HashKey_6 = 16*11 # store HashKey^6 <<1 mod poly here
-HashKey_7 = 16*12 # store HashKey^7 <<1 mod poly here
-HashKey_8 = 16*13 # store HashKey^8 <<1 mod poly here
-HashKey_k = 16*14 # store XOR of HashKey <<1 mod poly here (for Karatsuba purposes)
-HashKey_2_k = 16*15 # store XOR of HashKey^2 <<1 mod poly here (for Karatsuba purposes)
-HashKey_3_k = 16*16 # store XOR of HashKey^3 <<1 mod poly here (for Karatsuba purposes)
-HashKey_4_k = 16*17 # store XOR of HashKey^4 <<1 mod poly here (for Karatsuba purposes)
-HashKey_5_k = 16*18 # store XOR of HashKey^5 <<1 mod poly here (for Karatsuba purposes)
-HashKey_6_k = 16*19 # store XOR of HashKey^6 <<1 mod poly here (for Karatsuba purposes)
-HashKey_7_k = 16*20 # store XOR of HashKey^7 <<1 mod poly here (for Karatsuba purposes)
-HashKey_8_k = 16*21 # store XOR of HashKey^8 <<1 mod poly here (for Karatsuba purposes)
-
-#define arg1 %rdi
-#define arg2 %rsi
-#define arg3 %rdx
-#define arg4 %rcx
-#define arg5 %r8
-#define arg6 %r9
-#define keysize 2*15*16(arg1)
-
-i = 0
-j = 0
-
-out_order = 0
-in_order = 1
-DEC = 0
-ENC = 1
-
-.macro define_reg r n
-reg_\r = %xmm\n
-.endm
-
-.macro setreg
-.altmacro
-define_reg i %i
-define_reg j %j
-.noaltmacro
-.endm
-
-TMP1 = 16*0 # Temporary storage for AAD
-TMP2 = 16*1 # Temporary storage for AES State 2 (State 1 is stored in an XMM register)
-TMP3 = 16*2 # Temporary storage for AES State 3
-TMP4 = 16*3 # Temporary storage for AES State 4
-TMP5 = 16*4 # Temporary storage for AES State 5
-TMP6 = 16*5 # Temporary storage for AES State 6
-TMP7 = 16*6 # Temporary storage for AES State 7
-TMP8 = 16*7 # Temporary storage for AES State 8
-
-VARIABLE_OFFSET = 16*8
-
-################################
-# Utility Macros
-################################
-
-.macro FUNC_SAVE
- push %r12
- push %r13
- push %r15
-
- push %rbp
- mov %rsp, %rbp
-
- sub $VARIABLE_OFFSET, %rsp
- and $~63, %rsp # align rsp to 64 bytes
-.endm
-
-.macro FUNC_RESTORE
- mov %rbp, %rsp
- pop %rbp
-
- pop %r15
- pop %r13
- pop %r12
-.endm
-
-# Encryption of a single block
-.macro ENCRYPT_SINGLE_BLOCK REP XMM0
- vpxor (arg1), \XMM0, \XMM0
- i = 1
- setreg
-.rep \REP
- vaesenc 16*i(arg1), \XMM0, \XMM0
- i = (i+1)
- setreg
-.endr
- vaesenclast 16*i(arg1), \XMM0, \XMM0
-.endm
-
-# combined for GCM encrypt and decrypt functions
-# clobbering all xmm registers
-# clobbering r10, r11, r12, r13, r15, rax
-.macro GCM_ENC_DEC INITIAL_BLOCKS GHASH_8_ENCRYPT_8_PARALLEL GHASH_LAST_8 GHASH_MUL ENC_DEC REP
- vmovdqu AadHash(arg2), %xmm8
- vmovdqu HashKey(arg2), %xmm13 # xmm13 = HashKey
- add arg5, InLen(arg2)
-
- # initialize the data pointer offset as zero
- xor %r11d, %r11d
-
- PARTIAL_BLOCK \GHASH_MUL, arg3, arg4, arg5, %r11, %xmm8, \ENC_DEC
- sub %r11, arg5
-
- mov arg5, %r13 # save the number of bytes of plaintext/ciphertext
- and $-16, %r13 # r13 = r13 - (r13 mod 16)
-
- mov %r13, %r12
- shr $4, %r12
- and $7, %r12
- jz .L_initial_num_blocks_is_0\@
-
- cmp $7, %r12
- je .L_initial_num_blocks_is_7\@
- cmp $6, %r12
- je .L_initial_num_blocks_is_6\@
- cmp $5, %r12
- je .L_initial_num_blocks_is_5\@
- cmp $4, %r12
- je .L_initial_num_blocks_is_4\@
- cmp $3, %r12
- je .L_initial_num_blocks_is_3\@
- cmp $2, %r12
- je .L_initial_num_blocks_is_2\@
-
- jmp .L_initial_num_blocks_is_1\@
-
-.L_initial_num_blocks_is_7\@:
- \INITIAL_BLOCKS \REP, 7, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*7, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_6\@:
- \INITIAL_BLOCKS \REP, 6, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*6, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_5\@:
- \INITIAL_BLOCKS \REP, 5, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*5, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_4\@:
- \INITIAL_BLOCKS \REP, 4, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*4, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_3\@:
- \INITIAL_BLOCKS \REP, 3, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*3, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_2\@:
- \INITIAL_BLOCKS \REP, 2, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*2, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_1\@:
- \INITIAL_BLOCKS \REP, 1, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
- sub $16*1, %r13
- jmp .L_initial_blocks_encrypted\@
-
-.L_initial_num_blocks_is_0\@:
- \INITIAL_BLOCKS \REP, 0, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
-
-
-.L_initial_blocks_encrypted\@:
- test %r13, %r13
- je .L_zero_cipher_left\@
-
- sub $128, %r13
- je .L_eight_cipher_left\@
-
-
-
-
- vmovd %xmm9, %r15d
- and $255, %r15d
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
-
-
-.L_encrypt_by_8_new\@:
- cmp $(255-8), %r15d
- jg .L_encrypt_by_8\@
-
-
-
- add $8, %r15b
- \GHASH_8_ENCRYPT_8_PARALLEL \REP, %xmm0, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm15, out_order, \ENC_DEC
- add $128, %r11
- sub $128, %r13
- jne .L_encrypt_by_8_new\@
-
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
- jmp .L_eight_cipher_left\@
-
-.L_encrypt_by_8\@:
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
- add $8, %r15b
- \GHASH_8_ENCRYPT_8_PARALLEL \REP, %xmm0, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm15, in_order, \ENC_DEC
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
- add $128, %r11
- sub $128, %r13
- jne .L_encrypt_by_8_new\@
-
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
-
-
-
-
-.L_eight_cipher_left\@:
- \GHASH_LAST_8 %xmm0, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8
-
-
-.L_zero_cipher_left\@:
- vmovdqu %xmm14, AadHash(arg2)
- vmovdqu %xmm9, CurCount(arg2)
-
- # check for 0 length
- mov arg5, %r13
- and $15, %r13 # r13 = (arg5 mod 16)
-
- je .L_multiple_of_16_bytes\@
-
- # handle the last <16 Byte block separately
-
- mov %r13, PBlockLen(arg2)
-
- vpaddd ONE(%rip), %xmm9, %xmm9 # INCR CNT to get Yn
- vmovdqu %xmm9, CurCount(arg2)
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
-
- ENCRYPT_SINGLE_BLOCK \REP, %xmm9 # E(K, Yn)
- vmovdqu %xmm9, PBlockEncKey(arg2)
-
- cmp $16, arg5
- jge .L_large_enough_update\@
-
- lea (arg4,%r11,1), %r10
- mov %r13, %r12
-
- READ_PARTIAL_BLOCK %r10 %r12 %xmm1
-
- lea SHIFT_MASK+16(%rip), %r12
- sub %r13, %r12 # adjust the shuffle mask pointer to be
- # able to shift 16-r13 bytes (r13 is the
- # number of bytes in plaintext mod 16)
-
- jmp .L_final_ghash_mul\@
-
-.L_large_enough_update\@:
- sub $16, %r11
- add %r13, %r11
-
- # receive the last <16 Byte block
- vmovdqu (arg4, %r11, 1), %xmm1
-
- sub %r13, %r11
- add $16, %r11
-
- lea SHIFT_MASK+16(%rip), %r12
- # adjust the shuffle mask pointer to be able to shift 16-r13 bytes
- # (r13 is the number of bytes in plaintext mod 16)
- sub %r13, %r12
- # get the appropriate shuffle mask
- vmovdqu (%r12), %xmm2
- # shift right 16-r13 bytes
- vpshufb %xmm2, %xmm1, %xmm1
-
-.L_final_ghash_mul\@:
- .if \ENC_DEC == DEC
- vmovdqa %xmm1, %xmm2
- vpxor %xmm1, %xmm9, %xmm9 # Plaintext XOR E(K, Yn)
- vmovdqu ALL_F-SHIFT_MASK(%r12), %xmm1 # get the appropriate mask to
- # mask out top 16-r13 bytes of xmm9
- vpand %xmm1, %xmm9, %xmm9 # mask out top 16-r13 bytes of xmm9
- vpand %xmm1, %xmm2, %xmm2
- vpshufb SHUF_MASK(%rip), %xmm2, %xmm2
- vpxor %xmm2, %xmm14, %xmm14
-
- vmovdqu %xmm14, AadHash(arg2)
- .else
- vpxor %xmm1, %xmm9, %xmm9 # Plaintext XOR E(K, Yn)
- vmovdqu ALL_F-SHIFT_MASK(%r12), %xmm1 # get the appropriate mask to
- # mask out top 16-r13 bytes of xmm9
- vpand %xmm1, %xmm9, %xmm9 # mask out top 16-r13 bytes of xmm9
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
- vpxor %xmm9, %xmm14, %xmm14
-
- vmovdqu %xmm14, AadHash(arg2)
- vpshufb SHUF_MASK(%rip), %xmm9, %xmm9 # shuffle xmm9 back to output as ciphertext
- .endif
-
-
- #############################
- # output r13 Bytes
- vmovq %xmm9, %rax
- cmp $8, %r13
- jle .L_less_than_8_bytes_left\@
-
- mov %rax, (arg3 , %r11)
- add $8, %r11
- vpsrldq $8, %xmm9, %xmm9
- vmovq %xmm9, %rax
- sub $8, %r13
-
-.L_less_than_8_bytes_left\@:
- movb %al, (arg3 , %r11)
- add $1, %r11
- shr $8, %rax
- sub $1, %r13
- jne .L_less_than_8_bytes_left\@
- #############################
-
-.L_multiple_of_16_bytes\@:
-.endm
-
-
-# GCM_COMPLETE Finishes update of tag of last partial block
-# Output: Authorization Tag (AUTH_TAG)
-# Clobbers rax, r10-r12, and xmm0, xmm1, xmm5-xmm15
-.macro GCM_COMPLETE GHASH_MUL REP AUTH_TAG AUTH_TAG_LEN
- vmovdqu AadHash(arg2), %xmm14
- vmovdqu HashKey(arg2), %xmm13
-
- mov PBlockLen(arg2), %r12
- test %r12, %r12
- je .L_partial_done\@
-
- #GHASH computation for the last <16 Byte block
- \GHASH_MUL %xmm14, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
-
-.L_partial_done\@:
- mov AadLen(arg2), %r12 # r12 = aadLen (number of bytes)
- shl $3, %r12 # convert into number of bits
- vmovd %r12d, %xmm15 # len(A) in xmm15
-
- mov InLen(arg2), %r12
- shl $3, %r12 # len(C) in bits (*128)
- vmovq %r12, %xmm1
- vpslldq $8, %xmm15, %xmm15 # xmm15 = len(A)|| 0x0000000000000000
- vpxor %xmm1, %xmm15, %xmm15 # xmm15 = len(A)||len(C)
-
- vpxor %xmm15, %xmm14, %xmm14
- \GHASH_MUL %xmm14, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6 # final GHASH computation
- vpshufb SHUF_MASK(%rip), %xmm14, %xmm14 # perform a 16Byte swap
-
- vmovdqu OrigIV(arg2), %xmm9
-
- ENCRYPT_SINGLE_BLOCK \REP, %xmm9 # E(K, Y0)
-
- vpxor %xmm14, %xmm9, %xmm9
-
-
-
-.L_return_T\@:
- mov \AUTH_TAG, %r10 # r10 = authTag
- mov \AUTH_TAG_LEN, %r11 # r11 = auth_tag_len
-
- cmp $16, %r11
- je .L_T_16\@
-
- cmp $8, %r11
- jl .L_T_4\@
-
-.L_T_8\@:
- vmovq %xmm9, %rax
- mov %rax, (%r10)
- add $8, %r10
- sub $8, %r11
- vpsrldq $8, %xmm9, %xmm9
- test %r11, %r11
- je .L_return_T_done\@
-.L_T_4\@:
- vmovd %xmm9, %eax
- mov %eax, (%r10)
- add $4, %r10
- sub $4, %r11
- vpsrldq $4, %xmm9, %xmm9
- test %r11, %r11
- je .L_return_T_done\@
-.L_T_123\@:
- vmovd %xmm9, %eax
- cmp $2, %r11
- jl .L_T_1\@
- mov %ax, (%r10)
- cmp $2, %r11
- je .L_return_T_done\@
- add $2, %r10
- sar $16, %eax
-.L_T_1\@:
- mov %al, (%r10)
- jmp .L_return_T_done\@
-
-.L_T_16\@:
- vmovdqu %xmm9, (%r10)
-
-.L_return_T_done\@:
-.endm
-
-.macro CALC_AAD_HASH GHASH_MUL AAD AADLEN T1 T2 T3 T4 T5 T6 T7 T8
-
- mov \AAD, %r10 # r10 = AAD
- mov \AADLEN, %r12 # r12 = aadLen
-
-
- mov %r12, %r11
-
- vpxor \T8, \T8, \T8
- vpxor \T7, \T7, \T7
- cmp $16, %r11
- jl .L_get_AAD_rest8\@
-.L_get_AAD_blocks\@:
- vmovdqu (%r10), \T7
- vpshufb SHUF_MASK(%rip), \T7, \T7
- vpxor \T7, \T8, \T8
- \GHASH_MUL \T8, \T2, \T1, \T3, \T4, \T5, \T6
- add $16, %r10
- sub $16, %r12
- sub $16, %r11
- cmp $16, %r11
- jge .L_get_AAD_blocks\@
- vmovdqu \T8, \T7
- test %r11, %r11
- je .L_get_AAD_done\@
-
- vpxor \T7, \T7, \T7
-
- /* read the last <16B of AAD. since we have at least 4B of
- data right after the AAD (the ICV, and maybe some CT), we can
- read 4B/8B blocks safely, and then get rid of the extra stuff */
-.L_get_AAD_rest8\@:
- cmp $4, %r11
- jle .L_get_AAD_rest4\@
- movq (%r10), \T1
- add $8, %r10
- sub $8, %r11
- vpslldq $8, \T1, \T1
- vpsrldq $8, \T7, \T7
- vpxor \T1, \T7, \T7
- jmp .L_get_AAD_rest8\@
-.L_get_AAD_rest4\@:
- test %r11, %r11
- jle .L_get_AAD_rest0\@
- mov (%r10), %eax
- movq %rax, \T1
- add $4, %r10
- sub $4, %r11
- vpslldq $12, \T1, \T1
- vpsrldq $4, \T7, \T7
- vpxor \T1, \T7, \T7
-.L_get_AAD_rest0\@:
- /* finalize: shift out the extra bytes we read, and align
- left. since pslldq can only shift by an immediate, we use
- vpshufb and a pair of shuffle masks */
- leaq ALL_F(%rip), %r11
- subq %r12, %r11
- vmovdqu 16(%r11), \T1
- andq $~3, %r11
- vpshufb (%r11), \T7, \T7
- vpand \T1, \T7, \T7
-.L_get_AAD_rest_final\@:
- vpshufb SHUF_MASK(%rip), \T7, \T7
- vpxor \T8, \T7, \T7
- \GHASH_MUL \T7, \T2, \T1, \T3, \T4, \T5, \T6
-
-.L_get_AAD_done\@:
- vmovdqu \T7, AadHash(arg2)
-.endm
-
-.macro INIT GHASH_MUL PRECOMPUTE
- mov arg6, %r11
- mov %r11, AadLen(arg2) # ctx_data.aad_length = aad_length
- xor %r11d, %r11d
- mov %r11, InLen(arg2) # ctx_data.in_length = 0
-
- mov %r11, PBlockLen(arg2) # ctx_data.partial_block_length = 0
- mov %r11, PBlockEncKey(arg2) # ctx_data.partial_block_enc_key = 0
- mov arg3, %rax
- movdqu (%rax), %xmm0
- movdqu %xmm0, OrigIV(arg2) # ctx_data.orig_IV = iv
-
- vpshufb SHUF_MASK(%rip), %xmm0, %xmm0
- movdqu %xmm0, CurCount(arg2) # ctx_data.current_counter = iv
-
- vmovdqu (arg4), %xmm6 # xmm6 = HashKey
-
- vpshufb SHUF_MASK(%rip), %xmm6, %xmm6
- ############### PRECOMPUTATION of HashKey<<1 mod poly from the HashKey
- vmovdqa %xmm6, %xmm2
- vpsllq $1, %xmm6, %xmm6
- vpsrlq $63, %xmm2, %xmm2
- vmovdqa %xmm2, %xmm1
- vpslldq $8, %xmm2, %xmm2
- vpsrldq $8, %xmm1, %xmm1
- vpor %xmm2, %xmm6, %xmm6
- #reduction
- vpshufd $0b00100100, %xmm1, %xmm2
- vpcmpeqd TWOONE(%rip), %xmm2, %xmm2
- vpand POLY(%rip), %xmm2, %xmm2
- vpxor %xmm2, %xmm6, %xmm6 # xmm6 holds the HashKey<<1 mod poly
- #######################################################################
- vmovdqu %xmm6, HashKey(arg2) # store HashKey<<1 mod poly
-
- CALC_AAD_HASH \GHASH_MUL, arg5, arg6, %xmm2, %xmm6, %xmm3, %xmm4, %xmm5, %xmm7, %xmm1, %xmm0
-
- \PRECOMPUTE %xmm6, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5
-.endm
-
-
-# Reads DLEN bytes starting at DPTR and stores in XMMDst
-# where 0 < DLEN < 16
-# Clobbers %rax, DLEN
-.macro READ_PARTIAL_BLOCK DPTR DLEN XMMDst
- vpxor \XMMDst, \XMMDst, \XMMDst
-
- cmp $8, \DLEN
- jl .L_read_lt8_\@
- mov (\DPTR), %rax
- vpinsrq $0, %rax, \XMMDst, \XMMDst
- sub $8, \DLEN
- jz .L_done_read_partial_block_\@
- xor %eax, %eax
-.L_read_next_byte_\@:
- shl $8, %rax
- mov 7(\DPTR, \DLEN, 1), %al
- dec \DLEN
- jnz .L_read_next_byte_\@
- vpinsrq $1, %rax, \XMMDst, \XMMDst
- jmp .L_done_read_partial_block_\@
-.L_read_lt8_\@:
- xor %eax, %eax
-.L_read_next_byte_lt8_\@:
- shl $8, %rax
- mov -1(\DPTR, \DLEN, 1), %al
- dec \DLEN
- jnz .L_read_next_byte_lt8_\@
- vpinsrq $0, %rax, \XMMDst, \XMMDst
-.L_done_read_partial_block_\@:
-.endm
-
-# PARTIAL_BLOCK: Handles encryption/decryption and the tag partial blocks
-# between update calls.
-# Requires the input data be at least 1 byte long due to READ_PARTIAL_BLOCK
-# Outputs encrypted bytes, and updates hash and partial info in gcm_data_context
-# Clobbers rax, r10, r12, r13, xmm0-6, xmm9-13
-.macro PARTIAL_BLOCK GHASH_MUL CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \
- AAD_HASH ENC_DEC
- mov PBlockLen(arg2), %r13
- test %r13, %r13
- je .L_partial_block_done_\@ # Leave Macro if no partial blocks
- # Read in input data without over reading
- cmp $16, \PLAIN_CYPH_LEN
- jl .L_fewer_than_16_bytes_\@
- vmovdqu (\PLAIN_CYPH_IN), %xmm1 # If more than 16 bytes, just fill xmm
- jmp .L_data_read_\@
-
-.L_fewer_than_16_bytes_\@:
- lea (\PLAIN_CYPH_IN, \DATA_OFFSET, 1), %r10
- mov \PLAIN_CYPH_LEN, %r12
- READ_PARTIAL_BLOCK %r10 %r12 %xmm1
-
- mov PBlockLen(arg2), %r13
-
-.L_data_read_\@: # Finished reading in data
-
- vmovdqu PBlockEncKey(arg2), %xmm9
- vmovdqu HashKey(arg2), %xmm13
-
- lea SHIFT_MASK(%rip), %r12
-
- # adjust the shuffle mask pointer to be able to shift r13 bytes
- # r16-r13 is the number of bytes in plaintext mod 16)
- add %r13, %r12
- vmovdqu (%r12), %xmm2 # get the appropriate shuffle mask
- vpshufb %xmm2, %xmm9, %xmm9 # shift right r13 bytes
-
-.if \ENC_DEC == DEC
- vmovdqa %xmm1, %xmm3
- pxor %xmm1, %xmm9 # Ciphertext XOR E(K, Yn)
-
- mov \PLAIN_CYPH_LEN, %r10
- add %r13, %r10
- # Set r10 to be the amount of data left in CYPH_PLAIN_IN after filling
- sub $16, %r10
- # Determine if partial block is not being filled and
- # shift mask accordingly
- jge .L_no_extra_mask_1_\@
- sub %r10, %r12
-.L_no_extra_mask_1_\@:
-
- vmovdqu ALL_F-SHIFT_MASK(%r12), %xmm1
- # get the appropriate mask to mask out bottom r13 bytes of xmm9
- vpand %xmm1, %xmm9, %xmm9 # mask out bottom r13 bytes of xmm9
-
- vpand %xmm1, %xmm3, %xmm3
- vmovdqa SHUF_MASK(%rip), %xmm10
- vpshufb %xmm10, %xmm3, %xmm3
- vpshufb %xmm2, %xmm3, %xmm3
- vpxor %xmm3, \AAD_HASH, \AAD_HASH
-
- test %r10, %r10
- jl .L_partial_incomplete_1_\@
-
- # GHASH computation for the last <16 Byte block
- \GHASH_MUL \AAD_HASH, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
- xor %eax,%eax
-
- mov %rax, PBlockLen(arg2)
- jmp .L_dec_done_\@
-.L_partial_incomplete_1_\@:
- add \PLAIN_CYPH_LEN, PBlockLen(arg2)
-.L_dec_done_\@:
- vmovdqu \AAD_HASH, AadHash(arg2)
-.else
- vpxor %xmm1, %xmm9, %xmm9 # Plaintext XOR E(K, Yn)
-
- mov \PLAIN_CYPH_LEN, %r10
- add %r13, %r10
- # Set r10 to be the amount of data left in CYPH_PLAIN_IN after filling
- sub $16, %r10
- # Determine if partial block is not being filled and
- # shift mask accordingly
- jge .L_no_extra_mask_2_\@
- sub %r10, %r12
-.L_no_extra_mask_2_\@:
-
- vmovdqu ALL_F-SHIFT_MASK(%r12), %xmm1
- # get the appropriate mask to mask out bottom r13 bytes of xmm9
- vpand %xmm1, %xmm9, %xmm9
-
- vmovdqa SHUF_MASK(%rip), %xmm1
- vpshufb %xmm1, %xmm9, %xmm9
- vpshufb %xmm2, %xmm9, %xmm9
- vpxor %xmm9, \AAD_HASH, \AAD_HASH
-
- test %r10, %r10
- jl .L_partial_incomplete_2_\@
-
- # GHASH computation for the last <16 Byte block
- \GHASH_MUL \AAD_HASH, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
- xor %eax,%eax
-
- mov %rax, PBlockLen(arg2)
- jmp .L_encode_done_\@
-.L_partial_incomplete_2_\@:
- add \PLAIN_CYPH_LEN, PBlockLen(arg2)
-.L_encode_done_\@:
- vmovdqu \AAD_HASH, AadHash(arg2)
-
- vmovdqa SHUF_MASK(%rip), %xmm10
- # shuffle xmm9 back to output as ciphertext
- vpshufb %xmm10, %xmm9, %xmm9
- vpshufb %xmm2, %xmm9, %xmm9
-.endif
- # output encrypted Bytes
- test %r10, %r10
- jl .L_partial_fill_\@
- mov %r13, %r12
- mov $16, %r13
- # Set r13 to be the number of bytes to write out
- sub %r12, %r13
- jmp .L_count_set_\@
-.L_partial_fill_\@:
- mov \PLAIN_CYPH_LEN, %r13
-.L_count_set_\@:
- vmovdqa %xmm9, %xmm0
- vmovq %xmm0, %rax
- cmp $8, %r13
- jle .L_less_than_8_bytes_left_\@
-
- mov %rax, (\CYPH_PLAIN_OUT, \DATA_OFFSET, 1)
- add $8, \DATA_OFFSET
- psrldq $8, %xmm0
- vmovq %xmm0, %rax
- sub $8, %r13
-.L_less_than_8_bytes_left_\@:
- movb %al, (\CYPH_PLAIN_OUT, \DATA_OFFSET, 1)
- add $1, \DATA_OFFSET
- shr $8, %rax
- sub $1, %r13
- jne .L_less_than_8_bytes_left_\@
-.L_partial_block_done_\@:
-.endm # PARTIAL_BLOCK
-
-###############################################################################
-# GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0)
-# Input: A and B (128-bits each, bit-reflected)
-# Output: C = A*B*x mod poly, (i.e. >>1 )
-# To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input
-# GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly.
-###############################################################################
-.macro GHASH_MUL_AVX GH HK T1 T2 T3 T4 T5
-
- vpshufd $0b01001110, \GH, \T2
- vpshufd $0b01001110, \HK, \T3
- vpxor \GH , \T2, \T2 # T2 = (a1+a0)
- vpxor \HK , \T3, \T3 # T3 = (b1+b0)
-
- vpclmulqdq $0x11, \HK, \GH, \T1 # T1 = a1*b1
- vpclmulqdq $0x00, \HK, \GH, \GH # GH = a0*b0
- vpclmulqdq $0x00, \T3, \T2, \T2 # T2 = (a1+a0)*(b1+b0)
- vpxor \GH, \T2,\T2
- vpxor \T1, \T2,\T2 # T2 = a0*b1+a1*b0
-
- vpslldq $8, \T2,\T3 # shift-L T3 2 DWs
- vpsrldq $8, \T2,\T2 # shift-R T2 2 DWs
- vpxor \T3, \GH, \GH
- vpxor \T2, \T1, \T1 # <T1:GH> = GH x HK
-
- #first phase of the reduction
- vpslld $31, \GH, \T2 # packed right shifting << 31
- vpslld $30, \GH, \T3 # packed right shifting shift << 30
- vpslld $25, \GH, \T4 # packed right shifting shift << 25
-
- vpxor \T3, \T2, \T2 # xor the shifted versions
- vpxor \T4, \T2, \T2
-
- vpsrldq $4, \T2, \T5 # shift-R T5 1 DW
-
- vpslldq $12, \T2, \T2 # shift-L T2 3 DWs
- vpxor \T2, \GH, \GH # first phase of the reduction complete
-
- #second phase of the reduction
-
- vpsrld $1,\GH, \T2 # packed left shifting >> 1
- vpsrld $2,\GH, \T3 # packed left shifting >> 2
- vpsrld $7,\GH, \T4 # packed left shifting >> 7
- vpxor \T3, \T2, \T2 # xor the shifted versions
- vpxor \T4, \T2, \T2
-
- vpxor \T5, \T2, \T2
- vpxor \T2, \GH, \GH
- vpxor \T1, \GH, \GH # the result is in GH
-
-
-.endm
-
-.macro PRECOMPUTE_AVX HK T1 T2 T3 T4 T5 T6
-
- # Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
- vmovdqa \HK, \T5
-
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^2<<1 mod poly
- vmovdqu \T5, HashKey_2(arg2) # [HashKey_2] = HashKey^2<<1 mod poly
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_2_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^3<<1 mod poly
- vmovdqu \T5, HashKey_3(arg2)
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_3_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^4<<1 mod poly
- vmovdqu \T5, HashKey_4(arg2)
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_4_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^5<<1 mod poly
- vmovdqu \T5, HashKey_5(arg2)
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_5_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^6<<1 mod poly
- vmovdqu \T5, HashKey_6(arg2)
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_6_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^7<<1 mod poly
- vmovdqu \T5, HashKey_7(arg2)
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_7_k(arg2)
-
- GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^8<<1 mod poly
- vmovdqu \T5, HashKey_8(arg2)
- vpshufd $0b01001110, \T5, \T1
- vpxor \T5, \T1, \T1
- vmovdqu \T1, HashKey_8_k(arg2)
-
-.endm
-
-## if a = number of total plaintext bytes
-## b = floor(a/16)
-## num_initial_blocks = b mod 4#
-## encrypt the initial num_initial_blocks blocks and apply ghash on the ciphertext
-## r10, r11, r12, rax are clobbered
-## arg1, arg2, arg3, arg4 are used as pointers only, not modified
-
-.macro INITIAL_BLOCKS_AVX REP num_initial_blocks T1 T2 T3 T4 T5 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T6 T_key ENC_DEC
- i = (8-\num_initial_blocks)
- setreg
- vmovdqu AadHash(arg2), reg_i
-
- # start AES for num_initial_blocks blocks
- vmovdqu CurCount(arg2), \CTR
-
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, reg_i
- vpshufb SHUF_MASK(%rip), reg_i, reg_i # perform a 16Byte swap
- i = (i+1)
- setreg
-.endr
-
- vmovdqa (arg1), \T_key
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vpxor \T_key, reg_i, reg_i
- i = (i+1)
- setreg
-.endr
-
- j = 1
- setreg
-.rep \REP
- vmovdqa 16*j(arg1), \T_key
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vaesenc \T_key, reg_i, reg_i
- i = (i+1)
- setreg
-.endr
-
- j = (j+1)
- setreg
-.endr
-
- vmovdqa 16*j(arg1), \T_key
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vaesenclast \T_key, reg_i, reg_i
- i = (i+1)
- setreg
-.endr
-
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vmovdqu (arg4, %r11), \T1
- vpxor \T1, reg_i, reg_i
- vmovdqu reg_i, (arg3 , %r11) # write back ciphertext for num_initial_blocks blocks
- add $16, %r11
-.if \ENC_DEC == DEC
- vmovdqa \T1, reg_i
-.endif
- vpshufb SHUF_MASK(%rip), reg_i, reg_i # prepare ciphertext for GHASH computations
- i = (i+1)
- setreg
-.endr
-
-
- i = (8-\num_initial_blocks)
- j = (9-\num_initial_blocks)
- setreg
-
-.rep \num_initial_blocks
- vpxor reg_i, reg_j, reg_j
- GHASH_MUL_AVX reg_j, \T2, \T1, \T3, \T4, \T5, \T6 # apply GHASH on num_initial_blocks blocks
- i = (i+1)
- j = (j+1)
- setreg
-.endr
- # XMM8 has the combined result here
-
- vmovdqa \XMM8, TMP1(%rsp)
- vmovdqa \XMM8, \T3
-
- cmp $128, %r13
- jl .L_initial_blocks_done\@ # no need for precomputed constants
-
-###############################################################################
-# Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM1
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM2
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM3
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM4
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM5
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM6
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM7
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM8
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-
- vmovdqa (arg1), \T_key
- vpxor \T_key, \XMM1, \XMM1
- vpxor \T_key, \XMM2, \XMM2
- vpxor \T_key, \XMM3, \XMM3
- vpxor \T_key, \XMM4, \XMM4
- vpxor \T_key, \XMM5, \XMM5
- vpxor \T_key, \XMM6, \XMM6
- vpxor \T_key, \XMM7, \XMM7
- vpxor \T_key, \XMM8, \XMM8
-
- i = 1
- setreg
-.rep \REP # do REP rounds
- vmovdqa 16*i(arg1), \T_key
- vaesenc \T_key, \XMM1, \XMM1
- vaesenc \T_key, \XMM2, \XMM2
- vaesenc \T_key, \XMM3, \XMM3
- vaesenc \T_key, \XMM4, \XMM4
- vaesenc \T_key, \XMM5, \XMM5
- vaesenc \T_key, \XMM6, \XMM6
- vaesenc \T_key, \XMM7, \XMM7
- vaesenc \T_key, \XMM8, \XMM8
- i = (i+1)
- setreg
-.endr
-
- vmovdqa 16*i(arg1), \T_key
- vaesenclast \T_key, \XMM1, \XMM1
- vaesenclast \T_key, \XMM2, \XMM2
- vaesenclast \T_key, \XMM3, \XMM3
- vaesenclast \T_key, \XMM4, \XMM4
- vaesenclast \T_key, \XMM5, \XMM5
- vaesenclast \T_key, \XMM6, \XMM6
- vaesenclast \T_key, \XMM7, \XMM7
- vaesenclast \T_key, \XMM8, \XMM8
-
- vmovdqu (arg4, %r11), \T1
- vpxor \T1, \XMM1, \XMM1
- vmovdqu \XMM1, (arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM1
- .endif
-
- vmovdqu 16*1(arg4, %r11), \T1
- vpxor \T1, \XMM2, \XMM2
- vmovdqu \XMM2, 16*1(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM2
- .endif
-
- vmovdqu 16*2(arg4, %r11), \T1
- vpxor \T1, \XMM3, \XMM3
- vmovdqu \XMM3, 16*2(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM3
- .endif
-
- vmovdqu 16*3(arg4, %r11), \T1
- vpxor \T1, \XMM4, \XMM4
- vmovdqu \XMM4, 16*3(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM4
- .endif
-
- vmovdqu 16*4(arg4, %r11), \T1
- vpxor \T1, \XMM5, \XMM5
- vmovdqu \XMM5, 16*4(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM5
- .endif
-
- vmovdqu 16*5(arg4, %r11), \T1
- vpxor \T1, \XMM6, \XMM6
- vmovdqu \XMM6, 16*5(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM6
- .endif
-
- vmovdqu 16*6(arg4, %r11), \T1
- vpxor \T1, \XMM7, \XMM7
- vmovdqu \XMM7, 16*6(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM7
- .endif
-
- vmovdqu 16*7(arg4, %r11), \T1
- vpxor \T1, \XMM8, \XMM8
- vmovdqu \XMM8, 16*7(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM8
- .endif
-
- add $128, %r11
-
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
- vpxor TMP1(%rsp), \XMM1, \XMM1 # combine GHASHed value with the corresponding ciphertext
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-
-###############################################################################
-
-.L_initial_blocks_done\@:
-
-.endm
-
-# encrypt 8 blocks at a time
-# ghash the 8 previously encrypted ciphertext blocks
-# arg1, arg2, arg3, arg4 are used as pointers only, not modified
-# r11 is the data offset value
-.macro GHASH_8_ENCRYPT_8_PARALLEL_AVX REP T1 T2 T3 T4 T5 T6 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T7 loop_idx ENC_DEC
-
- vmovdqa \XMM1, \T2
- vmovdqa \XMM2, TMP2(%rsp)
- vmovdqa \XMM3, TMP3(%rsp)
- vmovdqa \XMM4, TMP4(%rsp)
- vmovdqa \XMM5, TMP5(%rsp)
- vmovdqa \XMM6, TMP6(%rsp)
- vmovdqa \XMM7, TMP7(%rsp)
- vmovdqa \XMM8, TMP8(%rsp)
-
-.if \loop_idx == in_order
- vpaddd ONE(%rip), \CTR, \XMM1 # INCR CNT
- vpaddd ONE(%rip), \XMM1, \XMM2
- vpaddd ONE(%rip), \XMM2, \XMM3
- vpaddd ONE(%rip), \XMM3, \XMM4
- vpaddd ONE(%rip), \XMM4, \XMM5
- vpaddd ONE(%rip), \XMM5, \XMM6
- vpaddd ONE(%rip), \XMM6, \XMM7
- vpaddd ONE(%rip), \XMM7, \XMM8
- vmovdqa \XMM8, \CTR
-
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-.else
- vpaddd ONEf(%rip), \CTR, \XMM1 # INCR CNT
- vpaddd ONEf(%rip), \XMM1, \XMM2
- vpaddd ONEf(%rip), \XMM2, \XMM3
- vpaddd ONEf(%rip), \XMM3, \XMM4
- vpaddd ONEf(%rip), \XMM4, \XMM5
- vpaddd ONEf(%rip), \XMM5, \XMM6
- vpaddd ONEf(%rip), \XMM6, \XMM7
- vpaddd ONEf(%rip), \XMM7, \XMM8
- vmovdqa \XMM8, \CTR
-.endif
-
-
- #######################################################################
-
- vmovdqu (arg1), \T1
- vpxor \T1, \XMM1, \XMM1
- vpxor \T1, \XMM2, \XMM2
- vpxor \T1, \XMM3, \XMM3
- vpxor \T1, \XMM4, \XMM4
- vpxor \T1, \XMM5, \XMM5
- vpxor \T1, \XMM6, \XMM6
- vpxor \T1, \XMM7, \XMM7
- vpxor \T1, \XMM8, \XMM8
-
- #######################################################################
-
-
-
-
-
- vmovdqu 16*1(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqu 16*2(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
-
- #######################################################################
-
- vmovdqu HashKey_8(arg2), \T5
- vpclmulqdq $0x11, \T5, \T2, \T4 # T4 = a1*b1
- vpclmulqdq $0x00, \T5, \T2, \T7 # T7 = a0*b0
-
- vpshufd $0b01001110, \T2, \T6
- vpxor \T2, \T6, \T6
-
- vmovdqu HashKey_8_k(arg2), \T5
- vpclmulqdq $0x00, \T5, \T6, \T6
-
- vmovdqu 16*3(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP2(%rsp), \T1
- vmovdqu HashKey_7(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_7_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*4(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- #######################################################################
-
- vmovdqa TMP3(%rsp), \T1
- vmovdqu HashKey_6(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_6_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*5(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP4(%rsp), \T1
- vmovdqu HashKey_5(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_5_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*6(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
-
- vmovdqa TMP5(%rsp), \T1
- vmovdqu HashKey_4(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_4_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*7(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP6(%rsp), \T1
- vmovdqu HashKey_3(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_3_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
-
- vmovdqu 16*8(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP7(%rsp), \T1
- vmovdqu HashKey_2(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_2_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
- #######################################################################
-
- vmovdqu 16*9(arg1), \T5
- vaesenc \T5, \XMM1, \XMM1
- vaesenc \T5, \XMM2, \XMM2
- vaesenc \T5, \XMM3, \XMM3
- vaesenc \T5, \XMM4, \XMM4
- vaesenc \T5, \XMM5, \XMM5
- vaesenc \T5, \XMM6, \XMM6
- vaesenc \T5, \XMM7, \XMM7
- vaesenc \T5, \XMM8, \XMM8
-
- vmovdqa TMP8(%rsp), \T1
- vmovdqu HashKey(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpshufd $0b01001110, \T1, \T3
- vpxor \T1, \T3, \T3
- vmovdqu HashKey_k(arg2), \T5
- vpclmulqdq $0x10, \T5, \T3, \T3
- vpxor \T3, \T6, \T6
-
- vpxor \T4, \T6, \T6
- vpxor \T7, \T6, \T6
-
- vmovdqu 16*10(arg1), \T5
-
- i = 11
- setreg
-.rep (\REP-9)
-
- vaesenc \T5, \XMM1, \XMM1
- vaesenc \T5, \XMM2, \XMM2
- vaesenc \T5, \XMM3, \XMM3
- vaesenc \T5, \XMM4, \XMM4
- vaesenc \T5, \XMM5, \XMM5
- vaesenc \T5, \XMM6, \XMM6
- vaesenc \T5, \XMM7, \XMM7
- vaesenc \T5, \XMM8, \XMM8
-
- vmovdqu 16*i(arg1), \T5
- i = i + 1
- setreg
-.endr
-
- i = 0
- j = 1
- setreg
-.rep 8
- vpxor 16*i(arg4, %r11), \T5, \T2
- .if \ENC_DEC == ENC
- vaesenclast \T2, reg_j, reg_j
- .else
- vaesenclast \T2, reg_j, \T3
- vmovdqu 16*i(arg4, %r11), reg_j
- vmovdqu \T3, 16*i(arg3, %r11)
- .endif
- i = (i+1)
- j = (j+1)
- setreg
-.endr
- #######################################################################
-
-
- vpslldq $8, \T6, \T3 # shift-L T3 2 DWs
- vpsrldq $8, \T6, \T6 # shift-R T2 2 DWs
- vpxor \T3, \T7, \T7
- vpxor \T4, \T6, \T6 # accumulate the results in T6:T7
-
-
-
- #######################################################################
- #first phase of the reduction
- #######################################################################
- vpslld $31, \T7, \T2 # packed right shifting << 31
- vpslld $30, \T7, \T3 # packed right shifting shift << 30
- vpslld $25, \T7, \T4 # packed right shifting shift << 25
-
- vpxor \T3, \T2, \T2 # xor the shifted versions
- vpxor \T4, \T2, \T2
-
- vpsrldq $4, \T2, \T1 # shift-R T1 1 DW
-
- vpslldq $12, \T2, \T2 # shift-L T2 3 DWs
- vpxor \T2, \T7, \T7 # first phase of the reduction complete
- #######################################################################
- .if \ENC_DEC == ENC
- vmovdqu \XMM1, 16*0(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM2, 16*1(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM3, 16*2(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM4, 16*3(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM5, 16*4(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM6, 16*5(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM7, 16*6(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM8, 16*7(arg3,%r11) # Write to the Ciphertext buffer
- .endif
-
- #######################################################################
- #second phase of the reduction
- vpsrld $1, \T7, \T2 # packed left shifting >> 1
- vpsrld $2, \T7, \T3 # packed left shifting >> 2
- vpsrld $7, \T7, \T4 # packed left shifting >> 7
- vpxor \T3, \T2, \T2 # xor the shifted versions
- vpxor \T4, \T2, \T2
-
- vpxor \T1, \T2, \T2
- vpxor \T2, \T7, \T7
- vpxor \T7, \T6, \T6 # the result is in T6
- #######################################################################
-
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-
-
- vpxor \T6, \XMM1, \XMM1
-
-
-
-.endm
-
-
-# GHASH the last 4 ciphertext blocks.
-.macro GHASH_LAST_8_AVX T1 T2 T3 T4 T5 T6 T7 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8
-
- ## Karatsuba Method
-
-
- vpshufd $0b01001110, \XMM1, \T2
- vpxor \XMM1, \T2, \T2
- vmovdqu HashKey_8(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM1, \T6
- vpclmulqdq $0x00, \T5, \XMM1, \T7
-
- vmovdqu HashKey_8_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM2, \T2
- vpxor \XMM2, \T2, \T2
- vmovdqu HashKey_7(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM2, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM2, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_7_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM3, \T2
- vpxor \XMM3, \T2, \T2
- vmovdqu HashKey_6(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM3, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM3, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_6_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM4, \T2
- vpxor \XMM4, \T2, \T2
- vmovdqu HashKey_5(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM4, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM4, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_5_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM5, \T2
- vpxor \XMM5, \T2, \T2
- vmovdqu HashKey_4(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM5, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM5, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_4_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM6, \T2
- vpxor \XMM6, \T2, \T2
- vmovdqu HashKey_3(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM6, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM6, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_3_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM7, \T2
- vpxor \XMM7, \T2, \T2
- vmovdqu HashKey_2(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM7, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM7, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_2_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vpshufd $0b01001110, \XMM8, \T2
- vpxor \XMM8, \T2, \T2
- vmovdqu HashKey(arg2), \T5
- vpclmulqdq $0x11, \T5, \XMM8, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM8, \T4
- vpxor \T4, \T7, \T7
-
- vmovdqu HashKey_k(arg2), \T3
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
- vpxor \T6, \XMM1, \XMM1
- vpxor \T7, \XMM1, \T2
-
-
-
-
- vpslldq $8, \T2, \T4
- vpsrldq $8, \T2, \T2
-
- vpxor \T4, \T7, \T7
- vpxor \T2, \T6, \T6 # <T6:T7> holds the result of
- # the accumulated carry-less multiplications
-
- #######################################################################
- #first phase of the reduction
- vpslld $31, \T7, \T2 # packed right shifting << 31
- vpslld $30, \T7, \T3 # packed right shifting shift << 30
- vpslld $25, \T7, \T4 # packed right shifting shift << 25
-
- vpxor \T3, \T2, \T2 # xor the shifted versions
- vpxor \T4, \T2, \T2
-
- vpsrldq $4, \T2, \T1 # shift-R T1 1 DW
-
- vpslldq $12, \T2, \T2 # shift-L T2 3 DWs
- vpxor \T2, \T7, \T7 # first phase of the reduction complete
- #######################################################################
-
-
- #second phase of the reduction
- vpsrld $1, \T7, \T2 # packed left shifting >> 1
- vpsrld $2, \T7, \T3 # packed left shifting >> 2
- vpsrld $7, \T7, \T4 # packed left shifting >> 7
- vpxor \T3, \T2, \T2 # xor the shifted versions
- vpxor \T4, \T2, \T2
-
- vpxor \T1, \T2, \T2
- vpxor \T2, \T7, \T7
- vpxor \T7, \T6, \T6 # the result is in T6
-
-.endm
-
-#############################################################
-#void aesni_gcm_precomp_avx_gen2
-# (gcm_data *my_ctx_data,
-# gcm_context_data *data,
-# u8 *hash_subkey# /* H, the Hash sub key input. Data starts on a 16-byte boundary. */
-# u8 *iv, /* Pre-counter block j0: 4 byte salt
-# (from Security Association) concatenated with 8 byte
-# Initialisation Vector (from IPSec ESP Payload)
-# concatenated with 0x00000001. 16-byte aligned pointer. */
-# const u8 *aad, /* Additional Authentication Data (AAD)*/
-# u64 aad_len) /* Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 Bytes */
-#############################################################
-SYM_FUNC_START(aesni_gcm_init_avx_gen2)
- FUNC_SAVE
- INIT GHASH_MUL_AVX, PRECOMPUTE_AVX
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_init_avx_gen2)
-
-###############################################################################
-#void aesni_gcm_enc_update_avx_gen2(
-# gcm_data *my_ctx_data, /* aligned to 16 Bytes */
-# gcm_context_data *data,
-# u8 *out, /* Ciphertext output. Encrypt in-place is allowed. */
-# const u8 *in, /* Plaintext input */
-# u64 plaintext_len) /* Length of data in Bytes for encryption. */
-###############################################################################
-SYM_FUNC_START(aesni_gcm_enc_update_avx_gen2)
- FUNC_SAVE
- mov keysize, %eax
- cmp $32, %eax
- je key_256_enc_update
- cmp $16, %eax
- je key_128_enc_update
- # must be 192
- GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, ENC, 11
- FUNC_RESTORE
- RET
-key_128_enc_update:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, ENC, 9
- FUNC_RESTORE
- RET
-key_256_enc_update:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, ENC, 13
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_enc_update_avx_gen2)
-
-###############################################################################
-#void aesni_gcm_dec_update_avx_gen2(
-# gcm_data *my_ctx_data, /* aligned to 16 Bytes */
-# gcm_context_data *data,
-# u8 *out, /* Plaintext output. Decrypt in-place is allowed. */
-# const u8 *in, /* Ciphertext input */
-# u64 plaintext_len) /* Length of data in Bytes for encryption. */
-###############################################################################
-SYM_FUNC_START(aesni_gcm_dec_update_avx_gen2)
- FUNC_SAVE
- mov keysize,%eax
- cmp $32, %eax
- je key_256_dec_update
- cmp $16, %eax
- je key_128_dec_update
- # must be 192
- GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, DEC, 11
- FUNC_RESTORE
- RET
-key_128_dec_update:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, DEC, 9
- FUNC_RESTORE
- RET
-key_256_dec_update:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, DEC, 13
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_dec_update_avx_gen2)
-
-###############################################################################
-#void aesni_gcm_finalize_avx_gen2(
-# gcm_data *my_ctx_data, /* aligned to 16 Bytes */
-# gcm_context_data *data,
-# u8 *auth_tag, /* Authenticated Tag output. */
-# u64 auth_tag_len)# /* Authenticated Tag Length in bytes.
-# Valid values are 16 (most likely), 12 or 8. */
-###############################################################################
-SYM_FUNC_START(aesni_gcm_finalize_avx_gen2)
- FUNC_SAVE
- mov keysize,%eax
- cmp $32, %eax
- je key_256_finalize
- cmp $16, %eax
- je key_128_finalize
- # must be 192
- GCM_COMPLETE GHASH_MUL_AVX, 11, arg3, arg4
- FUNC_RESTORE
- RET
-key_128_finalize:
- GCM_COMPLETE GHASH_MUL_AVX, 9, arg3, arg4
- FUNC_RESTORE
- RET
-key_256_finalize:
- GCM_COMPLETE GHASH_MUL_AVX, 13, arg3, arg4
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_finalize_avx_gen2)
-
-###############################################################################
-# GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0)
-# Input: A and B (128-bits each, bit-reflected)
-# Output: C = A*B*x mod poly, (i.e. >>1 )
-# To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input
-# GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly.
-###############################################################################
-.macro GHASH_MUL_AVX2 GH HK T1 T2 T3 T4 T5
-
- vpclmulqdq $0x11,\HK,\GH,\T1 # T1 = a1*b1
- vpclmulqdq $0x00,\HK,\GH,\T2 # T2 = a0*b0
- vpclmulqdq $0x01,\HK,\GH,\T3 # T3 = a1*b0
- vpclmulqdq $0x10,\HK,\GH,\GH # GH = a0*b1
- vpxor \T3, \GH, \GH
-
-
- vpsrldq $8 , \GH, \T3 # shift-R GH 2 DWs
- vpslldq $8 , \GH, \GH # shift-L GH 2 DWs
-
- vpxor \T3, \T1, \T1
- vpxor \T2, \GH, \GH
-
- #######################################################################
- #first phase of the reduction
- vmovdqa POLY2(%rip), \T3
-
- vpclmulqdq $0x01, \GH, \T3, \T2
- vpslldq $8, \T2, \T2 # shift-L T2 2 DWs
-
- vpxor \T2, \GH, \GH # first phase of the reduction complete
- #######################################################################
- #second phase of the reduction
- vpclmulqdq $0x00, \GH, \T3, \T2
- vpsrldq $4, \T2, \T2 # shift-R T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
-
- vpclmulqdq $0x10, \GH, \T3, \GH
- vpslldq $4, \GH, \GH # shift-L GH 1 DW (Shift-L 1-DW to obtain result with no shifts)
-
- vpxor \T2, \GH, \GH # second phase of the reduction complete
- #######################################################################
- vpxor \T1, \GH, \GH # the result is in GH
-
-
-.endm
-
-.macro PRECOMPUTE_AVX2 HK T1 T2 T3 T4 T5 T6
-
- # Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
- vmovdqa \HK, \T5
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^2<<1 mod poly
- vmovdqu \T5, HashKey_2(arg2) # [HashKey_2] = HashKey^2<<1 mod poly
-
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^3<<1 mod poly
- vmovdqu \T5, HashKey_3(arg2)
-
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^4<<1 mod poly
- vmovdqu \T5, HashKey_4(arg2)
-
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^5<<1 mod poly
- vmovdqu \T5, HashKey_5(arg2)
-
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^6<<1 mod poly
- vmovdqu \T5, HashKey_6(arg2)
-
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^7<<1 mod poly
- vmovdqu \T5, HashKey_7(arg2)
-
- GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2 # T5 = HashKey^8<<1 mod poly
- vmovdqu \T5, HashKey_8(arg2)
-
-.endm
-
-## if a = number of total plaintext bytes
-## b = floor(a/16)
-## num_initial_blocks = b mod 4#
-## encrypt the initial num_initial_blocks blocks and apply ghash on the ciphertext
-## r10, r11, r12, rax are clobbered
-## arg1, arg2, arg3, arg4 are used as pointers only, not modified
-
-.macro INITIAL_BLOCKS_AVX2 REP num_initial_blocks T1 T2 T3 T4 T5 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T6 T_key ENC_DEC VER
- i = (8-\num_initial_blocks)
- setreg
- vmovdqu AadHash(arg2), reg_i
-
- # start AES for num_initial_blocks blocks
- vmovdqu CurCount(arg2), \CTR
-
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, reg_i
- vpshufb SHUF_MASK(%rip), reg_i, reg_i # perform a 16Byte swap
- i = (i+1)
- setreg
-.endr
-
- vmovdqa (arg1), \T_key
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vpxor \T_key, reg_i, reg_i
- i = (i+1)
- setreg
-.endr
-
- j = 1
- setreg
-.rep \REP
- vmovdqa 16*j(arg1), \T_key
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vaesenc \T_key, reg_i, reg_i
- i = (i+1)
- setreg
-.endr
-
- j = (j+1)
- setreg
-.endr
-
-
- vmovdqa 16*j(arg1), \T_key
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vaesenclast \T_key, reg_i, reg_i
- i = (i+1)
- setreg
-.endr
-
- i = (9-\num_initial_blocks)
- setreg
-.rep \num_initial_blocks
- vmovdqu (arg4, %r11), \T1
- vpxor \T1, reg_i, reg_i
- vmovdqu reg_i, (arg3 , %r11) # write back ciphertext for
- # num_initial_blocks blocks
- add $16, %r11
-.if \ENC_DEC == DEC
- vmovdqa \T1, reg_i
-.endif
- vpshufb SHUF_MASK(%rip), reg_i, reg_i # prepare ciphertext for GHASH computations
- i = (i+1)
- setreg
-.endr
-
-
- i = (8-\num_initial_blocks)
- j = (9-\num_initial_blocks)
- setreg
-
-.rep \num_initial_blocks
- vpxor reg_i, reg_j, reg_j
- GHASH_MUL_AVX2 reg_j, \T2, \T1, \T3, \T4, \T5, \T6 # apply GHASH on num_initial_blocks blocks
- i = (i+1)
- j = (j+1)
- setreg
-.endr
- # XMM8 has the combined result here
-
- vmovdqa \XMM8, TMP1(%rsp)
- vmovdqa \XMM8, \T3
-
- cmp $128, %r13
- jl .L_initial_blocks_done\@ # no need for precomputed constants
-
-###############################################################################
-# Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM1
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM2
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM3
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM4
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM5
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM6
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM7
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
-
- vpaddd ONE(%rip), \CTR, \CTR # INCR Y0
- vmovdqa \CTR, \XMM8
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-
- vmovdqa (arg1), \T_key
- vpxor \T_key, \XMM1, \XMM1
- vpxor \T_key, \XMM2, \XMM2
- vpxor \T_key, \XMM3, \XMM3
- vpxor \T_key, \XMM4, \XMM4
- vpxor \T_key, \XMM5, \XMM5
- vpxor \T_key, \XMM6, \XMM6
- vpxor \T_key, \XMM7, \XMM7
- vpxor \T_key, \XMM8, \XMM8
-
- i = 1
- setreg
-.rep \REP # do REP rounds
- vmovdqa 16*i(arg1), \T_key
- vaesenc \T_key, \XMM1, \XMM1
- vaesenc \T_key, \XMM2, \XMM2
- vaesenc \T_key, \XMM3, \XMM3
- vaesenc \T_key, \XMM4, \XMM4
- vaesenc \T_key, \XMM5, \XMM5
- vaesenc \T_key, \XMM6, \XMM6
- vaesenc \T_key, \XMM7, \XMM7
- vaesenc \T_key, \XMM8, \XMM8
- i = (i+1)
- setreg
-.endr
-
-
- vmovdqa 16*i(arg1), \T_key
- vaesenclast \T_key, \XMM1, \XMM1
- vaesenclast \T_key, \XMM2, \XMM2
- vaesenclast \T_key, \XMM3, \XMM3
- vaesenclast \T_key, \XMM4, \XMM4
- vaesenclast \T_key, \XMM5, \XMM5
- vaesenclast \T_key, \XMM6, \XMM6
- vaesenclast \T_key, \XMM7, \XMM7
- vaesenclast \T_key, \XMM8, \XMM8
-
- vmovdqu (arg4, %r11), \T1
- vpxor \T1, \XMM1, \XMM1
- vmovdqu \XMM1, (arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM1
- .endif
-
- vmovdqu 16*1(arg4, %r11), \T1
- vpxor \T1, \XMM2, \XMM2
- vmovdqu \XMM2, 16*1(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM2
- .endif
-
- vmovdqu 16*2(arg4, %r11), \T1
- vpxor \T1, \XMM3, \XMM3
- vmovdqu \XMM3, 16*2(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM3
- .endif
-
- vmovdqu 16*3(arg4, %r11), \T1
- vpxor \T1, \XMM4, \XMM4
- vmovdqu \XMM4, 16*3(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM4
- .endif
-
- vmovdqu 16*4(arg4, %r11), \T1
- vpxor \T1, \XMM5, \XMM5
- vmovdqu \XMM5, 16*4(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM5
- .endif
-
- vmovdqu 16*5(arg4, %r11), \T1
- vpxor \T1, \XMM6, \XMM6
- vmovdqu \XMM6, 16*5(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM6
- .endif
-
- vmovdqu 16*6(arg4, %r11), \T1
- vpxor \T1, \XMM7, \XMM7
- vmovdqu \XMM7, 16*6(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM7
- .endif
-
- vmovdqu 16*7(arg4, %r11), \T1
- vpxor \T1, \XMM8, \XMM8
- vmovdqu \XMM8, 16*7(arg3 , %r11)
- .if \ENC_DEC == DEC
- vmovdqa \T1, \XMM8
- .endif
-
- add $128, %r11
-
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
- vpxor TMP1(%rsp), \XMM1, \XMM1 # combine GHASHed value with
- # the corresponding ciphertext
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-
-###############################################################################
-
-.L_initial_blocks_done\@:
-
-
-.endm
-
-
-
-# encrypt 8 blocks at a time
-# ghash the 8 previously encrypted ciphertext blocks
-# arg1, arg2, arg3, arg4 are used as pointers only, not modified
-# r11 is the data offset value
-.macro GHASH_8_ENCRYPT_8_PARALLEL_AVX2 REP T1 T2 T3 T4 T5 T6 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T7 loop_idx ENC_DEC
-
- vmovdqa \XMM1, \T2
- vmovdqa \XMM2, TMP2(%rsp)
- vmovdqa \XMM3, TMP3(%rsp)
- vmovdqa \XMM4, TMP4(%rsp)
- vmovdqa \XMM5, TMP5(%rsp)
- vmovdqa \XMM6, TMP6(%rsp)
- vmovdqa \XMM7, TMP7(%rsp)
- vmovdqa \XMM8, TMP8(%rsp)
-
-.if \loop_idx == in_order
- vpaddd ONE(%rip), \CTR, \XMM1 # INCR CNT
- vpaddd ONE(%rip), \XMM1, \XMM2
- vpaddd ONE(%rip), \XMM2, \XMM3
- vpaddd ONE(%rip), \XMM3, \XMM4
- vpaddd ONE(%rip), \XMM4, \XMM5
- vpaddd ONE(%rip), \XMM5, \XMM6
- vpaddd ONE(%rip), \XMM6, \XMM7
- vpaddd ONE(%rip), \XMM7, \XMM8
- vmovdqa \XMM8, \CTR
-
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-.else
- vpaddd ONEf(%rip), \CTR, \XMM1 # INCR CNT
- vpaddd ONEf(%rip), \XMM1, \XMM2
- vpaddd ONEf(%rip), \XMM2, \XMM3
- vpaddd ONEf(%rip), \XMM3, \XMM4
- vpaddd ONEf(%rip), \XMM4, \XMM5
- vpaddd ONEf(%rip), \XMM5, \XMM6
- vpaddd ONEf(%rip), \XMM6, \XMM7
- vpaddd ONEf(%rip), \XMM7, \XMM8
- vmovdqa \XMM8, \CTR
-.endif
-
-
- #######################################################################
-
- vmovdqu (arg1), \T1
- vpxor \T1, \XMM1, \XMM1
- vpxor \T1, \XMM2, \XMM2
- vpxor \T1, \XMM3, \XMM3
- vpxor \T1, \XMM4, \XMM4
- vpxor \T1, \XMM5, \XMM5
- vpxor \T1, \XMM6, \XMM6
- vpxor \T1, \XMM7, \XMM7
- vpxor \T1, \XMM8, \XMM8
-
- #######################################################################
-
-
-
-
-
- vmovdqu 16*1(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqu 16*2(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
-
- #######################################################################
-
- vmovdqu HashKey_8(arg2), \T5
- vpclmulqdq $0x11, \T5, \T2, \T4 # T4 = a1*b1
- vpclmulqdq $0x00, \T5, \T2, \T7 # T7 = a0*b0
- vpclmulqdq $0x01, \T5, \T2, \T6 # T6 = a1*b0
- vpclmulqdq $0x10, \T5, \T2, \T5 # T5 = a0*b1
- vpxor \T5, \T6, \T6
-
- vmovdqu 16*3(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP2(%rsp), \T1
- vmovdqu HashKey_7(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*4(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- #######################################################################
-
- vmovdqa TMP3(%rsp), \T1
- vmovdqu HashKey_6(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*5(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP4(%rsp), \T1
- vmovdqu HashKey_5(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*6(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
-
- vmovdqa TMP5(%rsp), \T1
- vmovdqu HashKey_4(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*7(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP6(%rsp), \T1
- vmovdqu HashKey_3(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vmovdqu 16*8(arg1), \T1
- vaesenc \T1, \XMM1, \XMM1
- vaesenc \T1, \XMM2, \XMM2
- vaesenc \T1, \XMM3, \XMM3
- vaesenc \T1, \XMM4, \XMM4
- vaesenc \T1, \XMM5, \XMM5
- vaesenc \T1, \XMM6, \XMM6
- vaesenc \T1, \XMM7, \XMM7
- vaesenc \T1, \XMM8, \XMM8
-
- vmovdqa TMP7(%rsp), \T1
- vmovdqu HashKey_2(arg2), \T5
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T4
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
-
- #######################################################################
-
- vmovdqu 16*9(arg1), \T5
- vaesenc \T5, \XMM1, \XMM1
- vaesenc \T5, \XMM2, \XMM2
- vaesenc \T5, \XMM3, \XMM3
- vaesenc \T5, \XMM4, \XMM4
- vaesenc \T5, \XMM5, \XMM5
- vaesenc \T5, \XMM6, \XMM6
- vaesenc \T5, \XMM7, \XMM7
- vaesenc \T5, \XMM8, \XMM8
-
- vmovdqa TMP8(%rsp), \T1
- vmovdqu HashKey(arg2), \T5
-
- vpclmulqdq $0x00, \T5, \T1, \T3
- vpxor \T3, \T7, \T7
-
- vpclmulqdq $0x01, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x10, \T5, \T1, \T3
- vpxor \T3, \T6, \T6
-
- vpclmulqdq $0x11, \T5, \T1, \T3
- vpxor \T3, \T4, \T1
-
-
- vmovdqu 16*10(arg1), \T5
-
- i = 11
- setreg
-.rep (\REP-9)
- vaesenc \T5, \XMM1, \XMM1
- vaesenc \T5, \XMM2, \XMM2
- vaesenc \T5, \XMM3, \XMM3
- vaesenc \T5, \XMM4, \XMM4
- vaesenc \T5, \XMM5, \XMM5
- vaesenc \T5, \XMM6, \XMM6
- vaesenc \T5, \XMM7, \XMM7
- vaesenc \T5, \XMM8, \XMM8
-
- vmovdqu 16*i(arg1), \T5
- i = i + 1
- setreg
-.endr
-
- i = 0
- j = 1
- setreg
-.rep 8
- vpxor 16*i(arg4, %r11), \T5, \T2
- .if \ENC_DEC == ENC
- vaesenclast \T2, reg_j, reg_j
- .else
- vaesenclast \T2, reg_j, \T3
- vmovdqu 16*i(arg4, %r11), reg_j
- vmovdqu \T3, 16*i(arg3, %r11)
- .endif
- i = (i+1)
- j = (j+1)
- setreg
-.endr
- #######################################################################
-
-
- vpslldq $8, \T6, \T3 # shift-L T3 2 DWs
- vpsrldq $8, \T6, \T6 # shift-R T2 2 DWs
- vpxor \T3, \T7, \T7
- vpxor \T6, \T1, \T1 # accumulate the results in T1:T7
-
-
-
- #######################################################################
- #first phase of the reduction
- vmovdqa POLY2(%rip), \T3
-
- vpclmulqdq $0x01, \T7, \T3, \T2
- vpslldq $8, \T2, \T2 # shift-L xmm2 2 DWs
-
- vpxor \T2, \T7, \T7 # first phase of the reduction complete
- #######################################################################
- .if \ENC_DEC == ENC
- vmovdqu \XMM1, 16*0(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM2, 16*1(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM3, 16*2(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM4, 16*3(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM5, 16*4(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM6, 16*5(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM7, 16*6(arg3,%r11) # Write to the Ciphertext buffer
- vmovdqu \XMM8, 16*7(arg3,%r11) # Write to the Ciphertext buffer
- .endif
-
- #######################################################################
- #second phase of the reduction
- vpclmulqdq $0x00, \T7, \T3, \T2
- vpsrldq $4, \T2, \T2 # shift-R xmm2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
-
- vpclmulqdq $0x10, \T7, \T3, \T4
- vpslldq $4, \T4, \T4 # shift-L xmm0 1 DW (Shift-L 1-DW to obtain result with no shifts)
-
- vpxor \T2, \T4, \T4 # second phase of the reduction complete
- #######################################################################
- vpxor \T4, \T1, \T1 # the result is in T1
-
- vpshufb SHUF_MASK(%rip), \XMM1, \XMM1 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM2, \XMM2 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM3, \XMM3 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM4, \XMM4 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM5, \XMM5 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM6, \XMM6 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM7, \XMM7 # perform a 16Byte swap
- vpshufb SHUF_MASK(%rip), \XMM8, \XMM8 # perform a 16Byte swap
-
-
- vpxor \T1, \XMM1, \XMM1
-
-
-
-.endm
-
-
-# GHASH the last 4 ciphertext blocks.
-.macro GHASH_LAST_8_AVX2 T1 T2 T3 T4 T5 T6 T7 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8
-
- ## Karatsuba Method
-
- vmovdqu HashKey_8(arg2), \T5
-
- vpshufd $0b01001110, \XMM1, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM1, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM1, \T6
- vpclmulqdq $0x00, \T5, \XMM1, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \XMM1
-
- ######################
-
- vmovdqu HashKey_7(arg2), \T5
- vpshufd $0b01001110, \XMM2, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM2, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM2, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM2, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vmovdqu HashKey_6(arg2), \T5
- vpshufd $0b01001110, \XMM3, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM3, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM3, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM3, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vmovdqu HashKey_5(arg2), \T5
- vpshufd $0b01001110, \XMM4, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM4, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM4, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM4, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vmovdqu HashKey_4(arg2), \T5
- vpshufd $0b01001110, \XMM5, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM5, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM5, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM5, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vmovdqu HashKey_3(arg2), \T5
- vpshufd $0b01001110, \XMM6, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM6, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM6, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM6, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vmovdqu HashKey_2(arg2), \T5
- vpshufd $0b01001110, \XMM7, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM7, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM7, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM7, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
-
- ######################
-
- vmovdqu HashKey(arg2), \T5
- vpshufd $0b01001110, \XMM8, \T2
- vpshufd $0b01001110, \T5, \T3
- vpxor \XMM8, \T2, \T2
- vpxor \T5, \T3, \T3
-
- vpclmulqdq $0x11, \T5, \XMM8, \T4
- vpxor \T4, \T6, \T6
-
- vpclmulqdq $0x00, \T5, \XMM8, \T4
- vpxor \T4, \T7, \T7
-
- vpclmulqdq $0x00, \T3, \T2, \T2
-
- vpxor \T2, \XMM1, \XMM1
- vpxor \T6, \XMM1, \XMM1
- vpxor \T7, \XMM1, \T2
-
-
-
-
- vpslldq $8, \T2, \T4
- vpsrldq $8, \T2, \T2
-
- vpxor \T4, \T7, \T7
- vpxor \T2, \T6, \T6 # <T6:T7> holds the result of the
- # accumulated carry-less multiplications
-
- #######################################################################
- #first phase of the reduction
- vmovdqa POLY2(%rip), \T3
-
- vpclmulqdq $0x01, \T7, \T3, \T2
- vpslldq $8, \T2, \T2 # shift-L xmm2 2 DWs
-
- vpxor \T2, \T7, \T7 # first phase of the reduction complete
- #######################################################################
-
-
- #second phase of the reduction
- vpclmulqdq $0x00, \T7, \T3, \T2
- vpsrldq $4, \T2, \T2 # shift-R T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
-
- vpclmulqdq $0x10, \T7, \T3, \T4
- vpslldq $4, \T4, \T4 # shift-L T4 1 DW (Shift-L 1-DW to obtain result with no shifts)
-
- vpxor \T2, \T4, \T4 # second phase of the reduction complete
- #######################################################################
- vpxor \T4, \T6, \T6 # the result is in T6
-.endm
-
-
-
-#############################################################
-#void aesni_gcm_init_avx_gen4
-# (gcm_data *my_ctx_data,
-# gcm_context_data *data,
-# u8 *iv, /* Pre-counter block j0: 4 byte salt
-# (from Security Association) concatenated with 8 byte
-# Initialisation Vector (from IPSec ESP Payload)
-# concatenated with 0x00000001. 16-byte aligned pointer. */
-# u8 *hash_subkey# /* H, the Hash sub key input. Data starts on a 16-byte boundary. */
-# const u8 *aad, /* Additional Authentication Data (AAD)*/
-# u64 aad_len) /* Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 Bytes */
-#############################################################
-SYM_FUNC_START(aesni_gcm_init_avx_gen4)
- FUNC_SAVE
- INIT GHASH_MUL_AVX2, PRECOMPUTE_AVX2
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_init_avx_gen4)
-
-###############################################################################
-#void aesni_gcm_enc_avx_gen4(
-# gcm_data *my_ctx_data, /* aligned to 16 Bytes */
-# gcm_context_data *data,
-# u8 *out, /* Ciphertext output. Encrypt in-place is allowed. */
-# const u8 *in, /* Plaintext input */
-# u64 plaintext_len) /* Length of data in Bytes for encryption. */
-###############################################################################
-SYM_FUNC_START(aesni_gcm_enc_update_avx_gen4)
- FUNC_SAVE
- mov keysize,%eax
- cmp $32, %eax
- je key_256_enc_update4
- cmp $16, %eax
- je key_128_enc_update4
- # must be 192
- GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, ENC, 11
- FUNC_RESTORE
- RET
-key_128_enc_update4:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, ENC, 9
- FUNC_RESTORE
- RET
-key_256_enc_update4:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, ENC, 13
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_enc_update_avx_gen4)
-
-###############################################################################
-#void aesni_gcm_dec_update_avx_gen4(
-# gcm_data *my_ctx_data, /* aligned to 16 Bytes */
-# gcm_context_data *data,
-# u8 *out, /* Plaintext output. Decrypt in-place is allowed. */
-# const u8 *in, /* Ciphertext input */
-# u64 plaintext_len) /* Length of data in Bytes for encryption. */
-###############################################################################
-SYM_FUNC_START(aesni_gcm_dec_update_avx_gen4)
- FUNC_SAVE
- mov keysize,%eax
- cmp $32, %eax
- je key_256_dec_update4
- cmp $16, %eax
- je key_128_dec_update4
- # must be 192
- GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, DEC, 11
- FUNC_RESTORE
- RET
-key_128_dec_update4:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, DEC, 9
- FUNC_RESTORE
- RET
-key_256_dec_update4:
- GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, DEC, 13
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_dec_update_avx_gen4)
-
-###############################################################################
-#void aesni_gcm_finalize_avx_gen4(
-# gcm_data *my_ctx_data, /* aligned to 16 Bytes */
-# gcm_context_data *data,
-# u8 *auth_tag, /* Authenticated Tag output. */
-# u64 auth_tag_len)# /* Authenticated Tag Length in bytes.
-# Valid values are 16 (most likely), 12 or 8. */
-###############################################################################
-SYM_FUNC_START(aesni_gcm_finalize_avx_gen4)
- FUNC_SAVE
- mov keysize,%eax
- cmp $32, %eax
- je key_256_finalize4
- cmp $16, %eax
- je key_128_finalize4
- # must be 192
- GCM_COMPLETE GHASH_MUL_AVX2, 11, arg3, arg4
- FUNC_RESTORE
- RET
-key_128_finalize4:
- GCM_COMPLETE GHASH_MUL_AVX2, 9, arg3, arg4
- FUNC_RESTORE
- RET
-key_256_finalize4:
- GCM_COMPLETE GHASH_MUL_AVX2, 13, arg3, arg4
- FUNC_RESTORE
- RET
-SYM_FUNC_END(aesni_gcm_finalize_avx_gen4)
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index b1d90c25975a..cd37de5ec404 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Support for Intel AES-NI instructions. This file contains glue
- * code, the real AES implementation is in intel-aes_asm.S.
+ * Support for AES-NI and VAES instructions. This file contains glue code.
+ * The real AES implementations are in aesni-intel_asm.S and other .S files.
*
* Copyright (C) 2008, Intel Corp.
* Author: Huang Ying <ying.huang@intel.com>
@@ -13,6 +13,8 @@
* Tadeusz Struk (tadeusz.struk@intel.com)
* Aidan O'Mahony (aidan.o.mahony@intel.com)
* Copyright (c) 2010, Intel Corporation.
+ *
+ * Copyright 2024 Google LLC
*/
#include <linux/hardirq.h>
@@ -40,46 +42,15 @@
#define AESNI_ALIGN 16
#define AESNI_ALIGN_ATTR __attribute__ ((__aligned__(AESNI_ALIGN)))
#define AES_BLOCK_MASK (~(AES_BLOCK_SIZE - 1))
-#define RFC4106_HASH_SUBKEY_SIZE 16
#define AESNI_ALIGN_EXTRA ((AESNI_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
#define CRYPTO_AES_CTX_SIZE (sizeof(struct crypto_aes_ctx) + AESNI_ALIGN_EXTRA)
#define XTS_AES_CTX_SIZE (sizeof(struct aesni_xts_ctx) + AESNI_ALIGN_EXTRA)
-/* This data is stored at the end of the crypto_tfm struct.
- * It's a type of per "session" data storage location.
- * This needs to be 16 byte aligned.
- */
-struct aesni_rfc4106_gcm_ctx {
- u8 hash_subkey[16] AESNI_ALIGN_ATTR;
- struct crypto_aes_ctx aes_key_expanded AESNI_ALIGN_ATTR;
- u8 nonce[4];
-};
-
-struct generic_gcmaes_ctx {
- u8 hash_subkey[16] AESNI_ALIGN_ATTR;
- struct crypto_aes_ctx aes_key_expanded AESNI_ALIGN_ATTR;
-};
-
struct aesni_xts_ctx {
struct crypto_aes_ctx tweak_ctx AESNI_ALIGN_ATTR;
struct crypto_aes_ctx crypt_ctx AESNI_ALIGN_ATTR;
};
-#define GCM_BLOCK_LEN 16
-
-struct gcm_context_data {
- /* init, update and finalize context data */
- u8 aad_hash[GCM_BLOCK_LEN];
- u64 aad_length;
- u64 in_length;
- u8 partial_block_enc_key[GCM_BLOCK_LEN];
- u8 orig_IV[GCM_BLOCK_LEN];
- u8 current_counter[GCM_BLOCK_LEN];
- u64 partial_block_len;
- u64 unused;
- u8 hash_keys[GCM_BLOCK_LEN * 16];
-};
-
static inline void *aes_align_addr(void *addr)
{
if (crypto_tfm_ctx_alignment() >= AESNI_ALIGN)
@@ -87,8 +58,8 @@ static inline void *aes_align_addr(void *addr)
return PTR_ALIGN(addr, AESNI_ALIGN);
}
-asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
- unsigned int key_len);
+asmlinkage void aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ unsigned int key_len);
asmlinkage void aesni_enc(const void *ctx, u8 *out, const u8 *in);
asmlinkage void aesni_dec(const void *ctx, u8 *out, const u8 *in);
asmlinkage void aesni_ecb_enc(struct crypto_aes_ctx *ctx, u8 *out,
@@ -104,14 +75,11 @@ asmlinkage void aesni_cts_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out,
asmlinkage void aesni_cts_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
const u8 *in, unsigned int len, u8 *iv);
-#define AVX_GEN2_OPTSIZE 640
-#define AVX_GEN4_OPTSIZE 4096
-
-asmlinkage void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *out,
- const u8 *in, unsigned int len, u8 *iv);
+asmlinkage void aesni_xts_enc(const struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len, u8 *iv);
-asmlinkage void aesni_xts_decrypt(const struct crypto_aes_ctx *ctx, u8 *out,
- const u8 *in, unsigned int len, u8 *iv);
+asmlinkage void aesni_xts_dec(const struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len, u8 *iv);
#ifdef CONFIG_X86_64
@@ -119,23 +87,6 @@ asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out,
const u8 *in, unsigned int len, u8 *iv);
DEFINE_STATIC_CALL(aesni_ctr_enc_tfm, aesni_ctr_enc);
-/* Scatter / Gather routines, with args similar to above */
-asmlinkage void aesni_gcm_init(void *ctx,
- struct gcm_context_data *gdata,
- u8 *iv,
- u8 *hash_subkey, const u8 *aad,
- unsigned long aad_len);
-asmlinkage void aesni_gcm_enc_update(void *ctx,
- struct gcm_context_data *gdata, u8 *out,
- const u8 *in, unsigned long plaintext_len);
-asmlinkage void aesni_gcm_dec_update(void *ctx,
- struct gcm_context_data *gdata, u8 *out,
- const u8 *in,
- unsigned long ciphertext_len);
-asmlinkage void aesni_gcm_finalize(void *ctx,
- struct gcm_context_data *gdata,
- u8 *auth_tag, unsigned long auth_tag_len);
-
asmlinkage void aes_ctr_enc_128_avx_by8(const u8 *in, u8 *iv,
void *keys, u8 *out, unsigned int num_bytes);
asmlinkage void aes_ctr_enc_192_avx_by8(const u8 *in, u8 *iv,
@@ -155,67 +106,6 @@ asmlinkage void aes_xctr_enc_192_avx_by8(const u8 *in, const u8 *iv,
asmlinkage void aes_xctr_enc_256_avx_by8(const u8 *in, const u8 *iv,
const void *keys, u8 *out, unsigned int num_bytes,
unsigned int byte_ctr);
-
-/*
- * asmlinkage void aesni_gcm_init_avx_gen2()
- * gcm_data *my_ctx_data, context data
- * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary.
- */
-asmlinkage void aesni_gcm_init_avx_gen2(void *my_ctx_data,
- struct gcm_context_data *gdata,
- u8 *iv,
- u8 *hash_subkey,
- const u8 *aad,
- unsigned long aad_len);
-
-asmlinkage void aesni_gcm_enc_update_avx_gen2(void *ctx,
- struct gcm_context_data *gdata, u8 *out,
- const u8 *in, unsigned long plaintext_len);
-asmlinkage void aesni_gcm_dec_update_avx_gen2(void *ctx,
- struct gcm_context_data *gdata, u8 *out,
- const u8 *in,
- unsigned long ciphertext_len);
-asmlinkage void aesni_gcm_finalize_avx_gen2(void *ctx,
- struct gcm_context_data *gdata,
- u8 *auth_tag, unsigned long auth_tag_len);
-
-/*
- * asmlinkage void aesni_gcm_init_avx_gen4()
- * gcm_data *my_ctx_data, context data
- * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary.
- */
-asmlinkage void aesni_gcm_init_avx_gen4(void *my_ctx_data,
- struct gcm_context_data *gdata,
- u8 *iv,
- u8 *hash_subkey,
- const u8 *aad,
- unsigned long aad_len);
-
-asmlinkage void aesni_gcm_enc_update_avx_gen4(void *ctx,
- struct gcm_context_data *gdata, u8 *out,
- const u8 *in, unsigned long plaintext_len);
-asmlinkage void aesni_gcm_dec_update_avx_gen4(void *ctx,
- struct gcm_context_data *gdata, u8 *out,
- const u8 *in,
- unsigned long ciphertext_len);
-asmlinkage void aesni_gcm_finalize_avx_gen4(void *ctx,
- struct gcm_context_data *gdata,
- u8 *auth_tag, unsigned long auth_tag_len);
-
-static __ro_after_init DEFINE_STATIC_KEY_FALSE(gcm_use_avx);
-static __ro_after_init DEFINE_STATIC_KEY_FALSE(gcm_use_avx2);
-
-static inline struct
-aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm)
-{
- return aes_align_addr(crypto_aead_ctx(tfm));
-}
-
-static inline struct
-generic_gcmaes_ctx *generic_gcmaes_ctx_get(struct crypto_aead *tfm)
-{
- return aes_align_addr(crypto_aead_ctx(tfm));
-}
#endif
static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
@@ -233,19 +123,17 @@ static int aes_set_key_common(struct crypto_aes_ctx *ctx,
{
int err;
- if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_192 &&
- key_len != AES_KEYSIZE_256)
- return -EINVAL;
-
if (!crypto_simd_usable())
- err = aes_expandkey(ctx, in_key, key_len);
- else {
- kernel_fpu_begin();
- err = aesni_set_key(ctx, in_key, key_len);
- kernel_fpu_end();
- }
+ return aes_expandkey(ctx, in_key, key_len);
- return err;
+ err = aes_check_keylen(key_len);
+ if (err)
+ return err;
+
+ kernel_fpu_begin();
+ aesni_set_key(ctx, in_key, key_len);
+ kernel_fpu_end();
+ return 0;
}
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
@@ -591,293 +479,9 @@ static int xctr_crypt(struct skcipher_request *req)
}
return err;
}
-
-static int
-rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
-{
- struct crypto_aes_ctx ctx;
- int ret;
-
- ret = aes_expandkey(&ctx, key, key_len);
- if (ret)
- return ret;
-
- /* Clear the data in the hash sub key container to zero.*/
- /* We want to cipher all zeros to create the hash sub key. */
- memset(hash_subkey, 0, RFC4106_HASH_SUBKEY_SIZE);
-
- aes_encrypt(&ctx, hash_subkey, hash_subkey);
-
- memzero_explicit(&ctx, sizeof(ctx));
- return 0;
-}
-
-static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key,
- unsigned int key_len)
-{
- struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(aead);
-
- if (key_len < 4)
- return -EINVAL;
-
- /*Account for 4 byte nonce at the end.*/
- key_len -= 4;
-
- memcpy(ctx->nonce, key + key_len, sizeof(ctx->nonce));
-
- return aes_set_key_common(&ctx->aes_key_expanded, key, key_len) ?:
- rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
-}
-
-/* This is the Integrity Check Value (aka the authentication tag) length and can
- * be 8, 12 or 16 bytes long. */
-static int common_rfc4106_set_authsize(struct crypto_aead *aead,
- unsigned int authsize)
-{
- switch (authsize) {
- case 8:
- case 12:
- case 16:
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int generic_gcmaes_set_authsize(struct crypto_aead *tfm,
- unsigned int authsize)
-{
- switch (authsize) {
- case 4:
- case 8:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int gcmaes_crypt_by_sg(bool enc, struct aead_request *req,
- unsigned int assoclen, u8 *hash_subkey,
- u8 *iv, void *aes_ctx, u8 *auth_tag,
- unsigned long auth_tag_len)
-{
- u8 databuf[sizeof(struct gcm_context_data) + (AESNI_ALIGN - 8)] __aligned(8);
- struct gcm_context_data *data = PTR_ALIGN((void *)databuf, AESNI_ALIGN);
- unsigned long left = req->cryptlen;
- struct scatter_walk assoc_sg_walk;
- struct skcipher_walk walk;
- bool do_avx, do_avx2;
- u8 *assocmem = NULL;
- u8 *assoc;
- int err;
-
- if (!enc)
- left -= auth_tag_len;
-
- do_avx = (left >= AVX_GEN2_OPTSIZE);
- do_avx2 = (left >= AVX_GEN4_OPTSIZE);
-
- /* Linearize assoc, if not already linear */
- if (req->src->length >= assoclen && req->src->length) {
- scatterwalk_start(&assoc_sg_walk, req->src);
- assoc = scatterwalk_map(&assoc_sg_walk);
- } else {
- gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
- GFP_KERNEL : GFP_ATOMIC;
-
- /* assoc can be any length, so must be on heap */
- assocmem = kmalloc(assoclen, flags);
- if (unlikely(!assocmem))
- return -ENOMEM;
- assoc = assocmem;
-
- scatterwalk_map_and_copy(assoc, req->src, 0, assoclen, 0);
- }
-
- kernel_fpu_begin();
- if (static_branch_likely(&gcm_use_avx2) && do_avx2)
- aesni_gcm_init_avx_gen4(aes_ctx, data, iv, hash_subkey, assoc,
- assoclen);
- else if (static_branch_likely(&gcm_use_avx) && do_avx)
- aesni_gcm_init_avx_gen2(aes_ctx, data, iv, hash_subkey, assoc,
- assoclen);
- else
- aesni_gcm_init(aes_ctx, data, iv, hash_subkey, assoc, assoclen);
- kernel_fpu_end();
-
- if (!assocmem)
- scatterwalk_unmap(assoc);
- else
- kfree(assocmem);
-
- err = enc ? skcipher_walk_aead_encrypt(&walk, req, false)
- : skcipher_walk_aead_decrypt(&walk, req, false);
-
- while (walk.nbytes > 0) {
- kernel_fpu_begin();
- if (static_branch_likely(&gcm_use_avx2) && do_avx2) {
- if (enc)
- aesni_gcm_enc_update_avx_gen4(aes_ctx, data,
- walk.dst.virt.addr,
- walk.src.virt.addr,
- walk.nbytes);
- else
- aesni_gcm_dec_update_avx_gen4(aes_ctx, data,
- walk.dst.virt.addr,
- walk.src.virt.addr,
- walk.nbytes);
- } else if (static_branch_likely(&gcm_use_avx) && do_avx) {
- if (enc)
- aesni_gcm_enc_update_avx_gen2(aes_ctx, data,
- walk.dst.virt.addr,
- walk.src.virt.addr,
- walk.nbytes);
- else
- aesni_gcm_dec_update_avx_gen2(aes_ctx, data,
- walk.dst.virt.addr,
- walk.src.virt.addr,
- walk.nbytes);
- } else if (enc) {
- aesni_gcm_enc_update(aes_ctx, data, walk.dst.virt.addr,
- walk.src.virt.addr, walk.nbytes);
- } else {
- aesni_gcm_dec_update(aes_ctx, data, walk.dst.virt.addr,
- walk.src.virt.addr, walk.nbytes);
- }
- kernel_fpu_end();
-
- err = skcipher_walk_done(&walk, 0);
- }
-
- if (err)
- return err;
-
- kernel_fpu_begin();
- if (static_branch_likely(&gcm_use_avx2) && do_avx2)
- aesni_gcm_finalize_avx_gen4(aes_ctx, data, auth_tag,
- auth_tag_len);
- else if (static_branch_likely(&gcm_use_avx) && do_avx)
- aesni_gcm_finalize_avx_gen2(aes_ctx, data, auth_tag,
- auth_tag_len);
- else
- aesni_gcm_finalize(aes_ctx, data, auth_tag, auth_tag_len);
- kernel_fpu_end();
-
- return 0;
-}
-
-static int gcmaes_encrypt(struct aead_request *req, unsigned int assoclen,
- u8 *hash_subkey, u8 *iv, void *aes_ctx)
-{
- struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- unsigned long auth_tag_len = crypto_aead_authsize(tfm);
- u8 auth_tag[16];
- int err;
-
- err = gcmaes_crypt_by_sg(true, req, assoclen, hash_subkey, iv, aes_ctx,
- auth_tag, auth_tag_len);
- if (err)
- return err;
-
- scatterwalk_map_and_copy(auth_tag, req->dst,
- req->assoclen + req->cryptlen,
- auth_tag_len, 1);
- return 0;
-}
-
-static int gcmaes_decrypt(struct aead_request *req, unsigned int assoclen,
- u8 *hash_subkey, u8 *iv, void *aes_ctx)
-{
- struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- unsigned long auth_tag_len = crypto_aead_authsize(tfm);
- u8 auth_tag_msg[16];
- u8 auth_tag[16];
- int err;
-
- err = gcmaes_crypt_by_sg(false, req, assoclen, hash_subkey, iv, aes_ctx,
- auth_tag, auth_tag_len);
- if (err)
- return err;
-
- /* Copy out original auth_tag */
- scatterwalk_map_and_copy(auth_tag_msg, req->src,
- req->assoclen + req->cryptlen - auth_tag_len,
- auth_tag_len, 0);
-
- /* Compare generated tag with passed in tag. */
- if (crypto_memneq(auth_tag_msg, auth_tag, auth_tag_len)) {
- memzero_explicit(auth_tag, sizeof(auth_tag));
- return -EBADMSG;
- }
- return 0;
-}
-
-static int helper_rfc4106_encrypt(struct aead_request *req)
-{
- struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
- void *aes_ctx = &(ctx->aes_key_expanded);
- u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8);
- u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN);
- unsigned int i;
- __be32 counter = cpu_to_be32(1);
-
- /* Assuming we are supporting rfc4106 64-bit extended */
- /* sequence numbers We need to have the AAD length equal */
- /* to 16 or 20 bytes */
- if (unlikely(req->assoclen != 16 && req->assoclen != 20))
- return -EINVAL;
-
- /* IV below built */
- for (i = 0; i < 4; i++)
- *(iv+i) = ctx->nonce[i];
- for (i = 0; i < 8; i++)
- *(iv+4+i) = req->iv[i];
- *((__be32 *)(iv+12)) = counter;
-
- return gcmaes_encrypt(req, req->assoclen - 8, ctx->hash_subkey, iv,
- aes_ctx);
-}
-
-static int helper_rfc4106_decrypt(struct aead_request *req)
-{
- __be32 counter = cpu_to_be32(1);
- struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
- void *aes_ctx = &(ctx->aes_key_expanded);
- u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8);
- u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN);
- unsigned int i;
-
- if (unlikely(req->assoclen != 16 && req->assoclen != 20))
- return -EINVAL;
-
- /* Assuming we are supporting rfc4106 64-bit extended */
- /* sequence numbers We need to have the AAD length */
- /* equal to 16 or 20 bytes */
-
- /* IV below built */
- for (i = 0; i < 4; i++)
- *(iv+i) = ctx->nonce[i];
- for (i = 0; i < 8; i++)
- *(iv+4+i) = req->iv[i];
- *((__be32 *)(iv+12)) = counter;
-
- return gcmaes_decrypt(req, req->assoclen - 8, ctx->hash_subkey, iv,
- aes_ctx);
-}
#endif
-static int xts_aesni_setkey(struct crypto_skcipher *tfm, const u8 *key,
+static int xts_setkey_aesni(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keylen)
{
struct aesni_xts_ctx *ctx = aes_xts_ctx(tfm);
@@ -898,108 +502,149 @@ static int xts_aesni_setkey(struct crypto_skcipher *tfm, const u8 *key,
return aes_set_key_common(&ctx->tweak_ctx, key + keylen, keylen);
}
-static int xts_crypt(struct skcipher_request *req, bool encrypt)
+typedef void (*xts_encrypt_iv_func)(const struct crypto_aes_ctx *tweak_key,
+ u8 iv[AES_BLOCK_SIZE]);
+typedef void (*xts_crypt_func)(const struct crypto_aes_ctx *key,
+ const u8 *src, u8 *dst, unsigned int len,
+ u8 tweak[AES_BLOCK_SIZE]);
+
+/* This handles cases where the source and/or destination span pages. */
+static noinline int
+xts_crypt_slowpath(struct skcipher_request *req, xts_crypt_func crypt_func)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct aesni_xts_ctx *ctx = aes_xts_ctx(tfm);
+ const struct aesni_xts_ctx *ctx = aes_xts_ctx(tfm);
int tail = req->cryptlen % AES_BLOCK_SIZE;
+ struct scatterlist sg_src[2], sg_dst[2];
struct skcipher_request subreq;
struct skcipher_walk walk;
+ struct scatterlist *src, *dst;
int err;
- if (req->cryptlen < AES_BLOCK_SIZE)
- return -EINVAL;
-
- err = skcipher_walk_virt(&walk, req, false);
- if (!walk.nbytes)
- return err;
-
- if (unlikely(tail > 0 && walk.nbytes < walk.total)) {
- int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2;
-
- skcipher_walk_abort(&walk);
-
+ /*
+ * If the message length isn't divisible by the AES block size, then
+ * separate off the last full block and the partial block. This ensures
+ * that they are processed in the same call to the assembly function,
+ * which is required for ciphertext stealing.
+ */
+ if (tail) {
skcipher_request_set_tfm(&subreq, tfm);
skcipher_request_set_callback(&subreq,
skcipher_request_flags(req),
NULL, NULL);
skcipher_request_set_crypt(&subreq, req->src, req->dst,
- blocks * AES_BLOCK_SIZE, req->iv);
+ req->cryptlen - tail - AES_BLOCK_SIZE,
+ req->iv);
req = &subreq;
-
- err = skcipher_walk_virt(&walk, req, false);
- if (!walk.nbytes)
- return err;
- } else {
- tail = 0;
}
- kernel_fpu_begin();
+ err = skcipher_walk_virt(&walk, req, false);
- /* calculate first value of T */
- aesni_enc(&ctx->tweak_ctx, walk.iv, walk.iv);
+ while (walk.nbytes) {
+ kernel_fpu_begin();
+ (*crypt_func)(&ctx->crypt_ctx,
+ walk.src.virt.addr, walk.dst.virt.addr,
+ walk.nbytes & ~(AES_BLOCK_SIZE - 1), req->iv);
+ kernel_fpu_end();
+ err = skcipher_walk_done(&walk,
+ walk.nbytes & (AES_BLOCK_SIZE - 1));
+ }
- while (walk.nbytes > 0) {
- int nbytes = walk.nbytes;
+ if (err || !tail)
+ return err;
- if (nbytes < walk.total)
- nbytes &= ~(AES_BLOCK_SIZE - 1);
+ /* Do ciphertext stealing with the last full block and partial block. */
- if (encrypt)
- aesni_xts_encrypt(&ctx->crypt_ctx,
- walk.dst.virt.addr, walk.src.virt.addr,
- nbytes, walk.iv);
- else
- aesni_xts_decrypt(&ctx->crypt_ctx,
- walk.dst.virt.addr, walk.src.virt.addr,
- nbytes, walk.iv);
- kernel_fpu_end();
+ dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen);
+ if (req->dst != req->src)
+ dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen);
- err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+ skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail,
+ req->iv);
- if (walk.nbytes > 0)
- kernel_fpu_begin();
- }
+ err = skcipher_walk_virt(&walk, req, false);
+ if (err)
+ return err;
- if (unlikely(tail > 0 && !err)) {
- struct scatterlist sg_src[2], sg_dst[2];
- struct scatterlist *src, *dst;
+ kernel_fpu_begin();
+ (*crypt_func)(&ctx->crypt_ctx, walk.src.virt.addr, walk.dst.virt.addr,
+ walk.nbytes, req->iv);
+ kernel_fpu_end();
- dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen);
- if (req->dst != req->src)
- dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen);
+ return skcipher_walk_done(&walk, 0);
+}
- skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail,
- req->iv);
+/* __always_inline to avoid indirect call in fastpath */
+static __always_inline int
+xts_crypt(struct skcipher_request *req, xts_encrypt_iv_func encrypt_iv,
+ xts_crypt_func crypt_func)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct aesni_xts_ctx *ctx = aes_xts_ctx(tfm);
+ const unsigned int cryptlen = req->cryptlen;
+ struct scatterlist *src = req->src;
+ struct scatterlist *dst = req->dst;
- err = skcipher_walk_virt(&walk, &subreq, false);
- if (err)
- return err;
+ if (unlikely(cryptlen < AES_BLOCK_SIZE))
+ return -EINVAL;
- kernel_fpu_begin();
- if (encrypt)
- aesni_xts_encrypt(&ctx->crypt_ctx,
- walk.dst.virt.addr, walk.src.virt.addr,
- walk.nbytes, walk.iv);
- else
- aesni_xts_decrypt(&ctx->crypt_ctx,
- walk.dst.virt.addr, walk.src.virt.addr,
- walk.nbytes, walk.iv);
- kernel_fpu_end();
+ kernel_fpu_begin();
+ (*encrypt_iv)(&ctx->tweak_ctx, req->iv);
- err = skcipher_walk_done(&walk, 0);
+ /*
+ * In practice, virtually all XTS plaintexts and ciphertexts are either
+ * 512 or 4096 bytes, aligned such that they don't span page boundaries.
+ * To optimize the performance of these cases, and also any other case
+ * where no page boundary is spanned, the below fast-path handles
+ * single-page sources and destinations as efficiently as possible.
+ */
+ if (likely(src->length >= cryptlen && dst->length >= cryptlen &&
+ src->offset + cryptlen <= PAGE_SIZE &&
+ dst->offset + cryptlen <= PAGE_SIZE)) {
+ struct page *src_page = sg_page(src);
+ struct page *dst_page = sg_page(dst);
+ void *src_virt = kmap_local_page(src_page) + src->offset;
+ void *dst_virt = kmap_local_page(dst_page) + dst->offset;
+
+ (*crypt_func)(&ctx->crypt_ctx, src_virt, dst_virt, cryptlen,
+ req->iv);
+ kunmap_local(dst_virt);
+ kunmap_local(src_virt);
+ kernel_fpu_end();
+ return 0;
}
- return err;
+ kernel_fpu_end();
+ return xts_crypt_slowpath(req, crypt_func);
+}
+
+static void aesni_xts_encrypt_iv(const struct crypto_aes_ctx *tweak_key,
+ u8 iv[AES_BLOCK_SIZE])
+{
+ aesni_enc(tweak_key, iv, iv);
}
-static int xts_encrypt(struct skcipher_request *req)
+static void aesni_xts_encrypt(const struct crypto_aes_ctx *key,
+ const u8 *src, u8 *dst, unsigned int len,
+ u8 tweak[AES_BLOCK_SIZE])
{
- return xts_crypt(req, true);
+ aesni_xts_enc(key, dst, src, len, tweak);
}
-static int xts_decrypt(struct skcipher_request *req)
+static void aesni_xts_decrypt(const struct crypto_aes_ctx *key,
+ const u8 *src, u8 *dst, unsigned int len,
+ u8 tweak[AES_BLOCK_SIZE])
{
- return xts_crypt(req, false);
+ aesni_xts_dec(key, dst, src, len, tweak);
+}
+
+static int xts_encrypt_aesni(struct skcipher_request *req)
+{
+ return xts_crypt(req, aesni_xts_encrypt_iv, aesni_xts_encrypt);
+}
+
+static int xts_decrypt_aesni(struct skcipher_request *req)
+{
+ return xts_crypt(req, aesni_xts_encrypt_iv, aesni_xts_decrypt);
}
static struct crypto_alg aesni_cipher_alg = {
@@ -1103,9 +748,9 @@ static struct skcipher_alg aesni_skciphers[] = {
.max_keysize = 2 * AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
.walksize = 2 * AES_BLOCK_SIZE,
- .setkey = xts_aesni_setkey,
- .encrypt = xts_encrypt,
- .decrypt = xts_decrypt,
+ .setkey = xts_setkey_aesni,
+ .encrypt = xts_encrypt_aesni,
+ .decrypt = xts_decrypt_aesni,
}
};
@@ -1137,90 +782,890 @@ static struct skcipher_alg aesni_xctr = {
};
static struct simd_skcipher_alg *aesni_simd_xctr;
-#endif /* CONFIG_X86_64 */
-#ifdef CONFIG_X86_64
-static int generic_gcmaes_set_key(struct crypto_aead *aead, const u8 *key,
- unsigned int key_len)
+asmlinkage void aes_xts_encrypt_iv(const struct crypto_aes_ctx *tweak_key,
+ u8 iv[AES_BLOCK_SIZE]);
+
+#define DEFINE_XTS_ALG(suffix, driver_name, priority) \
+ \
+asmlinkage void \
+aes_xts_encrypt_##suffix(const struct crypto_aes_ctx *key, const u8 *src, \
+ u8 *dst, unsigned int len, u8 tweak[AES_BLOCK_SIZE]); \
+asmlinkage void \
+aes_xts_decrypt_##suffix(const struct crypto_aes_ctx *key, const u8 *src, \
+ u8 *dst, unsigned int len, u8 tweak[AES_BLOCK_SIZE]); \
+ \
+static int xts_encrypt_##suffix(struct skcipher_request *req) \
+{ \
+ return xts_crypt(req, aes_xts_encrypt_iv, aes_xts_encrypt_##suffix); \
+} \
+ \
+static int xts_decrypt_##suffix(struct skcipher_request *req) \
+{ \
+ return xts_crypt(req, aes_xts_encrypt_iv, aes_xts_decrypt_##suffix); \
+} \
+ \
+static struct skcipher_alg aes_xts_alg_##suffix = { \
+ .base = { \
+ .cra_name = "__xts(aes)", \
+ .cra_driver_name = "__" driver_name, \
+ .cra_priority = priority, \
+ .cra_flags = CRYPTO_ALG_INTERNAL, \
+ .cra_blocksize = AES_BLOCK_SIZE, \
+ .cra_ctxsize = XTS_AES_CTX_SIZE, \
+ .cra_module = THIS_MODULE, \
+ }, \
+ .min_keysize = 2 * AES_MIN_KEY_SIZE, \
+ .max_keysize = 2 * AES_MAX_KEY_SIZE, \
+ .ivsize = AES_BLOCK_SIZE, \
+ .walksize = 2 * AES_BLOCK_SIZE, \
+ .setkey = xts_setkey_aesni, \
+ .encrypt = xts_encrypt_##suffix, \
+ .decrypt = xts_decrypt_##suffix, \
+}; \
+ \
+static struct simd_skcipher_alg *aes_xts_simdalg_##suffix
+
+DEFINE_XTS_ALG(aesni_avx, "xts-aes-aesni-avx", 500);
+#if defined(CONFIG_AS_VAES) && defined(CONFIG_AS_VPCLMULQDQ)
+DEFINE_XTS_ALG(vaes_avx2, "xts-aes-vaes-avx2", 600);
+DEFINE_XTS_ALG(vaes_avx10_256, "xts-aes-vaes-avx10_256", 700);
+DEFINE_XTS_ALG(vaes_avx10_512, "xts-aes-vaes-avx10_512", 800);
+#endif
+
+/* The common part of the x86_64 AES-GCM key struct */
+struct aes_gcm_key {
+ /* Expanded AES key and the AES key length in bytes */
+ struct crypto_aes_ctx aes_key;
+
+ /* RFC4106 nonce (used only by the rfc4106 algorithms) */
+ u32 rfc4106_nonce;
+};
+
+/* Key struct used by the AES-NI implementations of AES-GCM */
+struct aes_gcm_key_aesni {
+ /*
+ * Common part of the key. The assembly code requires 16-byte alignment
+ * for the round keys; we get this by them being located at the start of
+ * the struct and the whole struct being 16-byte aligned.
+ */
+ struct aes_gcm_key base;
+
+ /*
+ * Powers of the hash key H^8 through H^1. These are 128-bit values.
+ * They all have an extra factor of x^-1 and are byte-reversed. 16-byte
+ * alignment is required by the assembly code.
+ */
+ u64 h_powers[8][2] __aligned(16);
+
+ /*
+ * h_powers_xored[i] contains the two 64-bit halves of h_powers[i] XOR'd
+ * together. It's used for Karatsuba multiplication. 16-byte alignment
+ * is required by the assembly code.
+ */
+ u64 h_powers_xored[8] __aligned(16);
+
+ /*
+ * H^1 times x^64 (and also the usual extra factor of x^-1). 16-byte
+ * alignment is required by the assembly code.
+ */
+ u64 h_times_x64[2] __aligned(16);
+};
+#define AES_GCM_KEY_AESNI(key) \
+ container_of((key), struct aes_gcm_key_aesni, base)
+#define AES_GCM_KEY_AESNI_SIZE \
+ (sizeof(struct aes_gcm_key_aesni) + (15 & ~(CRYPTO_MINALIGN - 1)))
+
+/* Key struct used by the VAES + AVX10 implementations of AES-GCM */
+struct aes_gcm_key_avx10 {
+ /*
+ * Common part of the key. The assembly code prefers 16-byte alignment
+ * for the round keys; we get this by them being located at the start of
+ * the struct and the whole struct being 64-byte aligned.
+ */
+ struct aes_gcm_key base;
+
+ /*
+ * Powers of the hash key H^16 through H^1. These are 128-bit values.
+ * They all have an extra factor of x^-1 and are byte-reversed. This
+ * array is aligned to a 64-byte boundary to make it naturally aligned
+ * for 512-bit loads, which can improve performance. (The assembly code
+ * doesn't *need* the alignment; this is just an optimization.)
+ */
+ u64 h_powers[16][2] __aligned(64);
+
+ /* Three padding blocks required by the assembly code */
+ u64 padding[3][2];
+};
+#define AES_GCM_KEY_AVX10(key) \
+ container_of((key), struct aes_gcm_key_avx10, base)
+#define AES_GCM_KEY_AVX10_SIZE \
+ (sizeof(struct aes_gcm_key_avx10) + (63 & ~(CRYPTO_MINALIGN - 1)))
+
+/*
+ * These flags are passed to the AES-GCM helper functions to specify the
+ * specific version of AES-GCM (RFC4106 or not), whether it's encryption or
+ * decryption, and which assembly functions should be called. Assembly
+ * functions are selected using flags instead of function pointers to avoid
+ * indirect calls (which are very expensive on x86) regardless of inlining.
+ */
+#define FLAG_RFC4106 BIT(0)
+#define FLAG_ENC BIT(1)
+#define FLAG_AVX BIT(2)
+#if defined(CONFIG_AS_VAES) && defined(CONFIG_AS_VPCLMULQDQ)
+# define FLAG_AVX10_256 BIT(3)
+# define FLAG_AVX10_512 BIT(4)
+#else
+ /*
+ * This should cause all calls to the AVX10 assembly functions to be
+ * optimized out, avoiding the need to ifdef each call individually.
+ */
+# define FLAG_AVX10_256 0
+# define FLAG_AVX10_512 0
+#endif
+
+static inline struct aes_gcm_key *
+aes_gcm_key_get(struct crypto_aead *tfm, int flags)
{
- struct generic_gcmaes_ctx *ctx = generic_gcmaes_ctx_get(aead);
+ if (flags & (FLAG_AVX10_256 | FLAG_AVX10_512))
+ return PTR_ALIGN(crypto_aead_ctx(tfm), 64);
+ else
+ return PTR_ALIGN(crypto_aead_ctx(tfm), 16);
+}
+
+asmlinkage void
+aes_gcm_precompute_aesni(struct aes_gcm_key_aesni *key);
+asmlinkage void
+aes_gcm_precompute_aesni_avx(struct aes_gcm_key_aesni *key);
+asmlinkage void
+aes_gcm_precompute_vaes_avx10_256(struct aes_gcm_key_avx10 *key);
+asmlinkage void
+aes_gcm_precompute_vaes_avx10_512(struct aes_gcm_key_avx10 *key);
- return aes_set_key_common(&ctx->aes_key_expanded, key, key_len) ?:
- rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
+static void aes_gcm_precompute(struct aes_gcm_key *key, int flags)
+{
+ /*
+ * To make things a bit easier on the assembly side, the AVX10
+ * implementations use the same key format. Therefore, a single
+ * function using 256-bit vectors would suffice here. However, it's
+ * straightforward to provide a 512-bit one because of how the assembly
+ * code is structured, and it works nicely because the total size of the
+ * key powers is a multiple of 512 bits. So we take advantage of that.
+ *
+ * A similar situation applies to the AES-NI implementations.
+ */
+ if (flags & FLAG_AVX10_512)
+ aes_gcm_precompute_vaes_avx10_512(AES_GCM_KEY_AVX10(key));
+ else if (flags & FLAG_AVX10_256)
+ aes_gcm_precompute_vaes_avx10_256(AES_GCM_KEY_AVX10(key));
+ else if (flags & FLAG_AVX)
+ aes_gcm_precompute_aesni_avx(AES_GCM_KEY_AESNI(key));
+ else
+ aes_gcm_precompute_aesni(AES_GCM_KEY_AESNI(key));
}
-static int generic_gcmaes_encrypt(struct aead_request *req)
+asmlinkage void
+aes_gcm_aad_update_aesni(const struct aes_gcm_key_aesni *key,
+ u8 ghash_acc[16], const u8 *aad, int aadlen);
+asmlinkage void
+aes_gcm_aad_update_aesni_avx(const struct aes_gcm_key_aesni *key,
+ u8 ghash_acc[16], const u8 *aad, int aadlen);
+asmlinkage void
+aes_gcm_aad_update_vaes_avx10(const struct aes_gcm_key_avx10 *key,
+ u8 ghash_acc[16], const u8 *aad, int aadlen);
+
+static void aes_gcm_aad_update(const struct aes_gcm_key *key, u8 ghash_acc[16],
+ const u8 *aad, int aadlen, int flags)
{
- struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- struct generic_gcmaes_ctx *ctx = generic_gcmaes_ctx_get(tfm);
- void *aes_ctx = &(ctx->aes_key_expanded);
- u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8);
- u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN);
- __be32 counter = cpu_to_be32(1);
+ if (flags & (FLAG_AVX10_256 | FLAG_AVX10_512))
+ aes_gcm_aad_update_vaes_avx10(AES_GCM_KEY_AVX10(key), ghash_acc,
+ aad, aadlen);
+ else if (flags & FLAG_AVX)
+ aes_gcm_aad_update_aesni_avx(AES_GCM_KEY_AESNI(key), ghash_acc,
+ aad, aadlen);
+ else
+ aes_gcm_aad_update_aesni(AES_GCM_KEY_AESNI(key), ghash_acc,
+ aad, aadlen);
+}
+
+asmlinkage void
+aes_gcm_enc_update_aesni(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+asmlinkage void
+aes_gcm_enc_update_aesni_avx(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+asmlinkage void
+aes_gcm_enc_update_vaes_avx10_256(const struct aes_gcm_key_avx10 *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+asmlinkage void
+aes_gcm_enc_update_vaes_avx10_512(const struct aes_gcm_key_avx10 *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+
+asmlinkage void
+aes_gcm_dec_update_aesni(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+asmlinkage void
+aes_gcm_dec_update_aesni_avx(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+asmlinkage void
+aes_gcm_dec_update_vaes_avx10_256(const struct aes_gcm_key_avx10 *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+asmlinkage void
+aes_gcm_dec_update_vaes_avx10_512(const struct aes_gcm_key_avx10 *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen);
+
+/* __always_inline to optimize out the branches based on @flags */
+static __always_inline void
+aes_gcm_update(const struct aes_gcm_key *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ const u8 *src, u8 *dst, int datalen, int flags)
+{
+ if (flags & FLAG_ENC) {
+ if (flags & FLAG_AVX10_512)
+ aes_gcm_enc_update_vaes_avx10_512(AES_GCM_KEY_AVX10(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ else if (flags & FLAG_AVX10_256)
+ aes_gcm_enc_update_vaes_avx10_256(AES_GCM_KEY_AVX10(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ else if (flags & FLAG_AVX)
+ aes_gcm_enc_update_aesni_avx(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ else
+ aes_gcm_enc_update_aesni(AES_GCM_KEY_AESNI(key), le_ctr,
+ ghash_acc, src, dst, datalen);
+ } else {
+ if (flags & FLAG_AVX10_512)
+ aes_gcm_dec_update_vaes_avx10_512(AES_GCM_KEY_AVX10(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ else if (flags & FLAG_AVX10_256)
+ aes_gcm_dec_update_vaes_avx10_256(AES_GCM_KEY_AVX10(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ else if (flags & FLAG_AVX)
+ aes_gcm_dec_update_aesni_avx(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ else
+ aes_gcm_dec_update_aesni(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ src, dst, datalen);
+ }
+}
+
+asmlinkage void
+aes_gcm_enc_final_aesni(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen);
+asmlinkage void
+aes_gcm_enc_final_aesni_avx(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen);
+asmlinkage void
+aes_gcm_enc_final_vaes_avx10(const struct aes_gcm_key_avx10 *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen);
+
+/* __always_inline to optimize out the branches based on @flags */
+static __always_inline void
+aes_gcm_enc_final(const struct aes_gcm_key *key,
+ const u32 le_ctr[4], u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen, int flags)
+{
+ if (flags & (FLAG_AVX10_256 | FLAG_AVX10_512))
+ aes_gcm_enc_final_vaes_avx10(AES_GCM_KEY_AVX10(key),
+ le_ctr, ghash_acc,
+ total_aadlen, total_datalen);
+ else if (flags & FLAG_AVX)
+ aes_gcm_enc_final_aesni_avx(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ total_aadlen, total_datalen);
+ else
+ aes_gcm_enc_final_aesni(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ total_aadlen, total_datalen);
+}
+
+asmlinkage bool __must_check
+aes_gcm_dec_final_aesni(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], const u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen,
+ const u8 tag[16], int taglen);
+asmlinkage bool __must_check
+aes_gcm_dec_final_aesni_avx(const struct aes_gcm_key_aesni *key,
+ const u32 le_ctr[4], const u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen,
+ const u8 tag[16], int taglen);
+asmlinkage bool __must_check
+aes_gcm_dec_final_vaes_avx10(const struct aes_gcm_key_avx10 *key,
+ const u32 le_ctr[4], const u8 ghash_acc[16],
+ u64 total_aadlen, u64 total_datalen,
+ const u8 tag[16], int taglen);
+
+/* __always_inline to optimize out the branches based on @flags */
+static __always_inline bool __must_check
+aes_gcm_dec_final(const struct aes_gcm_key *key, const u32 le_ctr[4],
+ u8 ghash_acc[16], u64 total_aadlen, u64 total_datalen,
+ u8 tag[16], int taglen, int flags)
+{
+ if (flags & (FLAG_AVX10_256 | FLAG_AVX10_512))
+ return aes_gcm_dec_final_vaes_avx10(AES_GCM_KEY_AVX10(key),
+ le_ctr, ghash_acc,
+ total_aadlen, total_datalen,
+ tag, taglen);
+ else if (flags & FLAG_AVX)
+ return aes_gcm_dec_final_aesni_avx(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ total_aadlen, total_datalen,
+ tag, taglen);
+ else
+ return aes_gcm_dec_final_aesni(AES_GCM_KEY_AESNI(key),
+ le_ctr, ghash_acc,
+ total_aadlen, total_datalen,
+ tag, taglen);
+}
+
+/*
+ * This is the Integrity Check Value (aka the authentication tag) length and can
+ * be 8, 12 or 16 bytes long.
+ */
+static int common_rfc4106_set_authsize(struct crypto_aead *aead,
+ unsigned int authsize)
+{
+ switch (authsize) {
+ case 8:
+ case 12:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int generic_gcmaes_set_authsize(struct crypto_aead *tfm,
+ unsigned int authsize)
+{
+ switch (authsize) {
+ case 4:
+ case 8:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * This is the setkey function for the x86_64 implementations of AES-GCM. It
+ * saves the RFC4106 nonce if applicable, expands the AES key, and precomputes
+ * powers of the hash key.
+ *
+ * To comply with the crypto_aead API, this has to be usable in no-SIMD context.
+ * For that reason, this function includes a portable C implementation of the
+ * needed logic. However, the portable C implementation is very slow, taking
+ * about the same time as encrypting 37 KB of data. To be ready for users that
+ * may set a key even somewhat frequently, we therefore also include a SIMD
+ * assembly implementation, expanding the AES key using AES-NI and precomputing
+ * the hash key powers using PCLMULQDQ or VPCLMULQDQ.
+ */
+static int gcm_setkey(struct crypto_aead *tfm, const u8 *raw_key,
+ unsigned int keylen, int flags)
+{
+ struct aes_gcm_key *key = aes_gcm_key_get(tfm, flags);
+ int err;
+
+ if (flags & FLAG_RFC4106) {
+ if (keylen < 4)
+ return -EINVAL;
+ keylen -= 4;
+ key->rfc4106_nonce = get_unaligned_be32(raw_key + keylen);
+ }
- memcpy(iv, req->iv, 12);
- *((__be32 *)(iv+12)) = counter;
+ /* The assembly code assumes the following offsets. */
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_aesni, base.aes_key.key_enc) != 0);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_aesni, base.aes_key.key_length) != 480);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_aesni, h_powers) != 496);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_aesni, h_powers_xored) != 624);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_aesni, h_times_x64) != 688);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_avx10, base.aes_key.key_enc) != 0);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_avx10, base.aes_key.key_length) != 480);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_avx10, h_powers) != 512);
+ BUILD_BUG_ON(offsetof(struct aes_gcm_key_avx10, padding) != 768);
+
+ if (likely(crypto_simd_usable())) {
+ err = aes_check_keylen(keylen);
+ if (err)
+ return err;
+ kernel_fpu_begin();
+ aesni_set_key(&key->aes_key, raw_key, keylen);
+ aes_gcm_precompute(key, flags);
+ kernel_fpu_end();
+ } else {
+ static const u8 x_to_the_minus1[16] __aligned(__alignof__(be128)) = {
+ [0] = 0xc2, [15] = 1
+ };
+ static const u8 x_to_the_63[16] __aligned(__alignof__(be128)) = {
+ [7] = 1,
+ };
+ be128 h1 = {};
+ be128 h;
+ int i;
+
+ err = aes_expandkey(&key->aes_key, raw_key, keylen);
+ if (err)
+ return err;
- return gcmaes_encrypt(req, req->assoclen, ctx->hash_subkey, iv,
- aes_ctx);
+ /* Encrypt the all-zeroes block to get the hash key H^1 */
+ aes_encrypt(&key->aes_key, (u8 *)&h1, (u8 *)&h1);
+
+ /* Compute H^1 * x^-1 */
+ h = h1;
+ gf128mul_lle(&h, (const be128 *)x_to_the_minus1);
+
+ /* Compute the needed key powers */
+ if (flags & (FLAG_AVX10_256 | FLAG_AVX10_512)) {
+ struct aes_gcm_key_avx10 *k = AES_GCM_KEY_AVX10(key);
+
+ for (i = ARRAY_SIZE(k->h_powers) - 1; i >= 0; i--) {
+ k->h_powers[i][0] = be64_to_cpu(h.b);
+ k->h_powers[i][1] = be64_to_cpu(h.a);
+ gf128mul_lle(&h, &h1);
+ }
+ memset(k->padding, 0, sizeof(k->padding));
+ } else {
+ struct aes_gcm_key_aesni *k = AES_GCM_KEY_AESNI(key);
+
+ for (i = ARRAY_SIZE(k->h_powers) - 1; i >= 0; i--) {
+ k->h_powers[i][0] = be64_to_cpu(h.b);
+ k->h_powers[i][1] = be64_to_cpu(h.a);
+ k->h_powers_xored[i] = k->h_powers[i][0] ^
+ k->h_powers[i][1];
+ gf128mul_lle(&h, &h1);
+ }
+ gf128mul_lle(&h1, (const be128 *)x_to_the_63);
+ k->h_times_x64[0] = be64_to_cpu(h1.b);
+ k->h_times_x64[1] = be64_to_cpu(h1.a);
+ }
+ }
+ return 0;
}
-static int generic_gcmaes_decrypt(struct aead_request *req)
+/*
+ * Initialize @ghash_acc, then pass all @assoclen bytes of associated data
+ * (a.k.a. additional authenticated data) from @sg_src through the GHASH update
+ * assembly function. kernel_fpu_begin() must have already been called.
+ */
+static void gcm_process_assoc(const struct aes_gcm_key *key, u8 ghash_acc[16],
+ struct scatterlist *sg_src, unsigned int assoclen,
+ int flags)
+{
+ struct scatter_walk walk;
+ /*
+ * The assembly function requires that the length of any non-last
+ * segment of associated data be a multiple of 16 bytes, so this
+ * function does the buffering needed to achieve that.
+ */
+ unsigned int pos = 0;
+ u8 buf[16];
+
+ memset(ghash_acc, 0, 16);
+ scatterwalk_start(&walk, sg_src);
+
+ while (assoclen) {
+ unsigned int len_this_page = scatterwalk_clamp(&walk, assoclen);
+ void *mapped = scatterwalk_map(&walk);
+ const void *src = mapped;
+ unsigned int len;
+
+ assoclen -= len_this_page;
+ scatterwalk_advance(&walk, len_this_page);
+ if (unlikely(pos)) {
+ len = min(len_this_page, 16 - pos);
+ memcpy(&buf[pos], src, len);
+ pos += len;
+ src += len;
+ len_this_page -= len;
+ if (pos < 16)
+ goto next;
+ aes_gcm_aad_update(key, ghash_acc, buf, 16, flags);
+ pos = 0;
+ }
+ len = len_this_page;
+ if (unlikely(assoclen)) /* Not the last segment yet? */
+ len = round_down(len, 16);
+ aes_gcm_aad_update(key, ghash_acc, src, len, flags);
+ src += len;
+ len_this_page -= len;
+ if (unlikely(len_this_page)) {
+ memcpy(buf, src, len_this_page);
+ pos = len_this_page;
+ }
+next:
+ scatterwalk_unmap(mapped);
+ scatterwalk_pagedone(&walk, 0, assoclen);
+ if (need_resched()) {
+ kernel_fpu_end();
+ kernel_fpu_begin();
+ }
+ }
+ if (unlikely(pos))
+ aes_gcm_aad_update(key, ghash_acc, buf, pos, flags);
+}
+
+
+/* __always_inline to optimize out the branches based on @flags */
+static __always_inline int
+gcm_crypt(struct aead_request *req, int flags)
{
- __be32 counter = cpu_to_be32(1);
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- struct generic_gcmaes_ctx *ctx = generic_gcmaes_ctx_get(tfm);
- void *aes_ctx = &(ctx->aes_key_expanded);
- u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8);
- u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN);
+ const struct aes_gcm_key *key = aes_gcm_key_get(tfm, flags);
+ unsigned int assoclen = req->assoclen;
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ u8 ghash_acc[16]; /* GHASH accumulator */
+ u32 le_ctr[4]; /* Counter in little-endian format */
+ int taglen;
+ int err;
+
+ /* Initialize the counter and determine the associated data length. */
+ le_ctr[0] = 2;
+ if (flags & FLAG_RFC4106) {
+ if (unlikely(assoclen != 16 && assoclen != 20))
+ return -EINVAL;
+ assoclen -= 8;
+ le_ctr[1] = get_unaligned_be32(req->iv + 4);
+ le_ctr[2] = get_unaligned_be32(req->iv + 0);
+ le_ctr[3] = key->rfc4106_nonce; /* already byte-swapped */
+ } else {
+ le_ctr[1] = get_unaligned_be32(req->iv + 8);
+ le_ctr[2] = get_unaligned_be32(req->iv + 4);
+ le_ctr[3] = get_unaligned_be32(req->iv + 0);
+ }
- memcpy(iv, req->iv, 12);
- *((__be32 *)(iv+12)) = counter;
+ /* Begin walking through the plaintext or ciphertext. */
+ if (flags & FLAG_ENC)
+ err = skcipher_walk_aead_encrypt(&walk, req, false);
+ else
+ err = skcipher_walk_aead_decrypt(&walk, req, false);
- return gcmaes_decrypt(req, req->assoclen, ctx->hash_subkey, iv,
- aes_ctx);
+ /*
+ * Since the AES-GCM assembly code requires that at least three assembly
+ * functions be called to process any message (this is needed to support
+ * incremental updates cleanly), to reduce overhead we try to do all
+ * three calls in the same kernel FPU section if possible. We close the
+ * section and start a new one if there are multiple data segments or if
+ * rescheduling is needed while processing the associated data.
+ */
+ kernel_fpu_begin();
+
+ /* Pass the associated data through GHASH. */
+ gcm_process_assoc(key, ghash_acc, req->src, assoclen, flags);
+
+ /* En/decrypt the data and pass the ciphertext through GHASH. */
+ while ((nbytes = walk.nbytes) != 0) {
+ if (unlikely(nbytes < walk.total)) {
+ /*
+ * Non-last segment. In this case, the assembly
+ * function requires that the length be a multiple of 16
+ * (AES_BLOCK_SIZE) bytes. The needed buffering of up
+ * to 16 bytes is handled by the skcipher_walk. Here we
+ * just need to round down to a multiple of 16.
+ */
+ nbytes = round_down(nbytes, AES_BLOCK_SIZE);
+ aes_gcm_update(key, le_ctr, ghash_acc,
+ walk.src.virt.addr, walk.dst.virt.addr,
+ nbytes, flags);
+ le_ctr[0] += nbytes / AES_BLOCK_SIZE;
+ kernel_fpu_end();
+ err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+ kernel_fpu_begin();
+ } else {
+ /* Last segment: process all remaining data. */
+ aes_gcm_update(key, le_ctr, ghash_acc,
+ walk.src.virt.addr, walk.dst.virt.addr,
+ nbytes, flags);
+ err = skcipher_walk_done(&walk, 0);
+ /*
+ * The low word of the counter isn't used by the
+ * finalize, so there's no need to increment it here.
+ */
+ }
+ }
+ if (err)
+ goto out;
+
+ /* Finalize */
+ taglen = crypto_aead_authsize(tfm);
+ if (flags & FLAG_ENC) {
+ /* Finish computing the auth tag. */
+ aes_gcm_enc_final(key, le_ctr, ghash_acc, assoclen,
+ req->cryptlen, flags);
+
+ /* Store the computed auth tag in the dst scatterlist. */
+ scatterwalk_map_and_copy(ghash_acc, req->dst, req->assoclen +
+ req->cryptlen, taglen, 1);
+ } else {
+ unsigned int datalen = req->cryptlen - taglen;
+ u8 tag[16];
+
+ /* Get the transmitted auth tag from the src scatterlist. */
+ scatterwalk_map_and_copy(tag, req->src, req->assoclen + datalen,
+ taglen, 0);
+ /*
+ * Finish computing the auth tag and compare it to the
+ * transmitted one. The assembly function does the actual tag
+ * comparison. Here, just check the boolean result.
+ */
+ if (!aes_gcm_dec_final(key, le_ctr, ghash_acc, assoclen,
+ datalen, tag, taglen, flags))
+ err = -EBADMSG;
+ }
+out:
+ kernel_fpu_end();
+ return err;
}
-static struct aead_alg aesni_aeads[] = { {
- .setkey = common_rfc4106_set_key,
- .setauthsize = common_rfc4106_set_authsize,
- .encrypt = helper_rfc4106_encrypt,
- .decrypt = helper_rfc4106_decrypt,
- .ivsize = GCM_RFC4106_IV_SIZE,
- .maxauthsize = 16,
- .base = {
- .cra_name = "__rfc4106(gcm(aes))",
- .cra_driver_name = "__rfc4106-gcm-aesni",
- .cra_priority = 400,
- .cra_flags = CRYPTO_ALG_INTERNAL,
- .cra_blocksize = 1,
- .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx),
- .cra_alignmask = 0,
- .cra_module = THIS_MODULE,
- },
-}, {
- .setkey = generic_gcmaes_set_key,
- .setauthsize = generic_gcmaes_set_authsize,
- .encrypt = generic_gcmaes_encrypt,
- .decrypt = generic_gcmaes_decrypt,
- .ivsize = GCM_AES_IV_SIZE,
- .maxauthsize = 16,
- .base = {
- .cra_name = "__gcm(aes)",
- .cra_driver_name = "__generic-gcm-aesni",
- .cra_priority = 400,
- .cra_flags = CRYPTO_ALG_INTERNAL,
- .cra_blocksize = 1,
- .cra_ctxsize = sizeof(struct generic_gcmaes_ctx),
- .cra_alignmask = 0,
- .cra_module = THIS_MODULE,
- },
-} };
-#else
-static struct aead_alg aesni_aeads[0];
+#define DEFINE_GCM_ALGS(suffix, flags, generic_driver_name, rfc_driver_name, \
+ ctxsize, priority) \
+ \
+static int gcm_setkey_##suffix(struct crypto_aead *tfm, const u8 *raw_key, \
+ unsigned int keylen) \
+{ \
+ return gcm_setkey(tfm, raw_key, keylen, (flags)); \
+} \
+ \
+static int gcm_encrypt_##suffix(struct aead_request *req) \
+{ \
+ return gcm_crypt(req, (flags) | FLAG_ENC); \
+} \
+ \
+static int gcm_decrypt_##suffix(struct aead_request *req) \
+{ \
+ return gcm_crypt(req, (flags)); \
+} \
+ \
+static int rfc4106_setkey_##suffix(struct crypto_aead *tfm, const u8 *raw_key, \
+ unsigned int keylen) \
+{ \
+ return gcm_setkey(tfm, raw_key, keylen, (flags) | FLAG_RFC4106); \
+} \
+ \
+static int rfc4106_encrypt_##suffix(struct aead_request *req) \
+{ \
+ return gcm_crypt(req, (flags) | FLAG_RFC4106 | FLAG_ENC); \
+} \
+ \
+static int rfc4106_decrypt_##suffix(struct aead_request *req) \
+{ \
+ return gcm_crypt(req, (flags) | FLAG_RFC4106); \
+} \
+ \
+static struct aead_alg aes_gcm_algs_##suffix[] = { { \
+ .setkey = gcm_setkey_##suffix, \
+ .setauthsize = generic_gcmaes_set_authsize, \
+ .encrypt = gcm_encrypt_##suffix, \
+ .decrypt = gcm_decrypt_##suffix, \
+ .ivsize = GCM_AES_IV_SIZE, \
+ .chunksize = AES_BLOCK_SIZE, \
+ .maxauthsize = 16, \
+ .base = { \
+ .cra_name = "__gcm(aes)", \
+ .cra_driver_name = "__" generic_driver_name, \
+ .cra_priority = (priority), \
+ .cra_flags = CRYPTO_ALG_INTERNAL, \
+ .cra_blocksize = 1, \
+ .cra_ctxsize = (ctxsize), \
+ .cra_module = THIS_MODULE, \
+ }, \
+}, { \
+ .setkey = rfc4106_setkey_##suffix, \
+ .setauthsize = common_rfc4106_set_authsize, \
+ .encrypt = rfc4106_encrypt_##suffix, \
+ .decrypt = rfc4106_decrypt_##suffix, \
+ .ivsize = GCM_RFC4106_IV_SIZE, \
+ .chunksize = AES_BLOCK_SIZE, \
+ .maxauthsize = 16, \
+ .base = { \
+ .cra_name = "__rfc4106(gcm(aes))", \
+ .cra_driver_name = "__" rfc_driver_name, \
+ .cra_priority = (priority), \
+ .cra_flags = CRYPTO_ALG_INTERNAL, \
+ .cra_blocksize = 1, \
+ .cra_ctxsize = (ctxsize), \
+ .cra_module = THIS_MODULE, \
+ }, \
+} }; \
+ \
+static struct simd_aead_alg *aes_gcm_simdalgs_##suffix[2] \
+
+/* aes_gcm_algs_aesni */
+DEFINE_GCM_ALGS(aesni, /* no flags */ 0,
+ "generic-gcm-aesni", "rfc4106-gcm-aesni",
+ AES_GCM_KEY_AESNI_SIZE, 400);
+
+/* aes_gcm_algs_aesni_avx */
+DEFINE_GCM_ALGS(aesni_avx, FLAG_AVX,
+ "generic-gcm-aesni-avx", "rfc4106-gcm-aesni-avx",
+ AES_GCM_KEY_AESNI_SIZE, 500);
+
+#if defined(CONFIG_AS_VAES) && defined(CONFIG_AS_VPCLMULQDQ)
+/* aes_gcm_algs_vaes_avx10_256 */
+DEFINE_GCM_ALGS(vaes_avx10_256, FLAG_AVX10_256,
+ "generic-gcm-vaes-avx10_256", "rfc4106-gcm-vaes-avx10_256",
+ AES_GCM_KEY_AVX10_SIZE, 700);
+
+/* aes_gcm_algs_vaes_avx10_512 */
+DEFINE_GCM_ALGS(vaes_avx10_512, FLAG_AVX10_512,
+ "generic-gcm-vaes-avx10_512", "rfc4106-gcm-vaes-avx10_512",
+ AES_GCM_KEY_AVX10_SIZE, 800);
+#endif /* CONFIG_AS_VAES && CONFIG_AS_VPCLMULQDQ */
+
+/*
+ * This is a list of CPU models that are known to suffer from downclocking when
+ * zmm registers (512-bit vectors) are used. On these CPUs, the AES mode
+ * implementations with zmm registers won't be used by default. Implementations
+ * with ymm registers (256-bit vectors) will be used by default instead.
+ */
+static const struct x86_cpu_id zmm_exclusion_list[] = {
+ X86_MATCH_VFM(INTEL_SKYLAKE_X, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_L, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_NNPI, 0),
+ X86_MATCH_VFM(INTEL_TIGERLAKE_L, 0),
+ X86_MATCH_VFM(INTEL_TIGERLAKE, 0),
+ /* Allow Rocket Lake and later, and Sapphire Rapids and later. */
+ /* Also allow AMD CPUs (starting with Zen 4, the first with AVX-512). */
+ {},
+};
+
+static int __init register_avx_algs(void)
+{
+ int err;
+
+ if (!boot_cpu_has(X86_FEATURE_AVX))
+ return 0;
+ err = simd_register_skciphers_compat(&aes_xts_alg_aesni_avx, 1,
+ &aes_xts_simdalg_aesni_avx);
+ if (err)
+ return err;
+ err = simd_register_aeads_compat(aes_gcm_algs_aesni_avx,
+ ARRAY_SIZE(aes_gcm_algs_aesni_avx),
+ aes_gcm_simdalgs_aesni_avx);
+ if (err)
+ return err;
+#if defined(CONFIG_AS_VAES) && defined(CONFIG_AS_VPCLMULQDQ)
+ if (!boot_cpu_has(X86_FEATURE_AVX2) ||
+ !boot_cpu_has(X86_FEATURE_VAES) ||
+ !boot_cpu_has(X86_FEATURE_VPCLMULQDQ) ||
+ !boot_cpu_has(X86_FEATURE_PCLMULQDQ) ||
+ !cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL))
+ return 0;
+ err = simd_register_skciphers_compat(&aes_xts_alg_vaes_avx2, 1,
+ &aes_xts_simdalg_vaes_avx2);
+ if (err)
+ return err;
+
+ if (!boot_cpu_has(X86_FEATURE_AVX512BW) ||
+ !boot_cpu_has(X86_FEATURE_AVX512VL) ||
+ !boot_cpu_has(X86_FEATURE_BMI2) ||
+ !cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM |
+ XFEATURE_MASK_AVX512, NULL))
+ return 0;
+
+ err = simd_register_skciphers_compat(&aes_xts_alg_vaes_avx10_256, 1,
+ &aes_xts_simdalg_vaes_avx10_256);
+ if (err)
+ return err;
+ err = simd_register_aeads_compat(aes_gcm_algs_vaes_avx10_256,
+ ARRAY_SIZE(aes_gcm_algs_vaes_avx10_256),
+ aes_gcm_simdalgs_vaes_avx10_256);
+ if (err)
+ return err;
+
+ if (x86_match_cpu(zmm_exclusion_list)) {
+ int i;
+
+ aes_xts_alg_vaes_avx10_512.base.cra_priority = 1;
+ for (i = 0; i < ARRAY_SIZE(aes_gcm_algs_vaes_avx10_512); i++)
+ aes_gcm_algs_vaes_avx10_512[i].base.cra_priority = 1;
+ }
+
+ err = simd_register_skciphers_compat(&aes_xts_alg_vaes_avx10_512, 1,
+ &aes_xts_simdalg_vaes_avx10_512);
+ if (err)
+ return err;
+ err = simd_register_aeads_compat(aes_gcm_algs_vaes_avx10_512,
+ ARRAY_SIZE(aes_gcm_algs_vaes_avx10_512),
+ aes_gcm_simdalgs_vaes_avx10_512);
+ if (err)
+ return err;
+#endif /* CONFIG_AS_VAES && CONFIG_AS_VPCLMULQDQ */
+ return 0;
+}
+
+static void unregister_avx_algs(void)
+{
+ if (aes_xts_simdalg_aesni_avx)
+ simd_unregister_skciphers(&aes_xts_alg_aesni_avx, 1,
+ &aes_xts_simdalg_aesni_avx);
+ if (aes_gcm_simdalgs_aesni_avx[0])
+ simd_unregister_aeads(aes_gcm_algs_aesni_avx,
+ ARRAY_SIZE(aes_gcm_algs_aesni_avx),
+ aes_gcm_simdalgs_aesni_avx);
+#if defined(CONFIG_AS_VAES) && defined(CONFIG_AS_VPCLMULQDQ)
+ if (aes_xts_simdalg_vaes_avx2)
+ simd_unregister_skciphers(&aes_xts_alg_vaes_avx2, 1,
+ &aes_xts_simdalg_vaes_avx2);
+ if (aes_xts_simdalg_vaes_avx10_256)
+ simd_unregister_skciphers(&aes_xts_alg_vaes_avx10_256, 1,
+ &aes_xts_simdalg_vaes_avx10_256);
+ if (aes_gcm_simdalgs_vaes_avx10_256[0])
+ simd_unregister_aeads(aes_gcm_algs_vaes_avx10_256,
+ ARRAY_SIZE(aes_gcm_algs_vaes_avx10_256),
+ aes_gcm_simdalgs_vaes_avx10_256);
+ if (aes_xts_simdalg_vaes_avx10_512)
+ simd_unregister_skciphers(&aes_xts_alg_vaes_avx10_512, 1,
+ &aes_xts_simdalg_vaes_avx10_512);
+ if (aes_gcm_simdalgs_vaes_avx10_512[0])
+ simd_unregister_aeads(aes_gcm_algs_vaes_avx10_512,
+ ARRAY_SIZE(aes_gcm_algs_vaes_avx10_512),
+ aes_gcm_simdalgs_vaes_avx10_512);
#endif
+}
+#else /* CONFIG_X86_64 */
+static struct aead_alg aes_gcm_algs_aesni[0];
+static struct simd_aead_alg *aes_gcm_simdalgs_aesni[0];
-static struct simd_aead_alg *aesni_simd_aeads[ARRAY_SIZE(aesni_aeads)];
+static int __init register_avx_algs(void)
+{
+ return 0;
+}
+
+static void unregister_avx_algs(void)
+{
+}
+#endif /* !CONFIG_X86_64 */
static const struct x86_cpu_id aesni_cpu_id[] = {
X86_MATCH_FEATURE(X86_FEATURE_AES, NULL),
@@ -1235,17 +1680,6 @@ static int __init aesni_init(void)
if (!x86_match_cpu(aesni_cpu_id))
return -ENODEV;
#ifdef CONFIG_X86_64
- if (boot_cpu_has(X86_FEATURE_AVX2)) {
- pr_info("AVX2 version of gcm_enc/dec engaged.\n");
- static_branch_enable(&gcm_use_avx);
- static_branch_enable(&gcm_use_avx2);
- } else
- if (boot_cpu_has(X86_FEATURE_AVX)) {
- pr_info("AVX version of gcm_enc/dec engaged.\n");
- static_branch_enable(&gcm_use_avx);
- } else {
- pr_info("SSE version of gcm_enc/dec engaged.\n");
- }
if (boot_cpu_has(X86_FEATURE_AVX)) {
/* optimize performance of ctr mode encryption transform */
static_call_update(aesni_ctr_enc_tfm, aesni_ctr_enc_avx_tfm);
@@ -1263,8 +1697,9 @@ static int __init aesni_init(void)
if (err)
goto unregister_cipher;
- err = simd_register_aeads_compat(aesni_aeads, ARRAY_SIZE(aesni_aeads),
- aesni_simd_aeads);
+ err = simd_register_aeads_compat(aes_gcm_algs_aesni,
+ ARRAY_SIZE(aes_gcm_algs_aesni),
+ aes_gcm_simdalgs_aesni);
if (err)
goto unregister_skciphers;
@@ -1276,14 +1711,22 @@ static int __init aesni_init(void)
goto unregister_aeads;
#endif /* CONFIG_X86_64 */
+ err = register_avx_algs();
+ if (err)
+ goto unregister_avx;
+
return 0;
+unregister_avx:
+ unregister_avx_algs();
#ifdef CONFIG_X86_64
+ if (aesni_simd_xctr)
+ simd_unregister_skciphers(&aesni_xctr, 1, &aesni_simd_xctr);
unregister_aeads:
- simd_unregister_aeads(aesni_aeads, ARRAY_SIZE(aesni_aeads),
- aesni_simd_aeads);
#endif /* CONFIG_X86_64 */
-
+ simd_unregister_aeads(aes_gcm_algs_aesni,
+ ARRAY_SIZE(aes_gcm_algs_aesni),
+ aes_gcm_simdalgs_aesni);
unregister_skciphers:
simd_unregister_skciphers(aesni_skciphers, ARRAY_SIZE(aesni_skciphers),
aesni_simd_skciphers);
@@ -1294,8 +1737,9 @@ unregister_cipher:
static void __exit aesni_exit(void)
{
- simd_unregister_aeads(aesni_aeads, ARRAY_SIZE(aesni_aeads),
- aesni_simd_aeads);
+ simd_unregister_aeads(aes_gcm_algs_aesni,
+ ARRAY_SIZE(aes_gcm_algs_aesni),
+ aes_gcm_simdalgs_aesni);
simd_unregister_skciphers(aesni_skciphers, ARRAY_SIZE(aesni_skciphers),
aesni_simd_skciphers);
crypto_unregister_alg(&aesni_cipher_alg);
@@ -1303,6 +1747,7 @@ static void __exit aesni_exit(void)
if (boot_cpu_has(X86_FEATURE_AVX))
simd_unregister_skciphers(&aesni_xctr, 1, &aesni_simd_xctr);
#endif /* CONFIG_X86_64 */
+ unregister_avx_algs();
}
late_initcall(aesni_init);
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c
index 98cf3b4e4c9f..9f5e342b9845 100644
--- a/arch/x86/crypto/crc32-pclmul_glue.c
+++ b/arch/x86/crypto/crc32-pclmul_glue.c
@@ -195,6 +195,7 @@ module_init(crc32_pclmul_mod_init);
module_exit(crc32_pclmul_mod_fini);
MODULE_AUTHOR("Alexander Boyko <alexander_boyko@xyratex.com>");
+MODULE_DESCRIPTION("CRC32 algorithm (IEEE 802.3) accelerated with PCLMULQDQ");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CRYPTO("crc32");
diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c
index d55fa9e9b9e6..dcfc0de333de 100644
--- a/arch/x86/crypto/curve25519-x86_64.c
+++ b/arch/x86/crypto/curve25519-x86_64.c
@@ -1720,5 +1720,6 @@ module_exit(curve25519_mod_exit);
MODULE_ALIAS_CRYPTO("curve25519");
MODULE_ALIAS_CRYPTO("curve25519-x86");
+MODULE_DESCRIPTION("Curve25519 algorithm, ADX optimized");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
diff --git a/arch/x86/crypto/nh-avx2-x86_64.S b/arch/x86/crypto/nh-avx2-x86_64.S
index ef73a3ab8726..791386d9a83a 100644
--- a/arch/x86/crypto/nh-avx2-x86_64.S
+++ b/arch/x86/crypto/nh-avx2-x86_64.S
@@ -154,5 +154,6 @@ SYM_TYPED_FUNC_START(nh_avx2)
vpaddq T1, T0, T0
vpaddq T4, T0, T0
vmovdqu T0, (HASH)
+ vzeroupper
RET
SYM_FUNC_END(nh_avx2)
diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c
index 1dfb8af48a3c..08ff4b489f7e 100644
--- a/arch/x86/crypto/poly1305_glue.c
+++ b/arch/x86/crypto/poly1305_glue.c
@@ -12,7 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sizes.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/simd.h>
asmlinkage void poly1305_init_x86_64(void *ctx,
@@ -269,7 +269,7 @@ static int __init poly1305_simd_mod_init(void)
boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX512F) &&
cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM | XFEATURE_MASK_AVX512, NULL) &&
/* Skylake downclocks unacceptably much when using zmm, but later generations are fast. */
- boot_cpu_data.x86_model != INTEL_FAM6_SKYLAKE_X)
+ boot_cpu_data.x86_vfm != INTEL_SKYLAKE_X)
static_branch_enable(&poly1305_use_avx512);
return IS_REACHABLE(CONFIG_CRYPTO_HASH) ? crypto_register_shash(&alg) : 0;
}
diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S
index 9918212faf91..0ffb072be956 100644
--- a/arch/x86/crypto/sha256-avx2-asm.S
+++ b/arch/x86/crypto/sha256-avx2-asm.S
@@ -716,6 +716,7 @@ SYM_TYPED_FUNC_START(sha256_transform_rorx)
popq %r13
popq %r12
popq %rbx
+ vzeroupper
RET
SYM_FUNC_END(sha256_transform_rorx)
diff --git a/arch/x86/crypto/sha256_ni_asm.S b/arch/x86/crypto/sha256_ni_asm.S
index 537b6dcd7ed8..d515a55a3bc1 100644
--- a/arch/x86/crypto/sha256_ni_asm.S
+++ b/arch/x86/crypto/sha256_ni_asm.S
@@ -62,20 +62,41 @@
#define SHA256CONSTANTS %rax
-#define MSG %xmm0
+#define MSG %xmm0 /* sha256rnds2 implicit operand */
#define STATE0 %xmm1
#define STATE1 %xmm2
-#define MSGTMP0 %xmm3
-#define MSGTMP1 %xmm4
-#define MSGTMP2 %xmm5
-#define MSGTMP3 %xmm6
-#define MSGTMP4 %xmm7
+#define MSG0 %xmm3
+#define MSG1 %xmm4
+#define MSG2 %xmm5
+#define MSG3 %xmm6
+#define TMP %xmm7
#define SHUF_MASK %xmm8
#define ABEF_SAVE %xmm9
#define CDGH_SAVE %xmm10
+.macro do_4rounds i, m0, m1, m2, m3
+.if \i < 16
+ movdqu \i*4(DATA_PTR), \m0
+ pshufb SHUF_MASK, \m0
+.endif
+ movdqa (\i-32)*4(SHA256CONSTANTS), MSG
+ paddd \m0, MSG
+ sha256rnds2 STATE0, STATE1
+.if \i >= 12 && \i < 60
+ movdqa \m0, TMP
+ palignr $4, \m3, TMP
+ paddd TMP, \m1
+ sha256msg2 \m0, \m1
+.endif
+ punpckhqdq MSG, MSG
+ sha256rnds2 STATE1, STATE0
+.if \i >= 4 && \i < 52
+ sha256msg1 \m0, \m3
+.endif
+.endm
+
/*
* Intel SHA Extensions optimized implementation of a SHA-256 update function
*
@@ -86,9 +107,6 @@
* store partial blocks. All message padding and hash value initialization must
* be done outside the update function.
*
- * The indented lines in the loop are instructions related to rounds processing.
- * The non-indented lines are instructions related to the message schedule.
- *
* void sha256_ni_transform(uint32_t *digest, const void *data,
uint32_t numBlocks);
* digest : pointer to digest
@@ -108,202 +126,29 @@ SYM_TYPED_FUNC_START(sha256_ni_transform)
* Need to reorder these appropriately
* DCBA, HGFE -> ABEF, CDGH
*/
- movdqu 0*16(DIGEST_PTR), STATE0
- movdqu 1*16(DIGEST_PTR), STATE1
+ movdqu 0*16(DIGEST_PTR), STATE0 /* DCBA */
+ movdqu 1*16(DIGEST_PTR), STATE1 /* HGFE */
- pshufd $0xB1, STATE0, STATE0 /* CDAB */
- pshufd $0x1B, STATE1, STATE1 /* EFGH */
- movdqa STATE0, MSGTMP4
- palignr $8, STATE1, STATE0 /* ABEF */
- pblendw $0xF0, MSGTMP4, STATE1 /* CDGH */
+ movdqa STATE0, TMP
+ punpcklqdq STATE1, STATE0 /* FEBA */
+ punpckhqdq TMP, STATE1 /* DCHG */
+ pshufd $0x1B, STATE0, STATE0 /* ABEF */
+ pshufd $0xB1, STATE1, STATE1 /* CDGH */
movdqa PSHUFFLE_BYTE_FLIP_MASK(%rip), SHUF_MASK
- lea K256(%rip), SHA256CONSTANTS
+ lea K256+32*4(%rip), SHA256CONSTANTS
.Lloop0:
/* Save hash values for addition after rounds */
movdqa STATE0, ABEF_SAVE
movdqa STATE1, CDGH_SAVE
- /* Rounds 0-3 */
- movdqu 0*16(DATA_PTR), MSG
- pshufb SHUF_MASK, MSG
- movdqa MSG, MSGTMP0
- paddd 0*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
-
- /* Rounds 4-7 */
- movdqu 1*16(DATA_PTR), MSG
- pshufb SHUF_MASK, MSG
- movdqa MSG, MSGTMP1
- paddd 1*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP1, MSGTMP0
-
- /* Rounds 8-11 */
- movdqu 2*16(DATA_PTR), MSG
- pshufb SHUF_MASK, MSG
- movdqa MSG, MSGTMP2
- paddd 2*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP2, MSGTMP1
-
- /* Rounds 12-15 */
- movdqu 3*16(DATA_PTR), MSG
- pshufb SHUF_MASK, MSG
- movdqa MSG, MSGTMP3
- paddd 3*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP3, MSGTMP4
- palignr $4, MSGTMP2, MSGTMP4
- paddd MSGTMP4, MSGTMP0
- sha256msg2 MSGTMP3, MSGTMP0
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP3, MSGTMP2
-
- /* Rounds 16-19 */
- movdqa MSGTMP0, MSG
- paddd 4*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP0, MSGTMP4
- palignr $4, MSGTMP3, MSGTMP4
- paddd MSGTMP4, MSGTMP1
- sha256msg2 MSGTMP0, MSGTMP1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP0, MSGTMP3
-
- /* Rounds 20-23 */
- movdqa MSGTMP1, MSG
- paddd 5*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP1, MSGTMP4
- palignr $4, MSGTMP0, MSGTMP4
- paddd MSGTMP4, MSGTMP2
- sha256msg2 MSGTMP1, MSGTMP2
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP1, MSGTMP0
-
- /* Rounds 24-27 */
- movdqa MSGTMP2, MSG
- paddd 6*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP2, MSGTMP4
- palignr $4, MSGTMP1, MSGTMP4
- paddd MSGTMP4, MSGTMP3
- sha256msg2 MSGTMP2, MSGTMP3
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP2, MSGTMP1
-
- /* Rounds 28-31 */
- movdqa MSGTMP3, MSG
- paddd 7*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP3, MSGTMP4
- palignr $4, MSGTMP2, MSGTMP4
- paddd MSGTMP4, MSGTMP0
- sha256msg2 MSGTMP3, MSGTMP0
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP3, MSGTMP2
-
- /* Rounds 32-35 */
- movdqa MSGTMP0, MSG
- paddd 8*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP0, MSGTMP4
- palignr $4, MSGTMP3, MSGTMP4
- paddd MSGTMP4, MSGTMP1
- sha256msg2 MSGTMP0, MSGTMP1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP0, MSGTMP3
-
- /* Rounds 36-39 */
- movdqa MSGTMP1, MSG
- paddd 9*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP1, MSGTMP4
- palignr $4, MSGTMP0, MSGTMP4
- paddd MSGTMP4, MSGTMP2
- sha256msg2 MSGTMP1, MSGTMP2
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP1, MSGTMP0
-
- /* Rounds 40-43 */
- movdqa MSGTMP2, MSG
- paddd 10*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP2, MSGTMP4
- palignr $4, MSGTMP1, MSGTMP4
- paddd MSGTMP4, MSGTMP3
- sha256msg2 MSGTMP2, MSGTMP3
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP2, MSGTMP1
-
- /* Rounds 44-47 */
- movdqa MSGTMP3, MSG
- paddd 11*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP3, MSGTMP4
- palignr $4, MSGTMP2, MSGTMP4
- paddd MSGTMP4, MSGTMP0
- sha256msg2 MSGTMP3, MSGTMP0
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP3, MSGTMP2
-
- /* Rounds 48-51 */
- movdqa MSGTMP0, MSG
- paddd 12*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP0, MSGTMP4
- palignr $4, MSGTMP3, MSGTMP4
- paddd MSGTMP4, MSGTMP1
- sha256msg2 MSGTMP0, MSGTMP1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
- sha256msg1 MSGTMP0, MSGTMP3
-
- /* Rounds 52-55 */
- movdqa MSGTMP1, MSG
- paddd 13*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP1, MSGTMP4
- palignr $4, MSGTMP0, MSGTMP4
- paddd MSGTMP4, MSGTMP2
- sha256msg2 MSGTMP1, MSGTMP2
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
-
- /* Rounds 56-59 */
- movdqa MSGTMP2, MSG
- paddd 14*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- movdqa MSGTMP2, MSGTMP4
- palignr $4, MSGTMP1, MSGTMP4
- paddd MSGTMP4, MSGTMP3
- sha256msg2 MSGTMP2, MSGTMP3
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
-
- /* Rounds 60-63 */
- movdqa MSGTMP3, MSG
- paddd 15*16(SHA256CONSTANTS), MSG
- sha256rnds2 STATE0, STATE1
- pshufd $0x0E, MSG, MSG
- sha256rnds2 STATE1, STATE0
+.irp i, 0, 16, 32, 48
+ do_4rounds (\i + 0), MSG0, MSG1, MSG2, MSG3
+ do_4rounds (\i + 4), MSG1, MSG2, MSG3, MSG0
+ do_4rounds (\i + 8), MSG2, MSG3, MSG0, MSG1
+ do_4rounds (\i + 12), MSG3, MSG0, MSG1, MSG2
+.endr
/* Add current hash values with previously saved */
paddd ABEF_SAVE, STATE0
@@ -315,14 +160,14 @@ SYM_TYPED_FUNC_START(sha256_ni_transform)
jne .Lloop0
/* Write hash values back in the correct order */
- pshufd $0x1B, STATE0, STATE0 /* FEBA */
- pshufd $0xB1, STATE1, STATE1 /* DCHG */
- movdqa STATE0, MSGTMP4
- pblendw $0xF0, STATE1, STATE0 /* DCBA */
- palignr $8, MSGTMP4, STATE1 /* HGFE */
-
- movdqu STATE0, 0*16(DIGEST_PTR)
- movdqu STATE1, 1*16(DIGEST_PTR)
+ movdqa STATE0, TMP
+ punpcklqdq STATE1, STATE0 /* GHEF */
+ punpckhqdq TMP, STATE1 /* ABCD */
+ pshufd $0xB1, STATE0, STATE0 /* HGFE */
+ pshufd $0x1B, STATE1, STATE1 /* DCBA */
+
+ movdqu STATE1, 0*16(DIGEST_PTR)
+ movdqu STATE0, 1*16(DIGEST_PTR)
.Ldone_hash:
diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S
index f08496cd6870..24973f42c43f 100644
--- a/arch/x86/crypto/sha512-avx2-asm.S
+++ b/arch/x86/crypto/sha512-avx2-asm.S
@@ -680,6 +680,7 @@ SYM_TYPED_FUNC_START(sha512_transform_rorx)
pop %r12
pop %rbx
+ vzeroupper
RET
SYM_FUNC_END(sha512_transform_rorx)
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 90454cf18e0d..1a1ecfa7f72a 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -5,6 +5,7 @@
* Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
*/
+#include <asm/cpu_device_id.h>
#include <crypto/algapi.h>
#include <crypto/twofish.h>
#include <linux/crypto.h>
@@ -107,10 +108,10 @@ static bool is_blacklisted_cpu(void)
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return false;
- if (boot_cpu_data.x86 == 0x06 &&
- (boot_cpu_data.x86_model == 0x1c ||
- boot_cpu_data.x86_model == 0x26 ||
- boot_cpu_data.x86_model == 0x36)) {
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_ATOM_BONNELL:
+ case INTEL_ATOM_BONNELL_MID:
+ case INTEL_ATOM_SALTWELL:
/*
* On Atom, twofish-3way is slower than original assembler
* implementation. Twofish-3way trades off some performance in
diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
index c93e7f5c2a06..ce1cc1622385 100644
--- a/arch/x86/entry/Makefile
+++ b/arch/x86/entry/Makefile
@@ -17,7 +17,7 @@ obj-y += common.o
obj-y += vdso/
obj-y += vsyscall/
-obj-$(CONFIG_PREEMPTION) += thunk_$(BITS).o
+obj-$(CONFIG_PREEMPTION) += thunk.o
CFLAGS_entry_fred.o += -fno-stack-protector
CFLAGS_REMOVE_entry_fred.o += -pg $(CC_FLAGS_FTRACE)
obj-$(CONFIG_X86_FRED) += entry_64_fred.o entry_fred.o
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index c779046cc3fe..ed0a5f2dc129 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -7,7 +7,6 @@
#include <asm/asm-offsets.h>
#include <asm/current.h>
#include <asm/errno.h>
-#include <asm/ia32_unistd.h>
#include <asm/thread_info.h>
#include <asm/segment.h>
#include <asm/irqflags.h>
@@ -90,10 +89,6 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
cld
- IBRS_ENTER
- UNTRAIN_RET
- CLEAR_BRANCH_HISTORY
-
/*
* SYSENTER doesn't filter flags, so we need to clear NT and AC
* ourselves. To save a few cycles, we can check whether
@@ -117,6 +112,16 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
jnz .Lsysenter_fix_flags
.Lsysenter_flags_fixed:
+ /*
+ * CPU bugs mitigations mechanisms can call other functions. They
+ * should be invoked after making sure TF is cleared because
+ * single-step is ignored only for instructions inside the
+ * entry_SYSENTER_compat function.
+ */
+ IBRS_ENTER
+ UNTRAIN_RET
+ CLEAR_BRANCH_HISTORY
+
movq %rsp, %rdi
call do_SYSENTER_32
jmp sysret32_from_system_call
diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c
index 89c1476fcdd9..f004a4dc74c2 100644
--- a/arch/x86/entry/entry_fred.c
+++ b/arch/x86/entry/entry_fred.c
@@ -117,6 +117,8 @@ static idtentry_t sysvec_table[NR_SYSTEM_VECTORS] __ro_after_init = {
SYSVEC(POSTED_INTR_VECTOR, kvm_posted_intr_ipi),
SYSVEC(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi),
SYSVEC(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi),
+
+ SYSVEC(POSTED_MSI_NOTIFICATION_VECTOR, posted_msi_notification),
};
static bool fred_setup_done __initdata;
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c
index c2235bae17ef..8cc9950d7104 100644
--- a/arch/x86/entry/syscall_32.c
+++ b/arch/x86/entry/syscall_32.c
@@ -14,9 +14,12 @@
#endif
#define __SYSCALL(nr, sym) extern long __ia32_##sym(const struct pt_regs *);
-
+#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __ia32_##sym(const struct pt_regs *);
#include <asm/syscalls_32.h>
-#undef __SYSCALL
+#undef __SYSCALL
+
+#undef __SYSCALL_NORETURN
+#define __SYSCALL_NORETURN __SYSCALL
/*
* The sys_call_table[] is no longer used for system calls, but
@@ -28,11 +31,10 @@
const sys_call_ptr_t sys_call_table[] = {
#include <asm/syscalls_32.h>
};
-#undef __SYSCALL
+#undef __SYSCALL
#endif
#define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs);
-
long ia32_sys_call(const struct pt_regs *regs, unsigned int nr)
{
switch (nr) {
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c
index 33b3f09e6f15..ba8354424860 100644
--- a/arch/x86/entry/syscall_64.c
+++ b/arch/x86/entry/syscall_64.c
@@ -8,8 +8,12 @@
#include <asm/syscall.h>
#define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
+#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
#include <asm/syscalls_64.h>
-#undef __SYSCALL
+#undef __SYSCALL
+
+#undef __SYSCALL_NORETURN
+#define __SYSCALL_NORETURN __SYSCALL
/*
* The sys_call_table[] is no longer used for system calls, but
@@ -20,10 +24,9 @@
const sys_call_ptr_t sys_call_table[] = {
#include <asm/syscalls_64.h>
};
-#undef __SYSCALL
+#undef __SYSCALL
#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
-
long x64_sys_call(const struct pt_regs *regs, unsigned int nr)
{
switch (nr) {
diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
index 03de4a932131..fb77908f44f3 100644
--- a/arch/x86/entry/syscall_x32.c
+++ b/arch/x86/entry/syscall_x32.c
@@ -8,11 +8,14 @@
#include <asm/syscall.h>
#define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
+#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
#include <asm/syscalls_x32.h>
-#undef __SYSCALL
+#undef __SYSCALL
-#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
+#undef __SYSCALL_NORETURN
+#define __SYSCALL_NORETURN __SYSCALL
+#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
long x32_sys_call(const struct pt_regs *regs, unsigned int nr)
{
switch (nr) {
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 5f8591ce7f25..534c74b14fab 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -1,8 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# 32-bit system call numbers and entry vectors
#
# The format is:
-# <number> <abi> <name> <entry point> <compat entry point>
+# <number> <abi> <name> <entry point> [<compat entry point> [noreturn]]
#
# The __ia32_sys and __ia32_compat_sys stubs are created on-the-fly for
# sys_*() system calls and compat_sys_*() compat system calls if
@@ -12,7 +13,7 @@
# The abi is always "i386" for this file.
#
0 i386 restart_syscall sys_restart_syscall
-1 i386 exit sys_exit
+1 i386 exit sys_exit - noreturn
2 i386 fork sys_fork
3 i386 read sys_read
4 i386 write sys_write
@@ -263,7 +264,7 @@
249 i386 io_cancel sys_io_cancel
250 i386 fadvise64 sys_ia32_fadvise64
# 251 is available for reuse (was briefly sys_set_zone_reclaim)
-252 i386 exit_group sys_exit_group
+252 i386 exit_group sys_exit_group - noreturn
253 i386 lookup_dcookie
254 i386 epoll_create sys_epoll_create
255 i386 epoll_ctl sys_epoll_ctl
@@ -420,7 +421,7 @@
412 i386 utimensat_time64 sys_utimensat
413 i386 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
414 i386 ppoll_time64 sys_ppoll compat_sys_ppoll_time64
-416 i386 io_pgetevents_time64 sys_io_pgetevents
+416 i386 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64
417 i386 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
418 i386 mq_timedsend_time64 sys_mq_timedsend
419 i386 mq_timedreceive_time64 sys_mq_timedreceive
@@ -466,3 +467,4 @@
459 i386 lsm_get_self_attr sys_lsm_get_self_attr
460 i386 lsm_set_self_attr sys_lsm_set_self_attr
461 i386 lsm_list_modules sys_lsm_list_modules
+462 i386 mseal sys_mseal
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 7e8d46f4147f..83073fa3c989 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -1,8 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# 64-bit system call numbers and entry vectors
#
# The format is:
-# <number> <abi> <name> <entry point>
+# <number> <abi> <name> <entry point> [<compat entry point> [noreturn]]
#
# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
#
@@ -68,7 +69,7 @@
57 common fork sys_fork
58 common vfork sys_vfork
59 64 execve sys_execve
-60 common exit sys_exit
+60 common exit sys_exit - noreturn
61 common wait4 sys_wait4
62 common kill sys_kill
63 common uname sys_newuname
@@ -239,7 +240,7 @@
228 common clock_gettime sys_clock_gettime
229 common clock_getres sys_clock_getres
230 common clock_nanosleep sys_clock_nanosleep
-231 common exit_group sys_exit_group
+231 common exit_group sys_exit_group - noreturn
232 common epoll_wait sys_epoll_wait
233 common epoll_ctl sys_epoll_ctl
234 common tgkill sys_tgkill
@@ -374,7 +375,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
-453 64 map_shadow_stack sys_map_shadow_stack
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
@@ -383,6 +384,8 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
+467 common uretprobe sys_uretprobe
#
# Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk.S
index 119ebdc3d362..119ebdc3d362 100644
--- a/arch/x86/entry/thunk_64.S
+++ b/arch/x86/entry/thunk.S
diff --git a/arch/x86/entry/thunk_32.S b/arch/x86/entry/thunk_32.S
deleted file mode 100644
index da37f42f4549..000000000000
--- a/arch/x86/entry/thunk_32.S
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Trampoline to trace irqs off. (otherwise CALLER_ADDR1 might crash)
- * Copyright 2008 by Steven Rostedt, Red Hat, Inc
- * (inspired by Andi Kleen's thunk_64.S)
- */
-
-#include <linux/export.h>
-#include <linux/linkage.h>
-#include <asm/asm.h>
-
-#include "calling.h"
-
-THUNK preempt_schedule_thunk, preempt_schedule
-THUNK preempt_schedule_notrace_thunk, preempt_schedule_notrace
-EXPORT_SYMBOL(preempt_schedule_thunk)
-EXPORT_SYMBOL(preempt_schedule_notrace_thunk)
-
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 3d64bcc403cf..c9216ac4fb1e 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -6,45 +6,20 @@
# Include the generic Makefile to check the built vDSO:
include $(srctree)/lib/vdso/Makefile
-# Sanitizer runtimes are unavailable and cannot be linked here.
-KASAN_SANITIZE := n
-KMSAN_SANITIZE_vclock_gettime.o := n
-KMSAN_SANITIZE_vdso32/vclock_gettime.o := n
-KMSAN_SANITIZE_vgetcpu.o := n
-KMSAN_SANITIZE_vdso32/vgetcpu.o := n
-
-UBSAN_SANITIZE := n
-KCSAN_SANITIZE := n
-OBJECT_FILES_NON_STANDARD := y
-
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-
# Files to link into the vDSO:
-vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
+vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vgetrandom.o vgetrandom-chacha.o
vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o
vobjs32-y += vdso32/vclock_gettime.o vdso32/vgetcpu.o
vobjs-$(CONFIG_X86_SGX) += vsgx.o
# Files to link into the kernel:
obj-y += vma.o extable.o
-KASAN_SANITIZE_vma.o := y
-UBSAN_SANITIZE_vma.o := y
-KCSAN_SANITIZE_vma.o := y
-
-OBJECT_FILES_NON_STANDARD_vma.o := n
-OBJECT_FILES_NON_STANDARD_extable.o := n
# vDSO images to build:
obj-$(CONFIG_X86_64) += vdso-image-64.o
obj-$(CONFIG_X86_X32_ABI) += vdso-image-x32.o
obj-$(CONFIG_COMPAT_32) += vdso-image-32.o vdso32-setup.o
-OBJECT_FILES_NON_STANDARD_vdso-image-32.o := n
-OBJECT_FILES_NON_STANDARD_vdso-image-x32.o := n
-OBJECT_FILES_NON_STANDARD_vdso-image-64.o := n
-OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n
-
vobjs := $(addprefix $(obj)/, $(vobjs-y))
vobjs32 := $(addprefix $(obj)/, $(vobjs32-y))
@@ -98,6 +73,7 @@ CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
CFLAGS_REMOVE_vgetcpu.o = -pg
CFLAGS_REMOVE_vdso32/vgetcpu.o = -pg
CFLAGS_REMOVE_vsgx.o = -pg
+CFLAGS_REMOVE_vgetrandom.o = -pg
#
# X32 processes use x32 vDSO to access 64bit kernel data.
@@ -176,11 +152,10 @@ quiet_cmd_vdso = VDSO $@
cmd_vdso = $(LD) -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-T $(filter %.lds,$^) $(filter %.o,$^) && \
- sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
+ sh $(src)/checkundef.sh '$(NM)' '$@'
VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 \
$(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack
-GCOV_PROFILE := n
quiet_cmd_vdso_and_check = VDSO $@
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S
index e8c60ae7a7c8..0bab5f4af6d1 100644
--- a/arch/x86/entry/vdso/vdso.lds.S
+++ b/arch/x86/entry/vdso/vdso.lds.S
@@ -30,6 +30,8 @@ VERSION {
#ifdef CONFIG_X86_SGX
__vdso_sgx_enter_enclave;
#endif
+ getrandom;
+ __vdso_getrandom;
local: *;
};
}
diff --git a/arch/x86/entry/vdso/vgetrandom-chacha.S b/arch/x86/entry/vdso/vgetrandom-chacha.S
new file mode 100644
index 000000000000..bcba5639b8ee
--- /dev/null
+++ b/arch/x86/entry/vdso/vgetrandom-chacha.S
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022-2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+.section .rodata, "a"
+.align 16
+CONSTANTS: .octa 0x6b20657479622d323320646e61707865
+.text
+
+/*
+ * Very basic SSE2 implementation of ChaCha20. Produces a given positive number
+ * of blocks of output with a nonce of 0, taking an input key and 8-byte
+ * counter. Importantly does not spill to the stack. Its arguments are:
+ *
+ * rdi: output bytes
+ * rsi: 32-byte key input
+ * rdx: 8-byte counter input/output
+ * rcx: number of 64-byte blocks to write to output
+ */
+SYM_FUNC_START(__arch_chacha20_blocks_nostack)
+
+.set output, %rdi
+.set key, %rsi
+.set counter, %rdx
+.set nblocks, %rcx
+.set i, %al
+/* xmm registers are *not* callee-save. */
+.set temp, %xmm0
+.set state0, %xmm1
+.set state1, %xmm2
+.set state2, %xmm3
+.set state3, %xmm4
+.set copy0, %xmm5
+.set copy1, %xmm6
+.set copy2, %xmm7
+.set copy3, %xmm8
+.set one, %xmm9
+
+ /* copy0 = "expand 32-byte k" */
+ movaps CONSTANTS(%rip),copy0
+ /* copy1,copy2 = key */
+ movups 0x00(key),copy1
+ movups 0x10(key),copy2
+ /* copy3 = counter || zero nonce */
+ movq 0x00(counter),copy3
+ /* one = 1 || 0 */
+ movq $1,%rax
+ movq %rax,one
+
+.Lblock:
+ /* state0,state1,state2,state3 = copy0,copy1,copy2,copy3 */
+ movdqa copy0,state0
+ movdqa copy1,state1
+ movdqa copy2,state2
+ movdqa copy3,state3
+
+ movb $10,i
+.Lpermute:
+ /* state0 += state1, state3 = rotl32(state3 ^ state0, 16) */
+ paddd state1,state0
+ pxor state0,state3
+ movdqa state3,temp
+ pslld $16,temp
+ psrld $16,state3
+ por temp,state3
+
+ /* state2 += state3, state1 = rotl32(state1 ^ state2, 12) */
+ paddd state3,state2
+ pxor state2,state1
+ movdqa state1,temp
+ pslld $12,temp
+ psrld $20,state1
+ por temp,state1
+
+ /* state0 += state1, state3 = rotl32(state3 ^ state0, 8) */
+ paddd state1,state0
+ pxor state0,state3
+ movdqa state3,temp
+ pslld $8,temp
+ psrld $24,state3
+ por temp,state3
+
+ /* state2 += state3, state1 = rotl32(state1 ^ state2, 7) */
+ paddd state3,state2
+ pxor state2,state1
+ movdqa state1,temp
+ pslld $7,temp
+ psrld $25,state1
+ por temp,state1
+
+ /* state1[0,1,2,3] = state1[1,2,3,0] */
+ pshufd $0x39,state1,state1
+ /* state2[0,1,2,3] = state2[2,3,0,1] */
+ pshufd $0x4e,state2,state2
+ /* state3[0,1,2,3] = state3[3,0,1,2] */
+ pshufd $0x93,state3,state3
+
+ /* state0 += state1, state3 = rotl32(state3 ^ state0, 16) */
+ paddd state1,state0
+ pxor state0,state3
+ movdqa state3,temp
+ pslld $16,temp
+ psrld $16,state3
+ por temp,state3
+
+ /* state2 += state3, state1 = rotl32(state1 ^ state2, 12) */
+ paddd state3,state2
+ pxor state2,state1
+ movdqa state1,temp
+ pslld $12,temp
+ psrld $20,state1
+ por temp,state1
+
+ /* state0 += state1, state3 = rotl32(state3 ^ state0, 8) */
+ paddd state1,state0
+ pxor state0,state3
+ movdqa state3,temp
+ pslld $8,temp
+ psrld $24,state3
+ por temp,state3
+
+ /* state2 += state3, state1 = rotl32(state1 ^ state2, 7) */
+ paddd state3,state2
+ pxor state2,state1
+ movdqa state1,temp
+ pslld $7,temp
+ psrld $25,state1
+ por temp,state1
+
+ /* state1[0,1,2,3] = state1[3,0,1,2] */
+ pshufd $0x93,state1,state1
+ /* state2[0,1,2,3] = state2[2,3,0,1] */
+ pshufd $0x4e,state2,state2
+ /* state3[0,1,2,3] = state3[1,2,3,0] */
+ pshufd $0x39,state3,state3
+
+ decb i
+ jnz .Lpermute
+
+ /* output0 = state0 + copy0 */
+ paddd copy0,state0
+ movups state0,0x00(output)
+ /* output1 = state1 + copy1 */
+ paddd copy1,state1
+ movups state1,0x10(output)
+ /* output2 = state2 + copy2 */
+ paddd copy2,state2
+ movups state2,0x20(output)
+ /* output3 = state3 + copy3 */
+ paddd copy3,state3
+ movups state3,0x30(output)
+
+ /* ++copy3.counter */
+ paddq one,copy3
+
+ /* output += 64, --nblocks */
+ addq $64,output
+ decq nblocks
+ jnz .Lblock
+
+ /* counter = copy3.counter */
+ movq copy3,0x00(counter)
+
+ /* Zero out the potentially sensitive regs, in case nothing uses these again. */
+ pxor state0,state0
+ pxor state1,state1
+ pxor state2,state2
+ pxor state3,state3
+ pxor copy1,copy1
+ pxor copy2,copy2
+ pxor temp,temp
+
+ ret
+SYM_FUNC_END(__arch_chacha20_blocks_nostack)
diff --git a/arch/x86/entry/vdso/vgetrandom.c b/arch/x86/entry/vdso/vgetrandom.c
new file mode 100644
index 000000000000..52d3c7faae2e
--- /dev/null
+++ b/arch/x86/entry/vdso/vgetrandom.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+#include <linux/types.h>
+
+#include "../../../../lib/vdso/getrandom.c"
+
+ssize_t __vdso_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len);
+
+ssize_t __vdso_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len)
+{
+ return __cvdso_getrandom(buffer, len, flags, opaque_state, opaque_len);
+}
+
+ssize_t getrandom(void *, size_t, unsigned int, void *, size_t)
+ __attribute__((weak, alias("__vdso_getrandom")));
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index 985ef3b47919..920e3a640cad 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -432,8 +432,10 @@ static void __amd_put_nb_event_constraints(struct cpu_hw_events *cpuc,
* be removed on one CPU at a time AND PMU is disabled
* when we come here
*/
- for (i = 0; i < x86_pmu.num_counters; i++) {
- if (cmpxchg(nb->owners + i, event, NULL) == event)
+ for_each_set_bit(i, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
+ struct perf_event *tmp = event;
+
+ if (try_cmpxchg(nb->owners + i, &tmp, NULL))
break;
}
}
@@ -499,7 +501,7 @@ __amd_get_nb_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *ev
* because of successive calls to x86_schedule_events() from
* hw_perf_group_sched_in() without hw_perf_enable()
*/
- for_each_set_bit(idx, c->idxmsk, x86_pmu.num_counters) {
+ for_each_set_bit(idx, c->idxmsk, x86_pmu_max_num_counters(NULL)) {
if (new == -1 || hwc->idx == idx)
/* assign free slot, prefer hwc->idx */
old = cmpxchg(nb->owners + idx, NULL, event);
@@ -542,7 +544,7 @@ static struct amd_nb *amd_alloc_nb(int cpu)
/*
* initialize all possible NB constraints
*/
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for_each_set_bit(i, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
__set_bit(i, nb->event_constraints[i].idxmsk);
nb->event_constraints[i].weight = 1;
}
@@ -647,7 +649,7 @@ static void amd_pmu_cpu_dead(int cpu)
}
}
-static inline void amd_pmu_set_global_ctl(u64 ctl)
+static __always_inline void amd_pmu_set_global_ctl(u64 ctl)
{
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, ctl);
}
@@ -735,7 +737,7 @@ static void amd_pmu_check_overflow(void)
* counters are always enabled when this function is called and
* ARCH_PERFMON_EVENTSEL_INT is always set.
*/
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -755,7 +757,7 @@ static void amd_pmu_enable_all(int added)
amd_brs_enable_all();
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
/* only activate events which are marked as active */
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -907,6 +909,37 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
return amd_pmu_adjust_nmi_window(handled);
}
+/*
+ * AMD-specific callback invoked through perf_snapshot_branch_stack static
+ * call, defined in include/linux/perf_event.h. See its definition for API
+ * details. It's up to caller to provide enough space in *entries* to fit all
+ * LBR records, otherwise returned result will be truncated to *cnt* entries.
+ */
+static int amd_pmu_v2_snapshot_branch_stack(struct perf_branch_entry *entries, unsigned int cnt)
+{
+ struct cpu_hw_events *cpuc;
+ unsigned long flags;
+
+ /*
+ * The sequence of steps to freeze LBR should be completely inlined
+ * and contain no branches to minimize contamination of LBR snapshot
+ */
+ local_irq_save(flags);
+ amd_pmu_core_disable_all();
+ __amd_pmu_lbr_disable();
+
+ cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ amd_pmu_lbr_read();
+ cnt = min(cnt, x86_pmu.lbr_nr);
+ memcpy(entries, cpuc->lbr_entries, sizeof(struct perf_branch_entry) * cnt);
+
+ amd_pmu_v2_enable_all(0);
+ local_irq_restore(flags);
+
+ return cnt;
+}
+
static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -947,7 +980,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
/* Clear any reserved bits set by buggy microcode */
status &= amd_pmu_global_cntr_mask;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -1282,7 +1315,7 @@ static __initconst const struct x86_pmu amd_pmu = {
.addr_offset = amd_pmu_addr_offset,
.event_map = amd_pmu_event_map,
.max_events = ARRAY_SIZE(amd_perfmon_event_map),
- .num_counters = AMD64_NUM_COUNTERS,
+ .cntr_mask64 = GENMASK_ULL(AMD64_NUM_COUNTERS - 1, 0),
.add = amd_pmu_add_event,
.del = amd_pmu_del_event,
.cntval_bits = 48,
@@ -1381,7 +1414,7 @@ static int __init amd_core_pmu_init(void)
*/
x86_pmu.eventsel = MSR_F15H_PERF_CTL;
x86_pmu.perfctr = MSR_F15H_PERF_CTR;
- x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
+ x86_pmu.cntr_mask64 = GENMASK_ULL(AMD64_NUM_COUNTERS_CORE - 1, 0);
/* Check for Performance Monitoring v2 support */
if (boot_cpu_has(X86_FEATURE_PERFMON_V2)) {
@@ -1391,9 +1424,9 @@ static int __init amd_core_pmu_init(void)
x86_pmu.version = 2;
/* Find the number of available Core PMCs */
- x86_pmu.num_counters = ebx.split.num_core_pmc;
+ x86_pmu.cntr_mask64 = GENMASK_ULL(ebx.split.num_core_pmc - 1, 0);
- amd_pmu_global_cntr_mask = (1ULL << x86_pmu.num_counters) - 1;
+ amd_pmu_global_cntr_mask = x86_pmu.cntr_mask64;
/* Update PMC handling functions */
x86_pmu.enable_all = amd_pmu_v2_enable_all;
@@ -1421,12 +1454,12 @@ static int __init amd_core_pmu_init(void)
* even numbered counter that has a consecutive adjacent odd
* numbered counter following it.
*/
- for (i = 0; i < x86_pmu.num_counters - 1; i += 2)
+ for (i = 0; i < x86_pmu_max_num_counters(NULL) - 1; i += 2)
even_ctr_mask |= BIT_ULL(i);
pair_constraint = (struct event_constraint)
__EVENT_CONSTRAINT(0, even_ctr_mask, 0,
- x86_pmu.num_counters / 2, 0,
+ x86_pmu_max_num_counters(NULL) / 2, 0,
PERF_X86_EVENT_PAIR);
x86_pmu.get_event_constraints = amd_get_event_constraints_f17h;
@@ -1443,6 +1476,10 @@ static int __init amd_core_pmu_init(void)
static_call_update(amd_pmu_branch_reset, amd_pmu_lbr_reset);
static_call_update(amd_pmu_branch_add, amd_pmu_lbr_add);
static_call_update(amd_pmu_branch_del, amd_pmu_lbr_del);
+
+ /* Only support branch_stack snapshot on perfmon v2 */
+ if (x86_pmu.handle_irq == amd_pmu_v2_handle_irq)
+ static_call_update(perf_snapshot_branch_stack, amd_pmu_v2_snapshot_branch_stack);
} else if (!amd_brs_init()) {
/*
* BRS requires special event constraints and flushing on ctxsw.
diff --git a/arch/x86/events/amd/lbr.c b/arch/x86/events/amd/lbr.c
index 5149830c7c4f..19c7b76e21bc 100644
--- a/arch/x86/events/amd/lbr.c
+++ b/arch/x86/events/amd/lbr.c
@@ -310,10 +310,6 @@ int amd_pmu_lbr_hw_config(struct perf_event *event)
{
int ret = 0;
- /* LBR is not recommended in counting mode */
- if (!is_sampling_event(event))
- return -EINVAL;
-
ret = amd_pmu_lbr_setup_filter(event);
if (!ret)
event->attach_state |= PERF_ATTACH_SCHED_CB;
@@ -414,18 +410,11 @@ void amd_pmu_lbr_enable_all(void)
void amd_pmu_lbr_disable_all(void)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- u64 dbg_ctl, dbg_extn_cfg;
if (!cpuc->lbr_users || !x86_pmu.lbr_nr)
return;
- rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg);
- wrmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg & ~DBG_EXTN_CFG_LBRV2EN);
-
- if (cpu_feature_enabled(X86_FEATURE_AMD_LBR_PMC_FREEZE)) {
- rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl);
- wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl & ~DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
- }
+ __amd_pmu_lbr_disable();
}
__init int amd_pmu_lbr_init(void)
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index 4ccb8fa483e6..0bfde2ea5cb8 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -162,7 +162,9 @@ static int amd_uncore_add(struct perf_event *event, int flags)
/* if not, take the first available counter */
hwc->idx = -1;
for (i = 0; i < pmu->num_counters; i++) {
- if (cmpxchg(&ctx->events[i], NULL, event) == NULL) {
+ struct perf_event *tmp = NULL;
+
+ if (try_cmpxchg(&ctx->events[i], &tmp, event)) {
hwc->idx = i;
break;
}
@@ -196,7 +198,9 @@ static void amd_uncore_del(struct perf_event *event, int flags)
event->pmu->stop(event, PERF_EF_UPDATE);
for (i = 0; i < pmu->num_counters; i++) {
- if (cmpxchg(&ctx->events[i], event, NULL) == event)
+ struct perf_event *tmp = event;
+
+ if (try_cmpxchg(&ctx->events[i], &tmp, NULL))
break;
}
@@ -639,7 +643,7 @@ void amd_uncore_df_ctx_scan(struct amd_uncore *uncore, unsigned int cpu)
info.split.aux_data = 0;
info.split.num_pmcs = NUM_COUNTERS_NB;
info.split.gid = 0;
- info.split.cid = topology_die_id(cpu);
+ info.split.cid = topology_logical_package_id(cpu);
if (pmu_version >= 2) {
ebx.full = cpuid_ebx(EXT_PERFMON_DEBUG_FEATURES);
@@ -654,17 +658,20 @@ int amd_uncore_df_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
{
struct attribute **df_attr = amd_uncore_df_format_attr;
struct amd_uncore_pmu *pmu;
+ int num_counters;
/* Run just once */
if (uncore->init_done)
return amd_uncore_ctx_init(uncore, cpu);
+ num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+ if (!num_counters)
+ goto done;
+
/* No grouping, single instance for a system */
uncore->pmus = kzalloc(sizeof(*uncore->pmus), GFP_KERNEL);
- if (!uncore->pmus) {
- uncore->num_pmus = 0;
+ if (!uncore->pmus)
goto done;
- }
/*
* For Family 17h and above, the Northbridge counters are repurposed
@@ -674,7 +681,7 @@ int amd_uncore_df_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
pmu = &uncore->pmus[0];
strscpy(pmu->name, boot_cpu_data.x86 >= 0x17 ? "amd_df" : "amd_nb",
sizeof(pmu->name));
- pmu->num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+ pmu->num_counters = num_counters;
pmu->msr_base = MSR_F15H_NB_PERF_CTL;
pmu->rdpmc_base = RDPMC_BASE_NB;
pmu->group = amd_uncore_ctx_gid(uncore, cpu);
@@ -785,17 +792,20 @@ int amd_uncore_l3_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
{
struct attribute **l3_attr = amd_uncore_l3_format_attr;
struct amd_uncore_pmu *pmu;
+ int num_counters;
/* Run just once */
if (uncore->init_done)
return amd_uncore_ctx_init(uncore, cpu);
+ num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+ if (!num_counters)
+ goto done;
+
/* No grouping, single instance for a system */
uncore->pmus = kzalloc(sizeof(*uncore->pmus), GFP_KERNEL);
- if (!uncore->pmus) {
- uncore->num_pmus = 0;
+ if (!uncore->pmus)
goto done;
- }
/*
* For Family 17h and above, L3 cache counters are available instead
@@ -805,7 +815,7 @@ int amd_uncore_l3_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
pmu = &uncore->pmus[0];
strscpy(pmu->name, boot_cpu_data.x86 >= 0x17 ? "amd_l3" : "amd_l2",
sizeof(pmu->name));
- pmu->num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+ pmu->num_counters = num_counters;
pmu->msr_base = MSR_F16H_L2I_PERF_CTL;
pmu->rdpmc_base = RDPMC_BASE_LLC;
pmu->group = amd_uncore_ctx_gid(uncore, cpu);
@@ -893,8 +903,8 @@ void amd_uncore_umc_ctx_scan(struct amd_uncore *uncore, unsigned int cpu)
cpuid(EXT_PERFMON_DEBUG_FEATURES, &eax, &ebx.full, &ecx, &edx);
info.split.aux_data = ecx; /* stash active mask */
info.split.num_pmcs = ebx.split.num_umc_pmc;
- info.split.gid = topology_die_id(cpu);
- info.split.cid = topology_die_id(cpu);
+ info.split.gid = topology_logical_package_id(cpu);
+ info.split.cid = topology_logical_package_id(cpu);
*per_cpu_ptr(uncore->info, cpu) = info;
}
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 5b0dd07b1ef1..12f2a0c14d33 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -189,29 +189,31 @@ static DEFINE_MUTEX(pmc_reserve_mutex);
#ifdef CONFIG_X86_LOCAL_APIC
-static inline int get_possible_num_counters(void)
+static inline u64 get_possible_counter_mask(void)
{
- int i, num_counters = x86_pmu.num_counters;
+ u64 cntr_mask = x86_pmu.cntr_mask64;
+ int i;
if (!is_hybrid())
- return num_counters;
+ return cntr_mask;
for (i = 0; i < x86_pmu.num_hybrid_pmus; i++)
- num_counters = max_t(int, num_counters, x86_pmu.hybrid_pmu[i].num_counters);
+ cntr_mask |= x86_pmu.hybrid_pmu[i].cntr_mask64;
- return num_counters;
+ return cntr_mask;
}
static bool reserve_pmc_hardware(void)
{
- int i, num_counters = get_possible_num_counters();
+ u64 cntr_mask = get_possible_counter_mask();
+ int i, end;
- for (i = 0; i < num_counters; i++) {
+ for_each_set_bit(i, (unsigned long *)&cntr_mask, X86_PMC_IDX_MAX) {
if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
goto perfctr_fail;
}
- for (i = 0; i < num_counters; i++) {
+ for_each_set_bit(i, (unsigned long *)&cntr_mask, X86_PMC_IDX_MAX) {
if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
goto eventsel_fail;
}
@@ -219,13 +221,14 @@ static bool reserve_pmc_hardware(void)
return true;
eventsel_fail:
- for (i--; i >= 0; i--)
+ end = i;
+ for_each_set_bit(i, (unsigned long *)&cntr_mask, end)
release_evntsel_nmi(x86_pmu_config_addr(i));
-
- i = num_counters;
+ i = X86_PMC_IDX_MAX;
perfctr_fail:
- for (i--; i >= 0; i--)
+ end = i;
+ for_each_set_bit(i, (unsigned long *)&cntr_mask, end)
release_perfctr_nmi(x86_pmu_event_addr(i));
return false;
@@ -233,9 +236,10 @@ perfctr_fail:
static void release_pmc_hardware(void)
{
- int i, num_counters = get_possible_num_counters();
+ u64 cntr_mask = get_possible_counter_mask();
+ int i;
- for (i = 0; i < num_counters; i++) {
+ for_each_set_bit(i, (unsigned long *)&cntr_mask, X86_PMC_IDX_MAX) {
release_perfctr_nmi(x86_pmu_event_addr(i));
release_evntsel_nmi(x86_pmu_config_addr(i));
}
@@ -248,7 +252,8 @@ static void release_pmc_hardware(void) {}
#endif
-bool check_hw_exists(struct pmu *pmu, int num_counters, int num_counters_fixed)
+bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
+ unsigned long *fixed_cntr_mask)
{
u64 val, val_fail = -1, val_new= ~0;
int i, reg, reg_fail = -1, ret = 0;
@@ -259,7 +264,7 @@ bool check_hw_exists(struct pmu *pmu, int num_counters, int num_counters_fixed)
* Check to see if the BIOS enabled any of the counters, if so
* complain and bail.
*/
- for (i = 0; i < num_counters; i++) {
+ for_each_set_bit(i, cntr_mask, X86_PMC_IDX_MAX) {
reg = x86_pmu_config_addr(i);
ret = rdmsrl_safe(reg, &val);
if (ret)
@@ -273,12 +278,12 @@ bool check_hw_exists(struct pmu *pmu, int num_counters, int num_counters_fixed)
}
}
- if (num_counters_fixed) {
+ if (*(u64 *)fixed_cntr_mask) {
reg = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
ret = rdmsrl_safe(reg, &val);
if (ret)
goto msr_fail;
- for (i = 0; i < num_counters_fixed; i++) {
+ for_each_set_bit(i, fixed_cntr_mask, X86_PMC_IDX_MAX) {
if (fixed_counter_disabled(i, pmu))
continue;
if (val & (0x03ULL << i*4)) {
@@ -619,7 +624,7 @@ int x86_pmu_hw_config(struct perf_event *event)
event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
if (event->attr.type == event->pmu->type)
- event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
+ event->hw.config |= x86_pmu_get_event_config(event);
if (event->attr.sample_period && x86_pmu.limit_period) {
s64 left = event->attr.sample_period;
@@ -679,7 +684,7 @@ void x86_pmu_disable_all(void)
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
u64 val;
@@ -736,7 +741,7 @@ void x86_pmu_enable_all(int added)
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
if (!test_bit(idx, cpuc->active_mask))
@@ -975,7 +980,6 @@ EXPORT_SYMBOL_GPL(perf_assign_events);
int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
{
- int num_counters = hybrid(cpuc->pmu, num_counters);
struct event_constraint *c;
struct perf_event *e;
int n0, i, wmin, wmax, unsched = 0;
@@ -1051,7 +1055,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
/* slow path */
if (i != n) {
- int gpmax = num_counters;
+ int gpmax = x86_pmu_max_num_counters(cpuc->pmu);
/*
* Do not allow scheduling of more than half the available
@@ -1072,7 +1076,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
* the extra Merge events needed by large increment events.
*/
if (x86_pmu.flags & PMU_FL_PAIR) {
- gpmax = num_counters - cpuc->n_pair;
+ gpmax -= cpuc->n_pair;
WARN_ON(gpmax <= 0);
}
@@ -1157,12 +1161,10 @@ static int collect_event(struct cpu_hw_events *cpuc, struct perf_event *event,
*/
static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
{
- int num_counters = hybrid(cpuc->pmu, num_counters);
- int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
struct perf_event *event;
int n, max_count;
- max_count = num_counters + num_counters_fixed;
+ max_count = x86_pmu_num_counters(cpuc->pmu) + x86_pmu_num_counters_fixed(cpuc->pmu);
/* current number of events already accepted */
n = cpuc->n_events;
@@ -1234,8 +1236,7 @@ static inline void x86_assign_hw_event(struct perf_event *event,
fallthrough;
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 = x86_pmu_fixed_ctr_addr(idx - INTEL_PMC_IDX_FIXED);
hwc->event_base_rdpmc = (idx - INTEL_PMC_IDX_FIXED) |
INTEL_PMC_FIXED_RDPMC_BASE;
break;
@@ -1522,13 +1523,13 @@ void perf_event_print_debug(void)
u64 pebs, debugctl;
int cpu = smp_processor_id();
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- int num_counters = hybrid(cpuc->pmu, num_counters);
- int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
+ unsigned long *cntr_mask = hybrid(cpuc->pmu, cntr_mask);
+ unsigned long *fixed_cntr_mask = hybrid(cpuc->pmu, fixed_cntr_mask);
struct event_constraint *pebs_constraints = hybrid(cpuc->pmu, pebs_constraints);
unsigned long flags;
int idx;
- if (!num_counters)
+ if (!*(u64 *)cntr_mask)
return;
local_irq_save(flags);
@@ -1555,7 +1556,7 @@ void perf_event_print_debug(void)
}
pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask);
- for (idx = 0; idx < num_counters; idx++) {
+ for_each_set_bit(idx, cntr_mask, X86_PMC_IDX_MAX) {
rdmsrl(x86_pmu_config_addr(idx), pmc_ctrl);
rdmsrl(x86_pmu_event_addr(idx), pmc_count);
@@ -1568,10 +1569,10 @@ void perf_event_print_debug(void)
pr_info("CPU#%d: gen-PMC%d left: %016llx\n",
cpu, idx, prev_left);
}
- for (idx = 0; idx < num_counters_fixed; idx++) {
+ for_each_set_bit(idx, fixed_cntr_mask, X86_PMC_IDX_MAX) {
if (fixed_counter_disabled(idx, cpuc->pmu))
continue;
- rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
+ rdmsrl(x86_pmu_fixed_ctr_addr(idx), pmc_count);
pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
cpu, idx, pmc_count);
@@ -1682,7 +1683,7 @@ int x86_pmu_handle_irq(struct pt_regs *regs)
*/
apic_write(APIC_LVTPC, APIC_DM_NMI);
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -2038,18 +2039,15 @@ static void _x86_pmu_read(struct perf_event *event)
static_call(x86_pmu_update)(event);
}
-void x86_pmu_show_pmu_cap(int num_counters, int num_counters_fixed,
- u64 intel_ctrl)
+void x86_pmu_show_pmu_cap(struct pmu *pmu)
{
pr_info("... version: %d\n", x86_pmu.version);
pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
- pr_info("... generic registers: %d\n", num_counters);
+ pr_info("... generic registers: %d\n", x86_pmu_num_counters(pmu));
pr_info("... value mask: %016Lx\n", x86_pmu.cntval_mask);
pr_info("... max period: %016Lx\n", x86_pmu.max_period);
- pr_info("... fixed-purpose events: %lu\n",
- hweight64((((1ULL << num_counters_fixed) - 1)
- << INTEL_PMC_IDX_FIXED) & intel_ctrl));
- pr_info("... event mask: %016Lx\n", intel_ctrl);
+ pr_info("... fixed-purpose events: %d\n", x86_pmu_num_counters_fixed(pmu));
+ pr_info("... event mask: %016Lx\n", hybrid(pmu, intel_ctrl));
}
static int __init init_hw_perf_events(void)
@@ -2086,7 +2084,7 @@ static int __init init_hw_perf_events(void)
pmu_check_apic();
/* sanity check that the hardware exists or is emulated */
- if (!check_hw_exists(&pmu, x86_pmu.num_counters, x86_pmu.num_counters_fixed))
+ if (!check_hw_exists(&pmu, x86_pmu.cntr_mask, x86_pmu.fixed_cntr_mask))
goto out_bad_pmu;
pr_cont("%s PMU driver.\n", x86_pmu.name);
@@ -2097,14 +2095,17 @@ static int __init init_hw_perf_events(void)
quirk->func();
if (!x86_pmu.intel_ctrl)
- x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+ x86_pmu.intel_ctrl = x86_pmu.cntr_mask64;
+
+ if (!x86_pmu.config_mask)
+ x86_pmu.config_mask = X86_RAW_EVENT_MASK;
perf_events_lapic_init();
register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
unconstrained = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
- 0, x86_pmu.num_counters, 0, 0);
+ __EVENT_CONSTRAINT(0, x86_pmu.cntr_mask64,
+ 0, x86_pmu_num_counters(NULL), 0, 0);
x86_pmu_format_group.attrs = x86_pmu.format_attrs;
@@ -2113,11 +2114,8 @@ static int __init init_hw_perf_events(void)
pmu.attr_update = x86_pmu.attr_update;
- if (!is_hybrid()) {
- x86_pmu_show_pmu_cap(x86_pmu.num_counters,
- x86_pmu.num_counters_fixed,
- x86_pmu.intel_ctrl);
- }
+ if (!is_hybrid())
+ x86_pmu_show_pmu_cap(NULL);
if (!x86_pmu.read)
x86_pmu.read = _x86_pmu_read;
@@ -2481,10 +2479,10 @@ void perf_clear_dirty_counters(void)
for_each_set_bit(i, cpuc->dirty, X86_PMC_IDX_MAX) {
if (i >= INTEL_PMC_IDX_FIXED) {
/* Metrics and fake events don't have corresponding HW counters. */
- if ((i - INTEL_PMC_IDX_FIXED) >= hybrid(cpuc->pmu, num_counters_fixed))
+ if (!test_bit(i - INTEL_PMC_IDX_FIXED, hybrid(cpuc->pmu, fixed_cntr_mask)))
continue;
- wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + (i - INTEL_PMC_IDX_FIXED), 0);
+ wrmsrl(x86_pmu_fixed_ctr_addr(i - INTEL_PMC_IDX_FIXED), 0);
} else {
wrmsrl(x86_pmu_event_addr(i), 0);
}
@@ -2547,6 +2545,7 @@ static ssize_t set_attr_rdpmc(struct device *cdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ static DEFINE_MUTEX(rdpmc_mutex);
unsigned long val;
ssize_t ret;
@@ -2560,6 +2559,8 @@ static ssize_t set_attr_rdpmc(struct device *cdev,
if (x86_pmu.attr_rdpmc_broken)
return -ENOTSUPP;
+ guard(mutex)(&rdpmc_mutex);
+
if (val != x86_pmu.attr_rdpmc) {
/*
* Changing into or out of never available or always available,
@@ -2983,8 +2984,8 @@ void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
* base PMU holds the correct number of counters for P-cores.
*/
cap->version = x86_pmu.version;
- cap->num_counters_gp = x86_pmu.num_counters;
- cap->num_counters_fixed = x86_pmu.num_counters_fixed;
+ cap->num_counters_gp = x86_pmu_num_counters(NULL);
+ cap->num_counters_fixed = x86_pmu_num_counters_fixed(NULL);
cap->bit_width_gp = x86_pmu.cntval_bits;
cap->bit_width_fixed = x86_pmu.cntval_bits;
cap->events_mask = (unsigned int)x86_pmu.events_maskl;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 768d1414897f..0c9c2706d4ec 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -220,6 +220,17 @@ static struct event_constraint intel_grt_event_constraints[] __read_mostly = {
EVENT_CONSTRAINT_END
};
+static struct event_constraint intel_skt_event_constraints[] __read_mostly = {
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */
+ FIXED_EVENT_CONSTRAINT(0x013c, 2), /* CPU_CLK_UNHALTED.REF_TSC_P */
+ FIXED_EVENT_CONSTRAINT(0x0073, 4), /* TOPDOWN_BAD_SPECULATION.ALL */
+ FIXED_EVENT_CONSTRAINT(0x019c, 5), /* TOPDOWN_FE_BOUND.ALL */
+ FIXED_EVENT_CONSTRAINT(0x02c2, 6), /* TOPDOWN_RETIRING.ALL */
+ EVENT_CONSTRAINT_END
+};
+
static struct event_constraint intel_skl_event_constraints[] = {
FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -370,6 +381,55 @@ static struct extra_reg intel_rwc_extra_regs[] __read_mostly = {
EVENT_EXTRA_END
};
+static struct event_constraint intel_lnc_event_constraints[] = {
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x0100, 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(0x013c, 2), /* CPU_CLK_UNHALTED.REF_TSC_P */
+ 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),
+ METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_HEAVY_OPS, 4),
+ METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BR_MISPREDICT, 5),
+ METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_FETCH_LAT, 6),
+ METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_MEM_BOUND, 7),
+
+ INTEL_UEVENT_CONSTRAINT(0x0148, 0x4),
+ INTEL_UEVENT_CONSTRAINT(0x0175, 0x4),
+
+ INTEL_EVENT_CONSTRAINT(0x2e, 0x3ff),
+ INTEL_EVENT_CONSTRAINT(0x3c, 0x3ff),
+ /*
+ * Generally event codes < 0x90 are restricted to counters 0-3.
+ * The 0x2E and 0x3C are exception, which has no restriction.
+ */
+ INTEL_EVENT_CONSTRAINT_RANGE(0x01, 0x8f, 0xf),
+
+ INTEL_UEVENT_CONSTRAINT(0x01a3, 0xf),
+ INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf),
+ INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4),
+ INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
+ INTEL_UEVENT_CONSTRAINT(0x04a4, 0x1),
+ INTEL_UEVENT_CONSTRAINT(0x08a4, 0x1),
+ INTEL_UEVENT_CONSTRAINT(0x10a4, 0x1),
+ INTEL_UEVENT_CONSTRAINT(0x01b1, 0x8),
+ INTEL_UEVENT_CONSTRAINT(0x02cd, 0x3),
+ INTEL_EVENT_CONSTRAINT(0xce, 0x1),
+
+ INTEL_EVENT_CONSTRAINT_RANGE(0xd0, 0xdf, 0xf),
+ /*
+ * Generally event codes >= 0x90 are likely to have no restrictions.
+ * The exception are defined as above.
+ */
+ INTEL_EVENT_CONSTRAINT_RANGE(0x90, 0xfe, 0x3ff),
+
+ EVENT_CONSTRAINT_END
+};
+
+
EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
@@ -2874,26 +2934,26 @@ static void intel_pmu_reset(void)
{
struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
- int num_counters = hybrid(cpuc->pmu, num_counters);
+ unsigned long *cntr_mask = hybrid(cpuc->pmu, cntr_mask);
+ unsigned long *fixed_cntr_mask = hybrid(cpuc->pmu, fixed_cntr_mask);
unsigned long flags;
int idx;
- if (!num_counters)
+ if (!*(u64 *)cntr_mask)
return;
local_irq_save(flags);
pr_info("clearing PMU state on CPU#%d\n", smp_processor_id());
- for (idx = 0; idx < num_counters; idx++) {
+ for_each_set_bit(idx, cntr_mask, INTEL_PMC_MAX_GENERIC) {
wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
wrmsrl_safe(x86_pmu_event_addr(idx), 0ull);
}
- for (idx = 0; idx < num_counters_fixed; idx++) {
+ for_each_set_bit(idx, fixed_cntr_mask, INTEL_PMC_MAX_FIXED) {
if (fixed_counter_disabled(idx, cpuc->pmu))
continue;
- wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
+ wrmsrl_safe(x86_pmu_fixed_ctr_addr(idx), 0ull);
}
if (ds)
@@ -2940,8 +3000,7 @@ static void x86_pmu_handle_guest_pebs(struct pt_regs *regs,
!guest_pebs_idxs)
return;
- for_each_set_bit(bit, (unsigned long *)&guest_pebs_idxs,
- INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed) {
+ for_each_set_bit(bit, (unsigned long *)&guest_pebs_idxs, X86_PMC_IDX_MAX) {
event = cpuc->events[bit];
if (!event->attr.precise_ip)
continue;
@@ -4199,7 +4258,7 @@ static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr, void *data)
struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
struct perf_event *event = cpuc->events[idx];
arr[idx].msr = x86_pmu_config_addr(idx);
@@ -4217,7 +4276,7 @@ static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr, void *data)
arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
}
- *nr = x86_pmu.num_counters;
+ *nr = x86_pmu_max_num_counters(cpuc->pmu);
return arr;
}
@@ -4232,7 +4291,7 @@ static void core_pmu_enable_all(int added)
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
if (!test_bit(idx, cpuc->active_mask) ||
@@ -4573,8 +4632,55 @@ PMU_FORMAT_ATTR(pc, "config:19" );
PMU_FORMAT_ATTR(any, "config:21" ); /* v3 + */
PMU_FORMAT_ATTR(inv, "config:23" );
PMU_FORMAT_ATTR(cmask, "config:24-31" );
-PMU_FORMAT_ATTR(in_tx, "config:32");
-PMU_FORMAT_ATTR(in_tx_cp, "config:33");
+PMU_FORMAT_ATTR(in_tx, "config:32" );
+PMU_FORMAT_ATTR(in_tx_cp, "config:33" );
+PMU_FORMAT_ATTR(eq, "config:36" ); /* v6 + */
+
+static ssize_t umask2_show(struct device *dev,
+ struct device_attribute *attr,
+ char *page)
+{
+ u64 mask = hybrid(dev_get_drvdata(dev), config_mask) & ARCH_PERFMON_EVENTSEL_UMASK2;
+
+ if (mask == ARCH_PERFMON_EVENTSEL_UMASK2)
+ return sprintf(page, "config:8-15,40-47\n");
+
+ /* Roll back to the old format if umask2 is not supported. */
+ return sprintf(page, "config:8-15\n");
+}
+
+static struct device_attribute format_attr_umask2 =
+ __ATTR(umask, 0444, umask2_show, NULL);
+
+static struct attribute *format_evtsel_ext_attrs[] = {
+ &format_attr_umask2.attr,
+ &format_attr_eq.attr,
+ NULL
+};
+
+static umode_t
+evtsel_ext_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ u64 mask;
+
+ /*
+ * The umask and umask2 have different formats but share the
+ * same attr name. In update mode, the previous value of the
+ * umask is unconditionally removed before is_visible. If
+ * umask2 format is not enumerated, it's impossible to roll
+ * back to the old format.
+ * Does the check in umask2_show rather than is_visible.
+ */
+ if (i == 0)
+ return attr->mode;
+
+ mask = hybrid(dev_get_drvdata(dev), config_mask);
+ if (i == 1)
+ return (mask & ARCH_PERFMON_EVENTSEL_EQ) ? attr->mode : 0;
+
+ return 0;
+}
static struct attribute *intel_arch_formats_attr[] = {
&format_attr_event.attr,
@@ -4684,13 +4790,33 @@ static void flip_smm_bit(void *data)
}
}
-static void intel_pmu_check_num_counters(int *num_counters,
- int *num_counters_fixed,
- u64 *intel_ctrl, u64 fixed_mask);
+static void intel_pmu_check_counters_mask(u64 *cntr_mask,
+ u64 *fixed_cntr_mask,
+ u64 *intel_ctrl)
+{
+ unsigned int bit;
+
+ bit = fls64(*cntr_mask);
+ if (bit > INTEL_PMC_MAX_GENERIC) {
+ WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
+ bit, INTEL_PMC_MAX_GENERIC);
+ *cntr_mask &= GENMASK_ULL(INTEL_PMC_MAX_GENERIC - 1, 0);
+ }
+ *intel_ctrl = *cntr_mask;
+
+ bit = fls64(*fixed_cntr_mask);
+ if (bit > INTEL_PMC_MAX_FIXED) {
+ WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
+ bit, INTEL_PMC_MAX_FIXED);
+ *fixed_cntr_mask &= GENMASK_ULL(INTEL_PMC_MAX_FIXED - 1, 0);
+ }
+
+ *intel_ctrl |= *fixed_cntr_mask << INTEL_PMC_IDX_FIXED;
+}
static void intel_pmu_check_event_constraints(struct event_constraint *event_constraints,
- int num_counters,
- int num_counters_fixed,
+ u64 cntr_mask,
+ u64 fixed_cntr_mask,
u64 intel_ctrl);
static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs);
@@ -4698,8 +4824,8 @@ static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs);
static inline bool intel_pmu_broken_perf_cap(void)
{
/* The Perf Metric (Bit 15) is always cleared */
- if ((boot_cpu_data.x86_model == INTEL_FAM6_METEORLAKE) ||
- (boot_cpu_data.x86_model == INTEL_FAM6_METEORLAKE_L))
+ if (boot_cpu_data.x86_vfm == INTEL_METEORLAKE ||
+ boot_cpu_data.x86_vfm == INTEL_METEORLAKE_L)
return true;
return false;
@@ -4707,17 +4833,22 @@ static inline bool intel_pmu_broken_perf_cap(void)
static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
{
- unsigned int sub_bitmaps = cpuid_eax(ARCH_PERFMON_EXT_LEAF);
- unsigned int eax, ebx, ecx, edx;
+ unsigned int sub_bitmaps, eax, ebx, ecx, edx;
+
+ cpuid(ARCH_PERFMON_EXT_LEAF, &sub_bitmaps, &ebx, &ecx, &edx);
+
+ if (ebx & ARCH_PERFMON_EXT_UMASK2)
+ pmu->config_mask |= ARCH_PERFMON_EVENTSEL_UMASK2;
+ if (ebx & ARCH_PERFMON_EXT_EQ)
+ pmu->config_mask |= ARCH_PERFMON_EVENTSEL_EQ;
if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) {
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
&eax, &ebx, &ecx, &edx);
- pmu->num_counters = fls(eax);
- pmu->num_counters_fixed = fls(ebx);
+ pmu->cntr_mask64 = eax;
+ pmu->fixed_cntr_mask64 = ebx;
}
-
if (!intel_pmu_broken_perf_cap()) {
/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
rdmsrl(MSR_IA32_PERF_CAPABILITIES, pmu->intel_cap.capabilities);
@@ -4726,12 +4857,12 @@ static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
{
- intel_pmu_check_num_counters(&pmu->num_counters, &pmu->num_counters_fixed,
- &pmu->intel_ctrl, (1ULL << pmu->num_counters_fixed) - 1);
- pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
+ intel_pmu_check_counters_mask(&pmu->cntr_mask64, &pmu->fixed_cntr_mask64,
+ &pmu->intel_ctrl);
+ pmu->pebs_events_mask = intel_pmu_pebs_mask(pmu->cntr_mask64);
pmu->unconstrained = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
- 0, pmu->num_counters, 0, 0);
+ __EVENT_CONSTRAINT(0, pmu->cntr_mask64,
+ 0, x86_pmu_num_counters(&pmu->pmu), 0, 0);
if (pmu->intel_cap.perf_metrics)
pmu->intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS;
@@ -4744,8 +4875,8 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT;
intel_pmu_check_event_constraints(pmu->event_constraints,
- pmu->num_counters,
- pmu->num_counters_fixed,
+ pmu->cntr_mask64,
+ pmu->fixed_cntr_mask64,
pmu->intel_ctrl);
intel_pmu_check_extra_regs(pmu->extra_regs);
@@ -4806,7 +4937,7 @@ static bool init_hybrid_pmu(int cpu)
intel_pmu_check_hybrid_pmus(pmu);
- if (!check_hw_exists(&pmu->pmu, pmu->num_counters, pmu->num_counters_fixed))
+ if (!check_hw_exists(&pmu->pmu, pmu->cntr_mask, pmu->fixed_cntr_mask))
return false;
pr_info("%s PMU driver: ", pmu->name);
@@ -4816,8 +4947,7 @@ static bool init_hybrid_pmu(int cpu)
pr_cont("\n");
- x86_pmu_show_pmu_cap(pmu->num_counters, pmu->num_counters_fixed,
- pmu->intel_ctrl);
+ x86_pmu_show_pmu_cap(&pmu->pmu);
end:
cpumask_set_cpu(cpu, &pmu->supported_cpus);
@@ -5058,6 +5188,7 @@ static __initconst const struct x86_pmu core_pmu = {
.schedule_events = x86_schedule_events,
.eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
.perfctr = MSR_ARCH_PERFMON_PERFCTR0,
+ .fixedctr = MSR_ARCH_PERFMON_FIXED_CTR0,
.event_map = intel_pmu_event_map,
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
.apic = 1,
@@ -5111,6 +5242,7 @@ static __initconst const struct x86_pmu intel_pmu = {
.schedule_events = x86_schedule_events,
.eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
.perfctr = MSR_ARCH_PERFMON_PERFCTR0,
+ .fixedctr = MSR_ARCH_PERFMON_FIXED_CTR0,
.event_map = intel_pmu_event_map,
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
.apic = 1,
@@ -5187,35 +5319,35 @@ static __init void intel_clovertown_quirk(void)
}
static const struct x86_cpu_desc isolation_ucodes[] = {
- INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x0000001f),
- INTEL_CPU_DESC(INTEL_FAM6_HASWELL_L, 1, 0x0000001e),
- INTEL_CPU_DESC(INTEL_FAM6_HASWELL_G, 1, 0x00000015),
- INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x00000037),
- INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x00000023),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_G, 1, 0x00000014),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 2, 0x00000010),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 3, 0x07000009),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 4, 0x0f000009),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 5, 0x0e000002),
- INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 1, 0x0b000014),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 5, 0x00000000),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 6, 0x00000000),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 7, 0x00000000),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 11, 0x00000000),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c),
- INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 9, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 10, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 11, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 12, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 10, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 11, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 12, 0x0000004e),
- INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 13, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_HASWELL, 3, 0x0000001f),
+ INTEL_CPU_DESC(INTEL_HASWELL_L, 1, 0x0000001e),
+ INTEL_CPU_DESC(INTEL_HASWELL_G, 1, 0x00000015),
+ INTEL_CPU_DESC(INTEL_HASWELL_X, 2, 0x00000037),
+ INTEL_CPU_DESC(INTEL_HASWELL_X, 4, 0x0000000a),
+ INTEL_CPU_DESC(INTEL_BROADWELL, 4, 0x00000023),
+ INTEL_CPU_DESC(INTEL_BROADWELL_G, 1, 0x00000014),
+ INTEL_CPU_DESC(INTEL_BROADWELL_D, 2, 0x00000010),
+ INTEL_CPU_DESC(INTEL_BROADWELL_D, 3, 0x07000009),
+ INTEL_CPU_DESC(INTEL_BROADWELL_D, 4, 0x0f000009),
+ INTEL_CPU_DESC(INTEL_BROADWELL_D, 5, 0x0e000002),
+ INTEL_CPU_DESC(INTEL_BROADWELL_X, 1, 0x0b000014),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_X, 3, 0x00000021),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_X, 4, 0x00000000),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_X, 5, 0x00000000),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_X, 6, 0x00000000),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_X, 7, 0x00000000),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_X, 11, 0x00000000),
+ INTEL_CPU_DESC(INTEL_SKYLAKE_L, 3, 0x0000007c),
+ INTEL_CPU_DESC(INTEL_SKYLAKE, 3, 0x0000007c),
+ INTEL_CPU_DESC(INTEL_KABYLAKE, 9, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE_L, 9, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE_L, 10, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE_L, 11, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE_L, 12, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE, 10, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE, 11, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE, 12, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_KABYLAKE, 13, 0x0000004e),
{}
};
@@ -5232,9 +5364,9 @@ static __init void intel_pebs_isolation_quirk(void)
}
static const struct x86_cpu_desc pebs_ucodes[] = {
- INTEL_CPU_DESC(INTEL_FAM6_SANDYBRIDGE, 7, 0x00000028),
- INTEL_CPU_DESC(INTEL_FAM6_SANDYBRIDGE_X, 6, 0x00000618),
- INTEL_CPU_DESC(INTEL_FAM6_SANDYBRIDGE_X, 7, 0x0000070c),
+ INTEL_CPU_DESC(INTEL_SANDYBRIDGE, 7, 0x00000028),
+ INTEL_CPU_DESC(INTEL_SANDYBRIDGE_X, 6, 0x00000618),
+ INTEL_CPU_DESC(INTEL_SANDYBRIDGE_X, 7, 0x0000070c),
{}
};
@@ -5645,18 +5777,11 @@ lbr_is_visible(struct kobject *kobj, struct attribute *attr, int i)
static char pmu_name_str[30];
-static ssize_t pmu_name_show(struct device *cdev,
- struct device_attribute *attr,
- char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n", pmu_name_str);
-}
-
-static DEVICE_ATTR_RO(pmu_name);
+static DEVICE_STRING_ATTR_RO(pmu_name, 0444, pmu_name_str);
static struct attribute *intel_pmu_caps_attrs[] = {
- &dev_attr_pmu_name.attr,
- NULL
+ &dev_attr_pmu_name.attr.attr,
+ NULL
};
static DEVICE_ATTR(allow_tsx_force_abort, 0644,
@@ -5705,8 +5830,22 @@ exra_is_visible(struct kobject *kobj, struct attribute *attr, int i)
return x86_pmu.version >= 2 ? attr->mode : 0;
}
+static umode_t
+td_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ /*
+ * Hide the perf metrics topdown events
+ * if the feature is not enumerated.
+ */
+ if (x86_pmu.num_topdown_events)
+ return x86_pmu.intel_cap.perf_metrics ? attr->mode : 0;
+
+ return attr->mode;
+}
+
static struct attribute_group group_events_td = {
.name = "events",
+ .is_visible = td_is_visible,
};
static struct attribute_group group_events_mem = {
@@ -5740,6 +5879,12 @@ static struct attribute_group group_format_extra_skl = {
.is_visible = exra_is_visible,
};
+static struct attribute_group group_format_evtsel_ext = {
+ .name = "format",
+ .attrs = format_evtsel_ext_attrs,
+ .is_visible = evtsel_ext_is_visible,
+};
+
static struct attribute_group group_default = {
.attrs = intel_pmu_attrs,
.is_visible = default_is_visible,
@@ -5753,6 +5898,7 @@ static const struct attribute_group *attr_update[] = {
&group_caps_lbr,
&group_format_extra,
&group_format_extra_skl,
+ &group_format_evtsel_ext,
&group_default,
NULL,
};
@@ -5780,6 +5926,23 @@ static struct attribute *adl_hybrid_events_attrs[] = {
NULL,
};
+EVENT_ATTR_STR_HYBRID(topdown-retiring, td_retiring_lnl, "event=0xc2,umask=0x02;event=0x00,umask=0x80", hybrid_big_small);
+EVENT_ATTR_STR_HYBRID(topdown-fe-bound, td_fe_bound_lnl, "event=0x9c,umask=0x01;event=0x00,umask=0x82", hybrid_big_small);
+EVENT_ATTR_STR_HYBRID(topdown-be-bound, td_be_bound_lnl, "event=0xa4,umask=0x02;event=0x00,umask=0x83", hybrid_big_small);
+
+static struct attribute *lnl_hybrid_events_attrs[] = {
+ EVENT_PTR(slots_adl),
+ EVENT_PTR(td_retiring_lnl),
+ EVENT_PTR(td_bad_spec_adl),
+ EVENT_PTR(td_fe_bound_lnl),
+ EVENT_PTR(td_be_bound_lnl),
+ EVENT_PTR(td_heavy_ops_adl),
+ EVENT_PTR(td_br_mis_adl),
+ EVENT_PTR(td_fetch_lat_adl),
+ EVENT_PTR(td_mem_bound_adl),
+ NULL
+};
+
/* Must be in IDX order */
EVENT_ATTR_STR_HYBRID(mem-loads, mem_ld_adl, "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3", hybrid_big_small);
EVENT_ATTR_STR_HYBRID(mem-stores, mem_st_adl, "event=0xd0,umask=0x6;event=0xcd,umask=0x2", hybrid_big_small);
@@ -5908,9 +6071,27 @@ static umode_t hybrid_format_is_visible(struct kobject *kobj,
return (cpu >= 0) && (pmu->pmu_type & pmu_attr->pmu_type) ? attr->mode : 0;
}
+static umode_t hybrid_td_is_visible(struct kobject *kobj,
+ struct attribute *attr, int i)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct x86_hybrid_pmu *pmu =
+ container_of(dev_get_drvdata(dev), struct x86_hybrid_pmu, pmu);
+
+ if (!is_attr_for_this_pmu(kobj, attr))
+ return 0;
+
+
+ /* Only the big core supports perf metrics */
+ if (pmu->pmu_type == hybrid_big)
+ return pmu->intel_cap.perf_metrics ? attr->mode : 0;
+
+ return attr->mode;
+}
+
static struct attribute_group hybrid_group_events_td = {
.name = "events",
- .is_visible = hybrid_events_is_visible,
+ .is_visible = hybrid_td_is_visible,
};
static struct attribute_group hybrid_group_events_mem = {
@@ -5955,6 +6136,7 @@ static const struct attribute_group *hybrid_attr_update[] = {
&group_caps_gen,
&group_caps_lbr,
&hybrid_group_format_extra,
+ &group_format_evtsel_ext,
&group_default,
&hybrid_group_cpus,
NULL,
@@ -5962,29 +6144,9 @@ static const struct attribute_group *hybrid_attr_update[] = {
static struct attribute *empty_attrs;
-static void intel_pmu_check_num_counters(int *num_counters,
- int *num_counters_fixed,
- u64 *intel_ctrl, u64 fixed_mask)
-{
- if (*num_counters > INTEL_PMC_MAX_GENERIC) {
- WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
- *num_counters, INTEL_PMC_MAX_GENERIC);
- *num_counters = INTEL_PMC_MAX_GENERIC;
- }
- *intel_ctrl = (1ULL << *num_counters) - 1;
-
- if (*num_counters_fixed > INTEL_PMC_MAX_FIXED) {
- WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
- *num_counters_fixed, INTEL_PMC_MAX_FIXED);
- *num_counters_fixed = INTEL_PMC_MAX_FIXED;
- }
-
- *intel_ctrl |= fixed_mask << INTEL_PMC_IDX_FIXED;
-}
-
static void intel_pmu_check_event_constraints(struct event_constraint *event_constraints,
- int num_counters,
- int num_counters_fixed,
+ u64 cntr_mask,
+ u64 fixed_cntr_mask,
u64 intel_ctrl)
{
struct event_constraint *c;
@@ -6021,10 +6183,9 @@ static void intel_pmu_check_event_constraints(struct event_constraint *event_con
* generic counters
*/
if (!use_fixed_pseudo_encoding(c->code))
- c->idxmsk64 |= (1ULL << num_counters) - 1;
+ c->idxmsk64 |= cntr_mask;
}
- c->idxmsk64 &=
- ~(~0ULL << (INTEL_PMC_IDX_FIXED + num_counters_fixed));
+ c->idxmsk64 &= cntr_mask | (fixed_cntr_mask << INTEL_PMC_IDX_FIXED);
c->weight = hweight64(c->idxmsk64);
}
}
@@ -6049,6 +6210,11 @@ static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs)
}
}
+static inline int intel_pmu_v6_addr_offset(int index, bool eventsel)
+{
+ return MSR_IA32_PMC_V6_STEP * index;
+}
+
static const struct { enum hybrid_pmu_type id; char *name; } intel_hybrid_pmu_type_map[] __initconst = {
{ hybrid_small, "cpu_atom" },
{ hybrid_big, "cpu_core" },
@@ -6075,12 +6241,13 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus)
pmu->pmu_type = intel_hybrid_pmu_type_map[bit].id;
pmu->name = intel_hybrid_pmu_type_map[bit].name;
- pmu->num_counters = x86_pmu.num_counters;
- pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
- pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
+ pmu->cntr_mask64 = x86_pmu.cntr_mask64;
+ pmu->fixed_cntr_mask64 = x86_pmu.fixed_cntr_mask64;
+ pmu->pebs_events_mask = intel_pmu_pebs_mask(pmu->cntr_mask64);
+ pmu->config_mask = X86_RAW_EVENT_MASK;
pmu->unconstrained = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
- 0, pmu->num_counters, 0, 0);
+ __EVENT_CONSTRAINT(0, pmu->cntr_mask64,
+ 0, x86_pmu_num_counters(&pmu->pmu), 0, 0);
pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;
if (pmu->pmu_type & hybrid_small) {
@@ -6150,6 +6317,21 @@ static __always_inline void intel_pmu_init_grt(struct pmu *pmu)
intel_pmu_ref_cycles_ext();
}
+static __always_inline void intel_pmu_init_lnc(struct pmu *pmu)
+{
+ intel_pmu_init_glc(pmu);
+ hybrid(pmu, event_constraints) = intel_lnc_event_constraints;
+ hybrid(pmu, pebs_constraints) = intel_lnc_pebs_event_constraints;
+ hybrid(pmu, extra_regs) = intel_rwc_extra_regs;
+}
+
+static __always_inline void intel_pmu_init_skt(struct pmu *pmu)
+{
+ intel_pmu_init_grt(pmu);
+ hybrid(pmu, event_constraints) = intel_skt_event_constraints;
+ hybrid(pmu, extra_regs) = intel_cmt_extra_regs;
+}
+
__init int intel_pmu_init(void)
{
struct attribute **extra_skl_attr = &empty_attrs;
@@ -6193,14 +6375,14 @@ __init int intel_pmu_init(void)
x86_pmu = intel_pmu;
x86_pmu.version = version;
- x86_pmu.num_counters = eax.split.num_counters;
+ x86_pmu.cntr_mask64 = GENMASK_ULL(eax.split.num_counters - 1, 0);
x86_pmu.cntval_bits = eax.split.bit_width;
x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1;
x86_pmu.events_maskl = ebx.full;
x86_pmu.events_mask_len = eax.split.mask_length;
- x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
+ x86_pmu.pebs_events_mask = intel_pmu_pebs_mask(x86_pmu.cntr_mask64);
x86_pmu.pebs_capable = PEBS_COUNTER_MASK;
/*
@@ -6210,12 +6392,10 @@ __init int intel_pmu_init(void)
if (version > 1 && version < 5) {
int assume = 3 * !boot_cpu_has(X86_FEATURE_HYPERVISOR);
- x86_pmu.num_counters_fixed =
- max((int)edx.split.num_counters_fixed, assume);
-
- fixed_mask = (1L << x86_pmu.num_counters_fixed) - 1;
+ x86_pmu.fixed_cntr_mask64 =
+ GENMASK_ULL(max((int)edx.split.num_counters_fixed, assume) - 1, 0);
} else if (version >= 5)
- x86_pmu.num_counters_fixed = fls(fixed_mask);
+ x86_pmu.fixed_cntr_mask64 = fixed_mask;
if (boot_cpu_has(X86_FEATURE_PDCM)) {
u64 capabilities;
@@ -6245,19 +6425,19 @@ __init int intel_pmu_init(void)
/*
* Install the hw-cache-events table:
*/
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_CORE_YONAH:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_CORE_YONAH:
pr_cont("Core events, ");
name = "core";
break;
- case INTEL_FAM6_CORE2_MEROM:
+ case INTEL_CORE2_MEROM:
x86_add_quirk(intel_clovertown_quirk);
fallthrough;
- case INTEL_FAM6_CORE2_MEROM_L:
- case INTEL_FAM6_CORE2_PENRYN:
- case INTEL_FAM6_CORE2_DUNNINGTON:
+ case INTEL_CORE2_MEROM_L:
+ case INTEL_CORE2_PENRYN:
+ case INTEL_CORE2_DUNNINGTON:
memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
@@ -6269,9 +6449,9 @@ __init int intel_pmu_init(void)
name = "core2";
break;
- case INTEL_FAM6_NEHALEM:
- case INTEL_FAM6_NEHALEM_EP:
- case INTEL_FAM6_NEHALEM_EX:
+ case INTEL_NEHALEM:
+ case INTEL_NEHALEM_EP:
+ case INTEL_NEHALEM_EX:
memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
@@ -6303,11 +6483,11 @@ __init int intel_pmu_init(void)
name = "nehalem";
break;
- case INTEL_FAM6_ATOM_BONNELL:
- case INTEL_FAM6_ATOM_BONNELL_MID:
- case INTEL_FAM6_ATOM_SALTWELL:
- case INTEL_FAM6_ATOM_SALTWELL_MID:
- case INTEL_FAM6_ATOM_SALTWELL_TABLET:
+ case INTEL_ATOM_BONNELL:
+ case INTEL_ATOM_BONNELL_MID:
+ case INTEL_ATOM_SALTWELL:
+ case INTEL_ATOM_SALTWELL_MID:
+ case INTEL_ATOM_SALTWELL_TABLET:
memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
@@ -6320,11 +6500,11 @@ __init int intel_pmu_init(void)
name = "bonnell";
break;
- case INTEL_FAM6_ATOM_SILVERMONT:
- case INTEL_FAM6_ATOM_SILVERMONT_D:
- case INTEL_FAM6_ATOM_SILVERMONT_MID:
- case INTEL_FAM6_ATOM_AIRMONT:
- case INTEL_FAM6_ATOM_AIRMONT_MID:
+ case INTEL_ATOM_SILVERMONT:
+ case INTEL_ATOM_SILVERMONT_D:
+ case INTEL_ATOM_SILVERMONT_MID:
+ case INTEL_ATOM_AIRMONT:
+ case INTEL_ATOM_AIRMONT_MID:
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
@@ -6342,8 +6522,8 @@ __init int intel_pmu_init(void)
name = "silvermont";
break;
- case INTEL_FAM6_ATOM_GOLDMONT:
- case INTEL_FAM6_ATOM_GOLDMONT_D:
+ case INTEL_ATOM_GOLDMONT:
+ case INTEL_ATOM_GOLDMONT_D:
memcpy(hw_cache_event_ids, glm_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs,
@@ -6369,7 +6549,7 @@ __init int intel_pmu_init(void)
name = "goldmont";
break;
- case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
+ case INTEL_ATOM_GOLDMONT_PLUS:
memcpy(hw_cache_event_ids, glp_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs,
@@ -6398,9 +6578,9 @@ __init int intel_pmu_init(void)
name = "goldmont_plus";
break;
- case INTEL_FAM6_ATOM_TREMONT_D:
- case INTEL_FAM6_ATOM_TREMONT:
- case INTEL_FAM6_ATOM_TREMONT_L:
+ case INTEL_ATOM_TREMONT_D:
+ case INTEL_ATOM_TREMONT:
+ case INTEL_ATOM_TREMONT_L:
x86_pmu.late_ack = true;
memcpy(hw_cache_event_ids, glp_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
@@ -6427,10 +6607,10 @@ __init int intel_pmu_init(void)
name = "Tremont";
break;
- case INTEL_FAM6_ATOM_GRACEMONT:
+ case INTEL_ATOM_GRACEMONT:
intel_pmu_init_grt(NULL);
intel_pmu_pebs_data_source_grt();
- x86_pmu.pebs_latency_data = adl_latency_data_small;
+ x86_pmu.pebs_latency_data = grt_latency_data;
x86_pmu.get_event_constraints = tnt_get_event_constraints;
td_attr = tnt_events_attrs;
mem_attr = grt_mem_attrs;
@@ -6439,12 +6619,12 @@ __init int intel_pmu_init(void)
name = "gracemont";
break;
- case INTEL_FAM6_ATOM_CRESTMONT:
- case INTEL_FAM6_ATOM_CRESTMONT_X:
+ case INTEL_ATOM_CRESTMONT:
+ case INTEL_ATOM_CRESTMONT_X:
intel_pmu_init_grt(NULL);
x86_pmu.extra_regs = intel_cmt_extra_regs;
intel_pmu_pebs_data_source_cmt();
- x86_pmu.pebs_latency_data = mtl_latency_data_small;
+ x86_pmu.pebs_latency_data = cmt_latency_data;
x86_pmu.get_event_constraints = cmt_get_event_constraints;
td_attr = cmt_events_attrs;
mem_attr = grt_mem_attrs;
@@ -6453,9 +6633,9 @@ __init int intel_pmu_init(void)
name = "crestmont";
break;
- case INTEL_FAM6_WESTMERE:
- case INTEL_FAM6_WESTMERE_EP:
- case INTEL_FAM6_WESTMERE_EX:
+ case INTEL_WESTMERE:
+ case INTEL_WESTMERE_EP:
+ case INTEL_WESTMERE_EX:
memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
@@ -6484,8 +6664,8 @@ __init int intel_pmu_init(void)
name = "westmere";
break;
- case INTEL_FAM6_SANDYBRIDGE:
- case INTEL_FAM6_SANDYBRIDGE_X:
+ case INTEL_SANDYBRIDGE:
+ case INTEL_SANDYBRIDGE_X:
x86_add_quirk(intel_sandybridge_quirk);
x86_add_quirk(intel_ht_bug);
memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
@@ -6498,7 +6678,7 @@ __init int intel_pmu_init(void)
x86_pmu.event_constraints = intel_snb_event_constraints;
x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
- if (boot_cpu_data.x86_model == INTEL_FAM6_SANDYBRIDGE_X)
+ if (boot_cpu_data.x86_vfm == INTEL_SANDYBRIDGE_X)
x86_pmu.extra_regs = intel_snbep_extra_regs;
else
x86_pmu.extra_regs = intel_snb_extra_regs;
@@ -6524,8 +6704,8 @@ __init int intel_pmu_init(void)
name = "sandybridge";
break;
- case INTEL_FAM6_IVYBRIDGE:
- case INTEL_FAM6_IVYBRIDGE_X:
+ case INTEL_IVYBRIDGE:
+ case INTEL_IVYBRIDGE_X:
x86_add_quirk(intel_ht_bug);
memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
@@ -6541,7 +6721,7 @@ __init int intel_pmu_init(void)
x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
x86_pmu.pebs_prec_dist = true;
- if (boot_cpu_data.x86_model == INTEL_FAM6_IVYBRIDGE_X)
+ if (boot_cpu_data.x86_vfm == INTEL_IVYBRIDGE_X)
x86_pmu.extra_regs = intel_snbep_extra_regs;
else
x86_pmu.extra_regs = intel_snb_extra_regs;
@@ -6563,10 +6743,10 @@ __init int intel_pmu_init(void)
break;
- case INTEL_FAM6_HASWELL:
- case INTEL_FAM6_HASWELL_X:
- case INTEL_FAM6_HASWELL_L:
- case INTEL_FAM6_HASWELL_G:
+ case INTEL_HASWELL:
+ case INTEL_HASWELL_X:
+ case INTEL_HASWELL_L:
+ case INTEL_HASWELL_G:
x86_add_quirk(intel_ht_bug);
x86_add_quirk(intel_pebs_isolation_quirk);
x86_pmu.late_ack = true;
@@ -6596,10 +6776,10 @@ __init int intel_pmu_init(void)
name = "haswell";
break;
- case INTEL_FAM6_BROADWELL:
- case INTEL_FAM6_BROADWELL_D:
- case INTEL_FAM6_BROADWELL_G:
- case INTEL_FAM6_BROADWELL_X:
+ case INTEL_BROADWELL:
+ case INTEL_BROADWELL_D:
+ case INTEL_BROADWELL_G:
+ case INTEL_BROADWELL_X:
x86_add_quirk(intel_pebs_isolation_quirk);
x86_pmu.late_ack = true;
memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
@@ -6638,8 +6818,8 @@ __init int intel_pmu_init(void)
name = "broadwell";
break;
- case INTEL_FAM6_XEON_PHI_KNL:
- case INTEL_FAM6_XEON_PHI_KNM:
+ case INTEL_XEON_PHI_KNL:
+ case INTEL_XEON_PHI_KNM:
memcpy(hw_cache_event_ids,
slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs,
@@ -6658,15 +6838,15 @@ __init int intel_pmu_init(void)
name = "knights-landing";
break;
- case INTEL_FAM6_SKYLAKE_X:
+ case INTEL_SKYLAKE_X:
pmem = true;
fallthrough;
- case INTEL_FAM6_SKYLAKE_L:
- case INTEL_FAM6_SKYLAKE:
- case INTEL_FAM6_KABYLAKE_L:
- case INTEL_FAM6_KABYLAKE:
- case INTEL_FAM6_COMETLAKE_L:
- case INTEL_FAM6_COMETLAKE:
+ case INTEL_SKYLAKE_L:
+ case INTEL_SKYLAKE:
+ case INTEL_KABYLAKE_L:
+ case INTEL_KABYLAKE:
+ case INTEL_COMETLAKE_L:
+ case INTEL_COMETLAKE:
x86_add_quirk(intel_pebs_isolation_quirk);
x86_pmu.late_ack = true;
memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
@@ -6715,16 +6895,16 @@ __init int intel_pmu_init(void)
name = "skylake";
break;
- case INTEL_FAM6_ICELAKE_X:
- case INTEL_FAM6_ICELAKE_D:
+ case INTEL_ICELAKE_X:
+ case INTEL_ICELAKE_D:
x86_pmu.pebs_ept = 1;
pmem = true;
fallthrough;
- case INTEL_FAM6_ICELAKE_L:
- case INTEL_FAM6_ICELAKE:
- case INTEL_FAM6_TIGERLAKE_L:
- case INTEL_FAM6_TIGERLAKE:
- case INTEL_FAM6_ROCKETLAKE:
+ case INTEL_ICELAKE_L:
+ case INTEL_ICELAKE:
+ case INTEL_TIGERLAKE_L:
+ case INTEL_TIGERLAKE:
+ case INTEL_ROCKETLAKE:
x86_pmu.late_ack = true;
memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
@@ -6759,16 +6939,22 @@ __init int intel_pmu_init(void)
name = "icelake";
break;
- case INTEL_FAM6_SAPPHIRERAPIDS_X:
- case INTEL_FAM6_EMERALDRAPIDS_X:
+ case INTEL_SAPPHIRERAPIDS_X:
+ case INTEL_EMERALDRAPIDS_X:
x86_pmu.flags |= PMU_FL_MEM_LOADS_AUX;
x86_pmu.extra_regs = intel_glc_extra_regs;
- fallthrough;
- case INTEL_FAM6_GRANITERAPIDS_X:
- case INTEL_FAM6_GRANITERAPIDS_D:
+ pr_cont("Sapphire Rapids events, ");
+ name = "sapphire_rapids";
+ goto glc_common;
+
+ case INTEL_GRANITERAPIDS_X:
+ case INTEL_GRANITERAPIDS_D:
+ x86_pmu.extra_regs = intel_rwc_extra_regs;
+ pr_cont("Granite Rapids events, ");
+ name = "granite_rapids";
+
+ glc_common:
intel_pmu_init_glc(NULL);
- if (!x86_pmu.extra_regs)
- x86_pmu.extra_regs = intel_rwc_extra_regs;
x86_pmu.pebs_ept = 1;
x86_pmu.hw_config = hsw_hw_config;
x86_pmu.get_event_constraints = glc_get_event_constraints;
@@ -6779,15 +6965,13 @@ __init int intel_pmu_init(void)
td_attr = glc_td_events_attrs;
tsx_attr = glc_tsx_events_attrs;
intel_pmu_pebs_data_source_skl(true);
- pr_cont("Sapphire Rapids events, ");
- name = "sapphire_rapids";
break;
- case INTEL_FAM6_ALDERLAKE:
- case INTEL_FAM6_ALDERLAKE_L:
- case INTEL_FAM6_RAPTORLAKE:
- case INTEL_FAM6_RAPTORLAKE_P:
- case INTEL_FAM6_RAPTORLAKE_S:
+ case INTEL_ALDERLAKE:
+ case INTEL_ALDERLAKE_L:
+ case INTEL_RAPTORLAKE:
+ case INTEL_RAPTORLAKE_P:
+ case INTEL_RAPTORLAKE_S:
/*
* Alder Lake has 2 types of CPU, core and atom.
*
@@ -6795,7 +6979,7 @@ __init int intel_pmu_init(void)
*/
intel_pmu_init_hybrid(hybrid_big_small);
- x86_pmu.pebs_latency_data = adl_latency_data_small;
+ x86_pmu.pebs_latency_data = grt_latency_data;
x86_pmu.get_event_constraints = adl_get_event_constraints;
x86_pmu.hw_config = adl_hw_config;
x86_pmu.get_hybrid_cpu_type = adl_get_hybrid_cpu_type;
@@ -6810,11 +6994,13 @@ __init int intel_pmu_init(void)
pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
intel_pmu_init_glc(&pmu->pmu);
if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) {
- pmu->num_counters = x86_pmu.num_counters + 2;
- pmu->num_counters_fixed = x86_pmu.num_counters_fixed + 1;
+ pmu->cntr_mask64 <<= 2;
+ pmu->cntr_mask64 |= 0x3;
+ pmu->fixed_cntr_mask64 <<= 1;
+ pmu->fixed_cntr_mask64 |= 0x1;
} else {
- pmu->num_counters = x86_pmu.num_counters;
- pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
+ pmu->cntr_mask64 = x86_pmu.cntr_mask64;
+ pmu->fixed_cntr_mask64 = x86_pmu.fixed_cntr_mask64;
}
/*
@@ -6824,15 +7010,16 @@ __init int intel_pmu_init(void)
* mistakenly add extra counters for P-cores. Correct the number of
* counters here.
*/
- if ((pmu->num_counters > 8) || (pmu->num_counters_fixed > 4)) {
- pmu->num_counters = x86_pmu.num_counters;
- pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
+ if ((x86_pmu_num_counters(&pmu->pmu) > 8) || (x86_pmu_num_counters_fixed(&pmu->pmu) > 4)) {
+ pmu->cntr_mask64 = x86_pmu.cntr_mask64;
+ pmu->fixed_cntr_mask64 = x86_pmu.fixed_cntr_mask64;
}
- pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
+ pmu->pebs_events_mask = intel_pmu_pebs_mask(pmu->cntr_mask64);
pmu->unconstrained = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
- 0, pmu->num_counters, 0, 0);
+ __EVENT_CONSTRAINT(0, pmu->cntr_mask64,
+ 0, x86_pmu_num_counters(&pmu->pmu), 0, 0);
+
pmu->extra_regs = intel_glc_extra_regs;
/* Initialize Atom core specific PerfMon capabilities.*/
@@ -6845,11 +7032,11 @@ __init int intel_pmu_init(void)
name = "alderlake_hybrid";
break;
- case INTEL_FAM6_METEORLAKE:
- case INTEL_FAM6_METEORLAKE_L:
+ case INTEL_METEORLAKE:
+ case INTEL_METEORLAKE_L:
intel_pmu_init_hybrid(hybrid_big_small);
- x86_pmu.pebs_latency_data = mtl_latency_data_small;
+ x86_pmu.pebs_latency_data = cmt_latency_data;
x86_pmu.get_event_constraints = mtl_get_event_constraints;
x86_pmu.hw_config = adl_hw_config;
@@ -6874,6 +7061,33 @@ __init int intel_pmu_init(void)
name = "meteorlake_hybrid";
break;
+ case INTEL_LUNARLAKE_M:
+ case INTEL_ARROWLAKE:
+ intel_pmu_init_hybrid(hybrid_big_small);
+
+ x86_pmu.pebs_latency_data = lnl_latency_data;
+ x86_pmu.get_event_constraints = mtl_get_event_constraints;
+ x86_pmu.hw_config = adl_hw_config;
+
+ td_attr = lnl_hybrid_events_attrs;
+ mem_attr = mtl_hybrid_mem_attrs;
+ tsx_attr = adl_hybrid_tsx_attrs;
+ extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
+ mtl_hybrid_extra_attr_rtm : mtl_hybrid_extra_attr;
+
+ /* Initialize big core specific PerfMon capabilities.*/
+ pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
+ intel_pmu_init_lnc(&pmu->pmu);
+
+ /* Initialize Atom core specific PerfMon capabilities.*/
+ pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
+ intel_pmu_init_skt(&pmu->pmu);
+
+ intel_pmu_pebs_data_source_lnl();
+ pr_cont("Lunarlake Hybrid events, ");
+ name = "lunarlake_hybrid";
+ break;
+
default:
switch (x86_pmu.version) {
case 1:
@@ -6899,9 +7113,9 @@ __init int intel_pmu_init(void)
* The constraints may be cut according to the CPUID enumeration
* by inserting the EVENT_CONSTRAINT_END.
*/
- if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED)
- x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
- intel_v5_gen_event_constraints[x86_pmu.num_counters_fixed].weight = -1;
+ if (fls64(x86_pmu.fixed_cntr_mask64) > INTEL_PMC_MAX_FIXED)
+ x86_pmu.fixed_cntr_mask64 &= GENMASK_ULL(INTEL_PMC_MAX_FIXED - 1, 0);
+ intel_v5_gen_event_constraints[fls64(x86_pmu.fixed_cntr_mask64)].weight = -1;
x86_pmu.event_constraints = intel_v5_gen_event_constraints;
pr_cont("generic architected perfmon, ");
name = "generic_arch_v5+";
@@ -6928,18 +7142,17 @@ __init int intel_pmu_init(void)
x86_pmu.attr_update = hybrid_attr_update;
}
- intel_pmu_check_num_counters(&x86_pmu.num_counters,
- &x86_pmu.num_counters_fixed,
- &x86_pmu.intel_ctrl,
- (u64)fixed_mask);
+ intel_pmu_check_counters_mask(&x86_pmu.cntr_mask64,
+ &x86_pmu.fixed_cntr_mask64,
+ &x86_pmu.intel_ctrl);
/* AnyThread may be deprecated on arch perfmon v5 or later */
if (x86_pmu.intel_cap.anythread_deprecated)
x86_pmu.format_attrs = intel_arch_formats_attr;
intel_pmu_check_event_constraints(x86_pmu.event_constraints,
- x86_pmu.num_counters,
- x86_pmu.num_counters_fixed,
+ x86_pmu.cntr_mask64,
+ x86_pmu.fixed_cntr_mask64,
x86_pmu.intel_ctrl);
/*
* Access LBR MSR may cause #GP under certain circumstances.
@@ -6980,6 +7193,14 @@ __init int intel_pmu_init(void)
pr_cont("full-width counters, ");
}
+ /* Support V6+ MSR Aliasing */
+ if (x86_pmu.version >= 6) {
+ x86_pmu.perfctr = MSR_IA32_PMC_V6_GP0_CTR;
+ x86_pmu.eventsel = MSR_IA32_PMC_V6_GP0_CFG_A;
+ x86_pmu.fixedctr = MSR_IA32_PMC_V6_FX0_CTR;
+ x86_pmu.addr_offset = intel_pmu_v6_addr_offset;
+ }
+
if (!is_hybrid() && x86_pmu.intel_cap.perf_metrics)
x86_pmu.intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS;
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 326c8cd5aa2d..be58cfb012dd 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -41,7 +41,7 @@
* MSR_CORE_C1_RES: CORE C1 Residency Counter
* perf code: 0x00
* Available model: SLM,AMT,GLM,CNL,ICX,TNT,ADL,RPL
- * MTL,SRF,GRR
+ * MTL,SRF,GRR,ARL,LNL
* Scope: Core (each processor core has a MSR)
* MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
* perf code: 0x01
@@ -53,50 +53,50 @@
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
* TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
- * GRR
+ * GRR,ARL,LNL
* Scope: Core
* MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
* perf code: 0x03
* Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML,
- * ICL,TGL,RKL,ADL,RPL,MTL
+ * ICL,TGL,RKL,ADL,RPL,MTL,ARL,LNL
* Scope: Core
* MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter.
* perf code: 0x00
* Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL,
* KBL,CML,ICL,ICX,TGL,TNT,RKL,ADL,
- * RPL,SPR,MTL
+ * RPL,SPR,MTL,ARL,LNL
* Scope: Package (physical package)
* MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter.
* perf code: 0x01
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL,
* GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL,
- * ADL,RPL,MTL
+ * ADL,RPL,MTL,ARL,LNL
* Scope: Package (physical package)
* MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter.
* perf code: 0x02
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
- * TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF
+ * TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
+ * ARL,LNL
* Scope: Package (physical package)
* MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter.
* perf code: 0x03
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL,
- * KBL,CML,ICL,TGL,RKL,ADL,RPL,MTL
+ * KBL,CML,ICL,TGL,RKL
* Scope: Package (physical package)
* MSR_PKG_C8_RESIDENCY: Package C8 Residency Counter.
* perf code: 0x04
* Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL,
- * ADL,RPL,MTL
+ * ADL,RPL,MTL,ARL
* Scope: Package (physical package)
* MSR_PKG_C9_RESIDENCY: Package C9 Residency Counter.
* perf code: 0x05
- * Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL,
- * ADL,RPL,MTL
+ * Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL
* Scope: Package (physical package)
* MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
* perf code: 0x06
* Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL,
- * TNT,RKL,ADL,RPL,MTL
+ * TNT,RKL,ADL,RPL,MTL,ARL,LNL
* Scope: Package (physical package)
* MSR_MODULE_C6_RES_MS: Module C6 Residency Counter.
* perf code: 0x00
@@ -114,6 +114,7 @@
#include "../perf_event.h"
#include "../probe.h"
+MODULE_DESCRIPTION("Support for Intel cstate performance events");
MODULE_LICENSE("GPL");
#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
@@ -143,12 +144,6 @@ struct cstate_model {
#define SLM_PKG_C6_USE_C7_MSR (1UL << 0)
#define KNL_CORE_C6_MSR (1UL << 1)
-struct perf_cstate_msr {
- u64 msr;
- struct perf_pmu_events_attr *attr;
-};
-
-
/* cstate_core PMU */
static struct pmu cstate_core_pmu;
static bool has_cstate_core;
@@ -642,9 +637,18 @@ static const struct cstate_model adl_cstates __initconst = {
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
BIT(PERF_CSTATE_PKG_C3_RES) |
BIT(PERF_CSTATE_PKG_C6_RES) |
- BIT(PERF_CSTATE_PKG_C7_RES) |
BIT(PERF_CSTATE_PKG_C8_RES) |
- BIT(PERF_CSTATE_PKG_C9_RES) |
+ BIT(PERF_CSTATE_PKG_C10_RES),
+};
+
+static const struct cstate_model lnl_cstates __initconst = {
+ .core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
+ BIT(PERF_CSTATE_CORE_C6_RES) |
+ BIT(PERF_CSTATE_CORE_C7_RES),
+
+ .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
+ BIT(PERF_CSTATE_PKG_C3_RES) |
+ BIT(PERF_CSTATE_PKG_C6_RES) |
BIT(PERF_CSTATE_PKG_C10_RES),
};
@@ -696,78 +700,82 @@ static const struct cstate_model srf_cstates __initconst = {
static const struct x86_cpu_id intel_cstates_match[] __initconst = {
- X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &nhm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &nhm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &nhm_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &nhm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &nhm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &nhm_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &snb_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &snb_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &snb_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &hswult_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &slm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, &slm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &slm_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &snb_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &snb_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &snb_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &hswult_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &hswult_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &hswult_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &hswult_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, &cnl_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &knl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &knl_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &glm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &glm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &glm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &glm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, &glm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &glm_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X, &srf_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT, &grr_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &icl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, &icl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &icx_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &icx_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &icx_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &icx_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X, &icx_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_D, &icx_cstates),
-
- X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &icl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &icl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &icl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, &adl_cstates),
- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &adl_cstates),
+ X86_MATCH_VFM(INTEL_NEHALEM, &nhm_cstates),
+ X86_MATCH_VFM(INTEL_NEHALEM_EP, &nhm_cstates),
+ X86_MATCH_VFM(INTEL_NEHALEM_EX, &nhm_cstates),
+
+ X86_MATCH_VFM(INTEL_WESTMERE, &nhm_cstates),
+ X86_MATCH_VFM(INTEL_WESTMERE_EP, &nhm_cstates),
+ X86_MATCH_VFM(INTEL_WESTMERE_EX, &nhm_cstates),
+
+ X86_MATCH_VFM(INTEL_SANDYBRIDGE, &snb_cstates),
+ X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &snb_cstates),
+
+ X86_MATCH_VFM(INTEL_IVYBRIDGE, &snb_cstates),
+ X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &snb_cstates),
+
+ X86_MATCH_VFM(INTEL_HASWELL, &snb_cstates),
+ X86_MATCH_VFM(INTEL_HASWELL_X, &snb_cstates),
+ X86_MATCH_VFM(INTEL_HASWELL_G, &snb_cstates),
+
+ X86_MATCH_VFM(INTEL_HASWELL_L, &hswult_cstates),
+
+ X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &slm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_D, &slm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &slm_cstates),
+
+ X86_MATCH_VFM(INTEL_BROADWELL, &snb_cstates),
+ X86_MATCH_VFM(INTEL_BROADWELL_D, &snb_cstates),
+ X86_MATCH_VFM(INTEL_BROADWELL_G, &snb_cstates),
+ X86_MATCH_VFM(INTEL_BROADWELL_X, &snb_cstates),
+
+ X86_MATCH_VFM(INTEL_SKYLAKE_L, &snb_cstates),
+ X86_MATCH_VFM(INTEL_SKYLAKE, &snb_cstates),
+ X86_MATCH_VFM(INTEL_SKYLAKE_X, &snb_cstates),
+
+ X86_MATCH_VFM(INTEL_KABYLAKE_L, &hswult_cstates),
+ X86_MATCH_VFM(INTEL_KABYLAKE, &hswult_cstates),
+ X86_MATCH_VFM(INTEL_COMETLAKE_L, &hswult_cstates),
+ X86_MATCH_VFM(INTEL_COMETLAKE, &hswult_cstates),
+
+ X86_MATCH_VFM(INTEL_CANNONLAKE_L, &cnl_cstates),
+
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &knl_cstates),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &knl_cstates),
+
+ X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &glm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &glm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &glm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &glm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_TREMONT, &glm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &glm_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &adl_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &srf_cstates),
+ X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &grr_cstates),
+
+ X86_MATCH_VFM(INTEL_ICELAKE_L, &icl_cstates),
+ X86_MATCH_VFM(INTEL_ICELAKE, &icl_cstates),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, &icx_cstates),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, &icx_cstates),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &icx_cstates),
+ X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &icx_cstates),
+ X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &icx_cstates),
+ X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &icx_cstates),
+
+ X86_MATCH_VFM(INTEL_TIGERLAKE_L, &icl_cstates),
+ X86_MATCH_VFM(INTEL_TIGERLAKE, &icl_cstates),
+ X86_MATCH_VFM(INTEL_ROCKETLAKE, &icl_cstates),
+ X86_MATCH_VFM(INTEL_ALDERLAKE, &adl_cstates),
+ X86_MATCH_VFM(INTEL_ALDERLAKE_L, &adl_cstates),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_cstates),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &adl_cstates),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_cstates),
+ X86_MATCH_VFM(INTEL_METEORLAKE, &adl_cstates),
+ X86_MATCH_VFM(INTEL_METEORLAKE_L, &adl_cstates),
+ X86_MATCH_VFM(INTEL_ARROWLAKE, &adl_cstates),
+ X86_MATCH_VFM(INTEL_ARROWLAKE_H, &adl_cstates),
+ X86_MATCH_VFM(INTEL_ARROWLAKE_U, &adl_cstates),
+ X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_cstates),
{ },
};
MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index e010bfed8417..fa5ea65de0d0 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -63,6 +63,15 @@ union intel_x86_pebs_dse {
unsigned int mtl_fwd_blk:1;
unsigned int ld_reserved4:24;
};
+ struct {
+ unsigned int lnc_dse:8;
+ unsigned int ld_reserved5:2;
+ unsigned int lnc_stlb_miss:1;
+ unsigned int lnc_locked:1;
+ unsigned int lnc_data_blk:1;
+ unsigned int lnc_addr_blk:1;
+ unsigned int ld_reserved6:18;
+ };
};
@@ -77,7 +86,7 @@ union intel_x86_pebs_dse {
#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
/* Version for Sandy Bridge and later */
-static u64 pebs_data_source[] = {
+static u64 pebs_data_source[PERF_PEBS_DATA_SOURCE_MAX] = {
P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 local */
OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
@@ -173,6 +182,40 @@ void __init intel_pmu_pebs_data_source_cmt(void)
__intel_pmu_pebs_data_source_cmt(pebs_data_source);
}
+/* Version for Lion Cove and later */
+static u64 lnc_pebs_data_source[PERF_PEBS_DATA_SOURCE_MAX] = {
+ P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA), /* 0x00: ukn L3 */
+ OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 hit */
+ OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x02: L1 hit */
+ OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x03: LFB/L1 Miss Handling Buffer hit */
+ 0, /* 0x04: Reserved */
+ OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x05: L2 Hit */
+ OP_LH | LEVEL(L2_MHB) | P(SNOOP, NONE), /* 0x06: L2 Miss Handling Buffer Hit */
+ 0, /* 0x07: Reserved */
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* 0x08: L3 Hit */
+ 0, /* 0x09: Reserved */
+ 0, /* 0x0a: Reserved */
+ 0, /* 0x0b: Reserved */
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD), /* 0x0c: L3 Hit Snoop Fwd */
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* 0x0d: L3 Hit Snoop HitM */
+ 0, /* 0x0e: Reserved */
+ P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* 0x0f: L3 Miss Snoop HitM */
+ OP_LH | LEVEL(MSC) | P(SNOOP, NONE), /* 0x10: Memory-side Cache Hit */
+ OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, NONE), /* 0x11: Local Memory Hit */
+};
+
+void __init intel_pmu_pebs_data_source_lnl(void)
+{
+ u64 *data_source;
+
+ data_source = x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX].pebs_data_source;
+ memcpy(data_source, lnc_pebs_data_source, sizeof(lnc_pebs_data_source));
+
+ data_source = x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX].pebs_data_source;
+ memcpy(data_source, pebs_data_source, sizeof(pebs_data_source));
+ __intel_pmu_pebs_data_source_cmt(data_source);
+}
+
static u64 precise_store_data(u64 status)
{
union intel_x86_pebs_dse dse;
@@ -257,14 +300,14 @@ static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock)
}
/* Retrieve the latency data for e-core of ADL */
-static u64 __adl_latency_data_small(struct perf_event *event, u64 status,
- u8 dse, bool tlb, bool lock, bool blk)
+static u64 __grt_latency_data(struct perf_event *event, u64 status,
+ u8 dse, bool tlb, bool lock, bool blk)
{
u64 val;
WARN_ON_ONCE(hybrid_pmu(event->pmu)->pmu_type == hybrid_big);
- dse &= PERF_PEBS_DATA_SOURCE_MASK;
+ dse &= PERF_PEBS_DATA_SOURCE_GRT_MASK;
val = hybrid_var(event->pmu, pebs_data_source)[dse];
pebs_set_tlb_lock(&val, tlb, lock);
@@ -277,27 +320,72 @@ static u64 __adl_latency_data_small(struct perf_event *event, u64 status,
return val;
}
-u64 adl_latency_data_small(struct perf_event *event, u64 status)
+u64 grt_latency_data(struct perf_event *event, u64 status)
{
union intel_x86_pebs_dse dse;
dse.val = status;
- return __adl_latency_data_small(event, status, dse.ld_dse,
- dse.ld_locked, dse.ld_stlb_miss,
- dse.ld_data_blk);
+ return __grt_latency_data(event, status, dse.ld_dse,
+ dse.ld_locked, dse.ld_stlb_miss,
+ dse.ld_data_blk);
}
/* Retrieve the latency data for e-core of MTL */
-u64 mtl_latency_data_small(struct perf_event *event, u64 status)
+u64 cmt_latency_data(struct perf_event *event, u64 status)
{
union intel_x86_pebs_dse dse;
dse.val = status;
- return __adl_latency_data_small(event, status, dse.mtl_dse,
- dse.mtl_stlb_miss, dse.mtl_locked,
- dse.mtl_fwd_blk);
+ return __grt_latency_data(event, status, dse.mtl_dse,
+ dse.mtl_stlb_miss, dse.mtl_locked,
+ dse.mtl_fwd_blk);
+}
+
+static u64 lnc_latency_data(struct perf_event *event, u64 status)
+{
+ union intel_x86_pebs_dse dse;
+ union perf_mem_data_src src;
+ u64 val;
+
+ dse.val = status;
+
+ /* LNC core latency data */
+ val = hybrid_var(event->pmu, pebs_data_source)[status & PERF_PEBS_DATA_SOURCE_MASK];
+ if (!val)
+ val = P(OP, LOAD) | LEVEL(NA) | P(SNOOP, NA);
+
+ if (dse.lnc_stlb_miss)
+ val |= P(TLB, MISS) | P(TLB, L2);
+ else
+ val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
+
+ if (dse.lnc_locked)
+ val |= P(LOCK, LOCKED);
+
+ if (dse.lnc_data_blk)
+ val |= P(BLK, DATA);
+ if (dse.lnc_addr_blk)
+ val |= P(BLK, ADDR);
+ if (!dse.lnc_data_blk && !dse.lnc_addr_blk)
+ val |= P(BLK, NA);
+
+ src.val = val;
+ if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
+ src.mem_op = P(OP, STORE);
+
+ return src.val;
+}
+
+u64 lnl_latency_data(struct perf_event *event, u64 status)
+{
+ struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
+
+ if (pmu->pmu_type == hybrid_small)
+ return cmt_latency_data(event, status);
+
+ return lnc_latency_data(event, status);
}
static u64 load_latency_data(struct perf_event *event, u64 status)
@@ -1086,6 +1174,32 @@ struct event_constraint intel_glc_pebs_event_constraints[] = {
EVENT_CONSTRAINT_END
};
+struct event_constraint intel_lnc_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),
+
+ INTEL_HYBRID_LDLAT_CONSTRAINT(0x1cd, 0x3ff),
+ INTEL_HYBRID_STLAT_CONSTRAINT(0x2cd, 0x3),
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
+
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf),
+
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xd0, 0xf),
+
+ /*
+ * Everything else is handled by PMU_FL_PEBS_ALL, because we
+ * need the full constraints from the main table.
+ */
+
+ EVENT_CONSTRAINT_END
+};
+
struct event_constraint *intel_pebs_constraints(struct perf_event *event)
{
struct event_constraint *pebs_constraints = hybrid(event->pmu, pebs_constraints);
@@ -1137,8 +1251,7 @@ void intel_pmu_pebs_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sche
static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
{
struct debug_store *ds = cpuc->ds;
- int max_pebs_events = hybrid(cpuc->pmu, max_pebs_events);
- int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
+ int max_pebs_events = intel_pmu_max_num_pebs(cpuc->pmu);
u64 threshold;
int reserved;
@@ -1146,7 +1259,7 @@ static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
return;
if (x86_pmu.flags & PMU_FL_PEBS_ALL)
- reserved = max_pebs_events + num_counters_fixed;
+ reserved = max_pebs_events + x86_pmu_max_num_counters_fixed(cpuc->pmu);
else
reserved = max_pebs_events;
@@ -1831,8 +1944,12 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
set_linear_ip(regs, basic->ip);
regs->flags = PERF_EFLAGS_EXACT;
- if ((sample_type & PERF_SAMPLE_WEIGHT_STRUCT) && (x86_pmu.flags & PMU_FL_RETIRE_LATENCY))
- data->weight.var3_w = format_size >> PEBS_RETIRE_LATENCY_OFFSET & PEBS_LATENCY_MASK;
+ if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT) {
+ if (x86_pmu.flags & PMU_FL_RETIRE_LATENCY)
+ data->weight.var3_w = format_size >> PEBS_RETIRE_LATENCY_OFFSET & PEBS_LATENCY_MASK;
+ else
+ data->weight.var3_w = 0;
+ }
/*
* The record for MEMINFO is in front of GP
@@ -2157,6 +2274,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
void *base, *at, *top;
short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
short error[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
+ int max_pebs_events = intel_pmu_max_num_pebs(NULL);
int bit, i, size;
u64 mask;
@@ -2168,11 +2286,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
ds->pebs_index = ds->pebs_buffer_base;
- mask = (1ULL << x86_pmu.max_pebs_events) - 1;
- size = x86_pmu.max_pebs_events;
+ mask = x86_pmu.pebs_events_mask;
+ size = max_pebs_events;
if (x86_pmu.flags & PMU_FL_PEBS_ALL) {
- mask |= ((1ULL << x86_pmu.num_counters_fixed) - 1) << INTEL_PMC_IDX_FIXED;
- size = INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed;
+ mask |= x86_pmu.fixed_cntr_mask64 << INTEL_PMC_IDX_FIXED;
+ size = INTEL_PMC_IDX_FIXED + x86_pmu_max_num_counters_fixed(NULL);
}
if (unlikely(base >= top)) {
@@ -2208,8 +2326,9 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
pebs_status = p->status = cpuc->pebs_enabled;
bit = find_first_bit((unsigned long *)&pebs_status,
- x86_pmu.max_pebs_events);
- if (bit >= x86_pmu.max_pebs_events)
+ max_pebs_events);
+
+ if (!(x86_pmu.pebs_events_mask & (1 << bit)))
continue;
/*
@@ -2267,12 +2386,10 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
{
short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int max_pebs_events = hybrid(cpuc->pmu, max_pebs_events);
- int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
struct debug_store *ds = cpuc->ds;
struct perf_event *event;
void *base, *at, *top;
- int bit, size;
+ int bit;
u64 mask;
if (!x86_pmu.pebs_active)
@@ -2283,12 +2400,11 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
ds->pebs_index = ds->pebs_buffer_base;
- mask = ((1ULL << max_pebs_events) - 1) |
- (((1ULL << num_counters_fixed) - 1) << INTEL_PMC_IDX_FIXED);
- size = INTEL_PMC_IDX_FIXED + num_counters_fixed;
+ mask = hybrid(cpuc->pmu, pebs_events_mask) |
+ (hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED);
if (unlikely(base >= top)) {
- intel_pmu_pebs_event_update_no_drain(cpuc, size);
+ intel_pmu_pebs_event_update_no_drain(cpuc, X86_PMC_IDX_MAX);
return;
}
@@ -2298,11 +2414,11 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
pebs_status = get_pebs_status(at) & cpuc->pebs_enabled;
pebs_status &= mask;
- for_each_set_bit(bit, (unsigned long *)&pebs_status, size)
+ for_each_set_bit(bit, (unsigned long *)&pebs_status, X86_PMC_IDX_MAX)
counts[bit]++;
}
- for_each_set_bit(bit, (unsigned long *)&mask, size) {
+ for_each_set_bit(bit, (unsigned long *)&mask, X86_PMC_IDX_MAX) {
if (counts[bit] == 0)
continue;
diff --git a/arch/x86/events/intel/knc.c b/arch/x86/events/intel/knc.c
index 618001c208e8..034a1f6a457c 100644
--- a/arch/x86/events/intel/knc.c
+++ b/arch/x86/events/intel/knc.c
@@ -303,7 +303,7 @@ static const struct x86_pmu knc_pmu __initconst = {
.apic = 1,
.max_period = (1ULL << 39) - 1,
.version = 0,
- .num_counters = 2,
+ .cntr_mask64 = 0x3,
.cntval_bits = 40,
.cntval_mask = (1ULL << 40) - 1,
.get_event_constraints = x86_get_event_constraints,
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 4367aa77cb8d..dc641b50814e 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -2,6 +2,7 @@
#include <linux/perf_event.h>
#include <linux/types.h>
+#include <asm/cpu_device_id.h>
#include <asm/perf_event.h>
#include <asm/msr.h>
@@ -1457,7 +1458,7 @@ void __init intel_pmu_lbr_init_atom(void)
* to have an operational LBR which can freeze
* on PMU interrupt
*/
- if (boot_cpu_data.x86_model == 28
+ if (boot_cpu_data.x86_vfm == INTEL_ATOM_BONNELL
&& boot_cpu_data.x86_stepping < 10) {
pr_cont("LBR disabled due to erratum");
return;
diff --git a/arch/x86/events/intel/p4.c b/arch/x86/events/intel/p4.c
index 35936188db01..844bc4fc4724 100644
--- a/arch/x86/events/intel/p4.c
+++ b/arch/x86/events/intel/p4.c
@@ -919,7 +919,7 @@ static void p4_pmu_disable_all(void)
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
struct perf_event *event = cpuc->events[idx];
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -998,7 +998,7 @@ static void p4_pmu_enable_all(int added)
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
struct perf_event *event = cpuc->events[idx];
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -1040,7 +1040,7 @@ static int p4_pmu_handle_irq(struct pt_regs *regs)
cpuc = this_cpu_ptr(&cpu_hw_events);
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
int overflow;
if (!test_bit(idx, cpuc->active_mask)) {
@@ -1353,7 +1353,7 @@ static __initconst const struct x86_pmu p4_pmu = {
* though leave it restricted at moment assuming
* HT is on
*/
- .num_counters = ARCH_P4_MAX_CCCR,
+ .cntr_mask64 = GENMASK_ULL(ARCH_P4_MAX_CCCR - 1, 0),
.apic = 1,
.cntval_bits = ARCH_P4_CNTRVAL_BITS,
.cntval_mask = ARCH_P4_CNTRVAL_MASK,
@@ -1395,7 +1395,7 @@ __init int p4_pmu_init(void)
*
* Solve this by zero'ing out the registers to mimic a reset.
*/
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for_each_set_bit(i, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
reg = x86_pmu_config_addr(i);
wrmsrl_safe(reg, 0ULL);
}
diff --git a/arch/x86/events/intel/p6.c b/arch/x86/events/intel/p6.c
index 408879b0c0d4..a6cffb4f4ef5 100644
--- a/arch/x86/events/intel/p6.c
+++ b/arch/x86/events/intel/p6.c
@@ -214,7 +214,7 @@ static __initconst const struct x86_pmu p6_pmu = {
.apic = 1,
.max_period = (1ULL << 31) - 1,
.version = 0,
- .num_counters = 2,
+ .cntr_mask64 = 0x3,
/*
* Events have 40 bits implemented. However they are designed such
* that bits [32-39] are sign extensions of bit 31. As such the
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 8e2a12235e62..b4aa8daa4773 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -22,7 +22,7 @@
#include <asm/insn.h>
#include <asm/io.h>
#include <asm/intel_pt.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include "../perf_event.h"
#include "pt.h"
@@ -211,11 +211,11 @@ static int __init pt_pmu_hw_init(void)
}
/* model-specific quirks */
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_BROADWELL:
- case INTEL_FAM6_BROADWELL_D:
- case INTEL_FAM6_BROADWELL_G:
- case INTEL_FAM6_BROADWELL_X:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_BROADWELL:
+ case INTEL_BROADWELL_D:
+ case INTEL_BROADWELL_G:
+ case INTEL_BROADWELL_X:
/* not setting BRANCH_EN will #GP, erratum BDM106 */
pt_pmu.branch_en_always_on = true;
break;
@@ -878,7 +878,7 @@ static void pt_update_head(struct pt *pt)
*/
static void *pt_buffer_region(struct pt_buffer *buf)
{
- return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
+ return phys_to_virt((phys_addr_t)TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
}
/**
@@ -990,7 +990,7 @@ pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg)
* order allocations, there shouldn't be many of these.
*/
list_for_each_entry(topa, &buf->tables, list) {
- if (topa->offset + topa->size > pg << PAGE_SHIFT)
+ if (topa->offset + topa->size > (unsigned long)pg << PAGE_SHIFT)
goto found;
}
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index 96906a62aacd..f5e46c04c145 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -33,8 +33,8 @@ struct topa_entry {
u64 rsvd2 : 1;
u64 size : 4;
u64 rsvd3 : 2;
- u64 base : 36;
- u64 rsvd4 : 16;
+ u64 base : 40;
+ u64 rsvd4 : 12;
};
/* TSC to Core Crystal Clock Ratio */
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 258e2cdf28fa..64ca8625eb58 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -34,6 +34,7 @@ static struct event_constraint uncore_constraint_fixed =
struct event_constraint uncore_constraint_empty =
EVENT_CONSTRAINT(0, 0, 0);
+MODULE_DESCRIPTION("Support for Intel uncore performance events");
MODULE_LICENSE("GPL");
int uncore_pcibus_to_dieid(struct pci_bus *bus)
@@ -263,6 +264,9 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box,
return;
}
+ if (intel_generic_uncore_assign_hw_event(event, box))
+ return;
+
hwc->config_base = uncore_event_ctl(box, hwc->idx);
hwc->event_base = uncore_perf_ctr(box, hwc->idx);
}
@@ -843,7 +847,9 @@ static void uncore_pmu_disable(struct pmu *pmu)
static ssize_t uncore_get_attr_cpumask(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
+ struct intel_uncore_pmu *pmu = container_of(dev_get_drvdata(dev), struct intel_uncore_pmu, pmu);
+
+ return cpumap_print_to_pagebuf(true, buf, &pmu->cpu_mask);
}
static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
@@ -860,7 +866,10 @@ static const struct attribute_group uncore_pmu_attr_group = {
static inline int uncore_get_box_id(struct intel_uncore_type *type,
struct intel_uncore_pmu *pmu)
{
- return type->box_ids ? type->box_ids[pmu->pmu_idx] : pmu->pmu_idx;
+ if (type->boxes)
+ return intel_uncore_find_discovery_unit_id(type->boxes, -1, pmu->pmu_idx);
+
+ return pmu->pmu_idx;
}
void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu)
@@ -961,6 +970,9 @@ static void uncore_type_exit(struct intel_uncore_type *type)
if (type->cleanup_mapping)
type->cleanup_mapping(type);
+ if (type->cleanup_extra_boxes)
+ type->cleanup_extra_boxes(type);
+
if (pmu) {
for (i = 0; i < type->num_boxes; i++, pmu++) {
uncore_pmu_unregister(pmu);
@@ -969,10 +981,7 @@ static void uncore_type_exit(struct intel_uncore_type *type)
kfree(type->pmus);
type->pmus = NULL;
}
- if (type->box_ids) {
- kfree(type->box_ids);
- type->box_ids = NULL;
- }
+
kfree(type->events_group);
type->events_group = NULL;
}
@@ -1076,22 +1085,19 @@ static struct intel_uncore_pmu *
uncore_pci_find_dev_pmu_from_types(struct pci_dev *pdev)
{
struct intel_uncore_type **types = uncore_pci_uncores;
+ struct intel_uncore_discovery_unit *unit;
struct intel_uncore_type *type;
- u64 box_ctl;
- int i, die;
+ struct rb_node *node;
for (; *types; types++) {
type = *types;
- for (die = 0; die < __uncore_max_dies; die++) {
- for (i = 0; i < type->num_boxes; i++) {
- if (!type->box_ctls[die])
- continue;
- box_ctl = type->box_ctls[die] + type->pci_offsets[i];
- if (pdev->devfn == UNCORE_DISCOVERY_PCI_DEVFN(box_ctl) &&
- pdev->bus->number == UNCORE_DISCOVERY_PCI_BUS(box_ctl) &&
- pci_domain_nr(pdev->bus) == UNCORE_DISCOVERY_PCI_DOMAIN(box_ctl))
- return &type->pmus[i];
- }
+
+ for (node = rb_first(type->boxes); node; node = rb_next(node)) {
+ unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+ if (pdev->devfn == UNCORE_DISCOVERY_PCI_DEVFN(unit->addr) &&
+ pdev->bus->number == UNCORE_DISCOVERY_PCI_BUS(unit->addr) &&
+ pci_domain_nr(pdev->bus) == UNCORE_DISCOVERY_PCI_DOMAIN(unit->addr))
+ return &type->pmus[unit->pmu_idx];
}
}
@@ -1367,28 +1373,25 @@ static struct notifier_block uncore_pci_notifier = {
static void uncore_pci_pmus_register(void)
{
struct intel_uncore_type **types = uncore_pci_uncores;
+ struct intel_uncore_discovery_unit *unit;
struct intel_uncore_type *type;
struct intel_uncore_pmu *pmu;
+ struct rb_node *node;
struct pci_dev *pdev;
- u64 box_ctl;
- int i, die;
for (; *types; types++) {
type = *types;
- for (die = 0; die < __uncore_max_dies; die++) {
- for (i = 0; i < type->num_boxes; i++) {
- if (!type->box_ctls[die])
- continue;
- box_ctl = type->box_ctls[die] + type->pci_offsets[i];
- pdev = pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(box_ctl),
- UNCORE_DISCOVERY_PCI_BUS(box_ctl),
- UNCORE_DISCOVERY_PCI_DEVFN(box_ctl));
- if (!pdev)
- continue;
- pmu = &type->pmus[i];
-
- uncore_pci_pmu_register(pdev, type, pmu, die);
- }
+
+ for (node = rb_first(type->boxes); node; node = rb_next(node)) {
+ unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+ pdev = pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(unit->addr),
+ UNCORE_DISCOVERY_PCI_BUS(unit->addr),
+ UNCORE_DISCOVERY_PCI_DEVFN(unit->addr));
+
+ if (!pdev)
+ continue;
+ pmu = &type->pmus[unit->pmu_idx];
+ uncore_pci_pmu_register(pdev, type, pmu, unit->die);
}
}
@@ -1453,6 +1456,18 @@ static void uncore_pci_exit(void)
}
}
+static bool uncore_die_has_box(struct intel_uncore_type *type,
+ int die, unsigned int pmu_idx)
+{
+ if (!type->boxes)
+ return true;
+
+ if (intel_uncore_find_discovery_unit_id(type->boxes, die, pmu_idx) < 0)
+ return false;
+
+ return true;
+}
+
static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
int new_cpu)
{
@@ -1468,18 +1483,25 @@ static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
if (old_cpu < 0) {
WARN_ON_ONCE(box->cpu != -1);
- box->cpu = new_cpu;
+ if (uncore_die_has_box(type, die, pmu->pmu_idx)) {
+ box->cpu = new_cpu;
+ cpumask_set_cpu(new_cpu, &pmu->cpu_mask);
+ }
continue;
}
- WARN_ON_ONCE(box->cpu != old_cpu);
+ WARN_ON_ONCE(box->cpu != -1 && box->cpu != old_cpu);
box->cpu = -1;
+ cpumask_clear_cpu(old_cpu, &pmu->cpu_mask);
if (new_cpu < 0)
continue;
+ if (!uncore_die_has_box(type, die, pmu->pmu_idx))
+ continue;
uncore_pmu_cancel_hrtimer(box);
perf_pmu_migrate_context(&pmu->pmu, old_cpu, new_cpu);
box->cpu = new_cpu;
+ cpumask_set_cpu(new_cpu, &pmu->cpu_mask);
}
}
@@ -1502,7 +1524,7 @@ static void uncore_box_unref(struct intel_uncore_type **types, int id)
pmu = type->pmus;
for (i = 0; i < type->num_boxes; i++, pmu++) {
box = pmu->boxes[id];
- if (box && atomic_dec_return(&box->refcnt) == 0)
+ if (box && box->cpu >= 0 && atomic_dec_return(&box->refcnt) == 0)
uncore_box_exit(box);
}
}
@@ -1592,7 +1614,7 @@ static int uncore_box_ref(struct intel_uncore_type **types,
pmu = type->pmus;
for (i = 0; i < type->num_boxes; i++, pmu++) {
box = pmu->boxes[id];
- if (box && atomic_inc_return(&box->refcnt) == 1)
+ if (box && box->cpu >= 0 && atomic_inc_return(&box->refcnt) == 1)
uncore_box_init(box);
}
}
@@ -1829,56 +1851,56 @@ static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
};
static const struct x86_cpu_id intel_uncore_match[] __initconst = {
- X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &nhm_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &nhm_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &nhm_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &nhm_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &snb_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &ivb_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &hsw_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &hsw_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &hsw_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &bdw_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &bdw_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &snbep_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &nhmex_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &nhmex_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &ivbep_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &hswep_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &bdx_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &bdx_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &knl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &knl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &skl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &skl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &skx_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &skl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &skl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &skl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &skl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &icl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, &icl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, &icl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &icx_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &icx_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_l_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rkl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &adl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &adl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, &mtl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &mtl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &spr_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &spr_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X, &gnr_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_D, &gnr_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &snr_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, &adl_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X, &gnr_uncore_init),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT, &gnr_uncore_init),
+ X86_MATCH_VFM(INTEL_NEHALEM_EP, &nhm_uncore_init),
+ X86_MATCH_VFM(INTEL_NEHALEM, &nhm_uncore_init),
+ X86_MATCH_VFM(INTEL_WESTMERE, &nhm_uncore_init),
+ X86_MATCH_VFM(INTEL_WESTMERE_EP, &nhm_uncore_init),
+ X86_MATCH_VFM(INTEL_SANDYBRIDGE, &snb_uncore_init),
+ X86_MATCH_VFM(INTEL_IVYBRIDGE, &ivb_uncore_init),
+ X86_MATCH_VFM(INTEL_HASWELL, &hsw_uncore_init),
+ X86_MATCH_VFM(INTEL_HASWELL_L, &hsw_uncore_init),
+ X86_MATCH_VFM(INTEL_HASWELL_G, &hsw_uncore_init),
+ X86_MATCH_VFM(INTEL_BROADWELL, &bdw_uncore_init),
+ X86_MATCH_VFM(INTEL_BROADWELL_G, &bdw_uncore_init),
+ X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &snbep_uncore_init),
+ X86_MATCH_VFM(INTEL_NEHALEM_EX, &nhmex_uncore_init),
+ X86_MATCH_VFM(INTEL_WESTMERE_EX, &nhmex_uncore_init),
+ X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &ivbep_uncore_init),
+ X86_MATCH_VFM(INTEL_HASWELL_X, &hswep_uncore_init),
+ X86_MATCH_VFM(INTEL_BROADWELL_X, &bdx_uncore_init),
+ X86_MATCH_VFM(INTEL_BROADWELL_D, &bdx_uncore_init),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &knl_uncore_init),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &knl_uncore_init),
+ X86_MATCH_VFM(INTEL_SKYLAKE, &skl_uncore_init),
+ X86_MATCH_VFM(INTEL_SKYLAKE_L, &skl_uncore_init),
+ X86_MATCH_VFM(INTEL_SKYLAKE_X, &skx_uncore_init),
+ X86_MATCH_VFM(INTEL_KABYLAKE_L, &skl_uncore_init),
+ X86_MATCH_VFM(INTEL_KABYLAKE, &skl_uncore_init),
+ X86_MATCH_VFM(INTEL_COMETLAKE_L, &skl_uncore_init),
+ X86_MATCH_VFM(INTEL_COMETLAKE, &skl_uncore_init),
+ X86_MATCH_VFM(INTEL_ICELAKE_L, &icl_uncore_init),
+ X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &icl_uncore_init),
+ X86_MATCH_VFM(INTEL_ICELAKE, &icl_uncore_init),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, &icx_uncore_init),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, &icx_uncore_init),
+ X86_MATCH_VFM(INTEL_TIGERLAKE_L, &tgl_l_uncore_init),
+ X86_MATCH_VFM(INTEL_TIGERLAKE, &tgl_uncore_init),
+ X86_MATCH_VFM(INTEL_ROCKETLAKE, &rkl_uncore_init),
+ X86_MATCH_VFM(INTEL_ALDERLAKE, &adl_uncore_init),
+ X86_MATCH_VFM(INTEL_ALDERLAKE_L, &adl_uncore_init),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_uncore_init),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &adl_uncore_init),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_uncore_init),
+ X86_MATCH_VFM(INTEL_METEORLAKE, &mtl_uncore_init),
+ X86_MATCH_VFM(INTEL_METEORLAKE_L, &mtl_uncore_init),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_uncore_init),
+ X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_uncore_init),
+ X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_uncore_init),
+ X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &gnr_uncore_init),
+ X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &snr_uncore_init),
+ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &adl_uncore_init),
+ X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_uncore_init),
+ X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_uncore_init),
{},
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 4838502d89ae..027ef292c602 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -62,7 +62,6 @@ struct intel_uncore_type {
unsigned fixed_ctr;
unsigned fixed_ctl;
unsigned box_ctl;
- u64 *box_ctls; /* Unit ctrl addr of the first box of each die */
union {
unsigned msr_offset;
unsigned mmio_offset;
@@ -76,7 +75,6 @@ struct intel_uncore_type {
u64 *pci_offsets;
u64 *mmio_offsets;
};
- unsigned *box_ids;
struct event_constraint unconstrainted;
struct event_constraint *constraints;
struct intel_uncore_pmu *pmus;
@@ -86,6 +84,7 @@ struct intel_uncore_type {
const struct attribute_group *attr_groups[4];
const struct attribute_group **attr_update;
struct pmu *pmu; /* for custom pmu ops */
+ struct rb_root *boxes;
/*
* Uncore PMU would store relevant platform topology configuration here
* to identify which platform component each PMON block of that type is
@@ -98,6 +97,10 @@ struct intel_uncore_type {
int (*get_topology)(struct intel_uncore_type *type);
void (*set_mapping)(struct intel_uncore_type *type);
void (*cleanup_mapping)(struct intel_uncore_type *type);
+ /*
+ * Optional callbacks for extra uncore units cleanup
+ */
+ void (*cleanup_extra_boxes)(struct intel_uncore_type *type);
};
#define pmu_group attr_groups[0]
@@ -125,6 +128,7 @@ struct intel_uncore_pmu {
int func_id;
bool registered;
atomic_t activeboxes;
+ cpumask_t cpu_mask;
struct intel_uncore_type *type;
struct intel_uncore_box **boxes;
};
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 9a698a92962a..571e44b49691 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -89,9 +89,7 @@ add_uncore_discovery_type(struct uncore_unit_discovery *unit)
if (!type)
return NULL;
- type->box_ctrl_die = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
- if (!type->box_ctrl_die)
- goto free_type;
+ type->units = RB_ROOT;
type->access_type = unit->access_type;
num_discovered_types[type->access_type]++;
@@ -100,12 +98,6 @@ add_uncore_discovery_type(struct uncore_unit_discovery *unit)
rb_add(&type->node, &discovery_tables, __type_less);
return type;
-
-free_type:
- kfree(type);
-
- return NULL;
-
}
static struct intel_uncore_discovery_type *
@@ -120,14 +112,118 @@ get_uncore_discovery_type(struct uncore_unit_discovery *unit)
return add_uncore_discovery_type(unit);
}
+static inline int pmu_idx_cmp(const void *key, const struct rb_node *b)
+{
+ struct intel_uncore_discovery_unit *unit;
+ const unsigned int *id = key;
+
+ unit = rb_entry(b, struct intel_uncore_discovery_unit, node);
+
+ if (unit->pmu_idx > *id)
+ return -1;
+ else if (unit->pmu_idx < *id)
+ return 1;
+
+ return 0;
+}
+
+static struct intel_uncore_discovery_unit *
+intel_uncore_find_discovery_unit(struct rb_root *units, int die,
+ unsigned int pmu_idx)
+{
+ struct intel_uncore_discovery_unit *unit;
+ struct rb_node *pos;
+
+ if (!units)
+ return NULL;
+
+ pos = rb_find_first(&pmu_idx, units, pmu_idx_cmp);
+ if (!pos)
+ return NULL;
+ unit = rb_entry(pos, struct intel_uncore_discovery_unit, node);
+
+ if (die < 0)
+ return unit;
+
+ for (; pos; pos = rb_next(pos)) {
+ unit = rb_entry(pos, struct intel_uncore_discovery_unit, node);
+
+ if (unit->pmu_idx != pmu_idx)
+ break;
+
+ if (unit->die == die)
+ return unit;
+ }
+
+ return NULL;
+}
+
+int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
+ unsigned int pmu_idx)
+{
+ struct intel_uncore_discovery_unit *unit;
+
+ unit = intel_uncore_find_discovery_unit(units, die, pmu_idx);
+ if (unit)
+ return unit->id;
+
+ return -1;
+}
+
+static inline bool unit_less(struct rb_node *a, const struct rb_node *b)
+{
+ struct intel_uncore_discovery_unit *a_node, *b_node;
+
+ a_node = rb_entry(a, struct intel_uncore_discovery_unit, node);
+ b_node = rb_entry(b, struct intel_uncore_discovery_unit, node);
+
+ if (a_node->pmu_idx < b_node->pmu_idx)
+ return true;
+ if (a_node->pmu_idx > b_node->pmu_idx)
+ return false;
+
+ if (a_node->die < b_node->die)
+ return true;
+ if (a_node->die > b_node->die)
+ return false;
+
+ return 0;
+}
+
+static inline struct intel_uncore_discovery_unit *
+uncore_find_unit(struct rb_root *root, unsigned int id)
+{
+ struct intel_uncore_discovery_unit *unit;
+ struct rb_node *node;
+
+ for (node = rb_first(root); node; node = rb_next(node)) {
+ unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+ if (unit->id == id)
+ return unit;
+ }
+
+ return NULL;
+}
+
+void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
+ struct rb_root *root, u16 *num_units)
+{
+ struct intel_uncore_discovery_unit *unit = uncore_find_unit(root, node->id);
+
+ if (unit)
+ node->pmu_idx = unit->pmu_idx;
+ else if (num_units)
+ node->pmu_idx = (*num_units)++;
+
+ rb_add(&node->node, root, unit_less);
+}
+
static void
uncore_insert_box_info(struct uncore_unit_discovery *unit,
- int die, bool parsed)
+ int die)
{
+ struct intel_uncore_discovery_unit *node;
struct intel_uncore_discovery_type *type;
- unsigned int *ids;
- u64 *box_offset;
- int i;
if (!unit->ctl || !unit->ctl_offset || !unit->ctr_offset) {
pr_info("Invalid address is detected for uncore type %d box %d, "
@@ -136,71 +232,29 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
return;
}
- if (parsed) {
- type = search_uncore_discovery_type(unit->box_type);
- if (!type) {
- pr_info("A spurious uncore type %d is detected, "
- "Disable the uncore type.\n",
- unit->box_type);
- return;
- }
- /* Store the first box of each die */
- if (!type->box_ctrl_die[die])
- type->box_ctrl_die[die] = unit->ctl;
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ if (!node)
return;
- }
- type = get_uncore_discovery_type(unit);
- if (!type)
- return;
+ node->die = die;
+ node->id = unit->box_id;
+ node->addr = unit->ctl;
- box_offset = kcalloc(type->num_boxes + 1, sizeof(u64), GFP_KERNEL);
- if (!box_offset)
+ type = get_uncore_discovery_type(unit);
+ if (!type) {
+ kfree(node);
return;
+ }
- ids = kcalloc(type->num_boxes + 1, sizeof(unsigned int), GFP_KERNEL);
- if (!ids)
- goto free_box_offset;
+ uncore_find_add_unit(node, &type->units, &type->num_units);
/* Store generic information for the first box */
- if (!type->num_boxes) {
- type->box_ctrl = unit->ctl;
- type->box_ctrl_die[die] = unit->ctl;
+ if (type->num_units == 1) {
type->num_counters = unit->num_regs;
type->counter_width = unit->bit_width;
type->ctl_offset = unit->ctl_offset;
type->ctr_offset = unit->ctr_offset;
- *ids = unit->box_id;
- goto end;
- }
-
- for (i = 0; i < type->num_boxes; i++) {
- ids[i] = type->ids[i];
- box_offset[i] = type->box_offset[i];
-
- if (unit->box_id == ids[i]) {
- pr_info("Duplicate uncore type %d box ID %d is detected, "
- "Drop the duplicate uncore unit.\n",
- unit->box_type, unit->box_id);
- goto free_ids;
- }
}
- ids[i] = unit->box_id;
- box_offset[i] = unit->ctl - type->box_ctrl;
- kfree(type->ids);
- kfree(type->box_offset);
-end:
- type->ids = ids;
- type->box_offset = box_offset;
- type->num_boxes++;
- return;
-
-free_ids:
- kfree(ids);
-
-free_box_offset:
- kfree(box_offset);
-
}
static bool
@@ -279,7 +333,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
if (uncore_ignore_unit(&unit, ignore))
continue;
- uncore_insert_box_info(&unit, die, *parsed);
+ uncore_insert_box_info(&unit, die);
}
*parsed = true;
@@ -339,9 +393,16 @@ err:
void intel_uncore_clear_discovery_tables(void)
{
struct intel_uncore_discovery_type *type, *next;
+ struct intel_uncore_discovery_unit *pos;
+ struct rb_node *node;
rbtree_postorder_for_each_entry_safe(type, next, &discovery_tables, node) {
- kfree(type->box_ctrl_die);
+ while (!RB_EMPTY_ROOT(&type->units)) {
+ node = rb_first(&type->units);
+ pos = rb_entry(node, struct intel_uncore_discovery_unit, node);
+ rb_erase(node, &type->units);
+ kfree(pos);
+ }
kfree(type);
}
}
@@ -366,19 +427,31 @@ static const struct attribute_group generic_uncore_format_group = {
.attrs = generic_uncore_formats_attr,
};
+static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
+{
+ struct intel_uncore_discovery_unit *unit;
+
+ unit = intel_uncore_find_discovery_unit(box->pmu->type->boxes,
+ -1, box->pmu->pmu_idx);
+ if (WARN_ON_ONCE(!unit))
+ return 0;
+
+ return unit->addr;
+}
+
void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box)
{
- wrmsrl(uncore_msr_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
+ wrmsrl(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
}
void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box)
{
- wrmsrl(uncore_msr_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
+ wrmsrl(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
}
void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box)
{
- wrmsrl(uncore_msr_box_ctl(box), 0);
+ wrmsrl(intel_generic_uncore_box_ctl(box), 0);
}
static void intel_generic_uncore_msr_enable_event(struct intel_uncore_box *box,
@@ -406,10 +479,47 @@ static struct intel_uncore_ops generic_uncore_msr_ops = {
.read_counter = uncore_msr_read_counter,
};
+bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
+ struct intel_uncore_box *box)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 box_ctl;
+
+ if (!box->pmu->type->boxes)
+ return false;
+
+ if (box->io_addr) {
+ hwc->config_base = uncore_pci_event_ctl(box, hwc->idx);
+ hwc->event_base = uncore_pci_perf_ctr(box, hwc->idx);
+ return true;
+ }
+
+ box_ctl = intel_generic_uncore_box_ctl(box);
+ if (!box_ctl)
+ return false;
+
+ if (box->pci_dev) {
+ box_ctl = UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl);
+ hwc->config_base = box_ctl + uncore_pci_event_ctl(box, hwc->idx);
+ hwc->event_base = box_ctl + uncore_pci_perf_ctr(box, hwc->idx);
+ return true;
+ }
+
+ hwc->config_base = box_ctl + box->pmu->type->event_ctl + hwc->idx;
+ hwc->event_base = box_ctl + box->pmu->type->perf_ctr + hwc->idx;
+
+ return true;
+}
+
+static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box *box)
+{
+ return UNCORE_DISCOVERY_PCI_BOX_CTRL(intel_generic_uncore_box_ctl(box));
+}
+
void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
{
struct pci_dev *pdev = box->pci_dev;
- int box_ctl = uncore_pci_box_ctl(box);
+ int box_ctl = intel_pci_uncore_box_ctl(box);
__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
@@ -418,7 +528,7 @@ void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box)
{
struct pci_dev *pdev = box->pci_dev;
- int box_ctl = uncore_pci_box_ctl(box);
+ int box_ctl = intel_pci_uncore_box_ctl(box);
pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
}
@@ -426,7 +536,7 @@ void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box)
void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box)
{
struct pci_dev *pdev = box->pci_dev;
- int box_ctl = uncore_pci_box_ctl(box);
+ int box_ctl = intel_pci_uncore_box_ctl(box);
pci_write_config_dword(pdev, box_ctl, 0);
}
@@ -473,34 +583,30 @@ static struct intel_uncore_ops generic_uncore_pci_ops = {
#define UNCORE_GENERIC_MMIO_SIZE 0x4000
-static u64 generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
-{
- struct intel_uncore_type *type = box->pmu->type;
-
- if (!type->box_ctls || !type->box_ctls[box->dieid] || !type->mmio_offsets)
- return 0;
-
- return type->box_ctls[box->dieid] + type->mmio_offsets[box->pmu->pmu_idx];
-}
-
void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box)
{
- u64 box_ctl = generic_uncore_mmio_box_ctl(box);
+ static struct intel_uncore_discovery_unit *unit;
struct intel_uncore_type *type = box->pmu->type;
resource_size_t addr;
- if (!box_ctl) {
+ unit = intel_uncore_find_discovery_unit(type->boxes, box->dieid, box->pmu->pmu_idx);
+ if (!unit) {
+ pr_warn("Uncore type %d id %d: Cannot find box control address.\n",
+ type->type_id, box->pmu->pmu_idx);
+ return;
+ }
+
+ if (!unit->addr) {
pr_warn("Uncore type %d box %d: Invalid box control address.\n",
- type->type_id, type->box_ids[box->pmu->pmu_idx]);
+ type->type_id, unit->id);
return;
}
- addr = box_ctl;
+ addr = unit->addr;
box->io_addr = ioremap(addr, UNCORE_GENERIC_MMIO_SIZE);
if (!box->io_addr) {
pr_warn("Uncore type %d box %d: ioremap error for 0x%llx.\n",
- type->type_id, type->box_ids[box->pmu->pmu_idx],
- (unsigned long long)addr);
+ type->type_id, unit->id, (unsigned long long)addr);
return;
}
@@ -560,34 +666,22 @@ static bool uncore_update_uncore_type(enum uncore_access_type type_id,
struct intel_uncore_discovery_type *type)
{
uncore->type_id = type->type;
- uncore->num_boxes = type->num_boxes;
uncore->num_counters = type->num_counters;
uncore->perf_ctr_bits = type->counter_width;
- uncore->box_ids = type->ids;
+ uncore->perf_ctr = (unsigned int)type->ctr_offset;
+ uncore->event_ctl = (unsigned int)type->ctl_offset;
+ uncore->boxes = &type->units;
+ uncore->num_boxes = type->num_units;
switch (type_id) {
case UNCORE_ACCESS_MSR:
uncore->ops = &generic_uncore_msr_ops;
- uncore->perf_ctr = (unsigned int)type->box_ctrl + type->ctr_offset;
- uncore->event_ctl = (unsigned int)type->box_ctrl + type->ctl_offset;
- uncore->box_ctl = (unsigned int)type->box_ctrl;
- uncore->msr_offsets = type->box_offset;
break;
case UNCORE_ACCESS_PCI:
uncore->ops = &generic_uncore_pci_ops;
- uncore->perf_ctr = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl) + type->ctr_offset;
- uncore->event_ctl = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl) + type->ctl_offset;
- uncore->box_ctl = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl);
- uncore->box_ctls = type->box_ctrl_die;
- uncore->pci_offsets = type->box_offset;
break;
case UNCORE_ACCESS_MMIO:
uncore->ops = &generic_uncore_mmio_ops;
- uncore->perf_ctr = (unsigned int)type->ctr_offset;
- uncore->event_ctl = (unsigned int)type->ctl_offset;
- uncore->box_ctl = (unsigned int)type->box_ctrl;
- uncore->box_ctls = type->box_ctrl_die;
- uncore->mmio_offsets = type->box_offset;
uncore->mmio_map_size = UNCORE_GENERIC_MMIO_SIZE;
break;
default:
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 22e769a81103..0e94aa7db8e7 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -113,19 +113,24 @@ struct uncore_unit_discovery {
};
};
+struct intel_uncore_discovery_unit {
+ struct rb_node node;
+ unsigned int pmu_idx; /* The idx of the corresponding PMU */
+ unsigned int id; /* Unit ID */
+ unsigned int die; /* Die ID */
+ u64 addr; /* Unit Control Address */
+};
+
struct intel_uncore_discovery_type {
struct rb_node node;
enum uncore_access_type access_type;
- u64 box_ctrl; /* Unit ctrl addr of the first box */
- u64 *box_ctrl_die; /* Unit ctrl addr of the first box of each die */
+ struct rb_root units; /* Unit ctrl addr for all units */
u16 type; /* Type ID of the uncore block */
u8 num_counters;
u8 counter_width;
u8 ctl_offset; /* Counter Control 0 offset */
u8 ctr_offset; /* Counter 0 offset */
- u16 num_boxes; /* number of boxes for the uncore block */
- unsigned int *ids; /* Box IDs */
- u64 *box_offset; /* Box offset */
+ u16 num_units; /* number of units */
};
bool intel_uncore_has_discovery_tables(int *ignore);
@@ -156,3 +161,10 @@ u64 intel_generic_uncore_pci_read_counter(struct intel_uncore_box *box,
struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra);
+
+int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
+ unsigned int pmu_idx);
+bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
+ struct intel_uncore_box *box);
+void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
+ struct rb_root *root, u16 *num_units);
diff --git a/arch/x86/events/intel/uncore_nhmex.c b/arch/x86/events/intel/uncore_nhmex.c
index 92da8aaa5966..466833478e81 100644
--- a/arch/x86/events/intel/uncore_nhmex.c
+++ b/arch/x86/events/intel/uncore_nhmex.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Nehalem-EX/Westmere-EX uncore support */
+#include <asm/cpu_device_id.h>
#include "uncore.h"
/* NHM-EX event control */
@@ -1217,7 +1218,7 @@ static struct intel_uncore_type *nhmex_msr_uncores[] = {
void nhmex_uncore_cpu_init(void)
{
- if (boot_cpu_data.x86_model == 46)
+ if (boot_cpu_data.x86_vfm == INTEL_NEHALEM_EX)
uncore_nhmex = true;
else
nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 2eaf0f339849..ca98744343b8 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* SandyBridge-EP/IvyTown uncore support */
+#include <asm/cpu_device_id.h>
#include "uncore.h"
#include "uncore_discovery.h"
@@ -461,6 +462,7 @@
#define SPR_UBOX_DID 0x3250
/* SPR CHA */
+#define SPR_CHA_EVENT_MASK_EXT 0xffffffff
#define SPR_CHA_PMON_CTL_TID_EN (1 << 16)
#define SPR_CHA_PMON_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
SPR_CHA_PMON_CTL_TID_EN)
@@ -477,6 +479,7 @@ DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55");
DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57");
DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39");
DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55");
+DEFINE_UNCORE_FORMAT_ATTR(umask_ext5, umask, "config:8-15,32-63");
DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
@@ -3285,7 +3288,7 @@ void bdx_uncore_cpu_init(void)
uncore_msr_uncores = bdx_msr_uncores;
/* Detect systems with no SBOXes */
- if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID))
+ if (boot_cpu_data.x86_vfm == INTEL_BROADWELL_D || hswep_has_limit_sbox(BDX_PCU_DID))
uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
@@ -5394,7 +5397,7 @@ static int icx_iio_get_topology(struct intel_uncore_type *type)
static void icx_iio_set_mapping(struct intel_uncore_type *type)
{
/* Detect ICX-D system. This case is not supported */
- if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
+ if (boot_cpu_data.x86_vfm == INTEL_ICELAKE_D) {
pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
return;
}
@@ -5932,10 +5935,11 @@ static int spr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *ev
struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
bool tie_en = !!(event->hw.config & SPR_CHA_PMON_CTL_TID_EN);
struct intel_uncore_type *type = box->pmu->type;
+ int id = intel_uncore_find_discovery_unit_id(type->boxes, -1, box->pmu->pmu_idx);
if (tie_en) {
reg1->reg = SPR_C0_MSR_PMON_BOX_FILTER0 +
- HSWEP_CBO_MSR_OFFSET * type->box_ids[box->pmu->pmu_idx];
+ HSWEP_CBO_MSR_OFFSET * id;
reg1->config = event->attr.config1 & SPR_CHA_PMON_BOX_FILTER_TID;
reg1->idx = 0;
}
@@ -5957,7 +5961,7 @@ static struct intel_uncore_ops spr_uncore_chabox_ops = {
static struct attribute *spr_uncore_cha_formats_attr[] = {
&format_attr_event.attr,
- &format_attr_umask_ext4.attr,
+ &format_attr_umask_ext5.attr,
&format_attr_tid_en2.attr,
&format_attr_edge.attr,
&format_attr_inv.attr,
@@ -5993,7 +5997,7 @@ ATTRIBUTE_GROUPS(uncore_alias);
static struct intel_uncore_type spr_uncore_chabox = {
.name = "cha",
.event_mask = SPR_CHA_PMON_EVENT_MASK,
- .event_mask_ext = SPR_RAW_EVENT_MASK_EXT,
+ .event_mask_ext = SPR_CHA_EVENT_MASK_EXT,
.num_shared_regs = 1,
.constraints = skx_uncore_chabox_constraints,
.ops = &spr_uncore_chabox_ops,
@@ -6161,7 +6165,55 @@ static struct intel_uncore_type spr_uncore_mdf = {
.name = "mdf",
};
-#define UNCORE_SPR_NUM_UNCORE_TYPES 12
+static void spr_uncore_mmio_offs8_init_box(struct intel_uncore_box *box)
+{
+ __set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
+ intel_generic_uncore_mmio_init_box(box);
+}
+
+static struct intel_uncore_ops spr_uncore_mmio_offs8_ops = {
+ .init_box = spr_uncore_mmio_offs8_init_box,
+ .exit_box = uncore_mmio_exit_box,
+ .disable_box = intel_generic_uncore_mmio_disable_box,
+ .enable_box = intel_generic_uncore_mmio_enable_box,
+ .disable_event = intel_generic_uncore_mmio_disable_event,
+ .enable_event = spr_uncore_mmio_enable_event,
+ .read_counter = uncore_mmio_read_counter,
+};
+
+#define SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT() \
+ SPR_UNCORE_COMMON_FORMAT(), \
+ .ops = &spr_uncore_mmio_offs8_ops
+
+static struct event_constraint spr_uncore_cxlcm_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x02, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x05, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x40, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x41, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x42, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x43, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x4b, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x52, 0xf0),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type spr_uncore_cxlcm = {
+ SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT(),
+ .name = "cxlcm",
+ .constraints = spr_uncore_cxlcm_constraints,
+};
+
+static struct intel_uncore_type spr_uncore_cxldp = {
+ SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT(),
+ .name = "cxldp",
+};
+
+static struct intel_uncore_type spr_uncore_hbm = {
+ SPR_UNCORE_COMMON_FORMAT(),
+ .name = "hbm",
+};
+
+#define UNCORE_SPR_NUM_UNCORE_TYPES 15
#define UNCORE_SPR_CHA 0
#define UNCORE_SPR_IIO 1
#define UNCORE_SPR_IMC 6
@@ -6185,6 +6237,9 @@ static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
NULL,
NULL,
&spr_uncore_mdf,
+ &spr_uncore_cxlcm,
+ &spr_uncore_cxldp,
+ &spr_uncore_hbm,
};
/*
@@ -6197,6 +6252,24 @@ static u64 spr_upi_pci_offsets[SPR_UNCORE_UPI_NUM_BOXES] = {
0, 0x8000, 0x10000, 0x18000
};
+static void spr_extra_boxes_cleanup(struct intel_uncore_type *type)
+{
+ struct intel_uncore_discovery_unit *pos;
+ struct rb_node *node;
+
+ if (!type->boxes)
+ return;
+
+ while (!RB_EMPTY_ROOT(type->boxes)) {
+ node = rb_first(type->boxes);
+ pos = rb_entry(node, struct intel_uncore_discovery_unit, node);
+ rb_erase(node, type->boxes);
+ kfree(pos);
+ }
+ kfree(type->boxes);
+ type->boxes = NULL;
+}
+
static struct intel_uncore_type spr_uncore_upi = {
.event_mask = SNBEP_PMON_RAW_EVENT_MASK,
.event_mask_ext = SPR_RAW_EVENT_MASK_EXT,
@@ -6211,10 +6284,11 @@ static struct intel_uncore_type spr_uncore_upi = {
.num_counters = 4,
.num_boxes = SPR_UNCORE_UPI_NUM_BOXES,
.perf_ctr_bits = 48,
- .perf_ctr = ICX_UPI_PCI_PMON_CTR0,
- .event_ctl = ICX_UPI_PCI_PMON_CTL0,
+ .perf_ctr = ICX_UPI_PCI_PMON_CTR0 - ICX_UPI_PCI_PMON_BOX_CTL,
+ .event_ctl = ICX_UPI_PCI_PMON_CTL0 - ICX_UPI_PCI_PMON_BOX_CTL,
.box_ctl = ICX_UPI_PCI_PMON_BOX_CTL,
.pci_offsets = spr_upi_pci_offsets,
+ .cleanup_extra_boxes = spr_extra_boxes_cleanup,
};
static struct intel_uncore_type spr_uncore_m3upi = {
@@ -6224,11 +6298,12 @@ static struct intel_uncore_type spr_uncore_m3upi = {
.num_counters = 4,
.num_boxes = SPR_UNCORE_UPI_NUM_BOXES,
.perf_ctr_bits = 48,
- .perf_ctr = ICX_M3UPI_PCI_PMON_CTR0,
- .event_ctl = ICX_M3UPI_PCI_PMON_CTL0,
+ .perf_ctr = ICX_M3UPI_PCI_PMON_CTR0 - ICX_M3UPI_PCI_PMON_BOX_CTL,
+ .event_ctl = ICX_M3UPI_PCI_PMON_CTL0 - ICX_M3UPI_PCI_PMON_BOX_CTL,
.box_ctl = ICX_M3UPI_PCI_PMON_BOX_CTL,
.pci_offsets = spr_upi_pci_offsets,
.constraints = icx_uncore_m3upi_constraints,
+ .cleanup_extra_boxes = spr_extra_boxes_cleanup,
};
enum perf_uncore_spr_iio_freerunning_type_id {
@@ -6459,18 +6534,21 @@ uncore_find_type_by_id(struct intel_uncore_type **types, int type_id)
static int uncore_type_max_boxes(struct intel_uncore_type **types,
int type_id)
{
+ struct intel_uncore_discovery_unit *unit;
struct intel_uncore_type *type;
- int i, max = 0;
+ struct rb_node *node;
+ int max = 0;
type = uncore_find_type_by_id(types, type_id);
if (!type)
return 0;
- for (i = 0; i < type->num_boxes; i++) {
- if (type->box_ids[i] > max)
- max = type->box_ids[i];
- }
+ for (node = rb_first(type->boxes); node; node = rb_next(node)) {
+ unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+ if (unit->id > max)
+ max = unit->id;
+ }
return max + 1;
}
@@ -6512,10 +6590,11 @@ void spr_uncore_cpu_init(void)
static void spr_update_device_location(int type_id)
{
+ struct intel_uncore_discovery_unit *unit;
struct intel_uncore_type *type;
struct pci_dev *dev = NULL;
+ struct rb_root *root;
u32 device, devfn;
- u64 *ctls;
int die;
if (type_id == UNCORE_SPR_UPI) {
@@ -6529,27 +6608,35 @@ static void spr_update_device_location(int type_id)
} else
return;
- ctls = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
- if (!ctls) {
+ root = kzalloc(sizeof(struct rb_root), GFP_KERNEL);
+ if (!root) {
type->num_boxes = 0;
return;
}
+ *root = RB_ROOT;
while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) != NULL) {
- if (devfn != dev->devfn)
- continue;
die = uncore_device_to_die(dev);
if (die < 0)
continue;
- ctls[die] = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
- dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
- devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
- type->box_ctl;
+ unit = kzalloc(sizeof(*unit), GFP_KERNEL);
+ if (!unit)
+ continue;
+ unit->die = die;
+ unit->id = PCI_SLOT(dev->devfn) - PCI_SLOT(devfn);
+ unit->addr = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
+ dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
+ devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
+ type->box_ctl;
+
+ unit->pmu_idx = unit->id;
+
+ uncore_find_add_unit(unit, root, NULL);
}
- type->box_ctls = ctls;
+ type->boxes = root;
}
int spr_uncore_pci_init(void)
@@ -6622,7 +6709,7 @@ static struct intel_uncore_type gnr_uncore_b2cmi = {
};
static struct intel_uncore_type gnr_uncore_b2cxl = {
- SPR_UNCORE_MMIO_COMMON_FORMAT(),
+ SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT(),
.name = "b2cxl",
};
diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index 9e237b30f017..45b1866ff051 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -2,7 +2,7 @@
#include <linux/perf_event.h>
#include <linux/sysfs.h>
#include <linux/nospec.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include "probe.h"
enum perf_msr_id {
@@ -43,75 +43,75 @@ static bool test_intel(int idx, void *data)
boot_cpu_data.x86 != 6)
return false;
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_NEHALEM:
- case INTEL_FAM6_NEHALEM_G:
- case INTEL_FAM6_NEHALEM_EP:
- case INTEL_FAM6_NEHALEM_EX:
-
- case INTEL_FAM6_WESTMERE:
- case INTEL_FAM6_WESTMERE_EP:
- case INTEL_FAM6_WESTMERE_EX:
-
- case INTEL_FAM6_SANDYBRIDGE:
- case INTEL_FAM6_SANDYBRIDGE_X:
-
- case INTEL_FAM6_IVYBRIDGE:
- case INTEL_FAM6_IVYBRIDGE_X:
-
- case INTEL_FAM6_HASWELL:
- case INTEL_FAM6_HASWELL_X:
- case INTEL_FAM6_HASWELL_L:
- case INTEL_FAM6_HASWELL_G:
-
- case INTEL_FAM6_BROADWELL:
- case INTEL_FAM6_BROADWELL_D:
- case INTEL_FAM6_BROADWELL_G:
- case INTEL_FAM6_BROADWELL_X:
- case INTEL_FAM6_SAPPHIRERAPIDS_X:
- case INTEL_FAM6_EMERALDRAPIDS_X:
- case INTEL_FAM6_GRANITERAPIDS_X:
- case INTEL_FAM6_GRANITERAPIDS_D:
-
- case INTEL_FAM6_ATOM_SILVERMONT:
- case INTEL_FAM6_ATOM_SILVERMONT_D:
- case INTEL_FAM6_ATOM_AIRMONT:
-
- case INTEL_FAM6_ATOM_GOLDMONT:
- case INTEL_FAM6_ATOM_GOLDMONT_D:
- 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:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_NEHALEM:
+ case INTEL_NEHALEM_G:
+ case INTEL_NEHALEM_EP:
+ case INTEL_NEHALEM_EX:
+
+ case INTEL_WESTMERE:
+ case INTEL_WESTMERE_EP:
+ case INTEL_WESTMERE_EX:
+
+ case INTEL_SANDYBRIDGE:
+ case INTEL_SANDYBRIDGE_X:
+
+ case INTEL_IVYBRIDGE:
+ case INTEL_IVYBRIDGE_X:
+
+ case INTEL_HASWELL:
+ case INTEL_HASWELL_X:
+ case INTEL_HASWELL_L:
+ case INTEL_HASWELL_G:
+
+ case INTEL_BROADWELL:
+ case INTEL_BROADWELL_D:
+ case INTEL_BROADWELL_G:
+ case INTEL_BROADWELL_X:
+ case INTEL_SAPPHIRERAPIDS_X:
+ case INTEL_EMERALDRAPIDS_X:
+ case INTEL_GRANITERAPIDS_X:
+ case INTEL_GRANITERAPIDS_D:
+
+ case INTEL_ATOM_SILVERMONT:
+ case INTEL_ATOM_SILVERMONT_D:
+ case INTEL_ATOM_AIRMONT:
+
+ case INTEL_ATOM_GOLDMONT:
+ case INTEL_ATOM_GOLDMONT_D:
+ case INTEL_ATOM_GOLDMONT_PLUS:
+ case INTEL_ATOM_TREMONT_D:
+ case INTEL_ATOM_TREMONT:
+ case INTEL_ATOM_TREMONT_L:
+
+ case INTEL_XEON_PHI_KNL:
+ case INTEL_XEON_PHI_KNM:
if (idx == PERF_MSR_SMI)
return true;
break;
- case INTEL_FAM6_SKYLAKE_L:
- case INTEL_FAM6_SKYLAKE:
- case INTEL_FAM6_SKYLAKE_X:
- case INTEL_FAM6_KABYLAKE_L:
- case INTEL_FAM6_KABYLAKE:
- case INTEL_FAM6_COMETLAKE_L:
- case INTEL_FAM6_COMETLAKE:
- case INTEL_FAM6_ICELAKE_L:
- case INTEL_FAM6_ICELAKE:
- case INTEL_FAM6_ICELAKE_X:
- case INTEL_FAM6_ICELAKE_D:
- case INTEL_FAM6_TIGERLAKE_L:
- case INTEL_FAM6_TIGERLAKE:
- case INTEL_FAM6_ROCKETLAKE:
- case INTEL_FAM6_ALDERLAKE:
- case INTEL_FAM6_ALDERLAKE_L:
- case INTEL_FAM6_ATOM_GRACEMONT:
- case INTEL_FAM6_RAPTORLAKE:
- case INTEL_FAM6_RAPTORLAKE_P:
- case INTEL_FAM6_RAPTORLAKE_S:
- case INTEL_FAM6_METEORLAKE:
- case INTEL_FAM6_METEORLAKE_L:
+ case INTEL_SKYLAKE_L:
+ case INTEL_SKYLAKE:
+ case INTEL_SKYLAKE_X:
+ case INTEL_KABYLAKE_L:
+ case INTEL_KABYLAKE:
+ case INTEL_COMETLAKE_L:
+ case INTEL_COMETLAKE:
+ case INTEL_ICELAKE_L:
+ case INTEL_ICELAKE:
+ case INTEL_ICELAKE_X:
+ case INTEL_ICELAKE_D:
+ case INTEL_TIGERLAKE_L:
+ case INTEL_TIGERLAKE:
+ case INTEL_ROCKETLAKE:
+ case INTEL_ALDERLAKE:
+ case INTEL_ALDERLAKE_L:
+ case INTEL_ATOM_GRACEMONT:
+ case INTEL_RAPTORLAKE:
+ case INTEL_RAPTORLAKE_P:
+ case INTEL_RAPTORLAKE_S:
+ case INTEL_METEORLAKE:
+ case INTEL_METEORLAKE_L:
if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
return true;
break;
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index fb56518356ec..ac1182141bf6 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -476,6 +476,14 @@ struct cpu_hw_events {
__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID)
+#define INTEL_HYBRID_LDLAT_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID|PERF_X86_EVENT_PEBS_LD_HSW)
+
+#define INTEL_HYBRID_STLAT_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID|PERF_X86_EVENT_PEBS_ST_HSW)
+
/* Event constraint, but match on all event flags too. */
#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS)
@@ -655,8 +663,10 @@ enum {
x86_lbr_exclusive_max,
};
-#define PERF_PEBS_DATA_SOURCE_MAX 0x10
+#define PERF_PEBS_DATA_SOURCE_MAX 0x100
#define PERF_PEBS_DATA_SOURCE_MASK (PERF_PEBS_DATA_SOURCE_MAX - 1)
+#define PERF_PEBS_DATA_SOURCE_GRT_MAX 0x10
+#define PERF_PEBS_DATA_SOURCE_GRT_MASK (PERF_PEBS_DATA_SOURCE_GRT_MAX - 1)
enum hybrid_cpu_type {
HYBRID_INTEL_NONE,
@@ -684,9 +694,16 @@ struct x86_hybrid_pmu {
cpumask_t supported_cpus;
union perf_capabilities intel_cap;
u64 intel_ctrl;
- int max_pebs_events;
- int num_counters;
- int num_counters_fixed;
+ u64 pebs_events_mask;
+ u64 config_mask;
+ union {
+ u64 cntr_mask64;
+ unsigned long cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ };
+ union {
+ u64 fixed_cntr_mask64;
+ unsigned long fixed_cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ };
struct event_constraint unconstrained;
u64 hw_cache_event_ids
@@ -770,12 +787,20 @@ struct x86_pmu {
int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
unsigned eventsel;
unsigned perfctr;
+ unsigned fixedctr;
int (*addr_offset)(int index, bool eventsel);
int (*rdpmc_index)(int index);
u64 (*event_map)(int);
int max_events;
- int num_counters;
- int num_counters_fixed;
+ u64 config_mask;
+ union {
+ u64 cntr_mask64;
+ unsigned long cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ };
+ union {
+ u64 fixed_cntr_mask64;
+ unsigned long fixed_cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ };
int cntval_bits;
u64 cntval_mask;
union {
@@ -852,7 +877,7 @@ struct x86_pmu {
pebs_ept :1;
int pebs_record_size;
int pebs_buffer_size;
- int max_pebs_events;
+ u64 pebs_events_mask;
void (*drain_pebs)(struct pt_regs *regs, struct perf_sample_data *data);
struct event_constraint *pebs_constraints;
void (*pebs_aliases)(struct perf_event *event);
@@ -1120,13 +1145,19 @@ static inline unsigned int x86_pmu_event_addr(int index)
x86_pmu.addr_offset(index, false) : index);
}
+static inline unsigned int x86_pmu_fixed_ctr_addr(int index)
+{
+ return x86_pmu.fixedctr + (x86_pmu.addr_offset ?
+ x86_pmu.addr_offset(index, false) : index);
+}
+
static inline int x86_pmu_rdpmc_index(int index)
{
return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
}
-bool check_hw_exists(struct pmu *pmu, int num_counters,
- int num_counters_fixed);
+bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
+ unsigned long *fixed_cntr_mask);
int x86_add_exclusive(unsigned int what);
@@ -1197,8 +1228,32 @@ void x86_pmu_enable_event(struct perf_event *event);
int x86_pmu_handle_irq(struct pt_regs *regs);
-void x86_pmu_show_pmu_cap(int num_counters, int num_counters_fixed,
- u64 intel_ctrl);
+void x86_pmu_show_pmu_cap(struct pmu *pmu);
+
+static inline int x86_pmu_num_counters(struct pmu *pmu)
+{
+ return hweight64(hybrid(pmu, cntr_mask64));
+}
+
+static inline int x86_pmu_max_num_counters(struct pmu *pmu)
+{
+ return fls64(hybrid(pmu, cntr_mask64));
+}
+
+static inline int x86_pmu_num_counters_fixed(struct pmu *pmu)
+{
+ return hweight64(hybrid(pmu, fixed_cntr_mask64));
+}
+
+static inline int x86_pmu_max_num_counters_fixed(struct pmu *pmu)
+{
+ return fls64(hybrid(pmu, fixed_cntr_mask64));
+}
+
+static inline u64 x86_pmu_get_event_config(struct perf_event *event)
+{
+ return event->attr.config & hybrid(event->pmu, config_mask);
+}
extern struct event_constraint emptyconstraint;
@@ -1329,6 +1384,19 @@ void amd_pmu_lbr_enable_all(void);
void amd_pmu_lbr_disable_all(void);
int amd_pmu_lbr_hw_config(struct perf_event *event);
+static __always_inline void __amd_pmu_lbr_disable(void)
+{
+ u64 dbg_ctl, dbg_extn_cfg;
+
+ rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg);
+ wrmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg & ~DBG_EXTN_CFG_LBRV2EN);
+
+ if (cpu_feature_enabled(X86_FEATURE_AMD_LBR_PMC_FREEZE)) {
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl);
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl & ~DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+ }
+}
+
#ifdef CONFIG_PERF_EVENTS_AMD_BRS
#define AMD_FAM19H_BRS_EVENT 0xc4 /* RETIRED_TAKEN_BRANCH_INSTRUCTIONS */
@@ -1504,9 +1572,11 @@ void intel_pmu_disable_bts(void);
int intel_pmu_drain_bts_buffer(void);
-u64 adl_latency_data_small(struct perf_event *event, u64 status);
+u64 grt_latency_data(struct perf_event *event, u64 status);
+
+u64 cmt_latency_data(struct perf_event *event, u64 status);
-u64 mtl_latency_data_small(struct perf_event *event, u64 status);
+u64 lnl_latency_data(struct perf_event *event, u64 status);
extern struct event_constraint intel_core2_pebs_event_constraints[];
@@ -1538,6 +1608,8 @@ extern struct event_constraint intel_icl_pebs_event_constraints[];
extern struct event_constraint intel_glc_pebs_event_constraints[];
+extern struct event_constraint intel_lnc_pebs_event_constraints[];
+
struct event_constraint *intel_pebs_constraints(struct perf_event *event);
void intel_pmu_pebs_add(struct perf_event *event);
@@ -1627,6 +1699,8 @@ void intel_pmu_pebs_data_source_mtl(void);
void intel_pmu_pebs_data_source_cmt(void);
+void intel_pmu_pebs_data_source_lnl(void);
+
int intel_pmu_setup_lbr_filter(struct perf_event *event);
void intel_pt_interrupt(void);
@@ -1648,6 +1722,17 @@ static inline int is_ht_workaround_enabled(void)
return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
}
+static inline u64 intel_pmu_pebs_mask(u64 cntr_mask)
+{
+ return MAX_PEBS_EVENTS_MASK & cntr_mask;
+}
+
+static inline int intel_pmu_max_num_pebs(struct pmu *pmu)
+{
+ static_assert(MAX_PEBS_EVENTS == 32);
+ return fls((u32)hybrid(pmu, pebs_events_mask));
+}
+
#else /* CONFIG_CPU_SUP_INTEL */
static inline void reserve_ds_buffers(void)
diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c
index fb2b1961e5a3..b985ca79cf97 100644
--- a/arch/x86/events/rapl.c
+++ b/arch/x86/events/rapl.c
@@ -64,6 +64,7 @@
#include "perf_event.h"
#include "probe.h"
+MODULE_DESCRIPTION("Support Intel/AMD RAPL energy consumption counters");
MODULE_LICENSE("GPL");
/*
@@ -114,8 +115,8 @@ struct rapl_pmu {
struct rapl_pmus {
struct pmu pmu;
- unsigned int maxdie;
- struct rapl_pmu *pmus[] __counted_by(maxdie);
+ unsigned int nr_rapl_pmu;
+ struct rapl_pmu *pmus[] __counted_by(nr_rapl_pmu);
};
enum rapl_unit_quirk {
@@ -141,13 +142,13 @@ static struct perf_msr *rapl_msrs;
static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
{
- unsigned int dieid = topology_logical_die_id(cpu);
+ unsigned int rapl_pmu_idx = topology_logical_die_id(cpu);
/*
* The unsigned check also catches the '-1' return value for non
* existent mappings in the topology map.
*/
- return dieid < rapl_pmus->maxdie ? rapl_pmus->pmus[dieid] : NULL;
+ return rapl_pmu_idx < rapl_pmus->nr_rapl_pmu ? rapl_pmus->pmus[rapl_pmu_idx] : NULL;
}
static inline u64 rapl_read_counter(struct perf_event *event)
@@ -658,7 +659,7 @@ static void cleanup_rapl_pmus(void)
{
int i;
- for (i = 0; i < rapl_pmus->maxdie; i++)
+ for (i = 0; i < rapl_pmus->nr_rapl_pmu; i++)
kfree(rapl_pmus->pmus[i]);
kfree(rapl_pmus);
}
@@ -674,15 +675,13 @@ static const struct attribute_group *rapl_attr_update[] = {
static int __init init_rapl_pmus(void)
{
- int maxdie = topology_max_packages() * topology_max_dies_per_package();
- size_t size;
+ int nr_rapl_pmu = topology_max_packages() * topology_max_dies_per_package();
- size = sizeof(*rapl_pmus) + maxdie * sizeof(struct rapl_pmu *);
- rapl_pmus = kzalloc(size, GFP_KERNEL);
+ rapl_pmus = kzalloc(struct_size(rapl_pmus, pmus, nr_rapl_pmu), GFP_KERNEL);
if (!rapl_pmus)
return -ENOMEM;
- rapl_pmus->maxdie = maxdie;
+ rapl_pmus->nr_rapl_pmu = nr_rapl_pmu;
rapl_pmus->pmu.attr_groups = rapl_attr_groups;
rapl_pmus->pmu.attr_update = rapl_attr_update;
rapl_pmus->pmu.task_ctx_nr = perf_invalid_context;
@@ -766,48 +765,51 @@ static struct rapl_model model_amd_hygon = {
};
static const struct x86_cpu_id rapl_model_match[] __initconst = {
- X86_MATCH_FEATURE(X86_FEATURE_RAPL, &model_amd_hygon),
- X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &model_snb),
- X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &model_snbep),
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &model_snb),
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &model_snbep),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &model_hsx),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &model_hsx),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &model_hsx),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &model_knl),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &model_knl),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &model_hsx),
- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &model_hsw),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &model_hsx),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &model_hsx),
- X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &model_spr),
- X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &model_spr),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, &model_skl),
- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &model_skl),
+ X86_MATCH_FEATURE(X86_FEATURE_RAPL, &model_amd_hygon),
+ X86_MATCH_VFM(INTEL_SANDYBRIDGE, &model_snb),
+ X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &model_snbep),
+ X86_MATCH_VFM(INTEL_IVYBRIDGE, &model_snb),
+ X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &model_snbep),
+ X86_MATCH_VFM(INTEL_HASWELL, &model_hsw),
+ X86_MATCH_VFM(INTEL_HASWELL_X, &model_hsx),
+ X86_MATCH_VFM(INTEL_HASWELL_L, &model_hsw),
+ X86_MATCH_VFM(INTEL_HASWELL_G, &model_hsw),
+ X86_MATCH_VFM(INTEL_BROADWELL, &model_hsw),
+ X86_MATCH_VFM(INTEL_BROADWELL_G, &model_hsw),
+ X86_MATCH_VFM(INTEL_BROADWELL_X, &model_hsx),
+ X86_MATCH_VFM(INTEL_BROADWELL_D, &model_hsx),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &model_knl),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &model_knl),
+ X86_MATCH_VFM(INTEL_SKYLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_SKYLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_SKYLAKE_X, &model_hsx),
+ X86_MATCH_VFM(INTEL_KABYLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_KABYLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_CANNONLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &model_hsw),
+ X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &model_hsw),
+ X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &model_hsw),
+ X86_MATCH_VFM(INTEL_ICELAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_ICELAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, &model_hsx),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, &model_hsx),
+ X86_MATCH_VFM(INTEL_COMETLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_COMETLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_TIGERLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_TIGERLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_ALDERLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_ALDERLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &model_skl),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &model_spr),
+ X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &model_spr),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &model_skl),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &model_skl),
+ X86_MATCH_VFM(INTEL_METEORLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_METEORLAKE_L, &model_skl),
+ X86_MATCH_VFM(INTEL_ARROWLAKE_H, &model_skl),
+ X86_MATCH_VFM(INTEL_ARROWLAKE, &model_skl),
+ X86_MATCH_VFM(INTEL_LUNARLAKE_M, &model_skl),
{},
};
MODULE_DEVICE_TABLE(x86cpu, rapl_model_match);
diff --git a/arch/x86/events/zhaoxin/core.c b/arch/x86/events/zhaoxin/core.c
index 3e9acdaeed1e..2fd9b0cf9a5e 100644
--- a/arch/x86/events/zhaoxin/core.c
+++ b/arch/x86/events/zhaoxin/core.c
@@ -530,13 +530,13 @@ __init int zhaoxin_pmu_init(void)
pr_info("Version check pass!\n");
x86_pmu.version = version;
- x86_pmu.num_counters = eax.split.num_counters;
+ x86_pmu.cntr_mask64 = GENMASK_ULL(eax.split.num_counters - 1, 0);
x86_pmu.cntval_bits = eax.split.bit_width;
x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1;
x86_pmu.events_maskl = ebx.full;
x86_pmu.events_mask_len = eax.split.mask_length;
- x86_pmu.num_counters_fixed = edx.split.num_counters_fixed;
+ x86_pmu.fixed_cntr_mask64 = GENMASK_ULL(edx.split.num_counters_fixed - 1, 0);
x86_add_quirk(zhaoxin_arch_events_quirk);
switch (boot_cpu_data.x86) {
@@ -604,13 +604,13 @@ __init int zhaoxin_pmu_init(void)
return -ENODEV;
}
- x86_pmu.intel_ctrl = (1 << (x86_pmu.num_counters)) - 1;
- x86_pmu.intel_ctrl |= ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
+ x86_pmu.intel_ctrl = x86_pmu.cntr_mask64;
+ x86_pmu.intel_ctrl |= x86_pmu.fixed_cntr_mask64 << INTEL_PMC_IDX_FIXED;
if (x86_pmu.event_constraints) {
for_each_event_constraint(c, x86_pmu.event_constraints) {
- c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
- c->weight += x86_pmu.num_counters;
+ c->idxmsk64 |= x86_pmu.cntr_mask64;
+ c->weight += x86_pmu_num_counters(NULL);
}
}
diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
index 5c7de79423b8..04775346369c 100644
--- a/arch/x86/hyperv/hv_vtl.c
+++ b/arch/x86/hyperv/hv_vtl.c
@@ -34,7 +34,6 @@ void __init hv_vtl_init_platform(void)
/* Avoid searching for BIOS MP tables */
x86_init.mpparse.find_mptable = x86_init_noop;
x86_init.mpparse.early_parse_smp_cfg = x86_init_noop;
- x86_init.mpparse.parse_smp_cfg = x86_init_noop;
x86_platform.get_wallclock = get_rtc_noop;
x86_platform.set_wallclock = set_rtc_noop;
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 768d73de0d09..b4a851d27c7c 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -523,9 +523,9 @@ static int hv_mark_gpa_visibility(u16 count, const u64 pfn[],
* transition is complete, hv_vtom_set_host_visibility() marks the pages
* as "present" again.
*/
-static bool hv_vtom_clear_present(unsigned long kbuffer, int pagecount, bool enc)
+static int hv_vtom_clear_present(unsigned long kbuffer, int pagecount, bool enc)
{
- return !set_memory_np(kbuffer, pagecount);
+ return set_memory_np(kbuffer, pagecount);
}
/*
@@ -536,20 +536,19 @@ static bool hv_vtom_clear_present(unsigned long kbuffer, int pagecount, bool enc
* with host. This function works as wrap of hv_mark_gpa_visibility()
* with memory base and size.
*/
-static bool hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bool enc)
+static int hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bool enc)
{
enum hv_mem_host_visibility visibility = enc ?
VMBUS_PAGE_NOT_VISIBLE : VMBUS_PAGE_VISIBLE_READ_WRITE;
u64 *pfn_array;
phys_addr_t paddr;
+ int i, pfn, err;
void *vaddr;
int ret = 0;
- bool result = true;
- int i, pfn;
pfn_array = kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
if (!pfn_array) {
- result = false;
+ ret = -ENOMEM;
goto err_set_memory_p;
}
@@ -568,10 +567,8 @@ static bool hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bo
if (pfn == HV_MAX_MODIFY_GPA_REP_COUNT || i == pagecount - 1) {
ret = hv_mark_gpa_visibility(pfn, pfn_array,
visibility);
- if (ret) {
- result = false;
+ if (ret)
goto err_free_pfn_array;
- }
pfn = 0;
}
}
@@ -586,10 +583,11 @@ err_set_memory_p:
* order to avoid leaving the memory range in a "broken" state. Setting
* the PRESENT bits shouldn't fail, but return an error if it does.
*/
- if (set_memory_p(kbuffer, pagecount))
- result = false;
+ err = set_memory_p(kbuffer, pagecount);
+ if (err && !ret)
+ ret = err;
- return result;
+ return ret;
}
static bool hv_vtom_tlb_flush_required(bool private)
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index f896eed4516c..21bc53f5ed0c 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -56,6 +56,8 @@ static inline void disable_acpi(void)
extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
+extern int acpi_blacklisted(void);
+
static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
static inline void acpi_disable_pci(void)
{
@@ -76,6 +78,13 @@ static inline bool acpi_skip_set_wakeup_address(void)
#define acpi_skip_set_wakeup_address acpi_skip_set_wakeup_address
+union acpi_subtable_headers;
+
+int __init acpi_parse_mp_wake(union acpi_subtable_headers *header,
+ const unsigned long end);
+
+void asm_acpi_mp_play_dead(u64 reset_vector, u64 pgd_pa);
+
/*
* Check if the CPU can handle C2 and deeper
*/
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 67b68d0d17d1..ca9ae606aab9 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -156,102 +156,50 @@ static inline int alternatives_text_reserved(void *start, void *end)
#define ALT_CALL_INSTR "call BUG_func"
-#define b_replacement(num) "664"#num
-#define e_replacement(num) "665"#num
+#define alt_slen "772b-771b"
+#define alt_total_slen "773b-771b"
+#define alt_rlen "775f-774f"
-#define alt_end_marker "663"
-#define alt_slen "662b-661b"
-#define alt_total_slen alt_end_marker"b-661b"
-#define alt_rlen(num) e_replacement(num)"f-"b_replacement(num)"f"
-
-#define OLDINSTR(oldinstr, num) \
- "# ALT: oldnstr\n" \
- "661:\n\t" oldinstr "\n662:\n" \
+#define OLDINSTR(oldinstr) \
+ "# ALT: oldinstr\n" \
+ "771:\n\t" oldinstr "\n772:\n" \
"# ALT: padding\n" \
- ".skip -(((" alt_rlen(num) ")-(" alt_slen ")) > 0) * " \
- "((" alt_rlen(num) ")-(" alt_slen ")),0x90\n" \
- alt_end_marker ":\n"
-
-/*
- * gas compatible max based on the idea from:
- * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
- *
- * The additional "-" is needed because gas uses a "true" value of -1.
- */
-#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))"
-
-/*
- * Pad the second replacement alternative with additional NOPs if it is
- * additionally longer than the first replacement alternative.
- */
-#define OLDINSTR_2(oldinstr, num1, num2) \
- "# ALT: oldinstr2\n" \
- "661:\n\t" oldinstr "\n662:\n" \
- "# ALT: padding2\n" \
- ".skip -((" alt_max_short(alt_rlen(num1), alt_rlen(num2)) " - (" alt_slen ")) > 0) * " \
- "(" alt_max_short(alt_rlen(num1), alt_rlen(num2)) " - (" alt_slen ")), 0x90\n" \
- alt_end_marker ":\n"
-
-#define OLDINSTR_3(oldinsn, n1, n2, n3) \
- "# ALT: oldinstr3\n" \
- "661:\n\t" oldinsn "\n662:\n" \
- "# ALT: padding3\n" \
- ".skip -((" alt_max_short(alt_max_short(alt_rlen(n1), alt_rlen(n2)), alt_rlen(n3)) \
- " - (" alt_slen ")) > 0) * " \
- "(" alt_max_short(alt_max_short(alt_rlen(n1), alt_rlen(n2)), alt_rlen(n3)) \
- " - (" alt_slen ")), 0x90\n" \
- alt_end_marker ":\n"
-
-#define ALTINSTR_ENTRY(ft_flags, num) \
- " .long 661b - .\n" /* label */ \
- " .long " b_replacement(num)"f - .\n" /* new instruction */ \
+ ".skip -(((" alt_rlen ")-(" alt_slen ")) > 0) * " \
+ "((" alt_rlen ")-(" alt_slen ")),0x90\n" \
+ "773:\n"
+
+#define ALTINSTR_ENTRY(ft_flags) \
+ ".pushsection .altinstructions,\"a\"\n" \
+ " .long 771b - .\n" /* label */ \
+ " .long 774f - .\n" /* new instruction */ \
" .4byte " __stringify(ft_flags) "\n" /* feature + flags */ \
" .byte " alt_total_slen "\n" /* source len */ \
- " .byte " alt_rlen(num) "\n" /* replacement len */
+ " .byte " alt_rlen "\n" /* replacement len */ \
+ ".popsection\n"
-#define ALTINSTR_REPLACEMENT(newinstr, num) /* replacement */ \
- "# ALT: replacement " #num "\n" \
- b_replacement(num)":\n\t" newinstr "\n" e_replacement(num) ":\n"
+#define ALTINSTR_REPLACEMENT(newinstr) /* replacement */ \
+ ".pushsection .altinstr_replacement, \"ax\"\n" \
+ "# ALT: replacement\n" \
+ "774:\n\t" newinstr "\n775:\n" \
+ ".popsection\n"
/* alternative assembly primitive: */
#define ALTERNATIVE(oldinstr, newinstr, ft_flags) \
- OLDINSTR(oldinstr, 1) \
- ".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(ft_flags, 1) \
- ".popsection\n" \
- ".pushsection .altinstr_replacement, \"ax\"\n" \
- ALTINSTR_REPLACEMENT(newinstr, 1) \
- ".popsection\n"
+ OLDINSTR(oldinstr) \
+ ALTINSTR_ENTRY(ft_flags) \
+ ALTINSTR_REPLACEMENT(newinstr)
#define ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2) \
- OLDINSTR_2(oldinstr, 1, 2) \
- ".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(ft_flags1, 1) \
- ALTINSTR_ENTRY(ft_flags2, 2) \
- ".popsection\n" \
- ".pushsection .altinstr_replacement, \"ax\"\n" \
- ALTINSTR_REPLACEMENT(newinstr1, 1) \
- ALTINSTR_REPLACEMENT(newinstr2, 2) \
- ".popsection\n"
+ ALTERNATIVE(ALTERNATIVE(oldinstr, newinstr1, ft_flags1), newinstr2, ft_flags2)
/* If @feature is set, patch in @newinstr_yes, otherwise @newinstr_no. */
#define ALTERNATIVE_TERNARY(oldinstr, ft_flags, newinstr_yes, newinstr_no) \
- ALTERNATIVE_2(oldinstr, newinstr_no, X86_FEATURE_ALWAYS, \
- newinstr_yes, ft_flags)
-
-#define ALTERNATIVE_3(oldinsn, newinsn1, ft_flags1, newinsn2, ft_flags2, \
- newinsn3, ft_flags3) \
- OLDINSTR_3(oldinsn, 1, 2, 3) \
- ".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(ft_flags1, 1) \
- ALTINSTR_ENTRY(ft_flags2, 2) \
- ALTINSTR_ENTRY(ft_flags3, 3) \
- ".popsection\n" \
- ".pushsection .altinstr_replacement, \"ax\"\n" \
- ALTINSTR_REPLACEMENT(newinsn1, 1) \
- ALTINSTR_REPLACEMENT(newinsn2, 2) \
- ALTINSTR_REPLACEMENT(newinsn3, 3) \
- ".popsection\n"
+ ALTERNATIVE_2(oldinstr, newinstr_no, X86_FEATURE_ALWAYS, newinstr_yes, ft_flags)
+
+#define ALTERNATIVE_3(oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2, \
+ newinstr3, ft_flags3) \
+ ALTERNATIVE(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2), \
+ newinstr3, ft_flags3)
/*
* Alternative instructions for different CPU types or capabilities.
@@ -266,14 +214,11 @@ static inline int alternatives_text_reserved(void *start, void *end)
* without volatile and memory clobber.
*/
#define alternative(oldinstr, newinstr, ft_flags) \
- asm_inline volatile (ALTERNATIVE(oldinstr, newinstr, ft_flags) : : : "memory")
+ asm_inline volatile(ALTERNATIVE(oldinstr, newinstr, ft_flags) : : : "memory")
#define alternative_2(oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2) \
asm_inline volatile(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2) ::: "memory")
-#define alternative_ternary(oldinstr, ft_flags, newinstr_yes, newinstr_no) \
- asm_inline volatile(ALTERNATIVE_TERNARY(oldinstr, ft_flags, newinstr_yes, newinstr_no) ::: "memory")
-
/*
* Alternative inline assembly with input.
*
@@ -283,32 +228,28 @@ static inline int alternatives_text_reserved(void *start, void *end)
* Leaving an unused argument 0 to keep API compatibility.
*/
#define alternative_input(oldinstr, newinstr, ft_flags, input...) \
- asm_inline volatile (ALTERNATIVE(oldinstr, newinstr, ft_flags) \
- : : "i" (0), ## input)
-
-/*
- * This is similar to alternative_input. But it has two features and
- * respective instructions.
- *
- * If CPU has feature2, newinstr2 is used.
- * Otherwise, if CPU has feature1, newinstr1 is used.
- * Otherwise, oldinstr is used.
- */
-#define alternative_input_2(oldinstr, newinstr1, ft_flags1, newinstr2, \
- ft_flags2, input...) \
- asm_inline volatile(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, \
- newinstr2, ft_flags2) \
+ asm_inline volatile(ALTERNATIVE(oldinstr, newinstr, ft_flags) \
: : "i" (0), ## input)
/* Like alternative_input, but with a single output argument */
#define alternative_io(oldinstr, newinstr, ft_flags, output, input...) \
- asm_inline volatile (ALTERNATIVE(oldinstr, newinstr, ft_flags) \
+ asm_inline volatile(ALTERNATIVE(oldinstr, newinstr, ft_flags) \
: output : "i" (0), ## input)
-/* Like alternative_io, but for replacing a direct call with another one. */
-#define alternative_call(oldfunc, newfunc, ft_flags, output, input...) \
- asm_inline volatile (ALTERNATIVE("call %P[old]", "call %P[new]", ft_flags) \
- : output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input)
+/*
+ * Like alternative_io, but for replacing a direct call with another one.
+ *
+ * Use the %c operand modifier which is the generic way to print a bare
+ * constant expression with all syntax-specific punctuation omitted. %P
+ * is the x86-specific variant which can handle constants too, for
+ * historical reasons, but it should be used primarily for PIC
+ * references: i.e., if used for a function, it would add the PLT
+ * suffix.
+ */
+#define alternative_call(oldfunc, newfunc, ft_flags, output, input...) \
+ asm_inline volatile(ALTERNATIVE("call %c[old]", "call %c[new]", ft_flags) \
+ : ALT_OUTPUT_SP(output) \
+ : [old] "i" (oldfunc), [new] "i" (newfunc), ## input)
/*
* Like alternative_call, but there are two features and respective functions.
@@ -316,12 +257,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
* Otherwise, if CPU has feature1, function1 is used.
* Otherwise, old function is used.
*/
-#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2, \
- output, input...) \
- asm_inline volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", ft_flags1,\
- "call %P[new2]", ft_flags2) \
- : output, ASM_CALL_CONSTRAINT \
- : [old] "i" (oldfunc), [new1] "i" (newfunc1), \
+#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2, \
+ output, input...) \
+ asm_inline volatile(ALTERNATIVE_2("call %c[old]", "call %c[new1]", ft_flags1, \
+ "call %c[new2]", ft_flags2) \
+ : ALT_OUTPUT_SP(output) \
+ : [old] "i" (oldfunc), [new1] "i" (newfunc1), \
[new2] "i" (newfunc2), ## input)
/*
@@ -336,6 +277,8 @@ static inline int alternatives_text_reserved(void *start, void *end)
*/
#define ASM_NO_INPUT_CLOBBER(clbr...) "i" (0) : clbr
+#define ALT_OUTPUT_SP(...) ASM_CALL_CONSTRAINT, ## __VA_ARGS__
+
/* Macro for creating assembler functions avoiding any C magic. */
#define DEFINE_ASM_FUNC(func, instr, sec) \
asm (".pushsection " #sec ", \"ax\"\n" \
@@ -402,22 +345,23 @@ void nop_func(void);
* @newinstr. ".skip" directive takes care of proper instruction padding
* in case @newinstr is longer than @oldinstr.
*/
-.macro ALTERNATIVE oldinstr, newinstr, ft_flags
-140:
- \oldinstr
-141:
- .skip -(((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)),0x90
-142:
-
- .pushsection .altinstructions,"a"
- altinstr_entry 140b,143f,\ft_flags,142b-140b,144f-143f
- .popsection
+#define __ALTERNATIVE(oldinst, newinst, flag) \
+740: \
+ oldinst ; \
+741: \
+ .skip -(((744f-743f)-(741b-740b)) > 0) * ((744f-743f)-(741b-740b)),0x90 ;\
+742: \
+ .pushsection .altinstructions,"a" ; \
+ altinstr_entry 740b,743f,flag,742b-740b,744f-743f ; \
+ .popsection ; \
+ .pushsection .altinstr_replacement,"ax" ; \
+743: \
+ newinst ; \
+744: \
+ .popsection ;
- .pushsection .altinstr_replacement,"ax"
-143:
- \newinstr
-144:
- .popsection
+.macro ALTERNATIVE oldinstr, newinstr, ft_flags
+ __ALTERNATIVE(\oldinstr, \newinstr, \ft_flags)
.endm
#define old_len 141b-140b
@@ -426,65 +370,18 @@ void nop_func(void);
#define new_len3 146f-145f
/*
- * gas compatible max based on the idea from:
- * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
- *
- * The additional "-" is needed because gas uses a "true" value of -1.
- */
-#define alt_max_2(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
-#define alt_max_3(a, b, c) (alt_max_2(alt_max_2(a, b), c))
-
-
-/*
* Same as ALTERNATIVE macro above but for two alternatives. If CPU
* has @feature1, it replaces @oldinstr with @newinstr1. If CPU has
* @feature2, it replaces @oldinstr with @feature2.
*/
.macro ALTERNATIVE_2 oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2
-140:
- \oldinstr
-141:
- .skip -((alt_max_2(new_len1, new_len2) - (old_len)) > 0) * \
- (alt_max_2(new_len1, new_len2) - (old_len)),0x90
-142:
-
- .pushsection .altinstructions,"a"
- altinstr_entry 140b,143f,\ft_flags1,142b-140b,144f-143f
- altinstr_entry 140b,144f,\ft_flags2,142b-140b,145f-144f
- .popsection
-
- .pushsection .altinstr_replacement,"ax"
-143:
- \newinstr1
-144:
- \newinstr2
-145:
- .popsection
+ __ALTERNATIVE(__ALTERNATIVE(\oldinstr, \newinstr1, \ft_flags1),
+ \newinstr2, \ft_flags2)
.endm
.macro ALTERNATIVE_3 oldinstr, newinstr1, ft_flags1, newinstr2, ft_flags2, newinstr3, ft_flags3
-140:
- \oldinstr
-141:
- .skip -((alt_max_3(new_len1, new_len2, new_len3) - (old_len)) > 0) * \
- (alt_max_3(new_len1, new_len2, new_len3) - (old_len)),0x90
-142:
-
- .pushsection .altinstructions,"a"
- altinstr_entry 140b,143f,\ft_flags1,142b-140b,144f-143f
- altinstr_entry 140b,144f,\ft_flags2,142b-140b,145f-144f
- altinstr_entry 140b,145f,\ft_flags3,142b-140b,146f-145f
- .popsection
-
- .pushsection .altinstr_replacement,"ax"
-143:
- \newinstr1
-144:
- \newinstr2
-145:
- \newinstr3
-146:
- .popsection
+ __ALTERNATIVE(ALTERNATIVE_2(\oldinstr, \newinstr1, \ft_flags1, \newinstr2, \ft_flags2),
+ \newinstr3, \ft_flags3)
.endm
/* If @feature is set, patch in @newinstr_yes, otherwise @newinstr_no. */
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index 5c37944c8a5e..6f3b6aef47ba 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -21,8 +21,8 @@ extern int amd_numa_init(void);
extern int amd_get_subcaches(int);
extern int amd_set_subcaches(int, unsigned long);
-extern int amd_smn_read(u16 node, u32 address, u32 *value);
-extern int amd_smn_write(u16 node, u32 address, u32 value);
+int __must_check amd_smn_read(u16 node, u32 address, u32 *value);
+int __must_check amd_smn_write(u16 node, u32 address, u32 value);
struct amd_l3_cache {
unsigned indices;
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index e6ab0cf15ed5..9327eb00e96d 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -14,6 +14,7 @@
#include <asm/msr.h>
#include <asm/hardirq.h>
#include <asm/io.h>
+#include <asm/posted_intr.h>
#define ARCH_APICTIMER_STOPS_ON_C3 1
@@ -92,7 +93,7 @@ static inline void native_apic_mem_write(u32 reg, u32 v)
{
volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
- alternative_io("movl %0, %P1", "xchgl %0, %P1", X86_BUG_11AP,
+ alternative_io("movl %0, %1", "xchgl %0, %1", X86_BUG_11AP,
ASM_OUTPUT2("=r" (v), "=m" (*addr)),
ASM_OUTPUT2("0" (v), "m" (*addr)));
}
@@ -500,6 +501,11 @@ static inline bool lapic_vector_set_in_irr(unsigned int vector)
return !!(irr & (1U << (vector % 32)));
}
+static inline bool is_vector_pending(unsigned int vector)
+{
+ return lapic_vector_set_in_irr(vector) || pi_pending_this_cpu(vector);
+}
+
/*
* Warm reset vector position:
*/
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index ca8eed1d496a..2bec0c89a95c 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -229,9 +229,6 @@ register unsigned long current_stack_pointer asm(_ASM_SP);
#define _ASM_EXTABLE_UA(from, to) \
_ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS)
-#define _ASM_EXTABLE_CPY(from, to) \
- _ASM_EXTABLE_TYPE(from, to, EX_TYPE_COPY)
-
#define _ASM_EXTABLE_FAULT(from, to) \
_ASM_EXTABLE_TYPE(from, to, EX_TYPE_FAULT)
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index 55a55ec04350..55b4d24356ea 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -86,11 +86,7 @@ static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
}
#define arch_atomic_add_return arch_atomic_add_return
-static __always_inline int arch_atomic_sub_return(int i, atomic_t *v)
-{
- return arch_atomic_add_return(-i, v);
-}
-#define arch_atomic_sub_return arch_atomic_sub_return
+#define arch_atomic_sub_return(i, v) arch_atomic_add_return(-(i), v)
static __always_inline int arch_atomic_fetch_add(int i, atomic_t *v)
{
@@ -98,11 +94,7 @@ static __always_inline int arch_atomic_fetch_add(int i, atomic_t *v)
}
#define arch_atomic_fetch_add arch_atomic_fetch_add
-static __always_inline int arch_atomic_fetch_sub(int i, atomic_t *v)
-{
- return xadd(&v->counter, -i);
-}
-#define arch_atomic_fetch_sub arch_atomic_fetch_sub
+#define arch_atomic_fetch_sub(i, v) arch_atomic_fetch_add(-(i), v)
static __always_inline int arch_atomic_cmpxchg(atomic_t *v, int old, int new)
{
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index 3486d91b8595..8db2ec4d6cda 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -14,6 +14,32 @@ typedef struct {
#define ATOMIC64_INIT(val) { (val) }
+/*
+ * Read an atomic64_t non-atomically.
+ *
+ * This is intended to be used in cases where a subsequent atomic operation
+ * will handle the torn value, and can be used to prime the first iteration
+ * of unconditional try_cmpxchg() loops, e.g.:
+ *
+ * s64 val = arch_atomic64_read_nonatomic(v);
+ * do { } while (!arch_atomic64_try_cmpxchg(v, &val, val OP i);
+ *
+ * This is NOT safe to use where the value is not always checked by a
+ * subsequent atomic operation, such as in conditional try_cmpxchg() loops
+ * that can break before the atomic operation, e.g.:
+ *
+ * s64 val = arch_atomic64_read_nonatomic(v);
+ * do {
+ * if (condition(val))
+ * break;
+ * } while (!arch_atomic64_try_cmpxchg(v, &val, val OP i);
+ */
+static __always_inline s64 arch_atomic64_read_nonatomic(const atomic64_t *v)
+{
+ /* See comment in arch_atomic_read(). */
+ return __READ_ONCE(v->counter);
+}
+
#define __ATOMIC64_DECL(sym) void atomic64_##sym(atomic64_t *, ...)
#ifndef ATOMIC64_EXPORT
#define ATOMIC64_DECL_ONE __ATOMIC64_DECL
@@ -24,7 +50,7 @@ typedef struct {
#ifdef CONFIG_X86_CMPXCHG64
#define __alternative_atomic64(f, g, out, in...) \
- asm volatile("call %P[func]" \
+ asm volatile("call %c[func]" \
: out : [func] "i" (atomic64_##g##_cx8), ## in)
#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8)
@@ -61,12 +87,18 @@ ATOMIC64_DECL(add_unless);
#undef __ATOMIC64_DECL
#undef ATOMIC64_EXPORT
-static __always_inline s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 o, s64 n)
+static __always_inline s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
{
- return arch_cmpxchg64(&v->counter, o, n);
+ return arch_cmpxchg64(&v->counter, old, new);
}
#define arch_atomic64_cmpxchg arch_atomic64_cmpxchg
+static __always_inline bool arch_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
+{
+ return arch_try_cmpxchg64(&v->counter, old, new);
+}
+#define arch_atomic64_try_cmpxchg arch_atomic64_try_cmpxchg
+
static __always_inline s64 arch_atomic64_xchg(atomic64_t *v, s64 n)
{
s64 o;
@@ -195,69 +227,62 @@ static __always_inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
static __always_inline void arch_atomic64_and(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c & i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val & i));
}
static __always_inline s64 arch_atomic64_fetch_and(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c & i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val & i));
- return old;
+ return val;
}
#define arch_atomic64_fetch_and arch_atomic64_fetch_and
static __always_inline void arch_atomic64_or(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c | i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val | i));
}
static __always_inline s64 arch_atomic64_fetch_or(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c | i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val | i));
- return old;
+ return val;
}
#define arch_atomic64_fetch_or arch_atomic64_fetch_or
static __always_inline void arch_atomic64_xor(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c ^ i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val ^ i));
}
static __always_inline s64 arch_atomic64_fetch_xor(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c ^ i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val ^ i));
- return old;
+ return val;
}
#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor
static __always_inline s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v)
{
- s64 old, c = 0;
+ s64 val = arch_atomic64_read_nonatomic(v);
- while ((old = arch_atomic64_cmpxchg(v, c, c + i)) != c)
- c = old;
+ do { } while (!arch_atomic64_try_cmpxchg(v, &val, val + i));
- return old;
+ return val;
}
#define arch_atomic64_fetch_add arch_atomic64_fetch_add
diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h
index 3165c0feedf7..ae12acae5b06 100644
--- a/arch/x86/include/asm/atomic64_64.h
+++ b/arch/x86/include/asm/atomic64_64.h
@@ -80,11 +80,7 @@ static __always_inline s64 arch_atomic64_add_return(s64 i, atomic64_t *v)
}
#define arch_atomic64_add_return arch_atomic64_add_return
-static __always_inline s64 arch_atomic64_sub_return(s64 i, atomic64_t *v)
-{
- return arch_atomic64_add_return(-i, v);
-}
-#define arch_atomic64_sub_return arch_atomic64_sub_return
+#define arch_atomic64_sub_return(i, v) arch_atomic64_add_return(-(i), v)
static __always_inline s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v)
{
@@ -92,11 +88,7 @@ static __always_inline s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v)
}
#define arch_atomic64_fetch_add arch_atomic64_fetch_add
-static __always_inline s64 arch_atomic64_fetch_sub(s64 i, atomic64_t *v)
-{
- return xadd(&v->counter, -i);
-}
-#define arch_atomic64_fetch_sub arch_atomic64_fetch_sub
+#define arch_atomic64_fetch_sub(i, v) arch_atomic64_fetch_add(-(i), v)
static __always_inline s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
{
diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
index 63bdc6b85219..7b44b3c4cce1 100644
--- a/arch/x86/include/asm/barrier.h
+++ b/arch/x86/include/asm/barrier.h
@@ -33,20 +33,16 @@
* Returns:
* 0 - (index < size)
*/
-static __always_inline unsigned long array_index_mask_nospec(unsigned long index,
- unsigned long size)
-{
- unsigned long mask;
-
- asm volatile ("cmp %1,%2; sbb %0,%0;"
- :"=r" (mask)
- :"g"(size),"r" (index)
- :"cc");
- return mask;
-}
-
-/* Override the default implementation from linux/nospec.h. */
-#define array_index_mask_nospec array_index_mask_nospec
+#define array_index_mask_nospec(idx,sz) ({ \
+ typeof((idx)+(sz)) __idx = (idx); \
+ typeof(__idx) __sz = (sz); \
+ unsigned long __mask; \
+ asm volatile ("cmp %1,%2; sbb %0,%0" \
+ :"=r" (__mask) \
+ :ASM_INPUT_G (__sz), \
+ "r" (__idx) \
+ :"cc"); \
+ __mask; })
/* Prevent speculative execution past this barrier. */
#define barrier_nospec() alternative("", "lfence", X86_FEATURE_LFENCE_RDTSC)
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index 990eb686ca67..b96d45944c59 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -250,7 +250,7 @@ static __always_inline unsigned long variable__ffs(unsigned long word)
{
asm("rep; bsf %1,%0"
: "=r" (word)
- : "rm" (word));
+ : ASM_INPUT_RM (word));
return word;
}
@@ -297,7 +297,7 @@ static __always_inline unsigned long __fls(unsigned long word)
asm("bsr %1,%0"
: "=r" (word)
- : "rm" (word));
+ : ASM_INPUT_RM (word));
return word;
}
@@ -320,7 +320,7 @@ static __always_inline int variable_ffs(int x)
*/
asm("bsfl %1,%0"
: "=r" (r)
- : "rm" (x), "0" (-1));
+ : ASM_INPUT_RM (x), "0" (-1));
#elif defined(CONFIG_X86_CMOV)
asm("bsfl %1,%0\n\t"
"cmovzl %2,%0"
@@ -377,7 +377,7 @@ static __always_inline int fls(unsigned int x)
*/
asm("bsrl %1,%0"
: "=r" (r)
- : "rm" (x), "0" (-1));
+ : ASM_INPUT_RM (x), "0" (-1));
#elif defined(CONFIG_X86_CMOV)
asm("bsrl %1,%0\n\t"
"cmovzl %2,%0"
@@ -416,7 +416,7 @@ static __always_inline int fls64(__u64 x)
*/
asm("bsrq %1,%q0"
: "+r" (bitpos)
- : "rm" (x));
+ : ASM_INPUT_RM (x));
return bitpos + 1;
}
#else
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
index a3e0be0470a4..3e5b111e619d 100644
--- a/arch/x86/include/asm/boot.h
+++ b/arch/x86/include/asm/boot.h
@@ -6,11 +6,6 @@
#include <asm/pgtable_types.h>
#include <uapi/asm/boot.h>
-/* Physical address where kernel should be loaded. */
-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
- + (CONFIG_PHYSICAL_ALIGN - 1)) \
- & ~(CONFIG_PHYSICAL_ALIGN - 1))
-
/* Minimum kernel alignment, as a power of two */
#ifdef CONFIG_X86_64
# define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT
diff --git a/arch/x86/include/asm/cfi.h b/arch/x86/include/asm/cfi.h
index 7cd752557905..31d19c815f99 100644
--- a/arch/x86/include/asm/cfi.h
+++ b/arch/x86/include/asm/cfi.h
@@ -93,7 +93,7 @@
*
*/
enum cfi_mode {
- CFI_DEFAULT, /* FineIBT if hardware has IBT, otherwise kCFI */
+ CFI_AUTO, /* FineIBT if hardware has IBT, otherwise kCFI */
CFI_OFF, /* Taditional / IBT depending on .config */
CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */
CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index b5731c51f0f4..62cef2113ca7 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -3,103 +3,148 @@
#define _ASM_X86_CMPXCHG_32_H
/*
- * Note: if you use set64_bit(), __cmpxchg64(), or their variants,
+ * Note: if you use __cmpxchg64(), or their variants,
* you need to test for the feature in boot_cpu_data.
*/
-#ifdef CONFIG_X86_CMPXCHG64
-#define arch_cmpxchg64(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg64((ptr), (unsigned long long)(o), \
- (unsigned long long)(n)))
-#define arch_cmpxchg64_local(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg64_local((ptr), (unsigned long long)(o), \
- (unsigned long long)(n)))
-#define arch_try_cmpxchg64(ptr, po, n) \
- __try_cmpxchg64((ptr), (unsigned long long *)(po), \
- (unsigned long long)(n))
-#endif
+union __u64_halves {
+ u64 full;
+ struct {
+ u32 low, high;
+ };
+};
+
+#define __arch_cmpxchg64(_ptr, _old, _new, _lock) \
+({ \
+ union __u64_halves o = { .full = (_old), }, \
+ n = { .full = (_new), }; \
+ \
+ asm volatile(_lock "cmpxchg8b %[ptr]" \
+ : [ptr] "+m" (*(_ptr)), \
+ "+a" (o.low), "+d" (o.high) \
+ : "b" (n.low), "c" (n.high) \
+ : "memory"); \
+ \
+ o.full; \
+})
+
+
+static __always_inline u64 __cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
+{
+ return __arch_cmpxchg64(ptr, old, new, LOCK_PREFIX);
+}
-static inline u64 __cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
+static __always_inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
{
- u64 prev;
- asm volatile(LOCK_PREFIX "cmpxchg8b %1"
- : "=A" (prev),
- "+m" (*ptr)
- : "b" ((u32)new),
- "c" ((u32)(new >> 32)),
- "0" (old)
- : "memory");
- return prev;
+ return __arch_cmpxchg64(ptr, old, new,);
}
-static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
+#define __arch_try_cmpxchg64(_ptr, _oldp, _new, _lock) \
+({ \
+ union __u64_halves o = { .full = *(_oldp), }, \
+ n = { .full = (_new), }; \
+ bool ret; \
+ \
+ asm volatile(_lock "cmpxchg8b %[ptr]" \
+ CC_SET(e) \
+ : CC_OUT(e) (ret), \
+ [ptr] "+m" (*(_ptr)), \
+ "+a" (o.low), "+d" (o.high) \
+ : "b" (n.low), "c" (n.high) \
+ : "memory"); \
+ \
+ if (unlikely(!ret)) \
+ *(_oldp) = o.full; \
+ \
+ likely(ret); \
+})
+
+static __always_inline bool __try_cmpxchg64(volatile u64 *ptr, u64 *oldp, u64 new)
{
- u64 prev;
- asm volatile("cmpxchg8b %1"
- : "=A" (prev),
- "+m" (*ptr)
- : "b" ((u32)new),
- "c" ((u32)(new >> 32)),
- "0" (old)
- : "memory");
- return prev;
+ return __arch_try_cmpxchg64(ptr, oldp, new, LOCK_PREFIX);
}
-static inline bool __try_cmpxchg64(volatile u64 *ptr, u64 *pold, u64 new)
+static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp, u64 new)
{
- bool success;
- u64 old = *pold;
- asm volatile(LOCK_PREFIX "cmpxchg8b %[ptr]"
- CC_SET(z)
- : CC_OUT(z) (success),
- [ptr] "+m" (*ptr),
- "+A" (old)
- : "b" ((u32)new),
- "c" ((u32)(new >> 32))
- : "memory");
-
- if (unlikely(!success))
- *pold = old;
- return success;
+ return __arch_try_cmpxchg64(ptr, oldp, new,);
}
-#ifndef CONFIG_X86_CMPXCHG64
+#ifdef CONFIG_X86_CMPXCHG64
+
+#define arch_cmpxchg64 __cmpxchg64
+
+#define arch_cmpxchg64_local __cmpxchg64_local
+
+#define arch_try_cmpxchg64 __try_cmpxchg64
+
+#define arch_try_cmpxchg64_local __try_cmpxchg64_local
+
+#else
+
/*
* Building a kernel capable running on 80386 and 80486. It may be necessary
* to simulate the cmpxchg8b on the 80386 and 80486 CPU.
*/
-#define arch_cmpxchg64(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- __typeof__(*(ptr)) __old = (o); \
- __typeof__(*(ptr)) __new = (n); \
- alternative_io(LOCK_PREFIX_HERE \
- "call cmpxchg8b_emu", \
- "lock; cmpxchg8b (%%esi)" , \
- X86_FEATURE_CX8, \
- "=A" (__ret), \
- "S" ((ptr)), "0" (__old), \
- "b" ((unsigned int)__new), \
- "c" ((unsigned int)(__new>>32)) \
- : "memory"); \
- __ret; })
-
-
-#define arch_cmpxchg64_local(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- __typeof__(*(ptr)) __old = (o); \
- __typeof__(*(ptr)) __new = (n); \
- alternative_io("call cmpxchg8b_emu", \
- "cmpxchg8b (%%esi)" , \
- X86_FEATURE_CX8, \
- "=A" (__ret), \
- "S" ((ptr)), "0" (__old), \
- "b" ((unsigned int)__new), \
- "c" ((unsigned int)(__new>>32)) \
- : "memory"); \
- __ret; })
+#define __arch_cmpxchg64_emu(_ptr, _old, _new, _lock_loc, _lock) \
+({ \
+ union __u64_halves o = { .full = (_old), }, \
+ n = { .full = (_new), }; \
+ \
+ asm volatile(ALTERNATIVE(_lock_loc \
+ "call cmpxchg8b_emu", \
+ _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
+ : "+a" (o.low), "+d" (o.high) \
+ : "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \
+ : "memory"); \
+ \
+ o.full; \
+})
+
+static __always_inline u64 arch_cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
+{
+ return __arch_cmpxchg64_emu(ptr, old, new, LOCK_PREFIX_HERE, "lock; ");
+}
+#define arch_cmpxchg64 arch_cmpxchg64
+
+static __always_inline u64 arch_cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
+{
+ return __arch_cmpxchg64_emu(ptr, old, new, ,);
+}
+#define arch_cmpxchg64_local arch_cmpxchg64_local
+
+#define __arch_try_cmpxchg64_emu(_ptr, _oldp, _new, _lock_loc, _lock) \
+({ \
+ union __u64_halves o = { .full = *(_oldp), }, \
+ n = { .full = (_new), }; \
+ bool ret; \
+ \
+ asm volatile(ALTERNATIVE(_lock_loc \
+ "call cmpxchg8b_emu", \
+ _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
+ CC_SET(e) \
+ : CC_OUT(e) (ret), \
+ "+a" (o.low), "+d" (o.high) \
+ : "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \
+ : "memory"); \
+ \
+ if (unlikely(!ret)) \
+ *(_oldp) = o.full; \
+ \
+ likely(ret); \
+})
+
+static __always_inline bool arch_try_cmpxchg64(volatile u64 *ptr, u64 *oldp, u64 new)
+{
+ return __arch_try_cmpxchg64_emu(ptr, oldp, new, LOCK_PREFIX_HERE, "lock; ");
+}
+#define arch_try_cmpxchg64 arch_try_cmpxchg64
+
+static __always_inline bool arch_try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp, u64 new)
+{
+ return __arch_try_cmpxchg64_emu(ptr, oldp, new, ,);
+}
+#define arch_try_cmpxchg64_local arch_try_cmpxchg64_local
#endif
diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h
index 44b08b53ab32..5e241306db26 100644
--- a/arch/x86/include/asm/cmpxchg_64.h
+++ b/arch/x86/include/asm/cmpxchg_64.h
@@ -20,6 +20,12 @@
arch_try_cmpxchg((ptr), (po), (n)); \
})
+#define arch_try_cmpxchg64_local(ptr, po, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ arch_try_cmpxchg_local((ptr), (po), (n)); \
+})
+
union __u128_halves {
u128 full;
struct {
@@ -62,7 +68,7 @@ static __always_inline u128 arch_cmpxchg128_local(volatile u128 *ptr, u128 old,
asm volatile(_lock "cmpxchg16b %[ptr]" \
CC_SET(e) \
: CC_OUT(e) (ret), \
- [ptr] "+m" (*ptr), \
+ [ptr] "+m" (*(_ptr)), \
"+a" (o.low), "+d" (o.high) \
: "b" (n.low), "c" (n.high) \
: "memory"); \
diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h
index eb8fcede9e3b..3831f612e89c 100644
--- a/arch/x86/include/asm/cpu_device_id.h
+++ b/arch/x86/include/asm/cpu_device_id.h
@@ -3,6 +3,39 @@
#define _ASM_X86_CPU_DEVICE_ID
/*
+ * Can't use <linux/bitfield.h> because it generates expressions that
+ * cannot be used in structure initializers. Bitfield construction
+ * here must match the union in struct cpuinfo_86:
+ * union {
+ * struct {
+ * __u8 x86_model;
+ * __u8 x86;
+ * __u8 x86_vendor;
+ * __u8 x86_reserved;
+ * };
+ * __u32 x86_vfm;
+ * };
+ */
+#define VFM_MODEL_BIT 0
+#define VFM_FAMILY_BIT 8
+#define VFM_VENDOR_BIT 16
+#define VFM_RSVD_BIT 24
+
+#define VFM_MODEL_MASK GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT)
+#define VFM_FAMILY_MASK GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT)
+#define VFM_VENDOR_MASK GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT)
+
+#define VFM_MODEL(vfm) (((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT)
+#define VFM_FAMILY(vfm) (((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT)
+#define VFM_VENDOR(vfm) (((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT)
+
+#define VFM_MAKE(_vendor, _family, _model) ( \
+ ((_model) << VFM_MODEL_BIT) | \
+ ((_family) << VFM_FAMILY_BIT) | \
+ ((_vendor) << VFM_VENDOR_BIT) \
+)
+
+/*
* Declare drivers belonging to specific x86 CPUs
* Similar in spirit to pci_device_id and related PCI functions
*
@@ -20,6 +53,9 @@
#define X86_CENTAUR_FAM6_C7_D 0xd
#define X86_CENTAUR_FAM6_NANO 0xf
+/* x86_cpu_id::flags */
+#define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0)
+
#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins)
/**
* X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
@@ -46,6 +82,18 @@
.model = _model, \
.steppings = _steppings, \
.feature = _feature, \
+ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \
+ .driver_data = (unsigned long) _data \
+}
+
+#define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \
+ _steppings, _feature, _data) { \
+ .vendor = _vendor, \
+ .family = _family, \
+ .model = _model, \
+ .steppings = _steppings, \
+ .feature = _feature, \
+ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \
.driver_data = (unsigned long) _data \
}
@@ -164,6 +212,56 @@
X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
steppings, X86_FEATURE_ANY, data)
+/**
+ * X86_MATCH_VFM - Match encoded vendor/family/model
+ * @vfm: Encoded 8-bits each for vendor, family, model
+ * @data: Driver specific data or NULL. The internal storage
+ * format is unsigned long. The supplied value, pointer
+ * etc. is cast to unsigned long internally.
+ *
+ * Stepping and feature are set to wildcards
+ */
+#define X86_MATCH_VFM(vfm, data) \
+ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \
+ VFM_VENDOR(vfm), \
+ VFM_FAMILY(vfm), \
+ VFM_MODEL(vfm), \
+ X86_STEPPING_ANY, X86_FEATURE_ANY, data)
+
+/**
+ * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping
+ * @vfm: Encoded 8-bits each for vendor, family, model
+ * @steppings: Bitmask of steppings to match
+ * @data: Driver specific data or NULL. The internal storage
+ * format is unsigned long. The supplied value, pointer
+ * etc. is cast to unsigned long internally.
+ *
+ * feature is set to wildcard
+ */
+#define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data) \
+ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \
+ VFM_VENDOR(vfm), \
+ VFM_FAMILY(vfm), \
+ VFM_MODEL(vfm), \
+ steppings, X86_FEATURE_ANY, data)
+
+/**
+ * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature
+ * @vfm: Encoded 8-bits each for vendor, family, model
+ * @feature: A X86_FEATURE bit
+ * @data: Driver specific data or NULL. The internal storage
+ * format is unsigned long. The supplied value, pointer
+ * etc. is cast to unsigned long internally.
+ *
+ * Steppings is set to wildcard
+ */
+#define X86_MATCH_VFM_FEATURE(vfm, feature, data) \
+ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \
+ VFM_VENDOR(vfm), \
+ VFM_FAMILY(vfm), \
+ VFM_MODEL(vfm), \
+ X86_STEPPING_ANY, feature, data)
+
/*
* Match specific microcode revisions.
*
@@ -182,9 +280,17 @@ struct x86_cpu_desc {
u32 x86_microcode_rev;
};
-#define INTEL_CPU_DESC(model, stepping, revision) { \
- .x86_family = 6, \
- .x86_vendor = X86_VENDOR_INTEL, \
+#define INTEL_CPU_DESC(vfm, stepping, revision) { \
+ .x86_family = VFM_FAMILY(vfm), \
+ .x86_vendor = VFM_VENDOR(vfm), \
+ .x86_model = VFM_MODEL(vfm), \
+ .x86_stepping = (stepping), \
+ .x86_microcode_rev = (revision), \
+}
+
+#define AMD_CPU_DESC(fam, model, stepping, revision) { \
+ .x86_family = (fam), \
+ .x86_vendor = X86_VENDOR_AMD, \
.x86_model = (model), \
.x86_stepping = (stepping), \
.x86_microcode_rev = (revision), \
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 686e92d2663e..0b9611da6c53 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -129,8 +129,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define this_cpu_has(bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
- x86_this_cpu_test_bit(bit, \
- (unsigned long __percpu *)&cpu_info.x86_capability))
+ x86_this_cpu_test_bit(bit, cpu_info.x86_capability))
/*
* This macro is for detection of features which need kernel
@@ -150,8 +149,12 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
extern void setup_clear_cpu_cap(unsigned int bit);
extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
-#define setup_force_cpu_cap(bit) do { \
- set_cpu_cap(&boot_cpu_data, bit); \
+#define setup_force_cpu_cap(bit) do { \
+ \
+ if (!boot_cpu_has(bit)) \
+ WARN_ON(alternatives_patched); \
+ \
+ set_cpu_cap(&boot_cpu_data, bit); \
set_bit(bit, (unsigned long *)cpu_caps_set); \
} while (0)
@@ -172,11 +175,10 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
*/
static __always_inline bool _static_cpu_has(u16 bit)
{
- asm goto(
- ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]")
+ asm goto(ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]")
".pushsection .altinstr_aux,\"ax\"\n"
"6:\n"
- " testb %[bitnum]," _ASM_RIP(%P[cap_byte]) "\n"
+ " testb %[bitnum], %a[cap_byte]\n"
" jnz %l[t_yes]\n"
" jmp %l[t_no]\n"
".popsection\n"
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 3c7434329661..dd4682857c12 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -18,170 +18,170 @@
/*
* Note: If the comment begins with a quoted string, that string is used
- * in /proc/cpuinfo instead of the macro name. If the string is "",
- * this feature bit is not displayed in /proc/cpuinfo at all.
+ * in /proc/cpuinfo instead of the macro name. Otherwise, this feature
+ * bit is not displayed in /proc/cpuinfo at all.
*
* When adding new features here that depend on other features,
* please update the table in kernel/cpu/cpuid-deps.c as well.
*/
/* Intel-defined CPU features, CPUID level 0x00000001 (EDX), word 0 */
-#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */
-#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */
-#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions (plus FCMOVcc, FCOMI with FPU) */
-#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */
+#define X86_FEATURE_FPU ( 0*32+ 0) /* "fpu" Onboard FPU */
+#define X86_FEATURE_VME ( 0*32+ 1) /* "vme" Virtual Mode Extensions */
+#define X86_FEATURE_DE ( 0*32+ 2) /* "de" Debugging Extensions */
+#define X86_FEATURE_PSE ( 0*32+ 3) /* "pse" Page Size Extensions */
+#define X86_FEATURE_TSC ( 0*32+ 4) /* "tsc" Time Stamp Counter */
+#define X86_FEATURE_MSR ( 0*32+ 5) /* "msr" Model-Specific Registers */
+#define X86_FEATURE_PAE ( 0*32+ 6) /* "pae" Physical Address Extensions */
+#define X86_FEATURE_MCE ( 0*32+ 7) /* "mce" Machine Check Exception */
+#define X86_FEATURE_CX8 ( 0*32+ 8) /* "cx8" CMPXCHG8 instruction */
+#define X86_FEATURE_APIC ( 0*32+ 9) /* "apic" Onboard APIC */
+#define X86_FEATURE_SEP ( 0*32+11) /* "sep" SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR ( 0*32+12) /* "mtrr" Memory Type Range Registers */
+#define X86_FEATURE_PGE ( 0*32+13) /* "pge" Page Global Enable */
+#define X86_FEATURE_MCA ( 0*32+14) /* "mca" Machine Check Architecture */
+#define X86_FEATURE_CMOV ( 0*32+15) /* "cmov" CMOV instructions (plus FCMOVcc, FCOMI with FPU) */
+#define X86_FEATURE_PAT ( 0*32+16) /* "pat" Page Attribute Table */
+#define X86_FEATURE_PSE36 ( 0*32+17) /* "pse36" 36-bit PSEs */
+#define X86_FEATURE_PN ( 0*32+18) /* "pn" Processor serial number */
+#define X86_FEATURE_CLFLUSH ( 0*32+19) /* "clflush" CLFLUSH instruction */
#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */
-#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
+#define X86_FEATURE_ACPI ( 0*32+22) /* "acpi" ACPI via MSR */
+#define X86_FEATURE_MMX ( 0*32+23) /* "mmx" Multimedia Extensions */
+#define X86_FEATURE_FXSR ( 0*32+24) /* "fxsr" FXSAVE/FXRSTOR, CR4.OSFXSR */
#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */
#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */
#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */
-#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */
+#define X86_FEATURE_HT ( 0*32+28) /* "ht" Hyper-Threading */
#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */
-#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */
-#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
+#define X86_FEATURE_IA64 ( 0*32+30) /* "ia64" IA-64 processor */
+#define X86_FEATURE_PBE ( 0*32+31) /* "pbe" Pending Break Enable */
/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP ( 1*32+19) /* MP Capable */
-#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */
-#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
+#define X86_FEATURE_SYSCALL ( 1*32+11) /* "syscall" SYSCALL/SYSRET */
+#define X86_FEATURE_MP ( 1*32+19) /* "mp" MP Capable */
+#define X86_FEATURE_NX ( 1*32+20) /* "nx" Execute Disable */
+#define X86_FEATURE_MMXEXT ( 1*32+22) /* "mmxext" AMD MMX extensions */
+#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* "fxsr_opt" FXSAVE/FXRSTOR optimizations */
#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */
-#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64, 64-bit support) */
-#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow extensions */
-#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow */
+#define X86_FEATURE_RDTSCP ( 1*32+27) /* "rdtscp" RDTSCP */
+#define X86_FEATURE_LM ( 1*32+29) /* "lm" Long Mode (x86-64, 64-bit support) */
+#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* "3dnowext" AMD 3DNow extensions */
+#define X86_FEATURE_3DNOW ( 1*32+31) /* "3dnow" 3DNow */
/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */
+#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* "recovery" CPU in recovery mode */
+#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* "longrun" Longrun power control */
+#define X86_FEATURE_LRTI ( 2*32+ 3) /* "lrti" LongRun table interface */
/* Other features, Linux-defined mapping, word 3 */
/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
-#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */
-#define X86_FEATURE_ZEN5 ( 3*32+ 5) /* "" CPU based on Zen5 microarchitecture */
-#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */
-#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */
-#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
-#define X86_FEATURE_UP ( 3*32+ 9) /* SMP kernel running on UP */
-#define X86_FEATURE_ART ( 3*32+10) /* Always running timer (ART) */
-#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */
-#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 */
-#define X86_FEATURE_AMD_LBR_V2 ( 3*32+17) /* AMD Last Branch Record Extension Version 2 */
-#define X86_FEATURE_CLEAR_CPU_BUF ( 3*32+18) /* "" Clear CPU buffers using VERW */
-#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */
-#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
-#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
-#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* CPU topology enum extensions */
-#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
-#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */
-#define X86_FEATURE_CPUID ( 3*32+25) /* CPU has CPUID instruction itself */
-#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* Extended APICID (8 bits) */
-#define X86_FEATURE_AMD_DCM ( 3*32+27) /* AMD multi-node processor */
-#define X86_FEATURE_APERFMPERF ( 3*32+28) /* P-State hardware coordination feedback capability (APERF/MPERF MSRs) */
-#define X86_FEATURE_RAPL ( 3*32+29) /* AMD/Hygon RAPL interface */
-#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
-#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
+#define X86_FEATURE_CXMMX ( 3*32+ 0) /* "cxmmx" Cyrix MMX extensions */
+#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* "k6_mtrr" AMD K6 nonstandard MTRRs */
+#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* "cyrix_arr" Cyrix ARRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* "centaur_mcr" Centaur MCRs (= MTRRs) */
+#define X86_FEATURE_K8 ( 3*32+ 4) /* Opteron, Athlon64 */
+#define X86_FEATURE_ZEN5 ( 3*32+ 5) /* CPU based on Zen5 microarchitecture */
+#define X86_FEATURE_P3 ( 3*32+ 6) /* P3 */
+#define X86_FEATURE_P4 ( 3*32+ 7) /* P4 */
+#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* "constant_tsc" TSC ticks at a constant rate */
+#define X86_FEATURE_UP ( 3*32+ 9) /* "up" SMP kernel running on UP */
+#define X86_FEATURE_ART ( 3*32+10) /* "art" Always running timer (ART) */
+#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* "arch_perfmon" Intel Architectural PerfMon */
+#define X86_FEATURE_PEBS ( 3*32+12) /* "pebs" Precise-Event Based Sampling */
+#define X86_FEATURE_BTS ( 3*32+13) /* "bts" Branch Trace Store */
+#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_good" REP microcode works well */
+#define X86_FEATURE_AMD_LBR_V2 ( 3*32+17) /* "amd_lbr_v2" AMD Last Branch Record Extension Version 2 */
+#define X86_FEATURE_CLEAR_CPU_BUF ( 3*32+18) /* Clear CPU buffers using VERW */
+#define X86_FEATURE_ACC_POWER ( 3*32+19) /* "acc_power" AMD Accumulated Power Mechanism */
+#define X86_FEATURE_NOPL ( 3*32+20) /* "nopl" The NOPL (0F 1F) instructions */
+#define X86_FEATURE_ALWAYS ( 3*32+21) /* Always-present feature */
+#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* "xtopology" CPU topology enum extensions */
+#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* "tsc_reliable" TSC is known to be reliable */
+#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* "nonstop_tsc" TSC does not stop in C states */
+#define X86_FEATURE_CPUID ( 3*32+25) /* "cpuid" CPU has CPUID instruction itself */
+#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* "extd_apicid" Extended APICID (8 bits) */
+#define X86_FEATURE_AMD_DCM ( 3*32+27) /* "amd_dcm" AMD multi-node processor */
+#define X86_FEATURE_APERFMPERF ( 3*32+28) /* "aperfmperf" P-State hardware coordination feedback capability (APERF/MPERF MSRs) */
+#define X86_FEATURE_RAPL ( 3*32+29) /* "rapl" AMD/Hygon RAPL interface */
+#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* "nonstop_tsc_s3" TSC doesn't stop in S3 state */
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* "tsc_known_freq" TSC has known frequency */
/* Intel-defined CPU features, CPUID level 0x00000001 (ECX), word 4 */
#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
-#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */
-#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */
+#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* "pclmulqdq" PCLMULQDQ instruction */
+#define X86_FEATURE_DTES64 ( 4*32+ 2) /* "dtes64" 64-bit Debug Store */
#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" MONITOR/MWAIT support */
#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL-qualified (filtered) Debug Store */
-#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */
-#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer Mode eXtensions */
-#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */
-#define X86_FEATURE_CID ( 4*32+10) /* Context ID */
-#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */
-#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */
-#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B instruction */
-#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM ( 4*32+15) /* Perf/Debug Capabilities MSR */
-#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */
-#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */
+#define X86_FEATURE_VMX ( 4*32+ 5) /* "vmx" Hardware virtualization */
+#define X86_FEATURE_SMX ( 4*32+ 6) /* "smx" Safer Mode eXtensions */
+#define X86_FEATURE_EST ( 4*32+ 7) /* "est" Enhanced SpeedStep */
+#define X86_FEATURE_TM2 ( 4*32+ 8) /* "tm2" Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* "ssse3" Supplemental SSE-3 */
+#define X86_FEATURE_CID ( 4*32+10) /* "cid" Context ID */
+#define X86_FEATURE_SDBG ( 4*32+11) /* "sdbg" Silicon Debug */
+#define X86_FEATURE_FMA ( 4*32+12) /* "fma" Fused multiply-add */
+#define X86_FEATURE_CX16 ( 4*32+13) /* "cx16" CMPXCHG16B instruction */
+#define X86_FEATURE_XTPR ( 4*32+14) /* "xtpr" Send Task Priority Messages */
+#define X86_FEATURE_PDCM ( 4*32+15) /* "pdcm" Perf/Debug Capabilities MSR */
+#define X86_FEATURE_PCID ( 4*32+17) /* "pcid" Process Context Identifiers */
+#define X86_FEATURE_DCA ( 4*32+18) /* "dca" Direct Cache Access */
#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */
#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */
-#define X86_FEATURE_X2APIC ( 4*32+21) /* X2APIC */
-#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */
-#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* TSC deadline timer */
-#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */
-#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV instructions */
-#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE instruction enabled in the OS */
-#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */
-#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit FP conversions */
-#define X86_FEATURE_RDRAND ( 4*32+30) /* RDRAND instruction */
-#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */
+#define X86_FEATURE_X2APIC ( 4*32+21) /* "x2apic" X2APIC */
+#define X86_FEATURE_MOVBE ( 4*32+22) /* "movbe" MOVBE instruction */
+#define X86_FEATURE_POPCNT ( 4*32+23) /* "popcnt" POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* "tsc_deadline_timer" TSC deadline timer */
+#define X86_FEATURE_AES ( 4*32+25) /* "aes" AES instructions */
+#define X86_FEATURE_XSAVE ( 4*32+26) /* "xsave" XSAVE/XRSTOR/XSETBV/XGETBV instructions */
+#define X86_FEATURE_OSXSAVE ( 4*32+27) /* XSAVE instruction enabled in the OS */
+#define X86_FEATURE_AVX ( 4*32+28) /* "avx" Advanced Vector Extensions */
+#define X86_FEATURE_F16C ( 4*32+29) /* "f16c" 16-bit FP conversions */
+#define X86_FEATURE_RDRAND ( 4*32+30) /* "rdrand" RDRAND instruction */
+#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* "hypervisor" Running on a hypervisor */
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */
#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */
#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
-#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */
-#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */
-#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */
-#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */
+#define X86_FEATURE_ACE2 ( 5*32+ 8) /* "ace2" Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* "ace2_en" ACE v2 enabled */
+#define X86_FEATURE_PHE ( 5*32+10) /* "phe" PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN ( 5*32+11) /* "phe_en" PHE enabled */
+#define X86_FEATURE_PMM ( 5*32+12) /* "pmm" PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN ( 5*32+13) /* "pmm_en" PMM enabled */
/* More extended AMD flags: CPUID level 0x80000001, ECX, word 6 */
-#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure Virtual Machine */
-#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */
-#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */
-#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */
-#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */
-#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */
-#define X86_FEATURE_TCE ( 6*32+17) /* Translation Cache Extension */
-#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */
-#define X86_FEATURE_TBM ( 6*32+21) /* Trailing Bit Manipulations */
-#define X86_FEATURE_TOPOEXT ( 6*32+22) /* Topology extensions CPUID leafs */
-#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* Core performance counter extensions */
-#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
-#define X86_FEATURE_BPEXT ( 6*32+26) /* Data breakpoint extension */
-#define X86_FEATURE_PTSC ( 6*32+27) /* Performance time-stamp counter */
-#define X86_FEATURE_PERFCTR_LLC ( 6*32+28) /* Last Level Cache performance counter extensions */
-#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX instructions) */
+#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* "lahf_lm" LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* "cmp_legacy" If yes HyperThreading not valid */
+#define X86_FEATURE_SVM ( 6*32+ 2) /* "svm" Secure Virtual Machine */
+#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* "extapic" Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* "cr8_legacy" CR8 in 32-bit mode */
+#define X86_FEATURE_ABM ( 6*32+ 5) /* "abm" Advanced bit manipulation */
+#define X86_FEATURE_SSE4A ( 6*32+ 6) /* "sse4a" SSE-4A */
+#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* "misalignsse" Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* "3dnowprefetch" 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW ( 6*32+ 9) /* "osvw" OS Visible Workaround */
+#define X86_FEATURE_IBS ( 6*32+10) /* "ibs" Instruction Based Sampling */
+#define X86_FEATURE_XOP ( 6*32+11) /* "xop" Extended AVX instructions */
+#define X86_FEATURE_SKINIT ( 6*32+12) /* "skinit" SKINIT/STGI instructions */
+#define X86_FEATURE_WDT ( 6*32+13) /* "wdt" Watchdog timer */
+#define X86_FEATURE_LWP ( 6*32+15) /* "lwp" Light Weight Profiling */
+#define X86_FEATURE_FMA4 ( 6*32+16) /* "fma4" 4 operands MAC instructions */
+#define X86_FEATURE_TCE ( 6*32+17) /* "tce" Translation Cache Extension */
+#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* "nodeid_msr" NodeId MSR */
+#define X86_FEATURE_TBM ( 6*32+21) /* "tbm" Trailing Bit Manipulations */
+#define X86_FEATURE_TOPOEXT ( 6*32+22) /* "topoext" Topology extensions CPUID leafs */
+#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* "perfctr_core" Core performance counter extensions */
+#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* "perfctr_nb" NB performance counter extensions */
+#define X86_FEATURE_BPEXT ( 6*32+26) /* "bpext" Data breakpoint extension */
+#define X86_FEATURE_PTSC ( 6*32+27) /* "ptsc" Performance time-stamp counter */
+#define X86_FEATURE_PERFCTR_LLC ( 6*32+28) /* "perfctr_llc" Last Level Cache performance counter extensions */
+#define X86_FEATURE_MWAITX ( 6*32+29) /* "mwaitx" MWAIT extension (MONITORX/MWAITX instructions) */
/*
* Auxiliary flags: Linux defined - For features scattered in various
@@ -189,93 +189,93 @@
*
* Reuse free bits when adding new feature flags!
*/
-#define X86_FEATURE_RING3MWAIT ( 7*32+ 0) /* Ring 3 MONITOR/MWAIT instructions */
-#define X86_FEATURE_CPUID_FAULT ( 7*32+ 1) /* Intel CPUID faulting */
-#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
-#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
-#define X86_FEATURE_CAT_L3 ( 7*32+ 4) /* Cache Allocation Technology L3 */
-#define X86_FEATURE_CAT_L2 ( 7*32+ 5) /* Cache Allocation Technology L2 */
-#define X86_FEATURE_CDP_L3 ( 7*32+ 6) /* Code and Data Prioritization L3 */
-#define X86_FEATURE_TDX_HOST_PLATFORM ( 7*32+ 7) /* Platform supports being a TDX host */
-#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
-#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
-#define X86_FEATURE_XCOMPACTED ( 7*32+10) /* "" Use compacted XSTATE (XSAVES or XSAVEC) */
-#define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */
-#define X86_FEATURE_KERNEL_IBRS ( 7*32+12) /* "" Set/clear IBRS on kernel entry/exit */
-#define X86_FEATURE_RSB_VMEXIT ( 7*32+13) /* "" Fill RSB on VM-Exit */
-#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */
-#define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */
-#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
-#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
-#define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */
-#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
-#define X86_FEATURE_PERFMON_V2 ( 7*32+20) /* AMD Performance Monitoring Version 2 */
-#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
-#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
-#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
-#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */
-#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
-#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
-#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
-#define X86_FEATURE_ZEN ( 7*32+28) /* "" Generic flag for all Zen and newer */
-#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
-#define X86_FEATURE_IBRS_ENHANCED ( 7*32+30) /* Enhanced IBRS */
-#define X86_FEATURE_MSR_IA32_FEAT_CTL ( 7*32+31) /* "" MSR IA32_FEAT_CTL configured */
+#define X86_FEATURE_RING3MWAIT ( 7*32+ 0) /* "ring3mwait" Ring 3 MONITOR/MWAIT instructions */
+#define X86_FEATURE_CPUID_FAULT ( 7*32+ 1) /* "cpuid_fault" Intel CPUID faulting */
+#define X86_FEATURE_CPB ( 7*32+ 2) /* "cpb" AMD Core Performance Boost */
+#define X86_FEATURE_EPB ( 7*32+ 3) /* "epb" IA32_ENERGY_PERF_BIAS support */
+#define X86_FEATURE_CAT_L3 ( 7*32+ 4) /* "cat_l3" Cache Allocation Technology L3 */
+#define X86_FEATURE_CAT_L2 ( 7*32+ 5) /* "cat_l2" Cache Allocation Technology L2 */
+#define X86_FEATURE_CDP_L3 ( 7*32+ 6) /* "cdp_l3" Code and Data Prioritization L3 */
+#define X86_FEATURE_TDX_HOST_PLATFORM ( 7*32+ 7) /* "tdx_host_platform" Platform supports being a TDX host */
+#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* "hw_pstate" AMD HW-PState */
+#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* "proc_feedback" AMD ProcFeedbackInterface */
+#define X86_FEATURE_XCOMPACTED ( 7*32+10) /* Use compacted XSTATE (XSAVES or XSAVEC) */
+#define X86_FEATURE_PTI ( 7*32+11) /* "pti" Kernel Page Table Isolation enabled */
+#define X86_FEATURE_KERNEL_IBRS ( 7*32+12) /* Set/clear IBRS on kernel entry/exit */
+#define X86_FEATURE_RSB_VMEXIT ( 7*32+13) /* Fill RSB on VM-Exit */
+#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* "intel_ppin" Intel Processor Inventory Number */
+#define X86_FEATURE_CDP_L2 ( 7*32+15) /* "cdp_l2" Code and Data Prioritization L2 */
+#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* MSR SPEC_CTRL is implemented */
+#define X86_FEATURE_SSBD ( 7*32+17) /* "ssbd" Speculative Store Bypass Disable */
+#define X86_FEATURE_MBA ( 7*32+18) /* "mba" Memory Bandwidth Allocation */
+#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* Fill RSB on context switches */
+#define X86_FEATURE_PERFMON_V2 ( 7*32+20) /* "perfmon_v2" AMD Performance Monitoring Version 2 */
+#define X86_FEATURE_USE_IBPB ( 7*32+21) /* Indirect Branch Prediction Barrier enabled */
+#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* Use IBRS during runtime firmware calls */
+#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */
+#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */
+#define X86_FEATURE_IBRS ( 7*32+25) /* "ibrs" Indirect Branch Restricted Speculation */
+#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier */
+#define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */
+#define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */
+#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */
+#define X86_FEATURE_IBRS_ENHANCED ( 7*32+30) /* "ibrs_enhanced" Enhanced IBRS */
+#define X86_FEATURE_MSR_IA32_FEAT_CTL ( 7*32+31) /* MSR IA32_FEAT_CTL configured */
/* Virtualization flags: Linux defined, word 8 */
-#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
-#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 1) /* Intel FlexPriority */
-#define X86_FEATURE_EPT ( 8*32+ 2) /* Intel Extended Page Table */
-#define X86_FEATURE_VPID ( 8*32+ 3) /* Intel Virtual Processor ID */
+#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* "tpr_shadow" Intel TPR Shadow */
+#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 1) /* "flexpriority" Intel FlexPriority */
+#define X86_FEATURE_EPT ( 8*32+ 2) /* "ept" Intel Extended Page Table */
+#define X86_FEATURE_VPID ( 8*32+ 3) /* "vpid" Intel Virtual Processor ID */
-#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer VMMCALL to VMCALL */
-#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
-#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_PVUNLOCK ( 8*32+20) /* "" PV unlock function */
-#define X86_FEATURE_VCPUPREEMPT ( 8*32+21) /* "" PV vcpu_is_preempted function */
-#define X86_FEATURE_TDX_GUEST ( 8*32+22) /* Intel Trust Domain Extensions Guest */
+#define X86_FEATURE_VMMCALL ( 8*32+15) /* "vmmcall" Prefer VMMCALL to VMCALL */
+#define X86_FEATURE_XENPV ( 8*32+16) /* Xen paravirtual guest */
+#define X86_FEATURE_EPT_AD ( 8*32+17) /* "ept_ad" 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_PVUNLOCK ( 8*32+20) /* PV unlock function */
+#define X86_FEATURE_VCPUPREEMPT ( 8*32+21) /* PV vcpu_is_preempted function */
+#define X86_FEATURE_TDX_GUEST ( 8*32+22) /* "tdx_guest" Intel Trust Domain Extensions Guest */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
-#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
-#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3B */
-#define X86_FEATURE_SGX ( 9*32+ 2) /* Software Guard Extensions */
-#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */
-#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */
-#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */
-#define X86_FEATURE_FDP_EXCPTN_ONLY ( 9*32+ 6) /* "" FPU data pointer updated only on x87 exceptions */
-#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */
-#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */
-#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB instructions */
-#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
-#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
-#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
-#define X86_FEATURE_ZERO_FCS_FDS ( 9*32+13) /* "" Zero out FPU CS and FPU DS */
-#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
-#define X86_FEATURE_RDT_A ( 9*32+15) /* Resource Director Technology Allocation */
-#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
-#define X86_FEATURE_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */
-#define X86_FEATURE_RDSEED ( 9*32+18) /* RDSEED instruction */
-#define X86_FEATURE_ADX ( 9*32+19) /* ADCX and ADOX instructions */
-#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
-#define X86_FEATURE_AVX512IFMA ( 9*32+21) /* AVX-512 Integer Fused Multiply-Add instructions */
-#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
-#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
-#define X86_FEATURE_INTEL_PT ( 9*32+25) /* Intel Processor Trace */
-#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
-#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
-#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
-#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
-#define X86_FEATURE_AVX512BW ( 9*32+30) /* AVX-512 BW (Byte/Word granular) Instructions */
-#define X86_FEATURE_AVX512VL ( 9*32+31) /* AVX-512 VL (128/256 Vector Length) Extensions */
+#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* "fsgsbase" RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
+#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* "tsc_adjust" TSC adjustment MSR 0x3B */
+#define X86_FEATURE_SGX ( 9*32+ 2) /* "sgx" Software Guard Extensions */
+#define X86_FEATURE_BMI1 ( 9*32+ 3) /* "bmi1" 1st group bit manipulation extensions */
+#define X86_FEATURE_HLE ( 9*32+ 4) /* "hle" Hardware Lock Elision */
+#define X86_FEATURE_AVX2 ( 9*32+ 5) /* "avx2" AVX2 instructions */
+#define X86_FEATURE_FDP_EXCPTN_ONLY ( 9*32+ 6) /* FPU data pointer updated only on x87 exceptions */
+#define X86_FEATURE_SMEP ( 9*32+ 7) /* "smep" Supervisor Mode Execution Protection */
+#define X86_FEATURE_BMI2 ( 9*32+ 8) /* "bmi2" 2nd group bit manipulation extensions */
+#define X86_FEATURE_ERMS ( 9*32+ 9) /* "erms" Enhanced REP MOVSB/STOSB instructions */
+#define X86_FEATURE_INVPCID ( 9*32+10) /* "invpcid" Invalidate Processor Context ID */
+#define X86_FEATURE_RTM ( 9*32+11) /* "rtm" Restricted Transactional Memory */
+#define X86_FEATURE_CQM ( 9*32+12) /* "cqm" Cache QoS Monitoring */
+#define X86_FEATURE_ZERO_FCS_FDS ( 9*32+13) /* Zero out FPU CS and FPU DS */
+#define X86_FEATURE_MPX ( 9*32+14) /* "mpx" Memory Protection Extension */
+#define X86_FEATURE_RDT_A ( 9*32+15) /* "rdt_a" Resource Director Technology Allocation */
+#define X86_FEATURE_AVX512F ( 9*32+16) /* "avx512f" AVX-512 Foundation */
+#define X86_FEATURE_AVX512DQ ( 9*32+17) /* "avx512dq" AVX-512 DQ (Double/Quad granular) Instructions */
+#define X86_FEATURE_RDSEED ( 9*32+18) /* "rdseed" RDSEED instruction */
+#define X86_FEATURE_ADX ( 9*32+19) /* "adx" ADCX and ADOX instructions */
+#define X86_FEATURE_SMAP ( 9*32+20) /* "smap" Supervisor Mode Access Prevention */
+#define X86_FEATURE_AVX512IFMA ( 9*32+21) /* "avx512ifma" AVX-512 Integer Fused Multiply-Add instructions */
+#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* "clflushopt" CLFLUSHOPT instruction */
+#define X86_FEATURE_CLWB ( 9*32+24) /* "clwb" CLWB instruction */
+#define X86_FEATURE_INTEL_PT ( 9*32+25) /* "intel_pt" Intel Processor Trace */
+#define X86_FEATURE_AVX512PF ( 9*32+26) /* "avx512pf" AVX-512 Prefetch */
+#define X86_FEATURE_AVX512ER ( 9*32+27) /* "avx512er" AVX-512 Exponential and Reciprocal */
+#define X86_FEATURE_AVX512CD ( 9*32+28) /* "avx512cd" AVX-512 Conflict Detection */
+#define X86_FEATURE_SHA_NI ( 9*32+29) /* "sha_ni" SHA1/SHA256 Instruction Extensions */
+#define X86_FEATURE_AVX512BW ( 9*32+30) /* "avx512bw" AVX-512 BW (Byte/Word granular) Instructions */
+#define X86_FEATURE_AVX512VL ( 9*32+31) /* "avx512vl" AVX-512 VL (128/256 Vector Length) Extensions */
/* Extended state features, CPUID level 0x0000000d:1 (EAX), word 10 */
-#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT instruction */
-#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC instruction */
-#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 instruction */
-#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS instructions */
-#define X86_FEATURE_XFD (10*32+ 4) /* "" eXtended Feature Disabling */
+#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* "xsaveopt" XSAVEOPT instruction */
+#define X86_FEATURE_XSAVEC (10*32+ 1) /* "xsavec" XSAVEC instruction */
+#define X86_FEATURE_XGETBV1 (10*32+ 2) /* "xgetbv1" XGETBV with ECX = 1 instruction */
+#define X86_FEATURE_XSAVES (10*32+ 3) /* "xsaves" XSAVES/XRSTORS instructions */
+#define X86_FEATURE_XFD (10*32+ 4) /* eXtended Feature Disabling */
/*
* Extended auxiliary flags: Linux defined - for features scattered in various
@@ -283,181 +283,183 @@
*
* Reuse free bits when adding new feature flags!
*/
-#define X86_FEATURE_CQM_LLC (11*32+ 0) /* LLC QoS if 1 */
-#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */
-#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */
-#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */
-#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 */
-#define X86_FEATURE_SGX1 (11*32+ 8) /* "" Basic SGX */
-#define X86_FEATURE_SGX2 (11*32+ 9) /* "" SGX Enclave Dynamic Memory Management (EDMM) */
-#define X86_FEATURE_ENTRY_IBPB (11*32+10) /* "" Issue an IBPB on kernel entry */
-#define X86_FEATURE_RRSBA_CTRL (11*32+11) /* "" RET prediction control */
-#define X86_FEATURE_RETPOLINE (11*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
-#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
-#define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */
-#define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */
-#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
-#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
-#define X86_FEATURE_SGX_EDECCSSA (11*32+18) /* "" SGX EDECCSSA user leaf function */
-#define X86_FEATURE_CALL_DEPTH (11*32+19) /* "" Call depth tracking for RSB stuffing */
-#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
-#define X86_FEATURE_SMBA (11*32+21) /* "" Slow Memory Bandwidth Allocation */
-#define X86_FEATURE_BMEC (11*32+22) /* "" Bandwidth Monitoring Event Configuration */
-#define X86_FEATURE_USER_SHSTK (11*32+23) /* Shadow stack support for user mode applications */
-#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */
-#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */
-#define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */
-#define X86_FEATURE_APIC_MSRS_FENCE (11*32+27) /* "" IA32_TSC_DEADLINE and X2APIC MSRs need fencing */
-#define X86_FEATURE_ZEN2 (11*32+28) /* "" CPU based on Zen2 microarchitecture */
-#define X86_FEATURE_ZEN3 (11*32+29) /* "" CPU based on Zen3 microarchitecture */
-#define X86_FEATURE_ZEN4 (11*32+30) /* "" CPU based on Zen4 microarchitecture */
-#define X86_FEATURE_ZEN1 (11*32+31) /* "" CPU based on Zen1 microarchitecture */
+#define X86_FEATURE_CQM_LLC (11*32+ 0) /* "cqm_llc" LLC QoS if 1 */
+#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* "cqm_occup_llc" LLC occupancy monitoring */
+#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* "cqm_mbm_total" LLC Total MBM monitoring */
+#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* "cqm_mbm_local" LLC Local MBM monitoring */
+#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) /* "split_lock_detect" #AC for split lock */
+#define X86_FEATURE_PER_THREAD_MBA (11*32+ 7) /* Per-thread Memory Bandwidth Allocation */
+#define X86_FEATURE_SGX1 (11*32+ 8) /* Basic SGX */
+#define X86_FEATURE_SGX2 (11*32+ 9) /* SGX Enclave Dynamic Memory Management (EDMM) */
+#define X86_FEATURE_ENTRY_IBPB (11*32+10) /* Issue an IBPB on kernel entry */
+#define X86_FEATURE_RRSBA_CTRL (11*32+11) /* RET prediction control */
+#define X86_FEATURE_RETPOLINE (11*32+12) /* Generic Retpoline mitigation for Spectre variant 2 */
+#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* Use LFENCE for Spectre variant 2 */
+#define X86_FEATURE_RETHUNK (11*32+14) /* Use REturn THUNK */
+#define X86_FEATURE_UNRET (11*32+15) /* AMD BTB untrain return */
+#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* Use IBPB during runtime firmware calls */
+#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* Fill RSB on VM exit when EIBRS is enabled */
+#define X86_FEATURE_SGX_EDECCSSA (11*32+18) /* SGX EDECCSSA user leaf function */
+#define X86_FEATURE_CALL_DEPTH (11*32+19) /* Call depth tracking for RSB stuffing */
+#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* MSR IA32_TSX_CTRL (Intel) implemented */
+#define X86_FEATURE_SMBA (11*32+21) /* Slow Memory Bandwidth Allocation */
+#define X86_FEATURE_BMEC (11*32+22) /* Bandwidth Monitoring Event Configuration */
+#define X86_FEATURE_USER_SHSTK (11*32+23) /* "user_shstk" Shadow stack support for user mode applications */
+#define X86_FEATURE_SRSO (11*32+24) /* AMD BTB untrain RETs */
+#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* AMD BTB untrain RETs through aliasing */
+#define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* Issue an IBPB only on VMEXIT */
+#define X86_FEATURE_APIC_MSRS_FENCE (11*32+27) /* IA32_TSC_DEADLINE and X2APIC MSRs need fencing */
+#define X86_FEATURE_ZEN2 (11*32+28) /* CPU based on Zen2 microarchitecture */
+#define X86_FEATURE_ZEN3 (11*32+29) /* CPU based on Zen3 microarchitecture */
+#define X86_FEATURE_ZEN4 (11*32+30) /* CPU based on Zen4 microarchitecture */
+#define X86_FEATURE_ZEN1 (11*32+31) /* CPU based on Zen1 microarchitecture */
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
-#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
-#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
-#define X86_FEATURE_CMPCCXADD (12*32+ 7) /* "" CMPccXADD instructions */
-#define X86_FEATURE_ARCH_PERFMON_EXT (12*32+ 8) /* "" Intel Architectural PerfMon Extension */
-#define X86_FEATURE_FZRM (12*32+10) /* "" Fast zero-length REP MOVSB */
-#define X86_FEATURE_FSRS (12*32+11) /* "" Fast short REP STOSB */
-#define X86_FEATURE_FSRC (12*32+12) /* "" Fast short REP {CMPSB,SCASB} */
-#define X86_FEATURE_FRED (12*32+17) /* Flexible Return and Event Delivery */
-#define X86_FEATURE_LKGS (12*32+18) /* "" Load "kernel" (userspace) GS */
-#define X86_FEATURE_WRMSRNS (12*32+19) /* "" Non-serializing WRMSR */
-#define X86_FEATURE_AMX_FP16 (12*32+21) /* "" AMX fp16 Support */
-#define X86_FEATURE_AVX_IFMA (12*32+23) /* "" Support for VPMADD52[H,L]UQ */
-#define X86_FEATURE_LAM (12*32+26) /* Linear Address Masking */
+#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* "avx_vnni" AVX VNNI instructions */
+#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* "avx512_bf16" AVX512 BFLOAT16 instructions */
+#define X86_FEATURE_CMPCCXADD (12*32+ 7) /* CMPccXADD instructions */
+#define X86_FEATURE_ARCH_PERFMON_EXT (12*32+ 8) /* Intel Architectural PerfMon Extension */
+#define X86_FEATURE_FZRM (12*32+10) /* Fast zero-length REP MOVSB */
+#define X86_FEATURE_FSRS (12*32+11) /* Fast short REP STOSB */
+#define X86_FEATURE_FSRC (12*32+12) /* Fast short REP {CMPSB,SCASB} */
+#define X86_FEATURE_FRED (12*32+17) /* "fred" Flexible Return and Event Delivery */
+#define X86_FEATURE_LKGS (12*32+18) /* Load "kernel" (userspace) GS */
+#define X86_FEATURE_WRMSRNS (12*32+19) /* Non-serializing WRMSR */
+#define X86_FEATURE_AMX_FP16 (12*32+21) /* AMX fp16 Support */
+#define X86_FEATURE_AVX_IFMA (12*32+23) /* Support for VPMADD52[H,L]UQ */
+#define X86_FEATURE_LAM (12*32+26) /* "lam" Linear Address Masking */
/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
-#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
-#define X86_FEATURE_IRPERF (13*32+ 1) /* Instructions Retired Count */
-#define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* Always save/restore FP error pointers */
-#define X86_FEATURE_RDPRU (13*32+ 4) /* Read processor register at user level */
-#define X86_FEATURE_WBNOINVD (13*32+ 9) /* WBNOINVD instruction */
-#define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */
-#define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */
-#define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */
-#define X86_FEATURE_AMD_STIBP_ALWAYS_ON (13*32+17) /* "" Single Thread Indirect Branch Predictors always-on preferred */
-#define X86_FEATURE_AMD_PPIN (13*32+23) /* Protected Processor Inventory Number */
-#define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */
-#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
-#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
-#define X86_FEATURE_CPPC (13*32+27) /* Collaborative Processor Performance Control */
-#define X86_FEATURE_AMD_PSFD (13*32+28) /* "" Predictive Store Forwarding Disable */
-#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */
-#define X86_FEATURE_BRS (13*32+31) /* Branch Sampling available */
+#define X86_FEATURE_CLZERO (13*32+ 0) /* "clzero" CLZERO instruction */
+#define X86_FEATURE_IRPERF (13*32+ 1) /* "irperf" Instructions Retired Count */
+#define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* "xsaveerptr" Always save/restore FP error pointers */
+#define X86_FEATURE_RDPRU (13*32+ 4) /* "rdpru" Read processor register at user level */
+#define X86_FEATURE_WBNOINVD (13*32+ 9) /* "wbnoinvd" WBNOINVD instruction */
+#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
+#define X86_FEATURE_AMD_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */
+#define X86_FEATURE_AMD_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */
+#define X86_FEATURE_AMD_STIBP_ALWAYS_ON (13*32+17) /* Single Thread Indirect Branch Predictors always-on preferred */
+#define X86_FEATURE_AMD_PPIN (13*32+23) /* "amd_ppin" Protected Processor Inventory Number */
+#define X86_FEATURE_AMD_SSBD (13*32+24) /* Speculative Store Bypass Disable */
+#define X86_FEATURE_VIRT_SSBD (13*32+25) /* "virt_ssbd" Virtualized Speculative Store Bypass Disable */
+#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* Speculative Store Bypass is fixed in hardware. */
+#define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */
+#define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */
+#define X86_FEATURE_BTC_NO (13*32+29) /* Not vulnerable to Branch Type Confusion */
+#define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
-#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
-#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */
-#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */
-#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */
-#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */
-#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */
-#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */
-#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
-#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */
-#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
-#define X86_FEATURE_HFI (14*32+19) /* Hardware Feedback Interface */
+#define X86_FEATURE_DTHERM (14*32+ 0) /* "dtherm" Digital Thermal Sensor */
+#define X86_FEATURE_IDA (14*32+ 1) /* "ida" Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT (14*32+ 2) /* "arat" Always Running APIC Timer */
+#define X86_FEATURE_PLN (14*32+ 4) /* "pln" Intel Power Limit Notification */
+#define X86_FEATURE_PTS (14*32+ 6) /* "pts" Intel Package Thermal Status */
+#define X86_FEATURE_HWP (14*32+ 7) /* "hwp" Intel Hardware P-states */
+#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* "hwp_notify" HWP Notification */
+#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* "hwp_act_window" HWP Activity Window */
+#define X86_FEATURE_HWP_EPP (14*32+10) /* "hwp_epp" HWP Energy Perf. Preference */
+#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* "hwp_pkg_req" HWP Package Level Request */
+#define X86_FEATURE_HWP_HIGHEST_PERF_CHANGE (14*32+15) /* HWP Highest perf change */
+#define X86_FEATURE_HFI (14*32+19) /* "hfi" Hardware Feedback Interface */
/* AMD SVM Feature Identification, CPUID level 0x8000000a (EDX), word 15 */
-#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */
-#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */
+#define X86_FEATURE_NPT (15*32+ 0) /* "npt" Nested Page Table support */
+#define X86_FEATURE_LBRV (15*32+ 1) /* "lbrv" LBR Virtualization support */
#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */
#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */
#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */
#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */
-#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */
-#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */
-#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
-#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
-#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
-#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */
-#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */
-#define X86_FEATURE_X2AVIC (15*32+18) /* Virtual x2apic */
-#define X86_FEATURE_V_SPEC_CTRL (15*32+20) /* Virtual SPEC_CTRL */
-#define X86_FEATURE_VNMI (15*32+25) /* Virtual NMI */
-#define X86_FEATURE_SVME_ADDR_CHK (15*32+28) /* "" SVME addr check */
+#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* "flushbyasid" Flush-by-ASID support */
+#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* "decodeassists" Decode Assists support */
+#define X86_FEATURE_PAUSEFILTER (15*32+10) /* "pausefilter" Filtered pause intercept */
+#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* "pfthreshold" Pause filter threshold */
+#define X86_FEATURE_AVIC (15*32+13) /* "avic" Virtual Interrupt Controller */
+#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* "v_vmsave_vmload" Virtual VMSAVE VMLOAD */
+#define X86_FEATURE_VGIF (15*32+16) /* "vgif" Virtual GIF */
+#define X86_FEATURE_X2AVIC (15*32+18) /* "x2avic" Virtual x2apic */
+#define X86_FEATURE_V_SPEC_CTRL (15*32+20) /* "v_spec_ctrl" Virtual SPEC_CTRL */
+#define X86_FEATURE_VNMI (15*32+25) /* "vnmi" Virtual NMI */
+#define X86_FEATURE_SVME_ADDR_CHK (15*32+28) /* SVME addr check */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ECX), word 16 */
-#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
-#define X86_FEATURE_UMIP (16*32+ 2) /* User Mode Instruction Protection */
-#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
-#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
-#define X86_FEATURE_WAITPKG (16*32+ 5) /* UMONITOR/UMWAIT/TPAUSE Instructions */
-#define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* Additional AVX512 Vector Bit Manipulation Instructions */
-#define X86_FEATURE_SHSTK (16*32+ 7) /* "" Shadow stack */
-#define X86_FEATURE_GFNI (16*32+ 8) /* Galois Field New Instructions */
-#define X86_FEATURE_VAES (16*32+ 9) /* Vector AES */
-#define X86_FEATURE_VPCLMULQDQ (16*32+10) /* Carry-Less Multiplication Double Quadword */
-#define X86_FEATURE_AVX512_VNNI (16*32+11) /* Vector Neural Network Instructions */
-#define X86_FEATURE_AVX512_BITALG (16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */
-#define X86_FEATURE_TME (16*32+13) /* Intel Total Memory Encryption */
-#define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */
-#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
-#define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */
-#define X86_FEATURE_BUS_LOCK_DETECT (16*32+24) /* Bus Lock detect */
-#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 */
-#define X86_FEATURE_SGX_LC (16*32+30) /* Software Guard Extensions Launch Control */
+#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* "avx512vbmi" AVX512 Vector Bit Manipulation instructions*/
+#define X86_FEATURE_UMIP (16*32+ 2) /* "umip" User Mode Instruction Protection */
+#define X86_FEATURE_PKU (16*32+ 3) /* "pku" Protection Keys for Userspace */
+#define X86_FEATURE_OSPKE (16*32+ 4) /* "ospke" OS Protection Keys Enable */
+#define X86_FEATURE_WAITPKG (16*32+ 5) /* "waitpkg" UMONITOR/UMWAIT/TPAUSE Instructions */
+#define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* "avx512_vbmi2" Additional AVX512 Vector Bit Manipulation Instructions */
+#define X86_FEATURE_SHSTK (16*32+ 7) /* Shadow stack */
+#define X86_FEATURE_GFNI (16*32+ 8) /* "gfni" Galois Field New Instructions */
+#define X86_FEATURE_VAES (16*32+ 9) /* "vaes" Vector AES */
+#define X86_FEATURE_VPCLMULQDQ (16*32+10) /* "vpclmulqdq" Carry-Less Multiplication Double Quadword */
+#define X86_FEATURE_AVX512_VNNI (16*32+11) /* "avx512_vnni" Vector Neural Network Instructions */
+#define X86_FEATURE_AVX512_BITALG (16*32+12) /* "avx512_bitalg" Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */
+#define X86_FEATURE_TME (16*32+13) /* "tme" Intel Total Memory Encryption */
+#define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* "avx512_vpopcntdq" POPCNT for vectors of DW/QW */
+#define X86_FEATURE_LA57 (16*32+16) /* "la57" 5-level page tables */
+#define X86_FEATURE_RDPID (16*32+22) /* "rdpid" RDPID instruction */
+#define X86_FEATURE_BUS_LOCK_DETECT (16*32+24) /* "bus_lock_detect" Bus Lock detect */
+#define X86_FEATURE_CLDEMOTE (16*32+25) /* "cldemote" CLDEMOTE instruction */
+#define X86_FEATURE_MOVDIRI (16*32+27) /* "movdiri" MOVDIRI instruction */
+#define X86_FEATURE_MOVDIR64B (16*32+28) /* "movdir64b" MOVDIR64B instruction */
+#define X86_FEATURE_ENQCMD (16*32+29) /* "enqcmd" ENQCMD and ENQCMDS instructions */
+#define X86_FEATURE_SGX_LC (16*32+30) /* "sgx_lc" Software Guard Extensions Launch Control */
/* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */
-#define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */
-#define X86_FEATURE_SUCCOR (17*32+ 1) /* Uncorrectable error containment and recovery */
-#define X86_FEATURE_SMCA (17*32+ 3) /* Scalable MCA */
+#define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* "overflow_recov" MCA overflow recovery support */
+#define X86_FEATURE_SUCCOR (17*32+ 1) /* "succor" Uncorrectable error containment and recovery */
+#define X86_FEATURE_SMCA (17*32+ 3) /* "smca" Scalable MCA */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
-#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
-#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
-#define X86_FEATURE_FSRM (18*32+ 4) /* Fast Short Rep Mov */
-#define X86_FEATURE_AVX512_VP2INTERSECT (18*32+ 8) /* AVX-512 Intersect for D/Q */
-#define X86_FEATURE_SRBDS_CTRL (18*32+ 9) /* "" SRBDS mitigation MSR available */
-#define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */
-#define X86_FEATURE_RTM_ALWAYS_ABORT (18*32+11) /* "" RTM transaction always aborts */
-#define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
-#define X86_FEATURE_SERIALIZE (18*32+14) /* SERIALIZE instruction */
-#define X86_FEATURE_HYBRID_CPU (18*32+15) /* "" This part has CPUs of more than one type */
-#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_IBT (18*32+20) /* Indirect Branch Tracking */
-#define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
-#define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */
-#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
-#define X86_FEATURE_AMX_INT8 (18*32+25) /* AMX int8 Support */
-#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
-#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
-#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
-#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
-#define X86_FEATURE_CORE_CAPABILITIES (18*32+30) /* "" IA32_CORE_CAPABILITIES MSR */
-#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
+#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* "avx512_4vnniw" AVX-512 Neural Network Instructions */
+#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* "avx512_4fmaps" AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_FSRM (18*32+ 4) /* "fsrm" Fast Short Rep Mov */
+#define X86_FEATURE_AVX512_VP2INTERSECT (18*32+ 8) /* "avx512_vp2intersect" AVX-512 Intersect for D/Q */
+#define X86_FEATURE_SRBDS_CTRL (18*32+ 9) /* SRBDS mitigation MSR available */
+#define X86_FEATURE_MD_CLEAR (18*32+10) /* "md_clear" VERW clears CPU buffers */
+#define X86_FEATURE_RTM_ALWAYS_ABORT (18*32+11) /* RTM transaction always aborts */
+#define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* TSX_FORCE_ABORT */
+#define X86_FEATURE_SERIALIZE (18*32+14) /* "serialize" SERIALIZE instruction */
+#define X86_FEATURE_HYBRID_CPU (18*32+15) /* This part has CPUs of more than one type */
+#define X86_FEATURE_TSXLDTRK (18*32+16) /* "tsxldtrk" TSX Suspend Load Address Tracking */
+#define X86_FEATURE_PCONFIG (18*32+18) /* "pconfig" Intel PCONFIG */
+#define X86_FEATURE_ARCH_LBR (18*32+19) /* "arch_lbr" Intel ARCH LBR */
+#define X86_FEATURE_IBT (18*32+20) /* "ibt" Indirect Branch Tracking */
+#define X86_FEATURE_AMX_BF16 (18*32+22) /* "amx_bf16" AMX bf16 Support */
+#define X86_FEATURE_AVX512_FP16 (18*32+23) /* "avx512_fp16" AVX512 FP16 */
+#define X86_FEATURE_AMX_TILE (18*32+24) /* "amx_tile" AMX tile Support */
+#define X86_FEATURE_AMX_INT8 (18*32+25) /* "amx_int8" AMX int8 Support */
+#define X86_FEATURE_SPEC_CTRL (18*32+26) /* Speculation Control (IBRS + IBPB) */
+#define X86_FEATURE_INTEL_STIBP (18*32+27) /* Single Thread Indirect Branch Predictors */
+#define X86_FEATURE_FLUSH_L1D (18*32+28) /* "flush_l1d" Flush L1D cache */
+#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* "arch_capabilities" IA32_ARCH_CAPABILITIES MSR (Intel) */
+#define X86_FEATURE_CORE_CAPABILITIES (18*32+30) /* IA32_CORE_CAPABILITIES MSR */
+#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* Speculative Store Bypass Disable */
/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
-#define X86_FEATURE_SME (19*32+ 0) /* AMD Secure Memory Encryption */
-#define X86_FEATURE_SEV (19*32+ 1) /* AMD Secure Encrypted Virtualization */
-#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* "" VM Page Flush MSR is supported */
-#define X86_FEATURE_SEV_ES (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */
-#define X86_FEATURE_SEV_SNP (19*32+ 4) /* AMD Secure Encrypted Virtualization - Secure Nested Paging */
-#define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* "" Virtual TSC_AUX */
-#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */
-#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* AMD SEV-ES full debug state swap support */
+#define X86_FEATURE_SME (19*32+ 0) /* "sme" AMD Secure Memory Encryption */
+#define X86_FEATURE_SEV (19*32+ 1) /* "sev" AMD Secure Encrypted Virtualization */
+#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* VM Page Flush MSR is supported */
+#define X86_FEATURE_SEV_ES (19*32+ 3) /* "sev_es" AMD Secure Encrypted Virtualization - Encrypted State */
+#define X86_FEATURE_SEV_SNP (19*32+ 4) /* "sev_snp" AMD Secure Encrypted Virtualization - Secure Nested Paging */
+#define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* Virtual TSC_AUX */
+#define X86_FEATURE_SME_COHERENT (19*32+10) /* AMD hardware-enforced cache coherency */
+#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" AMD SEV-ES full debug state swap support */
+#define X86_FEATURE_SVSM (19*32+28) /* "svsm" SVSM present */
/* AMD-defined Extended Feature 2 EAX, CPUID level 0x80000021 (EAX), word 20 */
-#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* "" No Nested Data Breakpoints */
-#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* "" WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
-#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* "" LFENCE always serializing / synchronizes RDTSC */
-#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* "" Null Selector Clears Base */
-#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */
-#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* "" SMM_CTL MSR is not present */
+#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
+#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
+#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */
+#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */
+#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
+#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
-#define X86_FEATURE_SBPB (20*32+27) /* "" Selective Branch Prediction Barrier */
-#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */
-#define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */
+#define X86_FEATURE_SBPB (20*32+27) /* Selective Branch Prediction Barrier */
+#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */
+#define X86_FEATURE_SRSO_NO (20*32+29) /* CPU is not affected by SRSO */
/*
* Extended auxiliary flags: Linux defined - for features scattered in various
@@ -465,59 +467,60 @@
*
* Reuse free bits when adding new feature flags!
*/
-#define X86_FEATURE_AMD_LBR_PMC_FREEZE (21*32+ 0) /* AMD LBR and PMC Freeze */
-#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */
-#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */
-#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */
-#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */
+#define X86_FEATURE_AMD_LBR_PMC_FREEZE (21*32+ 0) /* "amd_lbr_pmc_freeze" AMD LBR and PMC Freeze */
+#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* Clear branch history at syscall entry using SW loop */
+#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* BHI_DIS_S HW control available */
+#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* BHI_DIS_S HW control enabled */
+#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
+#define X86_FEATURE_FAST_CPPC (21*32 + 5) /* AMD Fast CPPC */
/*
* BUG word(s)
*/
#define X86_BUG(x) (NCAPINTS*32 + (x))
-#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */
-#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
-#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
+#define X86_BUG_F00F X86_BUG(0) /* "f00f" Intel F00F */
+#define X86_BUG_FDIV X86_BUG(1) /* "fdiv" FPU FDIV */
+#define X86_BUG_COMA X86_BUG(2) /* "coma" Cyrix 6x86 coma */
#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
-#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */
-#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
-#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
-#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+#define X86_BUG_11AP X86_BUG(5) /* "11ap" Bad local APIC aka 11AP */
+#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* "fxsave_leak" FXSAVE leaks FOP/FIP/FOP */
+#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* "clflush_monitor" AAI65, CLFLUSH required before MONITOR */
+#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* "sysret_ss_attrs" SYSRET doesn't fix up SS attrs */
#ifdef CONFIG_X86_32
/*
* 64-bit kernels don't use X86_BUG_ESPFIX. Make the define conditional
* to avoid confusion.
*/
-#define X86_BUG_ESPFIX X86_BUG(9) /* "" IRET to 16-bit SS corrupts ESP/RSP high bits */
+#define X86_BUG_ESPFIX X86_BUG(9) /* IRET to 16-bit SS corrupts ESP/RSP high bits */
#endif
-#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
-#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
-#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
-#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
-#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
-#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
-#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
-#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
-#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
-#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
-#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
-#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
-#define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
-#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
-#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
-#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
-#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* CPU is too old and its MMIO Stale Data status is unknown */
-#define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */
-#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
-#define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */
-#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */
-#define X86_BUG_TDX_PW_MCE X86_BUG(31) /* CPU may incur #MC if non-TD software does partial write to TDX private memory */
+#define X86_BUG_NULL_SEG X86_BUG(10) /* "null_seg" Nulling a selector preserves the base */
+#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* "swapgs_fence" SWAPGS without input dep on GS */
+#define X86_BUG_MONITOR X86_BUG(12) /* "monitor" IPI required to wake up remote CPU */
+#define X86_BUG_AMD_E400 X86_BUG(13) /* "amd_e400" CPU is among the affected by Erratum 400 */
+#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* "cpu_meltdown" CPU is affected by meltdown attack and needs kernel page table isolation */
+#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* "spectre_v1" CPU is affected by Spectre variant 1 attack with conditional branches */
+#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* "spectre_v2" CPU is affected by Spectre variant 2 attack with indirect branches */
+#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* "spec_store_bypass" CPU is affected by speculative store bypass attack */
+#define X86_BUG_L1TF X86_BUG(18) /* "l1tf" CPU is affected by L1 Terminal Fault */
+#define X86_BUG_MDS X86_BUG(19) /* "mds" CPU is affected by Microarchitectural data sampling */
+#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* "msbds_only" CPU is only affected by the MSDBS variant of BUG_MDS */
+#define X86_BUG_SWAPGS X86_BUG(21) /* "swapgs" CPU is affected by speculation through SWAPGS */
+#define X86_BUG_TAA X86_BUG(22) /* "taa" CPU is affected by TSX Async Abort(TAA) */
+#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* "itlb_multihit" CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_SRBDS X86_BUG(24) /* "srbds" CPU may leak RNG bits if not mitigated */
+#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* "mmio_stale_data" CPU is affected by Processor MMIO Stale Data vulnerabilities */
+#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
+#define X86_BUG_RETBLEED X86_BUG(27) /* "retbleed" CPU is affected by RETBleed */
+#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* "eibrs_pbrsb" EIBRS is vulnerable to Post Barrier RSB Predictions */
+#define X86_BUG_SMT_RSB X86_BUG(29) /* "smt_rsb" CPU is vulnerable to Cross-Thread Return Address Predictions */
+#define X86_BUG_GDS X86_BUG(30) /* "gds" CPU is affected by Gather Data Sampling */
+#define X86_BUG_TDX_PW_MCE X86_BUG(31) /* "tdx_pw_mce" CPU may incur #MC if non-TD software does partial write to TDX private memory */
/* BUG word 2 */
-#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */
-#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
-#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */
-#define X86_BUG_BHI X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */
+#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* "srso" AMD SRSO bug */
+#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */
+#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
+#define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 1dc600fa3ba5..521aad70e41b 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -229,7 +229,8 @@ static inline bool efi_is_native(void)
static inline void *efi64_zero_upper(void *p)
{
- ((u32 *)p)[1] = 0;
+ if (p)
+ ((u32 *)p)[1] = 0;
return p;
}
@@ -315,6 +316,10 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \
((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags))
+/* EFI SMBIOS protocol */
+#define __efi64_argmap_get_next(protocol, smbioshandle, type, record, phandle) \
+ ((protocol), (smbioshandle), (type), efi64_zero_upper(record), \
+ efi64_zero_upper(phandle))
/*
* The macros below handle the plumbing for the argument mapping. To add a
* mapping for a specific EFI method, simply define a macro
@@ -384,24 +389,8 @@ static inline void efi_reserve_boot_services(void)
}
#endif /* CONFIG_EFI */
-#ifdef CONFIG_EFI_FAKE_MEMMAP
-extern void __init efi_fake_memmap_early(void);
-extern void __init efi_fake_memmap(void);
-#else
-static inline void efi_fake_memmap_early(void)
-{
-}
-
-static inline void efi_fake_memmap(void)
-{
-}
-#endif
-
extern int __init efi_memmap_alloc(unsigned int num_entries,
struct efi_memory_map_data *data);
-extern void __efi_memmap_free(u64 phys, unsigned long size,
- unsigned long flags);
-#define __efi_memmap_free __efi_memmap_free
extern int __init efi_memmap_install(struct efi_memory_map_data *data);
extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h
index 7e523bb3d2d3..fb2809b20b0a 100644
--- a/arch/x86/include/asm/entry-common.h
+++ b/arch/x86/include/asm/entry-common.h
@@ -73,19 +73,16 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
#endif
/*
- * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(),
- * but not enough for x86 stack utilization comfort. To keep
- * reasonable stack head room, reduce the maximum offset to 8 bits.
- *
- * The actual entropy will be further reduced by the compiler when
- * applying stack alignment constraints (see cc_stack_align4/8 in
+ * This value will get limited by KSTACK_OFFSET_MAX(), which is 10
+ * bits. The actual entropy will be further reduced by the compiler
+ * when applying stack alignment constraints (see cc_stack_align4/8 in
* arch/x86/Makefile), which will remove the 3 (x86_64) or 2 (ia32)
* low bits from any entropy chosen here.
*
- * Therefore, final stack offset entropy will be 5 (x86_64) or
- * 6 (ia32) bits.
+ * Therefore, final stack offset entropy will be 7 (x86_64) or
+ * 8 (ia32) bits.
*/
- choose_random_kstack_offset(rdtsc() & 0xFF);
+ choose_random_kstack_offset(rdtsc());
}
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h
index 7acf0383be80..906b0d5541e8 100644
--- a/arch/x86/include/asm/extable_fixup_types.h
+++ b/arch/x86/include/asm/extable_fixup_types.h
@@ -36,7 +36,7 @@
#define EX_TYPE_DEFAULT 1
#define EX_TYPE_FAULT 2
#define EX_TYPE_UACCESS 3
-#define EX_TYPE_COPY 4
+/* unused, was: #define EX_TYPE_COPY 4 */
#define EX_TYPE_CLEAR_FS 5
#define EX_TYPE_FPU_RESTORE 6
#define EX_TYPE_BPF 7
diff --git a/arch/x86/include/asm/fb.h b/arch/x86/include/asm/fb.h
deleted file mode 100644
index c3b9582de7ef..000000000000
--- a/arch/x86/include/asm/fb.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_FB_H
-#define _ASM_X86_FB_H
-
-#include <asm/page.h>
-
-struct fb_info;
-
-pgprot_t pgprot_framebuffer(pgprot_t prot,
- unsigned long vm_start, unsigned long vm_end,
- unsigned long offset);
-#define pgprot_framebuffer pgprot_framebuffer
-
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_X86_FB_H */
diff --git a/arch/x86/include/asm/fpu.h b/arch/x86/include/asm/fpu.h
new file mode 100644
index 000000000000..b2743fe19339
--- /dev/null
+++ b/arch/x86/include/asm/fpu.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 SiFive
+ */
+
+#ifndef _ASM_X86_FPU_H
+#define _ASM_X86_FPU_H
+
+#include <asm/fpu/api.h>
+
+#define kernel_fpu_available() true
+
+#endif /* ! _ASM_X86_FPU_H */
diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h
index a2be3aefff9f..f86ad3335529 100644
--- a/arch/x86/include/asm/fpu/api.h
+++ b/arch/x86/include/asm/fpu/api.h
@@ -143,6 +143,9 @@ extern void fpstate_clear_xstate_component(struct fpstate *fps, unsigned int xfe
extern u64 xstate_get_guest_group_perm(void);
+extern void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
+
+
/* KVM specific functions */
extern bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu);
extern void fpu_free_guest_fpstate(struct fpu_guest *gfpu);
diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index ace9aa3b78a3..eb17f31b06d2 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -2,8 +2,8 @@
/*
* FPU data structures:
*/
-#ifndef _ASM_X86_FPU_H
-#define _ASM_X86_FPU_H
+#ifndef _ASM_X86_FPU_TYPES_H
+#define _ASM_X86_FPU_TYPES_H
#include <asm/page_types.h>
@@ -596,4 +596,4 @@ struct fpu_state_config {
/* FPU state configuration information */
extern struct fpu_state_config fpu_kernel_cfg, fpu_user_cfg;
-#endif /* _ASM_X86_FPU_H */
+#endif /* _ASM_X86_FPU_TYPES_H */
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index 897cf02c20b1..0152a81d9b4a 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -20,8 +20,6 @@
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
-#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
-
#ifndef __ASSEMBLY__
extern void __fentry__(void);
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index fbc7722b87d1..c67fa6ad098a 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -44,10 +44,16 @@ typedef struct {
unsigned int irq_hv_reenlightenment_count;
unsigned int hyperv_stimer0_count;
#endif
+#ifdef CONFIG_X86_POSTED_MSI
+ unsigned int posted_msi_notification_count;
+#endif
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+#ifdef CONFIG_X86_POSTED_MSI
+DECLARE_PER_CPU_ALIGNED(struct pi_desc, posted_msi_pi_desc);
+#endif
#define __ARCH_IRQ_STAT
#define inc_irq_stat(member) this_cpu_inc(irq_stat.member)
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 4212c00c9708..9d69f3f8dbab 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -56,17 +56,6 @@ struct stat64 {
unsigned long long st_ino;
} __attribute__((packed));
-#define IA32_STACK_TOP IA32_PAGE_OFFSET
-
-#ifdef __KERNEL__
-struct linux_binprm;
-extern int ia32_setup_arg_pages(struct linux_binprm *bprm,
- unsigned long stack_top, int exec_stack);
-struct mm_struct;
-extern void ia32_pick_mmap_layout(struct mm_struct *mm);
-
-#endif
-
extern bool __ia32_enabled;
static __always_inline bool ia32_enabled(void)
diff --git a/arch/x86/include/asm/ia32_unistd.h b/arch/x86/include/asm/ia32_unistd.h
deleted file mode 100644
index aa065c94ccf5..000000000000
--- a/arch/x86/include/asm/ia32_unistd.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_IA32_UNISTD_H
-#define _ASM_X86_IA32_UNISTD_H
-
-/*
- * This file contains the system call numbers of the ia32 compat ABI,
- * this is for the kernel only.
- */
-#define __SYSCALL_ia32_NR(x) (x)
-#include <asm/unistd_32_ia32.h>
-
-#endif /* _ASM_X86_IA32_UNISTD_H */
diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
index 749c7411d2f1..d4f24499b256 100644
--- a/arch/x86/include/asm/idtentry.h
+++ b/arch/x86/include/asm/idtentry.h
@@ -751,6 +751,12 @@ DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested
# define fred_sysvec_kvm_posted_intr_nested_ipi NULL
#endif
+# ifdef CONFIG_X86_POSTED_MSI
+DECLARE_IDTENTRY_SYSVEC(POSTED_MSI_NOTIFICATION_VECTOR, sysvec_posted_msi_notification);
+#else
+# define fred_sysvec_posted_msi_notification NULL
+# endif
+
#if IS_ENABLED(CONFIG_HYPERV)
DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback);
DECLARE_IDTENTRY_SYSVEC(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment);
diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index b56c5741581a..53e4015242b4 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -35,6 +35,8 @@
#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
#define INAT_PFX_EVEX 15 /* EVEX prefix */
+/* x86-64 REX2 prefix */
+#define INAT_PFX_REX2 16 /* 0xD5 */
#define INAT_LSTPFX_MAX 3
#define INAT_LGCPFX_MAX 11
@@ -50,7 +52,7 @@
/* Legacy prefix */
#define INAT_PFX_OFFS 0
-#define INAT_PFX_BITS 4
+#define INAT_PFX_BITS 5
#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)
#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)
/* Escape opcodes */
@@ -77,6 +79,9 @@
#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
+#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8))
+#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))
+#define INAT_EVEX_SCALABLE (1 << (INAT_FLAG_OFFS + 10))
/* Attribute making macros for attribute tables */
#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
@@ -128,6 +133,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)
return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
}
+static inline int inat_is_rex2_prefix(insn_attr_t attr)
+{
+ return (attr & INAT_PFX_MASK) == INAT_PFX_REX2;
+}
+
static inline int inat_last_prefix_id(insn_attr_t attr)
{
if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
@@ -227,4 +237,9 @@ static inline int inat_must_evex(insn_attr_t attr)
{
return attr & INAT_EVEXONLY;
}
+
+static inline int inat_evex_scalable(insn_attr_t attr)
+{
+ return attr & INAT_EVEX_SCALABLE;
+}
#endif
diff --git a/arch/x86/include/asm/init.h b/arch/x86/include/asm/init.h
index cc9ccf61b6bd..14d72727d7ee 100644
--- a/arch/x86/include/asm/init.h
+++ b/arch/x86/include/asm/init.h
@@ -6,6 +6,7 @@
struct x86_mapping_info {
void *(*alloc_pgt_page)(void *); /* allocate buf for page table */
+ void (*free_pgt_page)(void *, void *); /* free buf for page table */
void *context; /* context for alloc_pgt_page */
unsigned long page_flag; /* page flag for PMD or PUD entry */
unsigned long offset; /* ident mapping offset */
@@ -16,4 +17,6 @@ struct x86_mapping_info {
int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page,
unsigned long pstart, unsigned long pend);
+void kernel_ident_mapping_free(struct x86_mapping_info *info, pgd_t *pgd);
+
#endif /* _ASM_X86_INIT_H */
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index 1b29f58f730f..7152ea809e6a 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -112,10 +112,15 @@ struct insn {
#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
#define X86_SIB_BASE(sib) ((sib) & 0x07)
-#define X86_REX_W(rex) ((rex) & 8)
-#define X86_REX_R(rex) ((rex) & 4)
-#define X86_REX_X(rex) ((rex) & 2)
-#define X86_REX_B(rex) ((rex) & 1)
+#define X86_REX2_M(rex) ((rex) & 0x80) /* REX2 M0 */
+#define X86_REX2_R(rex) ((rex) & 0x40) /* REX2 R4 */
+#define X86_REX2_X(rex) ((rex) & 0x20) /* REX2 X4 */
+#define X86_REX2_B(rex) ((rex) & 0x10) /* REX2 B4 */
+
+#define X86_REX_W(rex) ((rex) & 8) /* REX or REX2 W */
+#define X86_REX_R(rex) ((rex) & 4) /* REX or REX2 R3 */
+#define X86_REX_X(rex) ((rex) & 2) /* REX or REX2 X3 */
+#define X86_REX_B(rex) ((rex) & 1) /* REX or REX2 B3 */
/* VEX bit flags */
#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
@@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)
/* Instruction uses RIP-relative addressing */
extern int insn_rip_relative(struct insn *insn);
+static inline int insn_is_rex2(struct insn *insn)
+{
+ if (!insn->prefixes.got)
+ insn_get_prefixes(insn);
+ return insn->rex_prefix.nbytes == 2;
+}
+
+static inline insn_byte_t insn_rex2_m_bit(struct insn *insn)
+{
+ return X86_REX2_M(insn->rex_prefix.bytes[1]);
+}
+
static inline int insn_is_avx(struct insn *insn)
{
if (!insn->prefixes.got)
@@ -198,6 +215,13 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
return X86_VEX_P(insn->vex_prefix.bytes[2]);
}
+static inline insn_byte_t insn_vex_w_bit(struct insn *insn)
+{
+ if (insn->vex_prefix.nbytes < 3)
+ return 0;
+ return X86_VEX_W(insn->vex_prefix.bytes[2]);
+}
+
/* Get the last prefix id from last prefix or VEX prefix */
static inline int insn_last_prefix_id(struct insn *insn)
{
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
index d0941f4c2724..f81a851c46dc 100644
--- a/arch/x86/include/asm/intel-family.h
+++ b/arch/x86/include/asm/intel-family.h
@@ -40,137 +40,221 @@
* their own names :-(
*/
+#define IFM(_fam, _model) VFM_MAKE(X86_VENDOR_INTEL, _fam, _model)
+
/* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */
#define INTEL_FAM6_ANY X86_MODEL_ANY
+/* Wildcard match for FAM6 so X86_MATCH_VFM(ANY) works */
+#define INTEL_ANY IFM(X86_FAMILY_ANY, X86_MODEL_ANY)
#define INTEL_FAM6_CORE_YONAH 0x0E
+#define INTEL_CORE_YONAH IFM(6, 0x0E)
#define INTEL_FAM6_CORE2_MEROM 0x0F
+#define INTEL_CORE2_MEROM IFM(6, 0x0F)
#define INTEL_FAM6_CORE2_MEROM_L 0x16
+#define INTEL_CORE2_MEROM_L IFM(6, 0x16)
#define INTEL_FAM6_CORE2_PENRYN 0x17
+#define INTEL_CORE2_PENRYN IFM(6, 0x17)
#define INTEL_FAM6_CORE2_DUNNINGTON 0x1D
+#define INTEL_CORE2_DUNNINGTON IFM(6, 0x1D)
#define INTEL_FAM6_NEHALEM 0x1E
+#define INTEL_NEHALEM IFM(6, 0x1E)
#define INTEL_FAM6_NEHALEM_G 0x1F /* Auburndale / Havendale */
+#define INTEL_NEHALEM_G IFM(6, 0x1F) /* Auburndale / Havendale */
#define INTEL_FAM6_NEHALEM_EP 0x1A
+#define INTEL_NEHALEM_EP IFM(6, 0x1A)
#define INTEL_FAM6_NEHALEM_EX 0x2E
+#define INTEL_NEHALEM_EX IFM(6, 0x2E)
#define INTEL_FAM6_WESTMERE 0x25
+#define INTEL_WESTMERE IFM(6, 0x25)
#define INTEL_FAM6_WESTMERE_EP 0x2C
+#define INTEL_WESTMERE_EP IFM(6, 0x2C)
#define INTEL_FAM6_WESTMERE_EX 0x2F
+#define INTEL_WESTMERE_EX IFM(6, 0x2F)
#define INTEL_FAM6_SANDYBRIDGE 0x2A
+#define INTEL_SANDYBRIDGE IFM(6, 0x2A)
#define INTEL_FAM6_SANDYBRIDGE_X 0x2D
+#define INTEL_SANDYBRIDGE_X IFM(6, 0x2D)
#define INTEL_FAM6_IVYBRIDGE 0x3A
+#define INTEL_IVYBRIDGE IFM(6, 0x3A)
#define INTEL_FAM6_IVYBRIDGE_X 0x3E
+#define INTEL_IVYBRIDGE_X IFM(6, 0x3E)
#define INTEL_FAM6_HASWELL 0x3C
+#define INTEL_HASWELL IFM(6, 0x3C)
#define INTEL_FAM6_HASWELL_X 0x3F
+#define INTEL_HASWELL_X IFM(6, 0x3F)
#define INTEL_FAM6_HASWELL_L 0x45
+#define INTEL_HASWELL_L IFM(6, 0x45)
#define INTEL_FAM6_HASWELL_G 0x46
+#define INTEL_HASWELL_G IFM(6, 0x46)
#define INTEL_FAM6_BROADWELL 0x3D
+#define INTEL_BROADWELL IFM(6, 0x3D)
#define INTEL_FAM6_BROADWELL_G 0x47
+#define INTEL_BROADWELL_G IFM(6, 0x47)
#define INTEL_FAM6_BROADWELL_X 0x4F
+#define INTEL_BROADWELL_X IFM(6, 0x4F)
#define INTEL_FAM6_BROADWELL_D 0x56
+#define INTEL_BROADWELL_D IFM(6, 0x56)
#define INTEL_FAM6_SKYLAKE_L 0x4E /* Sky Lake */
+#define INTEL_SKYLAKE_L IFM(6, 0x4E) /* Sky Lake */
#define INTEL_FAM6_SKYLAKE 0x5E /* Sky Lake */
+#define INTEL_SKYLAKE IFM(6, 0x5E) /* Sky Lake */
#define INTEL_FAM6_SKYLAKE_X 0x55 /* Sky Lake */
+#define INTEL_SKYLAKE_X IFM(6, 0x55) /* Sky Lake */
/* CASCADELAKE_X 0x55 Sky Lake -- s: 7 */
/* COOPERLAKE_X 0x55 Sky Lake -- s: 11 */
#define INTEL_FAM6_KABYLAKE_L 0x8E /* Sky Lake */
+#define INTEL_KABYLAKE_L IFM(6, 0x8E) /* Sky Lake */
/* AMBERLAKE_L 0x8E Sky Lake -- s: 9 */
/* COFFEELAKE_L 0x8E Sky Lake -- s: 10 */
/* WHISKEYLAKE_L 0x8E Sky Lake -- s: 11,12 */
#define INTEL_FAM6_KABYLAKE 0x9E /* Sky Lake */
+#define INTEL_KABYLAKE IFM(6, 0x9E) /* Sky Lake */
/* COFFEELAKE 0x9E Sky Lake -- s: 10-13 */
#define INTEL_FAM6_COMETLAKE 0xA5 /* Sky Lake */
+#define INTEL_COMETLAKE IFM(6, 0xA5) /* Sky Lake */
#define INTEL_FAM6_COMETLAKE_L 0xA6 /* Sky Lake */
+#define INTEL_COMETLAKE_L IFM(6, 0xA6) /* Sky Lake */
#define INTEL_FAM6_CANNONLAKE_L 0x66 /* Palm Cove */
+#define INTEL_CANNONLAKE_L IFM(6, 0x66) /* Palm Cove */
#define INTEL_FAM6_ICELAKE_X 0x6A /* Sunny Cove */
+#define INTEL_ICELAKE_X IFM(6, 0x6A) /* Sunny Cove */
#define INTEL_FAM6_ICELAKE_D 0x6C /* Sunny Cove */
+#define INTEL_ICELAKE_D IFM(6, 0x6C) /* Sunny Cove */
#define INTEL_FAM6_ICELAKE 0x7D /* Sunny Cove */
+#define INTEL_ICELAKE IFM(6, 0x7D) /* Sunny Cove */
#define INTEL_FAM6_ICELAKE_L 0x7E /* Sunny Cove */
+#define INTEL_ICELAKE_L IFM(6, 0x7E) /* Sunny Cove */
#define INTEL_FAM6_ICELAKE_NNPI 0x9D /* Sunny Cove */
+#define INTEL_ICELAKE_NNPI IFM(6, 0x9D) /* Sunny Cove */
#define INTEL_FAM6_ROCKETLAKE 0xA7 /* Cypress Cove */
+#define INTEL_ROCKETLAKE IFM(6, 0xA7) /* Cypress Cove */
#define INTEL_FAM6_TIGERLAKE_L 0x8C /* Willow Cove */
+#define INTEL_TIGERLAKE_L IFM(6, 0x8C) /* Willow Cove */
#define INTEL_FAM6_TIGERLAKE 0x8D /* Willow Cove */
+#define INTEL_TIGERLAKE IFM(6, 0x8D) /* Willow Cove */
#define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Golden Cove */
+#define INTEL_SAPPHIRERAPIDS_X IFM(6, 0x8F) /* Golden Cove */
#define INTEL_FAM6_EMERALDRAPIDS_X 0xCF
+#define INTEL_EMERALDRAPIDS_X IFM(6, 0xCF)
#define INTEL_FAM6_GRANITERAPIDS_X 0xAD
+#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD)
#define INTEL_FAM6_GRANITERAPIDS_D 0xAE
+#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
/* "Hybrid" Processors (P-Core/E-Core) */
#define INTEL_FAM6_LAKEFIELD 0x8A /* Sunny Cove / Tremont */
+#define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */
#define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */
+#define INTEL_ALDERLAKE IFM(6, 0x97) /* Golden Cove / Gracemont */
#define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */
+#define INTEL_ALDERLAKE_L IFM(6, 0x9A) /* Golden Cove / Gracemont */
#define INTEL_FAM6_RAPTORLAKE 0xB7 /* Raptor Cove / Enhanced Gracemont */
+#define INTEL_RAPTORLAKE IFM(6, 0xB7) /* Raptor Cove / Enhanced Gracemont */
#define INTEL_FAM6_RAPTORLAKE_P 0xBA
+#define INTEL_RAPTORLAKE_P IFM(6, 0xBA)
#define INTEL_FAM6_RAPTORLAKE_S 0xBF
+#define INTEL_RAPTORLAKE_S IFM(6, 0xBF)
#define INTEL_FAM6_METEORLAKE 0xAC
+#define INTEL_METEORLAKE IFM(6, 0xAC)
#define INTEL_FAM6_METEORLAKE_L 0xAA
+#define INTEL_METEORLAKE_L IFM(6, 0xAA)
#define INTEL_FAM6_ARROWLAKE_H 0xC5
+#define INTEL_ARROWLAKE_H IFM(6, 0xC5)
#define INTEL_FAM6_ARROWLAKE 0xC6
+#define INTEL_ARROWLAKE IFM(6, 0xC6)
#define INTEL_FAM6_ARROWLAKE_U 0xB5
+#define INTEL_ARROWLAKE_U IFM(6, 0xB5)
#define INTEL_FAM6_LUNARLAKE_M 0xBD
+#define INTEL_LUNARLAKE_M IFM(6, 0xBD)
/* "Small Core" Processors (Atom/E-Core) */
#define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */
+#define INTEL_ATOM_BONNELL IFM(6, 0x1C) /* Diamondville, Pineview */
#define INTEL_FAM6_ATOM_BONNELL_MID 0x26 /* Silverthorne, Lincroft */
+#define INTEL_ATOM_BONNELL_MID IFM(6, 0x26) /* Silverthorne, Lincroft */
#define INTEL_FAM6_ATOM_SALTWELL 0x36 /* Cedarview */
+#define INTEL_ATOM_SALTWELL IFM(6, 0x36) /* Cedarview */
#define INTEL_FAM6_ATOM_SALTWELL_MID 0x27 /* Penwell */
+#define INTEL_ATOM_SALTWELL_MID IFM(6, 0x27) /* Penwell */
#define INTEL_FAM6_ATOM_SALTWELL_TABLET 0x35 /* Cloverview */
+#define INTEL_ATOM_SALTWELL_TABLET IFM(6, 0x35) /* Cloverview */
#define INTEL_FAM6_ATOM_SILVERMONT 0x37 /* Bay Trail, Valleyview */
+#define INTEL_ATOM_SILVERMONT IFM(6, 0x37) /* Bay Trail, Valleyview */
#define INTEL_FAM6_ATOM_SILVERMONT_D 0x4D /* Avaton, Rangely */
+#define INTEL_ATOM_SILVERMONT_D IFM(6, 0x4D) /* Avaton, Rangely */
#define INTEL_FAM6_ATOM_SILVERMONT_MID 0x4A /* Merriefield */
+#define INTEL_ATOM_SILVERMONT_MID IFM(6, 0x4A) /* Merriefield */
#define INTEL_FAM6_ATOM_AIRMONT 0x4C /* Cherry Trail, Braswell */
+#define INTEL_ATOM_AIRMONT IFM(6, 0x4C) /* Cherry Trail, Braswell */
#define INTEL_FAM6_ATOM_AIRMONT_MID 0x5A /* Moorefield */
+#define INTEL_ATOM_AIRMONT_MID IFM(6, 0x5A) /* Moorefield */
#define INTEL_FAM6_ATOM_AIRMONT_NP 0x75 /* Lightning Mountain */
+#define INTEL_ATOM_AIRMONT_NP IFM(6, 0x75) /* Lightning Mountain */
#define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */
+#define INTEL_ATOM_GOLDMONT IFM(6, 0x5C) /* Apollo Lake */
#define INTEL_FAM6_ATOM_GOLDMONT_D 0x5F /* Denverton */
+#define INTEL_ATOM_GOLDMONT_D IFM(6, 0x5F) /* Denverton */
/* Note: the micro-architecture is "Goldmont Plus" */
#define INTEL_FAM6_ATOM_GOLDMONT_PLUS 0x7A /* Gemini Lake */
+#define INTEL_ATOM_GOLDMONT_PLUS IFM(6, 0x7A) /* Gemini Lake */
#define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */
+#define INTEL_ATOM_TREMONT_D IFM(6, 0x86) /* Jacobsville */
#define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */
+#define INTEL_ATOM_TREMONT IFM(6, 0x96) /* Elkhart Lake */
#define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */
+#define INTEL_ATOM_TREMONT_L IFM(6, 0x9C) /* Jasper Lake */
#define INTEL_FAM6_ATOM_GRACEMONT 0xBE /* Alderlake N */
+#define INTEL_ATOM_GRACEMONT IFM(6, 0xBE) /* Alderlake N */
#define INTEL_FAM6_ATOM_CRESTMONT_X 0xAF /* Sierra Forest */
+#define INTEL_ATOM_CRESTMONT_X IFM(6, 0xAF) /* Sierra Forest */
#define INTEL_FAM6_ATOM_CRESTMONT 0xB6 /* Grand Ridge */
+#define INTEL_ATOM_CRESTMONT IFM(6, 0xB6) /* Grand Ridge */
#define INTEL_FAM6_ATOM_DARKMONT_X 0xDD /* Clearwater Forest */
+#define INTEL_ATOM_DARKMONT_X IFM(6, 0xDD) /* Clearwater Forest */
/* Xeon Phi */
#define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */
+#define INTEL_XEON_PHI_KNL IFM(6, 0x57) /* Knights Landing */
#define INTEL_FAM6_XEON_PHI_KNM 0x85 /* Knights Mill */
+#define INTEL_XEON_PHI_KNM IFM(6, 0x85) /* Knights Mill */
/* Family 5 */
#define INTEL_FAM5_QUARK_X1000 0x09 /* Quark X1000 SoC */
+#define INTEL_QUARK_X1000 IFM(5, 0x09) /* Quark X1000 SoC */
#endif /* _ASM_X86_INTEL_FAMILY_H */
diff --git a/arch/x86/include/asm/intel_ds.h b/arch/x86/include/asm/intel_ds.h
index 2f9eeb5c3069..5dbeac48a5b9 100644
--- a/arch/x86/include/asm/intel_ds.h
+++ b/arch/x86/include/asm/intel_ds.h
@@ -9,6 +9,7 @@
/* The maximal number of PEBS events: */
#define MAX_PEBS_EVENTS_FMT4 8
#define MAX_PEBS_EVENTS 32
+#define MAX_PEBS_EVENTS_MASK GENMASK_ULL(MAX_PEBS_EVENTS - 1, 0)
#define MAX_FIXED_PEBS_EVENTS 16
/*
diff --git a/arch/x86/include/asm/intel_pconfig.h b/arch/x86/include/asm/intel_pconfig.h
deleted file mode 100644
index 994638ef171b..000000000000
--- a/arch/x86/include/asm/intel_pconfig.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _ASM_X86_INTEL_PCONFIG_H
-#define _ASM_X86_INTEL_PCONFIG_H
-
-#include <asm/asm.h>
-#include <asm/processor.h>
-
-enum pconfig_target {
- INVALID_TARGET = 0,
- MKTME_TARGET = 1,
- PCONFIG_TARGET_NR
-};
-
-int pconfig_target_supported(enum pconfig_target target);
-
-enum pconfig_leaf {
- MKTME_KEY_PROGRAM = 0,
- PCONFIG_LEAF_INVALID,
-};
-
-#define PCONFIG ".byte 0x0f, 0x01, 0xc5"
-
-/* Defines and structure for MKTME_KEY_PROGRAM of PCONFIG instruction */
-
-/* mktme_key_program::keyid_ctrl COMMAND, bits [7:0] */
-#define MKTME_KEYID_SET_KEY_DIRECT 0
-#define MKTME_KEYID_SET_KEY_RANDOM 1
-#define MKTME_KEYID_CLEAR_KEY 2
-#define MKTME_KEYID_NO_ENCRYPT 3
-
-/* mktme_key_program::keyid_ctrl ENC_ALG, bits [23:8] */
-#define MKTME_AES_XTS_128 (1 << 8)
-
-/* Return codes from the PCONFIG MKTME_KEY_PROGRAM */
-#define MKTME_PROG_SUCCESS 0
-#define MKTME_INVALID_PROG_CMD 1
-#define MKTME_ENTROPY_ERROR 2
-#define MKTME_INVALID_KEYID 3
-#define MKTME_INVALID_ENC_ALG 4
-#define MKTME_DEVICE_BUSY 5
-
-/* Hardware requires the structure to be 256 byte aligned. Otherwise #GP(0). */
-struct mktme_key_program {
- u16 keyid;
- u32 keyid_ctrl;
- u8 __rsvd[58];
- u8 key_field_1[64];
- u8 key_field_2[64];
-} __packed __aligned(256);
-
-static inline int mktme_key_program(struct mktme_key_program *key_program)
-{
- unsigned long rax = MKTME_KEY_PROGRAM;
-
- if (!pconfig_target_supported(MKTME_TARGET))
- return -ENXIO;
-
- asm volatile(PCONFIG
- : "=a" (rax), "=b" (key_program)
- : "0" (rax), "1" (key_program)
- : "memory", "cc");
-
- return rax;
-}
-
-#endif /* _ASM_X86_INTEL_PCONFIG_H */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 294cd2a40818..1d60427379c9 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -42,6 +42,7 @@
#include <asm/early_ioremap.h>
#include <asm/pgtable_types.h>
#include <asm/shared/io.h>
+#include <asm/special_insns.h>
#define build_mmio_read(name, size, type, reg, barrier) \
static inline type name(const volatile void __iomem *addr) \
@@ -209,6 +210,23 @@ void memset_io(volatile void __iomem *, int, size_t);
#define memcpy_toio memcpy_toio
#define memset_io memset_io
+#ifdef CONFIG_X86_64
+/*
+ * Commit 0f07496144c2 ("[PATCH] Add faster __iowrite32_copy routine for
+ * x86_64") says that circa 2006 rep movsl is noticeably faster than a copy
+ * loop.
+ */
+static inline void __iowrite32_copy(void __iomem *to, const void *from,
+ size_t count)
+{
+ asm volatile("rep ; movsl"
+ : "=&c"(count), "=&D"(to), "=&S"(from)
+ : "0"(count), "1"(to), "2"(from)
+ : "memory");
+}
+#define __iowrite32_copy __iowrite32_copy
+#endif
+
/*
* ISA space is 'always mapped' on a typical x86 system, no need to
* explicitly ioremap() it. The fact that the ISA IO space is mapped
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 7a2ed154a5e1..5036f13ab69f 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -50,6 +50,13 @@ static inline struct irq_domain *arch_get_ir_parent_domain(void)
return x86_vector_domain;
}
+extern bool enable_posted_msi;
+
+static inline bool posted_msi_supported(void)
+{
+ return enable_posted_msi && irq_remapping_cap(IRQ_POSTING_CAP);
+}
+
#else /* CONFIG_IRQ_REMAP */
static inline bool irq_remapping_cap(enum irq_remap_cap cap) { return 0; }
diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h
index 798183867d78..b71ad173f877 100644
--- a/arch/x86/include/asm/irq_stack.h
+++ b/arch/x86/include/asm/irq_stack.h
@@ -100,7 +100,7 @@
}
#define ASM_CALL_ARG0 \
- "call %P[__func] \n" \
+ "call %c[__func] \n" \
ASM_REACHABLE
#define ASM_CALL_ARG1 \
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index d18bfb238f66..13aea8fc3d45 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -97,10 +97,16 @@
#define LOCAL_TIMER_VECTOR 0xec
+/*
+ * Posted interrupt notification vector for all device MSIs delivered to
+ * the host kernel.
+ */
+#define POSTED_MSI_NOTIFICATION_VECTOR 0xeb
+
#define NR_VECTORS 256
#ifdef CONFIG_X86_LOCAL_APIC
-#define FIRST_SYSTEM_VECTOR LOCAL_TIMER_VECTOR
+#define FIRST_SYSTEM_VECTOR POSTED_MSI_NOTIFICATION_VECTOR
#else
#define FIRST_SYSTEM_VECTOR NR_VECTORS
#endif
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index 8c5ae649d2df..cf7fc2b8e3ce 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -54,6 +54,26 @@ static __always_inline void native_halt(void)
asm volatile("hlt": : :"memory");
}
+static __always_inline int native_irqs_disabled_flags(unsigned long flags)
+{
+ return !(flags & X86_EFLAGS_IF);
+}
+
+static __always_inline unsigned long native_local_irq_save(void)
+{
+ unsigned long flags = native_save_fl();
+
+ native_irq_disable();
+
+ return flags;
+}
+
+static __always_inline void native_local_irq_restore(unsigned long flags)
+{
+ if (!native_irqs_disabled_flags(flags))
+ native_irq_enable();
+}
+
#endif
#ifdef CONFIG_PARAVIRT_XXL
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 91ca9a9ee3a2..ae5482a2f0ca 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -207,18 +207,11 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image);
extern void kdump_nmi_shootdown_cpus(void);
#ifdef CONFIG_CRASH_HOTPLUG
-void arch_crash_handle_hotplug_event(struct kimage *image);
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
#define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
-#ifdef CONFIG_HOTPLUG_CPU
-int arch_crash_hotplug_cpu_support(void);
-#define crash_hotplug_cpu_support arch_crash_hotplug_cpu_support
-#endif
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_crash_hotplug_memory_support(void);
-#define crash_hotplug_memory_support arch_crash_hotplug_memory_support
-#endif
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
+#define arch_crash_hotplug_support arch_crash_hotplug_support
unsigned int arch_crash_get_elfcorehdr_size(void);
#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index 110d7f29ca9a..68ad4f923664 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -9,8 +9,7 @@ BUILD_BUG_ON(1)
* "static_call_update()" calls.
*
* KVM_X86_OP_OPTIONAL() can be used for those functions that can have
- * a NULL definition, for example if "static_call_cond()" will be used
- * at the call sites. KVM_X86_OP_OPTIONAL_RET0() can be used likewise
+ * a NULL definition. KVM_X86_OP_OPTIONAL_RET0() can be used likewise
* to make a definition optional, but in this case the default will
* be __static_call_return0.
*/
@@ -85,7 +84,6 @@ KVM_X86_OP_OPTIONAL(update_cr8_intercept)
KVM_X86_OP(refresh_apicv_exec_ctrl)
KVM_X86_OP_OPTIONAL(hwapic_irr_update)
KVM_X86_OP_OPTIONAL(hwapic_isr_update)
-KVM_X86_OP_OPTIONAL_RET0(guest_apic_has_interrupt)
KVM_X86_OP_OPTIONAL(load_eoi_exitmap)
KVM_X86_OP_OPTIONAL(set_virtual_apic_mode)
KVM_X86_OP_OPTIONAL(set_apic_access_page_addr)
@@ -103,7 +101,6 @@ KVM_X86_OP(write_tsc_multiplier)
KVM_X86_OP(get_exit_info)
KVM_X86_OP(check_intercept)
KVM_X86_OP(handle_exit_irqoff)
-KVM_X86_OP(sched_in)
KVM_X86_OP_OPTIONAL(update_cpu_dirty_logging)
KVM_X86_OP_OPTIONAL(vcpu_blocking)
KVM_X86_OP_OPTIONAL(vcpu_unblocking)
@@ -121,6 +118,7 @@ KVM_X86_OP(enter_smm)
KVM_X86_OP(leave_smm)
KVM_X86_OP(enable_smi_window)
#endif
+KVM_X86_OP_OPTIONAL(dev_get_attr)
KVM_X86_OP_OPTIONAL(mem_enc_ioctl)
KVM_X86_OP_OPTIONAL(mem_enc_register_region)
KVM_X86_OP_OPTIONAL(mem_enc_unregister_region)
@@ -138,6 +136,9 @@ KVM_X86_OP(vcpu_deliver_sipi_vector)
KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons);
KVM_X86_OP_OPTIONAL(get_untagged_addr)
KVM_X86_OP_OPTIONAL(alloc_apic_backing_page)
+KVM_X86_OP_OPTIONAL_RET0(gmem_prepare)
+KVM_X86_OP_OPTIONAL_RET0(private_max_mapping_level)
+KVM_X86_OP_OPTIONAL(gmem_invalidate)
#undef KVM_X86_OP
#undef KVM_X86_OP_OPTIONAL
diff --git a/arch/x86/include/asm/kvm-x86-pmu-ops.h b/arch/x86/include/asm/kvm-x86-pmu-ops.h
index f852b13aeefe..9159bf1a4730 100644
--- a/arch/x86/include/asm/kvm-x86-pmu-ops.h
+++ b/arch/x86/include/asm/kvm-x86-pmu-ops.h
@@ -9,8 +9,7 @@ BUILD_BUG_ON(1)
* "static_call_update()" calls.
*
* KVM_X86_PMU_OP_OPTIONAL() can be used for those functions that can have
- * a NULL definition, for example if "static_call_cond()" will be used
- * at the call sites.
+ * a NULL definition.
*/
KVM_X86_PMU_OP(rdpmc_ecx_to_pmc)
KVM_X86_PMU_OP(msr_idx_to_pmc)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 6efd1497b026..950a03e0181e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -121,6 +121,7 @@
KVM_ARCH_REQ_FLAGS(31, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_HV_TLB_FLUSH \
KVM_ARCH_REQ_FLAGS(32, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
+#define KVM_REQ_UPDATE_PROTECTED_GUEST_STATE KVM_ARCH_REQ(34)
#define CR0_RESERVED_BITS \
(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
@@ -159,7 +160,6 @@
#define KVM_MIN_FREE_MMU_PAGES 5
#define KVM_REFILL_PAGES 25
#define KVM_MAX_CPUID_ENTRIES 256
-#define KVM_NR_FIXED_MTRR_REGION 88
#define KVM_NR_VAR_MTRR 8
#define ASYNC_PF_PER_VCPU 64
@@ -254,28 +254,31 @@ enum x86_intercept_stage;
KVM_GUESTDBG_INJECT_DB | \
KVM_GUESTDBG_BLOCKIRQ)
+#define PFERR_PRESENT_MASK BIT(0)
+#define PFERR_WRITE_MASK BIT(1)
+#define PFERR_USER_MASK BIT(2)
+#define PFERR_RSVD_MASK BIT(3)
+#define PFERR_FETCH_MASK BIT(4)
+#define PFERR_PK_MASK BIT(5)
+#define PFERR_SGX_MASK BIT(15)
+#define PFERR_GUEST_RMP_MASK BIT_ULL(31)
+#define PFERR_GUEST_FINAL_MASK BIT_ULL(32)
+#define PFERR_GUEST_PAGE_MASK BIT_ULL(33)
+#define PFERR_GUEST_ENC_MASK BIT_ULL(34)
+#define PFERR_GUEST_SIZEM_MASK BIT_ULL(35)
+#define PFERR_GUEST_VMPL_MASK BIT_ULL(36)
-#define PFERR_PRESENT_BIT 0
-#define PFERR_WRITE_BIT 1
-#define PFERR_USER_BIT 2
-#define PFERR_RSVD_BIT 3
-#define PFERR_FETCH_BIT 4
-#define PFERR_PK_BIT 5
-#define PFERR_SGX_BIT 15
-#define PFERR_GUEST_FINAL_BIT 32
-#define PFERR_GUEST_PAGE_BIT 33
-#define PFERR_IMPLICIT_ACCESS_BIT 48
-
-#define PFERR_PRESENT_MASK BIT(PFERR_PRESENT_BIT)
-#define PFERR_WRITE_MASK BIT(PFERR_WRITE_BIT)
-#define PFERR_USER_MASK BIT(PFERR_USER_BIT)
-#define PFERR_RSVD_MASK BIT(PFERR_RSVD_BIT)
-#define PFERR_FETCH_MASK BIT(PFERR_FETCH_BIT)
-#define PFERR_PK_MASK BIT(PFERR_PK_BIT)
-#define PFERR_SGX_MASK BIT(PFERR_SGX_BIT)
-#define PFERR_GUEST_FINAL_MASK BIT_ULL(PFERR_GUEST_FINAL_BIT)
-#define PFERR_GUEST_PAGE_MASK BIT_ULL(PFERR_GUEST_PAGE_BIT)
-#define PFERR_IMPLICIT_ACCESS BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT)
+/*
+ * IMPLICIT_ACCESS is a KVM-defined flag used to correctly perform SMAP checks
+ * when emulating instructions that triggers implicit access.
+ */
+#define PFERR_IMPLICIT_ACCESS BIT_ULL(48)
+/*
+ * PRIVATE_ACCESS is a KVM-defined flag us to indicate that a fault occurred
+ * when the guest was accessing private memory.
+ */
+#define PFERR_PRIVATE_ACCESS BIT_ULL(49)
+#define PFERR_SYNTHETIC_MASK (PFERR_IMPLICIT_ACCESS | PFERR_PRIVATE_ACCESS)
#define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \
PFERR_WRITE_MASK | \
@@ -530,12 +533,16 @@ struct kvm_pmc {
};
/* More counters may conflict with other existing Architectural MSRs */
-#define KVM_INTEL_PMC_MAX_GENERIC 8
-#define MSR_ARCH_PERFMON_PERFCTR_MAX (MSR_ARCH_PERFMON_PERFCTR0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
-#define MSR_ARCH_PERFMON_EVENTSEL_MAX (MSR_ARCH_PERFMON_EVENTSEL0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
-#define KVM_PMC_MAX_FIXED 3
-#define MSR_ARCH_PERFMON_FIXED_CTR_MAX (MSR_ARCH_PERFMON_FIXED_CTR0 + KVM_PMC_MAX_FIXED - 1)
-#define KVM_AMD_PMC_MAX_GENERIC 6
+#define KVM_MAX(a, b) ((a) >= (b) ? (a) : (b))
+#define KVM_MAX_NR_INTEL_GP_COUNTERS 8
+#define KVM_MAX_NR_AMD_GP_COUNTERS 6
+#define KVM_MAX_NR_GP_COUNTERS KVM_MAX(KVM_MAX_NR_INTEL_GP_COUNTERS, \
+ KVM_MAX_NR_AMD_GP_COUNTERS)
+
+#define KVM_MAX_NR_INTEL_FIXED_COUTNERS 3
+#define KVM_MAX_NR_AMD_FIXED_COUTNERS 0
+#define KVM_MAX_NR_FIXED_COUNTERS KVM_MAX(KVM_MAX_NR_INTEL_FIXED_COUTNERS, \
+ KVM_MAX_NR_AMD_FIXED_COUTNERS)
struct kvm_pmu {
u8 version;
@@ -543,16 +550,16 @@ struct kvm_pmu {
unsigned nr_arch_fixed_counters;
unsigned available_event_types;
u64 fixed_ctr_ctrl;
- u64 fixed_ctr_ctrl_mask;
+ u64 fixed_ctr_ctrl_rsvd;
u64 global_ctrl;
u64 global_status;
u64 counter_bitmask[2];
- u64 global_ctrl_mask;
- u64 global_status_mask;
+ u64 global_ctrl_rsvd;
+ u64 global_status_rsvd;
u64 reserved_bits;
u64 raw_event_mask;
- struct kvm_pmc gp_counters[KVM_INTEL_PMC_MAX_GENERIC];
- struct kvm_pmc fixed_counters[KVM_PMC_MAX_FIXED];
+ struct kvm_pmc gp_counters[KVM_MAX_NR_GP_COUNTERS];
+ struct kvm_pmc fixed_counters[KVM_MAX_NR_FIXED_COUNTERS];
/*
* Overlay the bitmap with a 64-bit atomic so that all bits can be
@@ -568,9 +575,9 @@ struct kvm_pmu {
u64 ds_area;
u64 pebs_enable;
- u64 pebs_enable_mask;
+ u64 pebs_enable_rsvd;
u64 pebs_data_cfg;
- u64 pebs_data_cfg_mask;
+ u64 pebs_data_cfg_rsvd;
/*
* If a guest counter is cross-mapped to host counter with different
@@ -601,18 +608,12 @@ enum {
KVM_DEBUGREG_WONT_EXIT = 2,
};
-struct kvm_mtrr_range {
- u64 base;
- u64 mask;
- struct list_head node;
-};
-
struct kvm_mtrr {
- struct kvm_mtrr_range var_ranges[KVM_NR_VAR_MTRR];
- mtrr_type fixed_ranges[KVM_NR_FIXED_MTRR_REGION];
+ u64 var[KVM_NR_VAR_MTRR * 2];
+ u64 fixed_64k;
+ u64 fixed_16k[2];
+ u64 fixed_4k[8];
u64 deftype;
-
- struct list_head head;
};
/* Hyper-V SynIC timer */
@@ -994,9 +995,6 @@ struct kvm_vcpu_arch {
u64 msr_kvm_poll_control;
- /* set at EPT violation at this point */
- unsigned long exit_qualification;
-
/* pv related host specific info */
struct {
bool pv_unhalted;
@@ -1207,7 +1205,7 @@ enum kvm_apicv_inhibit {
* APIC acceleration is disabled by a module parameter
* and/or not supported in hardware.
*/
- APICV_INHIBIT_REASON_DISABLE,
+ APICV_INHIBIT_REASON_DISABLED,
/*
* APIC acceleration is inhibited because AutoEOI feature is
@@ -1277,15 +1275,36 @@ enum kvm_apicv_inhibit {
* mapping between logical ID and vCPU.
*/
APICV_INHIBIT_REASON_LOGICAL_ID_ALIASED,
+
+ NR_APICV_INHIBIT_REASONS,
};
+#define __APICV_INHIBIT_REASON(reason) \
+ { BIT(APICV_INHIBIT_REASON_##reason), #reason }
+
+#define APICV_INHIBIT_REASONS \
+ __APICV_INHIBIT_REASON(DISABLED), \
+ __APICV_INHIBIT_REASON(HYPERV), \
+ __APICV_INHIBIT_REASON(ABSENT), \
+ __APICV_INHIBIT_REASON(BLOCKIRQ), \
+ __APICV_INHIBIT_REASON(PHYSICAL_ID_ALIASED), \
+ __APICV_INHIBIT_REASON(APIC_ID_MODIFIED), \
+ __APICV_INHIBIT_REASON(APIC_BASE_MODIFIED), \
+ __APICV_INHIBIT_REASON(NESTED), \
+ __APICV_INHIBIT_REASON(IRQWIN), \
+ __APICV_INHIBIT_REASON(PIT_REINJ), \
+ __APICV_INHIBIT_REASON(SEV), \
+ __APICV_INHIBIT_REASON(LOGICAL_ID_ALIASED)
+
struct kvm_arch {
- unsigned long vm_type;
unsigned long n_used_mmu_pages;
unsigned long n_requested_mmu_pages;
unsigned long n_max_mmu_pages;
unsigned int indirect_shadow_pages;
u8 mmu_valid_gen;
+ u8 vm_type;
+ bool has_private_mem;
+ bool has_protected_state;
struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
struct list_head active_mmu_pages;
struct list_head zapped_obsolete_pages;
@@ -1312,6 +1331,8 @@ struct kvm_arch {
*/
spinlock_t mmu_unsync_pages_lock;
+ u64 shadow_mmio_value;
+
struct iommu_domain *iommu_domain;
bool iommu_noncoherent;
#define __KVM_HAVE_ARCH_NONCOHERENT_DMA
@@ -1360,6 +1381,7 @@ struct kvm_arch {
u32 default_tsc_khz;
bool user_set_tsc;
+ u64 apic_bus_cycle_ns;
seqcount_raw_spinlock_t pvclock_sc;
bool use_master_clock;
@@ -1704,13 +1726,11 @@ struct kvm_x86_ops {
void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
void (*enable_irq_window)(struct kvm_vcpu *vcpu);
void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
- bool (*check_apicv_inhibit_reasons)(enum kvm_apicv_inhibit reason);
const unsigned long required_apicv_inhibits;
bool allow_apicv_in_x2apic_without_x2apic_virtualization;
void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
void (*hwapic_isr_update)(int isr);
- bool (*guest_apic_has_interrupt)(struct kvm_vcpu *vcpu);
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu);
@@ -1745,8 +1765,6 @@ struct kvm_x86_ops {
struct x86_exception *exception);
void (*handle_exit_irqoff)(struct kvm_vcpu *vcpu);
- void (*sched_in)(struct kvm_vcpu *vcpu, int cpu);
-
/*
* Size of the CPU's dirty log buffer, i.e. VMX's PML buffer. A zero
* value indicates CPU dirty logging is unsupported or disabled.
@@ -1779,6 +1797,7 @@ struct kvm_x86_ops {
void (*enable_smi_window)(struct kvm_vcpu *vcpu);
#endif
+ int (*dev_get_attr)(u32 group, u64 attr, u64 *val);
int (*mem_enc_ioctl)(struct kvm *kvm, void __user *argp);
int (*mem_enc_register_region)(struct kvm *kvm, struct kvm_enc_region *argp);
int (*mem_enc_unregister_region)(struct kvm *kvm, struct kvm_enc_region *argp);
@@ -1807,6 +1826,9 @@ struct kvm_x86_ops {
gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu);
+ int (*gmem_prepare)(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
+ void (*gmem_invalidate)(kvm_pfn_t start, kvm_pfn_t end);
+ int (*private_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn);
};
struct kvm_x86_nested_ops {
@@ -1814,7 +1836,7 @@ struct kvm_x86_nested_ops {
bool (*is_exception_vmexit)(struct kvm_vcpu *vcpu, u8 vector,
u32 error_code);
int (*check_events)(struct kvm_vcpu *vcpu);
- bool (*has_events)(struct kvm_vcpu *vcpu);
+ bool (*has_events)(struct kvm_vcpu *vcpu, bool for_injection);
void (*triple_fault)(struct kvm_vcpu *vcpu);
int (*get_state)(struct kvm_vcpu *vcpu,
struct kvm_nested_state __user *user_kvm_nested_state,
@@ -1844,14 +1866,17 @@ struct kvm_arch_async_pf {
gfn_t gfn;
unsigned long cr3;
bool direct_map;
+ u64 error_code;
};
extern u32 __read_mostly kvm_nr_uret_msrs;
-extern u64 __read_mostly host_efer;
extern bool __read_mostly allow_smaller_maxphyaddr;
extern bool __read_mostly enable_apicv;
extern struct kvm_x86_ops kvm_x86_ops;
+#define kvm_x86_call(func) static_call(kvm_x86_##func)
+#define kvm_pmu_call(func) static_call(kvm_x86_pmu_##func)
+
#define KVM_X86_OP(func) \
DECLARE_STATIC_CALL(kvm_x86_##func, *(((struct kvm_x86_ops *)0)->func));
#define KVM_X86_OP_OPTIONAL KVM_X86_OP
@@ -1875,7 +1900,7 @@ void kvm_arch_free_vm(struct kvm *kvm);
static inline int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
{
if (kvm_x86_ops.flush_remote_tlbs &&
- !static_call(kvm_x86_flush_remote_tlbs)(kvm))
+ !kvm_x86_call(flush_remote_tlbs)(kvm))
return 0;
else
return -ENOTSUPP;
@@ -1888,7 +1913,7 @@ static inline int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn,
if (!kvm_x86_ops.flush_remote_tlbs_range)
return -EOPNOTSUPP;
- return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages);
+ return kvm_x86_call(flush_remote_tlbs_range)(kvm, gfn, nr_pages);
}
#endif /* CONFIG_HYPERV */
@@ -1933,6 +1958,7 @@ void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm,
const struct kvm_memory_slot *memslot);
void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen);
void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned long kvm_nr_mmu_pages);
+void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end);
int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
@@ -2140,10 +2166,15 @@ static inline void kvm_clear_apicv_inhibit(struct kvm *kvm,
kvm_set_or_clear_apicv_inhibit(kvm, reason, false);
}
+unsigned long __kvm_emulate_hypercall(struct kvm_vcpu *vcpu, unsigned long nr,
+ unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ int op_64_bit, int cpl);
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code,
void *insn, int insn_len);
+void kvm_mmu_print_sptes(struct kvm_vcpu *vcpu, gpa_t gpa, const char *msg);
void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva);
void kvm_mmu_invalidate_addr(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
u64 addr, unsigned long roots);
@@ -2153,8 +2184,9 @@ void kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd);
void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level,
int tdp_max_root_level, int tdp_huge_page_level);
+
#ifdef CONFIG_KVM_PRIVATE_MEM
-#define kvm_arch_has_private_mem(kvm) ((kvm)->arch.vm_type != KVM_X86_DEFAULT_VM)
+#define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem)
#else
#define kvm_arch_has_private_mem(kvm) false
#endif
@@ -2280,12 +2312,12 @@ static inline bool kvm_irq_is_postable(struct kvm_lapic_irq *irq)
static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
{
- static_call_cond(kvm_x86_vcpu_blocking)(vcpu);
+ kvm_x86_call(vcpu_blocking)(vcpu);
}
static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
{
- static_call_cond(kvm_x86_vcpu_unblocking)(vcpu);
+ kvm_x86_call(vcpu_unblocking)(vcpu);
}
static inline int kvm_cpu_get_apicid(int mps_cpu)
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index de3118305838..3ad29b128943 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -13,6 +13,7 @@
#define MCG_CTL_P BIT_ULL(8) /* MCG_CTL register available */
#define MCG_EXT_P BIT_ULL(9) /* Extended registers available */
#define MCG_CMCI_P BIT_ULL(10) /* CMCI supported */
+#define MCG_SEAM_NR BIT_ULL(12) /* MCG_STATUS_SEAM_NR supported */
#define MCG_EXT_CNT_MASK 0xff0000 /* Number of Extended registers */
#define MCG_EXT_CNT_SHIFT 16
#define MCG_EXT_CNT(c) (((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)
@@ -25,6 +26,7 @@
#define MCG_STATUS_EIPV BIT_ULL(1) /* ip points to correct instruction */
#define MCG_STATUS_MCIP BIT_ULL(2) /* machine check in progress */
#define MCG_STATUS_LMCES BIT_ULL(3) /* LMCE signaled */
+#define MCG_STATUS_SEAM_NR BIT_ULL(12) /* Machine check inside SEAM non-root mode */
/* MCG_EXT_CTL register defines */
#define MCG_EXT_CTL_LMCE_EN BIT_ULL(0) /* Enable LMCE */
@@ -259,7 +261,8 @@ enum mcp_flags {
MCP_DONTLOG = BIT(2), /* only clear, don't log */
MCP_QUEUE_LOG = BIT(3), /* only queue to genpool */
};
-bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
+
+void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
int mce_notify_irq(void);
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index c72c7ff78fcd..d593e52e6635 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -16,10 +16,10 @@ extern int pic_mode;
* Summit or generic (i.e. installer) kernels need lots of bus entries.
* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets.
*/
-#if CONFIG_BASE_SMALL == 0
-# define MAX_MP_BUSSES 260
-#else
+#ifdef CONFIG_BASE_SMALL
# define MAX_MP_BUSSES 32
+#else
+# define MAX_MP_BUSSES 260
#endif
#define MAX_IRQ_SOURCES 256
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index e72c2b872957..82c6a4d350e0 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -170,6 +170,10 @@
* CPU is not affected by Branch
* History Injection.
*/
+#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
+ * IA32_XAPIC_DISABLE_STATUS MSR
+ * supported
+ */
#define ARCH_CAP_PBRSB_NO BIT(24) /*
* Not susceptible to Post-Barrier
* Return Stack Buffer Predictions.
@@ -192,11 +196,6 @@
* File.
*/
-#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
- * IA32_XAPIC_DISABLE_STATUS MSR
- * supported
- */
-
#define MSR_IA32_FLUSH_CMD 0x0000010b
#define L1D_FLUSH BIT(0) /*
* Writeback and invalidate the
@@ -567,6 +566,12 @@
#define MSR_RELOAD_PMC0 0x000014c1
#define MSR_RELOAD_FIXED_CTR0 0x00001309
+/* V6 PMON MSR range */
+#define MSR_IA32_PMC_V6_GP0_CTR 0x1900
+#define MSR_IA32_PMC_V6_GP0_CFG_A 0x1901
+#define MSR_IA32_PMC_V6_FX0_CTR 0x1980
+#define MSR_IA32_PMC_V6_STEP 4
+
/* KeyID partitioning between MKTME and TDX */
#define MSR_IA32_MKTME_KEYID_PARTITIONING 0x00000087
@@ -661,6 +666,8 @@
#define MSR_AMD64_RMP_BASE 0xc0010132
#define MSR_AMD64_RMP_END 0xc0010133
+#define MSR_SVSM_CAA 0xc001f000
+
/* AMD Collaborative Processor Performance Control MSRs */
#define MSR_AMD_CPPC_CAP1 0xc00102b0
#define MSR_AMD_CPPC_ENABLE 0xc00102b1
@@ -782,6 +789,8 @@
#define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
#define MSR_K7_FID_VID_CTL 0xc0010041
#define MSR_K7_FID_VID_STATUS 0xc0010042
+#define MSR_K7_HWCR_CPB_DIS_BIT 25
+#define MSR_K7_HWCR_CPB_DIS BIT_ULL(MSR_K7_HWCR_CPB_DIS_BIT)
/* K6 MSRs */
#define MSR_K6_WHCR 0xc0000082
@@ -1165,6 +1174,7 @@
#define MSR_IA32_QM_CTR 0xc8e
#define MSR_IA32_PQR_ASSOC 0xc8f
#define MSR_IA32_L3_CBM_BASE 0xc90
+#define MSR_RMID_SNC_CONFIG 0xca0
#define MSR_IA32_L2_CBM_BASE 0xd10
#define MSR_IA32_MBA_THRTL_BASE 0xd50
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index cc6b8e087192..af4302d79b59 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -54,7 +54,7 @@ static inline void clear_page(void *page)
clear_page_rep, X86_FEATURE_REP_GOOD,
clear_page_erms, X86_FEATURE_ERMS,
"=D" (page),
- "0" (page)
+ "D" (page)
: "cc", "memory", "rax", "rcx");
}
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index 9da9c8a2f1df..52f1b4ff0cc1 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -31,10 +31,12 @@
#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC
-#define __PHYSICAL_START ALIGN(CONFIG_PHYSICAL_START, \
- CONFIG_PHYSICAL_ALIGN)
+/* Physical address where kernel should be loaded. */
+#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
+ + (CONFIG_PHYSICAL_ALIGN - 1)) \
+ & ~(CONFIG_PHYSICAL_ALIGN - 1))
-#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
+#define __START_KERNEL (__START_KERNEL_map + LOAD_PHYSICAL_ADDR)
#ifdef CONFIG_X86_64
#include <asm/page_64_types.h>
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 44958ebaf626..c55a79d5feae 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -3,30 +3,30 @@
#define _ASM_X86_PERCPU_H
#ifdef CONFIG_X86_64
-#define __percpu_seg gs
-#define __percpu_rel (%rip)
+# define __percpu_seg gs
+# define __percpu_rel (%rip)
#else
-#define __percpu_seg fs
-#define __percpu_rel
+# define __percpu_seg fs
+# define __percpu_rel
#endif
#ifdef __ASSEMBLY__
#ifdef CONFIG_SMP
-#define __percpu %__percpu_seg:
+# define __percpu %__percpu_seg:
#else
-#define __percpu
+# define __percpu
#endif
#define PER_CPU_VAR(var) __percpu(var)__percpu_rel
#ifdef CONFIG_X86_64_SMP
-#define INIT_PER_CPU_VAR(var) init_per_cpu__##var
+# define INIT_PER_CPU_VAR(var) init_per_cpu__##var
#else
-#define INIT_PER_CPU_VAR(var) var
+# define INIT_PER_CPU_VAR(var) var
#endif
-#else /* ...!ASSEMBLY */
+#else /* !__ASSEMBLY__: */
#include <linux/build_bug.h>
#include <linux/stringify.h>
@@ -37,19 +37,19 @@
#ifdef CONFIG_CC_HAS_NAMED_AS
#ifdef __CHECKER__
-#define __seg_gs __attribute__((address_space(__seg_gs)))
-#define __seg_fs __attribute__((address_space(__seg_fs)))
+# define __seg_gs __attribute__((address_space(__seg_gs)))
+# define __seg_fs __attribute__((address_space(__seg_fs)))
#endif
#ifdef CONFIG_X86_64
-#define __percpu_seg_override __seg_gs
+# define __percpu_seg_override __seg_gs
#else
-#define __percpu_seg_override __seg_fs
+# define __percpu_seg_override __seg_fs
#endif
#define __percpu_prefix ""
-#else /* CONFIG_CC_HAS_NAMED_AS */
+#else /* !CONFIG_CC_HAS_NAMED_AS: */
#define __percpu_seg_override
#define __percpu_prefix "%%"__stringify(__percpu_seg)":"
@@ -59,40 +59,30 @@
#define __force_percpu_prefix "%%"__stringify(__percpu_seg)":"
#define __my_cpu_offset this_cpu_read(this_cpu_off)
-#ifdef CONFIG_USE_X86_SEG_SUPPORT
-/*
- * Efficient implementation for cases in which the compiler supports
- * named address spaces. Allows the compiler to perform additional
- * optimizations that can save more instructions.
- */
-#define arch_raw_cpu_ptr(ptr) \
-({ \
- unsigned long tcp_ptr__; \
- tcp_ptr__ = __raw_cpu_read(, this_cpu_off); \
- \
- tcp_ptr__ += (unsigned long)(ptr); \
- (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \
-})
-#else /* CONFIG_USE_X86_SEG_SUPPORT */
/*
* Compared to the generic __my_cpu_offset version, the following
* saves one instruction and avoids clobbering a temp register.
+ *
+ * arch_raw_cpu_ptr should not be used in 32-bit VDSO for a 64-bit
+ * kernel, because games are played with CONFIG_X86_64 there and
+ * sizeof(this_cpu_off) becames 4.
*/
-#define arch_raw_cpu_ptr(ptr) \
-({ \
- unsigned long tcp_ptr__; \
- asm ("mov " __percpu_arg(1) ", %0" \
- : "=r" (tcp_ptr__) \
- : "m" (__my_cpu_var(this_cpu_off))); \
- \
- tcp_ptr__ += (unsigned long)(ptr); \
- (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \
+#ifndef BUILD_VDSO32_64
+#define arch_raw_cpu_ptr(_ptr) \
+({ \
+ unsigned long tcp_ptr__ = raw_cpu_read_long(this_cpu_off); \
+ \
+ tcp_ptr__ += (__force unsigned long)(_ptr); \
+ (typeof(*(_ptr)) __kernel __force *)tcp_ptr__; \
})
-#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+#else
+#define arch_raw_cpu_ptr(_ptr) ({ BUILD_BUG(); (typeof(_ptr))0; })
+#endif
#define PER_CPU_VAR(var) %__percpu_seg:(var)__percpu_rel
-#else /* CONFIG_SMP */
+#else /* !CONFIG_SMP: */
+
#define __percpu_seg_override
#define __percpu_prefix ""
#define __force_percpu_prefix ""
@@ -102,13 +92,13 @@
#endif /* CONFIG_SMP */
#define __my_cpu_type(var) typeof(var) __percpu_seg_override
-#define __my_cpu_ptr(ptr) (__my_cpu_type(*ptr) *)(uintptr_t)(ptr)
-#define __my_cpu_var(var) (*__my_cpu_ptr(&var))
+#define __my_cpu_ptr(ptr) (__my_cpu_type(*(ptr))*)(__force uintptr_t)(ptr)
+#define __my_cpu_var(var) (*__my_cpu_ptr(&(var)))
#define __percpu_arg(x) __percpu_prefix "%" #x
#define __force_percpu_arg(x) __force_percpu_prefix "%" #x
/*
- * Initialized pointers to per-cpu variables needed for the boot
+ * Initialized pointers to per-CPU variables needed for the boot
* processor need to use these macros to get the proper address
* offset from __per_cpu_load on SMP.
*
@@ -118,65 +108,128 @@
extern typeof(var) init_per_cpu_var(var)
#ifdef CONFIG_X86_64_SMP
-#define init_per_cpu_var(var) init_per_cpu__##var
+# define init_per_cpu_var(var) init_per_cpu__##var
#else
-#define init_per_cpu_var(var) var
+# define init_per_cpu_var(var) var
#endif
-/* For arch-specific code, we can use direct single-insn ops (they
- * don't give an lvalue though). */
+/*
+ * For arch-specific code, we can use direct single-insn ops (they
+ * don't give an lvalue though).
+ */
-#define __pcpu_type_1 u8
-#define __pcpu_type_2 u16
-#define __pcpu_type_4 u32
-#define __pcpu_type_8 u64
+#define __pcpu_type_1 u8
+#define __pcpu_type_2 u16
+#define __pcpu_type_4 u32
+#define __pcpu_type_8 u64
-#define __pcpu_cast_1(val) ((u8)(((unsigned long) val) & 0xff))
-#define __pcpu_cast_2(val) ((u16)(((unsigned long) val) & 0xffff))
-#define __pcpu_cast_4(val) ((u32)(((unsigned long) val) & 0xffffffff))
-#define __pcpu_cast_8(val) ((u64)(val))
+#define __pcpu_cast_1(val) ((u8)(((unsigned long) val) & 0xff))
+#define __pcpu_cast_2(val) ((u16)(((unsigned long) val) & 0xffff))
+#define __pcpu_cast_4(val) ((u32)(((unsigned long) val) & 0xffffffff))
+#define __pcpu_cast_8(val) ((u64)(val))
-#define __pcpu_op1_1(op, dst) op "b " dst
-#define __pcpu_op1_2(op, dst) op "w " dst
-#define __pcpu_op1_4(op, dst) op "l " dst
-#define __pcpu_op1_8(op, dst) op "q " dst
+#define __pcpu_op1_1(op, dst) op "b " dst
+#define __pcpu_op1_2(op, dst) op "w " dst
+#define __pcpu_op1_4(op, dst) op "l " dst
+#define __pcpu_op1_8(op, dst) op "q " dst
#define __pcpu_op2_1(op, src, dst) op "b " src ", " dst
#define __pcpu_op2_2(op, src, dst) op "w " src ", " dst
#define __pcpu_op2_4(op, src, dst) op "l " src ", " dst
#define __pcpu_op2_8(op, src, dst) op "q " src ", " dst
-#define __pcpu_reg_1(mod, x) mod "q" (x)
-#define __pcpu_reg_2(mod, x) mod "r" (x)
-#define __pcpu_reg_4(mod, x) mod "r" (x)
-#define __pcpu_reg_8(mod, x) mod "r" (x)
+#define __pcpu_reg_1(mod, x) mod "q" (x)
+#define __pcpu_reg_2(mod, x) mod "r" (x)
+#define __pcpu_reg_4(mod, x) mod "r" (x)
+#define __pcpu_reg_8(mod, x) mod "r" (x)
+
+#define __pcpu_reg_imm_1(x) "qi" (x)
+#define __pcpu_reg_imm_2(x) "ri" (x)
+#define __pcpu_reg_imm_4(x) "ri" (x)
+#define __pcpu_reg_imm_8(x) "re" (x)
+
+#ifdef CONFIG_USE_X86_SEG_SUPPORT
-#define __pcpu_reg_imm_1(x) "qi" (x)
-#define __pcpu_reg_imm_2(x) "ri" (x)
-#define __pcpu_reg_imm_4(x) "ri" (x)
-#define __pcpu_reg_imm_8(x) "re" (x)
+#define __raw_cpu_read(size, qual, pcp) \
+({ \
+ *(qual __my_cpu_type(pcp) *)__my_cpu_ptr(&(pcp)); \
+})
-#define percpu_to_op(size, qual, op, _var, _val) \
+#define __raw_cpu_write(size, qual, pcp, val) \
+do { \
+ *(qual __my_cpu_type(pcp) *)__my_cpu_ptr(&(pcp)) = (val); \
+} while (0)
+
+#define __raw_cpu_read_const(pcp) __raw_cpu_read(, , pcp)
+
+#else /* !CONFIG_USE_X86_SEG_SUPPORT: */
+
+#define __raw_cpu_read(size, qual, _var) \
+({ \
+ __pcpu_type_##size pfo_val__; \
+ \
+ asm qual (__pcpu_op2_##size("mov", __percpu_arg([var]), "%[val]") \
+ : [val] __pcpu_reg_##size("=", pfo_val__) \
+ : [var] "m" (__my_cpu_var(_var))); \
+ \
+ (typeof(_var))(unsigned long) pfo_val__; \
+})
+
+#define __raw_cpu_write(size, qual, _var, _val) \
do { \
__pcpu_type_##size pto_val__ = __pcpu_cast_##size(_val); \
+ \
if (0) { \
typeof(_var) pto_tmp__; \
pto_tmp__ = (_val); \
(void)pto_tmp__; \
} \
- asm qual(__pcpu_op2_##size(op, "%[val]", __percpu_arg([var])) \
- : [var] "+m" (__my_cpu_var(_var)) \
+ asm qual(__pcpu_op2_##size("mov", "%[val]", __percpu_arg([var])) \
+ : [var] "=m" (__my_cpu_var(_var)) \
: [val] __pcpu_reg_imm_##size(pto_val__)); \
} while (0)
+/*
+ * The generic per-CPU infrastrucutre is not suitable for
+ * reading const-qualified variables.
+ */
+#define __raw_cpu_read_const(pcp) ({ BUILD_BUG(); (typeof(pcp))0; })
+
+#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+
+#define __raw_cpu_read_stable(size, _var) \
+({ \
+ __pcpu_type_##size pfo_val__; \
+ \
+ asm(__pcpu_op2_##size("mov", __force_percpu_arg(a[var]), "%[val]") \
+ : [val] __pcpu_reg_##size("=", pfo_val__) \
+ : [var] "i" (&(_var))); \
+ \
+ (typeof(_var))(unsigned long) pfo_val__; \
+})
+
#define percpu_unary_op(size, qual, op, _var) \
({ \
asm qual (__pcpu_op1_##size(op, __percpu_arg([var])) \
: [var] "+m" (__my_cpu_var(_var))); \
})
+#define percpu_binary_op(size, qual, op, _var, _val) \
+do { \
+ __pcpu_type_##size pto_val__ = __pcpu_cast_##size(_val); \
+ \
+ if (0) { \
+ typeof(_var) pto_tmp__; \
+ pto_tmp__ = (_val); \
+ (void)pto_tmp__; \
+ } \
+ asm qual(__pcpu_op2_##size(op, "%[val]", __percpu_arg([var])) \
+ : [var] "+m" (__my_cpu_var(_var)) \
+ : [val] __pcpu_reg_imm_##size(pto_val__)); \
+} while (0)
+
/*
- * Generate a percpu add to memory instruction and optimize code
+ * Generate a per-CPU add to memory instruction and optimize code
* if one is added or subtracted.
*/
#define percpu_add_op(size, qual, var, val) \
@@ -184,6 +237,7 @@ do { \
const int pao_ID__ = (__builtin_constant_p(val) && \
((val) == 1 || (val) == -1)) ? \
(int)(val) : 0; \
+ \
if (0) { \
typeof(var) pao_tmp__; \
pao_tmp__ = (val); \
@@ -194,33 +248,16 @@ do { \
else if (pao_ID__ == -1) \
percpu_unary_op(size, qual, "dec", var); \
else \
- percpu_to_op(size, qual, "add", var, val); \
+ percpu_binary_op(size, qual, "add", var, val); \
} while (0)
-#define percpu_from_op(size, qual, op, _var) \
-({ \
- __pcpu_type_##size pfo_val__; \
- asm qual (__pcpu_op2_##size(op, __percpu_arg([var]), "%[val]") \
- : [val] __pcpu_reg_##size("=", pfo_val__) \
- : [var] "m" (__my_cpu_var(_var))); \
- (typeof(_var))(unsigned long) pfo_val__; \
-})
-
-#define percpu_stable_op(size, op, _var) \
-({ \
- __pcpu_type_##size pfo_val__; \
- asm(__pcpu_op2_##size(op, __force_percpu_arg(a[var]), "%[val]") \
- : [val] __pcpu_reg_##size("=", pfo_val__) \
- : [var] "i" (&(_var))); \
- (typeof(_var))(unsigned long) pfo_val__; \
-})
-
/*
* Add return operation
*/
#define percpu_add_return_op(size, qual, _var, _val) \
({ \
__pcpu_type_##size paro_tmp__ = __pcpu_cast_##size(_val); \
+ \
asm qual (__pcpu_op2_##size("xadd", "%[tmp]", \
__percpu_arg([var])) \
: [tmp] __pcpu_reg_##size("+", paro_tmp__), \
@@ -230,41 +267,48 @@ do { \
})
/*
- * xchg is implemented using cmpxchg without a lock prefix. xchg is
- * expensive due to the implied lock prefix. The processor cannot prefetch
- * cachelines if xchg is used.
+ * raw_cpu_xchg() can use a load-store since
+ * it is not required to be IRQ-safe.
*/
-#define percpu_xchg_op(size, qual, _var, _nval) \
+#define raw_percpu_xchg_op(_var, _nval) \
({ \
- __pcpu_type_##size pxo_old__; \
- __pcpu_type_##size pxo_new__ = __pcpu_cast_##size(_nval); \
- asm qual (__pcpu_op2_##size("mov", __percpu_arg([var]), \
- "%[oval]") \
- "\n1:\t" \
- __pcpu_op2_##size("cmpxchg", "%[nval]", \
- __percpu_arg([var])) \
- "\n\tjnz 1b" \
- : [oval] "=&a" (pxo_old__), \
- [var] "+m" (__my_cpu_var(_var)) \
- : [nval] __pcpu_reg_##size(, pxo_new__) \
- : "memory"); \
- (typeof(_var))(unsigned long) pxo_old__; \
+ typeof(_var) pxo_old__ = raw_cpu_read(_var); \
+ \
+ raw_cpu_write(_var, _nval); \
+ \
+ pxo_old__; \
+})
+
+/*
+ * this_cpu_xchg() is implemented using CMPXCHG without a LOCK prefix.
+ * XCHG is expensive due to the implied LOCK prefix. The processor
+ * cannot prefetch cachelines if XCHG is used.
+ */
+#define this_percpu_xchg_op(_var, _nval) \
+({ \
+ typeof(_var) pxo_old__ = this_cpu_read(_var); \
+ \
+ do { } while (!this_cpu_try_cmpxchg(_var, &pxo_old__, _nval)); \
+ \
+ pxo_old__; \
})
/*
- * cmpxchg has no such implied lock semantics as a result it is much
- * more efficient for cpu local operations.
+ * CMPXCHG has no such implied lock semantics as a result it is much
+ * more efficient for CPU-local operations.
*/
#define percpu_cmpxchg_op(size, qual, _var, _oval, _nval) \
({ \
__pcpu_type_##size pco_old__ = __pcpu_cast_##size(_oval); \
__pcpu_type_##size pco_new__ = __pcpu_cast_##size(_nval); \
+ \
asm qual (__pcpu_op2_##size("cmpxchg", "%[nval]", \
__percpu_arg([var])) \
: [oval] "+a" (pco_old__), \
[var] "+m" (__my_cpu_var(_var)) \
: [nval] __pcpu_reg_##size(, pco_new__) \
: "memory"); \
+ \
(typeof(_var))(unsigned long) pco_old__; \
})
@@ -274,6 +318,7 @@ do { \
__pcpu_type_##size *pco_oval__ = (__pcpu_type_##size *)(_ovalp); \
__pcpu_type_##size pco_old__ = *pco_oval__; \
__pcpu_type_##size pco_new__ = __pcpu_cast_##size(_nval); \
+ \
asm qual (__pcpu_op2_##size("cmpxchg", "%[nval]", \
__percpu_arg([var])) \
CC_SET(z) \
@@ -284,10 +329,12 @@ do { \
: "memory"); \
if (unlikely(!success)) \
*pco_oval__ = pco_old__; \
+ \
likely(success); \
})
#if defined(CONFIG_X86_32) && !defined(CONFIG_UML)
+
#define percpu_cmpxchg64_op(size, qual, _var, _oval, _nval) \
({ \
union { \
@@ -313,8 +360,8 @@ do { \
old__.var; \
})
-#define raw_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg64_op(8, , pcp, oval, nval)
-#define this_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg64_op(8, volatile, pcp, oval, nval)
+#define raw_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg64_op(8, , pcp, oval, nval)
+#define this_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg64_op(8, volatile, pcp, oval, nval)
#define percpu_try_cmpxchg64_op(size, qual, _var, _ovalp, _nval) \
({ \
@@ -343,16 +390,18 @@ do { \
: "memory"); \
if (unlikely(!success)) \
*_oval = old__.var; \
+ \
likely(success); \
})
#define raw_cpu_try_cmpxchg64(pcp, ovalp, nval) percpu_try_cmpxchg64_op(8, , pcp, ovalp, nval)
#define this_cpu_try_cmpxchg64(pcp, ovalp, nval) percpu_try_cmpxchg64_op(8, volatile, pcp, ovalp, nval)
-#endif
+
+#endif /* defined(CONFIG_X86_32) && !defined(CONFIG_UML) */
#ifdef CONFIG_X86_64
-#define raw_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg_op(8, , pcp, oval, nval);
-#define this_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg_op(8, volatile, pcp, oval, nval);
+#define raw_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg_op(8, , pcp, oval, nval);
+#define this_cpu_cmpxchg64(pcp, oval, nval) percpu_cmpxchg_op(8, volatile, pcp, oval, nval);
#define raw_cpu_try_cmpxchg64(pcp, ovalp, nval) percpu_try_cmpxchg_op(8, , pcp, ovalp, nval);
#define this_cpu_try_cmpxchg64(pcp, ovalp, nval) percpu_try_cmpxchg_op(8, volatile, pcp, ovalp, nval);
@@ -382,8 +431,8 @@ do { \
old__.var; \
})
-#define raw_cpu_cmpxchg128(pcp, oval, nval) percpu_cmpxchg128_op(16, , pcp, oval, nval)
-#define this_cpu_cmpxchg128(pcp, oval, nval) percpu_cmpxchg128_op(16, volatile, pcp, oval, nval)
+#define raw_cpu_cmpxchg128(pcp, oval, nval) percpu_cmpxchg128_op(16, , pcp, oval, nval)
+#define this_cpu_cmpxchg128(pcp, oval, nval) percpu_cmpxchg128_op(16, volatile, pcp, oval, nval)
#define percpu_try_cmpxchg128_op(size, qual, _var, _ovalp, _nval) \
({ \
@@ -417,199 +466,151 @@ do { \
#define raw_cpu_try_cmpxchg128(pcp, ovalp, nval) percpu_try_cmpxchg128_op(16, , pcp, ovalp, nval)
#define this_cpu_try_cmpxchg128(pcp, ovalp, nval) percpu_try_cmpxchg128_op(16, volatile, pcp, ovalp, nval)
-#endif
+
+#endif /* CONFIG_X86_64 */
+
+#define raw_cpu_read_1(pcp) __raw_cpu_read(1, , pcp)
+#define raw_cpu_read_2(pcp) __raw_cpu_read(2, , pcp)
+#define raw_cpu_read_4(pcp) __raw_cpu_read(4, , pcp)
+#define raw_cpu_write_1(pcp, val) __raw_cpu_write(1, , pcp, val)
+#define raw_cpu_write_2(pcp, val) __raw_cpu_write(2, , pcp, val)
+#define raw_cpu_write_4(pcp, val) __raw_cpu_write(4, , pcp, val)
+
+#define this_cpu_read_1(pcp) __raw_cpu_read(1, volatile, pcp)
+#define this_cpu_read_2(pcp) __raw_cpu_read(2, volatile, pcp)
+#define this_cpu_read_4(pcp) __raw_cpu_read(4, volatile, pcp)
+#define this_cpu_write_1(pcp, val) __raw_cpu_write(1, volatile, pcp, val)
+#define this_cpu_write_2(pcp, val) __raw_cpu_write(2, volatile, pcp, val)
+#define this_cpu_write_4(pcp, val) __raw_cpu_write(4, volatile, pcp, val)
+
+#define this_cpu_read_stable_1(pcp) __raw_cpu_read_stable(1, pcp)
+#define this_cpu_read_stable_2(pcp) __raw_cpu_read_stable(2, pcp)
+#define this_cpu_read_stable_4(pcp) __raw_cpu_read_stable(4, pcp)
+
+#define raw_cpu_add_1(pcp, val) percpu_add_op(1, , (pcp), val)
+#define raw_cpu_add_2(pcp, val) percpu_add_op(2, , (pcp), val)
+#define raw_cpu_add_4(pcp, val) percpu_add_op(4, , (pcp), val)
+#define raw_cpu_and_1(pcp, val) percpu_binary_op(1, , "and", (pcp), val)
+#define raw_cpu_and_2(pcp, val) percpu_binary_op(2, , "and", (pcp), val)
+#define raw_cpu_and_4(pcp, val) percpu_binary_op(4, , "and", (pcp), val)
+#define raw_cpu_or_1(pcp, val) percpu_binary_op(1, , "or", (pcp), val)
+#define raw_cpu_or_2(pcp, val) percpu_binary_op(2, , "or", (pcp), val)
+#define raw_cpu_or_4(pcp, val) percpu_binary_op(4, , "or", (pcp), val)
+#define raw_cpu_xchg_1(pcp, val) raw_percpu_xchg_op(pcp, val)
+#define raw_cpu_xchg_2(pcp, val) raw_percpu_xchg_op(pcp, val)
+#define raw_cpu_xchg_4(pcp, val) raw_percpu_xchg_op(pcp, val)
+
+#define this_cpu_add_1(pcp, val) percpu_add_op(1, volatile, (pcp), val)
+#define this_cpu_add_2(pcp, val) percpu_add_op(2, volatile, (pcp), val)
+#define this_cpu_add_4(pcp, val) percpu_add_op(4, volatile, (pcp), val)
+#define this_cpu_and_1(pcp, val) percpu_binary_op(1, volatile, "and", (pcp), val)
+#define this_cpu_and_2(pcp, val) percpu_binary_op(2, volatile, "and", (pcp), val)
+#define this_cpu_and_4(pcp, val) percpu_binary_op(4, volatile, "and", (pcp), val)
+#define this_cpu_or_1(pcp, val) percpu_binary_op(1, volatile, "or", (pcp), val)
+#define this_cpu_or_2(pcp, val) percpu_binary_op(2, volatile, "or", (pcp), val)
+#define this_cpu_or_4(pcp, val) percpu_binary_op(4, volatile, "or", (pcp), val)
+#define this_cpu_xchg_1(pcp, nval) this_percpu_xchg_op(pcp, nval)
+#define this_cpu_xchg_2(pcp, nval) this_percpu_xchg_op(pcp, nval)
+#define this_cpu_xchg_4(pcp, nval) this_percpu_xchg_op(pcp, nval)
+
+#define raw_cpu_add_return_1(pcp, val) percpu_add_return_op(1, , pcp, val)
+#define raw_cpu_add_return_2(pcp, val) percpu_add_return_op(2, , pcp, val)
+#define raw_cpu_add_return_4(pcp, val) percpu_add_return_op(4, , pcp, val)
+#define raw_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(1, , pcp, oval, nval)
+#define raw_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(2, , pcp, oval, nval)
+#define raw_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(4, , pcp, oval, nval)
+#define raw_cpu_try_cmpxchg_1(pcp, ovalp, nval) percpu_try_cmpxchg_op(1, , pcp, ovalp, nval)
+#define raw_cpu_try_cmpxchg_2(pcp, ovalp, nval) percpu_try_cmpxchg_op(2, , pcp, ovalp, nval)
+#define raw_cpu_try_cmpxchg_4(pcp, ovalp, nval) percpu_try_cmpxchg_op(4, , pcp, ovalp, nval)
+
+#define this_cpu_add_return_1(pcp, val) percpu_add_return_op(1, volatile, pcp, val)
+#define this_cpu_add_return_2(pcp, val) percpu_add_return_op(2, volatile, pcp, val)
+#define this_cpu_add_return_4(pcp, val) percpu_add_return_op(4, volatile, pcp, val)
+#define this_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(1, volatile, pcp, oval, nval)
+#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(2, volatile, pcp, oval, nval)
+#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(4, volatile, pcp, oval, nval)
+#define this_cpu_try_cmpxchg_1(pcp, ovalp, nval) percpu_try_cmpxchg_op(1, volatile, pcp, ovalp, nval)
+#define this_cpu_try_cmpxchg_2(pcp, ovalp, nval) percpu_try_cmpxchg_op(2, volatile, pcp, ovalp, nval)
+#define this_cpu_try_cmpxchg_4(pcp, ovalp, nval) percpu_try_cmpxchg_op(4, volatile, pcp, ovalp, nval)
/*
- * this_cpu_read() makes gcc load the percpu variable every time it is
- * accessed while this_cpu_read_stable() allows the value to be cached.
- * this_cpu_read_stable() is more efficient and can be used if its value
- * is guaranteed to be valid across cpus. The current users include
- * pcpu_hot.current_task and pcpu_hot.top_of_stack, both of which are
- * actually per-thread variables implemented as per-CPU variables and
- * thus stable for the duration of the respective task.
+ * Per-CPU atomic 64-bit operations are only available under 64-bit kernels.
+ * 32-bit kernels must fall back to generic operations.
*/
-#define this_cpu_read_stable_1(pcp) percpu_stable_op(1, "mov", pcp)
-#define this_cpu_read_stable_2(pcp) percpu_stable_op(2, "mov", pcp)
-#define this_cpu_read_stable_4(pcp) percpu_stable_op(4, "mov", pcp)
-#define this_cpu_read_stable_8(pcp) percpu_stable_op(8, "mov", pcp)
-#define this_cpu_read_stable(pcp) __pcpu_size_call_return(this_cpu_read_stable_, pcp)
+#ifdef CONFIG_X86_64
-#ifdef CONFIG_USE_X86_SEG_SUPPORT
+#define raw_cpu_read_8(pcp) __raw_cpu_read(8, , pcp)
+#define raw_cpu_write_8(pcp, val) __raw_cpu_write(8, , pcp, val)
-#define __raw_cpu_read(qual, pcp) \
-({ \
- *(qual __my_cpu_type(pcp) *)__my_cpu_ptr(&(pcp)); \
-})
-
-#define __raw_cpu_write(qual, pcp, val) \
-do { \
- *(qual __my_cpu_type(pcp) *)__my_cpu_ptr(&(pcp)) = (val); \
-} while (0)
+#define this_cpu_read_8(pcp) __raw_cpu_read(8, volatile, pcp)
+#define this_cpu_write_8(pcp, val) __raw_cpu_write(8, volatile, pcp, val)
-#define raw_cpu_read_1(pcp) __raw_cpu_read(, pcp)
-#define raw_cpu_read_2(pcp) __raw_cpu_read(, pcp)
-#define raw_cpu_read_4(pcp) __raw_cpu_read(, pcp)
-#define raw_cpu_write_1(pcp, val) __raw_cpu_write(, pcp, val)
-#define raw_cpu_write_2(pcp, val) __raw_cpu_write(, pcp, val)
-#define raw_cpu_write_4(pcp, val) __raw_cpu_write(, pcp, val)
+#define this_cpu_read_stable_8(pcp) __raw_cpu_read_stable(8, pcp)
-#define this_cpu_read_1(pcp) __raw_cpu_read(volatile, pcp)
-#define this_cpu_read_2(pcp) __raw_cpu_read(volatile, pcp)
-#define this_cpu_read_4(pcp) __raw_cpu_read(volatile, pcp)
-#define this_cpu_write_1(pcp, val) __raw_cpu_write(volatile, pcp, val)
-#define this_cpu_write_2(pcp, val) __raw_cpu_write(volatile, pcp, val)
-#define this_cpu_write_4(pcp, val) __raw_cpu_write(volatile, pcp, val)
+#define raw_cpu_add_8(pcp, val) percpu_add_op(8, , (pcp), val)
+#define raw_cpu_and_8(pcp, val) percpu_binary_op(8, , "and", (pcp), val)
+#define raw_cpu_or_8(pcp, val) percpu_binary_op(8, , "or", (pcp), val)
+#define raw_cpu_add_return_8(pcp, val) percpu_add_return_op(8, , pcp, val)
+#define raw_cpu_xchg_8(pcp, nval) raw_percpu_xchg_op(pcp, nval)
+#define raw_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(8, , pcp, oval, nval)
+#define raw_cpu_try_cmpxchg_8(pcp, ovalp, nval) percpu_try_cmpxchg_op(8, , pcp, ovalp, nval)
-#ifdef CONFIG_X86_64
-#define raw_cpu_read_8(pcp) __raw_cpu_read(, pcp)
-#define raw_cpu_write_8(pcp, val) __raw_cpu_write(, pcp, val)
+#define this_cpu_add_8(pcp, val) percpu_add_op(8, volatile, (pcp), val)
+#define this_cpu_and_8(pcp, val) percpu_binary_op(8, volatile, "and", (pcp), val)
+#define this_cpu_or_8(pcp, val) percpu_binary_op(8, volatile, "or", (pcp), val)
+#define this_cpu_add_return_8(pcp, val) percpu_add_return_op(8, volatile, pcp, val)
+#define this_cpu_xchg_8(pcp, nval) this_percpu_xchg_op(pcp, nval)
+#define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(8, volatile, pcp, oval, nval)
+#define this_cpu_try_cmpxchg_8(pcp, ovalp, nval) percpu_try_cmpxchg_op(8, volatile, pcp, ovalp, nval)
-#define this_cpu_read_8(pcp) __raw_cpu_read(volatile, pcp)
-#define this_cpu_write_8(pcp, val) __raw_cpu_write(volatile, pcp, val)
-#endif
+#define raw_cpu_read_long(pcp) raw_cpu_read_8(pcp)
-#define this_cpu_read_const(pcp) __raw_cpu_read(, pcp)
-#else /* CONFIG_USE_X86_SEG_SUPPORT */
+#else /* !CONFIG_X86_64: */
-#define raw_cpu_read_1(pcp) percpu_from_op(1, , "mov", pcp)
-#define raw_cpu_read_2(pcp) percpu_from_op(2, , "mov", pcp)
-#define raw_cpu_read_4(pcp) percpu_from_op(4, , "mov", pcp)
-#define raw_cpu_write_1(pcp, val) percpu_to_op(1, , "mov", (pcp), val)
-#define raw_cpu_write_2(pcp, val) percpu_to_op(2, , "mov", (pcp), val)
-#define raw_cpu_write_4(pcp, val) percpu_to_op(4, , "mov", (pcp), val)
+/* There is no generic 64-bit read stable operation for 32-bit targets. */
+#define this_cpu_read_stable_8(pcp) ({ BUILD_BUG(); (typeof(pcp))0; })
-#define this_cpu_read_1(pcp) percpu_from_op(1, volatile, "mov", pcp)
-#define this_cpu_read_2(pcp) percpu_from_op(2, volatile, "mov", pcp)
-#define this_cpu_read_4(pcp) percpu_from_op(4, volatile, "mov", pcp)
-#define this_cpu_write_1(pcp, val) percpu_to_op(1, volatile, "mov", (pcp), val)
-#define this_cpu_write_2(pcp, val) percpu_to_op(2, volatile, "mov", (pcp), val)
-#define this_cpu_write_4(pcp, val) percpu_to_op(4, volatile, "mov", (pcp), val)
+#define raw_cpu_read_long(pcp) raw_cpu_read_4(pcp)
-#ifdef CONFIG_X86_64
-#define raw_cpu_read_8(pcp) percpu_from_op(8, , "mov", pcp)
-#define raw_cpu_write_8(pcp, val) percpu_to_op(8, , "mov", (pcp), val)
+#endif /* CONFIG_X86_64 */
-#define this_cpu_read_8(pcp) percpu_from_op(8, volatile, "mov", pcp)
-#define this_cpu_write_8(pcp, val) percpu_to_op(8, volatile, "mov", (pcp), val)
-#endif
+#define this_cpu_read_const(pcp) __raw_cpu_read_const(pcp)
/*
- * The generic per-cpu infrastrucutre is not suitable for
- * reading const-qualified variables.
+ * this_cpu_read() makes the compiler load the per-CPU variable every time
+ * it is accessed while this_cpu_read_stable() allows the value to be cached.
+ * this_cpu_read_stable() is more efficient and can be used if its value
+ * is guaranteed to be valid across CPUs. The current users include
+ * pcpu_hot.current_task and pcpu_hot.top_of_stack, both of which are
+ * actually per-thread variables implemented as per-CPU variables and
+ * thus stable for the duration of the respective task.
*/
-#define this_cpu_read_const(pcp) ({ BUILD_BUG(); (typeof(pcp))0; })
-#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+#define this_cpu_read_stable(pcp) __pcpu_size_call_return(this_cpu_read_stable_, pcp)
-#define raw_cpu_add_1(pcp, val) percpu_add_op(1, , (pcp), val)
-#define raw_cpu_add_2(pcp, val) percpu_add_op(2, , (pcp), val)
-#define raw_cpu_add_4(pcp, val) percpu_add_op(4, , (pcp), val)
-#define raw_cpu_and_1(pcp, val) percpu_to_op(1, , "and", (pcp), val)
-#define raw_cpu_and_2(pcp, val) percpu_to_op(2, , "and", (pcp), val)
-#define raw_cpu_and_4(pcp, val) percpu_to_op(4, , "and", (pcp), val)
-#define raw_cpu_or_1(pcp, val) percpu_to_op(1, , "or", (pcp), val)
-#define raw_cpu_or_2(pcp, val) percpu_to_op(2, , "or", (pcp), val)
-#define raw_cpu_or_4(pcp, val) percpu_to_op(4, , "or", (pcp), val)
-
-/*
- * raw_cpu_xchg() can use a load-store since it is not required to be
- * IRQ-safe.
- */
-#define raw_percpu_xchg_op(var, nval) \
+#define x86_this_cpu_constant_test_bit(_nr, _var) \
({ \
- typeof(var) pxo_ret__ = raw_cpu_read(var); \
- raw_cpu_write(var, (nval)); \
- pxo_ret__; \
+ unsigned long __percpu *addr__ = \
+ (unsigned long __percpu *)&(_var) + ((_nr) / BITS_PER_LONG); \
+ \
+ !!((1UL << ((_nr) % BITS_PER_LONG)) & raw_cpu_read(*addr__)); \
})
-#define raw_cpu_xchg_1(pcp, val) raw_percpu_xchg_op(pcp, val)
-#define raw_cpu_xchg_2(pcp, val) raw_percpu_xchg_op(pcp, val)
-#define raw_cpu_xchg_4(pcp, val) raw_percpu_xchg_op(pcp, val)
-
-#define this_cpu_add_1(pcp, val) percpu_add_op(1, volatile, (pcp), val)
-#define this_cpu_add_2(pcp, val) percpu_add_op(2, volatile, (pcp), val)
-#define this_cpu_add_4(pcp, val) percpu_add_op(4, volatile, (pcp), val)
-#define this_cpu_and_1(pcp, val) percpu_to_op(1, volatile, "and", (pcp), val)
-#define this_cpu_and_2(pcp, val) percpu_to_op(2, volatile, "and", (pcp), val)
-#define this_cpu_and_4(pcp, val) percpu_to_op(4, volatile, "and", (pcp), val)
-#define this_cpu_or_1(pcp, val) percpu_to_op(1, volatile, "or", (pcp), val)
-#define this_cpu_or_2(pcp, val) percpu_to_op(2, volatile, "or", (pcp), val)
-#define this_cpu_or_4(pcp, val) percpu_to_op(4, volatile, "or", (pcp), val)
-#define this_cpu_xchg_1(pcp, nval) percpu_xchg_op(1, volatile, pcp, nval)
-#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(2, volatile, pcp, nval)
-#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(4, volatile, pcp, nval)
-
-#define raw_cpu_add_return_1(pcp, val) percpu_add_return_op(1, , pcp, val)
-#define raw_cpu_add_return_2(pcp, val) percpu_add_return_op(2, , pcp, val)
-#define raw_cpu_add_return_4(pcp, val) percpu_add_return_op(4, , pcp, val)
-#define raw_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(1, , pcp, oval, nval)
-#define raw_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(2, , pcp, oval, nval)
-#define raw_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(4, , pcp, oval, nval)
-#define raw_cpu_try_cmpxchg_1(pcp, ovalp, nval) percpu_try_cmpxchg_op(1, , pcp, ovalp, nval)
-#define raw_cpu_try_cmpxchg_2(pcp, ovalp, nval) percpu_try_cmpxchg_op(2, , pcp, ovalp, nval)
-#define raw_cpu_try_cmpxchg_4(pcp, ovalp, nval) percpu_try_cmpxchg_op(4, , pcp, ovalp, nval)
-
-#define this_cpu_add_return_1(pcp, val) percpu_add_return_op(1, volatile, pcp, val)
-#define this_cpu_add_return_2(pcp, val) percpu_add_return_op(2, volatile, pcp, val)
-#define this_cpu_add_return_4(pcp, val) percpu_add_return_op(4, volatile, pcp, val)
-#define this_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(1, volatile, pcp, oval, nval)
-#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(2, volatile, pcp, oval, nval)
-#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(4, volatile, pcp, oval, nval)
-#define this_cpu_try_cmpxchg_1(pcp, ovalp, nval) percpu_try_cmpxchg_op(1, volatile, pcp, ovalp, nval)
-#define this_cpu_try_cmpxchg_2(pcp, ovalp, nval) percpu_try_cmpxchg_op(2, volatile, pcp, ovalp, nval)
-#define this_cpu_try_cmpxchg_4(pcp, ovalp, nval) percpu_try_cmpxchg_op(4, volatile, pcp, ovalp, nval)
-
-/*
- * Per cpu atomic 64 bit operations are only available under 64 bit.
- * 32 bit must fall back to generic operations.
- */
-#ifdef CONFIG_X86_64
-#define raw_cpu_add_8(pcp, val) percpu_add_op(8, , (pcp), val)
-#define raw_cpu_and_8(pcp, val) percpu_to_op(8, , "and", (pcp), val)
-#define raw_cpu_or_8(pcp, val) percpu_to_op(8, , "or", (pcp), val)
-#define raw_cpu_add_return_8(pcp, val) percpu_add_return_op(8, , pcp, val)
-#define raw_cpu_xchg_8(pcp, nval) raw_percpu_xchg_op(pcp, nval)
-#define raw_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(8, , pcp, oval, nval)
-#define raw_cpu_try_cmpxchg_8(pcp, ovalp, nval) percpu_try_cmpxchg_op(8, , pcp, ovalp, nval)
-
-#define this_cpu_add_8(pcp, val) percpu_add_op(8, volatile, (pcp), val)
-#define this_cpu_and_8(pcp, val) percpu_to_op(8, volatile, "and", (pcp), val)
-#define this_cpu_or_8(pcp, val) percpu_to_op(8, volatile, "or", (pcp), val)
-#define this_cpu_add_return_8(pcp, val) percpu_add_return_op(8, volatile, pcp, val)
-#define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(8, volatile, pcp, nval)
-#define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(8, volatile, pcp, oval, nval)
-#define this_cpu_try_cmpxchg_8(pcp, ovalp, nval) percpu_try_cmpxchg_op(8, volatile, pcp, ovalp, nval)
-#endif
-
-static __always_inline bool x86_this_cpu_constant_test_bit(unsigned int nr,
- const unsigned long __percpu *addr)
-{
- unsigned long __percpu *a =
- (unsigned long __percpu *)addr + nr / BITS_PER_LONG;
-
-#ifdef CONFIG_X86_64
- return ((1UL << (nr % BITS_PER_LONG)) & raw_cpu_read_8(*a)) != 0;
-#else
- return ((1UL << (nr % BITS_PER_LONG)) & raw_cpu_read_4(*a)) != 0;
-#endif
-}
-
-static inline bool x86_this_cpu_variable_test_bit(int nr,
- const unsigned long __percpu *addr)
-{
- bool oldbit;
-
- asm volatile("btl "__percpu_arg(2)",%1"
- CC_SET(c)
- : CC_OUT(c) (oldbit)
- : "m" (*__my_cpu_ptr((unsigned long __percpu *)(addr))), "Ir" (nr));
-
- return oldbit;
-}
+#define x86_this_cpu_variable_test_bit(_nr, _var) \
+({ \
+ bool oldbit; \
+ \
+ asm volatile("btl %[nr], " __percpu_arg([var]) \
+ CC_SET(c) \
+ : CC_OUT(c) (oldbit) \
+ : [var] "m" (__my_cpu_var(_var)), \
+ [nr] "rI" (_nr)); \
+ oldbit; \
+})
-#define x86_this_cpu_test_bit(nr, addr) \
- (__builtin_constant_p((nr)) \
- ? x86_this_cpu_constant_test_bit((nr), (addr)) \
- : x86_this_cpu_variable_test_bit((nr), (addr)))
+#define x86_this_cpu_test_bit(_nr, _var) \
+ (__builtin_constant_p(_nr) \
+ ? x86_this_cpu_constant_test_bit(_nr, _var) \
+ : x86_this_cpu_variable_test_bit(_nr, _var))
#include <asm-generic/percpu.h>
@@ -639,46 +640,47 @@ DECLARE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off);
{ [0 ... NR_CPUS-1] = _initvalue }; \
__typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map
-#define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \
+#define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \
EXPORT_PER_CPU_SYMBOL(_name)
-#define DECLARE_EARLY_PER_CPU(_type, _name) \
- DECLARE_PER_CPU(_type, _name); \
- extern __typeof__(_type) *_name##_early_ptr; \
+#define DECLARE_EARLY_PER_CPU(_type, _name) \
+ DECLARE_PER_CPU(_type, _name); \
+ extern __typeof__(_type) *_name##_early_ptr; \
extern __typeof__(_type) _name##_early_map[]
-#define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \
- DECLARE_PER_CPU_READ_MOSTLY(_type, _name); \
- extern __typeof__(_type) *_name##_early_ptr; \
+#define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \
+ DECLARE_PER_CPU_READ_MOSTLY(_type, _name); \
+ extern __typeof__(_type) *_name##_early_ptr; \
extern __typeof__(_type) _name##_early_map[]
-#define early_per_cpu_ptr(_name) (_name##_early_ptr)
-#define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx])
-#define early_per_cpu(_name, _cpu) \
- *(early_per_cpu_ptr(_name) ? \
- &early_per_cpu_ptr(_name)[_cpu] : \
+#define early_per_cpu_ptr(_name) (_name##_early_ptr)
+#define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx])
+
+#define early_per_cpu(_name, _cpu) \
+ *(early_per_cpu_ptr(_name) ? \
+ &early_per_cpu_ptr(_name)[_cpu] : \
&per_cpu(_name, _cpu))
-#else /* !CONFIG_SMP */
-#define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \
+#else /* !CONFIG_SMP: */
+#define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \
DEFINE_PER_CPU(_type, _name) = _initvalue
#define DEFINE_EARLY_PER_CPU_READ_MOSTLY(_type, _name, _initvalue) \
DEFINE_PER_CPU_READ_MOSTLY(_type, _name) = _initvalue
-#define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \
+#define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \
EXPORT_PER_CPU_SYMBOL(_name)
-#define DECLARE_EARLY_PER_CPU(_type, _name) \
+#define DECLARE_EARLY_PER_CPU(_type, _name) \
DECLARE_PER_CPU(_type, _name)
-#define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \
+#define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \
DECLARE_PER_CPU_READ_MOSTLY(_type, _name)
-#define early_per_cpu(_name, _cpu) per_cpu(_name, _cpu)
-#define early_per_cpu_ptr(_name) NULL
+#define early_per_cpu(_name, _cpu) per_cpu(_name, _cpu)
+#define early_per_cpu_ptr(_name) NULL
/* no early_per_cpu_map() */
-#endif /* !CONFIG_SMP */
+#endif /* !CONFIG_SMP */
#endif /* _ASM_X86_PERCPU_H */
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 7f1e17250546..91b73571412f 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -32,6 +32,8 @@
#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
#define ARCH_PERFMON_EVENTSEL_BR_CNTR (1ULL << 35)
+#define ARCH_PERFMON_EVENTSEL_EQ (1ULL << 36)
+#define ARCH_PERFMON_EVENTSEL_UMASK2 (0xFFULL << 40)
#define INTEL_FIXED_BITS_MASK 0xFULL
#define INTEL_FIXED_BITS_STRIDE 4
@@ -185,6 +187,8 @@ union cpuid10_edx {
* detection/enumeration details:
*/
#define ARCH_PERFMON_EXT_LEAF 0x00000023
+#define ARCH_PERFMON_EXT_UMASK2 0x1
+#define ARCH_PERFMON_EXT_EQ 0x2
#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1
#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1
@@ -307,6 +311,10 @@ struct x86_pmu_capability {
#define INTEL_PMC_IDX_FIXED_SLOTS (INTEL_PMC_IDX_FIXED + 3)
#define INTEL_PMC_MSK_FIXED_SLOTS (1ULL << INTEL_PMC_IDX_FIXED_SLOTS)
+/* TOPDOWN_BAD_SPECULATION.ALL: fixed counter 4 (Atom only) */
+/* TOPDOWN_FE_BOUND.ALL: fixed counter 5 (Atom only) */
+/* TOPDOWN_RETIRING.ALL: fixed counter 6 (Atom only) */
+
static inline bool use_fixed_pseudo_encoding(u64 code)
{
return !(code & 0xff);
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 315535ffb258..e39311a89bf4 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -140,6 +140,11 @@ static inline int pte_young(pte_t pte)
return pte_flags(pte) & _PAGE_ACCESSED;
}
+static inline bool pte_decrypted(pte_t pte)
+{
+ return cc_mkdec(pte_val(pte)) == pte_val(pte);
+}
+
#define pmd_dirty pmd_dirty
static inline bool pmd_dirty(pmd_t pmd)
{
@@ -234,6 +239,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd)
return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT;
}
+#define pud_pfn pud_pfn
static inline unsigned long pud_pfn(pud_t pud)
{
phys_addr_t pfn = pud_val(pud);
@@ -387,23 +393,7 @@ static inline pte_t pte_wrprotect(pte_t pte)
#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
static inline int pte_uffd_wp(pte_t pte)
{
- bool wp = pte_flags(pte) & _PAGE_UFFD_WP;
-
-#ifdef CONFIG_DEBUG_VM
- /*
- * Having write bit for wr-protect-marked present ptes is fatal,
- * because it means the uffd-wp bit will be ignored and write will
- * just go through.
- *
- * Use any chance of pgtable walking to verify this (e.g., when
- * page swapped out or being migrated for all purposes). It means
- * something is already wrong. Tell the admin even before the
- * process crashes. We also nail it with wrong pgtable setup.
- */
- WARN_ON_ONCE(wp && pte_write(pte));
-#endif
-
- return wp;
+ return pte_flags(pte) & _PAGE_UFFD_WP;
}
static inline pte_t pte_mkuffd_wp(pte_t pte)
@@ -1200,7 +1190,6 @@ static inline int pgd_none(pgd_t pgd)
extern int direct_gbpages;
void init_mem_mapping(void);
void early_alloc_pgt_buf(void);
-extern void memblock_find_dma_reserve(void);
void __init poking_init(void);
unsigned long init_memory_mapping(unsigned long start,
unsigned long end, pgprot_t prot);
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 7e9db77231ac..3c4407271d08 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -245,6 +245,7 @@ extern void cleanup_highmap(void);
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_UNMAPPED_AREA_VMFLAGS
#define PAGE_AGP PAGE_KERNEL_NOCACHE
#define HAVE_PAGE_AGP 1
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 9abb8cc4cd47..2f321137736c 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -549,6 +549,7 @@ enum pg_level {
PG_LEVEL_2M,
PG_LEVEL_1G,
PG_LEVEL_512G,
+ PG_LEVEL_256T,
PG_LEVEL_NUM
};
@@ -567,6 +568,8 @@ static inline void update_page_count(int level, unsigned long pages) { }
extern pte_t *lookup_address(unsigned long address, unsigned int *level);
extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
unsigned int *level);
+pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
+ unsigned int *level, bool *nx, bool *rw);
extern pmd_t *lookup_pmd_address(unsigned long address);
extern phys_addr_t slow_virt_to_phys(void *__address);
extern int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn,
diff --git a/arch/x86/include/asm/posted_intr.h b/arch/x86/include/asm/posted_intr.h
new file mode 100644
index 000000000000..de788b400fba
--- /dev/null
+++ b/arch/x86/include/asm/posted_intr.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _X86_POSTED_INTR_H
+#define _X86_POSTED_INTR_H
+#include <asm/irq_vectors.h>
+
+#define POSTED_INTR_ON 0
+#define POSTED_INTR_SN 1
+
+#define PID_TABLE_ENTRY_VALID 1
+
+/* Posted-Interrupt Descriptor */
+struct pi_desc {
+ union {
+ u32 pir[8]; /* Posted interrupt requested */
+ u64 pir64[4];
+ };
+ union {
+ struct {
+ u16 notifications; /* Suppress and outstanding bits */
+ u8 nv;
+ u8 rsvd_2;
+ 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 bool pi_test_and_clear_sn(struct pi_desc *pi_desc)
+{
+ return test_and_clear_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool 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 bool pi_test_on(struct pi_desc *pi_desc)
+{
+ return test_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool pi_test_sn(struct pi_desc *pi_desc)
+{
+ return test_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control);
+}
+
+/* Non-atomic helpers */
+static inline void __pi_set_sn(struct pi_desc *pi_desc)
+{
+ pi_desc->notifications |= BIT(POSTED_INTR_SN);
+}
+
+static inline void __pi_clear_sn(struct pi_desc *pi_desc)
+{
+ pi_desc->notifications &= ~BIT(POSTED_INTR_SN);
+}
+
+#ifdef CONFIG_X86_POSTED_MSI
+/*
+ * Not all external vectors are subject to interrupt remapping, e.g. IOMMU's
+ * own interrupts. Here we do not distinguish them since those vector bits in
+ * PIR will always be zero.
+ */
+static inline bool pi_pending_this_cpu(unsigned int vector)
+{
+ struct pi_desc *pid = this_cpu_ptr(&posted_msi_pi_desc);
+
+ if (WARN_ON_ONCE(vector > NR_VECTORS || vector < FIRST_EXTERNAL_VECTOR))
+ return false;
+
+ return test_bit(vector, (unsigned long *)pid->pir);
+}
+
+extern void intel_posted_msi_init(void);
+#else
+static inline bool pi_pending_this_cpu(unsigned int vector) { return false; }
+
+static inline void intel_posted_msi_init(void) {};
+#endif /* X86_POSTED_MSI */
+
+#endif /* _X86_POSTED_INTR_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 78e51b0d6433..a75a07f4931f 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -108,9 +108,23 @@ struct cpuinfo_topology {
};
struct cpuinfo_x86 {
- __u8 x86; /* CPU family */
- __u8 x86_vendor; /* CPU vendor */
- __u8 x86_model;
+ union {
+ /*
+ * The particular ordering (low-to-high) of (vendor,
+ * family, model) is done in case range of models, like
+ * it is usually done on AMD, need to be compared.
+ */
+ struct {
+ __u8 x86_model;
+ /* CPU family */
+ __u8 x86;
+ /* CPU vendor */
+ __u8 x86_vendor;
+ __u8 x86_reserved;
+ };
+ /* combined vendor, family, model */
+ __u32 x86_vfm;
+ };
__u8 x86_stepping;
#ifdef CONFIG_X86_64
/* Number of 4K pages in DTLB/ITLB combined(in pages): */
@@ -586,7 +600,7 @@ extern char ignore_fpu_irq;
# define BASE_PREFETCH ""
# define ARCH_HAS_PREFETCH
#else
-# define BASE_PREFETCH "prefetcht0 %P1"
+# define BASE_PREFETCH "prefetcht0 %1"
#endif
/*
@@ -597,7 +611,7 @@ extern char ignore_fpu_irq;
*/
static inline void prefetch(const void *x)
{
- alternative_input(BASE_PREFETCH, "prefetchnta %P1",
+ alternative_input(BASE_PREFETCH, "prefetchnta %1",
X86_FEATURE_XMM,
"m" (*(const char *)x));
}
@@ -609,7 +623,7 @@ static inline void prefetch(const void *x)
*/
static __always_inline void prefetchw(const void *x)
{
- alternative_input(BASE_PREFETCH, "prefetchw %P1",
+ alternative_input(BASE_PREFETCH, "prefetchw %1",
X86_FEATURE_3DNOWPREFETCH,
"m" (*(const char *)x));
}
@@ -635,12 +649,10 @@ static __always_inline void prefetchw(const void *x)
#define KSTK_ESP(task) (task_pt_regs(task)->sp)
#else
-extern unsigned long __end_init_task[];
+extern unsigned long __top_init_kernel_stack[];
#define INIT_THREAD { \
- .sp = (unsigned long)&__end_init_task - \
- TOP_OF_KERNEL_STACK_PADDING - \
- sizeof(struct pt_regs), \
+ .sp = (unsigned long)&__top_init_kernel_stack, \
}
extern unsigned long KSTK_ESP(struct task_struct *task);
@@ -680,7 +692,17 @@ static inline u32 per_cpu_l2c_id(unsigned int cpu)
#ifdef CONFIG_CPU_SUP_AMD
extern u32 amd_get_highest_perf(void);
-extern void amd_clear_divider(void);
+
+/*
+ * Issue a DIV 0/1 insn to clear any division data from previous DIV
+ * operations.
+ */
+static __always_inline void amd_clear_divider(void)
+{
+ asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
+ :: "a" (0), "d" (0), "r" (1));
+}
+
extern void amd_check_microcode(void);
#else
static inline u32 amd_get_highest_perf(void) { return 0; }
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 043758a2e627..365798cb4408 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -23,19 +23,14 @@ extern int of_ioapic;
extern u64 initial_dtb;
extern void add_dtb(u64 data);
void x86_of_pci_init(void);
-void x86_dtb_parse_smp_config(void);
+void x86_flattree_get_config(void);
#else
static inline void add_dtb(u64 data) { }
static inline void x86_of_pci_init(void) { }
-static inline void x86_dtb_parse_smp_config(void) { }
+static inline void x86_flattree_get_config(void) { }
#define of_ioapic 0
#endif
-#ifdef CONFIG_OF_EARLY_FLATTREE
-void x86_flattree_get_config(void);
-#else
-static inline void x86_flattree_get_config(void) { }
-#endif
extern char cmd_line[COMMAND_LINE_SIZE];
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h
index cde8357bb226..a053c1293975 100644
--- a/arch/x86/include/asm/qspinlock.h
+++ b/arch/x86/include/asm/qspinlock.h
@@ -85,6 +85,8 @@ DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key);
#define virt_spin_lock virt_spin_lock
static inline bool virt_spin_lock(struct qspinlock *lock)
{
+ int val;
+
if (!static_branch_likely(&virt_spin_lock_key))
return false;
@@ -94,10 +96,13 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
* horrible lock 'holder' preemption issues.
*/
- do {
- while (atomic_read(&lock->val) != 0)
- cpu_relax();
- } while (atomic_cmpxchg(&lock->val, 0, _Q_LOCKED_VAL) != 0);
+ __retry:
+ val = atomic_read(&lock->val);
+
+ if (val || !atomic_try_cmpxchg(&lock->val, &val, _Q_LOCKED_VAL)) {
+ cpu_relax();
+ goto __retry;
+ }
return true;
}
diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h
index ef9697f20129..0a985784be9b 100644
--- a/arch/x86/include/asm/qspinlock_paravirt.h
+++ b/arch/x86/include/asm/qspinlock_paravirt.h
@@ -25,9 +25,9 @@ __PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath, ".spinlock.text");
*
* void __lockfunc __pv_queued_spin_unlock(struct qspinlock *lock)
* {
- * u8 lockval = cmpxchg(&lock->locked, _Q_LOCKED_VAL, 0);
+ * u8 lockval = _Q_LOCKED_VAL;
*
- * if (likely(lockval == _Q_LOCKED_VAL))
+ * if (try_cmpxchg(&lock->locked, &lockval, 0))
* return;
* pv_queued_spin_unlock_slowpath(lock, lockval);
* }
@@ -40,10 +40,9 @@ __PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath, ".spinlock.text");
#define PV_UNLOCK_ASM \
FRAME_BEGIN \
"push %rdx\n\t" \
- "mov $0x1,%eax\n\t" \
+ "mov $" __stringify(_Q_LOCKED_VAL) ",%eax\n\t" \
"xor %edx,%edx\n\t" \
LOCK_PREFIX "cmpxchg %dl,(%rdi)\n\t" \
- "cmp $0x1,%al\n\t" \
"jne .slowpath\n\t" \
"pop %rdx\n\t" \
FRAME_END \
diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h
new file mode 100644
index 000000000000..24e3a53ca255
--- /dev/null
+++ b/arch/x86/include/asm/runtime-const.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RUNTIME_CONST_H
+#define _ASM_RUNTIME_CONST_H
+
+#define runtime_const_ptr(sym) ({ \
+ typeof(sym) __ret; \
+ asm_inline("mov %1,%0\n1:\n" \
+ ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \
+ ".long 1b - %c2 - .\n\t" \
+ ".popsection" \
+ :"=r" (__ret) \
+ :"i" ((unsigned long)0x0123456789abcdefull), \
+ "i" (sizeof(long))); \
+ __ret; })
+
+// The 'typeof' will create at _least_ a 32-bit type, but
+// will happily also take a bigger type and the 'shrl' will
+// clear the upper bits
+#define runtime_const_shift_right_32(val, sym) ({ \
+ typeof(0u+(val)) __ret = (val); \
+ asm_inline("shrl $12,%k0\n1:\n" \
+ ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \
+ ".long 1b - 1 - .\n\t" \
+ ".popsection" \
+ :"+r" (__ret)); \
+ __ret; })
+
+#define runtime_const_init(type, sym) do { \
+ extern s32 __start_runtime_##type##_##sym[]; \
+ extern s32 __stop_runtime_##type##_##sym[]; \
+ runtime_const_fixup(__runtime_fixup_##type, \
+ (unsigned long)(sym), \
+ __start_runtime_##type##_##sym, \
+ __stop_runtime_##type##_##sym); \
+} while (0)
+
+/*
+ * The text patching is trivial - you can only do this at init time,
+ * when the text section hasn't been marked RO, and before the text
+ * has ever been executed.
+ */
+static inline void __runtime_fixup_ptr(void *where, unsigned long val)
+{
+ *(unsigned long *)where = val;
+}
+
+static inline void __runtime_fixup_shift(void *where, unsigned long val)
+{
+ *(unsigned char *)where = val;
+}
+
+static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
+ unsigned long val, s32 *start, s32 *end)
+{
+ while (start < end) {
+ fn(*start + (void *)start, val);
+ start++;
+ }
+}
+
+#endif
diff --git a/arch/x86/include/asm/seccomp.h b/arch/x86/include/asm/seccomp.h
index fef16e398161..42bcd42d70d1 100644
--- a/arch/x86/include/asm/seccomp.h
+++ b/arch/x86/include/asm/seccomp.h
@@ -9,7 +9,7 @@
#endif
#ifdef CONFIG_COMPAT
-#include <asm/ia32_unistd.h>
+#include <asm/unistd_32_ia32.h>
#define __NR_seccomp_read_32 __NR_ia32_read
#define __NR_seccomp_write_32 __NR_ia32_write
#define __NR_seccomp_exit_32 __NR_ia32_exit
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index 9aee31862b4a..4b2abce2e3e7 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -49,8 +49,11 @@ int set_memory_wb(unsigned long addr, int numpages);
int set_memory_np(unsigned long addr, int numpages);
int set_memory_p(unsigned long addr, int numpages);
int set_memory_4k(unsigned long addr, int numpages);
+
+bool set_memory_enc_stop_conversion(void);
int set_memory_encrypted(unsigned long addr, int numpages);
int set_memory_decrypted(unsigned long addr, int numpages);
+
int set_memory_np_noalias(unsigned long addr, int numpages);
int set_memory_nonglobal(unsigned long addr, int numpages);
int set_memory_global(unsigned long addr, int numpages);
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index e61e68d71cba..0667b2a88614 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -28,6 +28,8 @@
#define NEW_CL_POINTER 0x228 /* Relative to real mode data */
#ifndef __ASSEMBLY__
+#include <linux/cache.h>
+
#include <asm/bootparam.h>
#include <asm/x86_init.h>
@@ -133,6 +135,12 @@ asmlinkage void __init __noreturn x86_64_start_reservations(char *real_mode_data
#endif /* __i386__ */
#endif /* _SETUP */
+#ifdef CONFIG_CMDLINE_BOOL
+extern bool builtin_cmdline_added __ro_after_init;
+#else
+#define builtin_cmdline_added 0
+#endif
+
#else /* __ASSEMBLY */
.macro __RESERVE_BRK name, size
diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
index b463fcbd4b90..98726c2b04f8 100644
--- a/arch/x86/include/asm/sev-common.h
+++ b/arch/x86/include/asm/sev-common.h
@@ -54,8 +54,18 @@
(((unsigned long)fn) << 32))
/* AP Reset Hold */
-#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
-#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
+#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
+#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
+#define GHCB_MSR_AP_RESET_HOLD_RESULT_POS 12
+#define GHCB_MSR_AP_RESET_HOLD_RESULT_MASK GENMASK_ULL(51, 0)
+
+/* Preferred GHCB GPA Request */
+#define GHCB_MSR_PREF_GPA_REQ 0x010
+#define GHCB_MSR_GPA_VALUE_POS 12
+#define GHCB_MSR_GPA_VALUE_MASK GENMASK_ULL(51, 0)
+
+#define GHCB_MSR_PREF_GPA_RESP 0x011
+#define GHCB_MSR_PREF_GPA_NONE 0xfffffffffffff
/* GHCB GPA Register */
#define GHCB_MSR_REG_GPA_REQ 0x012
@@ -91,28 +101,61 @@ enum psc_op {
/* GHCBData[11:0] */ \
GHCB_MSR_PSC_REQ)
+#define GHCB_MSR_PSC_REQ_TO_GFN(msr) (((msr) & GENMASK_ULL(51, 12)) >> 12)
+#define GHCB_MSR_PSC_REQ_TO_OP(msr) (((msr) & GENMASK_ULL(55, 52)) >> 52)
+
#define GHCB_MSR_PSC_RESP 0x015
#define GHCB_MSR_PSC_RESP_VAL(val) \
/* GHCBData[63:32] */ \
(((u64)(val) & GENMASK_ULL(63, 32)) >> 32)
+/* Set highest bit as a generic error response */
+#define GHCB_MSR_PSC_RESP_ERROR (BIT_ULL(63) | GHCB_MSR_PSC_RESP)
+
+/* GHCB Run at VMPL Request/Response */
+#define GHCB_MSR_VMPL_REQ 0x016
+#define GHCB_MSR_VMPL_REQ_LEVEL(v) \
+ /* GHCBData[39:32] */ \
+ (((u64)(v) & GENMASK_ULL(7, 0) << 32) | \
+ /* GHCBDdata[11:0] */ \
+ GHCB_MSR_VMPL_REQ)
+
+#define GHCB_MSR_VMPL_RESP 0x017
+#define GHCB_MSR_VMPL_RESP_VAL(v) \
+ /* GHCBData[63:32] */ \
+ (((u64)(v) & GENMASK_ULL(63, 32)) >> 32)
+
/* GHCB Hypervisor Feature Request/Response */
#define GHCB_MSR_HV_FT_REQ 0x080
#define GHCB_MSR_HV_FT_RESP 0x081
+#define GHCB_MSR_HV_FT_POS 12
+#define GHCB_MSR_HV_FT_MASK GENMASK_ULL(51, 0)
#define GHCB_MSR_HV_FT_RESP_VAL(v) \
/* GHCBData[63:12] */ \
(((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
#define GHCB_HV_FT_SNP BIT_ULL(0)
#define GHCB_HV_FT_SNP_AP_CREATION BIT_ULL(1)
+#define GHCB_HV_FT_SNP_MULTI_VMPL BIT_ULL(5)
/*
* SNP Page State Change NAE event
* The VMGEXIT_PSC_MAX_ENTRY determines the size of the PSC structure, which
* is a local stack variable in set_pages_state(). Do not increase this value
* without evaluating the impact to stack usage.
+ *
+ * Use VMGEXIT_PSC_MAX_COUNT in cases where the actual GHCB-defined max value
+ * is needed, such as when processing GHCB requests on the hypervisor side.
*/
#define VMGEXIT_PSC_MAX_ENTRY 64
+#define VMGEXIT_PSC_MAX_COUNT 253
+
+#define VMGEXIT_PSC_ERROR_GENERIC (0x100UL << 32)
+#define VMGEXIT_PSC_ERROR_INVALID_HDR ((1UL << 32) | 1)
+#define VMGEXIT_PSC_ERROR_INVALID_ENTRY ((1UL << 32) | 2)
+
+#define VMGEXIT_PSC_OP_PRIVATE 1
+#define VMGEXIT_PSC_OP_SHARED 2
struct psc_hdr {
u16 cur_entry;
@@ -159,6 +202,10 @@ struct snp_psc_desc {
#define GHCB_TERM_NOT_VMPL0 3 /* SNP guest is not running at VMPL-0 */
#define GHCB_TERM_CPUID 4 /* CPUID-validation failure */
#define GHCB_TERM_CPUID_HV 5 /* CPUID failure during hypervisor fallback */
+#define GHCB_TERM_SECRETS_PAGE 6 /* Secrets page failure */
+#define GHCB_TERM_NO_SVSM 7 /* SVSM is not advertised in the secrets page */
+#define GHCB_TERM_SVSM_VMPL0 8 /* SVSM is present but has set VMPL to 0 */
+#define GHCB_TERM_SVSM_CAA 9 /* SVSM is present but CAA is not page aligned */
#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 93ed60080cfe..79bbe2be900e 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -91,6 +91,9 @@ extern bool handle_vc_boot_ghcb(struct pt_regs *regs);
/* RMUPDATE detected 4K page and 2MB page overlap. */
#define RMPUPDATE_FAIL_OVERLAP 4
+/* PSMASH failed due to concurrent access by another CPU */
+#define PSMASH_FAIL_INUSE 3
+
/* RMP page size */
#define RMP_PG_SIZE_4K 0
#define RMP_PG_SIZE_2M 1
@@ -116,6 +119,54 @@ struct snp_req_data {
unsigned int data_npages;
};
+#define MAX_AUTHTAG_LEN 32
+
+/* See SNP spec SNP_GUEST_REQUEST section for the structure */
+enum msg_type {
+ SNP_MSG_TYPE_INVALID = 0,
+ SNP_MSG_CPUID_REQ,
+ SNP_MSG_CPUID_RSP,
+ SNP_MSG_KEY_REQ,
+ SNP_MSG_KEY_RSP,
+ SNP_MSG_REPORT_REQ,
+ SNP_MSG_REPORT_RSP,
+ SNP_MSG_EXPORT_REQ,
+ SNP_MSG_EXPORT_RSP,
+ SNP_MSG_IMPORT_REQ,
+ SNP_MSG_IMPORT_RSP,
+ SNP_MSG_ABSORB_REQ,
+ SNP_MSG_ABSORB_RSP,
+ SNP_MSG_VMRK_REQ,
+ SNP_MSG_VMRK_RSP,
+
+ SNP_MSG_TYPE_MAX
+};
+
+enum aead_algo {
+ SNP_AEAD_INVALID,
+ SNP_AEAD_AES_256_GCM,
+};
+
+struct snp_guest_msg_hdr {
+ u8 authtag[MAX_AUTHTAG_LEN];
+ u64 msg_seqno;
+ u8 rsvd1[8];
+ u8 algo;
+ u8 hdr_version;
+ u16 hdr_sz;
+ u8 msg_type;
+ u8 msg_version;
+ u16 msg_sz;
+ u32 rsvd2;
+ u8 msg_vmpck;
+ u8 rsvd3[35];
+} __packed;
+
+struct snp_guest_msg {
+ struct snp_guest_msg_hdr hdr;
+ u8 payload[4000];
+} __packed;
+
struct sev_guest_platform_data {
u64 secrets_gpa;
};
@@ -140,7 +191,7 @@ struct secrets_os_area {
#define VMPCK_KEY_LEN 32
/* See the SNP spec version 0.9 for secrets page format */
-struct snp_secrets_page_layout {
+struct snp_secrets_page {
u32 version;
u32 imien : 1,
rsvd1 : 31;
@@ -152,10 +203,119 @@ struct snp_secrets_page_layout {
u8 vmpck2[VMPCK_KEY_LEN];
u8 vmpck3[VMPCK_KEY_LEN];
struct secrets_os_area os_area;
- u8 rsvd3[3840];
+
+ u8 vmsa_tweak_bitmap[64];
+
+ /* SVSM fields */
+ u64 svsm_base;
+ u64 svsm_size;
+ u64 svsm_caa;
+ u32 svsm_max_version;
+ u8 svsm_guest_vmpl;
+ u8 rsvd3[3];
+
+ /* Remainder of page */
+ u8 rsvd4[3744];
} __packed;
+/*
+ * The SVSM Calling Area (CA) related structures.
+ */
+struct svsm_ca {
+ u8 call_pending;
+ u8 mem_available;
+ u8 rsvd1[6];
+
+ u8 svsm_buffer[PAGE_SIZE - 8];
+};
+
+#define SVSM_SUCCESS 0
+#define SVSM_ERR_INCOMPLETE 0x80000000
+#define SVSM_ERR_UNSUPPORTED_PROTOCOL 0x80000001
+#define SVSM_ERR_UNSUPPORTED_CALL 0x80000002
+#define SVSM_ERR_INVALID_ADDRESS 0x80000003
+#define SVSM_ERR_INVALID_FORMAT 0x80000004
+#define SVSM_ERR_INVALID_PARAMETER 0x80000005
+#define SVSM_ERR_INVALID_REQUEST 0x80000006
+#define SVSM_ERR_BUSY 0x80000007
+#define SVSM_PVALIDATE_FAIL_SIZEMISMATCH 0x80001006
+
+/*
+ * The SVSM PVALIDATE related structures
+ */
+struct svsm_pvalidate_entry {
+ u64 page_size : 2,
+ action : 1,
+ ignore_cf : 1,
+ rsvd : 8,
+ pfn : 52;
+};
+
+struct svsm_pvalidate_call {
+ u16 num_entries;
+ u16 cur_index;
+
+ u8 rsvd1[4];
+
+ struct svsm_pvalidate_entry entry[];
+};
+
+#define SVSM_PVALIDATE_MAX_COUNT ((sizeof_field(struct svsm_ca, svsm_buffer) - \
+ offsetof(struct svsm_pvalidate_call, entry)) / \
+ sizeof(struct svsm_pvalidate_entry))
+
+/*
+ * The SVSM Attestation related structures
+ */
+struct svsm_loc_entry {
+ u64 pa;
+ u32 len;
+ u8 rsvd[4];
+};
+
+struct svsm_attest_call {
+ struct svsm_loc_entry report_buf;
+ struct svsm_loc_entry nonce;
+ struct svsm_loc_entry manifest_buf;
+ struct svsm_loc_entry certificates_buf;
+
+ /* For attesting a single service */
+ u8 service_guid[16];
+ u32 service_manifest_ver;
+ u8 rsvd[4];
+};
+
+/*
+ * SVSM protocol structure
+ */
+struct svsm_call {
+ struct svsm_ca *caa;
+ u64 rax;
+ u64 rcx;
+ u64 rdx;
+ u64 r8;
+ u64 r9;
+ u64 rax_out;
+ u64 rcx_out;
+ u64 rdx_out;
+ u64 r8_out;
+ u64 r9_out;
+};
+
+#define SVSM_CORE_CALL(x) ((0ULL << 32) | (x))
+#define SVSM_CORE_REMAP_CA 0
+#define SVSM_CORE_PVALIDATE 1
+#define SVSM_CORE_CREATE_VCPU 2
+#define SVSM_CORE_DELETE_VCPU 3
+
+#define SVSM_ATTEST_CALL(x) ((1ULL << 32) | (x))
+#define SVSM_ATTEST_SERVICES 0
+#define SVSM_ATTEST_SINGLE_SERVICE 1
+
#ifdef CONFIG_AMD_MEM_ENCRYPT
+
+extern u8 snp_vmpl;
+
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)
@@ -181,6 +341,14 @@ static __always_inline void sev_es_nmi_complete(void)
extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
extern void sev_enable(struct boot_params *bp);
+/*
+ * RMPADJUST modifies the RMP permissions of a page of a lesser-
+ * privileged (numerically higher) VMPL.
+ *
+ * If the guest is running at a higher-privilege than the privilege
+ * level the instruction is targeting, the instruction will succeed,
+ * otherwise, it will fail.
+ */
static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs)
{
int rc;
@@ -225,11 +393,16 @@ bool snp_init(struct boot_params *bp);
void __noreturn snp_abort(void);
void snp_dmi_setup(void);
int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio);
+int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input);
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
u64 snp_get_unsupported_features(u64 status);
u64 sev_get_status(void);
void sev_show_status(void);
-#else
+void snp_update_svsm_ca(void);
+
+#else /* !CONFIG_AMD_MEM_ENCRYPT */
+
+#define snp_vmpl 0
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; }
@@ -253,12 +426,17 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
{
return -ENOTTY;
}
-
+static inline int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input)
+{
+ return -ENOTTY;
+}
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
static inline u64 sev_get_status(void) { return 0; }
static inline void sev_show_status(void) { }
-#endif
+static inline void snp_update_svsm_ca(void) { }
+
+#endif /* CONFIG_AMD_MEM_ENCRYPT */
#ifdef CONFIG_KVM_AMD_SEV
bool snp_probe_rmptable_info(void);
diff --git a/arch/x86/include/asm/shstk.h b/arch/x86/include/asm/shstk.h
index 42fee8959df7..4cb77e004615 100644
--- a/arch/x86/include/asm/shstk.h
+++ b/arch/x86/include/asm/shstk.h
@@ -21,6 +21,8 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clon
void shstk_free(struct task_struct *p);
int setup_signal_shadow_stack(struct ksignal *ksig);
int restore_signal_shadow_stack(void);
+int shstk_update_last_frame(unsigned long val);
+bool shstk_is_enabled(void);
#else
static inline long shstk_prctl(struct task_struct *task, int option,
unsigned long arg2) { return -EINVAL; }
@@ -31,6 +33,8 @@ static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p,
static inline void shstk_free(struct task_struct *p) {}
static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; }
static inline int restore_signal_shadow_stack(void) { return 0; }
+static inline int shstk_update_last_frame(unsigned long val) { return 0; }
+static inline bool shstk_is_enabled(void) { return false; }
#endif /* CONFIG_X86_USER_SHADOW_STACK */
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index a35936b512fe..ca073f40698f 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -35,6 +35,7 @@ struct smp_ops {
int (*cpu_disable)(void);
void (*cpu_die)(unsigned int cpu);
void (*play_dead)(void);
+ void (*stop_this_cpu)(void);
void (*send_call_func_ipi)(const struct cpumask *mask);
void (*send_call_func_single_ipi)(int cpu);
diff --git a/arch/x86/include/asm/sparsemem.h b/arch/x86/include/asm/sparsemem.h
index 1be13b2dfe8b..64df897c0ee3 100644
--- a/arch/x86/include/asm/sparsemem.h
+++ b/arch/x86/include/asm/sparsemem.h
@@ -37,8 +37,6 @@ extern int phys_to_target_node(phys_addr_t start);
#define phys_to_target_node phys_to_target_node
extern int memory_add_physaddr_to_nid(u64 start);
#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
-extern int numa_fill_memblks(u64 start, u64 end);
-#define numa_fill_memblks numa_fill_memblks
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index 2e9fc5c400cd..aec6e2d3aa1d 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -182,8 +182,8 @@ static __always_inline void clflush(volatile void *__p)
static inline void clflushopt(volatile void *__p)
{
- alternative_io(".byte 0x3e; clflush %P0",
- ".byte 0x66; clflush %P0",
+ alternative_io(".byte 0x3e; clflush %0",
+ ".byte 0x66; clflush %0",
X86_FEATURE_CLFLUSHOPT,
"+m" (*(volatile char __force *)__p));
}
@@ -205,9 +205,9 @@ static inline void clwb(volatile void *__p)
#ifdef CONFIG_X86_USER_SHADOW_STACK
static inline int write_user_shstk_64(u64 __user *addr, u64 val)
{
- asm goto("1: wrussq %[val], (%[addr])\n"
+ asm goto("1: wrussq %[val], %[addr]\n"
_ASM_EXTABLE(1b, %l[fail])
- :: [addr] "r" (addr), [val] "r" (val)
+ :: [addr] "m" (*addr), [val] "r" (val)
:: fail);
return 0;
fail:
diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h
index 857d364b9888..9d0b324eab21 100644
--- a/arch/x86/include/asm/string_64.h
+++ b/arch/x86/include/asm/string_64.h
@@ -30,37 +30,40 @@ void *__memset(void *s, int c, size_t n);
#define __HAVE_ARCH_MEMSET16
static inline void *memset16(uint16_t *s, uint16_t v, size_t n)
{
- long d0, d1;
- asm volatile("rep\n\t"
- "stosw"
- : "=&c" (d0), "=&D" (d1)
- : "a" (v), "1" (s), "0" (n)
- : "memory");
- return s;
+ const __auto_type s0 = s;
+ asm volatile (
+ "rep stosw"
+ : "+D" (s), "+c" (n)
+ : "a" (v)
+ : "memory"
+ );
+ return s0;
}
#define __HAVE_ARCH_MEMSET32
static inline void *memset32(uint32_t *s, uint32_t v, size_t n)
{
- long d0, d1;
- asm volatile("rep\n\t"
- "stosl"
- : "=&c" (d0), "=&D" (d1)
- : "a" (v), "1" (s), "0" (n)
- : "memory");
- return s;
+ const __auto_type s0 = s;
+ asm volatile (
+ "rep stosl"
+ : "+D" (s), "+c" (n)
+ : "a" (v)
+ : "memory"
+ );
+ return s0;
}
#define __HAVE_ARCH_MEMSET64
static inline void *memset64(uint64_t *s, uint64_t v, size_t n)
{
- long d0, d1;
- asm volatile("rep\n\t"
- "stosq"
- : "=&c" (d0), "=&D" (d1)
- : "a" (v), "1" (s), "0" (n)
- : "memory");
- return s;
+ const __auto_type s0 = s;
+ asm volatile (
+ "rep stosq"
+ : "+D" (s), "+c" (n)
+ : "a" (v)
+ : "memory"
+ );
+ return s0;
}
#endif
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 728c98175b9c..f0dea3750ca9 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -285,7 +285,14 @@ static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_
#define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF)
-#define SVM_SEV_FEAT_DEBUG_SWAP BIT(5)
+#define SVM_SEV_FEAT_SNP_ACTIVE BIT(0)
+#define SVM_SEV_FEAT_RESTRICTED_INJECTION BIT(3)
+#define SVM_SEV_FEAT_ALTERNATE_INJECTION BIT(4)
+#define SVM_SEV_FEAT_DEBUG_SWAP BIT(5)
+
+#define SVM_SEV_FEAT_INT_INJ_MODES \
+ (SVM_SEV_FEAT_RESTRICTED_INJECTION | \
+ SVM_SEV_FEAT_ALTERNATE_INJECTION)
struct vmcb_seg {
u16 selector;
diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h
index 345aafbc1964..6259f1937fe7 100644
--- a/arch/x86/include/asm/text-patching.h
+++ b/arch/x86/include/asm/text-patching.h
@@ -15,7 +15,7 @@
extern void text_poke_early(void *addr, const void *opcode, size_t len);
-extern void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len);
+extern void apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len);
/*
* Clear and restore the kernel write-protection flag on the local CPU.
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 405efb3e4996..94408a784c8e 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -28,9 +28,6 @@ static inline cycles_t get_cycles(void)
}
#define get_cycles get_cycles
-extern struct system_counterval_t convert_art_to_tsc(u64 art);
-extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
-
extern void tsc_early_init(void);
extern void tsc_init(void);
extern void mark_tsc_unstable(char *reason);
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 237dc8cdd12b..3a7755c1a441 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -78,10 +78,10 @@ extern int __get_user_bad(void);
int __ret_gu; \
register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \
__chk_user_ptr(ptr); \
- asm volatile("call __" #fn "_%P4" \
+ asm volatile("call __" #fn "_%c[size]" \
: "=a" (__ret_gu), "=r" (__val_gu), \
ASM_CALL_CONSTRAINT \
- : "0" (ptr), "i" (sizeof(*(ptr)))); \
+ : "0" (ptr), [size] "i" (sizeof(*(ptr)))); \
instrument_get_user(__val_gu); \
(x) = (__force __typeof__(*(ptr))) __val_gu; \
__builtin_expect(__ret_gu, 0); \
@@ -177,7 +177,7 @@ extern void __put_user_nocheck_8(void);
__chk_user_ptr(__ptr); \
__ptr_pu = __ptr; \
__val_pu = __x; \
- asm volatile("call __" #fn "_%P[size]" \
+ asm volatile("call __" #fn "_%c[size]" \
: "=c" (__ret_pu), \
ASM_CALL_CONSTRAINT \
: "0" (__ptr_pu), \
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 761173ccc33c..6c9e5bdd3916 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -56,6 +56,5 @@
# define __ARCH_WANT_SYS_FORK
# define __ARCH_WANT_SYS_VFORK
# define __ARCH_WANT_SYS_CLONE
-# define __ARCH_WANT_SYS_CLONE3
#endif /* _ASM_X86_UNISTD_H */
diff --git a/arch/x86/include/asm/vdso/getrandom.h b/arch/x86/include/asm/vdso/getrandom.h
new file mode 100644
index 000000000000..b96e674cafde
--- /dev/null
+++ b/arch/x86/include/asm/vdso/getrandom.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022-2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+#ifndef __ASM_VDSO_GETRANDOM_H
+#define __ASM_VDSO_GETRANDOM_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/unistd.h>
+#include <asm/vvar.h>
+
+/**
+ * getrandom_syscall - Invoke the getrandom() syscall.
+ * @buffer: Destination buffer to fill with random bytes.
+ * @len: Size of @buffer in bytes.
+ * @flags: Zero or more GRND_* flags.
+ * Returns: The number of random bytes written to @buffer, or a negative value indicating an error.
+ */
+static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsigned int flags)
+{
+ long ret;
+
+ asm ("syscall" : "=a" (ret) :
+ "0" (__NR_getrandom), "D" (buffer), "S" (len), "d" (flags) :
+ "rcx", "r11", "memory");
+
+ return ret;
+}
+
+#define __vdso_rng_data (VVAR(_vdso_rng_data))
+
+static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void)
+{
+ if (IS_ENABLED(CONFIG_TIME_NS) && __vdso_data->clock_mode == VDSO_CLOCKMODE_TIMENS)
+ return (void *)&__vdso_rng_data + ((void *)&__timens_vdso_data - (void *)&__vdso_data);
+ return &__vdso_rng_data;
+}
+
+/**
+ * __arch_chacha20_blocks_nostack - Generate ChaCha20 stream without using the stack.
+ * @dst_bytes: Destination buffer to hold @nblocks * 64 bytes of output.
+ * @key: 32-byte input key.
+ * @counter: 8-byte counter, read on input and updated on return.
+ * @nblocks: Number of blocks to generate.
+ *
+ * Generates a given positive number of blocks of ChaCha20 output with nonce=0, and does not write
+ * to any stack or memory outside of the parameters passed to it, in order to mitigate stack data
+ * leaking into forked child processes.
+ */
+extern void __arch_chacha20_blocks_nostack(u8 *dst_bytes, const u32 *key, u32 *counter, size_t nblocks);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETRANDOM_H */
diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h
index 8e048ca980df..b2d2df026f6e 100644
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -300,7 +300,7 @@ static inline bool arch_vdso_cycles_ok(u64 cycles)
#define vdso_cycles_ok arch_vdso_cycles_ok
/*
- * x86 specific delta calculation.
+ * x86 specific calculation of nanoseconds for the current cycle count
*
* The regular implementation assumes that clocksource reads are globally
* monotonic. The TSC can be slightly off across sockets which can cause
@@ -308,8 +308,8 @@ static inline bool arch_vdso_cycles_ok(u64 cycles)
* jump.
*
* Therefore it needs to be verified that @cycles are greater than
- * @last. If not then use @last, which is the base time of the current
- * conversion period.
+ * @vd->cycles_last. If not then use @vd->cycles_last, which is the base
+ * time of the current conversion period.
*
* This variant also uses a custom mask because while the clocksource mask of
* all the VDSO capable clocksources on x86 is U64_MAX, the above code uses
@@ -317,25 +317,36 @@ static inline bool arch_vdso_cycles_ok(u64 cycles)
* declares everything with the MSB/Sign-bit set as invalid. Therefore the
* effective mask is S64_MAX.
*/
-static __always_inline
-u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
+static __always_inline u64 vdso_calc_ns(const struct vdso_data *vd, u64 cycles, u64 base)
{
- /*
- * Due to the MSB/Sign-bit being used as invalid marker (see
- * arch_vdso_cycles_valid() above), the effective mask is S64_MAX.
- */
- u64 delta = (cycles - last) & S64_MAX;
+ u64 delta = cycles - vd->cycle_last;
/*
- * Due to the above mentioned TSC wobbles, filter out negative motion.
- * Per the above masking, the effective sign bit is now bit 62.
+ * Negative motion and deltas which can cause multiplication
+ * overflow require special treatment. This check covers both as
+ * negative motion is guaranteed to be greater than @vd::max_cycles
+ * due to unsigned comparison.
+ *
+ * Due to the MSB/Sign-bit being used as invalid marker (see
+ * arch_vdso_cycles_ok() above), the effective mask is S64_MAX, but that
+ * case is also unlikely and will also take the unlikely path here.
*/
- if (unlikely(delta & (1ULL << 62)))
- return 0;
+ if (unlikely(delta > vd->max_cycles)) {
+ /*
+ * Due to the above mentioned TSC wobbles, filter out
+ * negative motion. Per the above masking, the effective
+ * sign bit is now bit 62.
+ */
+ if (delta & (1ULL << 62))
+ return base >> vd->shift;
+
+ /* Handle multiplication overflow gracefully */
+ return mul_u64_u32_add_u64_shr(delta & S64_MAX, vd->mult, base, vd->shift);
+ }
- return delta * mult;
+ return ((delta * vd->mult) + base) >> vd->shift;
}
-#define vdso_calc_delta vdso_calc_delta
+#define vdso_calc_ns vdso_calc_ns
#endif /* !__ASSEMBLY__ */
diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h
index be199a9b2676..972415a8be31 100644
--- a/arch/x86/include/asm/vdso/vsyscall.h
+++ b/arch/x86/include/asm/vdso/vsyscall.h
@@ -4,13 +4,14 @@
#ifndef __ASSEMBLY__
-#include <linux/hrtimer.h>
#include <linux/timekeeper_internal.h>
#include <vdso/datapage.h>
#include <asm/vgtod.h>
#include <asm/vvar.h>
DEFINE_VVAR(struct vdso_data, _vdso_data);
+DEFINE_VVAR_SINGLE(struct vdso_rng_data, _vdso_rng_data);
+
/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index 7aa38b2ad8a9..a0ce291abcae 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -14,11 +14,6 @@
#include <uapi/linux/time.h>
-#ifdef BUILD_VDSO32_64
-typedef u64 gtod_long_t;
-#else
-typedef unsigned long gtod_long_t;
-#endif
#endif /* CONFIG_GENERIC_GETTIMEOFDAY */
#endif /* _ASM_X86_VGTOD_H */
diff --git a/arch/x86/include/asm/video.h b/arch/x86/include/asm/video.h
new file mode 100644
index 000000000000..0950c9535fae
--- /dev/null
+++ b/arch/x86/include/asm/video.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_VIDEO_H
+#define _ASM_X86_VIDEO_H
+
+#include <linux/types.h>
+
+#include <asm/page.h>
+
+struct device;
+
+pgprot_t pgprot_framebuffer(pgprot_t prot,
+ unsigned long vm_start, unsigned long vm_end,
+ unsigned long offset);
+#define pgprot_framebuffer pgprot_framebuffer
+
+bool video_is_primary_device(struct device *dev);
+#define video_is_primary_device video_is_primary_device
+
+#include <asm-generic/video.h>
+
+#endif /* _ASM_X86_VIDEO_H */
diff --git a/arch/x86/include/asm/vm86.h b/arch/x86/include/asm/vm86.h
index 9e8ac5073ecb..62ee19909903 100644
--- a/arch/x86/include/asm/vm86.h
+++ b/arch/x86/include/asm/vm86.h
@@ -84,7 +84,7 @@ static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c)
static inline void save_v86_state(struct kernel_vm86_regs *a, int b) { }
-#define free_vm86(t) do { } while(0)
+#define free_vm86(task) do { (void)(task); } while(0)
#endif /* CONFIG_VM86 */
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index ac9fc51e2b18..c9cf43d5ef23 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -7,51 +7,321 @@
#include <linux/stringify.h>
/*
- * The hypercall definitions differ in the low word of the %edx argument
- * in the following way: the old port base interface uses the port
- * number to distinguish between high- and low bandwidth versions.
+ * VMware hypercall ABI.
+ *
+ * - Low bandwidth (LB) hypercalls (I/O port based, vmcall and vmmcall)
+ * have up to 6 input and 6 output arguments passed and returned using
+ * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
+ * %esi (arg4), %edi (arg5).
+ * The following input arguments must be initialized by the caller:
+ * arg0 - VMWARE_HYPERVISOR_MAGIC
+ * arg2 - Hypercall command
+ * arg3 bits [15:0] - Port number, LB and direction flags
+ *
+ * - Low bandwidth TDX hypercalls (x86_64 only) are similar to LB
+ * hypercalls. They also have up to 6 input and 6 output on registers
+ * arguments, with different argument to register mapping:
+ * %r12 (arg0), %rbx (arg1), %r13 (arg2), %rdx (arg3),
+ * %rsi (arg4), %rdi (arg5).
+ *
+ * - High bandwidth (HB) hypercalls are I/O port based only. They have
+ * up to 7 input and 7 output arguments passed and returned using
+ * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
+ * %esi (arg4), %edi (arg5), %ebp (arg6).
+ * The following input arguments must be initialized by the caller:
+ * arg0 - VMWARE_HYPERVISOR_MAGIC
+ * arg1 - Hypercall command
+ * arg3 bits [15:0] - Port number, HB and direction flags
+ *
+ * For compatibility purposes, x86_64 systems use only lower 32 bits
+ * for input and output arguments.
+ *
+ * The hypercall definitions differ in the low word of the %edx (arg3)
+ * in the following way: the old I/O port based interface uses the port
+ * number to distinguish between high- and low bandwidth versions, and
+ * uses IN/OUT instructions to define transfer direction.
*
* The new vmcall interface instead uses a set of flags to select
* bandwidth mode and transfer direction. The flags should be loaded
- * into %dx by any user and are automatically replaced by the port
- * number if the VMWARE_HYPERVISOR_PORT method is used.
- *
- * In short, new driver code should strictly use the new definition of
- * %dx content.
+ * into arg3 by any user and are automatically replaced by the port
+ * number if the I/O port method is used.
*/
-/* Old port-based version */
-#define VMWARE_HYPERVISOR_PORT 0x5658
-#define VMWARE_HYPERVISOR_PORT_HB 0x5659
+#define VMWARE_HYPERVISOR_HB BIT(0)
+#define VMWARE_HYPERVISOR_OUT BIT(1)
-/* Current vmcall / vmmcall version */
-#define VMWARE_HYPERVISOR_HB BIT(0)
-#define VMWARE_HYPERVISOR_OUT BIT(1)
+#define VMWARE_HYPERVISOR_PORT 0x5658
+#define VMWARE_HYPERVISOR_PORT_HB (VMWARE_HYPERVISOR_PORT | \
+ VMWARE_HYPERVISOR_HB)
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL \
- ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
- "inl (%%dx), %%eax", \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
+#define VMWARE_HYPERVISOR_MAGIC 0x564d5868U
+#define VMWARE_CMD_GETVERSION 10
+#define VMWARE_CMD_GETHZ 45
+#define VMWARE_CMD_GETVCPU_INFO 68
+#define VMWARE_CMD_STEALCLOCK 91
/*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * Hypercall command mask:
+ * bits [6:0] command, range [0, 127]
+ * bits [19:16] sub-command, range [0, 15]
*/
-#define VMWARE_HYPERCALL_HB_OUT \
- ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
- "rep outsb", \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
+#define VMWARE_CMD_MASK 0xf007fU
+
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1)
+
+extern unsigned long vmware_hypercall_slow(unsigned long cmd,
+ unsigned long in1, unsigned long in3,
+ unsigned long in4, unsigned long in5,
+ u32 *out1, u32 *out2, u32 *out3,
+ u32 *out4, u32 *out5);
+
+#define VMWARE_TDX_VENDOR_LEAF 0x1af7e4909ULL
+#define VMWARE_TDX_HCALL_FUNC 1
+
+extern unsigned long vmware_tdx_hypercall(unsigned long cmd,
+ unsigned long in1, unsigned long in3,
+ unsigned long in4, unsigned long in5,
+ u32 *out1, u32 *out2, u32 *out3,
+ u32 *out4, u32 *out5);
/*
- * The high bandwidth in call. The low word of edx is presumed to have the
- * HB bit set.
+ * The low bandwidth call. The low word of %edx is presumed to have OUT bit
+ * set. The high word of %edx may contain input data from the caller.
*/
-#define VMWARE_HYPERCALL_HB_IN \
- ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
- "rep insb", \
- "vmcall", X86_FEATURE_VMCALL, \
+#define VMWARE_HYPERCALL \
+ ALTERNATIVE_2("movw %[port], %%dx\n\t" \
+ "inl (%%dx), %%eax", \
+ "vmcall", X86_FEATURE_VMCALL, \
"vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+ unsigned long out0;
+
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL);
+
+ if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+ return vmware_hypercall_slow(cmd, in1, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL);
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+ u32 *out1, u32 *out2)
+{
+ unsigned long out0;
+
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+ out1, out2, NULL, NULL, NULL);
+
+ if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+ return vmware_hypercall_slow(cmd, in1, 0, 0, 0,
+ out1, out2, NULL, NULL, NULL);
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=b" (*out1), "=c" (*out2)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+ u32 *out1, u32 *out2, u32 *out3)
+{
+ unsigned long out0;
+
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+ out1, out2, out3, NULL, NULL);
+
+ if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+ return vmware_hypercall_slow(cmd, in1, 0, 0, 0,
+ out1, out2, out3, NULL, NULL);
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, u32 *out2)
+{
+ unsigned long out0;
+
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, in3, in4, in5,
+ NULL, out2, NULL, NULL, NULL);
+
+ if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+ return vmware_hypercall_slow(cmd, in1, in3, in4, in5,
+ NULL, out2, NULL, NULL, NULL);
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=c" (*out2)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+ unsigned long in3, u32 *out2,
+ u32 *out3, u32 *out4, u32 *out5)
+{
+ unsigned long out0;
+
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, in3, 0, 0,
+ NULL, out2, out3, out4, out5);
+
+ if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+ return vmware_hypercall_slow(cmd, in1, in3, 0, 0,
+ NULL, out2, out3, out4, out5);
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
+ "=D" (*out5)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, u32 *out1,
+ u32 *out2, u32 *out3)
+{
+ unsigned long out0;
+
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, in3, in4, in5,
+ out1, out2, out3, NULL, NULL);
+
+ if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+ return vmware_hypercall_slow(cmd, in1, in3, in4, in5,
+ out1, out2, out3, NULL, NULL);
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ return out0;
+}
+
+#ifdef CONFIG_X86_64
+#define VMW_BP_CONSTRAINT "r"
+#else
+#define VMW_BP_CONSTRAINT "m"
+#endif
+
+/*
+ * High bandwidth calls are not supported on encrypted memory guests.
+ * The caller should check cc_platform_has(CC_ATTR_MEM_ENCRYPT) and use
+ * low bandwidth hypercall if memory encryption is set.
+ * This assumption simplifies HB hypercall implementation to just I/O port
+ * based approach without alternative patching.
+ */
+static inline
+unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ u32 *out1)
+{
+ unsigned long out0;
+
+ asm_inline volatile (
+ UNWIND_HINT_SAVE
+ "push %%" _ASM_BP "\n\t"
+ UNWIND_HINT_UNDEFINED
+ "mov %[in6], %%" _ASM_BP "\n\t"
+ "rep outsb\n\t"
+ "pop %%" _ASM_BP "\n\t"
+ UNWIND_HINT_RESTORE
+ : "=a" (out0), "=b" (*out1)
+ : "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (cmd),
+ "c" (in2),
+ "d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
+ "S" (in4),
+ "D" (in5),
+ [in6] VMW_BP_CONSTRAINT (in6)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ u32 *out1)
+{
+ unsigned long out0;
+
+ asm_inline volatile (
+ UNWIND_HINT_SAVE
+ "push %%" _ASM_BP "\n\t"
+ UNWIND_HINT_UNDEFINED
+ "mov %[in6], %%" _ASM_BP "\n\t"
+ "rep insb\n\t"
+ "pop %%" _ASM_BP "\n\t"
+ UNWIND_HINT_RESTORE
+ : "=a" (out0), "=b" (*out1)
+ : "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (cmd),
+ "c" (in2),
+ "d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
+ "S" (in4),
+ "D" (in5),
+ [in6] VMW_BP_CONSTRAINT (in6)
+ : "cc", "memory");
+ return out0;
+}
+#undef VMW_BP_CONSTRAINT
+#undef VMWARE_HYPERCALL
+
#endif
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 4dba17363008..d77a31039f24 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -71,6 +71,7 @@
#define SECONDARY_EXEC_ENCLS_EXITING VMCS_CONTROL_BIT(ENCLS_EXITING)
#define SECONDARY_EXEC_RDSEED_EXITING VMCS_CONTROL_BIT(RDSEED_EXITING)
#define SECONDARY_EXEC_ENABLE_PML VMCS_CONTROL_BIT(PAGE_MOD_LOGGING)
+#define SECONDARY_EXEC_EPT_VIOLATION_VE VMCS_CONTROL_BIT(EPT_VIOLATION_VE)
#define SECONDARY_EXEC_PT_CONCEAL_VMX VMCS_CONTROL_BIT(PT_CONCEAL_VMX)
#define SECONDARY_EXEC_ENABLE_XSAVES VMCS_CONTROL_BIT(XSAVES)
#define SECONDARY_EXEC_MODE_BASED_EPT_EXEC VMCS_CONTROL_BIT(MODE_BASED_EPT_EXEC)
@@ -226,6 +227,8 @@ enum vmcs_field {
VMREAD_BITMAP_HIGH = 0x00002027,
VMWRITE_BITMAP = 0x00002028,
VMWRITE_BITMAP_HIGH = 0x00002029,
+ VE_INFORMATION_ADDRESS = 0x0000202A,
+ VE_INFORMATION_ADDRESS_HIGH = 0x0000202B,
XSS_EXIT_BITMAP = 0x0000202C,
XSS_EXIT_BITMAP_HIGH = 0x0000202D,
ENCLS_EXITING_BITMAP = 0x0000202E,
@@ -514,6 +517,7 @@ enum vmcs_field {
#define VMX_EPT_IPAT_BIT (1ull << 6)
#define VMX_EPT_ACCESS_BIT (1ull << 8)
#define VMX_EPT_DIRTY_BIT (1ull << 9)
+#define VMX_EPT_SUPPRESS_VE_BIT (1ull << 63)
#define VMX_EPT_RWX_MASK (VMX_EPT_READABLE_MASK | \
VMX_EPT_WRITABLE_MASK | \
VMX_EPT_EXECUTABLE_MASK)
@@ -630,4 +634,13 @@ enum vmx_l1d_flush_state {
extern enum vmx_l1d_flush_state l1tf_vmx_mitigation;
+struct vmx_ve_information {
+ u32 exit_reason;
+ u32 delivery;
+ u64 exit_qualification;
+ u64 guest_linear_address;
+ u64 guest_physical_address;
+ u16 eptp_index;
+};
+
#endif
diff --git a/arch/x86/include/asm/vmxfeatures.h b/arch/x86/include/asm/vmxfeatures.h
index 266daf5b5b84..09b1d7e607c1 100644
--- a/arch/x86/include/asm/vmxfeatures.h
+++ b/arch/x86/include/asm/vmxfeatures.h
@@ -9,85 +9,85 @@
/*
* Note: If the comment begins with a quoted string, that string is used
- * in /proc/cpuinfo instead of the macro name. If the string is "",
- * this feature bit is not displayed in /proc/cpuinfo at all.
+ * in /proc/cpuinfo instead of the macro name. Otherwise, this feature bit
+ * is not displayed in /proc/cpuinfo at all.
*/
/* Pin-Based VM-Execution Controls, EPT/VPID, APIC and VM-Functions, word 0 */
-#define VMX_FEATURE_INTR_EXITING ( 0*32+ 0) /* "" VM-Exit on vectored interrupts */
-#define VMX_FEATURE_NMI_EXITING ( 0*32+ 3) /* "" VM-Exit on NMIs */
+#define VMX_FEATURE_INTR_EXITING ( 0*32+ 0) /* VM-Exit on vectored interrupts */
+#define VMX_FEATURE_NMI_EXITING ( 0*32+ 3) /* VM-Exit on NMIs */
#define VMX_FEATURE_VIRTUAL_NMIS ( 0*32+ 5) /* "vnmi" NMI virtualization */
-#define VMX_FEATURE_PREEMPTION_TIMER ( 0*32+ 6) /* VMX Preemption Timer */
-#define VMX_FEATURE_POSTED_INTR ( 0*32+ 7) /* Posted Interrupts */
+#define VMX_FEATURE_PREEMPTION_TIMER ( 0*32+ 6) /* "preemption_timer" VMX Preemption Timer */
+#define VMX_FEATURE_POSTED_INTR ( 0*32+ 7) /* "posted_intr" Posted Interrupts */
/* EPT/VPID features, scattered to bits 16-23 */
-#define VMX_FEATURE_INVVPID ( 0*32+ 16) /* INVVPID is supported */
+#define VMX_FEATURE_INVVPID ( 0*32+ 16) /* "invvpid" INVVPID is supported */
#define VMX_FEATURE_EPT_EXECUTE_ONLY ( 0*32+ 17) /* "ept_x_only" EPT entries can be execute only */
-#define VMX_FEATURE_EPT_AD ( 0*32+ 18) /* EPT Accessed/Dirty bits */
-#define VMX_FEATURE_EPT_1GB ( 0*32+ 19) /* 1GB EPT pages */
-#define VMX_FEATURE_EPT_5LEVEL ( 0*32+ 20) /* 5-level EPT paging */
+#define VMX_FEATURE_EPT_AD ( 0*32+ 18) /* "ept_ad" EPT Accessed/Dirty bits */
+#define VMX_FEATURE_EPT_1GB ( 0*32+ 19) /* "ept_1gb" 1GB EPT pages */
+#define VMX_FEATURE_EPT_5LEVEL ( 0*32+ 20) /* "ept_5level" 5-level EPT paging */
/* Aggregated APIC features 24-27 */
-#define VMX_FEATURE_FLEXPRIORITY ( 0*32+ 24) /* TPR shadow + virt APIC */
-#define VMX_FEATURE_APICV ( 0*32+ 25) /* TPR shadow + APIC reg virt + virt intr delivery + posted interrupts */
+#define VMX_FEATURE_FLEXPRIORITY ( 0*32+ 24) /* "flexpriority" TPR shadow + virt APIC */
+#define VMX_FEATURE_APICV ( 0*32+ 25) /* "apicv" TPR shadow + APIC reg virt + virt intr delivery + posted interrupts */
/* VM-Functions, shifted to bits 28-31 */
-#define VMX_FEATURE_EPTP_SWITCHING ( 0*32+ 28) /* EPTP switching (in guest) */
+#define VMX_FEATURE_EPTP_SWITCHING ( 0*32+ 28) /* "eptp_switching" EPTP switching (in guest) */
/* Primary Processor-Based VM-Execution Controls, word 1 */
-#define VMX_FEATURE_INTR_WINDOW_EXITING ( 1*32+ 2) /* "" VM-Exit if INTRs are unblocked in guest */
+#define VMX_FEATURE_INTR_WINDOW_EXITING ( 1*32+ 2) /* VM-Exit if INTRs are unblocked in guest */
#define VMX_FEATURE_USE_TSC_OFFSETTING ( 1*32+ 3) /* "tsc_offset" Offset hardware TSC when read in guest */
-#define VMX_FEATURE_HLT_EXITING ( 1*32+ 7) /* "" VM-Exit on HLT */
-#define VMX_FEATURE_INVLPG_EXITING ( 1*32+ 9) /* "" VM-Exit on INVLPG */
-#define VMX_FEATURE_MWAIT_EXITING ( 1*32+ 10) /* "" VM-Exit on MWAIT */
-#define VMX_FEATURE_RDPMC_EXITING ( 1*32+ 11) /* "" VM-Exit on RDPMC */
-#define VMX_FEATURE_RDTSC_EXITING ( 1*32+ 12) /* "" VM-Exit on RDTSC */
-#define VMX_FEATURE_CR3_LOAD_EXITING ( 1*32+ 15) /* "" VM-Exit on writes to CR3 */
-#define VMX_FEATURE_CR3_STORE_EXITING ( 1*32+ 16) /* "" VM-Exit on reads from CR3 */
-#define VMX_FEATURE_TERTIARY_CONTROLS ( 1*32+ 17) /* "" Enable Tertiary VM-Execution Controls */
-#define VMX_FEATURE_CR8_LOAD_EXITING ( 1*32+ 19) /* "" VM-Exit on writes to CR8 */
-#define VMX_FEATURE_CR8_STORE_EXITING ( 1*32+ 20) /* "" VM-Exit on reads from CR8 */
+#define VMX_FEATURE_HLT_EXITING ( 1*32+ 7) /* VM-Exit on HLT */
+#define VMX_FEATURE_INVLPG_EXITING ( 1*32+ 9) /* VM-Exit on INVLPG */
+#define VMX_FEATURE_MWAIT_EXITING ( 1*32+ 10) /* VM-Exit on MWAIT */
+#define VMX_FEATURE_RDPMC_EXITING ( 1*32+ 11) /* VM-Exit on RDPMC */
+#define VMX_FEATURE_RDTSC_EXITING ( 1*32+ 12) /* VM-Exit on RDTSC */
+#define VMX_FEATURE_CR3_LOAD_EXITING ( 1*32+ 15) /* VM-Exit on writes to CR3 */
+#define VMX_FEATURE_CR3_STORE_EXITING ( 1*32+ 16) /* VM-Exit on reads from CR3 */
+#define VMX_FEATURE_TERTIARY_CONTROLS ( 1*32+ 17) /* Enable Tertiary VM-Execution Controls */
+#define VMX_FEATURE_CR8_LOAD_EXITING ( 1*32+ 19) /* VM-Exit on writes to CR8 */
+#define VMX_FEATURE_CR8_STORE_EXITING ( 1*32+ 20) /* VM-Exit on reads from CR8 */
#define VMX_FEATURE_VIRTUAL_TPR ( 1*32+ 21) /* "vtpr" TPR virtualization, a.k.a. TPR shadow */
-#define VMX_FEATURE_NMI_WINDOW_EXITING ( 1*32+ 22) /* "" VM-Exit if NMIs are unblocked in guest */
-#define VMX_FEATURE_MOV_DR_EXITING ( 1*32+ 23) /* "" VM-Exit on accesses to debug registers */
-#define VMX_FEATURE_UNCOND_IO_EXITING ( 1*32+ 24) /* "" VM-Exit on *all* IN{S} and OUT{S}*/
-#define VMX_FEATURE_USE_IO_BITMAPS ( 1*32+ 25) /* "" VM-Exit based on I/O port */
+#define VMX_FEATURE_NMI_WINDOW_EXITING ( 1*32+ 22) /* VM-Exit if NMIs are unblocked in guest */
+#define VMX_FEATURE_MOV_DR_EXITING ( 1*32+ 23) /* VM-Exit on accesses to debug registers */
+#define VMX_FEATURE_UNCOND_IO_EXITING ( 1*32+ 24) /* VM-Exit on *all* IN{S} and OUT{S}*/
+#define VMX_FEATURE_USE_IO_BITMAPS ( 1*32+ 25) /* VM-Exit based on I/O port */
#define VMX_FEATURE_MONITOR_TRAP_FLAG ( 1*32+ 27) /* "mtf" VMX single-step VM-Exits */
-#define VMX_FEATURE_USE_MSR_BITMAPS ( 1*32+ 28) /* "" VM-Exit based on MSR index */
-#define VMX_FEATURE_MONITOR_EXITING ( 1*32+ 29) /* "" VM-Exit on MONITOR (MWAIT's accomplice) */
-#define VMX_FEATURE_PAUSE_EXITING ( 1*32+ 30) /* "" VM-Exit on PAUSE (unconditionally) */
-#define VMX_FEATURE_SEC_CONTROLS ( 1*32+ 31) /* "" Enable Secondary VM-Execution Controls */
+#define VMX_FEATURE_USE_MSR_BITMAPS ( 1*32+ 28) /* VM-Exit based on MSR index */
+#define VMX_FEATURE_MONITOR_EXITING ( 1*32+ 29) /* VM-Exit on MONITOR (MWAIT's accomplice) */
+#define VMX_FEATURE_PAUSE_EXITING ( 1*32+ 30) /* VM-Exit on PAUSE (unconditionally) */
+#define VMX_FEATURE_SEC_CONTROLS ( 1*32+ 31) /* Enable Secondary VM-Execution Controls */
/* Secondary Processor-Based VM-Execution Controls, word 2 */
#define VMX_FEATURE_VIRT_APIC_ACCESSES ( 2*32+ 0) /* "vapic" Virtualize memory mapped APIC accesses */
-#define VMX_FEATURE_EPT ( 2*32+ 1) /* Extended Page Tables, a.k.a. Two-Dimensional Paging */
-#define VMX_FEATURE_DESC_EXITING ( 2*32+ 2) /* "" VM-Exit on {S,L}*DT instructions */
-#define VMX_FEATURE_RDTSCP ( 2*32+ 3) /* "" Enable RDTSCP in guest */
-#define VMX_FEATURE_VIRTUAL_X2APIC ( 2*32+ 4) /* "" Virtualize X2APIC for the guest */
-#define VMX_FEATURE_VPID ( 2*32+ 5) /* Virtual Processor ID (TLB ASID modifier) */
-#define VMX_FEATURE_WBINVD_EXITING ( 2*32+ 6) /* "" VM-Exit on WBINVD */
-#define VMX_FEATURE_UNRESTRICTED_GUEST ( 2*32+ 7) /* Allow Big Real Mode and other "invalid" states */
+#define VMX_FEATURE_EPT ( 2*32+ 1) /* "ept" Extended Page Tables, a.k.a. Two-Dimensional Paging */
+#define VMX_FEATURE_DESC_EXITING ( 2*32+ 2) /* VM-Exit on {S,L}*DT instructions */
+#define VMX_FEATURE_RDTSCP ( 2*32+ 3) /* Enable RDTSCP in guest */
+#define VMX_FEATURE_VIRTUAL_X2APIC ( 2*32+ 4) /* Virtualize X2APIC for the guest */
+#define VMX_FEATURE_VPID ( 2*32+ 5) /* "vpid" Virtual Processor ID (TLB ASID modifier) */
+#define VMX_FEATURE_WBINVD_EXITING ( 2*32+ 6) /* VM-Exit on WBINVD */
+#define VMX_FEATURE_UNRESTRICTED_GUEST ( 2*32+ 7) /* "unrestricted_guest" Allow Big Real Mode and other "invalid" states */
#define VMX_FEATURE_APIC_REGISTER_VIRT ( 2*32+ 8) /* "vapic_reg" Hardware emulation of reads to the virtual-APIC */
#define VMX_FEATURE_VIRT_INTR_DELIVERY ( 2*32+ 9) /* "vid" Evaluation and delivery of pending virtual interrupts */
#define VMX_FEATURE_PAUSE_LOOP_EXITING ( 2*32+ 10) /* "ple" Conditionally VM-Exit on PAUSE at CPL0 */
-#define VMX_FEATURE_RDRAND_EXITING ( 2*32+ 11) /* "" VM-Exit on RDRAND*/
-#define VMX_FEATURE_INVPCID ( 2*32+ 12) /* "" Enable INVPCID in guest */
-#define VMX_FEATURE_VMFUNC ( 2*32+ 13) /* "" Enable VM-Functions (leaf dependent) */
-#define VMX_FEATURE_SHADOW_VMCS ( 2*32+ 14) /* VMREAD/VMWRITE in guest can access shadow VMCS */
-#define VMX_FEATURE_ENCLS_EXITING ( 2*32+ 15) /* "" VM-Exit on ENCLS (leaf dependent) */
-#define VMX_FEATURE_RDSEED_EXITING ( 2*32+ 16) /* "" VM-Exit on RDSEED */
+#define VMX_FEATURE_RDRAND_EXITING ( 2*32+ 11) /* VM-Exit on RDRAND*/
+#define VMX_FEATURE_INVPCID ( 2*32+ 12) /* Enable INVPCID in guest */
+#define VMX_FEATURE_VMFUNC ( 2*32+ 13) /* Enable VM-Functions (leaf dependent) */
+#define VMX_FEATURE_SHADOW_VMCS ( 2*32+ 14) /* "shadow_vmcs" VMREAD/VMWRITE in guest can access shadow VMCS */
+#define VMX_FEATURE_ENCLS_EXITING ( 2*32+ 15) /* VM-Exit on ENCLS (leaf dependent) */
+#define VMX_FEATURE_RDSEED_EXITING ( 2*32+ 16) /* VM-Exit on RDSEED */
#define VMX_FEATURE_PAGE_MOD_LOGGING ( 2*32+ 17) /* "pml" Log dirty pages into buffer */
-#define VMX_FEATURE_EPT_VIOLATION_VE ( 2*32+ 18) /* "" Conditionally reflect EPT violations as #VE exceptions */
-#define VMX_FEATURE_PT_CONCEAL_VMX ( 2*32+ 19) /* "" Suppress VMX indicators in Processor Trace */
-#define VMX_FEATURE_XSAVES ( 2*32+ 20) /* "" Enable XSAVES and XRSTORS in guest */
+#define VMX_FEATURE_EPT_VIOLATION_VE ( 2*32+ 18) /* "ept_violation_ve" Conditionally reflect EPT violations as #VE exceptions */
+#define VMX_FEATURE_PT_CONCEAL_VMX ( 2*32+ 19) /* Suppress VMX indicators in Processor Trace */
+#define VMX_FEATURE_XSAVES ( 2*32+ 20) /* Enable XSAVES and XRSTORS in guest */
#define VMX_FEATURE_MODE_BASED_EPT_EXEC ( 2*32+ 22) /* "ept_mode_based_exec" Enable separate EPT EXEC bits for supervisor vs. user */
-#define VMX_FEATURE_PT_USE_GPA ( 2*32+ 24) /* "" Processor Trace logs GPAs */
-#define VMX_FEATURE_TSC_SCALING ( 2*32+ 25) /* Scale hardware TSC when read in guest */
-#define VMX_FEATURE_USR_WAIT_PAUSE ( 2*32+ 26) /* Enable TPAUSE, UMONITOR, UMWAIT in guest */
-#define VMX_FEATURE_ENCLV_EXITING ( 2*32+ 28) /* "" VM-Exit on ENCLV (leaf dependent) */
-#define VMX_FEATURE_BUS_LOCK_DETECTION ( 2*32+ 30) /* "" VM-Exit when bus lock caused */
-#define VMX_FEATURE_NOTIFY_VM_EXITING ( 2*32+ 31) /* VM-Exit when no event windows after notify window */
+#define VMX_FEATURE_PT_USE_GPA ( 2*32+ 24) /* Processor Trace logs GPAs */
+#define VMX_FEATURE_TSC_SCALING ( 2*32+ 25) /* "tsc_scaling" Scale hardware TSC when read in guest */
+#define VMX_FEATURE_USR_WAIT_PAUSE ( 2*32+ 26) /* "usr_wait_pause" Enable TPAUSE, UMONITOR, UMWAIT in guest */
+#define VMX_FEATURE_ENCLV_EXITING ( 2*32+ 28) /* VM-Exit on ENCLV (leaf dependent) */
+#define VMX_FEATURE_BUS_LOCK_DETECTION ( 2*32+ 30) /* VM-Exit when bus lock caused */
+#define VMX_FEATURE_NOTIFY_VM_EXITING ( 2*32+ 31) /* "notify_vm_exiting" VM-Exit when no event windows after notify window */
/* Tertiary Processor-Based VM-Execution Controls, word 3 */
-#define VMX_FEATURE_IPI_VIRT ( 3*32+ 4) /* Enable IPI virtualization */
+#define VMX_FEATURE_IPI_VIRT ( 3*32+ 4) /* "ipi_virt" Enable IPI virtualization */
#endif /* _ASM_X86_VMXFEATURES_H */
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index 183e98e49ab9..9d9af37f7cab 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -26,6 +26,8 @@
*/
#define DECLARE_VVAR(offset, type, name) \
EMIT_VVAR(name, offset)
+#define DECLARE_VVAR_SINGLE(offset, type, name) \
+ EMIT_VVAR(name, offset)
#else
@@ -37,6 +39,10 @@ extern char __vvar_page;
extern type timens_ ## name[CS_BASES] \
__attribute__((visibility("hidden"))); \
+#define DECLARE_VVAR_SINGLE(offset, type, name) \
+ extern type vvar_ ## name \
+ __attribute__((visibility("hidden"))); \
+
#define VVAR(name) (vvar_ ## name)
#define TIMENS(name) (timens_ ## name)
@@ -44,12 +50,22 @@ extern char __vvar_page;
type name[CS_BASES] \
__attribute__((section(".vvar_" #name), aligned(16))) __visible
+#define DEFINE_VVAR_SINGLE(type, name) \
+ type name \
+ __attribute__((section(".vvar_" #name), aligned(16))) __visible
+
#endif
/* DECLARE_VVAR(offset, type, name) */
DECLARE_VVAR(128, struct vdso_data, _vdso_data)
+#if !defined(_SINGLE_DATA)
+#define _SINGLE_DATA
+DECLARE_VVAR_SINGLE(640, struct vdso_rng_data, _vdso_rng_data)
+#endif
+
#undef DECLARE_VVAR
+#undef DECLARE_VVAR_SINGLE
#endif
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h
index e8d7d4941c4c..422a47746657 100644
--- a/arch/x86/include/asm/word-at-a-time.h
+++ b/arch/x86/include/asm/word-at-a-time.h
@@ -5,45 +5,12 @@
#include <linux/bitops.h>
#include <linux/wordpart.h>
-/*
- * This is largely generic for little-endian machines, but the
- * optimal byte mask counting is probably going to be something
- * that is architecture-specific. If you have a reliably fast
- * bit count instruction, that might be better than the multiply
- * and shift, for example.
- */
struct word_at_a_time {
const unsigned long one_bits, high_bits;
};
#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
-#ifdef CONFIG_64BIT
-
-/*
- * Jan Achrenius on G+: microoptimized version of
- * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56"
- * that works for the bytemasks without having to
- * mask them first.
- */
-static inline long count_masked_bytes(unsigned long mask)
-{
- return mask*0x0001020304050608ul >> 56;
-}
-
-#else /* 32-bit case */
-
-/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
-static inline long count_masked_bytes(long mask)
-{
- /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
- long a = (0x0ff0001+mask) >> 23;
- /* Fix the 1 for 00 case */
- return a & mask;
-}
-
-#endif
-
/* Return nonzero if it has a zero */
static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
{
@@ -57,6 +24,22 @@ static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits,
return bits;
}
+#ifdef CONFIG_64BIT
+
+/* Keep the initial has_zero() value for both bitmask and size calc */
+#define create_zero_mask(bits) (bits)
+
+static inline unsigned long zero_bytemask(unsigned long bits)
+{
+ bits = (bits - 1) & ~bits;
+ return bits >> 7;
+}
+
+#define find_zero(bits) (__ffs(bits) >> 3)
+
+#else
+
+/* Create the final mask for both bytemask and size */
static inline unsigned long create_zero_mask(unsigned long bits)
{
bits = (bits - 1) & ~bits;
@@ -66,11 +49,17 @@ static inline unsigned long create_zero_mask(unsigned long bits)
/* The mask we created is directly usable as a bytemask */
#define zero_bytemask(mask) (mask)
+/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
static inline unsigned long find_zero(unsigned long mask)
{
- return count_masked_bytes(mask);
+ /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
+ long a = (0x0ff0001+mask) >> 23;
+ /* Fix the 1 for 00 case */
+ return a & mask;
}
+#endif
+
/*
* Load an unaligned word from kernel space.
*
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 6149eabe200f..213cf5379a5a 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -149,12 +149,22 @@ struct x86_init_acpi {
* @enc_status_change_finish Notify HV after the encryption status of a range is changed
* @enc_tlb_flush_required Returns true if a TLB flush is needed before changing page encryption status
* @enc_cache_flush_required Returns true if a cache flush is needed before changing page encryption status
+ * @enc_kexec_begin Begin the two-step process of converting shared memory back
+ * to private. It stops the new conversions from being started
+ * and waits in-flight conversions to finish, if possible.
+ * @enc_kexec_finish Finish the two-step process of converting shared memory to
+ * private. All memory is private after the call when
+ * the function returns.
+ * It is called on only one CPU while the others are shut down
+ * and with interrupts disabled.
*/
struct x86_guest {
- bool (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
- bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+ int (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+ int (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
bool (*enc_tlb_flush_required)(bool enc);
bool (*enc_cache_flush_required)(void);
+ void (*enc_kexec_begin)(void);
+ void (*enc_kexec_finish)(void);
};
/**
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index ef11aa4cab42..bf57a824f722 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -106,6 +106,7 @@ struct kvm_ioapic_state {
#define KVM_RUN_X86_SMM (1 << 0)
#define KVM_RUN_X86_BUS_LOCK (1 << 1)
+#define KVM_RUN_X86_GUEST_MODE (1 << 2)
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
@@ -457,8 +458,13 @@ struct kvm_sync_regs {
#define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001
-/* attributes for system fd (group 0) */
-#define KVM_X86_XCOMP_GUEST_SUPP 0
+/* vendor-independent attributes for system fd (group 0) */
+#define KVM_X86_GRP_SYSTEM 0
+# define KVM_X86_XCOMP_GUEST_SUPP 0
+
+/* vendor-specific groups and attributes for system fd */
+#define KVM_X86_GRP_SEV 1
+# define KVM_X86_SEV_VMSA_FEATURES 0
struct kvm_vmx_nested_state_data {
__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
@@ -689,6 +695,14 @@ enum sev_cmd_id {
/* Guest Migration Extension */
KVM_SEV_SEND_CANCEL,
+ /* Second time is the charm; improved versions of the above ioctls. */
+ KVM_SEV_INIT2,
+
+ /* SNP-specific commands */
+ KVM_SEV_SNP_LAUNCH_START = 100,
+ KVM_SEV_SNP_LAUNCH_UPDATE,
+ KVM_SEV_SNP_LAUNCH_FINISH,
+
KVM_SEV_NR_MAX,
};
@@ -700,6 +714,14 @@ struct kvm_sev_cmd {
__u32 sev_fd;
};
+struct kvm_sev_init {
+ __u64 vmsa_features;
+ __u32 flags;
+ __u16 ghcb_version;
+ __u16 pad1;
+ __u32 pad2[8];
+};
+
struct kvm_sev_launch_start {
__u32 handle;
__u32 policy;
@@ -808,6 +830,48 @@ struct kvm_sev_receive_update_data {
__u32 pad2;
};
+struct kvm_sev_snp_launch_start {
+ __u64 policy;
+ __u8 gosvw[16];
+ __u16 flags;
+ __u8 pad0[6];
+ __u64 pad1[4];
+};
+
+/* Kept in sync with firmware values for simplicity. */
+#define KVM_SEV_SNP_PAGE_TYPE_NORMAL 0x1
+#define KVM_SEV_SNP_PAGE_TYPE_ZERO 0x3
+#define KVM_SEV_SNP_PAGE_TYPE_UNMEASURED 0x4
+#define KVM_SEV_SNP_PAGE_TYPE_SECRETS 0x5
+#define KVM_SEV_SNP_PAGE_TYPE_CPUID 0x6
+
+struct kvm_sev_snp_launch_update {
+ __u64 gfn_start;
+ __u64 uaddr;
+ __u64 len;
+ __u8 type;
+ __u8 pad0;
+ __u16 flags;
+ __u32 pad1;
+ __u64 pad2[4];
+};
+
+#define KVM_SEV_SNP_ID_BLOCK_SIZE 96
+#define KVM_SEV_SNP_ID_AUTH_SIZE 4096
+#define KVM_SEV_SNP_FINISH_DATA_SIZE 32
+
+struct kvm_sev_snp_launch_finish {
+ __u64 id_block_uaddr;
+ __u64 id_auth_uaddr;
+ __u8 id_block_en;
+ __u8 auth_key_en;
+ __u8 vcek_disabled;
+ __u8 host_data[KVM_SEV_SNP_FINISH_DATA_SIZE];
+ __u8 pad0[3];
+ __u16 flags;
+ __u64 pad1[4];
+};
+
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
@@ -856,5 +920,8 @@ struct kvm_hyperv_eventfd {
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_SW_PROTECTED_VM 1
+#define KVM_X86_SEV_VM 2
+#define KVM_X86_SEV_ES_VM 3
+#define KVM_X86_SNP_VM 4
#endif /* _ASM_X86_KVM_H */
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index 80e1df482337..1814b413fd57 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -115,6 +115,7 @@
#define SVM_VMGEXIT_AP_CREATE_ON_INIT 0
#define SVM_VMGEXIT_AP_CREATE 1
#define SVM_VMGEXIT_AP_DESTROY 2
+#define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018
#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
#define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe
#define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code) \
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 74077694da7d..a847180836e4 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -17,7 +17,6 @@ CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_early_printk.o = -pg
CFLAGS_REMOVE_head64.o = -pg
CFLAGS_REMOVE_head32.o = -pg
-CFLAGS_REMOVE_sev.o = -pg
CFLAGS_REMOVE_rethook.o = -pg
endif
@@ -26,21 +25,18 @@ KASAN_SANITIZE_dumpstack.o := n
KASAN_SANITIZE_dumpstack_$(BITS).o := n
KASAN_SANITIZE_stacktrace.o := n
KASAN_SANITIZE_paravirt.o := n
-KASAN_SANITIZE_sev.o := n
# With some compiler versions the generated code results in boot hangs, caused
# by several compilation units. To be safe, disable all instrumentation.
KCSAN_SANITIZE := n
KMSAN_SANITIZE_head$(BITS).o := n
KMSAN_SANITIZE_nmi.o := n
-KMSAN_SANITIZE_sev.o := n
# If instrumentation of the following files is enabled, boot hangs during
# first second.
KCOV_INSTRUMENT_head$(BITS).o := n
-KCOV_INSTRUMENT_sev.o := n
-CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
+CFLAGS_irq.o := -I $(src)/../include/asm/trace
obj-y += head_$(BITS).o
obj-y += head$(BITS).o
@@ -62,7 +58,7 @@ obj-$(CONFIG_X86_64) += sys_x86_64.o
obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
obj-$(CONFIG_SYSFS) += ksysfs.o
obj-y += bootflag.o e820.o
-obj-y += pci-dma.o quirks.o topology.o kdebugfs.o
+obj-y += pci-dma.o quirks.o kdebugfs.o
obj-y += alternative.o i8253.o hw_breakpoint.o
obj-y += tsc.o tsc_msr.o io_delay.o rtc.o
obj-y += resource.o
@@ -142,8 +138,6 @@ 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.o
-
obj-$(CONFIG_CFI_CLANG) += cfi.o
obj-$(CONFIG_CALL_THUNKS) += callthunks.o
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
index fc17b3f136fe..842a5f449404 100644
--- a/arch/x86/kernel/acpi/Makefile
+++ b/arch/x86/kernel/acpi/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_ACPI) += boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
obj-$(CONFIG_ACPI_APEI) += apei.o
obj-$(CONFIG_ACPI_CPPC_LIB) += cppc.o
+obj-$(CONFIG_ACPI_MADT_WAKEUP) += madt_wakeup.o madt_playdead.o
ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += cstate.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 4bf82dbd2a6b..9f4618dcd704 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -67,13 +67,6 @@ static bool has_lapic_cpus __initdata;
static bool acpi_support_online_capable;
#endif
-#ifdef CONFIG_X86_64
-/* Physical address of the Multiprocessor Wakeup Structure mailbox */
-static u64 acpi_mp_wake_mailbox_paddr;
-/* Virtual address of the Multiprocessor Wakeup Structure mailbox */
-static struct acpi_madt_multiproc_wakeup_mailbox *acpi_mp_wake_mailbox;
-#endif
-
#ifdef CONFIG_X86_IO_APIC
/*
* Locks related to IOAPIC hotplug
@@ -341,60 +334,6 @@ acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long e
return 0;
}
-
-#ifdef CONFIG_X86_64
-static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip)
-{
- /*
- * Remap mailbox memory only for the first call to acpi_wakeup_cpu().
- *
- * Wakeup of secondary CPUs is fully serialized in the core code.
- * No need to protect acpi_mp_wake_mailbox from concurrent accesses.
- */
- if (!acpi_mp_wake_mailbox) {
- acpi_mp_wake_mailbox = memremap(acpi_mp_wake_mailbox_paddr,
- sizeof(*acpi_mp_wake_mailbox),
- MEMREMAP_WB);
- }
-
- /*
- * Mailbox memory is shared between the firmware and OS. Firmware will
- * listen on mailbox command address, and once it receives the wakeup
- * command, the CPU associated with the given apicid will be booted.
- *
- * The value of 'apic_id' and 'wakeup_vector' must be visible to the
- * firmware before the wakeup command is visible. smp_store_release()
- * ensures ordering and visibility.
- */
- acpi_mp_wake_mailbox->apic_id = apicid;
- acpi_mp_wake_mailbox->wakeup_vector = start_ip;
- smp_store_release(&acpi_mp_wake_mailbox->command,
- ACPI_MP_WAKE_COMMAND_WAKEUP);
-
- /*
- * Wait for the CPU to wake up.
- *
- * The CPU being woken up is essentially in a spin loop waiting to be
- * woken up. It should not take long for it wake up and acknowledge by
- * zeroing out ->command.
- *
- * ACPI specification doesn't provide any guidance on how long kernel
- * has to wait for a wake up acknowledgement. It also doesn't provide
- * a way to cancel a wake up request if it takes too long.
- *
- * In TDX environment, the VMM has control over how long it takes to
- * wake up secondary. It can postpone scheduling secondary vCPU
- * indefinitely. Giving up on wake up request and reporting error opens
- * possible attack vector for VMM: it can wake up a secondary CPU when
- * kernel doesn't expect it. Wait until positive result of the wake up
- * request.
- */
- while (READ_ONCE(acpi_mp_wake_mailbox->command))
- cpu_relax();
-
- return 0;
-}
-#endif /* CONFIG_X86_64 */
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_IO_APIC
@@ -1124,29 +1063,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
}
return 0;
}
-
-#ifdef CONFIG_X86_64
-static int __init acpi_parse_mp_wake(union acpi_subtable_headers *header,
- const unsigned long end)
-{
- struct acpi_madt_multiproc_wakeup *mp_wake;
-
- if (!IS_ENABLED(CONFIG_SMP))
- return -ENODEV;
-
- mp_wake = (struct acpi_madt_multiproc_wakeup *)header;
- if (BAD_MADT_ENTRY(mp_wake, end))
- return -EINVAL;
-
- acpi_table_print_madt_entry(&header->common);
-
- acpi_mp_wake_mailbox_paddr = mp_wake->base_address;
-
- apic_update_callback(wakeup_secondary_cpu_64, acpi_wakeup_cpu);
-
- return 0;
-}
-#endif /* CONFIG_X86_64 */
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_IO_APIC
@@ -1343,7 +1259,7 @@ static void __init acpi_process_madt(void)
smp_found_config = 1;
}
-#ifdef CONFIG_X86_64
+#ifdef CONFIG_ACPI_MADT_WAKEUP
/*
* Parse MADT MP Wake entry.
*/
diff --git a/arch/x86/kernel/acpi/madt_playdead.S b/arch/x86/kernel/acpi/madt_playdead.S
new file mode 100644
index 000000000000..4e498d28cdc8
--- /dev/null
+++ b/arch/x86/kernel/acpi/madt_playdead.S
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/nospec-branch.h>
+#include <asm/page_types.h>
+#include <asm/processor-flags.h>
+
+ .text
+ .align PAGE_SIZE
+
+/*
+ * asm_acpi_mp_play_dead() - Hand over control of the CPU to the BIOS
+ *
+ * rdi: Address of the ACPI MADT MPWK ResetVector
+ * rsi: PGD of the identity mapping
+ */
+SYM_FUNC_START(asm_acpi_mp_play_dead)
+ /* Turn off global entries. Following CR3 write will flush them. */
+ movq %cr4, %rdx
+ andq $~(X86_CR4_PGE), %rdx
+ movq %rdx, %cr4
+
+ /* Switch to identity mapping */
+ movq %rsi, %cr3
+
+ /* Jump to reset vector */
+ ANNOTATE_RETPOLINE_SAFE
+ jmp *%rdi
+SYM_FUNC_END(asm_acpi_mp_play_dead)
diff --git a/arch/x86/kernel/acpi/madt_wakeup.c b/arch/x86/kernel/acpi/madt_wakeup.c
new file mode 100644
index 000000000000..6cfe762be28b
--- /dev/null
+++ b/arch/x86/kernel/acpi/madt_wakeup.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/acpi.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kexec.h>
+#include <linux/memblock.h>
+#include <linux/pgtable.h>
+#include <linux/sched/hotplug.h>
+#include <asm/apic.h>
+#include <asm/barrier.h>
+#include <asm/init.h>
+#include <asm/intel_pt.h>
+#include <asm/nmi.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+
+/* Physical address of the Multiprocessor Wakeup Structure mailbox */
+static u64 acpi_mp_wake_mailbox_paddr __ro_after_init;
+
+/* Virtual address of the Multiprocessor Wakeup Structure mailbox */
+static struct acpi_madt_multiproc_wakeup_mailbox *acpi_mp_wake_mailbox __ro_after_init;
+
+static u64 acpi_mp_pgd __ro_after_init;
+static u64 acpi_mp_reset_vector_paddr __ro_after_init;
+
+static void acpi_mp_stop_this_cpu(void)
+{
+ asm_acpi_mp_play_dead(acpi_mp_reset_vector_paddr, acpi_mp_pgd);
+}
+
+static void acpi_mp_play_dead(void)
+{
+ play_dead_common();
+ asm_acpi_mp_play_dead(acpi_mp_reset_vector_paddr, acpi_mp_pgd);
+}
+
+static void acpi_mp_cpu_die(unsigned int cpu)
+{
+ u32 apicid = per_cpu(x86_cpu_to_apicid, cpu);
+ unsigned long timeout;
+
+ /*
+ * Use TEST mailbox command to prove that BIOS got control over
+ * the CPU before declaring it dead.
+ *
+ * BIOS has to clear 'command' field of the mailbox.
+ */
+ acpi_mp_wake_mailbox->apic_id = apicid;
+ smp_store_release(&acpi_mp_wake_mailbox->command,
+ ACPI_MP_WAKE_COMMAND_TEST);
+
+ /* Don't wait longer than a second. */
+ timeout = USEC_PER_SEC;
+ while (READ_ONCE(acpi_mp_wake_mailbox->command) && --timeout)
+ udelay(1);
+
+ if (!timeout)
+ pr_err("Failed to hand over CPU %d to BIOS\n", cpu);
+}
+
+/* The argument is required to match type of x86_mapping_info::alloc_pgt_page */
+static void __init *alloc_pgt_page(void *dummy)
+{
+ return memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+}
+
+static void __init free_pgt_page(void *pgt, void *dummy)
+{
+ return memblock_free(pgt, PAGE_SIZE);
+}
+
+/*
+ * Make sure asm_acpi_mp_play_dead() is present in the identity mapping at
+ * the same place as in the kernel page tables. asm_acpi_mp_play_dead() switches
+ * to the identity mapping and the function has be present at the same spot in
+ * the virtual address space before and after switching page tables.
+ */
+static int __init init_transition_pgtable(pgd_t *pgd)
+{
+ pgprot_t prot = PAGE_KERNEL_EXEC_NOENC;
+ unsigned long vaddr, paddr;
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ vaddr = (unsigned long)asm_acpi_mp_play_dead;
+ pgd += pgd_index(vaddr);
+ if (!pgd_present(*pgd)) {
+ p4d = (p4d_t *)alloc_pgt_page(NULL);
+ if (!p4d)
+ return -ENOMEM;
+ set_pgd(pgd, __pgd(__pa(p4d) | _KERNPG_TABLE));
+ }
+ p4d = p4d_offset(pgd, vaddr);
+ if (!p4d_present(*p4d)) {
+ pud = (pud_t *)alloc_pgt_page(NULL);
+ if (!pud)
+ return -ENOMEM;
+ set_p4d(p4d, __p4d(__pa(pud) | _KERNPG_TABLE));
+ }
+ pud = pud_offset(p4d, vaddr);
+ if (!pud_present(*pud)) {
+ pmd = (pmd_t *)alloc_pgt_page(NULL);
+ if (!pmd)
+ return -ENOMEM;
+ set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
+ }
+ pmd = pmd_offset(pud, vaddr);
+ if (!pmd_present(*pmd)) {
+ pte = (pte_t *)alloc_pgt_page(NULL);
+ if (!pte)
+ return -ENOMEM;
+ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
+ }
+ pte = pte_offset_kernel(pmd, vaddr);
+
+ paddr = __pa(vaddr);
+ set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, prot));
+
+ return 0;
+}
+
+static int __init acpi_mp_setup_reset(u64 reset_vector)
+{
+ struct x86_mapping_info info = {
+ .alloc_pgt_page = alloc_pgt_page,
+ .free_pgt_page = free_pgt_page,
+ .page_flag = __PAGE_KERNEL_LARGE_EXEC,
+ .kernpg_flag = _KERNPG_TABLE_NOENC,
+ };
+ pgd_t *pgd;
+
+ pgd = alloc_pgt_page(NULL);
+ if (!pgd)
+ return -ENOMEM;
+
+ for (int i = 0; i < nr_pfn_mapped; i++) {
+ unsigned long mstart, mend;
+
+ mstart = pfn_mapped[i].start << PAGE_SHIFT;
+ mend = pfn_mapped[i].end << PAGE_SHIFT;
+ if (kernel_ident_mapping_init(&info, pgd, mstart, mend)) {
+ kernel_ident_mapping_free(&info, pgd);
+ return -ENOMEM;
+ }
+ }
+
+ if (kernel_ident_mapping_init(&info, pgd,
+ PAGE_ALIGN_DOWN(reset_vector),
+ PAGE_ALIGN(reset_vector + 1))) {
+ kernel_ident_mapping_free(&info, pgd);
+ return -ENOMEM;
+ }
+
+ if (init_transition_pgtable(pgd)) {
+ kernel_ident_mapping_free(&info, pgd);
+ return -ENOMEM;
+ }
+
+ smp_ops.play_dead = acpi_mp_play_dead;
+ smp_ops.stop_this_cpu = acpi_mp_stop_this_cpu;
+ smp_ops.cpu_die = acpi_mp_cpu_die;
+
+ acpi_mp_reset_vector_paddr = reset_vector;
+ acpi_mp_pgd = __pa(pgd);
+
+ return 0;
+}
+
+static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip)
+{
+ if (!acpi_mp_wake_mailbox_paddr) {
+ pr_warn_once("No MADT mailbox: cannot bringup secondary CPUs. Booting with kexec?\n");
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * Remap mailbox memory only for the first call to acpi_wakeup_cpu().
+ *
+ * Wakeup of secondary CPUs is fully serialized in the core code.
+ * No need to protect acpi_mp_wake_mailbox from concurrent accesses.
+ */
+ if (!acpi_mp_wake_mailbox) {
+ acpi_mp_wake_mailbox = memremap(acpi_mp_wake_mailbox_paddr,
+ sizeof(*acpi_mp_wake_mailbox),
+ MEMREMAP_WB);
+ }
+
+ /*
+ * Mailbox memory is shared between the firmware and OS. Firmware will
+ * listen on mailbox command address, and once it receives the wakeup
+ * command, the CPU associated with the given apicid will be booted.
+ *
+ * The value of 'apic_id' and 'wakeup_vector' must be visible to the
+ * firmware before the wakeup command is visible. smp_store_release()
+ * ensures ordering and visibility.
+ */
+ acpi_mp_wake_mailbox->apic_id = apicid;
+ acpi_mp_wake_mailbox->wakeup_vector = start_ip;
+ smp_store_release(&acpi_mp_wake_mailbox->command,
+ ACPI_MP_WAKE_COMMAND_WAKEUP);
+
+ /*
+ * Wait for the CPU to wake up.
+ *
+ * The CPU being woken up is essentially in a spin loop waiting to be
+ * woken up. It should not take long for it wake up and acknowledge by
+ * zeroing out ->command.
+ *
+ * ACPI specification doesn't provide any guidance on how long kernel
+ * has to wait for a wake up acknowledgment. It also doesn't provide
+ * a way to cancel a wake up request if it takes too long.
+ *
+ * In TDX environment, the VMM has control over how long it takes to
+ * wake up secondary. It can postpone scheduling secondary vCPU
+ * indefinitely. Giving up on wake up request and reporting error opens
+ * possible attack vector for VMM: it can wake up a secondary CPU when
+ * kernel doesn't expect it. Wait until positive result of the wake up
+ * request.
+ */
+ while (READ_ONCE(acpi_mp_wake_mailbox->command))
+ cpu_relax();
+
+ return 0;
+}
+
+static void acpi_mp_disable_offlining(struct acpi_madt_multiproc_wakeup *mp_wake)
+{
+ cpu_hotplug_disable_offlining();
+
+ /*
+ * ACPI MADT doesn't allow to offline a CPU after it was onlined. This
+ * limits kexec: the second kernel won't be able to use more than one CPU.
+ *
+ * To prevent a kexec kernel from onlining secondary CPUs invalidate the
+ * mailbox address in the ACPI MADT wakeup structure which prevents a
+ * kexec kernel to use it.
+ *
+ * This is safe as the booting kernel has the mailbox address cached
+ * already and acpi_wakeup_cpu() uses the cached value to bring up the
+ * secondary CPUs.
+ *
+ * Note: This is a Linux specific convention and not covered by the
+ * ACPI specification.
+ */
+ mp_wake->mailbox_address = 0;
+}
+
+int __init acpi_parse_mp_wake(union acpi_subtable_headers *header,
+ const unsigned long end)
+{
+ struct acpi_madt_multiproc_wakeup *mp_wake;
+
+ mp_wake = (struct acpi_madt_multiproc_wakeup *)header;
+
+ /*
+ * Cannot use the standard BAD_MADT_ENTRY() to sanity check the @mp_wake
+ * entry. 'sizeof (struct acpi_madt_multiproc_wakeup)' can be larger
+ * than the actual size of the MP wakeup entry in ACPI table because the
+ * 'reset_vector' is only available in the V1 MP wakeup structure.
+ */
+ if (!mp_wake)
+ return -EINVAL;
+ if (end - (unsigned long)mp_wake < ACPI_MADT_MP_WAKEUP_SIZE_V0)
+ return -EINVAL;
+ if (mp_wake->header.length < ACPI_MADT_MP_WAKEUP_SIZE_V0)
+ return -EINVAL;
+
+ acpi_table_print_madt_entry(&header->common);
+
+ acpi_mp_wake_mailbox_paddr = mp_wake->mailbox_address;
+
+ if (mp_wake->version >= ACPI_MADT_MP_WAKEUP_VERSION_V1 &&
+ mp_wake->header.length >= ACPI_MADT_MP_WAKEUP_SIZE_V1) {
+ if (acpi_mp_setup_reset(mp_wake->reset_vector)) {
+ pr_warn("Failed to setup MADT reset vector\n");
+ acpi_mp_disable_offlining(mp_wake);
+ }
+ } else {
+ /*
+ * CPU offlining requires version 1 of the ACPI MADT wakeup
+ * structure.
+ */
+ acpi_mp_disable_offlining(mp_wake);
+ }
+
+ apic_update_callback(wakeup_secondary_cpu_64, acpi_wakeup_cpu);
+
+ return 0;
+}
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 45a280f2161c..d17518ca19b8 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -125,6 +125,20 @@ const unsigned char * const x86_nops[ASM_NOP_MAX+1] =
};
/*
+ * Nomenclature for variable names to simplify and clarify this code and ease
+ * any potential staring at it:
+ *
+ * @instr: source address of the original instructions in the kernel text as
+ * generated by the compiler.
+ *
+ * @buf: temporary buffer on which the patching operates. This buffer is
+ * eventually text-poked into the kernel image.
+ *
+ * @replacement/@repl: pointer to the opcodes which are replacing @instr, located
+ * in the .altinstr_replacement section.
+ */
+
+/*
* Fill the buffer with a single effective instruction of size @len.
*
* In order not to issue an ORC stack depth tracking CFI entry (Call Frame Info)
@@ -133,28 +147,28 @@ const unsigned char * const x86_nops[ASM_NOP_MAX+1] =
* each single-byte NOPs). If @len to fill out is > ASM_NOP_MAX, pad with INT3 and
* *jump* over instead of executing long and daft NOPs.
*/
-static void add_nop(u8 *instr, unsigned int len)
+static void add_nop(u8 *buf, unsigned int len)
{
- u8 *target = instr + len;
+ u8 *target = buf + len;
if (!len)
return;
if (len <= ASM_NOP_MAX) {
- memcpy(instr, x86_nops[len], len);
+ memcpy(buf, x86_nops[len], len);
return;
}
if (len < 128) {
- __text_gen_insn(instr, JMP8_INSN_OPCODE, instr, target, JMP8_INSN_SIZE);
- instr += JMP8_INSN_SIZE;
+ __text_gen_insn(buf, JMP8_INSN_OPCODE, buf, target, JMP8_INSN_SIZE);
+ buf += JMP8_INSN_SIZE;
} else {
- __text_gen_insn(instr, JMP32_INSN_OPCODE, instr, target, JMP32_INSN_SIZE);
- instr += JMP32_INSN_SIZE;
+ __text_gen_insn(buf, JMP32_INSN_OPCODE, buf, target, JMP32_INSN_SIZE);
+ buf += JMP32_INSN_SIZE;
}
- for (;instr < target; instr++)
- *instr = INT3_INSN_OPCODE;
+ for (;buf < target; buf++)
+ *buf = INT3_INSN_OPCODE;
}
extern s32 __retpoline_sites[], __retpoline_sites_end[];
@@ -187,12 +201,12 @@ static bool insn_is_nop(struct insn *insn)
* Find the offset of the first non-NOP instruction starting at @offset
* but no further than @len.
*/
-static int skip_nops(u8 *instr, int offset, int len)
+static int skip_nops(u8 *buf, int offset, int len)
{
struct insn insn;
for (; offset < len; offset += insn.length) {
- if (insn_decode_kernel(&insn, &instr[offset]))
+ if (insn_decode_kernel(&insn, &buf[offset]))
break;
if (!insn_is_nop(&insn))
@@ -203,66 +217,32 @@ static int skip_nops(u8 *instr, int offset, int len)
}
/*
- * Optimize a sequence of NOPs, possibly preceded by an unconditional jump
- * to the end of the NOP sequence into a single NOP.
- */
-static bool
-__optimize_nops(u8 *instr, size_t len, struct insn *insn, int *next, int *prev, int *target)
-{
- int i = *next - insn->length;
-
- switch (insn->opcode.bytes[0]) {
- case JMP8_INSN_OPCODE:
- case JMP32_INSN_OPCODE:
- *prev = i;
- *target = *next + insn->immediate.value;
- return false;
- }
-
- if (insn_is_nop(insn)) {
- int nop = i;
-
- *next = skip_nops(instr, *next, len);
- if (*target && *next == *target)
- nop = *prev;
-
- add_nop(instr + nop, *next - nop);
- DUMP_BYTES(ALT, instr, len, "%px: [%d:%d) optimized NOPs: ", instr, nop, *next);
- return true;
- }
-
- *target = 0;
- return false;
-}
-
-/*
* "noinline" to cause control flow change and thus invalidate I$ and
* cause refetch after modification.
*/
-static void __init_or_module noinline optimize_nops(u8 *instr, size_t len)
+static void noinline optimize_nops(const u8 * const instr, u8 *buf, size_t len)
{
- int prev, target = 0;
-
for (int next, i = 0; i < len; i = next) {
struct insn insn;
- if (insn_decode_kernel(&insn, &instr[i]))
+ if (insn_decode_kernel(&insn, &buf[i]))
return;
next = i + insn.length;
- __optimize_nops(instr, len, &insn, &next, &prev, &target);
- }
-}
+ if (insn_is_nop(&insn)) {
+ int nop = i;
-static void __init_or_module noinline optimize_nops_inplace(u8 *instr, size_t len)
-{
- unsigned long flags;
+ /* Has the NOP already been optimized? */
+ if (i + insn.length == len)
+ return;
- local_irq_save(flags);
- optimize_nops(instr, len);
- sync_core();
- local_irq_restore(flags);
+ next = skip_nops(buf, next, len);
+
+ add_nop(buf + nop, next - nop);
+ DUMP_BYTES(ALT, buf, len, "%px: [%d:%d) optimized NOPs: ", instr, nop, next);
+ }
+ }
}
/*
@@ -335,11 +315,9 @@ bool need_reloc(unsigned long offset, u8 *src, size_t src_len)
return (target < src || target > src + src_len);
}
-void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
+static void __apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len)
{
- int prev, target = 0;
-
- for (int next, i = 0; i < len; i = next) {
+ for (int next, i = 0; i < instrlen; i = next) {
struct insn insn;
if (WARN_ON_ONCE(insn_decode_kernel(&insn, &buf[i])))
@@ -347,9 +325,6 @@ void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
next = i + insn.length;
- if (__optimize_nops(buf, len, &insn, &next, &prev, &target))
- continue;
-
switch (insn.opcode.bytes[0]) {
case 0x0f:
if (insn.opcode.bytes[1] < 0x80 ||
@@ -361,10 +336,10 @@ void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
case JMP8_INSN_OPCODE:
case JMP32_INSN_OPCODE:
case CALL_INSN_OPCODE:
- if (need_reloc(next + insn.immediate.value, src, src_len)) {
+ if (need_reloc(next + insn.immediate.value, repl, repl_len)) {
apply_reloc(insn.immediate.nbytes,
buf + i + insn_offset_immediate(&insn),
- src - dest);
+ repl - instr);
}
/*
@@ -372,7 +347,7 @@ void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
*/
if (insn.opcode.bytes[0] == JMP32_INSN_OPCODE) {
s32 imm = insn.immediate.value;
- imm += src - dest;
+ imm += repl - instr;
imm += JMP32_INSN_SIZE - JMP8_INSN_SIZE;
if ((imm >> 31) == (imm >> 7)) {
buf[i+0] = JMP8_INSN_OPCODE;
@@ -385,15 +360,21 @@ void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
}
if (insn_rip_relative(&insn)) {
- if (need_reloc(next + insn.displacement.value, src, src_len)) {
+ if (need_reloc(next + insn.displacement.value, repl, repl_len)) {
apply_reloc(insn.displacement.nbytes,
buf + i + insn_offset_displacement(&insn),
- src - dest);
+ repl - instr);
}
}
}
}
+void apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len)
+{
+ __apply_relocation(buf, instr, instrlen, repl, repl_len);
+ optimize_nops(instr, buf, instrlen);
+}
+
/* Low-level backend functions usable from alternative code replacements. */
DEFINE_ASM_FUNC(nop_func, "", .entry.text);
EXPORT_SYMBOL_GPL(nop_func);
@@ -451,6 +432,11 @@ static int alt_replace_call(u8 *instr, u8 *insn_buff, struct alt_instr *a)
return 5;
}
+static inline u8 * instr_va(struct alt_instr *i)
+{
+ return (u8 *)&i->instr_offset + i->instr_offset;
+}
+
/*
* Replace instructions with better alternatives for this CPU type. This runs
* before SMP is initialized to avoid SMP problems with self modifying code.
@@ -464,9 +450,9 @@ static int alt_replace_call(u8 *instr, u8 *insn_buff, struct alt_instr *a)
void __init_or_module noinline apply_alternatives(struct alt_instr *start,
struct alt_instr *end)
{
- struct alt_instr *a;
- u8 *instr, *replacement;
u8 insn_buff[MAX_PATCH_LEN];
+ u8 *instr, *replacement;
+ struct alt_instr *a, *b;
DPRINTK(ALT, "alt table %px, -> %px", start, end);
@@ -492,7 +478,18 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
for (a = start; a < end; a++) {
int insn_buff_sz = 0;
- instr = (u8 *)&a->instr_offset + a->instr_offset;
+ /*
+ * In case of nested ALTERNATIVE()s the outer alternative might
+ * add more padding. To ensure consistent patching find the max
+ * padding for all alt_instr entries for this site (nested
+ * alternatives result in consecutive entries).
+ */
+ for (b = a+1; b < end && instr_va(b) == instr_va(a); b++) {
+ u8 len = max(a->instrlen, b->instrlen);
+ a->instrlen = b->instrlen = len;
+ }
+
+ instr = instr_va(a);
replacement = (u8 *)&a->repl_offset + a->repl_offset;
BUG_ON(a->instrlen > sizeof(insn_buff));
BUG_ON(a->cpuid >= (NCAPINTS + NBUGINTS) * 32);
@@ -504,7 +501,9 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
* patch if feature is *NOT* present.
*/
if (!boot_cpu_has(a->cpuid) == !(a->flags & ALT_FLAG_NOT)) {
- optimize_nops_inplace(instr, a->instrlen);
+ memcpy(insn_buff, instr, a->instrlen);
+ optimize_nops(instr, insn_buff, a->instrlen);
+ text_poke_early(instr, insn_buff, a->instrlen);
continue;
}
@@ -526,7 +525,7 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
for (; insn_buff_sz < a->instrlen; insn_buff_sz++)
insn_buff[insn_buff_sz] = 0x90;
- apply_relocation(insn_buff, a->instrlen, instr, replacement, a->replacementlen);
+ apply_relocation(insn_buff, instr, a->instrlen, replacement, a->replacementlen);
DUMP_BYTES(ALT, instr, a->instrlen, "%px: old_insn: ", instr);
DUMP_BYTES(ALT, replacement, a->replacementlen, "%px: rpl_insn: ", replacement);
@@ -761,7 +760,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
len = patch_retpoline(addr, &insn, bytes);
if (len == insn.length) {
- optimize_nops(bytes, len);
+ optimize_nops(addr, bytes, len);
DUMP_BYTES(RETPOLINE, ((u8*)addr), len, "%px: orig: ", addr);
DUMP_BYTES(RETPOLINE, ((u8*)bytes), len, "%px: repl: ", addr);
text_poke_early(addr, bytes, len);
@@ -902,8 +901,8 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { }
#endif /* CONFIG_X86_KERNEL_IBT */
-#ifdef CONFIG_FINEIBT
-#define __CFI_DEFAULT CFI_DEFAULT
+#ifdef CONFIG_CFI_AUTO_DEFAULT
+#define __CFI_DEFAULT CFI_AUTO
#elif defined(CONFIG_CFI_CLANG)
#define __CFI_DEFAULT CFI_KCFI
#else
@@ -1011,7 +1010,7 @@ static __init int cfi_parse_cmdline(char *str)
}
if (!strcmp(str, "auto")) {
- cfi_mode = CFI_DEFAULT;
+ cfi_mode = CFI_AUTO;
} else if (!strcmp(str, "off")) {
cfi_mode = CFI_OFF;
cfi_rand = false;
@@ -1271,7 +1270,7 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,
"FineIBT preamble wrong size: %ld", fineibt_preamble_size))
return;
- if (cfi_mode == CFI_DEFAULT) {
+ if (cfi_mode == CFI_AUTO) {
cfi_mode = CFI_KCFI;
if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT))
cfi_mode = CFI_FINEIBT;
@@ -1658,7 +1657,7 @@ static noinline void __init alt_reloc_selftest(void)
*/
asm_inline volatile (
ALTERNATIVE("", "lea %[mem], %%" _ASM_ARG1 "; call __alt_reloc_selftest;", X86_FEATURE_ALWAYS)
- : /* output */
+ : ASM_CALL_CONSTRAINT
: [mem] "m" (__alt_reloc_selftest_addr)
: _ASM_ARG1
);
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index 2ae98f754e59..c884deca839b 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -676,7 +676,7 @@ 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,
+ .alloc_pages_op = dma_direct_alloc_pages,
.free_pages = dma_direct_free_pages,
};
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 5bf5f9fc5753..059e5c16af05 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -95,6 +95,7 @@ static const struct pci_device_id amd_nb_misc_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) },
{}
@@ -179,6 +180,43 @@ static struct pci_dev *next_northbridge(struct pci_dev *dev,
return dev;
}
+/*
+ * SMN accesses may fail in ways that are difficult to detect here in the called
+ * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do
+ * their own checking based on what behavior they expect.
+ *
+ * For SMN reads, the returned value may be zero if the register is Read-as-Zero.
+ * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response"
+ * can be checked here, and a proper error code can be returned.
+ *
+ * But the Read-as-Zero response cannot be verified here. A value of 0 may be
+ * correct in some cases, so callers must check that this correct is for the
+ * register/fields they need.
+ *
+ * For SMN writes, success can be determined through a "write and read back"
+ * However, this is not robust when done here.
+ *
+ * Possible issues:
+ *
+ * 1) Bits that are "Write-1-to-Clear". In this case, the read value should
+ * *not* match the write value.
+ *
+ * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be
+ * known here.
+ *
+ * 3) Bits that are "Reserved / Set to 1". Ditto above.
+ *
+ * Callers of amd_smn_write() should do the "write and read back" check
+ * themselves, if needed.
+ *
+ * For #1, they can see if their target bits got cleared.
+ *
+ * For #2 and #3, they can check if their target bits got set as intended.
+ *
+ * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then
+ * the operation is considered a success, and the caller does their own
+ * checking.
+ */
static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
{
struct pci_dev *root;
@@ -201,9 +239,6 @@ static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
err = (write ? pci_write_config_dword(root, 0x64, *value)
: pci_read_config_dword(root, 0x64, value));
- if (err)
- pr_warn("Error %s SMN address 0x%x.\n",
- (write ? "writing to" : "reading from"), address);
out_unlock:
mutex_unlock(&smn_mutex);
@@ -212,13 +247,20 @@ out:
return err;
}
-int amd_smn_read(u16 node, u32 address, u32 *value)
+int __must_check amd_smn_read(u16 node, u32 address, u32 *value)
{
- return __amd_smn_rw(node, address, value, false);
+ int err = __amd_smn_rw(node, address, value, false);
+
+ if (PCI_POSSIBLE_ERROR(*value)) {
+ err = -ENODEV;
+ *value = 0;
+ }
+
+ return err;
}
EXPORT_SYMBOL_GPL(amd_smn_read);
-int amd_smn_write(u16 node, u32 address, u32 value)
+int __must_check amd_smn_write(u16 node, u32 address, u32 value)
{
return __amd_smn_rw(node, address, &value, true);
}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 803dcfb0e346..66fd4b2a37a3 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -497,32 +497,32 @@ static struct clock_event_device lapic_clockevent = {
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
static const struct x86_cpu_id deadline_match[] __initconst = {
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x2, 0x2), 0x3a), /* EP */
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x4, 0x4), 0x0f), /* EX */
+ X86_MATCH_VFM_STEPPINGS(INTEL_HASWELL_X, X86_STEPPINGS(0x2, 0x2), 0x3a), /* EP */
+ X86_MATCH_VFM_STEPPINGS(INTEL_HASWELL_X, X86_STEPPINGS(0x4, 0x4), 0x0f), /* EX */
- X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
+ X86_MATCH_VFM(INTEL_BROADWELL_X, 0x0b000020),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x2, 0x2), 0x00000011),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x3, 0x3), 0x0700000e),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x4, 0x4), 0x0f00000c),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x5, 0x5), 0x0e000003),
+ X86_MATCH_VFM_STEPPINGS(INTEL_BROADWELL_D, X86_STEPPINGS(0x2, 0x2), 0x00000011),
+ X86_MATCH_VFM_STEPPINGS(INTEL_BROADWELL_D, X86_STEPPINGS(0x3, 0x3), 0x0700000e),
+ X86_MATCH_VFM_STEPPINGS(INTEL_BROADWELL_D, X86_STEPPINGS(0x4, 0x4), 0x0f00000c),
+ X86_MATCH_VFM_STEPPINGS(INTEL_BROADWELL_D, X86_STEPPINGS(0x5, 0x5), 0x0e000003),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x3, 0x3), 0x01000136),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x4, 0x4), 0x02000014),
- X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x5, 0xf), 0),
+ X86_MATCH_VFM_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPINGS(0x3, 0x3), 0x01000136),
+ X86_MATCH_VFM_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPINGS(0x4, 0x4), 0x02000014),
+ X86_MATCH_VFM_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPINGS(0x5, 0xf), 0),
- X86_MATCH_INTEL_FAM6_MODEL( HASWELL, 0x22),
- X86_MATCH_INTEL_FAM6_MODEL( HASWELL_L, 0x20),
- X86_MATCH_INTEL_FAM6_MODEL( HASWELL_G, 0x17),
+ X86_MATCH_VFM(INTEL_HASWELL, 0x22),
+ X86_MATCH_VFM(INTEL_HASWELL_L, 0x20),
+ X86_MATCH_VFM(INTEL_HASWELL_G, 0x17),
- X86_MATCH_INTEL_FAM6_MODEL( BROADWELL, 0x25),
- X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_G, 0x17),
+ X86_MATCH_VFM(INTEL_BROADWELL, 0x25),
+ X86_MATCH_VFM(INTEL_BROADWELL_G, 0x17),
- X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE_L, 0xb2),
- X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE, 0xb2),
+ X86_MATCH_VFM(INTEL_SKYLAKE_L, 0xb2),
+ X86_MATCH_VFM(INTEL_SKYLAKE, 0xb2),
- X86_MATCH_INTEL_FAM6_MODEL( KABYLAKE_L, 0x52),
- X86_MATCH_INTEL_FAM6_MODEL( KABYLAKE, 0x52),
+ X86_MATCH_VFM(INTEL_KABYLAKE_L, 0x52),
+ X86_MATCH_VFM(INTEL_KABYLAKE, 0x52),
{},
};
@@ -631,7 +631,7 @@ void lapic_update_tsc_freq(void)
static __initdata int lapic_cal_loops = -1;
static __initdata long lapic_cal_t1, lapic_cal_t2;
static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2;
-static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2;
+static __initdata u32 lapic_cal_pm1, lapic_cal_pm2;
static __initdata unsigned long lapic_cal_j1, lapic_cal_j2;
/*
@@ -641,7 +641,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
{
unsigned long long tsc = 0;
long tapic = apic_read(APIC_TMCCT);
- unsigned long pm = acpi_pm_read_early();
+ u32 pm = acpi_pm_read_early();
if (boot_cpu_has(X86_FEATURE_TSC))
tsc = rdtsc();
@@ -666,7 +666,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
}
static int __init
-calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
+calibrate_by_pmtimer(u32 deltapm, long *delta, long *deltatsc)
{
const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
const long pm_thresh = pm_100ms / 100;
@@ -677,7 +677,7 @@ calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
return -1;
#endif
- apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm);
+ apic_printk(APIC_VERBOSE, "... PM-Timer delta = %u\n", deltapm);
/* Check, if the PM timer is available */
if (!deltapm)
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index d9651f15ae4f..340769242dea 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -184,7 +184,6 @@ static int x86_msi_prepare(struct irq_domain *domain, struct device *dev,
alloc->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
return 0;
case DOMAIN_BUS_PCI_DEVICE_MSIX:
- case DOMAIN_BUS_PCI_DEVICE_IMS:
alloc->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
return 0;
default:
@@ -229,10 +228,6 @@ static bool x86_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
case DOMAIN_BUS_PCI_DEVICE_MSI:
case DOMAIN_BUS_PCI_DEVICE_MSIX:
break;
- case DOMAIN_BUS_PCI_DEVICE_IMS:
- if (!(pops->supported_flags & MSI_FLAG_PCI_IMS))
- return false;
- break;
default:
WARN_ON_ONCE(1);
return false;
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 185738c72766..557318145038 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -965,7 +965,7 @@ static void __vector_cleanup(struct vector_cleanup *cl, bool check_irr)
lockdep_assert_held(&vector_lock);
hlist_for_each_entry_safe(apicd, tmp, &cl->head, clist) {
- unsigned int irr, vector = apicd->prev_vector;
+ unsigned int vector = apicd->prev_vector;
/*
* Paranoia: Check if the vector that needs to be cleaned
@@ -979,8 +979,7 @@ static void __vector_cleanup(struct vector_cleanup *cl, bool check_irr)
* fixup_irqs() was just called to scan IRR for set bits and
* forward them to new destination CPUs via IPIs.
*/
- irr = check_irr ? apic_read(APIC_IRR + (vector / 32 * 0x10)) : 0;
- if (irr & (1U << (vector % 32))) {
+ if (check_irr && is_vector_pending(vector)) {
pr_warn_once("Moved interrupt pending in old target APIC %u\n", apicd->irq);
rearm = true;
continue;
@@ -1036,7 +1035,8 @@ static void __vector_schedule_cleanup(struct apic_chip_data *apicd)
add_timer_on(&cl->timer, cpu);
}
} else {
- apicd->prev_vector = 0;
+ pr_warn("IRQ %u schedule cleanup for offline CPU %u\n", apicd->irq, cpu);
+ free_moved_vector(apicd);
}
raw_spin_unlock(&vector_lock);
}
@@ -1073,6 +1073,7 @@ void irq_complete_move(struct irq_cfg *cfg)
*/
void irq_force_complete_move(struct irq_desc *desc)
{
+ unsigned int cpu = smp_processor_id();
struct apic_chip_data *apicd;
struct irq_data *irqd;
unsigned int vector;
@@ -1097,10 +1098,11 @@ void irq_force_complete_move(struct irq_desc *desc)
goto unlock;
/*
- * If prev_vector is empty, no action required.
+ * If prev_vector is empty or the descriptor is neither currently
+ * nor previously on the outgoing CPU no action required.
*/
vector = apicd->prev_vector;
- if (!vector)
+ if (!vector || (apicd->cpu != cpu && apicd->prev_cpu != cpu))
goto unlock;
/*
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index 567dbd2fe4b6..7db83212effb 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -178,13 +178,16 @@ static int x2apic_prepare_cpu(unsigned int cpu)
u32 phys_apicid = apic->cpu_present_to_apicid(cpu);
u32 cluster = apic_cluster(phys_apicid);
u32 logical_apicid = (cluster << 16) | (1 << (phys_apicid & 0xf));
+ int node = cpu_to_node(cpu);
x86_cpu_to_logical_apicid[cpu] = logical_apicid;
- if (alloc_clustermask(cpu, cluster, cpu_to_node(cpu)) < 0)
+ if (alloc_clustermask(cpu, cluster, node) < 0)
return -ENOMEM;
- if (!zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL))
+
+ if (!zalloc_cpumask_var_node(&per_cpu(ipi_mask, cpu), GFP_KERNEL, node))
return -ENOMEM;
+
return 0;
}
diff --git a/arch/x86/kernel/callthunks.c b/arch/x86/kernel/callthunks.c
index e92ff0c11db8..465647456753 100644
--- a/arch/x86/kernel/callthunks.c
+++ b/arch/x86/kernel/callthunks.c
@@ -185,8 +185,7 @@ static void *patch_dest(void *dest, bool direct)
u8 *pad = dest - tsize;
memcpy(insn_buff, skl_call_thunk_template, tsize);
- apply_relocation(insn_buff, tsize, pad,
- skl_call_thunk_template, tsize);
+ apply_relocation(insn_buff, pad, tsize, skl_call_thunk_template, tsize);
/* Already patched? */
if (!bcmp(pad, insn_buff, tsize))
@@ -308,8 +307,7 @@ static bool is_callthunk(void *addr)
pad = (void *)(dest - tmpl_size);
memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
- apply_relocation(insn_buff, tmpl_size, pad,
- skl_call_thunk_template, tmpl_size);
+ apply_relocation(insn_buff, pad, tmpl_size, skl_call_thunk_template, tmpl_size);
return !bcmp(pad, insn_buff, tmpl_size);
}
@@ -327,8 +325,7 @@ int x86_call_depth_emit_accounting(u8 **pprog, void *func, void *ip)
return 0;
memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
- apply_relocation(insn_buff, tmpl_size, ip,
- skl_call_thunk_template, tmpl_size);
+ apply_relocation(insn_buff, ip, tmpl_size, skl_call_thunk_template, tmpl_size);
memcpy(*pprog, insn_buff, tmpl_size);
*pprog += tmpl_size;
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index eb4dbcdf41f1..5857a0f5d514 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IA32_FEAT_CTL) += feat_ctl.o
ifdef CONFIG_CPU_SUP_INTEL
-obj-y += intel.o intel_pconfig.o tsx.o
+obj-y += intel.o tsx.o
obj-$(CONFIG_PM) += intel_epb.o
endif
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
@@ -60,7 +60,7 @@ obj-$(CONFIG_ACRN_GUEST) += acrn.o
obj-$(CONFIG_DEBUG_FS) += debugfs.o
quiet_cmd_mkcapflags = MKCAP $@
- cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $@ $^
+ cmd_mkcapflags = $(CONFIG_SHELL) $(src)/mkcapflags.sh $@ $^
cpufeature = $(src)/../../include/asm/cpufeatures.h
vmxfeature = $(src)/../../include/asm/vmxfeatures.h
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 307302af0aee..be5889bded49 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -13,6 +13,7 @@
#include <asm/apic.h>
#include <asm/cacheinfo.h>
#include <asm/cpu.h>
+#include <asm/cpu_device_id.h>
#include <asm/spec-ctrl.h>
#include <asm/smp.h>
#include <asm/numa.h>
@@ -794,6 +795,11 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
clear_rdrand_cpuid_bit(c);
}
+static const struct x86_cpu_desc erratum_1386_microcode[] = {
+ AMD_CPU_DESC(0x17, 0x1, 0x2, 0x0800126e),
+ AMD_CPU_DESC(0x17, 0x31, 0x0, 0x08301052),
+};
+
static void fix_erratum_1386(struct cpuinfo_x86 *c)
{
/*
@@ -803,7 +809,13 @@ static void fix_erratum_1386(struct cpuinfo_x86 *c)
*
* Affected parts all have no supervisor XSAVE states, meaning that
* the XSAVEC instruction (which works fine) is equivalent.
+ *
+ * Clear the feature flag only on microcode revisions which
+ * don't have the fix.
*/
+ if (x86_cpu_has_min_microcode_rev(erratum_1386_microcode))
+ return;
+
clear_cpu_cap(c, X86_FEATURE_XSAVES);
}
@@ -1208,14 +1220,3 @@ void amd_check_microcode(void)
on_each_cpu(zenbleed_check_cpu, NULL, 1);
}
-
-/*
- * Issue a DIV 0/1 insn to clear any division data from previous DIV
- * operations.
- */
-void noinstr amd_clear_divider(void)
-{
- asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
- :: "a" (0), "d" (0), "r" (1));
-}
-EXPORT_SYMBOL_GPL(amd_clear_divider);
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index fdbb5f07448f..b3fa61d45352 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -124,25 +124,24 @@ static bool __init slv_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq)
return true;
}
-#define X86_MATCH(model) \
- X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \
- INTEL_FAM6_##model, X86_FEATURE_APERFMPERF, NULL)
+#define X86_MATCH(vfm) \
+ X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_APERFMPERF, NULL)
static const struct x86_cpu_id has_knl_turbo_ratio_limits[] __initconst = {
- X86_MATCH(XEON_PHI_KNL),
- X86_MATCH(XEON_PHI_KNM),
+ X86_MATCH(INTEL_XEON_PHI_KNL),
+ X86_MATCH(INTEL_XEON_PHI_KNM),
{}
};
static const struct x86_cpu_id has_skx_turbo_ratio_limits[] __initconst = {
- X86_MATCH(SKYLAKE_X),
+ X86_MATCH(INTEL_SKYLAKE_X),
{}
};
static const struct x86_cpu_id has_glm_turbo_ratio_limits[] __initconst = {
- X86_MATCH(ATOM_GOLDMONT),
- X86_MATCH(ATOM_GOLDMONT_D),
- X86_MATCH(ATOM_GOLDMONT_PLUS),
+ X86_MATCH(INTEL_ATOM_GOLDMONT),
+ X86_MATCH(INTEL_ATOM_GOLDMONT_D),
+ X86_MATCH(INTEL_ATOM_GOLDMONT_PLUS),
{}
};
@@ -346,6 +345,7 @@ static DECLARE_WORK(disable_freq_invariance_work,
disable_freq_invariance_workfn);
DEFINE_PER_CPU(unsigned long, arch_freq_scale) = SCHED_CAPACITY_SCALE;
+EXPORT_PER_CPU_SYMBOL_GPL(arch_freq_scale);
static void scale_freq_tick(u64 acnt, u64 mcnt)
{
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index ab18185894df..45675da354f3 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -26,7 +26,7 @@
#include <asm/msr.h>
#include <asm/vmx.h>
#include <asm/paravirt.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/e820/api.h>
#include <asm/hypervisor.h>
#include <asm/tlbflush.h>
@@ -1625,6 +1625,7 @@ static bool __init spec_ctrl_bhi_dis(void)
enum bhi_mitigations {
BHI_MITIGATION_OFF,
BHI_MITIGATION_ON,
+ BHI_MITIGATION_VMEXIT_ONLY,
};
static enum bhi_mitigations bhi_mitigation __ro_after_init =
@@ -1639,6 +1640,8 @@ static int __init spectre_bhi_parse_cmdline(char *str)
bhi_mitigation = BHI_MITIGATION_OFF;
else if (!strcmp(str, "on"))
bhi_mitigation = BHI_MITIGATION_ON;
+ else if (!strcmp(str, "vmexit"))
+ bhi_mitigation = BHI_MITIGATION_VMEXIT_ONLY;
else
pr_err("Ignoring unknown spectre_bhi option (%s)", str);
@@ -1659,19 +1662,22 @@ static void __init bhi_select_mitigation(void)
return;
}
+ /* Mitigate in hardware if supported */
if (spec_ctrl_bhi_dis())
return;
if (!IS_ENABLED(CONFIG_X86_64))
return;
- /* Mitigate KVM by default */
- setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT);
- pr_info("Spectre BHI mitigation: SW BHB clearing on vm exit\n");
+ if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) {
+ pr_info("Spectre BHI mitigation: SW BHB clearing on VM exit only\n");
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT);
+ return;
+ }
- /* Mitigate syscalls when the mitigation is forced =on */
+ pr_info("Spectre BHI mitigation: SW BHB clearing on syscall and VM exit\n");
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
- pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT);
}
static void __init spectre_v2_select_mitigation(void)
@@ -2391,20 +2397,20 @@ static void override_cache_bits(struct cpuinfo_x86 *c)
if (c->x86 != 6)
return;
- switch (c->x86_model) {
- case INTEL_FAM6_NEHALEM:
- case INTEL_FAM6_WESTMERE:
- case INTEL_FAM6_SANDYBRIDGE:
- case INTEL_FAM6_IVYBRIDGE:
- case INTEL_FAM6_HASWELL:
- case INTEL_FAM6_HASWELL_L:
- case INTEL_FAM6_HASWELL_G:
- case INTEL_FAM6_BROADWELL:
- case INTEL_FAM6_BROADWELL_G:
- case INTEL_FAM6_SKYLAKE_L:
- case INTEL_FAM6_SKYLAKE:
- case INTEL_FAM6_KABYLAKE_L:
- case INTEL_FAM6_KABYLAKE:
+ switch (c->x86_vfm) {
+ case INTEL_NEHALEM:
+ case INTEL_WESTMERE:
+ case INTEL_SANDYBRIDGE:
+ case INTEL_IVYBRIDGE:
+ case INTEL_HASWELL:
+ case INTEL_HASWELL_L:
+ case INTEL_HASWELL_G:
+ case INTEL_BROADWELL:
+ case INTEL_BROADWELL_G:
+ case INTEL_SKYLAKE_L:
+ case INTEL_SKYLAKE:
+ case INTEL_KABYLAKE_L:
+ case INTEL_KABYLAKE:
if (c->x86_cache_bits < 44)
c->x86_cache_bits = 44;
break;
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 605c26c009c8..d4e539d4e158 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -68,6 +68,7 @@
#include <asm/traps.h>
#include <asm/sev.h>
#include <asm/tdx.h>
+#include <asm/posted_intr.h>
#include "cpu.h"
@@ -114,17 +115,17 @@ static const struct x86_cpu_id ppin_cpuids[] = {
X86_MATCH_FEATURE(X86_FEATURE_INTEL_PPIN, &ppin_info[X86_VENDOR_INTEL]),
/* Legacy models without CPUID enumeration */
- X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &ppin_info[X86_VENDOR_INTEL]),
- X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_HASWELL_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_BROADWELL_D, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_BROADWELL_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_SKYLAKE_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &ppin_info[X86_VENDOR_INTEL]),
{}
};
@@ -1053,18 +1054,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
void get_cpu_address_sizes(struct cpuinfo_x86 *c)
{
u32 eax, ebx, ecx, edx;
- bool vp_bits_from_cpuid = true;
if (!cpu_has(c, X86_FEATURE_CPUID) ||
- (c->extended_cpuid_level < 0x80000008))
- vp_bits_from_cpuid = false;
-
- if (vp_bits_from_cpuid) {
- cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
-
- c->x86_virt_bits = (eax >> 8) & 0xff;
- c->x86_phys_bits = eax & 0xff;
- } else {
+ (c->extended_cpuid_level < 0x80000008)) {
if (IS_ENABLED(CONFIG_X86_64)) {
c->x86_clflush_size = 64;
c->x86_phys_bits = 36;
@@ -1078,7 +1070,17 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
cpu_has(c, X86_FEATURE_PSE36))
c->x86_phys_bits = 36;
}
+ } else {
+ cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
+
+ c->x86_virt_bits = (eax >> 8) & 0xff;
+ c->x86_phys_bits = eax & 0xff;
+
+ /* Provide a sane default if not enumerated: */
+ if (!c->x86_clflush_size)
+ c->x86_clflush_size = 32;
}
+
c->x86_cache_bits = c->x86_phys_bits;
c->x86_cache_alignment = c->x86_clflush_size;
}
@@ -1125,8 +1127,8 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
#define VULNWL(vendor, family, model, whitelist) \
X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist)
-#define VULNWL_INTEL(model, whitelist) \
- VULNWL(INTEL, 6, INTEL_FAM6_##model, whitelist)
+#define VULNWL_INTEL(vfm, whitelist) \
+ X86_MATCH_VFM(vfm, whitelist)
#define VULNWL_AMD(family, whitelist) \
VULNWL(AMD, family, X86_MODEL_ANY, whitelist)
@@ -1143,32 +1145,32 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL(VORTEX, 6, X86_MODEL_ANY, NO_SPECULATION),
/* Intel Family 6 */
- VULNWL_INTEL(TIGERLAKE, NO_MMIO),
- VULNWL_INTEL(TIGERLAKE_L, NO_MMIO),
- VULNWL_INTEL(ALDERLAKE, NO_MMIO),
- VULNWL_INTEL(ALDERLAKE_L, NO_MMIO),
+ VULNWL_INTEL(INTEL_TIGERLAKE, NO_MMIO),
+ VULNWL_INTEL(INTEL_TIGERLAKE_L, NO_MMIO),
+ VULNWL_INTEL(INTEL_ALDERLAKE, NO_MMIO),
+ VULNWL_INTEL(INTEL_ALDERLAKE_L, NO_MMIO),
- VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_BONNELL, NO_SPECULATION | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_BONNELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(CORE_YONAH, NO_SSB),
+ VULNWL_INTEL(INTEL_CORE_YONAH, NO_SSB),
- VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
+ VULNWL_INTEL(INTEL_ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
- VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
- VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
- VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
+ VULNWL_INTEL(INTEL_ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
+ VULNWL_INTEL(INTEL_ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
+ VULNWL_INTEL(INTEL_ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
/*
* Technically, swapgs isn't serializing on AMD (despite it previously
@@ -1178,9 +1180,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
* good enough for our purposes.
*/
- VULNWL_INTEL(ATOM_TREMONT, NO_EIBRS_PBRSB),
- VULNWL_INTEL(ATOM_TREMONT_L, NO_EIBRS_PBRSB),
- VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
+ VULNWL_INTEL(INTEL_ATOM_TREMONT, NO_EIBRS_PBRSB),
+ VULNWL_INTEL(INTEL_ATOM_TREMONT_L, NO_EIBRS_PBRSB),
+ VULNWL_INTEL(INTEL_ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
/* AMD Family 0xf - 0x12 */
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
@@ -1201,10 +1203,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
#define VULNBL(vendor, family, model, blacklist) \
X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, blacklist)
-#define VULNBL_INTEL_STEPPINGS(model, steppings, issues) \
- X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, \
- INTEL_FAM6_##model, steppings, \
- X86_FEATURE_ANY, issues)
+#define VULNBL_INTEL_STEPPINGS(vfm, steppings, issues) \
+ X86_MATCH_VFM_STEPPINGS(vfm, steppings, issues)
#define VULNBL_AMD(family, blacklist) \
VULNBL(AMD, family, X86_MODEL_ANY, blacklist)
@@ -1229,43 +1229,43 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
#define RFDS BIT(7)
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
- VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
- VULNBL_INTEL_STEPPINGS(HASWELL, X86_STEPPING_ANY, SRBDS),
- VULNBL_INTEL_STEPPINGS(HASWELL_L, X86_STEPPING_ANY, SRBDS),
- VULNBL_INTEL_STEPPINGS(HASWELL_G, X86_STEPPING_ANY, SRBDS),
- VULNBL_INTEL_STEPPINGS(HASWELL_X, X86_STEPPING_ANY, MMIO),
- VULNBL_INTEL_STEPPINGS(BROADWELL_D, X86_STEPPING_ANY, MMIO),
- VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS),
- VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO),
- VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS),
- VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
- VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
- VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
- VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
- VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
- VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED),
- VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
- VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS),
- VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS),
- VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
- VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED),
- VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
- VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS),
- VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS),
- VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
- VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
- VULNBL_INTEL_STEPPINGS(ALDERLAKE, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(ALDERLAKE_L, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(RAPTORLAKE, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(RAPTORLAKE_P, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(RAPTORLAKE_S, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_GRACEMONT, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO | RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_D, X86_STEPPING_ANY, RFDS),
- VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_PLUS, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_HASWELL, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_HASWELL_L, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_HASWELL_G, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_HASWELL_X, X86_STEPPING_ANY, MMIO),
+ VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL_D, X86_STEPPING_ANY, MMIO),
+ VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL_G, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL_X, X86_STEPPING_ANY, MMIO),
+ VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED),
+ VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED),
+ VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE_L, X86_STEPPING_ANY, GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE, X86_STEPPING_ANY, GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
+ VULNBL_INTEL_STEPPINGS(INTEL_ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ALDERLAKE, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ALDERLAKE_L, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_RAPTORLAKE, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_RAPTORLAKE_P, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_RAPTORLAKE_S, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_GRACEMONT, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO | RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_GOLDMONT, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_GOLDMONT_D, X86_STEPPING_ANY, RFDS),
+ VULNBL_INTEL_STEPPINGS(INTEL_ATOM_GOLDMONT_PLUS, X86_STEPPING_ANY, RFDS),
VULNBL_AMD(0x15, RETBLEED),
VULNBL_AMD(0x16, RETBLEED),
@@ -1589,6 +1589,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
if (have_cpuid_p()) {
cpu_detect(c);
get_cpu_vendor(c);
+ intel_unlock_cpuid_leafs(c);
get_cpu_cap(c);
setup_force_cpu_cap(X86_FEATURE_CPUID);
get_cpu_address_sizes(c);
@@ -1748,7 +1749,7 @@ static void generic_identify(struct cpuinfo_x86 *c)
cpu_detect(c);
get_cpu_vendor(c);
-
+ intel_unlock_cpuid_leafs(c);
get_cpu_cap(c);
get_cpu_address_sizes(c);
@@ -2227,6 +2228,8 @@ void cpu_init(void)
barrier();
x2apic_setup();
+
+ intel_posted_msi_init();
}
mmgrab(&init_mm);
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index ea9e07d57c8d..1beccefbaff9 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -61,9 +61,11 @@ extern __ro_after_init enum tsx_ctrl_states tsx_ctrl_state;
extern void __init tsx_init(void);
void tsx_ap_init(void);
+void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c);
#else
static inline void tsx_init(void) { }
static inline void tsx_ap_init(void) { }
+static inline void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c) { }
#endif /* CONFIG_CPU_SUP_INTEL */
extern void init_spectral_chicken(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index 946813d816bf..b7d9f530ae16 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -114,6 +114,9 @@ static void do_clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
if (WARN_ON(feature >= MAX_FEATURE_BITS))
return;
+ if (boot_cpu_has(feature))
+ WARN_ON(alternatives_patched);
+
clear_feature(c, feature);
/* Collect all features to disable, handling dependencies */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index be30d7fa2e66..08b95a35b5cb 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -72,19 +72,19 @@ static bool cpu_model_supports_sld __ro_after_init;
*/
static void check_memory_type_self_snoop_errata(struct cpuinfo_x86 *c)
{
- switch (c->x86_model) {
- case INTEL_FAM6_CORE_YONAH:
- case INTEL_FAM6_CORE2_MEROM:
- case INTEL_FAM6_CORE2_MEROM_L:
- case INTEL_FAM6_CORE2_PENRYN:
- case INTEL_FAM6_CORE2_DUNNINGTON:
- case INTEL_FAM6_NEHALEM:
- case INTEL_FAM6_NEHALEM_G:
- case INTEL_FAM6_NEHALEM_EP:
- case INTEL_FAM6_NEHALEM_EX:
- case INTEL_FAM6_WESTMERE:
- case INTEL_FAM6_WESTMERE_EP:
- case INTEL_FAM6_SANDYBRIDGE:
+ switch (c->x86_vfm) {
+ case INTEL_CORE_YONAH:
+ case INTEL_CORE2_MEROM:
+ case INTEL_CORE2_MEROM_L:
+ case INTEL_CORE2_PENRYN:
+ case INTEL_CORE2_DUNNINGTON:
+ case INTEL_NEHALEM:
+ case INTEL_NEHALEM_G:
+ case INTEL_NEHALEM_EP:
+ case INTEL_NEHALEM_EX:
+ case INTEL_WESTMERE:
+ case INTEL_WESTMERE_EP:
+ case INTEL_SANDYBRIDGE:
setup_clear_cpu_cap(X86_FEATURE_SELFSNOOP);
}
}
@@ -106,9 +106,9 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c)
*/
if (c->x86 != 6)
return;
- switch (c->x86_model) {
- case INTEL_FAM6_XEON_PHI_KNL:
- case INTEL_FAM6_XEON_PHI_KNM:
+ switch (c->x86_vfm) {
+ case INTEL_XEON_PHI_KNL:
+ case INTEL_XEON_PHI_KNM:
break;
default:
return;
@@ -134,32 +134,32 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c)
* - Release note from 20180108 microcode release
*/
struct sku_microcode {
- u8 model;
+ u32 vfm;
u8 stepping;
u32 microcode;
};
static const struct sku_microcode spectre_bad_microcodes[] = {
- { INTEL_FAM6_KABYLAKE, 0x0B, 0x80 },
- { INTEL_FAM6_KABYLAKE, 0x0A, 0x80 },
- { INTEL_FAM6_KABYLAKE, 0x09, 0x80 },
- { INTEL_FAM6_KABYLAKE_L, 0x0A, 0x80 },
- { INTEL_FAM6_KABYLAKE_L, 0x09, 0x80 },
- { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e },
- { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c },
- { INTEL_FAM6_BROADWELL, 0x04, 0x28 },
- { INTEL_FAM6_BROADWELL_G, 0x01, 0x1b },
- { INTEL_FAM6_BROADWELL_D, 0x02, 0x14 },
- { INTEL_FAM6_BROADWELL_D, 0x03, 0x07000011 },
- { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 },
- { INTEL_FAM6_HASWELL_L, 0x01, 0x21 },
- { INTEL_FAM6_HASWELL_G, 0x01, 0x18 },
- { INTEL_FAM6_HASWELL, 0x03, 0x23 },
- { INTEL_FAM6_HASWELL_X, 0x02, 0x3b },
- { INTEL_FAM6_HASWELL_X, 0x04, 0x10 },
- { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a },
+ { INTEL_KABYLAKE, 0x0B, 0x80 },
+ { INTEL_KABYLAKE, 0x0A, 0x80 },
+ { INTEL_KABYLAKE, 0x09, 0x80 },
+ { INTEL_KABYLAKE_L, 0x0A, 0x80 },
+ { INTEL_KABYLAKE_L, 0x09, 0x80 },
+ { INTEL_SKYLAKE_X, 0x03, 0x0100013e },
+ { INTEL_SKYLAKE_X, 0x04, 0x0200003c },
+ { INTEL_BROADWELL, 0x04, 0x28 },
+ { INTEL_BROADWELL_G, 0x01, 0x1b },
+ { INTEL_BROADWELL_D, 0x02, 0x14 },
+ { INTEL_BROADWELL_D, 0x03, 0x07000011 },
+ { INTEL_BROADWELL_X, 0x01, 0x0b000025 },
+ { INTEL_HASWELL_L, 0x01, 0x21 },
+ { INTEL_HASWELL_G, 0x01, 0x18 },
+ { INTEL_HASWELL, 0x03, 0x23 },
+ { INTEL_HASWELL_X, 0x02, 0x3b },
+ { INTEL_HASWELL_X, 0x04, 0x10 },
+ { INTEL_IVYBRIDGE_X, 0x04, 0x42a },
/* Observed in the wild */
- { INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b },
- { INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 },
+ { INTEL_SANDYBRIDGE_X, 0x06, 0x61b },
+ { INTEL_SANDYBRIDGE_X, 0x07, 0x712 },
};
static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
@@ -173,11 +173,8 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
return false;
- if (c->x86 != 6)
- return false;
-
for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
- if (c->x86_model == spectre_bad_microcodes[i].model &&
+ if (c->x86_vfm == spectre_bad_microcodes[i].vfm &&
c->x86_stepping == spectre_bad_microcodes[i].stepping)
return (c->microcode <= spectre_bad_microcodes[i].microcode);
}
@@ -190,97 +187,57 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
#define TME_ACTIVATE_LOCKED(x) (x & 0x1)
#define TME_ACTIVATE_ENABLED(x) (x & 0x2)
-#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */
-#define TME_ACTIVATE_POLICY_AES_XTS_128 0
-
#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */
-#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */
-#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1
-
-/* Values for mktme_status (SW only construct) */
-#define MKTME_ENABLED 0
-#define MKTME_DISABLED 1
-#define MKTME_UNINITIALIZED 2
-static int mktme_status = MKTME_UNINITIALIZED;
-
static void detect_tme_early(struct cpuinfo_x86 *c)
{
- u64 tme_activate, tme_policy, tme_crypto_algs;
- int keyid_bits = 0, nr_keyids = 0;
- static u64 tme_activate_cpu0 = 0;
+ u64 tme_activate;
+ int keyid_bits;
rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate);
- if (mktme_status != MKTME_UNINITIALIZED) {
- if (tme_activate != tme_activate_cpu0) {
- /* Broken BIOS? */
- pr_err_once("x86/tme: configuration is inconsistent between CPUs\n");
- pr_err_once("x86/tme: MKTME is not usable\n");
- mktme_status = MKTME_DISABLED;
-
- /* Proceed. We may need to exclude bits from x86_phys_bits. */
- }
- } else {
- tme_activate_cpu0 = tme_activate;
- }
-
if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) {
pr_info_once("x86/tme: not enabled by BIOS\n");
- mktme_status = MKTME_DISABLED;
+ clear_cpu_cap(c, X86_FEATURE_TME);
return;
}
+ pr_info_once("x86/tme: enabled by BIOS\n");
+ keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
+ if (!keyid_bits)
+ return;
- if (mktme_status != MKTME_UNINITIALIZED)
- goto detect_keyid_bits;
-
- pr_info("x86/tme: enabled by BIOS\n");
-
- tme_policy = TME_ACTIVATE_POLICY(tme_activate);
- if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128)
- pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy);
+ /*
+ * KeyID bits are set by BIOS and can be present regardless
+ * of whether the kernel is using them. They effectively lower
+ * the number of physical address bits.
+ *
+ * Update cpuinfo_x86::x86_phys_bits accordingly.
+ */
+ c->x86_phys_bits -= keyid_bits;
+ pr_info_once("x86/mktme: BIOS enabled: x86_phys_bits reduced by %d\n",
+ keyid_bits);
+}
- tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate);
- if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) {
- pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n",
- tme_crypto_algs);
- mktme_status = MKTME_DISABLED;
- }
-detect_keyid_bits:
- keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
- nr_keyids = (1UL << keyid_bits) - 1;
- if (nr_keyids) {
- pr_info_once("x86/mktme: enabled by BIOS\n");
- pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids);
- } else {
- pr_info_once("x86/mktme: disabled by BIOS\n");
- }
+void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c)
+{
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+ return;
- if (mktme_status == MKTME_UNINITIALIZED) {
- /* MKTME is usable */
- mktme_status = MKTME_ENABLED;
- }
+ if (c->x86 < 6 || (c->x86 == 6 && c->x86_model < 0xd))
+ return;
/*
- * KeyID bits effectively lower the number of physical address
- * bits. Update cpuinfo_x86::x86_phys_bits accordingly.
+ * The BIOS can have limited CPUID to leaf 2, which breaks feature
+ * enumeration. Unlock it and update the maximum leaf info.
*/
- c->x86_phys_bits -= keyid_bits;
+ if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0)
+ c->cpuid_level = cpuid_eax(0);
}
static void early_init_intel(struct cpuinfo_x86 *c)
{
u64 misc_enable;
- /* Unmask CPUID levels if masked: */
- if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
- if (msr_clear_bit(MSR_IA32_MISC_ENABLE,
- MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0) {
- c->cpuid_level = cpuid_eax(0);
- get_cpu_cap(c);
- }
- }
-
if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
(c->x86 == 0x6 && c->x86_model >= 0x0e))
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
@@ -312,7 +269,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
* need the microcode to have already been loaded... so if it is
* not, recommend a BIOS update and disable large pages.
*/
- if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_stepping <= 2 &&
+ if (c->x86_vfm == INTEL_ATOM_BONNELL && c->x86_stepping <= 2 &&
c->microcode < 0x20e) {
pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n");
clear_cpu_cap(c, X86_FEATURE_PSE);
@@ -344,17 +301,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
}
/* Penwell and Cloverview have the TSC which doesn't sleep on S3 */
- if (c->x86 == 6) {
- switch (c->x86_model) {
- case INTEL_FAM6_ATOM_SALTWELL_MID:
- case INTEL_FAM6_ATOM_SALTWELL_TABLET:
- case INTEL_FAM6_ATOM_SILVERMONT_MID:
- case INTEL_FAM6_ATOM_AIRMONT_NP:
- set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
- break;
- default:
- break;
- }
+ switch (c->x86_vfm) {
+ case INTEL_ATOM_SALTWELL_MID:
+ case INTEL_ATOM_SALTWELL_TABLET:
+ case INTEL_ATOM_SILVERMONT_MID:
+ case INTEL_ATOM_AIRMONT_NP:
+ set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
+ break;
}
/*
@@ -393,7 +346,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
* should be false so that __flush_tlb_all() causes CR3 instead of CR4.PGE
* to be modified.
*/
- if (c->x86 == 5 && c->x86_model == 9) {
+ if (c->x86_vfm == INTEL_QUARK_X1000) {
pr_info("Disabling PGE capability bit\n");
setup_clear_cpu_cap(X86_FEATURE_PGE);
}
@@ -625,12 +578,13 @@ static void init_intel(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_PEBS);
}
- if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_CLFLUSH) &&
- (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
+ if (boot_cpu_has(X86_FEATURE_CLFLUSH) &&
+ (c->x86_vfm == INTEL_CORE2_DUNNINGTON ||
+ c->x86_vfm == INTEL_NEHALEM_EX ||
+ c->x86_vfm == INTEL_WESTMERE_EX))
set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR);
- if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_MWAIT) &&
- ((c->x86_model == INTEL_FAM6_ATOM_GOLDMONT)))
+ if (boot_cpu_has(X86_FEATURE_MWAIT) && c->x86_vfm == INTEL_ATOM_GOLDMONT)
set_cpu_bug(c, X86_BUG_MONITOR);
#ifdef CONFIG_X86_64
@@ -1246,9 +1200,9 @@ void handle_bus_lock(struct pt_regs *regs)
* feature even though they do not enumerate IA32_CORE_CAPABILITIES.
*/
static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = {
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, 0),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_L, 0),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, 0),
{}
};
diff --git a/arch/x86/kernel/cpu/intel_epb.c b/arch/x86/kernel/cpu/intel_epb.c
index f18d35fe27a9..30b1d63b97f3 100644
--- a/arch/x86/kernel/cpu/intel_epb.c
+++ b/arch/x86/kernel/cpu/intel_epb.c
@@ -204,12 +204,12 @@ static int intel_epb_offline(unsigned int cpu)
}
static const struct x86_cpu_id intel_epb_normal[] = {
- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,
- ENERGY_PERF_BIAS_NORMAL_POWERSAVE),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT,
- ENERGY_PERF_BIAS_NORMAL_POWERSAVE),
- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P,
- ENERGY_PERF_BIAS_NORMAL_POWERSAVE),
+ X86_MATCH_VFM(INTEL_ALDERLAKE_L,
+ ENERGY_PERF_BIAS_NORMAL_POWERSAVE),
+ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT,
+ ENERGY_PERF_BIAS_NORMAL_POWERSAVE),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_P,
+ ENERGY_PERF_BIAS_NORMAL_POWERSAVE),
{}
};
diff --git a/arch/x86/kernel/cpu/intel_pconfig.c b/arch/x86/kernel/cpu/intel_pconfig.c
deleted file mode 100644
index 5be2b1790282..000000000000
--- a/arch/x86/kernel/cpu/intel_pconfig.c
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Intel PCONFIG instruction support.
- *
- * Copyright (C) 2017 Intel Corporation
- *
- * Author:
- * Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
- */
-#include <linux/bug.h>
-#include <linux/limits.h>
-
-#include <asm/cpufeature.h>
-#include <asm/intel_pconfig.h>
-
-#define PCONFIG_CPUID 0x1b
-
-#define PCONFIG_CPUID_SUBLEAF_MASK ((1 << 12) - 1)
-
-/* Subleaf type (EAX) for PCONFIG CPUID leaf (0x1B) */
-enum {
- PCONFIG_CPUID_SUBLEAF_INVALID = 0,
- PCONFIG_CPUID_SUBLEAF_TARGETID = 1,
-};
-
-/* Bitmask of supported targets */
-static u64 targets_supported __read_mostly;
-
-int pconfig_target_supported(enum pconfig_target target)
-{
- /*
- * We would need to re-think the implementation once we get > 64
- * PCONFIG targets. Spec allows up to 2^32 targets.
- */
- BUILD_BUG_ON(PCONFIG_TARGET_NR >= 64);
-
- if (WARN_ON_ONCE(target >= 64))
- return 0;
- return targets_supported & (1ULL << target);
-}
-
-static int __init intel_pconfig_init(void)
-{
- int subleaf;
-
- if (!boot_cpu_has(X86_FEATURE_PCONFIG))
- return 0;
-
- /*
- * Scan subleafs of PCONFIG CPUID leaf.
- *
- * Subleafs of the same type need not to be consecutive.
- *
- * Stop on the first invalid subleaf type. All subleafs after the first
- * invalid are invalid too.
- */
- for (subleaf = 0; subleaf < INT_MAX; subleaf++) {
- struct cpuid_regs regs;
-
- cpuid_count(PCONFIG_CPUID, subleaf,
- &regs.eax, &regs.ebx, &regs.ecx, &regs.edx);
-
- switch (regs.eax & PCONFIG_CPUID_SUBLEAF_MASK) {
- case PCONFIG_CPUID_SUBLEAF_INVALID:
- /* Stop on the first invalid subleaf */
- goto out;
- case PCONFIG_CPUID_SUBLEAF_TARGETID:
- /* Mark supported PCONFIG targets */
- if (regs.ebx < 64)
- targets_supported |= (1ULL << regs.ebx);
- if (regs.ecx < 64)
- targets_supported |= (1ULL << regs.ecx);
- if (regs.edx < 64)
- targets_supported |= (1ULL << regs.edx);
- break;
- default:
- /* Unknown CPUID.PCONFIG subleaf: ignore */
- break;
- }
- }
-out:
- return 0;
-}
-arch_initcall(intel_pconfig_init);
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
index ad6776081e60..8e7de733320a 100644
--- a/arch/x86/kernel/cpu/match.c
+++ b/arch/x86/kernel/cpu/match.c
@@ -17,8 +17,7 @@
*
* A typical table entry would be to match a specific CPU
*
- * X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_BROADWELL,
- * X86_FEATURE_ANY, NULL);
+ * X86_MATCH_VFM_FEATURE(INTEL_BROADWELL, X86_FEATURE_ANY, NULL);
*
* Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY,
* %X86_MODEL_ANY, %X86_FEATURE_ANY (except for vendor)
@@ -26,7 +25,7 @@
* asm/cpu_device_id.h contains a set of useful macros which are shortcuts
* for various common selections. The above can be shortened to:
*
- * X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, NULL);
+ * X86_MATCH_VFM(INTEL_BROADWELL, NULL);
*
* Arrays used to match for this should also be declared using
* MODULE_DEVICE_TABLE(x86cpu, ...)
@@ -39,9 +38,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
const struct x86_cpu_id *m;
struct cpuinfo_x86 *c = &boot_cpu_data;
- for (m = match;
- m->vendor | m->family | m->model | m->steppings | m->feature;
- m++) {
+ for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) {
if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
continue;
if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 84d41be6d06b..b85ec7a4ec9e 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -47,7 +47,7 @@
#include <linux/kexec.h>
#include <asm/fred.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/processor.h>
#include <asm/traps.h>
#include <asm/tlbflush.h>
@@ -677,10 +677,9 @@ DEFINE_PER_CPU(unsigned, mce_poll_count);
* is already totally * confused. In this case it's likely it will
* not fully execute the machine check handler either.
*/
-bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
+void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
{
struct mce_bank *mce_banks = this_cpu_ptr(mce_banks_array);
- bool error_seen = false;
struct mce m;
int i;
@@ -754,8 +753,6 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
continue;
log_it:
- error_seen = true;
-
if (flags & MCP_DONTLOG)
goto clear_it;
@@ -787,8 +784,6 @@ clear_it:
*/
sync_core();
-
- return error_seen;
}
EXPORT_SYMBOL_GPL(machine_check_poll);
@@ -1593,6 +1588,24 @@ noinstr void do_machine_check(struct pt_regs *regs)
else
queue_task_work(&m, msg, kill_me_maybe);
+ } else if (m.mcgstatus & MCG_STATUS_SEAM_NR) {
+ /*
+ * Saved RIP on stack makes it look like the machine check
+ * was taken in the kernel on the instruction following
+ * the entry to SEAM mode. But MCG_STATUS_SEAM_NR indicates
+ * that the machine check was taken inside SEAM non-root
+ * mode. CPU core has already marked that guest as dead.
+ * It is OK for the kernel to resume execution at the
+ * apparent point of the machine check as the fault did
+ * not occur there. Mark the page as poisoned so it won't
+ * be added to free list when the guest is terminated.
+ */
+ if (mce_usable_address(&m)) {
+ struct page *p = pfn_to_online_page(m.addr >> PAGE_SHIFT);
+
+ if (p)
+ SetPageHWPoison(p);
+ }
} else {
/*
* Handle an MCE which has happened in kernel space but from
@@ -1930,14 +1943,14 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
if (c->x86 == 6 && c->x86_model <= 13 && cfg->bootlog < 0)
cfg->bootlog = 0;
- if (c->x86 == 6 && c->x86_model == 45)
+ if (c->x86_vfm == INTEL_SANDYBRIDGE_X)
mce_flags.snb_ifu_quirk = 1;
/*
* Skylake, Cascacde Lake and Cooper Lake require a quirk on
* rep movs.
*/
- if (c->x86 == 6 && c->x86_model == INTEL_FAM6_SKYLAKE_X)
+ if (c->x86_vfm == INTEL_SKYLAKE_X)
mce_flags.skx_repmov_quirk = 1;
}
diff --git a/arch/x86/kernel/cpu/mce/genpool.c b/arch/x86/kernel/cpu/mce/genpool.c
index fbe8b61c3413..4284749ec803 100644
--- a/arch/x86/kernel/cpu/mce/genpool.c
+++ b/arch/x86/kernel/cpu/mce/genpool.c
@@ -16,14 +16,14 @@
* used to save error information organized in a lock-less list.
*
* This memory pool is only to be used to save MCE records in MCE context.
- * MCE events are rare, so a fixed size memory pool should be enough. Use
- * 2 pages to save MCE events for now (~80 MCE records at most).
+ * MCE events are rare, so a fixed size memory pool should be enough.
+ * Allocate on a sliding scale based on number of CPUs.
*/
-#define MCE_POOLSZ (2 * PAGE_SIZE)
+#define MCE_MIN_ENTRIES 80
+#define MCE_PER_CPU 2
static struct gen_pool *mce_evt_pool;
static LLIST_HEAD(mce_event_llist);
-static char gen_pool_buf[MCE_POOLSZ];
/*
* Compare the record "t" with each of the records on list "l" to see if
@@ -118,22 +118,32 @@ int mce_gen_pool_add(struct mce *mce)
static int mce_gen_pool_create(void)
{
- struct gen_pool *tmpp;
+ int mce_numrecords, mce_poolsz, order;
+ struct gen_pool *gpool;
int ret = -ENOMEM;
-
- tmpp = gen_pool_create(ilog2(sizeof(struct mce_evt_llist)), -1);
- if (!tmpp)
- goto out;
-
- ret = gen_pool_add(tmpp, (unsigned long)gen_pool_buf, MCE_POOLSZ, -1);
+ void *mce_pool;
+
+ order = order_base_2(sizeof(struct mce_evt_llist));
+ gpool = gen_pool_create(order, -1);
+ if (!gpool)
+ return ret;
+
+ mce_numrecords = max(MCE_MIN_ENTRIES, num_possible_cpus() * MCE_PER_CPU);
+ mce_poolsz = mce_numrecords * (1 << order);
+ mce_pool = kmalloc(mce_poolsz, GFP_KERNEL);
+ if (!mce_pool) {
+ gen_pool_destroy(gpool);
+ return ret;
+ }
+ ret = gen_pool_add(gpool, (unsigned long)mce_pool, mce_poolsz, -1);
if (ret) {
- gen_pool_destroy(tmpp);
- goto out;
+ gen_pool_destroy(gpool);
+ kfree(mce_pool);
+ return ret;
}
- mce_evt_pool = tmpp;
+ mce_evt_pool = gpool;
-out:
return ret;
}
diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c
index 94953d749475..49ed3428785d 100644
--- a/arch/x86/kernel/cpu/mce/inject.c
+++ b/arch/x86/kernel/cpu/mce/inject.c
@@ -487,12 +487,16 @@ static void prepare_msrs(void *info)
wrmsrl(MSR_AMD64_SMCA_MCx_ADDR(b), m.addr);
}
- wrmsrl(MSR_AMD64_SMCA_MCx_MISC(b), m.misc);
wrmsrl(MSR_AMD64_SMCA_MCx_SYND(b), m.synd);
+
+ if (m.misc)
+ wrmsrl(MSR_AMD64_SMCA_MCx_MISC(b), m.misc);
} else {
wrmsrl(MSR_IA32_MCx_STATUS(b), m.status);
wrmsrl(MSR_IA32_MCx_ADDR(b), m.addr);
- wrmsrl(MSR_IA32_MCx_MISC(b), m.misc);
+
+ if (m.misc)
+ wrmsrl(MSR_IA32_MCx_MISC(b), m.misc);
}
}
@@ -795,4 +799,5 @@ static void __exit inject_exit(void)
module_init(inject_init);
module_exit(inject_exit);
+MODULE_DESCRIPTION("Machine check injection support");
MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/mce/intel.c b/arch/x86/kernel/cpu/mce/intel.c
index 399b62e223d2..f6103e6bf69a 100644
--- a/arch/x86/kernel/cpu/mce/intel.c
+++ b/arch/x86/kernel/cpu/mce/intel.c
@@ -13,7 +13,7 @@
#include <linux/cpumask.h>
#include <asm/apic.h>
#include <asm/cpufeature.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/mce.h>
@@ -455,10 +455,10 @@ static void intel_imc_init(struct cpuinfo_x86 *c)
{
u64 error_control;
- switch (c->x86_model) {
- case INTEL_FAM6_SANDYBRIDGE_X:
- case INTEL_FAM6_IVYBRIDGE_X:
- case INTEL_FAM6_HASWELL_X:
+ switch (c->x86_vfm) {
+ case INTEL_SANDYBRIDGE_X:
+ case INTEL_IVYBRIDGE_X:
+ case INTEL_HASWELL_X:
if (rdmsrl_safe(MSR_ERROR_CONTROL, &error_control))
return;
error_control |= 2;
@@ -484,12 +484,11 @@ bool intel_filter_mce(struct mce *m)
struct cpuinfo_x86 *c = &boot_cpu_data;
/* MCE errata HSD131, HSM142, HSW131, BDM48, HSM142 and SKX37 */
- if ((c->x86 == 6) &&
- ((c->x86_model == INTEL_FAM6_HASWELL) ||
- (c->x86_model == INTEL_FAM6_HASWELL_L) ||
- (c->x86_model == INTEL_FAM6_BROADWELL) ||
- (c->x86_model == INTEL_FAM6_HASWELL_G) ||
- (c->x86_model == INTEL_FAM6_SKYLAKE_X)) &&
+ if ((c->x86_vfm == INTEL_HASWELL ||
+ c->x86_vfm == INTEL_HASWELL_L ||
+ c->x86_vfm == INTEL_BROADWELL ||
+ c->x86_vfm == INTEL_HASWELL_G ||
+ c->x86_vfm == INTEL_SKYLAKE_X) &&
(m->bank == 0) &&
((m->status & 0xa0000000ffffffff) == 0x80000000000f0005))
return true;
diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c
index c4477162c07d..dac4d64dfb2a 100644
--- a/arch/x86/kernel/cpu/mce/severity.c
+++ b/arch/x86/kernel/cpu/mce/severity.c
@@ -12,7 +12,7 @@
#include <linux/uaccess.h>
#include <asm/mce.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/traps.h>
#include <asm/insn.h>
#include <asm/insn-eval.h>
@@ -39,20 +39,20 @@ static struct severity {
u64 mask;
u64 result;
unsigned char sev;
- unsigned char mcgmask;
- unsigned char mcgres;
+ unsigned short mcgmask;
+ unsigned short mcgres;
unsigned char ser;
unsigned char context;
unsigned char excp;
unsigned char covered;
- unsigned char cpu_model;
+ unsigned int cpu_vfm;
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 VFM_STEPPING(m, s) .cpu_vfm = m, .cpu_minstepping = s
#define KERNEL .context = IN_KERNEL
#define USER .context = IN_USER
#define KERNEL_RECOV .context = IN_KERNEL_RECOV
@@ -128,7 +128,7 @@ static struct severity {
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)
+ VFM_STEPPING(INTEL_SKYLAKE_X, 4), BANK_RANGE(13, 18)
),
/* ignore OVER for UCNA */
@@ -174,6 +174,18 @@ static struct severity {
USER
),
MCESEV(
+ AR, "Data load error in SEAM non-root mode",
+ SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
+ MCGMASK(MCG_STATUS_SEAM_NR, MCG_STATUS_SEAM_NR),
+ KERNEL
+ ),
+ MCESEV(
+ AR, "Instruction fetch error in SEAM non-root mode",
+ SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
+ MCGMASK(MCG_STATUS_SEAM_NR, MCG_STATUS_SEAM_NR),
+ KERNEL
+ ),
+ MCESEV(
PANIC, "Data load in unrecoverable area of kernel",
SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
KERNEL
@@ -290,7 +302,6 @@ static noinstr int error_context(struct mce *m, struct pt_regs *regs)
switch (fixup_type) {
case EX_TYPE_UACCESS:
- case EX_TYPE_COPY:
if (!copy_user)
return IN_KERNEL;
m->kflags |= MCE_IN_KERNEL_COPYIN;
@@ -386,7 +397,7 @@ static noinstr int mce_severity_intel(struct mce *m, struct pt_regs *regs, char
continue;
if (s->excp && excp != s->excp)
continue;
- if (s->cpu_model && boot_cpu_data.x86_model != s->cpu_model)
+ if (s->cpu_vfm && boot_cpu_data.x86_vfm != s->cpu_vfm)
continue;
if (s->cpu_minstepping && boot_cpu_data.x86_stepping < s->cpu_minstepping)
continue;
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 13b45b9c806d..c0d56c02b8da 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -84,8 +84,6 @@ struct microcode_amd {
unsigned int mpb[];
};
-#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
-
static struct equiv_cpu_table {
unsigned int num_entries;
struct equiv_cpu_entry *entry;
@@ -465,7 +463,7 @@ static bool early_apply_microcode(u32 cpuid_1_eax, u32 old_rev, void *ucode, siz
return !__apply_microcode_amd(mc);
}
-static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
+static bool get_builtin_microcode(struct cpio_data *cp, u8 family)
{
char fw_name[36] = "amd-ucode/microcode_amd.bin";
struct firmware fw;
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 232026a239a6..b3658d11e7b6 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -60,11 +60,6 @@ module_param(force_minrev, bool, S_IRUSR | S_IWUSR);
*/
struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
-struct cpu_info_ctx {
- struct cpu_signature *cpu_sig;
- int err;
-};
-
/*
* Those patch levels cannot be updated to newer ones and thus should be final.
*/
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 5f0414452b67..815fa67356a2 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -21,7 +21,7 @@
#include <linux/uio.h>
#include <linux/mm.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/setup.h>
@@ -577,8 +577,7 @@ static bool is_blacklisted(unsigned int cpu)
* This behavior is documented in item BDF90, #334165 (Intel Xeon
* Processor E7-8800/4800 v4 Product Family).
*/
- if (c->x86 == 6 &&
- c->x86_model == INTEL_FAM6_BROADWELL_X &&
+ if (c->x86_vfm == INTEL_BROADWELL_X &&
c->x86_stepping == 0x01 &&
llc_size_per_core > 2621440 &&
c->microcode < 0x0b000021) {
diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh
index 1db560ed2ca3..68f537347466 100644
--- a/arch/x86/kernel/cpu/mkcapflags.sh
+++ b/arch/x86/kernel/cpu/mkcapflags.sh
@@ -30,8 +30,7 @@ dump_array()
# If the /* comment */ starts with a quote string, grab that.
VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')"
- [ -z "$VALUE" ] && VALUE="\"$NAME\""
- [ "$VALUE" = '""' ] && continue
+ [ ! "$VALUE" ] && continue
# Name is uppercase, VALUE is all lowercase
VALUE="$(echo "$VALUE" | tr A-Z a-z)"
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 83e40341583e..1930fce9dfe9 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -19,10 +19,9 @@
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/err.h>
-#include <linux/cacheinfo.h>
#include <linux/cpuhotplug.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/resctrl.h>
#include "internal.h"
@@ -56,16 +55,12 @@ int max_name_width, max_data_width;
*/
bool rdt_alloc_capable;
-static void
-mba_wrmsr_intel(struct rdt_domain *d, struct msr_param *m,
- struct rdt_resource *r);
-static void
-cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r);
-static void
-mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m,
- struct rdt_resource *r);
+static void mba_wrmsr_intel(struct msr_param *m);
+static void cat_wrmsr(struct msr_param *m);
+static void mba_wrmsr_amd(struct msr_param *m);
-#define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].r_resctrl.domains)
+#define ctrl_domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].r_resctrl.ctrl_domains)
+#define mon_domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].r_resctrl.mon_domains)
struct rdt_hw_resource rdt_resources_all[] = {
[RDT_RESOURCE_L3] =
@@ -73,8 +68,10 @@ struct rdt_hw_resource rdt_resources_all[] = {
.r_resctrl = {
.rid = RDT_RESOURCE_L3,
.name = "L3",
- .cache_level = 3,
- .domains = domain_init(RDT_RESOURCE_L3),
+ .ctrl_scope = RESCTRL_L3_CACHE,
+ .mon_scope = RESCTRL_L3_CACHE,
+ .ctrl_domains = ctrl_domain_init(RDT_RESOURCE_L3),
+ .mon_domains = mon_domain_init(RDT_RESOURCE_L3),
.parse_ctrlval = parse_cbm,
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
@@ -87,8 +84,8 @@ struct rdt_hw_resource rdt_resources_all[] = {
.r_resctrl = {
.rid = RDT_RESOURCE_L2,
.name = "L2",
- .cache_level = 2,
- .domains = domain_init(RDT_RESOURCE_L2),
+ .ctrl_scope = RESCTRL_L2_CACHE,
+ .ctrl_domains = ctrl_domain_init(RDT_RESOURCE_L2),
.parse_ctrlval = parse_cbm,
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
@@ -101,8 +98,8 @@ struct rdt_hw_resource rdt_resources_all[] = {
.r_resctrl = {
.rid = RDT_RESOURCE_MBA,
.name = "MB",
- .cache_level = 3,
- .domains = domain_init(RDT_RESOURCE_MBA),
+ .ctrl_scope = RESCTRL_L3_CACHE,
+ .ctrl_domains = ctrl_domain_init(RDT_RESOURCE_MBA),
.parse_ctrlval = parse_bw,
.format_str = "%d=%*u",
.fflags = RFTYPE_RES_MB,
@@ -113,8 +110,8 @@ struct rdt_hw_resource rdt_resources_all[] = {
.r_resctrl = {
.rid = RDT_RESOURCE_SMBA,
.name = "SMBA",
- .cache_level = 3,
- .domains = domain_init(RDT_RESOURCE_SMBA),
+ .ctrl_scope = RESCTRL_L3_CACHE,
+ .ctrl_domains = ctrl_domain_init(RDT_RESOURCE_SMBA),
.parse_ctrlval = parse_bw,
.format_str = "%d=%*u",
.fflags = RFTYPE_RES_MB,
@@ -309,12 +306,11 @@ static void rdt_get_cdp_l2_config(void)
rdt_get_cdp_config(RDT_RESOURCE_L2);
}
-static void
-mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r)
+static void mba_wrmsr_amd(struct msr_param *m)
{
+ struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(m->dom);
+ struct rdt_hw_resource *hw_res = resctrl_to_arch_res(m->res);
unsigned int i;
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
- struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
for (i = m->low; i < m->high; i++)
wrmsrl(hw_res->msr_base + i, hw_dom->ctrl_val[i]);
@@ -334,37 +330,51 @@ static u32 delay_bw_map(unsigned long bw, struct rdt_resource *r)
return r->default_ctrl;
}
-static void
-mba_wrmsr_intel(struct rdt_domain *d, struct msr_param *m,
- struct rdt_resource *r)
+static void mba_wrmsr_intel(struct msr_param *m)
{
+ struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(m->dom);
+ struct rdt_hw_resource *hw_res = resctrl_to_arch_res(m->res);
unsigned int i;
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
- struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
/* Write the delay values for mba. */
for (i = m->low; i < m->high; i++)
- wrmsrl(hw_res->msr_base + i, delay_bw_map(hw_dom->ctrl_val[i], r));
+ wrmsrl(hw_res->msr_base + i, delay_bw_map(hw_dom->ctrl_val[i], m->res));
}
-static void
-cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r)
+static void cat_wrmsr(struct msr_param *m)
{
+ struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(m->dom);
+ struct rdt_hw_resource *hw_res = resctrl_to_arch_res(m->res);
unsigned int i;
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
- struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
for (i = m->low; i < m->high; i++)
wrmsrl(hw_res->msr_base + i, hw_dom->ctrl_val[i]);
}
-struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r)
+struct rdt_ctrl_domain *get_ctrl_domain_from_cpu(int cpu, struct rdt_resource *r)
{
- struct rdt_domain *d;
+ struct rdt_ctrl_domain *d;
+
+ lockdep_assert_cpus_held();
- list_for_each_entry(d, &r->domains, list) {
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
/* Find the domain that contains this CPU */
- if (cpumask_test_cpu(cpu, &d->cpu_mask))
+ if (cpumask_test_cpu(cpu, &d->hdr.cpu_mask))
+ return d;
+ }
+
+ return NULL;
+}
+
+struct rdt_mon_domain *get_mon_domain_from_cpu(int cpu, struct rdt_resource *r)
+{
+ struct rdt_mon_domain *d;
+
+ lockdep_assert_cpus_held();
+
+ list_for_each_entry(d, &r->mon_domains, hdr.list) {
+ /* Find the domain that contains this CPU */
+ if (cpumask_test_cpu(cpu, &d->hdr.cpu_mask))
return d;
}
@@ -378,40 +388,29 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *r)
void rdt_ctrl_update(void *arg)
{
+ struct rdt_hw_resource *hw_res;
struct msr_param *m = arg;
- struct rdt_hw_resource *hw_res = resctrl_to_arch_res(m->res);
- struct rdt_resource *r = m->res;
- int cpu = smp_processor_id();
- struct rdt_domain *d;
- d = get_domain_from_cpu(cpu, r);
- if (d) {
- hw_res->msr_update(d, m, r);
- return;
- }
- pr_warn_once("cpu %d not found in any domain for resource %s\n",
- cpu, r->name);
+ hw_res = resctrl_to_arch_res(m->res);
+ hw_res->msr_update(m);
}
/*
- * rdt_find_domain - Find a domain in a resource that matches input resource id
+ * rdt_find_domain - Search for a domain id in a resource domain list.
*
- * Search resource r's domain list to find the resource id. If the resource
- * id is found in a domain, return the domain. Otherwise, if requested by
- * caller, return the first domain whose id is bigger than the input id.
- * The domain list is sorted by id in ascending order.
+ * Search the domain list to find the domain id. If the domain id is
+ * found, return the domain. NULL otherwise. If the domain id is not
+ * found (and NULL returned) then the first domain with id bigger than
+ * the input id can be returned to the caller via @pos.
*/
-struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id,
- struct list_head **pos)
+struct rdt_domain_hdr *rdt_find_domain(struct list_head *h, int id,
+ struct list_head **pos)
{
- struct rdt_domain *d;
+ struct rdt_domain_hdr *d;
struct list_head *l;
- if (id < 0)
- return ERR_PTR(-ENODEV);
-
- list_for_each(l, &r->domains) {
- d = list_entry(l, struct rdt_domain, list);
+ list_for_each(l, h) {
+ d = list_entry(l, struct rdt_domain_hdr, list);
/* When id is found, return its domain. */
if (id == d->id)
return d;
@@ -440,18 +439,23 @@ static void setup_default_ctrlval(struct rdt_resource *r, u32 *dc)
*dc = r->default_ctrl;
}
-static void domain_free(struct rdt_hw_domain *hw_dom)
+static void ctrl_domain_free(struct rdt_hw_ctrl_domain *hw_dom)
+{
+ kfree(hw_dom->ctrl_val);
+ kfree(hw_dom);
+}
+
+static void mon_domain_free(struct rdt_hw_mon_domain *hw_dom)
{
kfree(hw_dom->arch_mbm_total);
kfree(hw_dom->arch_mbm_local);
- kfree(hw_dom->ctrl_val);
kfree(hw_dom);
}
-static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
+static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_ctrl_domain *d)
{
+ struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(d);
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
struct msr_param m;
u32 *dc;
@@ -463,9 +467,11 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
hw_dom->ctrl_val = dc;
setup_default_ctrlval(r, dc);
+ m.res = r;
+ m.dom = d;
m.low = 0;
m.high = hw_res->num_closid;
- hw_res->msr_update(d, &m, r);
+ hw_res->msr_update(&m);
return 0;
}
@@ -474,7 +480,7 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
* @num_rmid: The size of the MBM counter array
* @hw_dom: The domain that owns the allocated arrays
*/
-static int arch_domain_mbm_alloc(u32 num_rmid, struct rdt_hw_domain *hw_dom)
+static int arch_domain_mbm_alloc(u32 num_rmid, struct rdt_hw_mon_domain *hw_dom)
{
size_t tsize;
@@ -497,37 +503,45 @@ static int arch_domain_mbm_alloc(u32 num_rmid, struct rdt_hw_domain *hw_dom)
return 0;
}
-/*
- * domain_add_cpu - Add a cpu to a resource's domain list.
- *
- * If an existing domain in the resource r's domain list matches the cpu's
- * resource id, add the cpu in the domain.
- *
- * Otherwise, a new domain is allocated and inserted into the right position
- * in the domain list sorted by id in ascending order.
- *
- * The order in the domain list is visible to users when we print entries
- * in the schemata file and schemata input is validated to have the same order
- * as this list.
- */
-static void domain_add_cpu(int cpu, struct rdt_resource *r)
+static int get_domain_id_from_scope(int cpu, enum resctrl_scope scope)
+{
+ switch (scope) {
+ case RESCTRL_L2_CACHE:
+ case RESCTRL_L3_CACHE:
+ return get_cpu_cacheinfo_id(cpu, scope);
+ case RESCTRL_L3_NODE:
+ return cpu_to_node(cpu);
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static void domain_add_cpu_ctrl(int cpu, struct rdt_resource *r)
{
- int id = get_cpu_cacheinfo_id(cpu, r->cache_level);
+ int id = get_domain_id_from_scope(cpu, r->ctrl_scope);
+ struct rdt_hw_ctrl_domain *hw_dom;
struct list_head *add_pos = NULL;
- struct rdt_hw_domain *hw_dom;
- struct rdt_domain *d;
+ struct rdt_domain_hdr *hdr;
+ struct rdt_ctrl_domain *d;
int err;
lockdep_assert_held(&domain_list_lock);
- d = rdt_find_domain(r, id, &add_pos);
- if (IS_ERR(d)) {
- pr_warn("Couldn't find cache id for CPU %d\n", cpu);
+ if (id < 0) {
+ pr_warn_once("Can't find control domain id for CPU:%d scope:%d for resource %s\n",
+ cpu, r->ctrl_scope, r->name);
return;
}
- if (d) {
- cpumask_set_cpu(cpu, &d->cpu_mask);
+ hdr = rdt_find_domain(&r->ctrl_domains, id, &add_pos);
+ if (hdr) {
+ if (WARN_ON_ONCE(hdr->type != RESCTRL_CTRL_DOMAIN))
+ return;
+ d = container_of(hdr, struct rdt_ctrl_domain, hdr);
+
+ cpumask_set_cpu(cpu, &d->hdr.cpu_mask);
if (r->cache.arch_has_per_cpu_cfg)
rdt_domain_reconfigure_cdp(r);
return;
@@ -538,62 +552,185 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
return;
d = &hw_dom->d_resctrl;
- d->id = id;
- cpumask_set_cpu(cpu, &d->cpu_mask);
+ d->hdr.id = id;
+ d->hdr.type = RESCTRL_CTRL_DOMAIN;
+ cpumask_set_cpu(cpu, &d->hdr.cpu_mask);
rdt_domain_reconfigure_cdp(r);
- if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
- domain_free(hw_dom);
+ if (domain_setup_ctrlval(r, d)) {
+ ctrl_domain_free(hw_dom);
return;
}
- if (r->mon_capable && arch_domain_mbm_alloc(r->num_rmid, hw_dom)) {
- domain_free(hw_dom);
+ list_add_tail_rcu(&d->hdr.list, add_pos);
+
+ err = resctrl_online_ctrl_domain(r, d);
+ if (err) {
+ list_del_rcu(&d->hdr.list);
+ synchronize_rcu();
+ ctrl_domain_free(hw_dom);
+ }
+}
+
+static void domain_add_cpu_mon(int cpu, struct rdt_resource *r)
+{
+ int id = get_domain_id_from_scope(cpu, r->mon_scope);
+ struct list_head *add_pos = NULL;
+ struct rdt_hw_mon_domain *hw_dom;
+ struct rdt_domain_hdr *hdr;
+ struct rdt_mon_domain *d;
+ int err;
+
+ lockdep_assert_held(&domain_list_lock);
+
+ if (id < 0) {
+ pr_warn_once("Can't find monitor domain id for CPU:%d scope:%d for resource %s\n",
+ cpu, r->mon_scope, r->name);
return;
}
- list_add_tail_rcu(&d->list, add_pos);
+ hdr = rdt_find_domain(&r->mon_domains, id, &add_pos);
+ if (hdr) {
+ if (WARN_ON_ONCE(hdr->type != RESCTRL_MON_DOMAIN))
+ return;
+ d = container_of(hdr, struct rdt_mon_domain, hdr);
- err = resctrl_online_domain(r, d);
+ cpumask_set_cpu(cpu, &d->hdr.cpu_mask);
+ return;
+ }
+
+ hw_dom = kzalloc_node(sizeof(*hw_dom), GFP_KERNEL, cpu_to_node(cpu));
+ if (!hw_dom)
+ return;
+
+ d = &hw_dom->d_resctrl;
+ d->hdr.id = id;
+ d->hdr.type = RESCTRL_MON_DOMAIN;
+ d->ci = get_cpu_cacheinfo_level(cpu, RESCTRL_L3_CACHE);
+ if (!d->ci) {
+ pr_warn_once("Can't find L3 cache for CPU:%d resource %s\n", cpu, r->name);
+ mon_domain_free(hw_dom);
+ return;
+ }
+ cpumask_set_cpu(cpu, &d->hdr.cpu_mask);
+
+ arch_mon_domain_online(r, d);
+
+ if (arch_domain_mbm_alloc(r->num_rmid, hw_dom)) {
+ mon_domain_free(hw_dom);
+ return;
+ }
+
+ list_add_tail_rcu(&d->hdr.list, add_pos);
+
+ err = resctrl_online_mon_domain(r, d);
if (err) {
- list_del_rcu(&d->list);
+ list_del_rcu(&d->hdr.list);
synchronize_rcu();
- domain_free(hw_dom);
+ mon_domain_free(hw_dom);
}
}
-static void domain_remove_cpu(int cpu, struct rdt_resource *r)
+static void domain_add_cpu(int cpu, struct rdt_resource *r)
{
- int id = get_cpu_cacheinfo_id(cpu, r->cache_level);
- struct rdt_hw_domain *hw_dom;
- struct rdt_domain *d;
+ if (r->alloc_capable)
+ domain_add_cpu_ctrl(cpu, r);
+ if (r->mon_capable)
+ domain_add_cpu_mon(cpu, r);
+}
+
+static void domain_remove_cpu_ctrl(int cpu, struct rdt_resource *r)
+{
+ int id = get_domain_id_from_scope(cpu, r->ctrl_scope);
+ struct rdt_hw_ctrl_domain *hw_dom;
+ struct rdt_domain_hdr *hdr;
+ struct rdt_ctrl_domain *d;
lockdep_assert_held(&domain_list_lock);
- d = rdt_find_domain(r, id, NULL);
- if (IS_ERR_OR_NULL(d)) {
- pr_warn("Couldn't find cache id for CPU %d\n", cpu);
+ if (id < 0) {
+ pr_warn_once("Can't find control domain id for CPU:%d scope:%d for resource %s\n",
+ cpu, r->ctrl_scope, r->name);
+ return;
+ }
+
+ hdr = rdt_find_domain(&r->ctrl_domains, id, NULL);
+ if (!hdr) {
+ pr_warn("Can't find control domain for id=%d for CPU %d for resource %s\n",
+ id, cpu, r->name);
return;
}
- hw_dom = resctrl_to_arch_dom(d);
- cpumask_clear_cpu(cpu, &d->cpu_mask);
- if (cpumask_empty(&d->cpu_mask)) {
- resctrl_offline_domain(r, d);
- list_del_rcu(&d->list);
+ if (WARN_ON_ONCE(hdr->type != RESCTRL_CTRL_DOMAIN))
+ return;
+
+ d = container_of(hdr, struct rdt_ctrl_domain, hdr);
+ hw_dom = resctrl_to_arch_ctrl_dom(d);
+
+ cpumask_clear_cpu(cpu, &d->hdr.cpu_mask);
+ if (cpumask_empty(&d->hdr.cpu_mask)) {
+ resctrl_offline_ctrl_domain(r, d);
+ list_del_rcu(&d->hdr.list);
synchronize_rcu();
/*
- * rdt_domain "d" is going to be freed below, so clear
+ * rdt_ctrl_domain "d" is going to be freed below, so clear
* its pointer from pseudo_lock_region struct.
*/
if (d->plr)
d->plr->d = NULL;
- domain_free(hw_dom);
+ ctrl_domain_free(hw_dom);
+
+ return;
+ }
+}
+
+static void domain_remove_cpu_mon(int cpu, struct rdt_resource *r)
+{
+ int id = get_domain_id_from_scope(cpu, r->mon_scope);
+ struct rdt_hw_mon_domain *hw_dom;
+ struct rdt_domain_hdr *hdr;
+ struct rdt_mon_domain *d;
+
+ lockdep_assert_held(&domain_list_lock);
+
+ if (id < 0) {
+ pr_warn_once("Can't find monitor domain id for CPU:%d scope:%d for resource %s\n",
+ cpu, r->mon_scope, r->name);
+ return;
+ }
+ hdr = rdt_find_domain(&r->mon_domains, id, NULL);
+ if (!hdr) {
+ pr_warn("Can't find monitor domain for id=%d for CPU %d for resource %s\n",
+ id, cpu, r->name);
return;
}
+
+ if (WARN_ON_ONCE(hdr->type != RESCTRL_MON_DOMAIN))
+ return;
+
+ d = container_of(hdr, struct rdt_mon_domain, hdr);
+ hw_dom = resctrl_to_arch_mon_dom(d);
+
+ cpumask_clear_cpu(cpu, &d->hdr.cpu_mask);
+ if (cpumask_empty(&d->hdr.cpu_mask)) {
+ resctrl_offline_mon_domain(r, d);
+ list_del_rcu(&d->hdr.list);
+ synchronize_rcu();
+ mon_domain_free(hw_dom);
+
+ return;
+ }
+}
+
+static void domain_remove_cpu(int cpu, struct rdt_resource *r)
+{
+ if (r->alloc_capable)
+ domain_remove_cpu_ctrl(cpu, r);
+ if (r->mon_capable)
+ domain_remove_cpu_mon(cpu, r);
}
static void clear_closid_rmid(int cpu)
@@ -821,18 +958,18 @@ static __init bool get_rdt_mon_resources(void)
static __init void __check_quirks_intel(void)
{
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_HASWELL_X:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_HASWELL_X:
if (!rdt_options[RDT_FLAG_L3_CAT].force_off)
cache_alloc_hsw_probe();
break;
- case INTEL_FAM6_SKYLAKE_X:
+ case INTEL_SKYLAKE_X:
if (boot_cpu_data.x86_stepping <= 4)
set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat");
else
set_rdt_options("!l3cat");
fallthrough;
- case INTEL_FAM6_BROADWELL_X:
+ case INTEL_BROADWELL_X:
intel_rdt_mbm_apply_quirk();
break;
}
diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
index 7997b47743a2..50fa1fe9a073 100644
--- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -60,7 +60,7 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
}
int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
- struct rdt_domain *d)
+ struct rdt_ctrl_domain *d)
{
struct resctrl_staged_config *cfg;
u32 closid = data->rdtgrp->closid;
@@ -69,7 +69,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
cfg = &d->staged_config[s->conf_type];
if (cfg->have_new_ctrl) {
- rdt_last_cmd_printf("Duplicate domain %d\n", d->id);
+ rdt_last_cmd_printf("Duplicate domain %d\n", d->hdr.id);
return -EINVAL;
}
@@ -139,7 +139,7 @@ static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)
* resource type.
*/
int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
- struct rdt_domain *d)
+ struct rdt_ctrl_domain *d)
{
struct rdtgroup *rdtgrp = data->rdtgrp;
struct resctrl_staged_config *cfg;
@@ -148,7 +148,7 @@ int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
cfg = &d->staged_config[s->conf_type];
if (cfg->have_new_ctrl) {
- rdt_last_cmd_printf("Duplicate domain %d\n", d->id);
+ rdt_last_cmd_printf("Duplicate domain %d\n", d->hdr.id);
return -EINVAL;
}
@@ -208,8 +208,8 @@ static int parse_line(char *line, struct resctrl_schema *s,
struct resctrl_staged_config *cfg;
struct rdt_resource *r = s->res;
struct rdt_parse_data data;
+ struct rdt_ctrl_domain *d;
char *dom = NULL, *id;
- struct rdt_domain *d;
unsigned long dom_id;
/* Walking r->domains, ensure it can't race with cpuhp */
@@ -231,8 +231,8 @@ next:
return -EINVAL;
}
dom = strim(dom);
- list_for_each_entry(d, &r->domains, list) {
- if (d->id == dom_id) {
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
+ if (d->hdr.id == dom_id) {
data.buf = dom;
data.rdtgrp = rdtgrp;
if (r->parse_ctrlval(&data, s, d))
@@ -272,39 +272,24 @@ static u32 get_config_index(u32 closid, enum resctrl_conf_type type)
}
}
-static bool apply_config(struct rdt_hw_domain *hw_dom,
- struct resctrl_staged_config *cfg, u32 idx,
- cpumask_var_t cpu_mask)
-{
- struct rdt_domain *dom = &hw_dom->d_resctrl;
-
- if (cfg->new_ctrl != hw_dom->ctrl_val[idx]) {
- cpumask_set_cpu(cpumask_any(&dom->cpu_mask), cpu_mask);
- hw_dom->ctrl_val[idx] = cfg->new_ctrl;
-
- return true;
- }
-
- return false;
-}
-
-int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d,
+int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
u32 closid, enum resctrl_conf_type t, u32 cfg_val)
{
+ struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(d);
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
u32 idx = get_config_index(closid, t);
struct msr_param msr_param;
- if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask))
+ if (!cpumask_test_cpu(smp_processor_id(), &d->hdr.cpu_mask))
return -EINVAL;
hw_dom->ctrl_val[idx] = cfg_val;
msr_param.res = r;
+ msr_param.dom = d;
msr_param.low = idx;
msr_param.high = idx + 1;
- hw_res->msr_update(d, &msr_param, r);
+ hw_res->msr_update(&msr_param);
return 0;
}
@@ -312,51 +297,42 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d,
int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
{
struct resctrl_staged_config *cfg;
- struct rdt_hw_domain *hw_dom;
+ struct rdt_hw_ctrl_domain *hw_dom;
struct msr_param msr_param;
+ struct rdt_ctrl_domain *d;
enum resctrl_conf_type t;
- cpumask_var_t cpu_mask;
- struct rdt_domain *d;
u32 idx;
/* Walking r->domains, ensure it can't race with cpuhp */
lockdep_assert_cpus_held();
- if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
- return -ENOMEM;
-
- msr_param.res = NULL;
- list_for_each_entry(d, &r->domains, list) {
- hw_dom = resctrl_to_arch_dom(d);
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
+ hw_dom = resctrl_to_arch_ctrl_dom(d);
+ msr_param.res = NULL;
for (t = 0; t < CDP_NUM_TYPES; t++) {
cfg = &hw_dom->d_resctrl.staged_config[t];
if (!cfg->have_new_ctrl)
continue;
idx = get_config_index(closid, t);
- if (!apply_config(hw_dom, cfg, idx, cpu_mask))
+ if (cfg->new_ctrl == hw_dom->ctrl_val[idx])
continue;
+ hw_dom->ctrl_val[idx] = cfg->new_ctrl;
if (!msr_param.res) {
msr_param.low = idx;
msr_param.high = msr_param.low + 1;
msr_param.res = r;
+ msr_param.dom = d;
} else {
msr_param.low = min(msr_param.low, idx);
msr_param.high = max(msr_param.high, idx + 1);
}
}
+ if (msr_param.res)
+ smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &msr_param, 1);
}
- if (cpumask_empty(cpu_mask))
- goto done;
-
- /* Update resource control msr on all the CPUs. */
- on_each_cpu_mask(cpu_mask, rdt_ctrl_update, &msr_param, 1);
-
-done:
- free_cpumask_var(cpu_mask);
-
return 0;
}
@@ -454,10 +430,10 @@ out:
return ret ?: nbytes;
}
-u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d,
+u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
u32 closid, enum resctrl_conf_type type)
{
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+ struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(d);
u32 idx = get_config_index(closid, type);
return hw_dom->ctrl_val[idx];
@@ -466,7 +442,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d,
static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid)
{
struct rdt_resource *r = schema->res;
- struct rdt_domain *dom;
+ struct rdt_ctrl_domain *dom;
bool sep = false;
u32 ctrl_val;
@@ -474,7 +450,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo
lockdep_assert_cpus_held();
seq_printf(s, "%*s:", max_name_width, schema->name);
- list_for_each_entry(dom, &r->domains, list) {
+ list_for_each_entry(dom, &r->ctrl_domains, hdr.list) {
if (sep)
seq_puts(s, ";");
@@ -484,7 +460,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo
ctrl_val = resctrl_arch_get_config(r, dom, closid,
schema->conf_type);
- seq_printf(s, r->format_str, dom->id, max_data_width,
+ seq_printf(s, r->format_str, dom->hdr.id, max_data_width,
ctrl_val);
sep = true;
}
@@ -513,7 +489,7 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of,
} else {
seq_printf(s, "%s:%d=%x\n",
rdtgrp->plr->s->res->name,
- rdtgrp->plr->d->id,
+ rdtgrp->plr->d->hdr.id,
rdtgrp->plr->cbm);
}
} else {
@@ -538,8 +514,8 @@ static int smp_mon_event_count(void *arg)
}
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
- struct rdt_domain *d, struct rdtgroup *rdtgrp,
- int evtid, int first)
+ struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
+ cpumask_t *cpumask, int evtid, int first)
{
int cpu;
@@ -553,7 +529,6 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
rr->evtid = evtid;
rr->r = r;
rr->d = d;
- rr->val = 0;
rr->first = first;
rr->arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, evtid);
if (IS_ERR(rr->arch_mon_ctx)) {
@@ -561,7 +536,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
return;
}
- cpu = cpumask_any_housekeeping(&d->cpu_mask, RESCTRL_PICK_ANY_CPU);
+ cpu = cpumask_any_housekeeping(cpumask, RESCTRL_PICK_ANY_CPU);
/*
* cpumask_any_housekeeping() prefers housekeeping CPUs, but
@@ -570,7 +545,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
* counters on some platforms if its called in IRQ context.
*/
if (tick_nohz_full_cpu(cpu))
- smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1);
+ smp_call_function_any(cpumask, mon_event_count, rr, 1);
else
smp_call_on_cpu(cpu, smp_mon_event_count, rr, false);
@@ -580,12 +555,13 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
int rdtgroup_mondata_show(struct seq_file *m, void *arg)
{
struct kernfs_open_file *of = m->private;
+ struct rdt_domain_hdr *hdr;
+ struct rmid_read rr = {0};
+ struct rdt_mon_domain *d;
u32 resid, evtid, domid;
struct rdtgroup *rdtgrp;
struct rdt_resource *r;
union mon_data_bits md;
- struct rdt_domain *d;
- struct rmid_read rr;
int ret = 0;
rdtgrp = rdtgroup_kn_lock_live(of->kn);
@@ -598,15 +574,40 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
resid = md.u.rid;
domid = md.u.domid;
evtid = md.u.evtid;
-
r = &rdt_resources_all[resid].r_resctrl;
- d = rdt_find_domain(r, domid, NULL);
- if (IS_ERR_OR_NULL(d)) {
+
+ if (md.u.sum) {
+ /*
+ * This file requires summing across all domains that share
+ * the L3 cache id that was provided in the "domid" field of the
+ * mon_data_bits union. Search all domains in the resource for
+ * one that matches this cache id.
+ */
+ list_for_each_entry(d, &r->mon_domains, hdr.list) {
+ if (d->ci->id == domid) {
+ rr.ci = d->ci;
+ mon_event_read(&rr, r, NULL, rdtgrp,
+ &d->ci->shared_cpu_map, evtid, false);
+ goto checkresult;
+ }
+ }
ret = -ENOENT;
goto out;
+ } else {
+ /*
+ * This file provides data from a single domain. Search
+ * the resource to find the domain with "domid".
+ */
+ hdr = rdt_find_domain(&r->mon_domains, domid, NULL);
+ if (!hdr || WARN_ON_ONCE(hdr->type != RESCTRL_MON_DOMAIN)) {
+ ret = -ENOENT;
+ goto out;
+ }
+ d = container_of(hdr, struct rdt_mon_domain, hdr);
+ mon_event_read(&rr, r, d, rdtgrp, &d->hdr.cpu_mask, evtid, false);
}
- mon_event_read(&rr, r, d, rdtgrp, evtid, false);
+checkresult:
if (rr.err == -EIO)
seq_puts(m, "Error\n");
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 1a8687f8073a..955999aecfca 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -127,29 +127,54 @@ struct mon_evt {
};
/**
- * union mon_data_bits - Monitoring details for each event file
+ * union mon_data_bits - Monitoring details for each event file.
* @priv: Used to store monitoring event data in @u
- * as kernfs private data
- * @rid: Resource id associated with the event file
- * @evtid: Event id associated with the event file
- * @domid: The domain to which the event file belongs
- * @u: Name of the bit fields struct
+ * as kernfs private data.
+ * @u.rid: Resource id associated with the event file.
+ * @u.evtid: Event id associated with the event file.
+ * @u.sum: Set when event must be summed across multiple
+ * domains.
+ * @u.domid: When @u.sum is zero this is the domain to which
+ * the event file belongs. When @sum is one this
+ * is the id of the L3 cache that all domains to be
+ * summed share.
+ * @u: Name of the bit fields struct.
*/
union mon_data_bits {
void *priv;
struct {
unsigned int rid : 10;
- enum resctrl_event_id evtid : 8;
+ enum resctrl_event_id evtid : 7;
+ unsigned int sum : 1;
unsigned int domid : 14;
} u;
};
+/**
+ * struct rmid_read - Data passed across smp_call*() to read event count.
+ * @rgrp: Resource group for which the counter is being read. If it is a parent
+ * resource group then its event count is summed with the count from all
+ * its child resource groups.
+ * @r: Resource describing the properties of the event being read.
+ * @d: Domain that the counter should be read from. If NULL then sum all
+ * domains in @r sharing L3 @ci.id
+ * @evtid: Which monitor event to read.
+ * @first: Initialize MBM counter when true.
+ * @ci: Cacheinfo for L3. Only set when @d is NULL. Used when summing domains.
+ * @err: Error encountered when reading counter.
+ * @val: Returned value of event counter. If @rgrp is a parent resource group,
+ * @val includes the sum of event counts from its child resource groups.
+ * If @d is NULL, @val includes the sum of all domains in @r sharing @ci.id,
+ * (summed across child resource groups if @rgrp is a parent resource group).
+ * @arch_mon_ctx: Hardware monitor allocated for this read request (MPAM only).
+ */
struct rmid_read {
struct rdtgroup *rgrp;
struct rdt_resource *r;
- struct rdt_domain *d;
+ struct rdt_mon_domain *d;
enum resctrl_event_id evtid;
bool first;
+ struct cacheinfo *ci;
int err;
u64 val;
void *arch_mon_ctx;
@@ -232,7 +257,7 @@ struct mongroup {
*/
struct pseudo_lock_region {
struct resctrl_schema *s;
- struct rdt_domain *d;
+ struct rdt_ctrl_domain *d;
u32 cbm;
wait_queue_head_t lock_thread_wq;
int thread_done;
@@ -355,35 +380,53 @@ struct arch_mbm_state {
};
/**
- * struct rdt_hw_domain - Arch private attributes of a set of CPUs that share
- * a resource
+ * struct rdt_hw_ctrl_domain - Arch private attributes of a set of CPUs that share
+ * a resource for a control function
* @d_resctrl: Properties exposed to the resctrl file system
* @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID)
+ *
+ * Members of this structure are accessed via helpers that provide abstraction.
+ */
+struct rdt_hw_ctrl_domain {
+ struct rdt_ctrl_domain d_resctrl;
+ u32 *ctrl_val;
+};
+
+/**
+ * struct rdt_hw_mon_domain - Arch private attributes of a set of CPUs that share
+ * a resource for a monitor function
+ * @d_resctrl: Properties exposed to the resctrl file system
* @arch_mbm_total: arch private state for MBM total bandwidth
* @arch_mbm_local: arch private state for MBM local bandwidth
*
* Members of this structure are accessed via helpers that provide abstraction.
*/
-struct rdt_hw_domain {
- struct rdt_domain d_resctrl;
- u32 *ctrl_val;
+struct rdt_hw_mon_domain {
+ struct rdt_mon_domain d_resctrl;
struct arch_mbm_state *arch_mbm_total;
struct arch_mbm_state *arch_mbm_local;
};
-static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r)
+static inline struct rdt_hw_ctrl_domain *resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain *r)
{
- return container_of(r, struct rdt_hw_domain, d_resctrl);
+ return container_of(r, struct rdt_hw_ctrl_domain, d_resctrl);
+}
+
+static inline struct rdt_hw_mon_domain *resctrl_to_arch_mon_dom(struct rdt_mon_domain *r)
+{
+ return container_of(r, struct rdt_hw_mon_domain, d_resctrl);
}
/**
* struct msr_param - set a range of MSRs from a domain
* @res: The resource to use
+ * @dom: The domain to update
* @low: Beginning index from base MSR
* @high: End index
*/
struct msr_param {
struct rdt_resource *res;
+ struct rdt_ctrl_domain *dom;
u32 low;
u32 high;
};
@@ -443,8 +486,7 @@ struct rdt_hw_resource {
struct rdt_resource r_resctrl;
u32 num_closid;
unsigned int msr_base;
- void (*msr_update) (struct rdt_domain *d, struct msr_param *m,
- struct rdt_resource *r);
+ void (*msr_update)(struct msr_param *m);
unsigned int mon_scale;
unsigned int mbm_width;
unsigned int mbm_cfg_mask;
@@ -457,9 +499,9 @@ static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r
}
int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
- struct rdt_domain *d);
+ struct rdt_ctrl_domain *d);
int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
- struct rdt_domain *d);
+ struct rdt_ctrl_domain *d);
extern struct mutex rdtgroup_mutex;
@@ -492,6 +534,8 @@ static inline bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l)
int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable);
+void arch_mon_domain_online(struct rdt_resource *r, struct rdt_mon_domain *d);
+
/*
* To return the common struct rdt_resource, which is contained in struct
* rdt_hw_resource, walk the resctrl member of struct rdt_hw_resource.
@@ -557,27 +601,28 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn);
int rdtgroup_kn_mode_restrict(struct rdtgroup *r, const char *name);
int rdtgroup_kn_mode_restore(struct rdtgroup *r, const char *name,
umode_t mask);
-struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id,
- struct list_head **pos);
+struct rdt_domain_hdr *rdt_find_domain(struct list_head *h, int id,
+ struct list_head **pos);
ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off);
int rdtgroup_schemata_show(struct kernfs_open_file *of,
struct seq_file *s, void *v);
-bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_domain *d,
+bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_ctrl_domain *d,
unsigned long cbm, int closid, bool exclusive);
-unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct rdt_domain *d,
+unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct rdt_ctrl_domain *d,
unsigned long cbm);
enum rdtgrp_mode rdtgroup_mode_by_closid(int closid);
int rdtgroup_tasks_assigned(struct rdtgroup *r);
int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp);
int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp);
-bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm);
-bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d);
+bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned long cbm);
+bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain *d);
int rdt_pseudo_lock_init(void);
void rdt_pseudo_lock_release(void);
int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp);
void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp);
-struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r);
+struct rdt_ctrl_domain *get_ctrl_domain_from_cpu(int cpu, struct rdt_resource *r);
+struct rdt_mon_domain *get_mon_domain_from_cpu(int cpu, struct rdt_resource *r);
int closids_supported(void);
void closid_free(int closid);
int alloc_rmid(u32 closid);
@@ -588,19 +633,19 @@ bool __init rdt_cpu_has(int flag);
void mon_event_count(void *info);
int rdtgroup_mondata_show(struct seq_file *m, void *arg);
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
- struct rdt_domain *d, struct rdtgroup *rdtgrp,
- int evtid, int first);
-void mbm_setup_overflow_handler(struct rdt_domain *dom,
+ struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
+ cpumask_t *cpumask, int evtid, int first);
+void mbm_setup_overflow_handler(struct rdt_mon_domain *dom,
unsigned long delay_ms,
int exclude_cpu);
void mbm_handle_overflow(struct work_struct *work);
void __init intel_rdt_mbm_apply_quirk(void);
bool is_mba_sc(struct rdt_resource *r);
-void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms,
+void cqm_setup_limbo_handler(struct rdt_mon_domain *dom, unsigned long delay_ms,
int exclude_cpu);
void cqm_handle_limbo(struct work_struct *work);
-bool has_busy_rmid(struct rdt_domain *d);
-void __check_limbo(struct rdt_domain *d, bool force_free);
+bool has_busy_rmid(struct rdt_mon_domain *d);
+void __check_limbo(struct rdt_mon_domain *d, bool force_free);
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
void __init thread_throttle_mode_init(void);
void __init mbm_config_rftype_init(const char *config);
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index c34a35ec0f03..851b561850e0 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -15,6 +15,8 @@
* Software Developer Manual June 2016, volume 3, section 17.17.
*/
+#define pr_fmt(fmt) "resctrl: " fmt
+
#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/sizes.h>
@@ -24,6 +26,7 @@
#include <asm/resctrl.h>
#include "internal.h"
+#include "trace.h"
/**
* struct rmid_entry - dirty tracking for all RMID.
@@ -96,6 +99,8 @@ unsigned int resctrl_rmid_realloc_limit;
#define CF(cf) ((unsigned long)(1048576 * (cf) + 0.5))
+static int snc_nodes_per_l3_cache = 1;
+
/*
* The correction factor table is documented in Documentation/arch/x86/resctrl.rst.
* If rmid > rmid threshold, MBM total and local values should be multiplied
@@ -184,7 +189,43 @@ static inline struct rmid_entry *__rmid_entry(u32 idx)
return entry;
}
-static int __rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *val)
+/*
+ * When Sub-NUMA Cluster (SNC) mode is not enabled (as indicated by
+ * "snc_nodes_per_l3_cache == 1") no translation of the RMID value is
+ * needed. The physical RMID is the same as the logical RMID.
+ *
+ * On a platform with SNC mode enabled, Linux enables RMID sharing mode
+ * via MSR 0xCA0 (see the "RMID Sharing Mode" section in the "Intel
+ * Resource Director Technology Architecture Specification" for a full
+ * description of RMID sharing mode).
+ *
+ * In RMID sharing mode there are fewer "logical RMID" values available
+ * to accumulate data ("physical RMIDs" are divided evenly between SNC
+ * nodes that share an L3 cache). Linux creates an rdt_mon_domain for
+ * each SNC node.
+ *
+ * The value loaded into IA32_PQR_ASSOC is the "logical RMID".
+ *
+ * Data is collected independently on each SNC node and can be retrieved
+ * using the "physical RMID" value computed by this function and loaded
+ * into IA32_QM_EVTSEL. @cpu can be any CPU in the SNC node.
+ *
+ * The scope of the IA32_QM_EVTSEL and IA32_QM_CTR MSRs is at the L3
+ * cache. So a "physical RMID" may be read from any CPU that shares
+ * the L3 cache with the desired SNC node, not just from a CPU in
+ * the specific SNC node.
+ */
+static int logical_rmid_to_physical_rmid(int cpu, int lrmid)
+{
+ struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+
+ if (snc_nodes_per_l3_cache == 1)
+ return lrmid;
+
+ return lrmid + (cpu_to_node(cpu) % snc_nodes_per_l3_cache) * r->num_rmid;
+}
+
+static int __rmid_read_phys(u32 prmid, enum resctrl_event_id eventid, u64 *val)
{
u64 msr_val;
@@ -196,7 +237,7 @@ static int __rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *val)
* IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62)
* are error bits.
*/
- wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
+ wrmsr(MSR_IA32_QM_EVTSEL, eventid, prmid);
rdmsrl(MSR_IA32_QM_CTR, msr_val);
if (msr_val & RMID_VAL_ERROR)
@@ -208,7 +249,7 @@ static int __rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *val)
return 0;
}
-static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom,
+static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_mon_domain *hw_dom,
u32 rmid,
enum resctrl_event_id eventid)
{
@@ -227,19 +268,22 @@ static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom,
return NULL;
}
-void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
+void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_mon_domain *d,
u32 unused, u32 rmid,
enum resctrl_event_id eventid)
{
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+ struct rdt_hw_mon_domain *hw_dom = resctrl_to_arch_mon_dom(d);
+ int cpu = cpumask_any(&d->hdr.cpu_mask);
struct arch_mbm_state *am;
+ u32 prmid;
am = get_arch_mbm_state(hw_dom, rmid, eventid);
if (am) {
memset(am, 0, sizeof(*am));
+ prmid = logical_rmid_to_physical_rmid(cpu, rmid);
/* Record any initial, non-zero count value. */
- __rmid_read(rmid, eventid, &am->prev_msr);
+ __rmid_read_phys(prmid, eventid, &am->prev_msr);
}
}
@@ -247,9 +291,9 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
* Assumes that hardware counters are also reset and thus that there is
* no need to record initial non-zero counts.
*/
-void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_domain *d)
+void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_mon_domain *d)
{
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+ struct rdt_hw_mon_domain *hw_dom = resctrl_to_arch_mon_dom(d);
if (is_mbm_total_enabled())
memset(hw_dom->arch_mbm_total, 0,
@@ -268,22 +312,22 @@ static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width)
return chunks >> shift;
}
-int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
+int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_mon_domain *d,
u32 unused, u32 rmid, enum resctrl_event_id eventid,
u64 *val, void *ignored)
{
+ struct rdt_hw_mon_domain *hw_dom = resctrl_to_arch_mon_dom(d);
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
- struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+ int cpu = cpumask_any(&d->hdr.cpu_mask);
struct arch_mbm_state *am;
u64 msr_val, chunks;
+ u32 prmid;
int ret;
resctrl_arch_rmid_read_context_check();
- if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask))
- return -EINVAL;
-
- ret = __rmid_read(rmid, eventid, &msr_val);
+ prmid = logical_rmid_to_physical_rmid(cpu, rmid);
+ ret = __rmid_read_phys(prmid, eventid, &msr_val);
if (ret)
return ret;
@@ -319,7 +363,7 @@ static void limbo_release_entry(struct rmid_entry *entry)
* decrement the count. If the busy count gets to zero on an RMID, we
* free the RMID
*/
-void __check_limbo(struct rdt_domain *d, bool force_free)
+void __check_limbo(struct rdt_mon_domain *d, bool force_free)
{
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
u32 idx_limit = resctrl_arch_system_num_rmid_idx();
@@ -354,6 +398,16 @@ void __check_limbo(struct rdt_domain *d, bool force_free)
rmid_dirty = true;
} else {
rmid_dirty = (val >= resctrl_rmid_realloc_threshold);
+
+ /*
+ * x86's CLOSID and RMID are independent numbers, so the entry's
+ * CLOSID is an empty CLOSID (X86_RESCTRL_EMPTY_CLOSID). On Arm the
+ * RMID (PMG) extends the CLOSID (PARTID) space with bits that aren't
+ * used to select the configuration. It is thus necessary to track both
+ * CLOSID and RMID because there may be dependencies between them
+ * on some architectures.
+ */
+ trace_mon_llc_occupancy_limbo(entry->closid, entry->rmid, d->hdr.id, val);
}
if (force_free || !rmid_dirty) {
@@ -367,7 +421,7 @@ void __check_limbo(struct rdt_domain *d, bool force_free)
resctrl_arch_mon_ctx_free(r, QOS_L3_OCCUP_EVENT_ID, arch_mon_ctx);
}
-bool has_busy_rmid(struct rdt_domain *d)
+bool has_busy_rmid(struct rdt_mon_domain *d)
{
u32 idx_limit = resctrl_arch_system_num_rmid_idx();
@@ -468,7 +522,7 @@ int alloc_rmid(u32 closid)
static void add_rmid_to_limbo(struct rmid_entry *entry)
{
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
- struct rdt_domain *d;
+ struct rdt_mon_domain *d;
u32 idx;
lockdep_assert_held(&rdtgroup_mutex);
@@ -479,7 +533,7 @@ static void add_rmid_to_limbo(struct rmid_entry *entry)
idx = resctrl_arch_rmid_idx_encode(entry->closid, entry->rmid);
entry->busy = 0;
- list_for_each_entry(d, &r->domains, list) {
+ list_for_each_entry(d, &r->mon_domains, hdr.list) {
/*
* For the first limbo RMID in the domain,
* setup up the limbo worker.
@@ -508,7 +562,8 @@ void free_rmid(u32 closid, u32 rmid)
* allows architectures that ignore the closid parameter to avoid an
* unnecessary check.
*/
- if (idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
+ if (!resctrl_arch_mon_capable() ||
+ idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
RESCTRL_RESERVED_RMID))
return;
@@ -520,7 +575,7 @@ void free_rmid(u32 closid, u32 rmid)
list_add_tail(&entry->list, &rmid_free_lru);
}
-static struct mbm_state *get_mbm_state(struct rdt_domain *d, u32 closid,
+static struct mbm_state *get_mbm_state(struct rdt_mon_domain *d, u32 closid,
u32 rmid, enum resctrl_event_id evtid)
{
u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
@@ -537,7 +592,10 @@ static struct mbm_state *get_mbm_state(struct rdt_domain *d, u32 closid,
static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
{
+ int cpu = smp_processor_id();
+ struct rdt_mon_domain *d;
struct mbm_state *m;
+ int err, ret;
u64 tval = 0;
if (rr->first) {
@@ -548,14 +606,47 @@ static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
return 0;
}
- rr->err = resctrl_arch_rmid_read(rr->r, rr->d, closid, rmid, rr->evtid,
- &tval, rr->arch_mon_ctx);
- if (rr->err)
- return rr->err;
+ if (rr->d) {
+ /* Reading a single domain, must be on a CPU in that domain. */
+ if (!cpumask_test_cpu(cpu, &rr->d->hdr.cpu_mask))
+ return -EINVAL;
+ rr->err = resctrl_arch_rmid_read(rr->r, rr->d, closid, rmid,
+ rr->evtid, &tval, rr->arch_mon_ctx);
+ if (rr->err)
+ return rr->err;
- rr->val += tval;
+ rr->val += tval;
- return 0;
+ return 0;
+ }
+
+ /* Summing domains that share a cache, must be on a CPU for that cache. */
+ if (!cpumask_test_cpu(cpu, &rr->ci->shared_cpu_map))
+ return -EINVAL;
+
+ /*
+ * Legacy files must report the sum of an event across all
+ * domains that share the same L3 cache instance.
+ * Report success if a read from any domain succeeds, -EINVAL
+ * (translated to "Unavailable" for user space) if reading from
+ * all domains fail for any reason.
+ */
+ ret = -EINVAL;
+ list_for_each_entry(d, &rr->r->mon_domains, hdr.list) {
+ if (d->ci->id != rr->ci->id)
+ continue;
+ err = resctrl_arch_rmid_read(rr->r, d, closid, rmid,
+ rr->evtid, &tval, rr->arch_mon_ctx);
+ if (!err) {
+ rr->val += tval;
+ ret = 0;
+ }
+ }
+
+ if (ret)
+ rr->err = ret;
+
+ return ret;
}
/*
@@ -656,12 +747,12 @@ void mon_event_count(void *info)
* throttle MSRs already have low percentage values. To avoid
* unnecessarily restricting such rdtgroups, we also increase the bandwidth.
*/
-static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
+static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_mon_domain *dom_mbm)
{
u32 closid, rmid, cur_msr_val, new_msr_val;
struct mbm_state *pmbm_data, *cmbm_data;
+ struct rdt_ctrl_domain *dom_mba;
struct rdt_resource *r_mba;
- struct rdt_domain *dom_mba;
u32 cur_bw, user_bw, idx;
struct list_head *head;
struct rdtgroup *entry;
@@ -676,7 +767,7 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
idx = resctrl_arch_rmid_idx_encode(closid, rmid);
pmbm_data = &dom_mbm->mbm_local[idx];
- dom_mba = get_domain_from_cpu(smp_processor_id(), r_mba);
+ dom_mba = get_ctrl_domain_from_cpu(smp_processor_id(), r_mba);
if (!dom_mba) {
pr_warn_once("Failure to get domain for MBA update\n");
return;
@@ -722,12 +813,11 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
}
-static void mbm_update(struct rdt_resource *r, struct rdt_domain *d,
+static void mbm_update(struct rdt_resource *r, struct rdt_mon_domain *d,
u32 closid, u32 rmid)
{
- struct rmid_read rr;
+ struct rmid_read rr = {0};
- rr.first = false;
rr.r = r;
rr.d = d;
@@ -780,17 +870,17 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d,
void cqm_handle_limbo(struct work_struct *work)
{
unsigned long delay = msecs_to_jiffies(CQM_LIMBOCHECK_INTERVAL);
- struct rdt_domain *d;
+ struct rdt_mon_domain *d;
cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
- d = container_of(work, struct rdt_domain, cqm_limbo.work);
+ d = container_of(work, struct rdt_mon_domain, cqm_limbo.work);
__check_limbo(d, false);
if (has_busy_rmid(d)) {
- d->cqm_work_cpu = cpumask_any_housekeeping(&d->cpu_mask,
+ d->cqm_work_cpu = cpumask_any_housekeeping(&d->hdr.cpu_mask,
RESCTRL_PICK_ANY_CPU);
schedule_delayed_work_on(d->cqm_work_cpu, &d->cqm_limbo,
delay);
@@ -808,13 +898,13 @@ void cqm_handle_limbo(struct work_struct *work)
* @exclude_cpu: Which CPU the handler should not run on,
* RESCTRL_PICK_ANY_CPU to pick any CPU.
*/
-void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms,
+void cqm_setup_limbo_handler(struct rdt_mon_domain *dom, unsigned long delay_ms,
int exclude_cpu)
{
unsigned long delay = msecs_to_jiffies(delay_ms);
int cpu;
- cpu = cpumask_any_housekeeping(&dom->cpu_mask, exclude_cpu);
+ cpu = cpumask_any_housekeeping(&dom->hdr.cpu_mask, exclude_cpu);
dom->cqm_work_cpu = cpu;
if (cpu < nr_cpu_ids)
@@ -825,9 +915,9 @@ void mbm_handle_overflow(struct work_struct *work)
{
unsigned long delay = msecs_to_jiffies(MBM_OVERFLOW_INTERVAL);
struct rdtgroup *prgrp, *crgrp;
+ struct rdt_mon_domain *d;
struct list_head *head;
struct rdt_resource *r;
- struct rdt_domain *d;
cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
@@ -840,7 +930,7 @@ void mbm_handle_overflow(struct work_struct *work)
goto out_unlock;
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
- d = container_of(work, struct rdt_domain, mbm_over.work);
+ d = container_of(work, struct rdt_mon_domain, mbm_over.work);
list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
mbm_update(r, d, prgrp->closid, prgrp->mon.rmid);
@@ -857,7 +947,7 @@ void mbm_handle_overflow(struct work_struct *work)
* Re-check for housekeeping CPUs. This allows the overflow handler to
* move off a nohz_full CPU quickly.
*/
- d->mbm_work_cpu = cpumask_any_housekeeping(&d->cpu_mask,
+ d->mbm_work_cpu = cpumask_any_housekeeping(&d->hdr.cpu_mask,
RESCTRL_PICK_ANY_CPU);
schedule_delayed_work_on(d->mbm_work_cpu, &d->mbm_over, delay);
@@ -874,7 +964,7 @@ out_unlock:
* @exclude_cpu: Which CPU the handler should not run on,
* RESCTRL_PICK_ANY_CPU to pick any CPU.
*/
-void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms,
+void mbm_setup_overflow_handler(struct rdt_mon_domain *dom, unsigned long delay_ms,
int exclude_cpu)
{
unsigned long delay = msecs_to_jiffies(delay_ms);
@@ -886,7 +976,7 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms,
*/
if (!resctrl_mounted || !resctrl_arch_mon_capable())
return;
- cpu = cpumask_any_housekeeping(&dom->cpu_mask, exclude_cpu);
+ cpu = cpumask_any_housekeeping(&dom->hdr.cpu_mask, exclude_cpu);
dom->mbm_work_cpu = cpu;
if (cpu < nr_cpu_ids)
@@ -1003,6 +1093,88 @@ static void l3_mon_evt_init(struct rdt_resource *r)
list_add_tail(&mbm_local_event.list, &r->evt_list);
}
+/*
+ * The power-on reset value of MSR_RMID_SNC_CONFIG is 0x1
+ * which indicates that RMIDs are configured in legacy mode.
+ * This mode is incompatible with Linux resctrl semantics
+ * as RMIDs are partitioned between SNC nodes, which requires
+ * a user to know which RMID is allocated to a task.
+ * Clearing bit 0 reconfigures the RMID counters for use
+ * in RMID sharing mode. This mode is better for Linux.
+ * The RMID space is divided between all SNC nodes with the
+ * RMIDs renumbered to start from zero in each node when
+ * counting operations from tasks. Code to read the counters
+ * must adjust RMID counter numbers based on SNC node. See
+ * logical_rmid_to_physical_rmid() for code that does this.
+ */
+void arch_mon_domain_online(struct rdt_resource *r, struct rdt_mon_domain *d)
+{
+ if (snc_nodes_per_l3_cache > 1)
+ msr_clear_bit(MSR_RMID_SNC_CONFIG, 0);
+}
+
+/* CPU models that support MSR_RMID_SNC_CONFIG */
+static const struct x86_cpu_id snc_cpu_ids[] __initconst = {
+ X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),
+ X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, 0),
+ X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, 0),
+ X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, 0),
+ {}
+};
+
+/*
+ * There isn't a simple hardware bit that indicates whether a CPU is running
+ * in Sub-NUMA Cluster (SNC) mode. Infer the state by comparing the
+ * number of CPUs sharing the L3 cache with CPU0 to the number of CPUs in
+ * the same NUMA node as CPU0.
+ * It is not possible to accurately determine SNC state if the system is
+ * booted with a maxcpus=N parameter. That distorts the ratio of SNC nodes
+ * to L3 caches. It will be OK if system is booted with hyperthreading
+ * disabled (since this doesn't affect the ratio).
+ */
+static __init int snc_get_config(void)
+{
+ struct cacheinfo *ci = get_cpu_cacheinfo_level(0, RESCTRL_L3_CACHE);
+ const cpumask_t *node0_cpumask;
+ int cpus_per_node, cpus_per_l3;
+ int ret;
+
+ if (!x86_match_cpu(snc_cpu_ids) || !ci)
+ return 1;
+
+ cpus_read_lock();
+ if (num_online_cpus() != num_present_cpus())
+ pr_warn("Some CPUs offline, SNC detection may be incorrect\n");
+ cpus_read_unlock();
+
+ node0_cpumask = cpumask_of_node(cpu_to_node(0));
+
+ cpus_per_node = cpumask_weight(node0_cpumask);
+ cpus_per_l3 = cpumask_weight(&ci->shared_cpu_map);
+
+ if (!cpus_per_node || !cpus_per_l3)
+ return 1;
+
+ ret = cpus_per_l3 / cpus_per_node;
+
+ /* sanity check: Only valid results are 1, 2, 3, 4 */
+ switch (ret) {
+ case 1:
+ break;
+ case 2 ... 4:
+ pr_info("Sub-NUMA Cluster mode detected with %d nodes per L3 cache\n", ret);
+ rdt_resources_all[RDT_RESOURCE_L3].r_resctrl.mon_scope = RESCTRL_L3_NODE;
+ break;
+ default:
+ pr_warn("Ignore improbable SNC node count %d\n", ret);
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
int __init rdt_get_mon_l3_config(struct rdt_resource *r)
{
unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset;
@@ -1010,9 +1182,11 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
unsigned int threshold;
int ret;
+ snc_nodes_per_l3_cache = snc_get_config();
+
resctrl_rmid_realloc_limit = boot_cpu_data.x86_cache_size * 1024;
- hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale;
- r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1;
+ hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale / snc_nodes_per_l3_cache;
+ r->num_rmid = (boot_cpu_data.x86_cache_max_rmid + 1) / snc_nodes_per_l3_cache;
hw_res->mbm_width = MBM_CNTR_WIDTH_BASE;
if (mbm_offset > 0 && mbm_offset <= MBM_CNTR_WIDTH_OFFSET_MAX)
diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
index 884b88e25141..e69489d48625 100644
--- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
@@ -11,7 +11,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/cacheinfo.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/debugfs.h>
@@ -23,7 +22,7 @@
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/resctrl.h>
#include <asm/perf_event.h>
@@ -31,7 +30,7 @@
#include "internal.h"
#define CREATE_TRACE_POINTS
-#include "pseudo_lock_event.h"
+#include "trace.h"
/*
* The bits needed to disable hardware prefetching varies based on the
@@ -88,8 +87,8 @@ static u64 get_prefetch_disable_bits(void)
boot_cpu_data.x86 != 6)
return 0;
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_BROADWELL_X:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_BROADWELL_X:
/*
* SDM defines bits of MSR_MISC_FEATURE_CONTROL register
* as:
@@ -100,8 +99,8 @@ static u64 get_prefetch_disable_bits(void)
* 63:4 Reserved
*/
return 0xF;
- case INTEL_FAM6_ATOM_GOLDMONT:
- case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
+ case INTEL_ATOM_GOLDMONT:
+ case INTEL_ATOM_GOLDMONT_PLUS:
/*
* SDM defines bits of MSR_MISC_FEATURE_CONTROL register
* as:
@@ -221,7 +220,7 @@ static int pseudo_lock_cstates_constrain(struct pseudo_lock_region *plr)
int cpu;
int ret;
- for_each_cpu(cpu, &plr->d->cpu_mask) {
+ for_each_cpu(cpu, &plr->d->hdr.cpu_mask) {
pm_req = kzalloc(sizeof(*pm_req), GFP_KERNEL);
if (!pm_req) {
rdt_last_cmd_puts("Failure to allocate memory for PM QoS\n");
@@ -292,12 +291,15 @@ static void pseudo_lock_region_clear(struct pseudo_lock_region *plr)
*/
static int pseudo_lock_region_init(struct pseudo_lock_region *plr)
{
- struct cpu_cacheinfo *ci;
+ enum resctrl_scope scope = plr->s->res->ctrl_scope;
+ struct cacheinfo *ci;
int ret;
- int i;
+
+ if (WARN_ON_ONCE(scope != RESCTRL_L2_CACHE && scope != RESCTRL_L3_CACHE))
+ return -ENODEV;
/* Pick the first cpu we find that is associated with the cache. */
- plr->cpu = cpumask_first(&plr->d->cpu_mask);
+ plr->cpu = cpumask_first(&plr->d->hdr.cpu_mask);
if (!cpu_online(plr->cpu)) {
rdt_last_cmd_printf("CPU %u associated with cache not online\n",
@@ -306,15 +308,11 @@ static int pseudo_lock_region_init(struct pseudo_lock_region *plr)
goto out_region;
}
- ci = get_cpu_cacheinfo(plr->cpu);
-
- plr->size = rdtgroup_cbm_to_size(plr->s->res, plr->d, plr->cbm);
-
- for (i = 0; i < ci->num_leaves; i++) {
- if (ci->info_list[i].level == plr->s->res->cache_level) {
- plr->line_size = ci->info_list[i].coherency_line_size;
- return 0;
- }
+ ci = get_cpu_cacheinfo_level(plr->cpu, scope);
+ if (ci) {
+ plr->line_size = ci->coherency_line_size;
+ plr->size = rdtgroup_cbm_to_size(plr->s->res, plr->d, plr->cbm);
+ return 0;
}
ret = -1;
@@ -810,7 +808,7 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp)
* Return: true if @cbm overlaps with pseudo-locked region on @d, false
* otherwise.
*/
-bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm)
+bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned long cbm)
{
unsigned int cbm_len;
unsigned long cbm_b;
@@ -837,11 +835,11 @@ bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm
* if it is not possible to test due to memory allocation issue,
* false otherwise.
*/
-bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
+bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain *d)
{
+ struct rdt_ctrl_domain *d_i;
cpumask_var_t cpu_with_psl;
struct rdt_resource *r;
- struct rdt_domain *d_i;
bool ret = false;
/* Walking r->domains, ensure it can't race with cpuhp */
@@ -855,10 +853,10 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
* associated with them.
*/
for_each_alloc_capable_rdt_resource(r) {
- list_for_each_entry(d_i, &r->domains, list) {
+ list_for_each_entry(d_i, &r->ctrl_domains, hdr.list) {
if (d_i->plr)
cpumask_or(cpu_with_psl, cpu_with_psl,
- &d_i->cpu_mask);
+ &d_i->hdr.cpu_mask);
}
}
@@ -866,7 +864,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
* Next test if new pseudo-locked region would intersect with
* existing region.
*/
- if (cpumask_intersects(&d->cpu_mask, cpu_with_psl))
+ if (cpumask_intersects(&d->hdr.cpu_mask, cpu_with_psl))
ret = true;
free_cpumask_var(cpu_with_psl);
@@ -1084,9 +1082,9 @@ static int measure_l2_residency(void *_plr)
* L2_HIT 02H
* L2_MISS 10H
*/
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_ATOM_GOLDMONT:
- case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_ATOM_GOLDMONT:
+ case INTEL_ATOM_GOLDMONT_PLUS:
perf_miss_attr.config = X86_CONFIG(.event = 0xd1,
.umask = 0x10);
perf_hit_attr.config = X86_CONFIG(.event = 0xd1,
@@ -1123,8 +1121,8 @@ static int measure_l3_residency(void *_plr)
* MISS 41H
*/
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_BROADWELL_X:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_BROADWELL_X:
/* On BDW the hit event counts references, not hits */
perf_hit_attr.config = X86_CONFIG(.event = 0x2e,
.umask = 0x4f);
@@ -1142,7 +1140,7 @@ static int measure_l3_residency(void *_plr)
*/
counts.miss_after -= counts.miss_before;
- if (boot_cpu_data.x86_model == INTEL_FAM6_BROADWELL_X) {
+ if (boot_cpu_data.x86_vfm == INTEL_BROADWELL_X) {
/*
* On BDW references and misses are counted, need to adjust.
* Sometimes the "hits" counter is a bit more than the
@@ -1198,7 +1196,7 @@ static int pseudo_lock_measure_cycles(struct rdtgroup *rdtgrp, int sel)
}
plr->thread_done = 0;
- cpu = cpumask_first(&plr->d->cpu_mask);
+ cpu = cpumask_first(&plr->d->hdr.cpu_mask);
if (!cpu_online(cpu)) {
ret = -ENODEV;
goto out;
@@ -1528,7 +1526,7 @@ static int pseudo_lock_dev_mmap(struct file *filp, struct vm_area_struct *vma)
* may be scheduled elsewhere and invalidate entries in the
* pseudo-locked region.
*/
- if (!cpumask_subset(current->cpus_ptr, &plr->d->cpu_mask)) {
+ if (!cpumask_subset(current->cpus_ptr, &plr->d->hdr.cpu_mask)) {
mutex_unlock(&rdtgroup_mutex);
return -EINVAL;
}
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 011e17efb1a6..d7163b764c62 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -12,7 +12,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/cacheinfo.h>
#include <linux/cpu.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
@@ -92,13 +91,13 @@ void rdt_last_cmd_printf(const char *fmt, ...)
void rdt_staged_configs_clear(void)
{
+ struct rdt_ctrl_domain *dom;
struct rdt_resource *r;
- struct rdt_domain *dom;
lockdep_assert_held(&rdtgroup_mutex);
for_each_alloc_capable_rdt_resource(r) {
- list_for_each_entry(dom, &r->domains, list)
+ list_for_each_entry(dom, &r->ctrl_domains, hdr.list)
memset(dom->staged_config, 0, sizeof(dom->staged_config));
}
}
@@ -317,7 +316,7 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of,
rdt_last_cmd_puts("Cache domain offline\n");
ret = -ENODEV;
} else {
- mask = &rdtgrp->plr->d->cpu_mask;
+ mask = &rdtgrp->plr->d->hdr.cpu_mask;
seq_printf(s, is_cpu_list(of) ?
"%*pbl\n" : "%*pb\n",
cpumask_pr_args(mask));
@@ -1012,7 +1011,7 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
unsigned long sw_shareable = 0, hw_shareable = 0;
unsigned long exclusive = 0, pseudo_locked = 0;
struct rdt_resource *r = s->res;
- struct rdt_domain *dom;
+ struct rdt_ctrl_domain *dom;
int i, hwb, swb, excl, psl;
enum rdtgrp_mode mode;
bool sep = false;
@@ -1021,12 +1020,12 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
hw_shareable = r->cache.shareable_bits;
- list_for_each_entry(dom, &r->domains, list) {
+ list_for_each_entry(dom, &r->ctrl_domains, hdr.list) {
if (sep)
seq_putc(seq, ';');
sw_shareable = 0;
exclusive = 0;
- seq_printf(seq, "%d=", dom->id);
+ seq_printf(seq, "%d=", dom->hdr.id);
for (i = 0; i < closids_supported(); i++) {
if (!closid_allocated(i))
continue;
@@ -1243,7 +1242,7 @@ static int rdt_has_sparse_bitmasks_show(struct kernfs_open_file *of,
*
* Return: false if CBM does not overlap, true if it does.
*/
-static bool __rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_domain *d,
+static bool __rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_ctrl_domain *d,
unsigned long cbm, int closid,
enum resctrl_conf_type type, bool exclusive)
{
@@ -1298,7 +1297,7 @@ static bool __rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_domain *d
*
* Return: true if CBM overlap detected, false if there is no overlap
*/
-bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_domain *d,
+bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_ctrl_domain *d,
unsigned long cbm, int closid, bool exclusive)
{
enum resctrl_conf_type peer_type = resctrl_peer_type(s->conf_type);
@@ -1329,10 +1328,10 @@ bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_domain *d,
static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
{
int closid = rdtgrp->closid;
+ struct rdt_ctrl_domain *d;
struct resctrl_schema *s;
struct rdt_resource *r;
bool has_cache = false;
- struct rdt_domain *d;
u32 ctrl;
/* Walking r->domains, ensure it can't race with cpuhp */
@@ -1343,7 +1342,7 @@ static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
if (r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)
continue;
has_cache = true;
- list_for_each_entry(d, &r->domains, list) {
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
ctrl = resctrl_arch_get_config(r, d, closid,
s->conf_type);
if (rdtgroup_cbm_overlaps(s, d, ctrl, closid, false)) {
@@ -1448,20 +1447,19 @@ out:
* bitmap functions work correctly.
*/
unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r,
- struct rdt_domain *d, unsigned long cbm)
+ struct rdt_ctrl_domain *d, unsigned long cbm)
{
- struct cpu_cacheinfo *ci;
unsigned int size = 0;
- int num_b, i;
+ struct cacheinfo *ci;
+ int num_b;
+
+ if (WARN_ON_ONCE(r->ctrl_scope != RESCTRL_L2_CACHE && r->ctrl_scope != RESCTRL_L3_CACHE))
+ return size;
num_b = bitmap_weight(&cbm, r->cache.cbm_len);
- ci = get_cpu_cacheinfo(cpumask_any(&d->cpu_mask));
- for (i = 0; i < ci->num_leaves; i++) {
- if (ci->info_list[i].level == r->cache_level) {
- size = ci->info_list[i].size / r->cache.cbm_len * num_b;
- break;
- }
- }
+ ci = get_cpu_cacheinfo_level(cpumask_any(&d->hdr.cpu_mask), r->ctrl_scope);
+ if (ci)
+ size = ci->size / r->cache.cbm_len * num_b;
return size;
}
@@ -1477,9 +1475,9 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
{
struct resctrl_schema *schema;
enum resctrl_conf_type type;
+ struct rdt_ctrl_domain *d;
struct rdtgroup *rdtgrp;
struct rdt_resource *r;
- struct rdt_domain *d;
unsigned int size;
int ret = 0;
u32 closid;
@@ -1503,7 +1501,7 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
size = rdtgroup_cbm_to_size(rdtgrp->plr->s->res,
rdtgrp->plr->d,
rdtgrp->plr->cbm);
- seq_printf(s, "%d=%u\n", rdtgrp->plr->d->id, size);
+ seq_printf(s, "%d=%u\n", rdtgrp->plr->d->hdr.id, size);
}
goto out;
}
@@ -1515,7 +1513,7 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
type = schema->conf_type;
sep = false;
seq_printf(s, "%*s:", max_name_width, schema->name);
- list_for_each_entry(d, &r->domains, list) {
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
if (sep)
seq_putc(s, ';');
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
@@ -1533,7 +1531,7 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
else
size = rdtgroup_cbm_to_size(r, d, ctrl);
}
- seq_printf(s, "%d=%u", d->id, size);
+ seq_printf(s, "%d=%u", d->hdr.id, size);
sep = true;
}
seq_putc(s, '\n');
@@ -1591,21 +1589,21 @@ static void mon_event_config_read(void *info)
mon_info->mon_config = msrval & MAX_EVT_CONFIG_BITS;
}
-static void mondata_config_read(struct rdt_domain *d, struct mon_config_info *mon_info)
+static void mondata_config_read(struct rdt_mon_domain *d, struct mon_config_info *mon_info)
{
- smp_call_function_any(&d->cpu_mask, mon_event_config_read, mon_info, 1);
+ smp_call_function_any(&d->hdr.cpu_mask, mon_event_config_read, mon_info, 1);
}
static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid)
{
struct mon_config_info mon_info = {0};
- struct rdt_domain *dom;
+ struct rdt_mon_domain *dom;
bool sep = false;
cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
- list_for_each_entry(dom, &r->domains, list) {
+ list_for_each_entry(dom, &r->mon_domains, hdr.list) {
if (sep)
seq_puts(s, ";");
@@ -1613,7 +1611,7 @@ static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid
mon_info.evtid = evtid;
mondata_config_read(dom, &mon_info);
- seq_printf(s, "%d=0x%02x", dom->id, mon_info.mon_config);
+ seq_printf(s, "%d=0x%02x", dom->hdr.id, mon_info.mon_config);
sep = true;
}
seq_puts(s, "\n");
@@ -1658,7 +1656,7 @@ static void mon_event_config_write(void *info)
}
static void mbm_config_write_domain(struct rdt_resource *r,
- struct rdt_domain *d, u32 evtid, u32 val)
+ struct rdt_mon_domain *d, u32 evtid, u32 val)
{
struct mon_config_info mon_info = {0};
@@ -1679,7 +1677,7 @@ static void mbm_config_write_domain(struct rdt_resource *r,
* are scoped at the domain level. Writing any of these MSRs
* on one CPU is observed by all the CPUs in the domain.
*/
- smp_call_function_any(&d->cpu_mask, mon_event_config_write,
+ smp_call_function_any(&d->hdr.cpu_mask, mon_event_config_write,
&mon_info, 1);
/*
@@ -1699,7 +1697,7 @@ static int mon_config_write(struct rdt_resource *r, char *tok, u32 evtid)
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
char *dom_str = NULL, *id_str;
unsigned long dom_id, val;
- struct rdt_domain *d;
+ struct rdt_mon_domain *d;
/* Walking r->domains, ensure it can't race with cpuhp */
lockdep_assert_cpus_held();
@@ -1729,8 +1727,8 @@ next:
return -EINVAL;
}
- list_for_each_entry(d, &r->domains, list) {
- if (d->id == dom_id) {
+ list_for_each_entry(d, &r->mon_domains, hdr.list) {
+ if (d->hdr.id == dom_id) {
mbm_config_write_domain(r, d, evtid, val);
goto next;
}
@@ -2258,9 +2256,9 @@ static inline bool is_mba_linear(void)
static int set_cache_qos_cfg(int level, bool enable)
{
void (*update)(void *arg);
+ struct rdt_ctrl_domain *d;
struct rdt_resource *r_l;
cpumask_var_t cpu_mask;
- struct rdt_domain *d;
int cpu;
/* Walking r->domains, ensure it can't race with cpuhp */
@@ -2277,14 +2275,14 @@ static int set_cache_qos_cfg(int level, bool enable)
return -ENOMEM;
r_l = &rdt_resources_all[level].r_resctrl;
- list_for_each_entry(d, &r_l->domains, list) {
+ list_for_each_entry(d, &r_l->ctrl_domains, hdr.list) {
if (r_l->cache.arch_has_per_cpu_cfg)
/* Pick all the CPUs in the domain instance */
- for_each_cpu(cpu, &d->cpu_mask)
+ for_each_cpu(cpu, &d->hdr.cpu_mask)
cpumask_set_cpu(cpu, cpu_mask);
else
/* Pick one CPU from each domain instance to update MSR */
- cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
+ cpumask_set_cpu(cpumask_any(&d->hdr.cpu_mask), cpu_mask);
}
/* Update QOS_CFG MSR on all the CPUs in cpu_mask */
@@ -2310,10 +2308,10 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r)
l3_qos_cfg_update(&hw_res->cdp_enabled);
}
-static int mba_sc_domain_allocate(struct rdt_resource *r, struct rdt_domain *d)
+static int mba_sc_domain_allocate(struct rdt_resource *r, struct rdt_ctrl_domain *d)
{
u32 num_closid = resctrl_arch_get_num_closid(r);
- int cpu = cpumask_any(&d->cpu_mask);
+ int cpu = cpumask_any(&d->hdr.cpu_mask);
int i;
d->mbps_val = kcalloc_node(num_closid, sizeof(*d->mbps_val),
@@ -2328,7 +2326,7 @@ static int mba_sc_domain_allocate(struct rdt_resource *r, struct rdt_domain *d)
}
static void mba_sc_domain_destroy(struct rdt_resource *r,
- struct rdt_domain *d)
+ struct rdt_ctrl_domain *d)
{
kfree(d->mbps_val);
d->mbps_val = NULL;
@@ -2336,14 +2334,18 @@ static void mba_sc_domain_destroy(struct rdt_resource *r,
/*
* MBA software controller is supported only if
- * MBM is supported and MBA is in linear scale.
+ * MBM is supported and MBA is in linear scale,
+ * and the MBM monitor scope is the same as MBA
+ * control scope.
*/
static bool supports_mba_mbps(void)
{
+ struct rdt_resource *rmbm = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl;
return (is_mbm_local_enabled() &&
- r->alloc_capable && is_mba_linear());
+ r->alloc_capable && is_mba_linear() &&
+ r->ctrl_scope == rmbm->mon_scope);
}
/*
@@ -2354,7 +2356,7 @@ static int set_mba_sc(bool mba_sc)
{
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl;
u32 num_closid = resctrl_arch_get_num_closid(r);
- struct rdt_domain *d;
+ struct rdt_ctrl_domain *d;
int i;
if (!supports_mba_mbps() || mba_sc == is_mba_sc(r))
@@ -2362,7 +2364,7 @@ static int set_mba_sc(bool mba_sc)
r->membw.mba_sc = mba_sc;
- list_for_each_entry(d, &r->domains, list) {
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
for (i = 0; i < num_closid; i++)
d->mbps_val[i] = MBA_MAX_MBPS;
}
@@ -2626,7 +2628,7 @@ static int rdt_get_tree(struct fs_context *fc)
{
struct rdt_fs_context *ctx = rdt_fc2context(fc);
unsigned long flags = RFTYPE_CTRL_BASE;
- struct rdt_domain *dom;
+ struct rdt_mon_domain *dom;
struct rdt_resource *r;
int ret;
@@ -2701,7 +2703,7 @@ static int rdt_get_tree(struct fs_context *fc)
if (is_mbm_enabled()) {
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
- list_for_each_entry(dom, &r->domains, list)
+ list_for_each_entry(dom, &r->mon_domains, hdr.list)
mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL,
RESCTRL_PICK_ANY_CPU);
}
@@ -2751,6 +2753,7 @@ static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
struct rdt_fs_context *ctx = rdt_fc2context(fc);
struct fs_parse_result result;
+ const char *msg;
int opt;
opt = fs_parse(fc, rdt_fs_parameters, param, &result);
@@ -2765,8 +2768,9 @@ static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param)
ctx->enable_cdpl2 = true;
return 0;
case Opt_mba_mbps:
+ msg = "mba_MBps requires local MBM and linear scale MBA at L3 scope";
if (!supports_mba_mbps())
- return -EINVAL;
+ return invalfc(fc, msg);
ctx->enable_mba_mbps = true;
return 0;
case Opt_debug:
@@ -2811,40 +2815,32 @@ static int rdt_init_fs_context(struct fs_context *fc)
static int reset_all_ctrls(struct rdt_resource *r)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
- struct rdt_hw_domain *hw_dom;
+ struct rdt_hw_ctrl_domain *hw_dom;
struct msr_param msr_param;
- cpumask_var_t cpu_mask;
- struct rdt_domain *d;
+ struct rdt_ctrl_domain *d;
int i;
/* Walking r->domains, ensure it can't race with cpuhp */
lockdep_assert_cpus_held();
- if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
- return -ENOMEM;
-
msr_param.res = r;
msr_param.low = 0;
msr_param.high = hw_res->num_closid;
/*
* Disable resource control for this resource by setting all
- * CBMs in all domains to the maximum mask value. Pick one CPU
+ * CBMs in all ctrl_domains to the maximum mask value. Pick one CPU
* from each domain to update the MSRs below.
*/
- list_for_each_entry(d, &r->domains, list) {
- hw_dom = resctrl_to_arch_dom(d);
- cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
+ hw_dom = resctrl_to_arch_ctrl_dom(d);
for (i = 0; i < hw_res->num_closid; i++)
hw_dom->ctrl_val[i] = r->default_ctrl;
+ msr_param.dom = d;
+ smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &msr_param, 1);
}
- /* Update CBM on all the CPUs in cpu_mask */
- on_each_cpu_mask(cpu_mask, rdt_ctrl_update, &msr_param, 1);
-
- free_cpumask_var(cpu_mask);
-
return 0;
}
@@ -3010,62 +3006,126 @@ static int mon_addfile(struct kernfs_node *parent_kn, const char *name,
return ret;
}
+static void mon_rmdir_one_subdir(struct kernfs_node *pkn, char *name, char *subname)
+{
+ struct kernfs_node *kn;
+
+ kn = kernfs_find_and_get(pkn, name);
+ if (!kn)
+ return;
+ kernfs_put(kn);
+
+ if (kn->dir.subdirs <= 1)
+ kernfs_remove(kn);
+ else
+ kernfs_remove_by_name(kn, subname);
+}
+
/*
* Remove all subdirectories of mon_data of ctrl_mon groups
- * and monitor groups with given domain id.
+ * and monitor groups for the given domain.
+ * Remove files and directories containing "sum" of domain data
+ * when last domain being summed is removed.
*/
static void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
- unsigned int dom_id)
+ struct rdt_mon_domain *d)
{
struct rdtgroup *prgrp, *crgrp;
+ char subname[32];
+ bool snc_mode;
char name[32];
+ snc_mode = r->mon_scope == RESCTRL_L3_NODE;
+ sprintf(name, "mon_%s_%02d", r->name, snc_mode ? d->ci->id : d->hdr.id);
+ if (snc_mode)
+ sprintf(subname, "mon_sub_%s_%02d", r->name, d->hdr.id);
+
list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
- sprintf(name, "mon_%s_%02d", r->name, dom_id);
- kernfs_remove_by_name(prgrp->mon.mon_data_kn, name);
+ mon_rmdir_one_subdir(prgrp->mon.mon_data_kn, name, subname);
list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list)
- kernfs_remove_by_name(crgrp->mon.mon_data_kn, name);
+ mon_rmdir_one_subdir(crgrp->mon.mon_data_kn, name, subname);
}
}
-static int mkdir_mondata_subdir(struct kernfs_node *parent_kn,
- struct rdt_domain *d,
- struct rdt_resource *r, struct rdtgroup *prgrp)
+static int mon_add_all_files(struct kernfs_node *kn, struct rdt_mon_domain *d,
+ struct rdt_resource *r, struct rdtgroup *prgrp,
+ bool do_sum)
{
+ struct rmid_read rr = {0};
union mon_data_bits priv;
- struct kernfs_node *kn;
struct mon_evt *mevt;
- struct rmid_read rr;
- char name[32];
int ret;
- sprintf(name, "mon_%s_%02d", r->name, d->id);
- /* create the directory */
- kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp);
- if (IS_ERR(kn))
- return PTR_ERR(kn);
-
- ret = rdtgroup_kn_set_ugid(kn);
- if (ret)
- goto out_destroy;
-
- if (WARN_ON(list_empty(&r->evt_list))) {
- ret = -EPERM;
- goto out_destroy;
- }
+ if (WARN_ON(list_empty(&r->evt_list)))
+ return -EPERM;
priv.u.rid = r->rid;
- priv.u.domid = d->id;
+ priv.u.domid = do_sum ? d->ci->id : d->hdr.id;
+ priv.u.sum = do_sum;
list_for_each_entry(mevt, &r->evt_list, list) {
priv.u.evtid = mevt->evtid;
ret = mon_addfile(kn, mevt->name, priv.priv);
if (ret)
+ return ret;
+
+ if (!do_sum && is_mbm_event(mevt->evtid))
+ mon_event_read(&rr, r, d, prgrp, &d->hdr.cpu_mask, mevt->evtid, true);
+ }
+
+ return 0;
+}
+
+static int mkdir_mondata_subdir(struct kernfs_node *parent_kn,
+ struct rdt_mon_domain *d,
+ struct rdt_resource *r, struct rdtgroup *prgrp)
+{
+ struct kernfs_node *kn, *ckn;
+ char name[32];
+ bool snc_mode;
+ int ret = 0;
+
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ snc_mode = r->mon_scope == RESCTRL_L3_NODE;
+ sprintf(name, "mon_%s_%02d", r->name, snc_mode ? d->ci->id : d->hdr.id);
+ kn = kernfs_find_and_get(parent_kn, name);
+ if (kn) {
+ /*
+ * rdtgroup_mutex will prevent this directory from being
+ * removed. No need to keep this hold.
+ */
+ kernfs_put(kn);
+ } else {
+ kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp);
+ if (IS_ERR(kn))
+ return PTR_ERR(kn);
+
+ ret = rdtgroup_kn_set_ugid(kn);
+ if (ret)
goto out_destroy;
+ ret = mon_add_all_files(kn, d, r, prgrp, snc_mode);
+ if (ret)
+ goto out_destroy;
+ }
- if (is_mbm_event(mevt->evtid))
- mon_event_read(&rr, r, d, prgrp, mevt->evtid, true);
+ if (snc_mode) {
+ sprintf(name, "mon_sub_%s_%02d", r->name, d->hdr.id);
+ ckn = kernfs_create_dir(kn, name, parent_kn->mode, prgrp);
+ if (IS_ERR(ckn)) {
+ ret = -EINVAL;
+ goto out_destroy;
+ }
+
+ ret = rdtgroup_kn_set_ugid(ckn);
+ if (ret)
+ goto out_destroy;
+
+ ret = mon_add_all_files(ckn, d, r, prgrp, false);
+ if (ret)
+ goto out_destroy;
}
+
kernfs_activate(kn);
return 0;
@@ -3079,7 +3139,7 @@ out_destroy:
* and "monitor" groups with given domain id.
*/
static void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
- struct rdt_domain *d)
+ struct rdt_mon_domain *d)
{
struct kernfs_node *parent_kn;
struct rdtgroup *prgrp, *crgrp;
@@ -3101,13 +3161,13 @@ static int mkdir_mondata_subdir_alldom(struct kernfs_node *parent_kn,
struct rdt_resource *r,
struct rdtgroup *prgrp)
{
- struct rdt_domain *dom;
+ struct rdt_mon_domain *dom;
int ret;
/* Walking r->domains, ensure it can't race with cpuhp */
lockdep_assert_cpus_held();
- list_for_each_entry(dom, &r->domains, list) {
+ list_for_each_entry(dom, &r->mon_domains, hdr.list) {
ret = mkdir_mondata_subdir(parent_kn, dom, r, prgrp);
if (ret)
return ret;
@@ -3206,7 +3266,7 @@ static u32 cbm_ensure_valid(u32 _val, struct rdt_resource *r)
* Set the RDT domain up to start off with all usable allocations. That is,
* all shareable and unused bits. All-zero CBM is invalid.
*/
-static int __init_one_rdt_domain(struct rdt_domain *d, struct resctrl_schema *s,
+static int __init_one_rdt_domain(struct rdt_ctrl_domain *d, struct resctrl_schema *s,
u32 closid)
{
enum resctrl_conf_type peer_type = resctrl_peer_type(s->conf_type);
@@ -3266,7 +3326,7 @@ static int __init_one_rdt_domain(struct rdt_domain *d, struct resctrl_schema *s,
*/
tmp_cbm = cfg->new_ctrl;
if (bitmap_weight(&tmp_cbm, r->cache.cbm_len) < r->cache.min_cbm_bits) {
- rdt_last_cmd_printf("No space on %s:%d\n", s->name, d->id);
+ rdt_last_cmd_printf("No space on %s:%d\n", s->name, d->hdr.id);
return -ENOSPC;
}
cfg->have_new_ctrl = true;
@@ -3286,10 +3346,10 @@ static int __init_one_rdt_domain(struct rdt_domain *d, struct resctrl_schema *s,
*/
static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid)
{
- struct rdt_domain *d;
+ struct rdt_ctrl_domain *d;
int ret;
- list_for_each_entry(d, &s->res->domains, list) {
+ list_for_each_entry(d, &s->res->ctrl_domains, hdr.list) {
ret = __init_one_rdt_domain(d, s, closid);
if (ret < 0)
return ret;
@@ -3302,9 +3362,9 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid)
static void rdtgroup_init_mba(struct rdt_resource *r, u32 closid)
{
struct resctrl_staged_config *cfg;
- struct rdt_domain *d;
+ struct rdt_ctrl_domain *d;
- list_for_each_entry(d, &r->domains, list) {
+ list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
if (is_mba_sc(r)) {
d->mbps_val[closid] = MBA_MAX_MBPS;
continue;
@@ -3928,29 +3988,33 @@ static void __init rdtgroup_setup_default(void)
mutex_unlock(&rdtgroup_mutex);
}
-static void domain_destroy_mon_state(struct rdt_domain *d)
+static void domain_destroy_mon_state(struct rdt_mon_domain *d)
{
bitmap_free(d->rmid_busy_llc);
kfree(d->mbm_total);
kfree(d->mbm_local);
}
-void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d)
+void resctrl_offline_ctrl_domain(struct rdt_resource *r, struct rdt_ctrl_domain *d)
{
mutex_lock(&rdtgroup_mutex);
if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA)
mba_sc_domain_destroy(r, d);
- if (!r->mon_capable)
- goto out_unlock;
+ mutex_unlock(&rdtgroup_mutex);
+}
+
+void resctrl_offline_mon_domain(struct rdt_resource *r, struct rdt_mon_domain *d)
+{
+ mutex_lock(&rdtgroup_mutex);
/*
* If resctrl is mounted, remove all the
* per domain monitor data directories.
*/
if (resctrl_mounted && resctrl_arch_mon_capable())
- rmdir_mondata_subdir_allrdtgrp(r, d->id);
+ rmdir_mondata_subdir_allrdtgrp(r, d);
if (is_mbm_enabled())
cancel_delayed_work(&d->mbm_over);
@@ -3969,11 +4033,10 @@ void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d)
domain_destroy_mon_state(d);
-out_unlock:
mutex_unlock(&rdtgroup_mutex);
}
-static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d)
+static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_mon_domain *d)
{
u32 idx_limit = resctrl_arch_system_num_rmid_idx();
size_t tsize;
@@ -4004,7 +4067,7 @@ static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d)
return 0;
}
-int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d)
+int resctrl_online_ctrl_domain(struct rdt_resource *r, struct rdt_ctrl_domain *d)
{
int err = 0;
@@ -4013,11 +4076,18 @@ int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d)
if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA) {
/* RDT_RESOURCE_MBA is never mon_capable */
err = mba_sc_domain_allocate(r, d);
- goto out_unlock;
}
- if (!r->mon_capable)
- goto out_unlock;
+ mutex_unlock(&rdtgroup_mutex);
+
+ return err;
+}
+
+int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_mon_domain *d)
+{
+ int err;
+
+ mutex_lock(&rdtgroup_mutex);
err = domain_setup_mon_state(r, d);
if (err)
@@ -4068,8 +4138,8 @@ static void clear_childcpus(struct rdtgroup *r, unsigned int cpu)
void resctrl_offline_cpu(unsigned int cpu)
{
struct rdt_resource *l3 = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+ struct rdt_mon_domain *d;
struct rdtgroup *rdtgrp;
- struct rdt_domain *d;
mutex_lock(&rdtgroup_mutex);
list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) {
@@ -4082,7 +4152,7 @@ void resctrl_offline_cpu(unsigned int cpu)
if (!l3->mon_capable)
goto out_unlock;
- d = get_domain_from_cpu(cpu, l3);
+ d = get_mon_domain_from_cpu(cpu, l3);
if (d) {
if (is_mbm_enabled() && cpu == d->mbm_work_cpu) {
cancel_delayed_work(&d->mbm_over);
diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock_event.h b/arch/x86/kernel/cpu/resctrl/trace.h
index 428ebbd4270b..2a506316b303 100644
--- a/arch/x86/kernel/cpu/resctrl/pseudo_lock_event.h
+++ b/arch/x86/kernel/cpu/resctrl/trace.h
@@ -2,8 +2,8 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM resctrl
-#if !defined(_TRACE_PSEUDO_LOCK_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_PSEUDO_LOCK_H
+#if !defined(_TRACE_RESCTRL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RESCTRL_H
#include <linux/tracepoint.h>
@@ -35,9 +35,25 @@ TRACE_EVENT(pseudo_lock_l3,
TP_printk("hits=%llu miss=%llu",
__entry->l3_hits, __entry->l3_miss));
-#endif /* _TRACE_PSEUDO_LOCK_H */
+TRACE_EVENT(mon_llc_occupancy_limbo,
+ TP_PROTO(u32 ctrl_hw_id, u32 mon_hw_id, int domain_id, u64 llc_occupancy_bytes),
+ TP_ARGS(ctrl_hw_id, mon_hw_id, domain_id, llc_occupancy_bytes),
+ TP_STRUCT__entry(__field(u32, ctrl_hw_id)
+ __field(u32, mon_hw_id)
+ __field(int, domain_id)
+ __field(u64, llc_occupancy_bytes)),
+ TP_fast_assign(__entry->ctrl_hw_id = ctrl_hw_id;
+ __entry->mon_hw_id = mon_hw_id;
+ __entry->domain_id = domain_id;
+ __entry->llc_occupancy_bytes = llc_occupancy_bytes;),
+ TP_printk("ctrl_hw_id=%u mon_hw_id=%u domain_id=%d llc_occupancy_bytes=%llu",
+ __entry->ctrl_hw_id, __entry->mon_hw_id, __entry->domain_id,
+ __entry->llc_occupancy_bytes)
+ );
+
+#endif /* _TRACE_RESCTRL_H */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE pseudo_lock_event
+#define TRACE_INCLUDE_FILE trace
#include <trace/define_trace.h>
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index af5aa2c754c2..c84c30188fdf 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -45,6 +45,7 @@ static const struct cpuid_bit cpuid_bits[] = {
{ 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_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 },
{ X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
{ X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 },
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c
index 262f5fb18d74..22b65a5f5ec6 100644
--- a/arch/x86/kernel/cpu/sgx/driver.c
+++ b/arch/x86/kernel/cpu/sgx/driver.c
@@ -113,7 +113,7 @@ static unsigned long sgx_get_unmapped_area(struct file *file,
if (flags & MAP_FIXED)
return addr;
- return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
+ return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags);
}
#ifdef CONFIG_COMPAT
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index 166692f2d501..27892e57c4ef 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -13,6 +13,7 @@
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
+#include <linux/vmalloc.h>
#include <asm/sgx.h>
#include "driver.h"
#include "encl.h"
diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
index d17c9b71eb4a..621a151ccf7d 100644
--- a/arch/x86/kernel/cpu/topology.c
+++ b/arch/x86/kernel/cpu/topology.c
@@ -128,6 +128,9 @@ static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id)
static __init bool check_for_real_bsp(u32 apic_id)
{
+ bool is_bsp = false, has_apic_base = boot_cpu_data.x86 >= 6;
+ u64 msr;
+
/*
* There is no real good way to detect whether this a kdump()
* kernel, but except on the Voyager SMP monstrosity which is not
@@ -144,17 +147,61 @@ static __init bool check_for_real_bsp(u32 apic_id)
if (topo_info.real_bsp_apic_id != BAD_APICID)
return false;
+ /*
+ * Check whether the enumeration order is broken by evaluating the
+ * BSP bit in the APICBASE MSR. If the CPU does not have the
+ * APICBASE MSR then the BSP detection is not possible and the
+ * kernel must rely on the firmware enumeration order.
+ */
+ if (has_apic_base) {
+ rdmsrl(MSR_IA32_APICBASE, msr);
+ is_bsp = !!(msr & MSR_IA32_APICBASE_BSP);
+ }
+
if (apic_id == topo_info.boot_cpu_apic_id) {
- topo_info.real_bsp_apic_id = apic_id;
- return false;
+ /*
+ * If the boot CPU has the APIC BSP bit set then the
+ * firmware enumeration is agreeing. If the CPU does not
+ * have the APICBASE MSR then the only choice is to trust
+ * the enumeration order.
+ */
+ if (is_bsp || !has_apic_base) {
+ topo_info.real_bsp_apic_id = apic_id;
+ return false;
+ }
+ /*
+ * If the boot APIC is enumerated first, but the APICBASE
+ * MSR does not have the BSP bit set, then there is no way
+ * to discover the real BSP here. Assume a crash kernel and
+ * limit the number of CPUs to 1 as an INIT to the real BSP
+ * would reset the machine.
+ */
+ pr_warn("Enumerated BSP APIC %x is not marked in APICBASE MSR\n", apic_id);
+ pr_warn("Assuming crash kernel. Limiting to one CPU to prevent machine INIT\n");
+ set_nr_cpu_ids(1);
+ goto fwbug;
}
- pr_warn("Boot CPU APIC ID not the first enumerated APIC ID: %x > %x\n",
+ pr_warn("Boot CPU APIC ID not the first enumerated APIC ID: %x != %x\n",
topo_info.boot_cpu_apic_id, apic_id);
+
+ if (is_bsp) {
+ /*
+ * The boot CPU has the APIC BSP bit set. Use it and complain
+ * about the broken firmware enumeration.
+ */
+ topo_info.real_bsp_apic_id = topo_info.boot_cpu_apic_id;
+ goto fwbug;
+ }
+
pr_warn("Crash kernel detected. Disabling real BSP to prevent machine INIT\n");
topo_info.real_bsp_apic_id = apic_id;
return true;
+
+fwbug:
+ pr_warn(FW_BUG "APIC enumeration order not specification compliant\n");
+ return false;
}
static unsigned int topo_unit_count(u32 lvlid, enum x86_topology_domains at_level,
diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c
index a7aa6eff4ae5..7d476fa697ca 100644
--- a/arch/x86/kernel/cpu/topology_amd.c
+++ b/arch/x86/kernel/cpu/topology_amd.c
@@ -58,7 +58,7 @@ static void store_node(struct topo_scan *tscan, u16 nr_nodes, u16 node_id)
tscan->amd_node_id = node_id;
}
-static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
+static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
{
struct {
// eax
@@ -84,9 +84,9 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
/*
* If leaf 0xb is available, then the domain shifts are set
- * already and nothing to do here.
+ * already and nothing to do here. Only valid for family >= 0x17.
*/
- if (!has_0xb) {
+ if (!has_topoext && tscan->c->x86 >= 0x17) {
/*
* Leaf 0x80000008 set the CORE domain shift already.
* Update the SMT domain, but do not propagate it.
@@ -119,7 +119,7 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
return true;
}
-static bool parse_fam10h_node_id(struct topo_scan *tscan)
+static void parse_fam10h_node_id(struct topo_scan *tscan)
{
union {
struct {
@@ -131,20 +131,20 @@ static bool parse_fam10h_node_id(struct topo_scan *tscan)
} nid;
if (!boot_cpu_has(X86_FEATURE_NODEID_MSR))
- return false;
+ return;
rdmsrl(MSR_FAM10H_NODE_ID, nid.msr);
store_node(tscan, nid.nodes_per_pkg + 1, nid.node_id);
tscan->c->topo.llc_id = nid.node_id;
- return true;
}
static void legacy_set_llc(struct topo_scan *tscan)
{
unsigned int apicid = tscan->c->topo.initial_apicid;
- /* parse_8000_0008() set everything up except llc_id */
- tscan->c->topo.llc_id = apicid >> tscan->dom_shifts[TOPO_CORE_DOMAIN];
+ /* If none of the parsers set LLC ID then use the die ID for it. */
+ if (tscan->c->topo.llc_id == BAD_APICID)
+ tscan->c->topo.llc_id = apicid >> tscan->dom_shifts[TOPO_CORE_DOMAIN];
}
static void topoext_fixup(struct topo_scan *tscan)
@@ -169,28 +169,28 @@ static void topoext_fixup(struct topo_scan *tscan)
static void parse_topology_amd(struct topo_scan *tscan)
{
- bool has_0xb = false;
+ bool has_topoext = false;
/*
* If the extended topology leaf 0x8000_001e is available
- * try to get SMT and CORE shift from leaf 0xb first, then
- * try to get the CORE shift from leaf 0x8000_0008.
+ * try to get SMT, CORE, TILE, and DIE shifts from extended
+ * CPUID leaf 0x8000_0026 on supported processors first. If
+ * extended CPUID leaf 0x8000_0026 is not supported, try to
+ * get SMT and CORE shift from leaf 0xb first, then try to
+ * get the CORE shift from leaf 0x8000_0008.
*/
if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
- has_0xb = cpu_parse_topology_ext(tscan);
+ has_topoext = cpu_parse_topology_ext(tscan);
- if (!has_0xb && !parse_8000_0008(tscan))
+ if (!has_topoext && !parse_8000_0008(tscan))
return;
/* Prefer leaf 0x8000001e if available */
- if (parse_8000_001e(tscan, has_0xb))
+ if (parse_8000_001e(tscan, has_topoext))
return;
/* Try the NODEID MSR */
- if (parse_fam10h_node_id(tscan))
- return;
-
- legacy_set_llc(tscan);
+ parse_fam10h_node_id(tscan);
}
void cpu_parse_topology_amd(struct topo_scan *tscan)
@@ -198,6 +198,7 @@ void cpu_parse_topology_amd(struct topo_scan *tscan)
tscan->amd_nodes_per_pkg = 1;
topoext_fixup(tscan);
parse_topology_amd(tscan);
+ legacy_set_llc(tscan);
if (tscan->amd_nodes_per_pkg > 1)
set_cpu_cap(tscan->c, X86_FEATURE_AMD_DCM);
diff --git a/arch/x86/kernel/cpu/topology_ext.c b/arch/x86/kernel/cpu/topology_ext.c
index e477228cd5b2..467b0326bf1a 100644
--- a/arch/x86/kernel/cpu/topology_ext.c
+++ b/arch/x86/kernel/cpu/topology_ext.c
@@ -13,7 +13,10 @@ enum topo_types {
CORE_TYPE = 2,
MAX_TYPE_0B = 3,
MODULE_TYPE = 3,
+ AMD_CCD_TYPE = 3,
TILE_TYPE = 4,
+ AMD_SOCKET_TYPE = 4,
+ MAX_TYPE_80000026 = 5,
DIE_TYPE = 5,
DIEGRP_TYPE = 6,
MAX_TYPE_1F = 7,
@@ -32,6 +35,13 @@ static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
[DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
};
+static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
+ [SMT_TYPE] = TOPO_SMT_DOMAIN,
+ [CORE_TYPE] = TOPO_CORE_DOMAIN,
+ [AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
+ [AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
+};
+
static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
unsigned int *last_dom)
{
@@ -56,6 +66,7 @@ static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
switch (leaf) {
case 0x0b: maxtype = MAX_TYPE_0B; map = topo_domain_map_0b_1f; break;
case 0x1f: maxtype = MAX_TYPE_1F; map = topo_domain_map_0b_1f; break;
+ case 0x80000026: maxtype = MAX_TYPE_80000026; map = topo_domain_map_80000026; break;
default: return false;
}
@@ -125,6 +136,10 @@ bool cpu_parse_topology_ext(struct topo_scan *tscan)
if (tscan->c->cpuid_level >= 0x1f && parse_topology_leaf(tscan, 0x1f))
return true;
+ /* AMD: Try leaf 0x80000026 first. */
+ if (tscan->c->extended_cpuid_level >= 0x80000026 && parse_topology_leaf(tscan, 0x80000026))
+ return true;
+
/* Intel/AMD: Fall back to leaf 0xB if available */
return tscan->c->cpuid_level >= 0x0b && parse_topology_leaf(tscan, 0x0b);
}
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 11f83d07925e..00189cdeb775 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -41,80 +41,97 @@
#define CPUID_VMWARE_INFO_LEAF 0x40000000
#define CPUID_VMWARE_FEATURES_LEAF 0x40000010
-#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0)
-#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1)
-#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
-
-#define VMWARE_CMD_GETVERSION 10
-#define VMWARE_CMD_GETHZ 45
-#define VMWARE_CMD_GETVCPU_INFO 68
-#define VMWARE_CMD_LEGACY_X2APIC 3
-#define VMWARE_CMD_VCPU_RESERVED 31
-#define VMWARE_CMD_STEALCLOCK 91
+#define GETVCPU_INFO_LEGACY_X2APIC BIT(3)
+#define GETVCPU_INFO_VCPU_RESERVED BIT(31)
#define STEALCLOCK_NOT_AVAILABLE (-1)
#define STEALCLOCK_DISABLED 0
#define STEALCLOCK_ENABLED 1
-#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
- __asm__("inl (%%dx), %%eax" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
- __asm__("vmcall" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(0), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx) \
- __asm__("vmmcall" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(0), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do { \
- switch (vmware_hypercall_mode) { \
- case CPUID_VMWARE_FEATURES_ECX_VMCALL: \
- VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
- break; \
- case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
- VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx); \
- break; \
- default: \
- VMWARE_PORT(cmd, eax, ebx, ecx, edx); \
- break; \
- } \
- } while (0)
-
struct vmware_steal_time {
union {
- uint64_t clock; /* stolen time counter in units of vtsc */
+ u64 clock; /* stolen time counter in units of vtsc */
struct {
/* only for little-endian */
- uint32_t clock_low;
- uint32_t clock_high;
+ u32 clock_low;
+ u32 clock_high;
};
};
- uint64_t reserved[7];
+ u64 reserved[7];
};
static unsigned long vmware_tsc_khz __ro_after_init;
static u8 vmware_hypercall_mode __ro_after_init;
+unsigned long vmware_hypercall_slow(unsigned long cmd,
+ unsigned long in1, unsigned long in3,
+ unsigned long in4, unsigned long in5,
+ u32 *out1, u32 *out2, u32 *out3,
+ u32 *out4, u32 *out5)
+{
+ unsigned long out0, rbx, rcx, rdx, rsi, rdi;
+
+ switch (vmware_hypercall_mode) {
+ case CPUID_VMWARE_FEATURES_ECX_VMCALL:
+ asm_inline volatile ("vmcall"
+ : "=a" (out0), "=b" (rbx), "=c" (rcx),
+ "=d" (rdx), "=S" (rsi), "=D" (rdi)
+ : "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ break;
+ case CPUID_VMWARE_FEATURES_ECX_VMMCALL:
+ asm_inline volatile ("vmmcall"
+ : "=a" (out0), "=b" (rbx), "=c" (rcx),
+ "=d" (rdx), "=S" (rsi), "=D" (rdi)
+ : "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ break;
+ default:
+ asm_inline volatile ("movw %[port], %%dx; inl (%%dx), %%eax"
+ : "=a" (out0), "=b" (rbx), "=c" (rcx),
+ "=d" (rdx), "=S" (rsi), "=D" (rdi)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ break;
+ }
+
+ if (out1)
+ *out1 = rbx;
+ if (out2)
+ *out2 = rcx;
+ if (out3)
+ *out3 = rdx;
+ if (out4)
+ *out4 = rsi;
+ if (out5)
+ *out5 = rdi;
+
+ return out0;
+}
+
static inline int __vmware_platform(void)
{
- uint32_t eax, ebx, ecx, edx;
- VMWARE_CMD(GETVERSION, eax, ebx, ecx, edx);
- return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
+ u32 eax, ebx, ecx;
+
+ eax = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &ebx, &ecx);
+ return eax != UINT_MAX && ebx == VMWARE_HYPERVISOR_MAGIC;
}
static unsigned long vmware_get_tsc_khz(void)
@@ -166,21 +183,12 @@ static void __init vmware_cyc2ns_setup(void)
pr_info("using clock offset of %llu ns\n", d->cyc2ns_offset);
}
-static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2)
+static int vmware_cmd_stealclock(u32 addr_hi, u32 addr_lo)
{
- uint32_t result, info;
-
- asm volatile (VMWARE_HYPERCALL :
- "=a"(result),
- "=c"(info) :
- "a"(VMWARE_HYPERVISOR_MAGIC),
- "b"(0),
- "c"(VMWARE_CMD_STEALCLOCK),
- "d"(0),
- "S"(arg1),
- "D"(arg2) :
- "memory");
- return result;
+ u32 info;
+
+ return vmware_hypercall5(VMWARE_CMD_STEALCLOCK, 0, 0, addr_hi, addr_lo,
+ &info);
}
static bool stealclock_enable(phys_addr_t pa)
@@ -215,15 +223,15 @@ static bool vmware_is_stealclock_available(void)
* Return:
* The steal clock reading in ns.
*/
-static uint64_t vmware_steal_clock(int cpu)
+static u64 vmware_steal_clock(int cpu)
{
struct vmware_steal_time *steal = &per_cpu(vmw_steal_time, cpu);
- uint64_t clock;
+ u64 clock;
if (IS_ENABLED(CONFIG_64BIT))
clock = READ_ONCE(steal->clock);
else {
- uint32_t initial_high, low, high;
+ u32 initial_high, low, high;
do {
initial_high = READ_ONCE(steal->clock_high);
@@ -235,7 +243,7 @@ static uint64_t vmware_steal_clock(int cpu)
high = READ_ONCE(steal->clock_high);
} while (initial_high != high);
- clock = ((uint64_t)high << 32) | low;
+ clock = ((u64)high << 32) | low;
}
return mul_u64_u32_shr(clock, vmware_cyc2ns.cyc2ns_mul,
@@ -389,13 +397,13 @@ static void __init vmware_set_capabilities(void)
static void __init vmware_platform_setup(void)
{
- uint32_t eax, ebx, ecx, edx;
- uint64_t lpj, tsc_khz;
+ u32 eax, ebx, ecx;
+ u64 lpj, tsc_khz;
- VMWARE_CMD(GETHZ, eax, ebx, ecx, edx);
+ eax = vmware_hypercall3(VMWARE_CMD_GETHZ, UINT_MAX, &ebx, &ecx);
if (ebx != UINT_MAX) {
- lpj = tsc_khz = eax | (((uint64_t)ebx) << 32);
+ lpj = tsc_khz = eax | (((u64)ebx) << 32);
do_div(tsc_khz, 1000);
WARN_ON(tsc_khz >> 32);
pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n",
@@ -446,7 +454,7 @@ static u8 __init vmware_select_hypercall(void)
* If !boot_cpu_has(X86_FEATURE_HYPERVISOR), vmware_hypercall_mode
* intentionally defaults to 0.
*/
-static uint32_t __init vmware_platform(void)
+static u32 __init vmware_platform(void)
{
if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
unsigned int eax;
@@ -474,12 +482,65 @@ static uint32_t __init vmware_platform(void)
/* Checks if hypervisor supports x2apic without VT-D interrupt remapping. */
static bool __init vmware_legacy_x2apic_available(void)
{
- uint32_t eax, ebx, ecx, edx;
- VMWARE_CMD(GETVCPU_INFO, eax, ebx, ecx, edx);
- return !(eax & BIT(VMWARE_CMD_VCPU_RESERVED)) &&
- (eax & BIT(VMWARE_CMD_LEGACY_X2APIC));
+ u32 eax;
+
+ eax = vmware_hypercall1(VMWARE_CMD_GETVCPU_INFO, 0);
+ return !(eax & GETVCPU_INFO_VCPU_RESERVED) &&
+ (eax & GETVCPU_INFO_LEGACY_X2APIC);
}
+#ifdef CONFIG_INTEL_TDX_GUEST
+/*
+ * TDCALL[TDG.VP.VMCALL] uses %rax (arg0) and %rcx (arg2). Therefore,
+ * we remap those registers to %r12 and %r13, respectively.
+ */
+unsigned long vmware_tdx_hypercall(unsigned long cmd,
+ unsigned long in1, unsigned long in3,
+ unsigned long in4, unsigned long in5,
+ u32 *out1, u32 *out2, u32 *out3,
+ u32 *out4, u32 *out5)
+{
+ struct tdx_module_args args = {};
+
+ if (!hypervisor_is_type(X86_HYPER_VMWARE)) {
+ pr_warn_once("Incorrect usage\n");
+ return ULONG_MAX;
+ }
+
+ if (cmd & ~VMWARE_CMD_MASK) {
+ pr_warn_once("Out of range command %lx\n", cmd);
+ return ULONG_MAX;
+ }
+
+ args.rbx = in1;
+ args.rdx = in3;
+ args.rsi = in4;
+ args.rdi = in5;
+ args.r10 = VMWARE_TDX_VENDOR_LEAF;
+ args.r11 = VMWARE_TDX_HCALL_FUNC;
+ args.r12 = VMWARE_HYPERVISOR_MAGIC;
+ args.r13 = cmd;
+ /* CPL */
+ args.r15 = 0;
+
+ __tdx_hypercall(&args);
+
+ if (out1)
+ *out1 = args.rbx;
+ if (out2)
+ *out2 = args.r13;
+ if (out3)
+ *out3 = args.rdx;
+ if (out4)
+ *out4 = args.rsi;
+ if (out5)
+ *out5 = args.rdi;
+
+ return args.r12;
+}
+EXPORT_SYMBOL_GPL(vmware_tdx_hypercall);
+#endif
+
#ifdef CONFIG_AMD_MEM_ENCRYPT
static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb,
struct pt_regs *regs)
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index e74d0c4286c1..340af8155658 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -128,6 +128,18 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
#ifdef CONFIG_HPET_TIMER
hpet_disable();
#endif
+
+ /*
+ * Non-crash kexec calls enc_kexec_begin() while scheduling is still
+ * active. This allows the callback to wait until all in-flight
+ * shared<->private conversions are complete. In a crash scenario,
+ * enc_kexec_begin() gets called after all but one CPU have been shut
+ * down and interrupts have been disabled. This allows the callback to
+ * detect a race with the conversion and report it.
+ */
+ x86_platform.guest.enc_kexec_begin();
+ x86_platform.guest.enc_kexec_finish();
+
crash_save_cpu(regs, safe_smp_processor_id());
}
@@ -402,20 +414,26 @@ int crash_load_segments(struct kimage *image)
#undef pr_fmt
#define pr_fmt(fmt) "crash hp: " fmt
-/* These functions provide the value for the sysfs crash_hotplug nodes */
-#ifdef CONFIG_HOTPLUG_CPU
-int arch_crash_hotplug_cpu_support(void)
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
{
- return crash_check_update_elfcorehdr();
-}
-#endif
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_crash_hotplug_memory_support(void)
-{
- return crash_check_update_elfcorehdr();
-}
+#ifdef CONFIG_KEXEC_FILE
+ if (image->file_mode)
+ return 1;
#endif
+ /*
+ * Initially, crash hotplug support for kexec_load was added
+ * with the KEXEC_UPDATE_ELFCOREHDR flag. Later, this
+ * functionality was expanded to accommodate multiple kexec
+ * segment updates, leading to the introduction of the
+ * KEXEC_CRASH_HOTPLUG_SUPPORT kexec flag bit. Consequently,
+ * when the kexec tool sends either of these flags, it indicates
+ * that the required kexec segment (elfcorehdr) is excluded from
+ * the SHA calculation.
+ */
+ return (kexec_flags & KEXEC_UPDATE_ELFCOREHDR ||
+ kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT);
+}
unsigned int arch_crash_get_elfcorehdr_size(void)
{
@@ -432,10 +450,12 @@ unsigned int arch_crash_get_elfcorehdr_size(void)
/**
* arch_crash_handle_hotplug_event() - Handle hotplug elfcorehdr changes
* @image: a pointer to kexec_crash_image
+ * @arg: struct memory_notify handler for memory hotplug case and
+ * NULL for CPU hotplug case.
*
* Prepare the new elfcorehdr and replace the existing elfcorehdr.
*/
-void arch_crash_handle_hotplug_event(struct kimage *image)
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
{
void *elfbuf = NULL, *old_elfcorehdr;
unsigned long nr_mem_ranges;
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 003e0298f46a..64280879c68c 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -24,6 +24,7 @@
#include <asm/pci_x86.h>
#include <asm/setup.h>
#include <asm/i8259.h>
+#include <asm/numa.h>
#include <asm/prom.h>
__initdata u64 initial_dtb;
@@ -82,7 +83,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev)
ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (ret)
- return ret;
+ return pcibios_err_to_errno(ret);
if (!pin)
return 0;
@@ -137,6 +138,7 @@ static void __init dtb_cpu_setup(void)
continue;
}
topology_register_apic(apic_id, CPU_ACPIID_INVALID, true);
+ set_apicid_to_node(apic_id, of_node_to_nid(dn));
}
}
@@ -277,9 +279,18 @@ static void __init dtb_apic_setup(void)
dtb_ioapic_setup();
}
-#ifdef CONFIG_OF_EARLY_FLATTREE
+static void __init x86_dtb_parse_smp_config(void)
+{
+ if (!of_have_populated_dt())
+ return;
+
+ dtb_setup_hpet();
+ dtb_apic_setup();
+}
+
void __init x86_flattree_get_config(void)
{
+#ifdef CONFIG_OF_EARLY_FLATTREE
u32 size, map_len;
void *dt;
@@ -301,14 +312,7 @@ void __init x86_flattree_get_config(void)
if (initial_dtb)
early_memunmap(dt, map_len);
-}
#endif
-
-void __init x86_dtb_parse_smp_config(void)
-{
- if (!of_have_populated_dt())
- return;
-
- dtb_setup_hpet();
- dtb_apic_setup();
+ if (of_have_populated_dt())
+ x86_init.mpparse.parse_smp_cfg = x86_dtb_parse_smp_config;
}
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 44a91ef5a23b..a7d562697e50 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -405,8 +405,8 @@ static void __die_header(const char *str, struct pt_regs *regs, long err)
pr = IS_ENABLED(CONFIG_PREEMPT_RT) ? " PREEMPT_RT" : " PREEMPT";
printk(KERN_DEFAULT
- "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter,
- pr,
+ "Oops: %s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff,
+ ++die_counter, pr,
IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
IS_ENABLED(CONFIG_KASAN) ? " KASAN" : "",
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 68b09f718f10..4893d30ce438 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -828,7 +828,7 @@ u64 __init e820__memblock_alloc_reserved(u64 size, u64 align)
/*
* Find the highest page frame number we have available
*/
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, enum e820_type type)
+static unsigned long __init e820__end_ram_pfn(unsigned long limit_pfn)
{
int i;
unsigned long last_pfn = 0;
@@ -839,7 +839,8 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, enum e820_type
unsigned long start_pfn;
unsigned long end_pfn;
- if (entry->type != type)
+ if (entry->type != E820_TYPE_RAM &&
+ entry->type != E820_TYPE_ACPI)
continue;
start_pfn = entry->addr >> PAGE_SHIFT;
@@ -865,12 +866,12 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, enum e820_type
unsigned long __init e820__end_of_ram_pfn(void)
{
- return e820_end_pfn(MAX_ARCH_PFN, E820_TYPE_RAM);
+ return e820__end_ram_pfn(MAX_ARCH_PFN);
}
unsigned long __init e820__end_of_low_ram_pfn(void)
{
- return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_TYPE_RAM);
+ return e820__end_ram_pfn(1UL << (32 - PAGE_SHIFT));
}
static void __init early_panic(char *msg)
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 59f4aefc6bc1..29d1f9104e94 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -17,8 +17,8 @@
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_regs.h>
#include <linux/platform_data/x86/apple.h>
-#include <drm/i915_drm.h>
-#include <drm/i915_pciids.h>
+#include <drm/intel/i915_drm.h>
+#include <drm/intel/i915_pciids.h>
#include <asm/pci-direct.h>
#include <asm/dma.h>
#include <asm/io_apic.h>
@@ -518,47 +518,46 @@ static const struct intel_early_ops gen11_early_ops __initconst = {
/* Intel integrated GPUs for which we need to reserve "stolen memory" */
static const struct pci_device_id intel_early_ids[] __initconst = {
- INTEL_I830_IDS(&i830_early_ops),
- INTEL_I845G_IDS(&i845_early_ops),
- INTEL_I85X_IDS(&i85x_early_ops),
- INTEL_I865G_IDS(&i865_early_ops),
- INTEL_I915G_IDS(&gen3_early_ops),
- INTEL_I915GM_IDS(&gen3_early_ops),
- INTEL_I945G_IDS(&gen3_early_ops),
- INTEL_I945GM_IDS(&gen3_early_ops),
- INTEL_VLV_IDS(&gen6_early_ops),
- INTEL_PINEVIEW_G_IDS(&gen3_early_ops),
- INTEL_PINEVIEW_M_IDS(&gen3_early_ops),
- INTEL_I965G_IDS(&gen3_early_ops),
- INTEL_G33_IDS(&gen3_early_ops),
- INTEL_I965GM_IDS(&gen3_early_ops),
- INTEL_GM45_IDS(&gen3_early_ops),
- INTEL_G45_IDS(&gen3_early_ops),
- INTEL_IRONLAKE_D_IDS(&gen3_early_ops),
- INTEL_IRONLAKE_M_IDS(&gen3_early_ops),
- INTEL_SNB_D_IDS(&gen6_early_ops),
- INTEL_SNB_M_IDS(&gen6_early_ops),
- INTEL_IVB_M_IDS(&gen6_early_ops),
- INTEL_IVB_D_IDS(&gen6_early_ops),
- INTEL_HSW_IDS(&gen6_early_ops),
- INTEL_BDW_IDS(&gen8_early_ops),
- INTEL_CHV_IDS(&chv_early_ops),
- INTEL_SKL_IDS(&gen9_early_ops),
- INTEL_BXT_IDS(&gen9_early_ops),
- INTEL_KBL_IDS(&gen9_early_ops),
- INTEL_CFL_IDS(&gen9_early_ops),
- INTEL_GLK_IDS(&gen9_early_ops),
- INTEL_CNL_IDS(&gen9_early_ops),
- INTEL_ICL_11_IDS(&gen11_early_ops),
- INTEL_EHL_IDS(&gen11_early_ops),
- INTEL_JSL_IDS(&gen11_early_ops),
- INTEL_TGL_12_IDS(&gen11_early_ops),
- INTEL_RKL_IDS(&gen11_early_ops),
- INTEL_ADLS_IDS(&gen11_early_ops),
- INTEL_ADLP_IDS(&gen11_early_ops),
- INTEL_ADLN_IDS(&gen11_early_ops),
- INTEL_RPLS_IDS(&gen11_early_ops),
- INTEL_RPLP_IDS(&gen11_early_ops),
+ INTEL_I830_IDS(INTEL_VGA_DEVICE, &i830_early_ops),
+ INTEL_I845G_IDS(INTEL_VGA_DEVICE, &i845_early_ops),
+ INTEL_I85X_IDS(INTEL_VGA_DEVICE, &i85x_early_ops),
+ INTEL_I865G_IDS(INTEL_VGA_DEVICE, &i865_early_ops),
+ INTEL_I915G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I915GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I945G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I945GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_VLV_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_PNV_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I965G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_G33_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I965GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_GM45_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_G45_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_ILK_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_SNB_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_IVB_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_HSW_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_BDW_IDS(INTEL_VGA_DEVICE, &gen8_early_ops),
+ INTEL_CHV_IDS(INTEL_VGA_DEVICE, &chv_early_ops),
+ INTEL_SKL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_BXT_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_KBL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_CFL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_WHL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_CML_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_GLK_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_CNL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_ICL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_EHL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_JSL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_TGL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RKL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_ADLS_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_ADLP_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_ADLN_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RPLS_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RPLU_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
};
struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0);
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 520deb411a70..1209c7aebb21 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -145,8 +145,8 @@ void restore_fpregs_from_fpstate(struct fpstate *fpstate, u64 mask)
asm volatile(
"fnclex\n\t"
"emms\n\t"
- "fildl %P[addr]" /* set F?P to defined value */
- : : [addr] "m" (fpstate));
+ "fildl %[addr]" /* set F?P to defined value */
+ : : [addr] "m" (*fpstate));
}
if (use_xsave()) {
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 33a214b1a4ce..c5a026fee5e0 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -991,6 +991,7 @@ void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
return __raw_xsave_addr(xsave, xfeature_nr);
}
+EXPORT_SYMBOL_GPL(get_xsave_addr);
#ifdef CONFIG_ARCH_HAS_PKEYS
@@ -1434,8 +1435,8 @@ static bool xstate_op_valid(struct fpstate *fpstate, u64 mask, bool rstor)
return rstor;
/*
- * XSAVE(S): clone(), fpu_swap_kvm_fpu()
- * XRSTORS(S): fpu_swap_kvm_fpu()
+ * XSAVE(S): clone(), fpu_swap_kvm_fpstate()
+ * XRSTORS(S): fpu_swap_kvm_fpstate()
*/
/*
diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h
index 19ca623ffa2a..2ee0b9c53dcc 100644
--- a/arch/x86/kernel/fpu/xstate.h
+++ b/arch/x86/kernel/fpu/xstate.h
@@ -54,8 +54,6 @@ extern int copy_sigframe_from_user_to_xstate(struct task_struct *tsk, const void
extern void fpu__init_cpu_xstate(void);
extern void fpu__init_system_xstate(unsigned int legacy_size);
-extern void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
-
static inline u64 xfeatures_mask_supervisor(void)
{
return fpu_kernel_cfg.max_features & XFEATURE_MASK_SUPERVISOR_SUPPORTED;
@@ -108,21 +106,17 @@ static inline u64 xfeatures_mask_independent(void)
* Otherwise, if XSAVEOPT is enabled, XSAVEOPT replaces XSAVE because XSAVEOPT
* supports modified optimization which is not supported by XSAVE.
*
- * We use XSAVE as a fallback.
- *
- * The 661 label is defined in the ALTERNATIVE* macros as the address of the
- * original instruction which gets replaced. We need to use it here as the
- * address of the instruction where we might get an exception at.
+ * Use XSAVE as a fallback.
*/
#define XSTATE_XSAVE(st, lmask, hmask, err) \
- asm volatile(ALTERNATIVE_3(XSAVE, \
+ asm volatile("1: " ALTERNATIVE_3(XSAVE, \
XSAVEOPT, X86_FEATURE_XSAVEOPT, \
XSAVEC, X86_FEATURE_XSAVEC, \
XSAVES, X86_FEATURE_XSAVES) \
"\n" \
"xor %[err], %[err]\n" \
"3:\n" \
- _ASM_EXTABLE_TYPE_REG(661b, 3b, EX_TYPE_EFAULT_REG, %[err]) \
+ _ASM_EXTABLE_TYPE_REG(1b, 3b, EX_TYPE_EFAULT_REG, %[err]) \
: [err] "=r" (err) \
: "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
: "memory")
@@ -132,11 +126,11 @@ static inline u64 xfeatures_mask_independent(void)
* XSAVE area format.
*/
#define XSTATE_XRESTORE(st, lmask, hmask) \
- asm volatile(ALTERNATIVE(XRSTOR, \
+ asm volatile("1: " ALTERNATIVE(XRSTOR, \
XRSTORS, X86_FEATURE_XSAVES) \
"\n" \
"3:\n" \
- _ASM_EXTABLE_TYPE(661b, 3b, EX_TYPE_FPU_RESTORE) \
+ _ASM_EXTABLE_TYPE(1b, 3b, EX_TYPE_FPU_RESTORE) \
: \
: "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
: "memory")
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 70139d9d2e01..8da0e66ca22d 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -25,6 +25,7 @@
#include <linux/memory.h>
#include <linux/vmalloc.h>
#include <linux/set_memory.h>
+#include <linux/execmem.h>
#include <trace/syscall.h>
@@ -260,25 +261,14 @@ void arch_ftrace_update_code(int command)
/* Currently only x86_64 supports dynamic trampolines */
#ifdef CONFIG_X86_64
-#ifdef CONFIG_MODULES
-#include <linux/moduleloader.h>
-/* Module allocation simplifies allocating memory for code */
static inline void *alloc_tramp(unsigned long size)
{
- return module_alloc(size);
+ return execmem_alloc(EXECMEM_FTRACE, size);
}
static inline void tramp_free(void *tramp)
{
- module_memfree(tramp);
+ execmem_free(tramp);
}
-#else
-/* Trampolines can only be created if modules are supported */
-static inline void *alloc_tramp(unsigned long size)
-{
- return NULL;
-}
-static inline void tramp_free(void *tramp) { }
-#endif
/* Defined as markers to the end of the ftrace default trampolines */
extern void ftrace_regs_caller_end(void);
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index b50f3641c4d6..2e42056d2306 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -44,9 +44,6 @@
#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
-
-#define SIZEOF_PTREGS 17*4
-
/*
* Worst-case size of the kernel mapping we need to make:
* a relocatable kernel can live anywhere in lowmem, so we need to be able
@@ -488,19 +485,13 @@ SYM_DATA_END(initial_page_table)
.data
.balign 4
-/*
- * The SIZEOF_PTREGS gap is a convention which helps the in-kernel unwinder
- * reliably detect the end of the stack.
- */
-SYM_DATA(initial_stack,
- .long init_thread_union + THREAD_SIZE -
- SIZEOF_PTREGS - TOP_OF_KERNEL_STACK_PADDING)
+SYM_DATA(initial_stack, .long __top_init_kernel_stack)
__INITRODATA
int_msg:
.asciz "Unknown interrupt or fault at: %p %p %p\n"
-#include "../../x86/xen/xen-head.S"
+#include "../xen/xen-head.S"
/*
* The IDT and GDT 'descriptors' are a strange 48-bit object
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index d8198fbd70e5..330922b328bf 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -66,7 +66,7 @@ SYM_CODE_START_NOALIGN(startup_64)
mov %rsi, %r15
/* Set up the stack for verify_cpu() */
- leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
+ leaq __top_init_kernel_stack(%rip), %rsp
/* Setup GSBASE to allow stack canary access for C code */
movl $MSR_GS_BASE, %ecx
@@ -720,7 +720,7 @@ SYM_DATA(smpboot_control, .long 0)
SYM_DATA(phys_base, .quad 0x0)
EXPORT_SYMBOL(phys_base)
-#include "../../x86/xen/xen-head.S"
+#include "../xen/xen-head.S"
__PAGE_ALIGNED_BSS
SYM_DATA_START_PAGE_ALIGNED(empty_zero_page)
diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c
index fc37c8d83daf..f445bec516a0 100644
--- a/arch/x86/kernel/idt.c
+++ b/arch/x86/kernel/idt.c
@@ -163,6 +163,9 @@ static const __initconst struct idt_data apic_idts[] = {
# endif
INTG(SPURIOUS_APIC_VECTOR, asm_sysvec_spurious_apic_interrupt),
INTG(ERROR_APIC_VECTOR, asm_sysvec_error_interrupt),
+# ifdef CONFIG_X86_POSTED_MSI
+ INTG(POSTED_MSI_NOTIFICATION_VECTOR, asm_sysvec_posted_msi_notification),
+# endif
#endif
};
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 35fde0107901..385e3a5fc304 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -22,6 +22,8 @@
#include <asm/desc.h>
#include <asm/traps.h>
#include <asm/thermal.h>
+#include <asm/posted_intr.h>
+#include <asm/irq_remapping.h>
#define CREATE_TRACE_POINTS
#include <asm/trace/irq_vectors.h>
@@ -182,6 +184,13 @@ int arch_show_interrupts(struct seq_file *p, int prec)
irq_stats(j)->kvm_posted_intr_wakeup_ipis);
seq_puts(p, " Posted-interrupt wakeup event\n");
#endif
+#ifdef CONFIG_X86_POSTED_MSI
+ seq_printf(p, "%*s: ", prec, "PMN");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ irq_stats(j)->posted_msi_notification_count);
+ seq_puts(p, " Posted MSI notification event\n");
+#endif
return 0;
}
@@ -240,24 +249,16 @@ static __always_inline void handle_irq(struct irq_desc *desc,
__handle_irq(desc, regs);
}
-/*
- * common_interrupt() handles all normal device IRQ's (the special SMP
- * cross-CPU interrupts have their own entry points).
- */
-DEFINE_IDTENTRY_IRQ(common_interrupt)
+static __always_inline int call_irq_handler(int vector, struct pt_regs *regs)
{
- struct pt_regs *old_regs = set_irq_regs(regs);
struct irq_desc *desc;
-
- /* entry code tells RCU that we're not quiescent. Check it. */
- RCU_LOCKDEP_WARN(!rcu_is_watching(), "IRQ failed to wake up RCU");
+ int ret = 0;
desc = __this_cpu_read(vector_irq[vector]);
if (likely(!IS_ERR_OR_NULL(desc))) {
handle_irq(desc, regs);
} else {
- apic_eoi();
-
+ ret = -EINVAL;
if (desc == VECTOR_UNUSED) {
pr_emerg_ratelimited("%s: %d.%u No irq handler for vector\n",
__func__, smp_processor_id(),
@@ -267,6 +268,23 @@ DEFINE_IDTENTRY_IRQ(common_interrupt)
}
}
+ return ret;
+}
+
+/*
+ * common_interrupt() handles all normal device IRQ's (the special SMP
+ * cross-CPU interrupts have their own entry points).
+ */
+DEFINE_IDTENTRY_IRQ(common_interrupt)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ /* entry code tells RCU that we're not quiescent. Check it. */
+ RCU_LOCKDEP_WARN(!rcu_is_watching(), "IRQ failed to wake up RCU");
+
+ if (unlikely(call_irq_handler(vector, regs)))
+ apic_eoi();
+
set_irq_regs(old_regs);
}
@@ -334,12 +352,139 @@ DEFINE_IDTENTRY_SYSVEC_SIMPLE(sysvec_kvm_posted_intr_nested_ipi)
}
#endif
+#ifdef CONFIG_X86_POSTED_MSI
+
+/* Posted Interrupt Descriptors for coalesced MSIs to be posted */
+DEFINE_PER_CPU_ALIGNED(struct pi_desc, posted_msi_pi_desc);
+
+void intel_posted_msi_init(void)
+{
+ u32 destination;
+ u32 apic_id;
+
+ this_cpu_write(posted_msi_pi_desc.nv, POSTED_MSI_NOTIFICATION_VECTOR);
+
+ /*
+ * APIC destination ID is stored in bit 8:15 while in XAPIC mode.
+ * VT-d spec. CH 9.11
+ */
+ apic_id = this_cpu_read(x86_cpu_to_apicid);
+ destination = x2apic_enabled() ? apic_id : apic_id << 8;
+ this_cpu_write(posted_msi_pi_desc.ndst, destination);
+}
+
+/*
+ * De-multiplexing posted interrupts is on the performance path, the code
+ * below is written to optimize the cache performance based on the following
+ * considerations:
+ * 1.Posted interrupt descriptor (PID) fits in a cache line that is frequently
+ * accessed by both CPU and IOMMU.
+ * 2.During posted MSI processing, the CPU needs to do 64-bit read and xchg
+ * for checking and clearing posted interrupt request (PIR), a 256 bit field
+ * within the PID.
+ * 3.On the other side, the IOMMU does atomic swaps of the entire PID cache
+ * line when posting interrupts and setting control bits.
+ * 4.The CPU can access the cache line a magnitude faster than the IOMMU.
+ * 5.Each time the IOMMU does interrupt posting to the PIR will evict the PID
+ * cache line. The cache line states after each operation are as follows:
+ * CPU IOMMU PID Cache line state
+ * ---------------------------------------------------------------
+ *...read64 exclusive
+ *...lock xchg64 modified
+ *... post/atomic swap invalid
+ *...-------------------------------------------------------------
+ *
+ * To reduce L1 data cache miss, it is important to avoid contention with
+ * IOMMU's interrupt posting/atomic swap. Therefore, a copy of PIR is used
+ * to dispatch interrupt handlers.
+ *
+ * In addition, the code is trying to keep the cache line state consistent
+ * as much as possible. e.g. when making a copy and clearing the PIR
+ * (assuming non-zero PIR bits are present in the entire PIR), it does:
+ * read, read, read, read, xchg, xchg, xchg, xchg
+ * instead of:
+ * read, xchg, read, xchg, read, xchg, read, xchg
+ */
+static __always_inline bool handle_pending_pir(u64 *pir, struct pt_regs *regs)
+{
+ int i, vec = FIRST_EXTERNAL_VECTOR;
+ unsigned long pir_copy[4];
+ bool handled = false;
+
+ for (i = 0; i < 4; i++)
+ pir_copy[i] = pir[i];
+
+ for (i = 0; i < 4; i++) {
+ if (!pir_copy[i])
+ continue;
+
+ pir_copy[i] = arch_xchg(&pir[i], 0);
+ handled = true;
+ }
+
+ if (handled) {
+ for_each_set_bit_from(vec, pir_copy, FIRST_SYSTEM_VECTOR)
+ call_irq_handler(vec, regs);
+ }
+
+ return handled;
+}
+
+/*
+ * Performance data shows that 3 is good enough to harvest 90+% of the benefit
+ * on high IRQ rate workload.
+ */
+#define MAX_POSTED_MSI_COALESCING_LOOP 3
+
+/*
+ * For MSIs that are delivered as posted interrupts, the CPU notifications
+ * can be coalesced if the MSIs arrive in high frequency bursts.
+ */
+DEFINE_IDTENTRY_SYSVEC(sysvec_posted_msi_notification)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ struct pi_desc *pid;
+ int i = 0;
+
+ pid = this_cpu_ptr(&posted_msi_pi_desc);
+
+ inc_irq_stat(posted_msi_notification_count);
+ irq_enter();
+
+ /*
+ * Max coalescing count includes the extra round of handle_pending_pir
+ * after clearing the outstanding notification bit. Hence, at most
+ * MAX_POSTED_MSI_COALESCING_LOOP - 1 loops are executed here.
+ */
+ while (++i < MAX_POSTED_MSI_COALESCING_LOOP) {
+ if (!handle_pending_pir(pid->pir64, regs))
+ break;
+ }
+
+ /*
+ * Clear outstanding notification bit to allow new IRQ notifications,
+ * do this last to maximize the window of interrupt coalescing.
+ */
+ pi_clear_on(pid);
+
+ /*
+ * There could be a race of PI notification and the clearing of ON bit,
+ * process PIR bits one last time such that handling the new interrupts
+ * are not delayed until the next IRQ.
+ */
+ handle_pending_pir(pid->pir64, regs);
+
+ apic_eoi();
+ irq_exit();
+ set_irq_regs(old_regs);
+}
+#endif /* X86_POSTED_MSI */
#ifdef CONFIG_HOTPLUG_CPU
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
void fixup_irqs(void)
{
- unsigned int irr, vector;
+ unsigned int vector;
struct irq_desc *desc;
struct irq_data *data;
struct irq_chip *chip;
@@ -366,8 +511,7 @@ void fixup_irqs(void)
if (IS_ERR_OR_NULL(__this_cpu_read(vector_irq[vector])))
continue;
- irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
- if (irr & (1 << (vector % 32))) {
+ if (is_vector_pending(vector)) {
desc = __this_cpu_read(vector_irq[vector]);
raw_spin_lock(&desc->lock);
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index fe0c859873d1..ade0043ce56e 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -18,6 +18,7 @@
#include <linux/uaccess.h>
#include <linux/smp.h>
#include <linux/sched/task_stack.h>
+#include <linux/vmalloc.h>
#include <asm/cpu_entry_area.h>
#include <asm/softirq_stack.h>
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
index 9a7c03d47861..51b805c727fc 100644
--- a/arch/x86/kernel/itmt.c
+++ b/arch/x86/kernel/itmt.c
@@ -38,7 +38,7 @@ static bool __read_mostly sched_itmt_capable;
*/
unsigned int __read_mostly sysctl_sched_itmt_enabled;
-static int sched_itmt_update_handler(struct ctl_table *table, int write,
+static int sched_itmt_update_handler(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
unsigned int old_sysctl;
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index d0e49bd7c6f3..72e6a45e7ec2 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -40,12 +40,12 @@
#include <linux/kgdb.h>
#include <linux/ftrace.h>
#include <linux/kasan.h>
-#include <linux/moduleloader.h>
#include <linux/objtool.h>
#include <linux/vmalloc.h>
#include <linux/pgtable.h>
#include <linux/set_memory.h>
#include <linux/cfi.h>
+#include <linux/execmem.h>
#include <asm/text-patching.h>
#include <asm/cacheflush.h>
@@ -495,7 +495,7 @@ void *alloc_insn_page(void)
{
void *page;
- page = module_alloc(PAGE_SIZE);
+ page = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE);
if (!page)
return NULL;
diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c
index dd2ec14adb77..15af7e98e161 100644
--- a/arch/x86/kernel/kprobes/ftrace.c
+++ b/arch/x86/kernel/kprobes/ftrace.c
@@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe_ctlblk *kcb;
int bit;
+ if (unlikely(kprobe_ftrace_disabled))
+ return;
+
bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 7f0732bc0ccd..263f8aed4e2c 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -44,7 +44,7 @@
#include <asm/svm.h>
#include <asm/e820/api.h>
-DEFINE_STATIC_KEY_FALSE(kvm_async_pf_enabled);
+DEFINE_STATIC_KEY_FALSE_RO(kvm_async_pf_enabled);
static int kvmapf = 1;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index b180d8e497c3..cc0f7f70b17b 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -295,8 +295,15 @@ void machine_kexec_cleanup(struct kimage *image)
void machine_kexec(struct kimage *image)
{
unsigned long page_list[PAGES_NR];
- void *control_page;
+ unsigned int host_mem_enc_active;
int save_ftrace_enabled;
+ void *control_page;
+
+ /*
+ * This must be done before load_segments() since if call depth tracking
+ * is used then GS must be valid to make any function calls.
+ */
+ host_mem_enc_active = cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT);
#ifdef CONFIG_KEXEC_JUMP
if (image->preserve_context)
@@ -358,7 +365,7 @@ void machine_kexec(struct kimage *image)
(unsigned long)page_list,
image->start,
image->preserve_context,
- cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT));
+ host_mem_enc_active);
#ifdef CONFIG_KEXEC_JUMP
if (image->preserve_context)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index e18914c0e38a..837450b6e882 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -36,57 +36,6 @@ do { \
} while (0)
#endif
-#ifdef CONFIG_RANDOMIZE_BASE
-static unsigned long module_load_offset;
-
-/* Mutex protects the module_load_offset. */
-static DEFINE_MUTEX(module_kaslr_mutex);
-
-static unsigned long int get_module_load_offset(void)
-{
- if (kaslr_enabled()) {
- mutex_lock(&module_kaslr_mutex);
- /*
- * Calculate the module_load_offset the first time this
- * code is called. Once calculated it stays the same until
- * reboot.
- */
- if (module_load_offset == 0)
- module_load_offset =
- get_random_u32_inclusive(1, 1024) * PAGE_SIZE;
- mutex_unlock(&module_kaslr_mutex);
- }
- return module_load_offset;
-}
-#else
-static unsigned long int get_module_load_offset(void)
-{
- return 0;
-}
-#endif
-
-void *module_alloc(unsigned long size)
-{
- gfp_t gfp_mask = GFP_KERNEL;
- void *p;
-
- if (PAGE_ALIGN(size) > MODULES_LEN)
- return NULL;
-
- p = __vmalloc_node_range(size, MODULE_ALIGN,
- MODULES_VADDR + get_module_load_offset(),
- MODULES_END, gfp_mask, PAGE_KERNEL,
- VM_FLUSH_RESET_PERMS | VM_DEFER_KMEMLEAK,
- NUMA_NO_NODE, __builtin_return_address(0));
-
- if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
- vfree(p);
- return NULL;
- }
-
- return p;
-}
-
#ifdef CONFIG_X86_32
int apply_relocate(Elf32_Shdr *sechdrs,
const char *strtab,
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index b8441147eb5e..f63f8fd00a91 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -835,6 +835,13 @@ void __noreturn stop_this_cpu(void *dummy)
*/
cpumask_clear_cpu(cpu, &cpus_stop_mask);
+#ifdef CONFIG_SMP
+ if (smp_ops.stop_this_cpu) {
+ smp_ops.stop_this_cpu();
+ unreachable();
+ }
+#endif
+
for (;;) {
/*
* Use native_halt() so that memory contents don't change
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index f3130f762784..0e0a4cf6b5eb 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/objtool.h>
#include <linux/pgtable.h>
+#include <linux/kexec.h>
#include <acpi/reboot.h>
#include <asm/io.h>
#include <asm/apic.h>
@@ -716,6 +717,14 @@ static void native_machine_emergency_restart(void)
void native_machine_shutdown(void)
{
+ /*
+ * Call enc_kexec_begin() while all CPUs are still active and
+ * interrupts are enabled. This will allow all in-flight memory
+ * conversions to finish cleanly.
+ */
+ if (kexec_in_progress)
+ x86_platform.guest.enc_kexec_begin();
+
/* Stop the cpus and apics */
#ifdef CONFIG_X86_IO_APIC
/*
@@ -752,6 +761,9 @@ void native_machine_shutdown(void)
#ifdef CONFIG_X86_64
x86_platform.iommu_shutdown();
#endif
+
+ if (kexec_in_progress)
+ x86_platform.guest.enc_kexec_finish();
}
static void __machine_emergency_restart(int emergency)
@@ -868,6 +880,12 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
cpu_emergency_disable_virtualization();
atomic_dec(&waiting_for_crash_ipi);
+
+ if (smp_ops.stop_this_cpu) {
+ smp_ops.stop_this_cpu();
+ unreachable();
+ }
+
/* Assume hlt works */
halt();
for (;;)
diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S
index 56cab1bb25f5..042c9a0334e9 100644
--- a/arch/x86/kernel/relocate_kernel_64.S
+++ b/arch/x86/kernel/relocate_kernel_64.S
@@ -5,6 +5,8 @@
*/
#include <linux/linkage.h>
+#include <linux/stringify.h>
+#include <asm/alternative.h>
#include <asm/page_types.h>
#include <asm/kexec.h>
#include <asm/processor-flags.h>
@@ -145,16 +147,15 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
* Set cr4 to a known state:
* - physical address extension enabled
* - 5-level paging, if it was enabled before
+ * - Machine check exception on TDX guest, if it was enabled before.
+ * Clearing MCE might not be allowed in TDX guests, depending on setup.
+ *
+ * Use R13 that contains the original CR4 value, read in relocate_kernel().
+ * PAE is always set in the original CR4.
*/
- movl $X86_CR4_PAE, %eax
- testq $X86_CR4_LA57, %r13
- jz 1f
- orl $X86_CR4_LA57, %eax
-1:
- movq %rax, %cr4
-
- jmp 1f
-1:
+ andl $(X86_CR4_PAE | X86_CR4_LA57), %r13d
+ ALTERNATIVE "", __stringify(orl $X86_CR4_MCE, %r13d), X86_FEATURE_TDX_GUEST
+ movq %r13, %cr4
/* Flush the TLB (needed?) */
movq %r9, %cr3
@@ -165,9 +166,9 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
* used by kexec. Flush the caches before copying the kernel.
*/
testq %r12, %r12
- jz 1f
+ jz .Lsme_off
wbinvd
-1:
+.Lsme_off:
movq %rcx, %r11
call swap_pages
@@ -187,7 +188,7 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
*/
testq %r11, %r11
- jnz 1f
+ jnz .Lrelocate
xorl %eax, %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
@@ -208,7 +209,7 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
ret
int3
-1:
+.Lrelocate:
popq %rdx
leaq PAGE_SIZE(%r10), %rsp
ANNOTATE_RETPOLINE_SAFE
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 2e7066980f3e..51a849a79c98 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -10,7 +10,6 @@
#include <asm/vsyscall.h>
#include <asm/x86_init.h>
#include <asm/time.h>
-#include <asm/intel-mid.h>
#include <asm/setup.h>
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index e125e059e2c4..5d34cad9b7b1 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -7,6 +7,7 @@
*/
#include <linux/acpi.h>
#include <linux/console.h>
+#include <linux/cpu.h>
#include <linux/crash_dump.h>
#include <linux/dma-map-ops.h>
#include <linux/efi.h>
@@ -164,6 +165,7 @@ unsigned long saved_video_mode;
static char __initdata command_line[COMMAND_LINE_SIZE];
#ifdef CONFIG_CMDLINE_BOOL
static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
+bool builtin_cmdline_added __ro_after_init;
#endif
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
@@ -753,6 +755,23 @@ void __init setup_arch(char **cmdline_p)
boot_cpu_data.x86_phys_bits = MAX_PHYSMEM_BITS;
#endif
+#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERRIDE
+ strscpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+ if (builtin_cmdline[0]) {
+ /* append boot loader cmdline to builtin */
+ strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
+ strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+ strscpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+ }
+#endif
+ builtin_cmdline_added = true;
+#endif
+
+ strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+ *cmdline_p = command_line;
+
/*
* If we have OLPC OFW, we might end up relocating the fixmap due to
* reserve_top(), so do this before touching the ioremap area.
@@ -832,22 +851,6 @@ void __init setup_arch(char **cmdline_p)
bss_resource.start = __pa_symbol(__bss_start);
bss_resource.end = __pa_symbol(__bss_stop)-1;
-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
- strscpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-#else
- if (builtin_cmdline[0]) {
- /* append boot loader cmdline to builtin */
- strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
- strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
- strscpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
- }
-#endif
-#endif
-
- strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
- *cmdline_p = command_line;
-
/*
* x86_configure_nx() is called before parse_early_param() to detect
* whether hardware doesn't support NX (so that the early EHCI debug
@@ -994,7 +997,6 @@ void __init setup_arch(char **cmdline_p)
mem_encrypt_setup_arch();
cc_random_init();
- efi_fake_memmap();
efi_find_mirror();
efi_esrt_init();
efi_mokvar_table_init();
@@ -1107,8 +1109,6 @@ void __init setup_arch(char **cmdline_p)
*/
arch_reserve_crashkernel();
- memblock_find_dma_reserve();
-
if (!early_xdbc_setup_hardware())
early_xdbc_register_console();
@@ -1218,3 +1218,10 @@ static int __init register_kernel_offset_dumper(void)
return 0;
}
__initcall(register_kernel_offset_dumper);
+
+#ifdef CONFIG_HOTPLUG_CPU
+bool arch_cpu_is_hotpluggable(int cpu)
+{
+ return cpu > 0;
+}
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c
index 59e15dd8d0f8..059685612362 100644
--- a/arch/x86/kernel/shstk.c
+++ b/arch/x86/kernel/shstk.c
@@ -163,8 +163,8 @@ static int shstk_setup(void)
if (features_enabled(ARCH_SHSTK_SHSTK))
return 0;
- /* Also not supported for 32 bit and x32 */
- if (!cpu_feature_enabled(X86_FEATURE_USER_SHSTK) || in_32bit_syscall())
+ /* Also not supported for 32 bit */
+ if (!cpu_feature_enabled(X86_FEATURE_USER_SHSTK) || in_ia32_syscall())
return -EOPNOTSUPP;
size = adjust_shstk_size(0);
@@ -577,3 +577,19 @@ long shstk_prctl(struct task_struct *task, int option, unsigned long arg2)
return wrss_control(true);
return -EINVAL;
}
+
+int shstk_update_last_frame(unsigned long val)
+{
+ unsigned long ssp;
+
+ if (!features_enabled(ARCH_SHSTK_SHSTK))
+ return 0;
+
+ ssp = get_user_shstk_addr();
+ return write_user_shstk_64((u64 __user *)ssp, (u64)val);
+}
+
+bool shstk_is_enabled(void)
+{
+ return features_enabled(ARCH_SHSTK_SHSTK);
+}
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index c12624bc82a3..ef654530bf5a 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -34,7 +34,7 @@
#include <asm/gsseg.h>
#ifdef CONFIG_IA32_EMULATION
-#include <asm/ia32_unistd.h>
+#include <asm/unistd_32_ia32.h>
static inline void reload_segments(struct sigcontext_32 *sc)
{
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 23d8aaf8d9fd..8a94053c5444 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -315,6 +315,9 @@ int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
uc_flags = frame_uc_flags(regs);
+ if (setup_signal_shadow_stack(ksig))
+ return -EFAULT;
+
if (!user_access_begin(frame, sizeof(*frame)))
return -EFAULT;
@@ -377,6 +380,9 @@ COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)
if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
goto badframe;
+ if (restore_signal_shadow_stack())
+ goto badframe;
+
if (compat_restore_altstack(&frame->uc.uc_stack))
goto badframe;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 76bb65045c64..0c35207320cb 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -438,9 +438,9 @@ static bool match_pkg(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
*/
static const struct x86_cpu_id intel_cod_cpu[] = {
- X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, 0), /* COD */
- X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, 0), /* COD */
- X86_MATCH_INTEL_FAM6_MODEL(ANY, 1), /* SNC */
+ X86_MATCH_VFM(INTEL_HASWELL_X, 0), /* COD */
+ X86_MATCH_VFM(INTEL_BROADWELL_X, 0), /* COD */
+ X86_MATCH_VFM(INTEL_ANY, 1), /* SNC */
{}
};
@@ -1033,20 +1033,22 @@ static __init void disable_smp(void)
void __init smp_prepare_cpus_common(void)
{
- unsigned int i;
+ unsigned int cpu, node;
/* Mark all except the boot CPU as hotpluggable */
- for_each_possible_cpu(i) {
- if (i)
- per_cpu(cpu_info.cpu_index, i) = nr_cpu_ids;
+ for_each_possible_cpu(cpu) {
+ if (cpu)
+ per_cpu(cpu_info.cpu_index, cpu) = nr_cpu_ids;
}
- for_each_possible_cpu(i) {
- zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
- zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
- zalloc_cpumask_var(&per_cpu(cpu_die_map, i), GFP_KERNEL);
- zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL);
- zalloc_cpumask_var(&per_cpu(cpu_l2c_shared_map, i), GFP_KERNEL);
+ for_each_possible_cpu(cpu) {
+ node = cpu_to_node(cpu);
+
+ zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu), GFP_KERNEL, node);
+ zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), GFP_KERNEL, node);
+ zalloc_cpumask_var_node(&per_cpu(cpu_die_map, cpu), GFP_KERNEL, node);
+ zalloc_cpumask_var_node(&per_cpu(cpu_llc_shared_map, cpu), GFP_KERNEL, node);
+ zalloc_cpumask_var_node(&per_cpu(cpu_l2c_shared_map, cpu), GFP_KERNEL, node);
}
set_cpu_sibling_map(0);
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index cb9fa1d5c66f..01d7cd85ef97 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -112,13 +112,21 @@ static void find_start_end(unsigned long addr, unsigned long flags,
*end = task_size_64bit(addr > DEFAULT_MAP_WINDOW);
}
+static inline unsigned long stack_guard_placement(vm_flags_t vm_flags)
+{
+ if (vm_flags & VM_SHADOW_STACK)
+ return PAGE_SIZE;
+
+ return 0;
+}
+
unsigned long
-arch_get_unmapped_area(struct file *filp, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
+arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
unsigned long begin, end;
if (flags & MAP_FIXED)
@@ -137,12 +145,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- info.flags = 0;
info.length = len;
info.low_limit = begin;
info.high_limit = end;
- info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.start_gap = stack_guard_placement(vm_flags);
if (filp) {
info.align_mask = get_align_mask();
info.align_offset += get_align_bits();
@@ -151,14 +158,14 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
}
unsigned long
-arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
- const unsigned long len, const unsigned long pgoff,
- const unsigned long flags)
+arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags, vm_flags_t vm_flags)
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
/* requested length too big for entire address space */
if (len > TASK_SIZE)
@@ -192,6 +199,7 @@ get_unmapped_area:
info.low_limit = PAGE_SIZE;
info.high_limit = get_mmap_base(0);
+ info.start_gap = stack_guard_placement(vm_flags);
/*
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
@@ -203,7 +211,6 @@ get_unmapped_area:
if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
- info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
if (filp) {
info.align_mask = get_align_mask();
@@ -223,3 +230,18 @@ bottomup:
*/
return arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
}
+
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ return arch_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, 0);
+}
+
+unsigned long
+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
+ const unsigned long len, const unsigned long pgoff,
+ const unsigned long flags)
+{
+ return arch_get_unmapped_area_topdown_vmflags(filp, addr, len, pgoff, flags, 0);
+}
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index e42faa792c07..52e1f3f0b361 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -27,25 +27,7 @@
unsigned long profile_pc(struct pt_regs *regs)
{
- unsigned long pc = instruction_pointer(regs);
-
- if (!user_mode(regs) && in_lock_functions(pc)) {
-#ifdef CONFIG_FRAME_POINTER
- return *(unsigned long *)(regs->bp + sizeof(long));
-#else
- unsigned long *sp = (unsigned long *)regs->sp;
- /*
- * Return address is either directly at stack pointer
- * or above a saved flags. Eflags has bits 22-31 zero,
- * kernel addresses don't.
- */
- if (sp[0] >> 22)
- return sp[0];
- if (sp[1] >> 22)
- return sp[1];
-#endif
- }
- return pc;
+ return instruction_pointer(regs);
}
EXPORT_SYMBOL(profile_pc);
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
deleted file mode 100644
index d42c28b8bfd8..000000000000
--- a/arch/x86/kernel/topology.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Populate sysfs with topology information
- *
- * Written by: Matthew Dobson, IBM Corporation
- * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
- *
- * Copyright (C) 2002, IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <colpatch@us.ibm.com>
- */
-#include <linux/interrupt.h>
-#include <linux/nodemask.h>
-#include <linux/export.h>
-#include <linux/mmzone.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/irq.h>
-#include <asm/io_apic.h>
-#include <asm/cpu.h>
-
-#ifdef CONFIG_HOTPLUG_CPU
-bool arch_cpu_is_hotpluggable(int cpu)
-{
- return cpu > 0;
-}
-#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 5a69a49acc96..d4462fb26299 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -26,7 +26,7 @@
#include <asm/x86_init.h>
#include <asm/geode.h>
#include <asm/apic.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/i8259.h>
#include <asm/uv/uv.h>
@@ -44,15 +44,15 @@ EXPORT_SYMBOL(tsc_khz);
static int __read_mostly tsc_unstable;
static unsigned int __initdata tsc_early_khz;
-static DEFINE_STATIC_KEY_FALSE(__use_tsc);
+static DEFINE_STATIC_KEY_FALSE_RO(__use_tsc);
int tsc_clocksource_reliable;
static int __read_mostly tsc_force_recalibrate;
-static u32 art_to_tsc_numerator;
-static u32 art_to_tsc_denominator;
-static u64 art_to_tsc_offset;
+static struct clocksource_base art_base_clk = {
+ .id = CSID_X86_ART,
+};
static bool have_art;
struct cyc2ns {
@@ -682,7 +682,7 @@ unsigned long native_calibrate_tsc(void)
* clock.
*/
if (crystal_khz == 0 &&
- boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_D)
+ boot_cpu_data.x86_vfm == INTEL_ATOM_GOLDMONT_D)
crystal_khz = 25000;
/*
@@ -713,7 +713,7 @@ unsigned long native_calibrate_tsc(void)
* For Atom SoCs TSC is the only reliable clocksource.
* Mark TSC reliable so no watchdog on it.
*/
- if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+ if (boot_cpu_data.x86_vfm == INTEL_ATOM_GOLDMONT)
setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
#ifdef CONFIG_X86_LOCAL_APIC
@@ -1074,7 +1074,7 @@ core_initcall(cpufreq_register_tsc_scaling);
*/
static void __init detect_art(void)
{
- unsigned int unused[2];
+ unsigned int unused;
if (boot_cpu_data.cpuid_level < ART_CPUID_LEAF)
return;
@@ -1089,13 +1089,14 @@ static void __init detect_art(void)
tsc_async_resets)
return;
- cpuid(ART_CPUID_LEAF, &art_to_tsc_denominator,
- &art_to_tsc_numerator, unused, unused+1);
+ cpuid(ART_CPUID_LEAF, &art_base_clk.denominator,
+ &art_base_clk.numerator, &art_base_clk.freq_khz, &unused);
- if (art_to_tsc_denominator < ART_MIN_DENOMINATOR)
+ art_base_clk.freq_khz /= KHZ;
+ if (art_base_clk.denominator < ART_MIN_DENOMINATOR)
return;
- rdmsrl(MSR_IA32_TSC_ADJUST, art_to_tsc_offset);
+ rdmsrl(MSR_IA32_TSC_ADJUST, art_base_clk.offset);
/* Make this sticky over multiple CPU init calls */
setup_force_cpu_cap(X86_FEATURE_ART);
@@ -1296,67 +1297,6 @@ int unsynchronized_tsc(void)
return 0;
}
-/*
- * Convert ART to TSC given numerator/denominator found in detect_art()
- */
-struct system_counterval_t convert_art_to_tsc(u64 art)
-{
- u64 tmp, res, rem;
-
- rem = do_div(art, art_to_tsc_denominator);
-
- res = art * art_to_tsc_numerator;
- tmp = rem * art_to_tsc_numerator;
-
- do_div(tmp, art_to_tsc_denominator);
- res += tmp + art_to_tsc_offset;
-
- return (struct system_counterval_t) {
- .cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
- .cycles = res,
- };
-}
-EXPORT_SYMBOL(convert_art_to_tsc);
-
-/**
- * convert_art_ns_to_tsc() - Convert ART in nanoseconds to TSC.
- * @art_ns: ART (Always Running Timer) in unit of nanoseconds
- *
- * PTM requires all timestamps to be in units of nanoseconds. When user
- * software requests a cross-timestamp, this function converts system timestamp
- * to TSC.
- *
- * This is valid when CPU feature flag X86_FEATURE_TSC_KNOWN_FREQ is set
- * indicating the tsc_khz is derived from CPUID[15H]. Drivers should check
- * that this flag is set before conversion to TSC is attempted.
- *
- * Return:
- * struct system_counterval_t - system counter value with the ID of the
- * corresponding clocksource:
- * cycles: System counter value
- * cs_id: The clocksource ID for validating comparability
- */
-
-struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
-{
- u64 tmp, res, rem;
-
- rem = do_div(art_ns, USEC_PER_SEC);
-
- res = art_ns * tsc_khz;
- tmp = rem * tsc_khz;
-
- do_div(tmp, USEC_PER_SEC);
- res += tmp;
-
- return (struct system_counterval_t) {
- .cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
- .cycles = res,
- };
-}
-EXPORT_SYMBOL(convert_art_ns_to_tsc);
-
-
static void tsc_refine_calibration_work(struct work_struct *work);
static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
/**
@@ -1458,8 +1398,10 @@ out:
if (tsc_unstable)
goto unreg;
- if (boot_cpu_has(X86_FEATURE_ART))
+ if (boot_cpu_has(X86_FEATURE_ART)) {
have_art = true;
+ clocksource_tsc.base = &art_base_clk;
+ }
clocksource_register_khz(&clocksource_tsc, tsc_khz);
unreg:
clocksource_unregister(&clocksource_tsc_early);
@@ -1484,8 +1426,10 @@ static int __init init_tsc_clocksource(void)
* the refined calibration and directly register it as a clocksource.
*/
if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
- if (boot_cpu_has(X86_FEATURE_ART))
+ if (boot_cpu_has(X86_FEATURE_ART)) {
have_art = true;
+ clocksource_tsc.base = &art_base_clk;
+ }
clocksource_register_khz(&clocksource_tsc, tsc_khz);
clocksource_unregister(&clocksource_tsc_early);
@@ -1509,10 +1453,12 @@ static bool __init determine_cpu_tsc_frequencies(bool early)
if (early) {
cpu_khz = x86_platform.calibrate_cpu();
- if (tsc_early_khz)
+ if (tsc_early_khz) {
tsc_khz = tsc_early_khz;
- else
+ } else {
tsc_khz = x86_platform.calibrate_tsc();
+ clocksource_tsc.freq_khz = tsc_khz;
+ }
} else {
/* We should not be here with non-native cpu calibration */
WARN_ON(x86_platform.calibrate_cpu != native_calibrate_cpu);
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 6555a857a1e6..deeb02825670 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -147,13 +147,13 @@ static const struct freq_desc freq_desc_lgm = {
};
static const struct x86_cpu_id tsc_msr_cpu_ids[] = {
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL_MID, &freq_desc_pnw),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL_TABLET,&freq_desc_clv),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &freq_desc_byt),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &freq_desc_tng),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &freq_desc_cht),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT_MID, &freq_desc_ann),
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT_NP, &freq_desc_lgm),
+ X86_MATCH_VFM(INTEL_ATOM_SALTWELL_MID, &freq_desc_pnw),
+ X86_MATCH_VFM(INTEL_ATOM_SALTWELL_TABLET, &freq_desc_clv),
+ X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &freq_desc_byt),
+ X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &freq_desc_tng),
+ X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &freq_desc_cht),
+ X86_MATCH_VFM(INTEL_ATOM_AIRMONT_MID, &freq_desc_ann),
+ X86_MATCH_VFM(INTEL_ATOM_AIRMONT_NP, &freq_desc_lgm),
{}
};
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 1123ef3ccf90..4334033658ed 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -193,11 +193,9 @@ bool tsc_store_and_check_tsc_adjust(bool bootcpu)
cur->warned = false;
/*
- * If a non-zero TSC value for socket 0 may be valid then the default
- * adjusted value cannot assumed to be zero either.
+ * The default adjust value cannot be assumed to be zero on any socket.
*/
- if (tsc_async_resets)
- cur->adjusted = bootval;
+ cur->adjusted = bootval;
/*
* Check whether this CPU is the first in a package to come up. In
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 6c07f6daaa22..5a952c5ea66b 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -12,6 +12,7 @@
#include <linux/ptrace.h>
#include <linux/uprobes.h>
#include <linux/uaccess.h>
+#include <linux/syscalls.h>
#include <linux/kdebug.h>
#include <asm/processor.h>
@@ -308,6 +309,122 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool
}
#ifdef CONFIG_X86_64
+
+asm (
+ ".pushsection .rodata\n"
+ ".global uretprobe_trampoline_entry\n"
+ "uretprobe_trampoline_entry:\n"
+ "pushq %rax\n"
+ "pushq %rcx\n"
+ "pushq %r11\n"
+ "movq $" __stringify(__NR_uretprobe) ", %rax\n"
+ "syscall\n"
+ ".global uretprobe_syscall_check\n"
+ "uretprobe_syscall_check:\n"
+ "popq %r11\n"
+ "popq %rcx\n"
+
+ /* The uretprobe syscall replaces stored %rax value with final
+ * return address, so we don't restore %rax in here and just
+ * call ret.
+ */
+ "retq\n"
+ ".global uretprobe_trampoline_end\n"
+ "uretprobe_trampoline_end:\n"
+ ".popsection\n"
+);
+
+extern u8 uretprobe_trampoline_entry[];
+extern u8 uretprobe_trampoline_end[];
+extern u8 uretprobe_syscall_check[];
+
+void *arch_uprobe_trampoline(unsigned long *psize)
+{
+ static uprobe_opcode_t insn = UPROBE_SWBP_INSN;
+ struct pt_regs *regs = task_pt_regs(current);
+
+ /*
+ * At the moment the uretprobe syscall trampoline is supported
+ * only for native 64-bit process, the compat process still uses
+ * standard breakpoint.
+ */
+ if (user_64bit_mode(regs)) {
+ *psize = uretprobe_trampoline_end - uretprobe_trampoline_entry;
+ return uretprobe_trampoline_entry;
+ }
+
+ *psize = UPROBE_SWBP_INSN_SIZE;
+ return &insn;
+}
+
+static unsigned long trampoline_check_ip(void)
+{
+ unsigned long tramp = uprobe_get_trampoline_vaddr();
+
+ return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
+}
+
+SYSCALL_DEFINE0(uretprobe)
+{
+ struct pt_regs *regs = task_pt_regs(current);
+ unsigned long err, ip, sp, r11_cx_ax[3];
+
+ if (regs->ip != trampoline_check_ip())
+ goto sigill;
+
+ err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
+ if (err)
+ goto sigill;
+
+ /* expose the "right" values of r11/cx/ax/sp to uprobe_consumer/s */
+ regs->r11 = r11_cx_ax[0];
+ regs->cx = r11_cx_ax[1];
+ regs->ax = r11_cx_ax[2];
+ regs->sp += sizeof(r11_cx_ax);
+ regs->orig_ax = -1;
+
+ ip = regs->ip;
+ sp = regs->sp;
+
+ uprobe_handle_trampoline(regs);
+
+ /*
+ * Some of the uprobe consumers has changed sp, we can do nothing,
+ * just return via iret.
+ * .. or shadow stack is enabled, in which case we need to skip
+ * return through the user space stack address.
+ */
+ if (regs->sp != sp || shstk_is_enabled())
+ return regs->ax;
+ regs->sp -= sizeof(r11_cx_ax);
+
+ /* for the case uprobe_consumer has changed r11/cx */
+ r11_cx_ax[0] = regs->r11;
+ r11_cx_ax[1] = regs->cx;
+
+ /*
+ * ax register is passed through as return value, so we can use
+ * its space on stack for ip value and jump to it through the
+ * trampoline's ret instruction
+ */
+ r11_cx_ax[2] = regs->ip;
+ regs->ip = ip;
+
+ err = copy_to_user((void __user *)regs->sp, r11_cx_ax, sizeof(r11_cx_ax));
+ if (err)
+ goto sigill;
+
+ /* ensure sysret, see do_syscall_64() */
+ regs->r11 = regs->flags;
+ regs->cx = regs->ip;
+
+ return regs->ax;
+
+sigill:
+ force_sig(SIGILL);
+ return -1;
+}
+
/*
* If arch_uprobe->insn doesn't use rip-relative addressing, return
* immediately. Otherwise, rewrite the instruction so that it accesses
@@ -1076,8 +1193,13 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs
return orig_ret_vaddr;
nleft = copy_to_user((void __user *)regs->sp, &trampoline_vaddr, rasize);
- if (likely(!nleft))
+ if (likely(!nleft)) {
+ if (shstk_update_last_frame(trampoline_vaddr)) {
+ force_sig(SIGSEGV);
+ return -1;
+ }
return orig_ret_vaddr;
+ }
if (nleft != rasize) {
pr_err("return address clobbered: pid=%d, %%sp=%#lx, %%ip=%#lx\n",
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 56451fd2099e..6e73403e874f 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -15,11 +15,7 @@
* put it inside the section definition.
*/
-#ifdef CONFIG_X86_32
-#define LOAD_OFFSET __PAGE_OFFSET
-#else
#define LOAD_OFFSET __START_KERNEL_map
-#endif
#define RUNTIME_DISCARD_EXIT
#define EMITS_PT_NOTE
@@ -114,11 +110,10 @@ PHDRS {
SECTIONS
{
+ . = __START_KERNEL;
#ifdef CONFIG_X86_32
- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
phys_startup_32 = ABSOLUTE(startup_32 - LOAD_OFFSET);
#else
- . = __START_KERNEL;
phys_startup_64 = ABSOLUTE(startup_64 - LOAD_OFFSET);
#endif
@@ -172,6 +167,9 @@ SECTIONS
/* init_task */
INIT_TASK_DATA(THREAD_SIZE)
+ /* equivalent to task_pt_regs(&init_task) */
+ __top_init_kernel_stack = __end_init_stack - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE;
+
#ifdef CONFIG_X86_32
/* 32 bit has nosave before _edata */
NOSAVE_DATA
@@ -359,6 +357,9 @@ SECTIONS
PERCPU_SECTION(INTERNODE_CACHE_BYTES)
#endif
+ RUNTIME_CONST(shift, d_hash_shift)
+ RUNTIME_CONST(ptr, dentry_hashtable)
+
. = ALIGN(PAGE_SIZE);
/* freed after init ends here */
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index d5dc5a92635a..82b128d3f309 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -134,10 +134,12 @@ struct x86_cpuinit_ops x86_cpuinit = {
static void default_nmi_init(void) { };
-static bool enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { return true; }
-static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return true; }
+static int enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { return 0; }
+static int enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return 0; }
static bool enc_tlb_flush_required_noop(bool enc) { return false; }
static bool enc_cache_flush_required_noop(void) { return false; }
+static void enc_kexec_begin_noop(void) {}
+static void enc_kexec_finish_noop(void) {}
static bool is_private_mmio_noop(u64 addr) {return false; }
struct x86_platform_ops x86_platform __ro_after_init = {
@@ -161,6 +163,8 @@ struct x86_platform_ops x86_platform __ro_after_init = {
.enc_status_change_finish = enc_status_change_finish_noop,
.enc_tlb_flush_required = enc_tlb_flush_required_noop,
.enc_cache_flush_required = enc_cache_flush_required_noop,
+ .enc_kexec_begin = enc_kexec_begin_noop,
+ .enc_kexec_finish = enc_kexec_finish_noop,
},
};
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 0ebdd088f28b..4287a8071a3a 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -44,6 +44,8 @@ config KVM
select KVM_VFIO
select HAVE_KVM_PM_NOTIFIER if PM
select KVM_GENERIC_HARDWARE_ENABLING
+ select KVM_GENERIC_PRE_FAULT_MEMORY
+ select KVM_WERROR if WERROR
help
Support hosting fully virtualized guest machines using hardware
virtualization extensions. You will need a fairly recent
@@ -66,7 +68,7 @@ config KVM_WERROR
# FRAME_WARN, i.e. KVM_WERROR=y with KASAN=y requires special tuning.
# Building KVM with -Werror and KASAN is still doable via enabling
# the kernel-wide WERROR=y.
- depends on KVM && EXPERT && !KASAN
+ depends on KVM && ((EXPERT && !KASAN) || WERROR)
help
Add -Werror to the build flags for KVM.
@@ -95,6 +97,21 @@ config KVM_INTEL
To compile this as a module, choose M here: the module
will be called kvm-intel.
+config KVM_INTEL_PROVE_VE
+ bool "Check that guests do not receive #VE exceptions"
+ depends on KVM_INTEL && EXPERT
+ help
+ Checks that KVM's page table management code will not incorrectly
+ let guests receive a virtualization exception. Virtualization
+ exceptions will be trapped by the hypervisor rather than injected
+ in the guest.
+
+ Note: some CPUs appear to generate spurious EPT Violations #VEs
+ that trigger KVM's WARN, in particular with eptad=0 and/or nested
+ virtualization.
+
+ If unsure, say N.
+
config X86_SGX_KVM
bool "Software Guard eXtensions (SGX) Virtualization"
depends on X86_SGX && KVM_INTEL
@@ -123,6 +140,9 @@ config KVM_AMD_SEV
depends on KVM_AMD && X86_64
depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m)
select ARCH_HAS_CC_PLATFORM
+ select KVM_GENERIC_PRIVATE_MEM
+ select HAVE_KVM_GMEM_PREPARE
+ select HAVE_KVM_GMEM_INVALIDATE
help
Provides support for launching Encrypted VMs (SEV) and Encrypted VMs
with Encrypted State (SEV-ES) on AMD processors.
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index addc44fc7187..5494669a055a 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -16,14 +16,15 @@ kvm-$(CONFIG_KVM_XEN) += xen.o
kvm-$(CONFIG_KVM_SMM) += smm.o
kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \
- vmx/nested.o vmx/posted_intr.o
+ vmx/nested.o vmx/posted_intr.o vmx/main.o
kvm-intel-$(CONFIG_X86_SGX_KVM) += vmx/sgx.o
kvm-intel-$(CONFIG_KVM_HYPERV) += vmx/hyperv.o vmx/hyperv_evmcs.o
-kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o \
- svm/sev.o
-kvm-amd-$(CONFIG_KVM_HYPERV) += svm/hyperv.o
+kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o
+
+kvm-amd-$(CONFIG_KVM_AMD_SEV) += svm/sev.o
+kvm-amd-$(CONFIG_KVM_HYPERV) += svm/hyperv.o
ifdef CONFIG_HYPERV
kvm-y += kvm_onhyperv.o
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 77352a4abd87..2617be544480 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -335,6 +335,18 @@ static bool kvm_cpuid_has_hyperv(struct kvm_cpuid_entry2 *entries, int nent)
#endif
}
+static bool guest_cpuid_is_amd_or_hygon(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *entry;
+
+ entry = kvm_find_cpuid_entry(vcpu, 0);
+ if (!entry)
+ return false;
+
+ return is_guest_vendor_amd(entry->ebx, entry->ecx, entry->edx) ||
+ is_guest_vendor_hygon(entry->ebx, entry->ecx, entry->edx);
+}
+
static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
@@ -388,7 +400,7 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
vcpu->arch.cpuid_nent));
/* Invoke the vendor callback only after the above state is updated. */
- static_call(kvm_x86_vcpu_after_set_cpuid)(vcpu);
+ kvm_x86_call(vcpu_after_set_cpuid)(vcpu);
/*
* Except for the MMU, which needs to do its thing any vendor specific
@@ -772,7 +784,7 @@ void kvm_set_cpu_caps(void)
kvm_cpu_cap_mask(CPUID_8000_000A_EDX, 0);
kvm_cpu_cap_mask(CPUID_8000_001F_EAX,
- 0 /* SME */ | F(SEV) | 0 /* VM_PAGE_FLUSH */ | F(SEV_ES) |
+ 0 /* SME */ | 0 /* SEV */ | 0 /* VM_PAGE_FLUSH */ | 0 /* SEV_ES */ |
F(SME_COHERENT));
kvm_cpu_cap_mask(CPUID_8000_0021_EAX,
@@ -1232,9 +1244,22 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->eax = entry->ebx = entry->ecx = 0;
break;
case 0x80000008: {
- unsigned g_phys_as = (entry->eax >> 16) & 0xff;
- unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
- unsigned phys_as = entry->eax & 0xff;
+ /*
+ * GuestPhysAddrSize (EAX[23:16]) is intended for software
+ * use.
+ *
+ * KVM's ABI is to report the effective MAXPHYADDR for the
+ * guest in PhysAddrSize (phys_as), and the maximum
+ * *addressable* GPA in GuestPhysAddrSize (g_phys_as).
+ *
+ * GuestPhysAddrSize is valid if and only if TDP is enabled,
+ * in which case the max GPA that can be addressed by KVM may
+ * be less than the max GPA that can be legally generated by
+ * the guest, e.g. if MAXPHYADDR>48 but the CPU doesn't
+ * support 5-level TDP.
+ */
+ unsigned int virt_as = max((entry->eax >> 8) & 0xff, 48U);
+ unsigned int phys_as, g_phys_as;
/*
* If TDP (NPT) is disabled use the adjusted host MAXPHYADDR as
@@ -1242,16 +1267,24 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
* reductions in MAXPHYADDR for memory encryption affect shadow
* paging, too.
*
- * If TDP is enabled but an explicit guest MAXPHYADDR is not
- * provided, use the raw bare metal MAXPHYADDR as reductions to
- * the HPAs do not affect GPAs.
+ * If TDP is enabled, use the raw bare metal MAXPHYADDR as
+ * reductions to the HPAs do not affect GPAs. The max
+ * addressable GPA is the same as the max effective GPA, except
+ * that it's capped at 48 bits if 5-level TDP isn't supported
+ * (hardware processes bits 51:48 only when walking the fifth
+ * level page table).
*/
- if (!tdp_enabled)
- g_phys_as = boot_cpu_data.x86_phys_bits;
- else if (!g_phys_as)
+ if (!tdp_enabled) {
+ phys_as = boot_cpu_data.x86_phys_bits;
+ g_phys_as = 0;
+ } else {
+ phys_as = entry->eax & 0xff;
g_phys_as = phys_as;
+ if (kvm_mmu_get_max_tdp_level() < 5)
+ g_phys_as = min(g_phys_as, 48);
+ }
- entry->eax = g_phys_as | (virt_as << 8);
+ entry->eax = phys_as | (virt_as << 8) | (g_phys_as << 16);
entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
entry->edx = 0;
cpuid_entry_override(entry, CPUID_8000_0008_EBX);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index 23dbb9eb277c..41697cca354e 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -102,24 +102,6 @@ static __always_inline void guest_cpuid_clear(struct kvm_vcpu *vcpu,
*reg &= ~__feature_bit(x86_feature);
}
-static inline bool guest_cpuid_is_amd_or_hygon(struct kvm_vcpu *vcpu)
-{
- struct kvm_cpuid_entry2 *best;
-
- best = kvm_find_cpuid_entry(vcpu, 0);
- return best &&
- (is_guest_vendor_amd(best->ebx, best->ecx, best->edx) ||
- is_guest_vendor_hygon(best->ebx, best->ecx, best->edx));
-}
-
-static inline bool guest_cpuid_is_intel(struct kvm_vcpu *vcpu)
-{
- struct kvm_cpuid_entry2 *best;
-
- best = kvm_find_cpuid_entry(vcpu, 0);
- return best && is_guest_vendor_intel(best->ebx, best->ecx, best->edx);
-}
-
static inline bool guest_cpuid_is_amd_compatible(struct kvm_vcpu *vcpu)
{
return vcpu->arch.is_amd_compatible;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 5d4c86133453..e72aed25d721 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1069,7 +1069,7 @@ static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
asm("push %[flags]; popf; " CALL_NOSPEC
- : "=a"(rc) : [thunk_target]"r"(fop), [flags]"r"(flags));
+ : "=a"(rc), ASM_CALL_CONSTRAINT : [thunk_target]"r"(fop), [flags]"r"(flags));
return rc;
}
@@ -2354,50 +2354,6 @@ setup_syscalls_segments(struct desc_struct *cs, struct desc_struct *ss)
ss->avl = 0;
}
-static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
-{
- u32 eax, ebx, ecx, edx;
-
- eax = ecx = 0;
- ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
- return is_guest_vendor_intel(ebx, ecx, edx);
-}
-
-static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
-{
- const struct x86_emulate_ops *ops = ctxt->ops;
- u32 eax, ebx, ecx, edx;
-
- /*
- * syscall should always be enabled in longmode - so only become
- * vendor specific (cpuid) if other modes are active...
- */
- if (ctxt->mode == X86EMUL_MODE_PROT64)
- return true;
-
- eax = 0x00000000;
- ecx = 0x00000000;
- ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
- /*
- * remark: Intel CPUs only support "syscall" in 64bit longmode. Also a
- * 64bit guest with a 32bit compat-app running will #UD !! While this
- * behaviour can be fixed (by emulating) into AMD response - CPUs of
- * AMD can't behave like Intel.
- */
- if (is_guest_vendor_intel(ebx, ecx, edx))
- return false;
-
- if (is_guest_vendor_amd(ebx, ecx, edx) ||
- is_guest_vendor_hygon(ebx, ecx, edx))
- return true;
-
- /*
- * default: (not Intel, not AMD, not Hygon), apply Intel's
- * stricter rules...
- */
- return false;
-}
-
static int em_syscall(struct x86_emulate_ctxt *ctxt)
{
const struct x86_emulate_ops *ops = ctxt->ops;
@@ -2411,7 +2367,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
ctxt->mode == X86EMUL_MODE_VM86)
return emulate_ud(ctxt);
- if (!(em_syscall_is_enabled(ctxt)))
+ /*
+ * Intel compatible CPUs only support SYSCALL in 64-bit mode, whereas
+ * AMD allows SYSCALL in any flavor of protected mode. Note, it's
+ * infeasible to emulate Intel behavior when running on AMD hardware,
+ * as SYSCALL won't fault in the "wrong" mode, i.e. there is no #UD
+ * for KVM to trap-and-emulate, unlike emulating AMD on Intel.
+ */
+ if (ctxt->mode != X86EMUL_MODE_PROT64 &&
+ ctxt->ops->guest_cpuid_is_intel_compatible(ctxt))
return emulate_ud(ctxt);
ops->get_msr(ctxt, MSR_EFER, &efer);
@@ -2471,11 +2435,11 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
return emulate_gp(ctxt, 0);
/*
- * Not recognized on AMD in compat mode (but is recognized in legacy
- * mode).
+ * Intel's architecture allows SYSENTER in compatibility mode, but AMD
+ * does not. Note, AMD does allow SYSENTER in legacy protected mode.
*/
- if ((ctxt->mode != X86EMUL_MODE_PROT64) && (efer & EFER_LMA)
- && !vendor_intel(ctxt))
+ if ((ctxt->mode != X86EMUL_MODE_PROT64) && (efer & EFER_LMA) &&
+ !ctxt->ops->guest_cpuid_is_intel_compatible(ctxt))
return emulate_ud(ctxt);
/* sysenter/sysexit have not been tested in 64bit mode. */
@@ -2647,7 +2611,14 @@ static void string_registers_quirk(struct x86_emulate_ctxt *ctxt)
* manner when ECX is zero due to REP-string optimizations.
*/
#ifdef CONFIG_X86_64
- if (ctxt->ad_bytes != 4 || !vendor_intel(ctxt))
+ u32 eax, ebx, ecx, edx;
+
+ if (ctxt->ad_bytes != 4)
+ return;
+
+ eax = ecx = 0;
+ ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
+ if (!is_guest_vendor_intel(ebx, ecx, edx))
return;
*reg_write(ctxt, VCPU_REGS_RCX) = 0;
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 8a47f8541eab..4f0a94346d00 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1417,7 +1417,7 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
}
/* vmcall/vmmcall */
- static_call(kvm_x86_patch_hypercall)(vcpu, instructions + i);
+ kvm_x86_call(patch_hypercall)(vcpu, instructions + i);
i += 3;
/* ret */
@@ -1737,7 +1737,8 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
data = (u64)vcpu->arch.virtual_tsc_khz * 1000;
break;
case HV_X64_MSR_APIC_FREQUENCY:
- data = APIC_BUS_FREQUENCY;
+ data = div64_u64(1000000000ULL,
+ vcpu->kvm->arch.apic_bus_cycle_ns);
break;
default:
kvm_pr_unimpl_rdmsr(vcpu, msr);
@@ -1985,7 +1986,7 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
*/
gva = entries[i] & PAGE_MASK;
for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++)
- static_call(kvm_x86_flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE);
+ kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE);
++vcpu->stat.tlb_flush;
}
@@ -2526,7 +2527,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
* hypercall generates UD from non zero cpl and real mode
* per HYPER-V spec
*/
- if (static_call(kvm_x86_get_cpl)(vcpu) != 0 || !is_protmode(vcpu)) {
+ if (kvm_x86_call(get_cpl)(vcpu) != 0 || !is_protmode(vcpu)) {
kvm_queue_exception(vcpu, UD_VECTOR);
return 1;
}
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index ad9ca8a60144..3d7eb11d0e45 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -157,7 +157,7 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
{
__kvm_migrate_apic_timer(vcpu);
__kvm_migrate_pit_timer(vcpu);
- static_call_cond(kvm_x86_migrate_timers)(vcpu);
+ kvm_x86_call(migrate_timers)(vcpu);
}
bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index c2d7cfe82d00..76d46b2f41dd 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -106,7 +106,6 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu);
int apic_has_pending_timer(struct kvm_vcpu *vcpu);
int kvm_setup_default_irq_routing(struct kvm *kvm);
-int kvm_setup_empty_irq_routing(struct kvm *kvm);
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
struct kvm_lapic_irq *irq,
struct dest_map *dest_map);
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 68f3f6c26046..8136695f7b96 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -395,13 +395,6 @@ int kvm_setup_default_irq_routing(struct kvm *kvm)
ARRAY_SIZE(default_routing), 0);
}
-static const struct kvm_irq_routing_entry empty_routing[] = {};
-
-int kvm_setup_empty_irq_routing(struct kvm *kvm)
-{
- return kvm_set_irq_routing(kvm, empty_routing, 0, 0);
-}
-
void kvm_arch_post_irq_routing_update(struct kvm *kvm)
{
if (!irqchip_split(kvm))
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
index 75eae9c4998a..b1eb46e26b2e 100644
--- a/arch/x86/kvm/kvm_cache_regs.h
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -98,7 +98,7 @@ static inline unsigned long kvm_register_read_raw(struct kvm_vcpu *vcpu, int reg
return 0;
if (!kvm_register_is_available(vcpu, reg))
- static_call(kvm_x86_cache_reg)(vcpu, reg);
+ kvm_x86_call(cache_reg)(vcpu, reg);
return vcpu->arch.regs[reg];
}
@@ -138,7 +138,7 @@ static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
might_sleep(); /* on svm */
if (!kvm_register_is_available(vcpu, VCPU_EXREG_PDPTR))
- static_call(kvm_x86_cache_reg)(vcpu, VCPU_EXREG_PDPTR);
+ kvm_x86_call(cache_reg)(vcpu, VCPU_EXREG_PDPTR);
return vcpu->arch.walk_mmu->pdptrs[index];
}
@@ -153,7 +153,7 @@ static inline ulong kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask)
ulong tmask = mask & KVM_POSSIBLE_CR0_GUEST_BITS;
if ((tmask & vcpu->arch.cr0_guest_owned_bits) &&
!kvm_register_is_available(vcpu, VCPU_EXREG_CR0))
- static_call(kvm_x86_cache_reg)(vcpu, VCPU_EXREG_CR0);
+ kvm_x86_call(cache_reg)(vcpu, VCPU_EXREG_CR0);
return vcpu->arch.cr0 & mask;
}
@@ -175,7 +175,7 @@ static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask)
ulong tmask = mask & KVM_POSSIBLE_CR4_GUEST_BITS;
if ((tmask & vcpu->arch.cr4_guest_owned_bits) &&
!kvm_register_is_available(vcpu, VCPU_EXREG_CR4))
- static_call(kvm_x86_cache_reg)(vcpu, VCPU_EXREG_CR4);
+ kvm_x86_call(cache_reg)(vcpu, VCPU_EXREG_CR4);
return vcpu->arch.cr4 & mask;
}
@@ -190,7 +190,7 @@ static __always_inline bool kvm_is_cr4_bit_set(struct kvm_vcpu *vcpu,
static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu)
{
if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3))
- static_call(kvm_x86_cache_reg)(vcpu, VCPU_EXREG_CR3);
+ kvm_x86_call(cache_reg)(vcpu, VCPU_EXREG_CR3);
return vcpu->arch.cr3;
}
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index 5382646162a3..55a18e2f2dcd 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -26,6 +26,7 @@ struct x86_exception {
bool nested_page_fault;
u64 address; /* cr2 or nested page fault gpa */
u8 async_page_fault;
+ unsigned long exit_qualification;
};
/*
@@ -222,6 +223,7 @@ struct x86_emulate_ops {
bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
bool (*guest_has_rdpid)(struct x86_emulate_ctxt *ctxt);
+ bool (*guest_cpuid_is_intel_compatible)(struct x86_emulate_ctxt *ctxt);
void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ebf41023be38..a7172ba59ad2 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -59,7 +59,17 @@
#define MAX_APIC_VECTOR 256
#define APIC_VECTORS_PER_REG 32
-static bool lapic_timer_advance_dynamic __read_mostly;
+/*
+ * Enable local APIC timer advancement (tscdeadline mode only) with adaptive
+ * tuning. When enabled, KVM programs the host timer event to fire early, i.e.
+ * before the deadline expires, to account for the delay between taking the
+ * VM-Exit (to inject the guest event) and the subsequent VM-Enter to resume
+ * the guest, i.e. so that the interrupt arrives in the guest with minimal
+ * latency relative to the deadline programmed by the guest.
+ */
+static bool lapic_timer_advance __read_mostly = true;
+module_param(lapic_timer_advance, bool, 0444);
+
#define LAPIC_TIMER_ADVANCE_ADJUST_MIN 100 /* clock cycles */
#define LAPIC_TIMER_ADVANCE_ADJUST_MAX 10000 /* clock cycles */
#define LAPIC_TIMER_ADVANCE_NS_INIT 1000
@@ -728,8 +738,8 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
if (unlikely(apic->apicv_active)) {
/* need to update RVI */
kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR);
- static_call_cond(kvm_x86_hwapic_irr_update)(apic->vcpu,
- apic_find_highest_irr(apic));
+ kvm_x86_call(hwapic_irr_update)(apic->vcpu,
+ apic_find_highest_irr(apic));
} else {
apic->irr_pending = false;
kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR);
@@ -755,7 +765,7 @@ static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
* just set SVI.
*/
if (unlikely(apic->apicv_active))
- static_call_cond(kvm_x86_hwapic_isr_update)(vec);
+ kvm_x86_call(hwapic_isr_update)(vec);
else {
++apic->isr_count;
BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
@@ -800,7 +810,7 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
* and must be left alone.
*/
if (unlikely(apic->apicv_active))
- static_call_cond(kvm_x86_hwapic_isr_update)(apic_find_highest_isr(apic));
+ kvm_x86_call(hwapic_isr_update)(apic_find_highest_isr(apic));
else {
--apic->isr_count;
BUG_ON(apic->isr_count < 0);
@@ -936,7 +946,7 @@ static int apic_has_interrupt_for_ppr(struct kvm_lapic *apic, u32 ppr)
{
int highest_irr;
if (kvm_x86_ops.sync_pir_to_irr)
- highest_irr = static_call(kvm_x86_sync_pir_to_irr)(apic->vcpu);
+ highest_irr = kvm_x86_call(sync_pir_to_irr)(apic->vcpu);
else
highest_irr = apic_find_highest_irr(apic);
if (highest_irr == -1 || (highest_irr & 0xF0) <= ppr)
@@ -1328,8 +1338,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
apic->regs + APIC_TMR);
}
- static_call(kvm_x86_deliver_interrupt)(apic, delivery_mode,
- trig_mode, vector);
+ kvm_x86_call(deliver_interrupt)(apic, delivery_mode,
+ trig_mode, vector);
break;
case APIC_DM_REMRD:
@@ -1547,7 +1557,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
remaining = 0;
ns = mod_64(ktime_to_ns(remaining), apic->lapic_timer.period);
- return div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->divide_count));
+ return div64_u64(ns, (apic->vcpu->kvm->arch.apic_bus_cycle_ns *
+ apic->divide_count));
}
static void __report_tpr_access(struct kvm_lapic *apic, bool write)
@@ -1854,16 +1865,14 @@ static void __kvm_wait_lapic_expire(struct kvm_vcpu *vcpu)
guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
trace_kvm_wait_lapic_expire(vcpu->vcpu_id, guest_tsc - tsc_deadline);
- if (lapic_timer_advance_dynamic) {
- adjust_lapic_timer_advance(vcpu, guest_tsc - tsc_deadline);
- /*
- * If the timer fired early, reread the TSC to account for the
- * overhead of the above adjustment to avoid waiting longer
- * than is necessary.
- */
- if (guest_tsc < tsc_deadline)
- guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
- }
+ adjust_lapic_timer_advance(vcpu, guest_tsc - tsc_deadline);
+
+ /*
+ * If the timer fired early, reread the TSC to account for the overhead
+ * of the above adjustment to avoid waiting longer than is necessary.
+ */
+ if (guest_tsc < tsc_deadline)
+ guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
if (guest_tsc < tsc_deadline)
__wait_lapic_expire(vcpu, tsc_deadline - guest_tsc);
@@ -1965,7 +1974,8 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic)
static inline u64 tmict_to_ns(struct kvm_lapic *apic, u32 tmict)
{
- return (u64)tmict * APIC_BUS_CYCLE_NS * (u64)apic->divide_count;
+ return (u64)tmict * apic->vcpu->kvm->arch.apic_bus_cycle_ns *
+ (u64)apic->divide_count;
}
static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor)
@@ -2095,7 +2105,7 @@ static void cancel_hv_timer(struct kvm_lapic *apic)
{
WARN_ON(preemptible());
WARN_ON(!apic->lapic_timer.hv_timer_in_use);
- static_call(kvm_x86_cancel_hv_timer)(apic->vcpu);
+ kvm_x86_call(cancel_hv_timer)(apic->vcpu);
apic->lapic_timer.hv_timer_in_use = false;
}
@@ -2112,7 +2122,7 @@ static bool start_hv_timer(struct kvm_lapic *apic)
if (!ktimer->tscdeadline)
return false;
- if (static_call(kvm_x86_set_hv_timer)(vcpu, ktimer->tscdeadline, &expired))
+ if (kvm_x86_call(set_hv_timer)(vcpu, ktimer->tscdeadline, &expired))
return false;
ktimer->hv_timer_in_use = true;
@@ -2567,7 +2577,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
if ((old_value ^ value) & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE)) {
kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
- static_call_cond(kvm_x86_set_virtual_apic_mode)(vcpu);
+ kvm_x86_call(set_virtual_apic_mode)(vcpu);
}
apic->base_address = apic->vcpu->arch.apic_base &
@@ -2677,7 +2687,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
u64 msr_val;
int i;
- static_call_cond(kvm_x86_apicv_pre_state_restore)(vcpu);
+ kvm_x86_call(apicv_pre_state_restore)(vcpu);
if (!init_event) {
msr_val = APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE;
@@ -2732,9 +2742,9 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
vcpu->arch.pv_eoi.msr_val = 0;
apic_update_ppr(apic);
if (apic->apicv_active) {
- static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
- static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, -1);
- static_call_cond(kvm_x86_hwapic_isr_update)(-1);
+ kvm_x86_call(apicv_post_state_restore)(vcpu);
+ kvm_x86_call(hwapic_irr_update)(vcpu, -1);
+ kvm_x86_call(hwapic_isr_update)(-1);
}
vcpu->arch.apic_arb_prio = 0;
@@ -2812,7 +2822,7 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)
return HRTIMER_NORESTART;
}
-int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
+int kvm_create_lapic(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic;
@@ -2830,7 +2840,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
vcpu->arch.apic = apic;
if (kvm_x86_ops.alloc_apic_backing_page)
- apic->regs = static_call(kvm_x86_alloc_apic_backing_page)(vcpu);
+ apic->regs = kvm_x86_call(alloc_apic_backing_page)(vcpu);
else
apic->regs = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT);
if (!apic->regs) {
@@ -2845,13 +2855,8 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
HRTIMER_MODE_ABS_HARD);
apic->lapic_timer.timer.function = apic_timer_fn;
- if (timer_advance_ns == -1) {
+ if (lapic_timer_advance)
apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT;
- lapic_timer_advance_dynamic = true;
- } else {
- apic->lapic_timer.timer_advance_ns = timer_advance_ns;
- lapic_timer_advance_dynamic = false;
- }
/*
* Stuff the APIC ENABLE bit in lieu of temporarily incrementing
@@ -3014,7 +3019,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
struct kvm_lapic *apic = vcpu->arch.apic;
int r;
- static_call_cond(kvm_x86_apicv_pre_state_restore)(vcpu);
+ kvm_x86_call(apicv_pre_state_restore)(vcpu);
kvm_lapic_set_base(vcpu, vcpu->arch.apic_base);
/* set SPIV separately to get count of SW disabled APICs right */
@@ -3041,9 +3046,10 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
kvm_lapic_set_reg(apic, APIC_TMCCT, 0);
kvm_apic_update_apicv(vcpu);
if (apic->apicv_active) {
- static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
- static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
- static_call_cond(kvm_x86_hwapic_isr_update)(apic_find_highest_isr(apic));
+ kvm_x86_call(apicv_post_state_restore)(vcpu);
+ kvm_x86_call(hwapic_irr_update)(vcpu,
+ apic_find_highest_irr(apic));
+ kvm_x86_call(hwapic_isr_update)(apic_find_highest_isr(apic));
}
kvm_make_request(KVM_REQ_EVENT, vcpu);
if (ioapic_in_kernel(vcpu->kvm))
@@ -3331,7 +3337,8 @@ int kvm_apic_accept_events(struct kvm_vcpu *vcpu)
/* evaluate pending_events before reading the vector */
smp_rmb();
sipi_vector = apic->sipi_vector;
- static_call(kvm_x86_vcpu_deliver_sipi_vector)(vcpu, sipi_vector);
+ kvm_x86_call(vcpu_deliver_sipi_vector)(vcpu,
+ sipi_vector);
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
}
}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 0a0ea4b5dd8c..7ef8ae73e82d 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -16,8 +16,7 @@
#define APIC_DEST_NOSHORT 0x0
#define APIC_DEST_MASK 0x800
-#define APIC_BUS_CYCLE_NS 1
-#define APIC_BUS_FREQUENCY (1000000000ULL / APIC_BUS_CYCLE_NS)
+#define APIC_BUS_CYCLE_NS_DEFAULT 1
#define APIC_BROADCAST 0xFF
#define X2APIC_BROADCAST 0xFFFFFFFFul
@@ -85,7 +84,7 @@ struct kvm_lapic {
struct dest_map;
-int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns);
+int kvm_create_lapic(struct kvm_vcpu *vcpu);
void kvm_free_lapic(struct kvm_vcpu *vcpu);
int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu);
@@ -236,7 +235,7 @@ static inline bool kvm_apic_has_pending_init_or_sipi(struct kvm_vcpu *vcpu)
static inline bool kvm_apic_init_sipi_allowed(struct kvm_vcpu *vcpu)
{
return !is_smm(vcpu) &&
- !static_call(kvm_x86_apic_init_signal_blocked)(vcpu);
+ !kvm_x86_call(apic_init_signal_blocked)(vcpu);
}
static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 60f21bb4c27b..4341e0e28571 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -57,12 +57,6 @@ static __always_inline u64 rsvd_bits(int s, int e)
return ((2ULL << (e - s)) - 1) << s;
}
-/*
- * 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 gfn_t kvm_mmu_max_gfn(void)
{
/*
@@ -76,29 +70,12 @@ static inline gfn_t kvm_mmu_max_gfn(void)
* than hardware's real MAXPHYADDR. Using the host MAXPHYADDR
* disallows such SPTEs entirely and simplifies the TDP MMU.
*/
- int max_gpa_bits = likely(tdp_enabled) ? shadow_phys_bits : 52;
+ int max_gpa_bits = likely(tdp_enabled) ? kvm_host.maxphyaddr : 52;
return (1ULL << (max_gpa_bits - PAGE_SHIFT)) - 1;
}
-static inline 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;
-}
+u8 kvm_mmu_get_max_tdp_level(void);
void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask);
void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_mask);
@@ -161,8 +138,8 @@ static inline void kvm_mmu_load_pgd(struct kvm_vcpu *vcpu)
if (!VALID_PAGE(root_hpa))
return;
- static_call(kvm_x86_load_mmu_pgd)(vcpu, root_hpa,
- vcpu->arch.mmu->root_role.level);
+ kvm_x86_call(load_mmu_pgd)(vcpu, root_hpa,
+ vcpu->arch.mmu->root_role.level);
}
static inline void kvm_mmu_refresh_passthrough_bits(struct kvm_vcpu *vcpu,
@@ -197,7 +174,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
{
/* strip nested paging fault error codes */
unsigned int pfec = access;
- unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
+ unsigned long rflags = kvm_x86_call(get_rflags)(vcpu);
/*
* For explicit supervisor accesses, SMAP is disabled if EFLAGS.AC = 1.
@@ -213,7 +190,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
*/
u64 implicit_access = access & PFERR_IMPLICIT_ACCESS;
bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC;
- int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1;
+ int index = (pfec | (not_smap ? PFERR_RSVD_MASK : 0)) >> 1;
u32 errcode = PFERR_PRESENT_MASK;
bool fault;
@@ -234,8 +211,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
pkru_bits = (vcpu->arch.pkru >> (pte_pkey * 2)) & 3;
/* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */
- offset = (pfec & ~1) +
- ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT));
+ offset = (pfec & ~1) | ((pte_access & PT_USER_MASK) ? PFERR_RSVD_MASK : 0);
pkru_bits &= mmu->pkru_mask >> offset;
errcode |= -pkru_bits & PFERR_PK_MASK;
@@ -245,14 +221,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
return -(u32)fault & errcode;
}
-bool __kvm_mmu_honors_guest_mtrrs(bool vm_has_noncoherent_dma);
-
-static inline bool kvm_mmu_honors_guest_mtrrs(struct kvm *kvm)
-{
- return __kvm_mmu_honors_guest_mtrrs(kvm_arch_has_noncoherent_dma(kvm));
-}
-
-void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end);
+bool kvm_mmu_may_ignore_guest_pat(void);
int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index db007a4dffa2..901be9e420a4 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -336,16 +336,19 @@ static int is_cpuid_PSE36(void)
#ifdef CONFIG_X86_64
static void __set_spte(u64 *sptep, u64 spte)
{
+ KVM_MMU_WARN_ON(is_ept_ve_possible(spte));
WRITE_ONCE(*sptep, spte);
}
static void __update_clear_spte_fast(u64 *sptep, u64 spte)
{
+ KVM_MMU_WARN_ON(is_ept_ve_possible(spte));
WRITE_ONCE(*sptep, spte);
}
static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
{
+ KVM_MMU_WARN_ON(is_ept_ve_possible(spte));
return xchg(sptep, spte);
}
@@ -432,8 +435,8 @@ static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
* The idea using the light way get the spte on x86_32 guest is from
* gup_get_pte (mm/gup.c).
*
- * An spte tlb flush may be pending, because kvm_set_pte_rmap
- * coalesces them and we are running out of the MMU lock. Therefore
+ * An spte tlb flush may be pending, because they are coalesced and
+ * we are running out of the MMU lock. Therefore
* we need to protect against in-progress updates of the spte.
*
* Reading the spte while an update is in progress may get the old value
@@ -567,9 +570,9 @@ static u64 mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
if (!is_shadow_present_pte(old_spte) ||
!spte_has_volatile_bits(old_spte))
- __update_clear_spte_fast(sptep, 0ull);
+ __update_clear_spte_fast(sptep, SHADOW_NONPRESENT_VALUE);
else
- old_spte = __update_clear_spte_slow(sptep, 0ull);
+ old_spte = __update_clear_spte_slow(sptep, SHADOW_NONPRESENT_VALUE);
if (!is_shadow_present_pte(old_spte))
return old_spte;
@@ -603,7 +606,7 @@ static u64 mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
*/
static void mmu_spte_clear_no_track(u64 *sptep)
{
- __update_clear_spte_fast(sptep, 0ull);
+ __update_clear_spte_fast(sptep, SHADOW_NONPRESENT_VALUE);
}
static u64 mmu_spte_get_lockless(u64 *sptep)
@@ -719,7 +722,7 @@ static gfn_t kvm_mmu_page_get_gfn(struct kvm_mmu_page *sp, int index)
if (sp->role.passthrough)
return sp->gfn;
- if (!sp->role.direct)
+ if (sp->shadowed_translation)
return sp->shadowed_translation[index] >> PAGE_SHIFT;
return sp->gfn + (index << ((sp->role.level - 1) * SPTE_LEVEL_BITS));
@@ -733,7 +736,7 @@ static gfn_t kvm_mmu_page_get_gfn(struct kvm_mmu_page *sp, int index)
*/
static u32 kvm_mmu_page_get_access(struct kvm_mmu_page *sp, int index)
{
- if (sp_has_gptes(sp))
+ if (sp->shadowed_translation)
return sp->shadowed_translation[index] & ACC_ALL;
/*
@@ -754,7 +757,7 @@ static u32 kvm_mmu_page_get_access(struct kvm_mmu_page *sp, int index)
static void kvm_mmu_page_set_translation(struct kvm_mmu_page *sp, int index,
gfn_t gfn, unsigned int access)
{
- if (sp_has_gptes(sp)) {
+ if (sp->shadowed_translation) {
sp->shadowed_translation[index] = (gfn << PAGE_SHIFT) | access;
return;
}
@@ -831,6 +834,15 @@ static void account_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
gfn_t gfn;
kvm->arch.indirect_shadow_pages++;
+ /*
+ * Ensure indirect_shadow_pages is elevated prior to re-reading guest
+ * child PTEs in FNAME(gpte_changed), i.e. guarantee either in-flight
+ * emulated writes are visible before re-reading guest PTEs, or that
+ * an emulated write will see the elevated count and acquire mmu_lock
+ * to update SPTEs. Pairs with the smp_mb() in kvm_mmu_track_write().
+ */
+ smp_mb();
+
gfn = sp->gfn;
slots = kvm_memslots_for_spte_role(kvm, sp->role);
slot = __gfn_to_memslot(slots, gfn);
@@ -1448,49 +1460,11 @@ static bool __kvm_zap_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
}
static bool kvm_zap_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
- struct kvm_memory_slot *slot, gfn_t gfn, int level,
- pte_t unused)
+ struct kvm_memory_slot *slot, gfn_t gfn, int level)
{
return __kvm_zap_rmap(kvm, rmap_head, slot);
}
-static bool kvm_set_pte_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
- struct kvm_memory_slot *slot, gfn_t gfn, int level,
- pte_t pte)
-{
- u64 *sptep;
- struct rmap_iterator iter;
- bool need_flush = false;
- u64 new_spte;
- kvm_pfn_t new_pfn;
-
- WARN_ON_ONCE(pte_huge(pte));
- new_pfn = pte_pfn(pte);
-
-restart:
- for_each_rmap_spte(rmap_head, &iter, sptep) {
- need_flush = true;
-
- if (pte_write(pte)) {
- kvm_zap_one_rmap_spte(kvm, rmap_head, sptep);
- goto restart;
- } else {
- new_spte = kvm_mmu_changed_pte_notifier_make_spte(
- *sptep, new_pfn);
-
- mmu_spte_clear_track_bits(kvm, sptep);
- mmu_spte_set(sptep, new_spte);
- }
- }
-
- if (need_flush && kvm_available_flush_remote_tlbs_range()) {
- kvm_flush_remote_tlbs_gfn(kvm, gfn, level);
- return false;
- }
-
- return need_flush;
-}
-
struct slot_rmap_walk_iterator {
/* input fields. */
const struct kvm_memory_slot *slot;
@@ -1562,7 +1536,7 @@ static void slot_rmap_walk_next(struct slot_rmap_walk_iterator *iterator)
typedef bool (*rmap_handler_t)(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot, gfn_t gfn,
- int level, pte_t pte);
+ int level);
static __always_inline bool kvm_handle_gfn_range(struct kvm *kvm,
struct kvm_gfn_range *range,
@@ -1574,7 +1548,7 @@ static __always_inline bool kvm_handle_gfn_range(struct kvm *kvm,
for_each_slot_rmap_range(range->slot, PG_LEVEL_4K, KVM_MAX_HUGEPAGE_LEVEL,
range->start, range->end - 1, &iterator)
ret |= handler(kvm, iterator.rmap, range->slot, iterator.gfn,
- iterator.level, range->arg.pte);
+ iterator.level);
return ret;
}
@@ -1596,22 +1570,8 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
return flush;
}
-bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- bool flush = false;
-
- if (kvm_memslots_have_rmaps(kvm))
- flush = kvm_handle_gfn_range(kvm, range, kvm_set_pte_rmap);
-
- if (tdp_mmu_enabled)
- flush |= kvm_tdp_mmu_set_spte_gfn(kvm, range);
-
- return flush;
-}
-
static bool kvm_age_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
- struct kvm_memory_slot *slot, gfn_t gfn, int level,
- pte_t unused)
+ struct kvm_memory_slot *slot, gfn_t gfn, int level)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -1624,8 +1584,7 @@ static bool kvm_age_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
}
static bool kvm_test_age_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
- struct kvm_memory_slot *slot, gfn_t gfn,
- int level, pte_t unused)
+ struct kvm_memory_slot *slot, gfn_t gfn, int level)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -1741,8 +1700,7 @@ static void kvm_mmu_free_shadow_page(struct kvm_mmu_page *sp)
hlist_del(&sp->hash_link);
list_del(&sp->link);
free_page((unsigned long)sp->spt);
- if (!sp->role.direct)
- free_page((unsigned long)sp->shadowed_translation);
+ free_page((unsigned long)sp->shadowed_translation);
kmem_cache_free(mmu_page_header_cache, sp);
}
@@ -1950,7 +1908,8 @@ static bool kvm_sync_page_check(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
static int kvm_sync_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, int i)
{
- if (!sp->spt[i])
+ /* sp->spt[i] has initial value of shadow page table allocation */
+ if (sp->spt[i] == SHADOW_NONPRESENT_VALUE)
return 0;
return vcpu->arch.mmu->sync_spte(vcpu, sp, i);
@@ -2243,7 +2202,7 @@ static struct kvm_mmu_page *kvm_mmu_alloc_shadow_page(struct kvm *kvm,
sp = kvm_mmu_memory_cache_alloc(caches->page_header_cache);
sp->spt = kvm_mmu_memory_cache_alloc(caches->shadow_page_cache);
- if (!role.direct)
+ if (!role.direct && role.level <= KVM_MAX_HUGEPAGE_LEVEL)
sp->shadowed_translation = kvm_mmu_memory_cache_alloc(caches->shadowed_info_cache);
set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
@@ -2514,7 +2473,7 @@ static int mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
return kvm_mmu_prepare_zap_page(kvm, child,
invalid_list);
}
- } else if (is_mmio_spte(pte)) {
+ } else if (is_mmio_spte(kvm, pte)) {
mmu_spte_clear_no_track(spte);
}
return 0;
@@ -3314,9 +3273,19 @@ static int kvm_handle_noslot_fault(struct kvm_vcpu *vcpu,
{
gva_t gva = fault->is_tdp ? 0 : fault->addr;
+ if (fault->is_private) {
+ kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+ return -EFAULT;
+ }
+
vcpu_cache_mmio_info(vcpu, gva, fault->gfn,
access & shadow_mmio_access_mask);
+ fault->slot = NULL;
+ fault->pfn = KVM_PFN_NOSLOT;
+ fault->map_writable = false;
+ fault->hva = KVM_HVA_ERR_BAD;
+
/*
* If MMIO caching is disabled, emulate immediately without
* touching the shadow page tables as attempting to install an
@@ -3338,7 +3307,7 @@ static int kvm_handle_noslot_fault(struct kvm_vcpu *vcpu,
return RET_PF_CONTINUE;
}
-static bool page_fault_can_be_fast(struct kvm_page_fault *fault)
+static bool page_fault_can_be_fast(struct kvm *kvm, struct kvm_page_fault *fault)
{
/*
* Page faults with reserved bits set, i.e. faults on MMIO SPTEs, only
@@ -3350,6 +3319,26 @@ static bool page_fault_can_be_fast(struct kvm_page_fault *fault)
return false;
/*
+ * For hardware-protected VMs, certain conditions like attempting to
+ * perform a write to a page which is not in the state that the guest
+ * expects it to be in can result in a nested/extended #PF. In this
+ * case, the below code might misconstrue this situation as being the
+ * result of a write-protected access, and treat it as a spurious case
+ * rather than taking any action to satisfy the real source of the #PF
+ * such as generating a KVM_EXIT_MEMORY_FAULT. This can lead to the
+ * guest spinning on a #PF indefinitely, so don't attempt the fast path
+ * in this case.
+ *
+ * Note that the kvm_mem_is_private() check might race with an
+ * attribute update, but this will either result in the guest spinning
+ * on RET_PF_SPURIOUS until the update completes, or an actual spurious
+ * case might go down the slow path. Either case will resolve itself.
+ */
+ if (kvm->arch.has_private_mem &&
+ fault->is_private != kvm_mem_is_private(kvm, fault->gfn))
+ return false;
+
+ /*
* #PF can be fast if:
*
* 1. The shadow page table entry is not present and A/D bits are
@@ -3449,7 +3438,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
u64 *sptep;
uint retry_count = 0;
- if (!page_fault_can_be_fast(fault))
+ if (!page_fault_can_be_fast(vcpu->kvm, fault))
return ret;
walk_shadow_page_lockless_begin(vcpu);
@@ -3458,7 +3447,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
u64 new_spte;
if (tdp_mmu_enabled)
- sptep = kvm_tdp_mmu_fast_pf_get_last_sptep(vcpu, fault->addr, &spte);
+ sptep = kvm_tdp_mmu_fast_pf_get_last_sptep(vcpu, fault->gfn, &spte);
else
sptep = fast_pf_get_last_sptep(vcpu, fault->addr, &spte);
@@ -3468,7 +3457,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
* available as the vCPU holds a reference to its root(s).
*/
if (WARN_ON_ONCE(!sptep))
- spte = REMOVED_SPTE;
+ spte = FROZEN_SPTE;
if (!is_shadow_present_pte(spte))
break;
@@ -4134,23 +4123,31 @@ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level
return leaf;
}
-/* return true if reserved bit(s) are detected on a valid, non-MMIO SPTE. */
-static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep)
+static int get_sptes_lockless(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes,
+ int *root_level)
{
- u64 sptes[PT64_ROOT_MAX_LEVEL + 1];
- struct rsvd_bits_validate *rsvd_check;
- int root, leaf, level;
- bool reserved = false;
+ int leaf;
walk_shadow_page_lockless_begin(vcpu);
if (is_tdp_mmu_active(vcpu))
- leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, &root);
+ leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, root_level);
else
- leaf = get_walk(vcpu, addr, sptes, &root);
+ leaf = get_walk(vcpu, addr, sptes, root_level);
walk_shadow_page_lockless_end(vcpu);
+ return leaf;
+}
+/* return true if reserved bit(s) are detected on a valid, non-MMIO SPTE. */
+static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep)
+{
+ u64 sptes[PT64_ROOT_MAX_LEVEL + 1];
+ struct rsvd_bits_validate *rsvd_check;
+ int root, leaf, level;
+ bool reserved = false;
+
+ leaf = get_sptes_lockless(vcpu, addr, sptes, &root);
if (unlikely(leaf < 0)) {
*sptep = 0ull;
return reserved;
@@ -4196,7 +4193,7 @@ static int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct)
if (WARN_ON_ONCE(reserved))
return -EINVAL;
- if (is_mmio_spte(spte)) {
+ if (is_mmio_spte(vcpu->kvm, spte)) {
gfn_t gfn = get_mmio_spte_gfn(spte);
unsigned int access = get_mmio_spte_access(spte);
@@ -4259,24 +4256,28 @@ static u32 alloc_apf_token(struct kvm_vcpu *vcpu)
return (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id;
}
-static bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
- gfn_t gfn)
+static bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu,
+ struct kvm_page_fault *fault)
{
struct kvm_arch_async_pf arch;
arch.token = alloc_apf_token(vcpu);
- arch.gfn = gfn;
+ arch.gfn = fault->gfn;
+ arch.error_code = fault->error_code;
arch.direct_map = vcpu->arch.mmu->root_role.direct;
arch.cr3 = kvm_mmu_get_guest_pgd(vcpu, vcpu->arch.mmu);
- return kvm_setup_async_pf(vcpu, cr2_or_gpa,
- kvm_vcpu_gfn_to_hva(vcpu, gfn), &arch);
+ return kvm_setup_async_pf(vcpu, fault->addr,
+ kvm_vcpu_gfn_to_hva(vcpu, fault->gfn), &arch);
}
void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work)
{
int r;
+ if (WARN_ON_ONCE(work->arch.error_code & PFERR_PRIVATE_ACCESS))
+ return;
+
if ((vcpu->arch.mmu->root_role.direct != work->arch.direct_map) ||
work->wakeup_all)
return;
@@ -4289,7 +4290,16 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work)
work->arch.cr3 != kvm_mmu_get_guest_pgd(vcpu, vcpu->arch.mmu))
return;
- kvm_mmu_do_page_fault(vcpu, work->cr2_or_gpa, 0, true, NULL);
+ r = kvm_mmu_do_page_fault(vcpu, work->cr2_or_gpa, work->arch.error_code,
+ true, NULL, NULL);
+
+ /*
+ * Account fixed page faults, otherwise they'll never be counted, but
+ * ignore stats for all other return times. Page-ready "faults" aren't
+ * truly spurious and never trigger emulation
+ */
+ if (r == RET_PF_FIXED)
+ vcpu->stat.pf_fixed++;
}
static inline u8 kvm_max_level_for_order(int order)
@@ -4309,12 +4319,23 @@ static inline u8 kvm_max_level_for_order(int order)
return PG_LEVEL_4K;
}
-static void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
- struct kvm_page_fault *fault)
+static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn,
+ u8 max_level, int gmem_order)
{
- kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
- PAGE_SIZE, fault->write, fault->exec,
- fault->is_private);
+ u8 req_max_level;
+
+ if (max_level == PG_LEVEL_4K)
+ return PG_LEVEL_4K;
+
+ max_level = min(kvm_max_level_for_order(gmem_order), max_level);
+ if (max_level == PG_LEVEL_4K)
+ return PG_LEVEL_4K;
+
+ req_max_level = kvm_x86_call(private_max_mapping_level)(kvm, pfn);
+ if (req_max_level)
+ max_level = min(max_level, req_max_level);
+
+ return req_max_level;
}
static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
@@ -4334,57 +4355,24 @@ static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
return r;
}
- fault->max_level = min(kvm_max_level_for_order(max_order),
- fault->max_level);
fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY);
+ fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault->pfn,
+ fault->max_level, max_order);
return RET_PF_CONTINUE;
}
static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
{
- struct kvm_memory_slot *slot = fault->slot;
bool async;
- /*
- * Retry the page fault if the gfn hit a memslot that is being deleted
- * or moved. This ensures any existing SPTEs for the old memslot will
- * be zapped before KVM inserts a new MMIO SPTE for the gfn.
- */
- if (slot && (slot->flags & KVM_MEMSLOT_INVALID))
- return RET_PF_RETRY;
-
- if (!kvm_is_visible_memslot(slot)) {
- /* Don't expose private memslots to L2. */
- if (is_guest_mode(vcpu)) {
- fault->slot = NULL;
- fault->pfn = KVM_PFN_NOSLOT;
- fault->map_writable = false;
- return RET_PF_CONTINUE;
- }
- /*
- * If the APIC access page exists but is disabled, go directly
- * to emulation without caching the MMIO access or creating a
- * MMIO SPTE. That way the cache doesn't need to be purged
- * when the AVIC is re-enabled.
- */
- if (slot && slot->id == APIC_ACCESS_PAGE_PRIVATE_MEMSLOT &&
- !kvm_apicv_activated(vcpu->kvm))
- return RET_PF_EMULATE;
- }
-
- if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) {
- kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
- return -EFAULT;
- }
-
if (fault->is_private)
return kvm_faultin_pfn_private(vcpu, fault);
async = false;
- fault->pfn = __gfn_to_pfn_memslot(slot, fault->gfn, false, false, &async,
- fault->write, &fault->map_writable,
- &fault->hva);
+ fault->pfn = __gfn_to_pfn_memslot(fault->slot, fault->gfn, false, false,
+ &async, fault->write,
+ &fault->map_writable, &fault->hva);
if (!async)
return RET_PF_CONTINUE; /* *pfn has correct page already */
@@ -4394,7 +4382,7 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
trace_kvm_async_pf_repeated_fault(fault->addr, fault->gfn);
kvm_make_request(KVM_REQ_APF_HALT, vcpu);
return RET_PF_RETRY;
- } else if (kvm_arch_setup_async_pf(vcpu, fault->addr, fault->gfn)) {
+ } else if (kvm_arch_setup_async_pf(vcpu, fault)) {
return RET_PF_RETRY;
}
}
@@ -4404,21 +4392,73 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
* to wait for IO. Note, gup always bails if it is unable to quickly
* get a page and a fatal signal, i.e. SIGKILL, is pending.
*/
- fault->pfn = __gfn_to_pfn_memslot(slot, fault->gfn, false, true, NULL,
- fault->write, &fault->map_writable,
- &fault->hva);
+ fault->pfn = __gfn_to_pfn_memslot(fault->slot, fault->gfn, false, true,
+ NULL, fault->write,
+ &fault->map_writable, &fault->hva);
return RET_PF_CONTINUE;
}
static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
unsigned int access)
{
+ struct kvm_memory_slot *slot = fault->slot;
int ret;
+ /*
+ * Note that the mmu_invalidate_seq also serves to detect a concurrent
+ * change in attributes. is_page_fault_stale() will detect an
+ * invalidation relate to fault->fn and resume the guest without
+ * installing a mapping in the page tables.
+ */
fault->mmu_seq = vcpu->kvm->mmu_invalidate_seq;
smp_rmb();
/*
+ * Now that we have a snapshot of mmu_invalidate_seq we can check for a
+ * private vs. shared mismatch.
+ */
+ if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) {
+ kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+ return -EFAULT;
+ }
+
+ if (unlikely(!slot))
+ return kvm_handle_noslot_fault(vcpu, fault, access);
+
+ /*
+ * Retry the page fault if the gfn hit a memslot that is being deleted
+ * or moved. This ensures any existing SPTEs for the old memslot will
+ * be zapped before KVM inserts a new MMIO SPTE for the gfn.
+ */
+ if (slot->flags & KVM_MEMSLOT_INVALID)
+ return RET_PF_RETRY;
+
+ if (slot->id == APIC_ACCESS_PAGE_PRIVATE_MEMSLOT) {
+ /*
+ * Don't map L1's APIC access page into L2, KVM doesn't support
+ * using APICv/AVIC to accelerate L2 accesses to L1's APIC,
+ * i.e. the access needs to be emulated. Emulating access to
+ * L1's APIC is also correct if L1 is accelerating L2's own
+ * virtual APIC, but for some reason L1 also maps _L1's_ APIC
+ * into L2. Note, vcpu_is_mmio_gpa() always treats access to
+ * the APIC as MMIO. Allow an MMIO SPTE to be created, as KVM
+ * uses different roots for L1 vs. L2, i.e. there is no danger
+ * of breaking APICv/AVIC for L1.
+ */
+ if (is_guest_mode(vcpu))
+ return kvm_handle_noslot_fault(vcpu, fault, access);
+
+ /*
+ * If the APIC access page exists but is disabled, go directly
+ * to emulation without caching the MMIO access or creating a
+ * MMIO SPTE. That way the cache doesn't need to be purged
+ * when the AVIC is re-enabled.
+ */
+ if (!kvm_apicv_activated(vcpu->kvm))
+ return RET_PF_EMULATE;
+ }
+
+ /*
* Check for a relevant mmu_notifier invalidation event before getting
* the pfn from the primary MMU, and before acquiring mmu_lock.
*
@@ -4439,8 +4479,7 @@ static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
* *guaranteed* to need to retry, i.e. waiting until mmu_lock is held
* to detect retry guarantees the worst case latency for the vCPU.
*/
- if (fault->slot &&
- mmu_invalidate_retry_gfn_unsafe(vcpu->kvm, fault->mmu_seq, fault->gfn))
+ if (mmu_invalidate_retry_gfn_unsafe(vcpu->kvm, fault->mmu_seq, fault->gfn))
return RET_PF_RETRY;
ret = __kvm_faultin_pfn(vcpu, fault);
@@ -4450,7 +4489,7 @@ static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
if (unlikely(is_error_pfn(fault->pfn)))
return kvm_handle_error_pfn(vcpu, fault);
- if (unlikely(!fault->slot))
+ if (WARN_ON_ONCE(!fault->slot || is_noslot_pfn(fault->pfn)))
return kvm_handle_noslot_fault(vcpu, fault, access);
/*
@@ -4561,6 +4600,19 @@ int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code,
if (WARN_ON_ONCE(fault_address >> 32))
return -EFAULT;
#endif
+ /*
+ * Legacy #PF exception only have a 32-bit error code. Simply drop the
+ * upper bits as KVM doesn't use them for #PF (because they are never
+ * set), and to ensure there are no collisions with KVM-defined bits.
+ */
+ if (WARN_ON_ONCE(error_code >> 32))
+ error_code = lower_32_bits(error_code);
+
+ /*
+ * Restrict KVM-defined flags to bits 63:32 so that it's impossible for
+ * them to conflict with #PF error codes, which are limited to 32 bits.
+ */
+ BUILD_BUG_ON(lower_32_bits(PFERR_SYNTHETIC_MASK));
vcpu->arch.l1tf_flush_l1d = true;
if (!flags) {
@@ -4619,38 +4671,23 @@ out_unlock:
}
#endif
-bool __kvm_mmu_honors_guest_mtrrs(bool vm_has_noncoherent_dma)
+bool kvm_mmu_may_ignore_guest_pat(void)
{
/*
- * If host MTRRs are ignored (shadow_memtype_mask is non-zero), and the
- * VM has non-coherent DMA (DMA doesn't snoop CPU caches), KVM's ABI is
- * to honor the memtype from the guest's MTRRs so that guest accesses
- * to memory that is DMA'd aren't cached against the guest's wishes.
- *
- * Note, KVM may still ultimately ignore guest MTRRs for certain PFNs,
- * e.g. KVM will force UC memtype for host MMIO.
+ * When EPT is enabled (shadow_memtype_mask is non-zero), the CPU does
+ * not support self-snoop (or is affected by an erratum), and the VM
+ * has non-coherent DMA (DMA doesn't snoop CPU caches), KVM's ABI is to
+ * honor the memtype from the guest's PAT so that guest accesses to
+ * memory that is DMA'd aren't cached against the guest's wishes. As a
+ * result, KVM _may_ ignore guest PAT, whereas without non-coherent DMA,
+ * KVM _always_ ignores or honors guest PAT, i.e. doesn't toggle SPTE
+ * bits in response to non-coherent device (un)registration.
*/
- return vm_has_noncoherent_dma && shadow_memtype_mask;
+ return !static_cpu_has(X86_FEATURE_SELFSNOOP) && shadow_memtype_mask;
}
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
{
- /*
- * If the guest's MTRRs may be used to compute the "real" memtype,
- * restrict the mapping level to ensure KVM uses a consistent memtype
- * across the entire mapping.
- */
- if (kvm_mmu_honors_guest_mtrrs(vcpu->kvm)) {
- for ( ; fault->max_level > PG_LEVEL_4K; --fault->max_level) {
- int page_num = KVM_PAGES_PER_HPAGE(fault->max_level);
- gfn_t base = gfn_round_for_level(fault->gfn,
- fault->max_level);
-
- if (kvm_mtrr_check_gfn_range_consistency(vcpu, base, page_num))
- break;
- }
- }
-
#ifdef CONFIG_X86_64
if (tdp_mmu_enabled)
return kvm_tdp_mmu_page_fault(vcpu, fault);
@@ -4659,6 +4696,79 @@ int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
return direct_page_fault(vcpu, fault);
}
+static int kvm_tdp_map_page(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code,
+ u8 *level)
+{
+ int r;
+
+ /*
+ * Restrict to TDP page fault, since that's the only case where the MMU
+ * is indexed by GPA.
+ */
+ if (vcpu->arch.mmu->page_fault != kvm_tdp_page_fault)
+ return -EOPNOTSUPP;
+
+ do {
+ if (signal_pending(current))
+ return -EINTR;
+ cond_resched();
+ r = kvm_mmu_do_page_fault(vcpu, gpa, error_code, true, NULL, level);
+ } while (r == RET_PF_RETRY);
+
+ if (r < 0)
+ return r;
+
+ switch (r) {
+ case RET_PF_FIXED:
+ case RET_PF_SPURIOUS:
+ return 0;
+
+ case RET_PF_EMULATE:
+ return -ENOENT;
+
+ case RET_PF_RETRY:
+ case RET_PF_CONTINUE:
+ case RET_PF_INVALID:
+ default:
+ WARN_ONCE(1, "could not fix page fault during prefault");
+ return -EIO;
+ }
+}
+
+long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
+ struct kvm_pre_fault_memory *range)
+{
+ u64 error_code = PFERR_GUEST_FINAL_MASK;
+ u8 level = PG_LEVEL_4K;
+ u64 end;
+ int r;
+
+ /*
+ * reload is efficient when called repeatedly, so we can do it on
+ * every iteration.
+ */
+ kvm_mmu_reload(vcpu);
+
+ if (kvm_arch_has_private_mem(vcpu->kvm) &&
+ kvm_mem_is_private(vcpu->kvm, gpa_to_gfn(range->gpa)))
+ error_code |= PFERR_PRIVATE_ACCESS;
+
+ /*
+ * Shadow paging uses GVA for kvm page fault, so restrict to
+ * two-dimensional paging.
+ */
+ r = kvm_tdp_map_page(vcpu, range->gpa, error_code, &level);
+ if (r < 0)
+ return r;
+
+ /*
+ * If the mapping that covers range->gpa can use a huge page, it
+ * may start below it or end after range->gpa + range->size.
+ */
+ end = (range->gpa & KVM_HPAGE_MASK(level)) + KVM_HPAGE_SIZE(level);
+ return min(range->size, end - range->gpa);
+}
+
static void nonpaging_init_context(struct kvm_mmu *context)
{
context->page_fault = nonpaging_page_fault;
@@ -4812,7 +4922,7 @@ EXPORT_SYMBOL_GPL(kvm_mmu_new_pgd);
static bool sync_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn,
unsigned int access)
{
- if (unlikely(is_mmio_spte(*sptep))) {
+ if (unlikely(is_mmio_spte(vcpu->kvm, *sptep))) {
if (gfn != get_mmio_spte_gfn(*sptep)) {
mmu_spte_clear_no_track(sptep);
return true;
@@ -4986,7 +5096,7 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
static inline u64 reserved_hpa_bits(void)
{
- return rsvd_bits(shadow_phys_bits, 63);
+ return rsvd_bits(kvm_host.maxphyaddr, 63);
}
/*
@@ -5322,6 +5432,11 @@ static inline int kvm_mmu_get_tdp_level(struct kvm_vcpu *vcpu)
return max_tdp_level;
}
+u8 kvm_mmu_get_max_tdp_level(void)
+{
+ return tdp_root_level ? tdp_root_level : max_tdp_level;
+}
+
static union kvm_mmu_page_role
kvm_calc_tdp_mmu_root_page_role(struct kvm_vcpu *vcpu,
union kvm_cpu_role cpu_role)
@@ -5626,7 +5741,7 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
* stale entries. Flushing on alloc also allows KVM to skip the TLB
* flush when freeing a root (see kvm_tdp_mmu_put_root()).
*/
- static_call(kvm_x86_flush_tlb_current)(vcpu);
+ kvm_x86_call(flush_tlb_current)(vcpu);
out:
return r;
}
@@ -5802,10 +5917,15 @@ void kvm_mmu_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
bool flush = false;
/*
- * If we don't have indirect shadow pages, it means no page is
- * write-protected, so we can exit simply.
+ * When emulating guest writes, ensure the written value is visible to
+ * any task that is handling page faults before checking whether or not
+ * KVM is shadowing a guest PTE. This ensures either KVM will create
+ * the correct SPTE in the page fault handler, or this task will see
+ * a non-zero indirect_shadow_pages. Pairs with the smp_mb() in
+ * account_shadowed().
*/
- if (!READ_ONCE(vcpu->kvm->arch.indirect_shadow_pages))
+ smp_mb();
+ if (!vcpu->kvm->arch.indirect_shadow_pages)
return;
write_lock(&vcpu->kvm->mmu_lock);
@@ -5846,37 +5966,52 @@ int noinline kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 err
int r, emulation_type = EMULTYPE_PF;
bool direct = vcpu->arch.mmu->root_role.direct;
- /*
- * IMPLICIT_ACCESS is a KVM-defined flag used to correctly perform SMAP
- * checks when emulating instructions that triggers implicit access.
- * WARN if hardware generates a fault with an error code that collides
- * with the KVM-defined value. Clear the flag and continue on, i.e.
- * don't terminate the VM, as KVM can't possibly be relying on a flag
- * that KVM doesn't know about.
- */
- if (WARN_ON_ONCE(error_code & PFERR_IMPLICIT_ACCESS))
- error_code &= ~PFERR_IMPLICIT_ACCESS;
-
if (WARN_ON_ONCE(!VALID_PAGE(vcpu->arch.mmu->root.hpa)))
return RET_PF_RETRY;
+ /*
+ * Except for reserved faults (emulated MMIO is shared-only), set the
+ * PFERR_PRIVATE_ACCESS flag for software-protected VMs based on the gfn's
+ * current attributes, which are the source of truth for such VMs. Note,
+ * this wrong for nested MMUs as the GPA is an L2 GPA, but KVM doesn't
+ * currently supported nested virtualization (among many other things)
+ * for software-protected VMs.
+ */
+ if (IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) &&
+ !(error_code & PFERR_RSVD_MASK) &&
+ vcpu->kvm->arch.vm_type == KVM_X86_SW_PROTECTED_VM &&
+ kvm_mem_is_private(vcpu->kvm, gpa_to_gfn(cr2_or_gpa)))
+ error_code |= PFERR_PRIVATE_ACCESS;
+
r = RET_PF_INVALID;
if (unlikely(error_code & PFERR_RSVD_MASK)) {
+ if (WARN_ON_ONCE(error_code & PFERR_PRIVATE_ACCESS))
+ return -EFAULT;
+
r = handle_mmio_page_fault(vcpu, cr2_or_gpa, direct);
if (r == RET_PF_EMULATE)
goto emulate;
}
if (r == RET_PF_INVALID) {
- r = kvm_mmu_do_page_fault(vcpu, cr2_or_gpa,
- lower_32_bits(error_code), false,
- &emulation_type);
+ vcpu->stat.pf_taken++;
+
+ r = kvm_mmu_do_page_fault(vcpu, cr2_or_gpa, error_code, false,
+ &emulation_type, NULL);
if (KVM_BUG_ON(r == RET_PF_INVALID, vcpu->kvm))
return -EIO;
}
if (r < 0)
return r;
+
+ if (r == RET_PF_FIXED)
+ vcpu->stat.pf_fixed++;
+ else if (r == RET_PF_EMULATE)
+ vcpu->stat.pf_emulate++;
+ else if (r == RET_PF_SPURIOUS)
+ vcpu->stat.pf_spurious++;
+
if (r != RET_PF_EMULATE)
return 1;
@@ -5912,6 +6047,22 @@ emulate:
}
EXPORT_SYMBOL_GPL(kvm_mmu_page_fault);
+void kvm_mmu_print_sptes(struct kvm_vcpu *vcpu, gpa_t gpa, const char *msg)
+{
+ u64 sptes[PT64_ROOT_MAX_LEVEL + 1];
+ int root_level, leaf, level;
+
+ leaf = get_sptes_lockless(vcpu, gpa, sptes, &root_level);
+ if (unlikely(leaf < 0))
+ return;
+
+ pr_err("%s %llx", msg, gpa);
+ for (level = root_level; level >= leaf; level--)
+ pr_cont(", spte[%d] = 0x%llx", level, sptes[level]);
+ pr_cont("\n");
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_print_sptes);
+
static void __kvm_mmu_invalidate_addr(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
u64 addr, hpa_t root_hpa)
{
@@ -5962,7 +6113,7 @@ void kvm_mmu_invalidate_addr(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
if (is_noncanonical_address(addr, vcpu))
return;
- static_call(kvm_x86_flush_tlb_gva)(vcpu, addr);
+ kvm_x86_call(flush_tlb_gva)(vcpu, addr);
}
if (!mmu->sync_spte)
@@ -6173,7 +6324,10 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu)
vcpu->arch.mmu_page_header_cache.kmem_cache = mmu_page_header_cache;
vcpu->arch.mmu_page_header_cache.gfp_zero = __GFP_ZERO;
- vcpu->arch.mmu_shadow_page_cache.gfp_zero = __GFP_ZERO;
+ vcpu->arch.mmu_shadow_page_cache.init_value =
+ SHADOW_NONPRESENT_VALUE;
+ if (!vcpu->arch.mmu_shadow_page_cache.init_value)
+ vcpu->arch.mmu_shadow_page_cache.gfp_zero = __GFP_ZERO;
vcpu->arch.mmu = &vcpu->arch.root_mmu;
vcpu->arch.walk_mmu = &vcpu->arch.root_mmu;
@@ -6316,6 +6470,7 @@ static bool kvm_has_zapped_obsolete_pages(struct kvm *kvm)
void kvm_mmu_init_vm(struct kvm *kvm)
{
+ kvm->arch.shadow_mmio_value = shadow_mmio_value;
INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages);
INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages);
@@ -6750,6 +6905,7 @@ restart:
return need_tlb_flush;
}
+EXPORT_SYMBOL_GPL(kvm_zap_gfn_range);
static void kvm_rmap_zap_collapsible_sptes(struct kvm *kvm,
const struct kvm_memory_slot *slot)
@@ -6880,7 +7036,6 @@ static unsigned long mmu_shrink_scan(struct shrinker *shrink,
list_for_each_entry(kvm, &vm_list, vm_list) {
int idx;
- LIST_HEAD(invalid_list);
/*
* Never scan more than sc->nr_to_scan VM instances.
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index 5390a591a571..1721d97743e9 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -190,7 +190,7 @@ static inline bool is_nx_huge_page_enabled(struct kvm *kvm)
struct kvm_page_fault {
/* arguments to kvm_mmu_do_page_fault. */
const gpa_t addr;
- const u32 error_code;
+ const u64 error_code;
const bool prefetch;
/* Derived from error_code. */
@@ -279,8 +279,17 @@ enum {
RET_PF_SPURIOUS,
};
+static inline void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
+ struct kvm_page_fault *fault)
+{
+ kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
+ PAGE_SIZE, fault->write, fault->exec,
+ fault->is_private);
+}
+
static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
- u32 err, bool prefetch, int *emulation_type)
+ u64 err, bool prefetch,
+ int *emulation_type, u8 *level)
{
struct kvm_page_fault fault = {
.addr = cr2_or_gpa,
@@ -298,7 +307,10 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
.max_level = KVM_MAX_HUGEPAGE_LEVEL,
.req_level = PG_LEVEL_4K,
.goal_level = PG_LEVEL_4K,
- .is_private = kvm_mem_is_private(vcpu->kvm, cr2_or_gpa >> PAGE_SHIFT),
+ .is_private = err & PFERR_PRIVATE_ACCESS,
+
+ .pfn = KVM_PFN_ERR_FAULT,
+ .hva = KVM_HVA_ERR_BAD,
};
int r;
@@ -307,35 +319,27 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
fault.slot = kvm_vcpu_gfn_to_memslot(vcpu, fault.gfn);
}
- /*
- * Async #PF "faults", a.k.a. prefetch faults, are not faults from the
- * guest perspective and have already been counted at the time of the
- * original fault.
- */
- if (!prefetch)
- vcpu->stat.pf_taken++;
-
if (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) && fault.is_tdp)
r = kvm_tdp_page_fault(vcpu, &fault);
else
r = vcpu->arch.mmu->page_fault(vcpu, &fault);
+ /*
+ * Not sure what's happening, but punt to userspace and hope that
+ * they can fix it by changing memory to shared, or they can
+ * provide a better error.
+ */
+ if (r == RET_PF_EMULATE && fault.is_private) {
+ pr_warn_ratelimited("kvm: unexpected emulation request on private memory\n");
+ kvm_mmu_prepare_memory_fault_exit(vcpu, &fault);
+ return -EFAULT;
+ }
+
if (fault.write_fault_to_shadow_pgtable && emulation_type)
*emulation_type |= EMULTYPE_WRITE_PF_TO_SP;
+ if (level)
+ *level = fault.goal_level;
- /*
- * Similar to above, prefetch faults aren't truly spurious, and the
- * async #PF path doesn't do emulation. Do count faults that are fixed
- * by the async #PF handler though, otherwise they'll never be counted.
- */
- if (r == RET_PF_FIXED)
- vcpu->stat.pf_fixed++;
- else if (prefetch)
- ;
- else if (r == RET_PF_EMULATE)
- vcpu->stat.pf_emulate++;
- else if (r == RET_PF_SPURIOUS)
- vcpu->stat.pf_spurious++;
return r;
}
diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h
index ae86820cef69..195d98bc8de8 100644
--- a/arch/x86/kvm/mmu/mmutrace.h
+++ b/arch/x86/kvm/mmu/mmutrace.h
@@ -260,7 +260,7 @@ TRACE_EVENT(
TP_STRUCT__entry(
__field(int, vcpu_id)
__field(gpa_t, cr2_or_gpa)
- __field(u32, error_code)
+ __field(u64, error_code)
__field(u64 *, sptep)
__field(u64, old_spte)
__field(u64, new_spte)
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index f6448284c18e..561c331fd6ec 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -41,7 +41,7 @@ bool kvm_page_track_write_tracking_enabled(struct kvm *kvm)
void kvm_page_track_free_memslot(struct kvm_memory_slot *slot)
{
- kvfree(slot->arch.gfn_write_track);
+ vfree(slot->arch.gfn_write_track);
slot->arch.gfn_write_track = NULL;
}
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 4d4e98fe4f35..69941cebb3a8 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -497,21 +497,21 @@ error:
* The other bits are set to 0.
*/
if (!(errcode & PFERR_RSVD_MASK)) {
- vcpu->arch.exit_qualification &= (EPT_VIOLATION_GVA_IS_VALID |
- EPT_VIOLATION_GVA_TRANSLATED);
+ walker->fault.exit_qualification = 0;
+
if (write_fault)
- vcpu->arch.exit_qualification |= EPT_VIOLATION_ACC_WRITE;
+ walker->fault.exit_qualification |= EPT_VIOLATION_ACC_WRITE;
if (user_fault)
- vcpu->arch.exit_qualification |= EPT_VIOLATION_ACC_READ;
+ walker->fault.exit_qualification |= EPT_VIOLATION_ACC_READ;
if (fetch_fault)
- vcpu->arch.exit_qualification |= EPT_VIOLATION_ACC_INSTR;
+ walker->fault.exit_qualification |= EPT_VIOLATION_ACC_INSTR;
/*
* Note, pte_access holds the raw RWX bits from the EPTE, not
* ACC_*_MASK flags!
*/
- vcpu->arch.exit_qualification |= (pte_access & VMX_EPT_RWX_MASK) <<
- EPT_VIOLATION_RWX_SHIFT;
+ walker->fault.exit_qualification |= (pte_access & VMX_EPT_RWX_MASK) <<
+ EPT_VIOLATION_RWX_SHIFT;
}
#endif
walker->fault.address = addr;
@@ -911,7 +911,8 @@ static int FNAME(sync_spte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, int
gpa_t pte_gpa;
gfn_t gfn;
- if (WARN_ON_ONCE(!sp->spt[i]))
+ if (WARN_ON_ONCE(sp->spt[i] == SHADOW_NONPRESENT_VALUE ||
+ !sp->shadowed_translation))
return 0;
first_pte_gpa = FNAME(get_level1_sp_gpa)(sp);
@@ -933,13 +934,13 @@ static int FNAME(sync_spte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, int
return 0;
/*
- * Drop the SPTE if the new protections would result in a RWX=0
- * SPTE or if the gfn is changing. The RWX=0 case only affects
- * EPT with execute-only support, i.e. EPT without an effective
- * "present" bit, as all other paging modes will create a
- * read-only SPTE if pte_access is zero.
+ * Drop the SPTE if the new protections result in no effective
+ * "present" bit or if the gfn is changing. The former case
+ * only affects EPT with execute-only support with pte_access==0;
+ * all other paging modes will create a read-only SPTE if
+ * pte_access is zero.
*/
- if ((!pte_access && !shadow_present_mask) ||
+ if ((pte_access | shadow_present_mask) == SHADOW_NONPRESENT_VALUE ||
gfn != kvm_mmu_page_get_gfn(sp, i)) {
drop_spte(vcpu->kvm, &sp->spt[i]);
return 1;
diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c
index 4a599130e9c9..d4527965e48c 100644
--- a/arch/x86/kvm/mmu/spte.c
+++ b/arch/x86/kvm/mmu/spte.c
@@ -43,7 +43,25 @@ 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 u8 __init kvm_get_host_maxphyaddr(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, i.e. the raw MAXPHYADDR,
+ * when reasoning about CPU behavior with respect to MAXPHYADDR.
+ */
+ 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;
+}
void __init kvm_mmu_spte_module_init(void)
{
@@ -55,6 +73,8 @@ void __init kvm_mmu_spte_module_init(void)
* will change when the vendor module is (re)loaded.
*/
allow_mmio_caching = enable_mmio_caching;
+
+ kvm_host.maxphyaddr = kvm_get_host_maxphyaddr();
}
static u64 generation_mmio_spte_mask(u64 gen)
@@ -74,10 +94,10 @@ u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access)
u64 spte = generation_mmio_spte_mask(gen);
u64 gpa = gfn << PAGE_SHIFT;
- WARN_ON_ONCE(!shadow_mmio_value);
+ WARN_ON_ONCE(!vcpu->kvm->arch.shadow_mmio_value);
access &= shadow_mmio_access_mask;
- spte |= shadow_mmio_value | access;
+ spte |= vcpu->kvm->arch.shadow_mmio_value | access;
spte |= gpa | shadow_nonpresent_or_rsvd_mask;
spte |= (gpa & shadow_nonpresent_or_rsvd_mask)
<< SHADOW_NONPRESENT_OR_RSVD_MASK_LEN;
@@ -144,19 +164,19 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
u64 spte = SPTE_MMU_PRESENT_MASK;
bool wrprot = false;
- WARN_ON_ONCE(!pte_access && !shadow_present_mask);
+ /*
+ * For the EPT case, shadow_present_mask has no RWX bits set if
+ * exec-only page table entries are supported. In that case,
+ * ACC_USER_MASK and shadow_user_mask are used to represent
+ * read access. See FNAME(gpte_access) in paging_tmpl.h.
+ */
+ WARN_ON_ONCE((pte_access | shadow_present_mask) == SHADOW_NONPRESENT_VALUE);
if (sp->role.ad_disabled)
spte |= SPTE_TDP_AD_DISABLED;
else if (kvm_mmu_page_ad_need_write_protect(sp))
spte |= SPTE_TDP_AD_WRPROT_ONLY;
- /*
- * 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 (!prefetch)
spte |= spte_shadow_accessed_mask(spte);
@@ -190,8 +210,8 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
spte |= PT_PAGE_SIZE_MASK;
if (shadow_memtype_mask)
- spte |= static_call(kvm_x86_get_mt_mask)(vcpu, gfn,
- kvm_is_mmio_pfn(pfn));
+ spte |= kvm_x86_call(get_mt_mask)(vcpu, gfn,
+ kvm_is_mmio_pfn(pfn));
if (host_writable)
spte |= shadow_host_writable_mask;
else
@@ -271,18 +291,12 @@ static u64 make_spte_executable(u64 spte)
* This is used during huge page splitting to build the SPTEs that make up the
* new page table.
*/
-u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, union kvm_mmu_page_role role,
- int index)
+u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte,
+ union kvm_mmu_page_role role, int index)
{
- u64 child_spte;
-
- if (WARN_ON_ONCE(!is_shadow_present_pte(huge_spte)))
- return 0;
+ u64 child_spte = huge_spte;
- if (WARN_ON_ONCE(!is_large_pte(huge_spte)))
- return 0;
-
- child_spte = huge_spte;
+ KVM_BUG_ON(!is_shadow_present_pte(huge_spte) || !is_large_pte(huge_spte), kvm);
/*
* The child_spte already has the base address of the huge page being
@@ -322,22 +336,6 @@ u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled)
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 & ~SPTE_BASE_ADDR_MASK;
- new_spte |= (u64)new_pfn << PAGE_SHIFT;
-
- new_spte &= ~PT_WRITABLE_MASK;
- new_spte &= ~shadow_host_writable_mask;
- new_spte &= ~shadow_mmu_writable_mask;
-
- new_spte = mark_spte_for_access_track(new_spte);
-
- return new_spte;
-}
-
u64 mark_spte_for_access_track(u64 spte)
{
if (spte_ad_enabled(spte))
@@ -399,7 +397,7 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask)
* not set any RWX bits.
*/
if (WARN_ON((mmio_value & mmio_mask) != mmio_value) ||
- WARN_ON(mmio_value && (REMOVED_SPTE & mmio_mask) == mmio_value))
+ WARN_ON(mmio_value && (FROZEN_SPTE & mmio_mask) == mmio_value))
mmio_value = 0;
if (!mmio_value)
@@ -429,7 +427,9 @@ void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only)
shadow_dirty_mask = has_ad_bits ? VMX_EPT_DIRTY_BIT : 0ull;
shadow_nx_mask = 0ull;
shadow_x_mask = VMX_EPT_EXECUTABLE_MASK;
- shadow_present_mask = has_exec_only ? 0ull : VMX_EPT_READABLE_MASK;
+ /* VMX_EPT_SUPPRESS_VE_BIT is needed for W or X violation. */
+ shadow_present_mask =
+ (has_exec_only ? 0ull : VMX_EPT_READABLE_MASK) | VMX_EPT_SUPPRESS_VE_BIT;
/*
* EPT overrides the host MTRRs, and so KVM must program the desired
* memtype directly into the SPTEs. Note, this mask is just the mask
@@ -446,7 +446,7 @@ void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only)
* of an EPT paging-structure entry is 110b (write/execute).
*/
kvm_mmu_set_mmio_spte_mask(VMX_EPT_MISCONFIG_WX_VALUE,
- VMX_EPT_RWX_MASK, 0);
+ VMX_EPT_RWX_MASK | VMX_EPT_SUPPRESS_VE_BIT, 0);
}
EXPORT_SYMBOL_GPL(kvm_mmu_set_ept_masks);
@@ -455,8 +455,6 @@ void kvm_mmu_reset_all_pte_masks(void)
u8 low_phys_bits;
u64 mask;
- 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
@@ -508,7 +506,7 @@ void kvm_mmu_reset_all_pte_masks(void)
* 52-bit physical addresses then there are no reserved PA bits in the
* PTEs and so the reserved PA approach must be disabled.
*/
- if (shadow_phys_bits < 52)
+ if (kvm_host.maxphyaddr < 52)
mask = BIT_ULL(51) | PT_PRESENT_MASK;
else
mask = 0;
diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h
index a129951c9a88..ef793c459b05 100644
--- a/arch/x86/kvm/mmu/spte.h
+++ b/arch/x86/kvm/mmu/spte.h
@@ -3,6 +3,8 @@
#ifndef KVM_X86_MMU_SPTE_H
#define KVM_X86_MMU_SPTE_H
+#include <asm/vmx.h>
+
#include "mmu.h"
#include "mmu_internal.h"
@@ -149,6 +151,22 @@ static_assert(MMIO_SPTE_GEN_LOW_BITS == 8 && MMIO_SPTE_GEN_HIGH_BITS == 11);
#define MMIO_SPTE_GEN_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_BITS + MMIO_SPTE_GEN_HIGH_BITS - 1, 0)
+/*
+ * Non-present SPTE value needs to set bit 63 for TDX, in order to suppress
+ * #VE and get EPT violations on non-present PTEs. We can use the
+ * same value also without TDX for both VMX and SVM:
+ *
+ * For SVM NPT, for non-present spte (bit 0 = 0), other bits are ignored.
+ * For VMX EPT, bit 63 is ignored if #VE is disabled. (EPT_VIOLATION_VE=0)
+ * bit 63 is #VE suppress if #VE is enabled. (EPT_VIOLATION_VE=1)
+ */
+#ifdef CONFIG_X86_64
+#define SHADOW_NONPRESENT_VALUE BIT_ULL(63)
+static_assert(!(SHADOW_NONPRESENT_VALUE & SPTE_MMU_PRESENT_MASK));
+#else
+#define SHADOW_NONPRESENT_VALUE 0ULL
+#endif
+
extern u64 __read_mostly shadow_host_writable_mask;
extern u64 __read_mostly shadow_mmu_writable_mask;
extern u64 __read_mostly shadow_nx_mask;
@@ -184,24 +202,24 @@ extern u64 __read_mostly shadow_nonpresent_or_rsvd_mask;
/*
* If a thread running without exclusive control of the MMU lock must perform a
- * multi-part operation on an SPTE, it can set the SPTE to REMOVED_SPTE as a
+ * multi-part operation on an SPTE, it can set the SPTE to FROZEN_SPTE as a
* non-present intermediate value. Other threads which encounter this value
* should not modify the SPTE.
*
* Use a semi-arbitrary value that doesn't set RWX bits, i.e. is not-present on
* both AMD and Intel CPUs, and doesn't set PFN bits, i.e. doesn't create a L1TF
- * vulnerability. Use only low bits to avoid 64-bit immediates.
+ * vulnerability.
*
* Only used by the TDP MMU.
*/
-#define REMOVED_SPTE 0x5a0ULL
+#define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL)
/* Removed SPTEs must not be misconstrued as shadow present PTEs. */
-static_assert(!(REMOVED_SPTE & SPTE_MMU_PRESENT_MASK));
+static_assert(!(FROZEN_SPTE & SPTE_MMU_PRESENT_MASK));
-static inline bool is_removed_spte(u64 spte)
+static inline bool is_frozen_spte(u64 spte)
{
- return spte == REMOVED_SPTE;
+ return spte == FROZEN_SPTE;
}
/* Get an SPTE's index into its parent's page table (and the spt array). */
@@ -249,9 +267,9 @@ static inline struct kvm_mmu_page *root_to_sp(hpa_t root)
return spte_to_child_sp(root);
}
-static inline bool is_mmio_spte(u64 spte)
+static inline bool is_mmio_spte(struct kvm *kvm, u64 spte)
{
- return (spte & shadow_mmio_mask) == shadow_mmio_value &&
+ return (spte & shadow_mmio_mask) == kvm->arch.shadow_mmio_value &&
likely(enable_mmio_caching);
}
@@ -260,6 +278,13 @@ static inline bool is_shadow_present_pte(u64 pte)
return !!(pte & SPTE_MMU_PRESENT_MASK);
}
+static inline bool is_ept_ve_possible(u64 spte)
+{
+ return (shadow_present_mask & VMX_EPT_SUPPRESS_VE_BIT) &&
+ !(spte & VMX_EPT_SUPPRESS_VE_BIT) &&
+ (spte & VMX_EPT_RWX_MASK) != VMX_EPT_MISCONFIG_WX_VALUE;
+}
+
/*
* Returns true if A/D bits are supported in hardware and are enabled by KVM.
* When enabled, KVM uses A/D bits for all non-nested MMUs. Because L1 can
@@ -496,8 +521,6 @@ static inline u64 restore_acc_track_spte(u64 spte)
return spte;
}
-u64 kvm_mmu_changed_pte_notifier_make_spte(u64 old_spte, kvm_pfn_t new_pfn);
-
void __init kvm_mmu_spte_module_init(void);
void kvm_mmu_reset_all_pte_masks(void);
diff --git a/arch/x86/kvm/mmu/tdp_iter.h b/arch/x86/kvm/mmu/tdp_iter.h
index fae559559a80..2880fd392e0c 100644
--- a/arch/x86/kvm/mmu/tdp_iter.h
+++ b/arch/x86/kvm/mmu/tdp_iter.h
@@ -21,11 +21,13 @@ static inline u64 kvm_tdp_mmu_read_spte(tdp_ptep_t sptep)
static inline u64 kvm_tdp_mmu_write_spte_atomic(tdp_ptep_t sptep, u64 new_spte)
{
+ KVM_MMU_WARN_ON(is_ept_ve_possible(new_spte));
return xchg(rcu_dereference(sptep), new_spte);
}
static inline void __kvm_tdp_mmu_write_spte(tdp_ptep_t sptep, u64 new_spte)
{
+ KVM_MMU_WARN_ON(is_ept_ve_possible(new_spte));
WRITE_ONCE(*rcu_dereference(sptep), new_spte);
}
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 04c1f0957fea..c7dc49ee7388 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -365,8 +365,8 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
* value to the removed SPTE value.
*/
for (;;) {
- old_spte = kvm_tdp_mmu_write_spte_atomic(sptep, REMOVED_SPTE);
- if (!is_removed_spte(old_spte))
+ old_spte = kvm_tdp_mmu_write_spte_atomic(sptep, FROZEN_SPTE);
+ if (!is_frozen_spte(old_spte))
break;
cpu_relax();
}
@@ -397,11 +397,11 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
* No retry is needed in the atomic update path as the
* sole concern is dropping a Dirty bit, i.e. no other
* task can zap/remove the SPTE as mmu_lock is held for
- * write. Marking the SPTE as a removed SPTE is not
+ * write. Marking the SPTE as a frozen SPTE is not
* strictly necessary for the same reason, but using
- * the remove SPTE value keeps the shared/exclusive
+ * the frozen SPTE value keeps the shared/exclusive
* paths consistent and allows the handle_changed_spte()
- * call below to hardcode the new value to REMOVED_SPTE.
+ * call below to hardcode the new value to FROZEN_SPTE.
*
* Note, even though dropping a Dirty bit is the only
* scenario where a non-atomic update could result in a
@@ -413,10 +413,10 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
* it here.
*/
old_spte = kvm_tdp_mmu_write_spte(sptep, old_spte,
- REMOVED_SPTE, level);
+ FROZEN_SPTE, level);
}
handle_changed_spte(kvm, kvm_mmu_page_as_id(sp), gfn,
- old_spte, REMOVED_SPTE, level, shared);
+ old_spte, FROZEN_SPTE, level, shared);
}
call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback);
@@ -490,19 +490,19 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
*/
if (!was_present && !is_present) {
/*
- * If this change does not involve a MMIO SPTE or removed SPTE,
+ * If this change does not involve a MMIO SPTE or frozen 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_ONCE(!is_mmio_spte(old_spte) &&
- !is_mmio_spte(new_spte) &&
- !is_removed_spte(new_spte)))
+ if (WARN_ON_ONCE(!is_mmio_spte(kvm, old_spte) &&
+ !is_mmio_spte(kvm, new_spte) &&
+ !is_frozen_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, or the new SPTE is\n"
- "a temporary removed SPTE.\n"
+ "a temporary frozen SPTE.\n"
"as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
as_id, gfn, old_spte, new_spte, level);
return;
@@ -530,6 +530,32 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
kvm_set_pfn_accessed(spte_to_pfn(old_spte));
}
+static inline int __must_check __tdp_mmu_set_spte_atomic(struct tdp_iter *iter,
+ u64 new_spte)
+{
+ u64 *sptep = rcu_dereference(iter->sptep);
+
+ /*
+ * The caller is responsible for ensuring the old SPTE is not a REMOVED
+ * SPTE. KVM should never attempt to zap or manipulate a REMOVED SPTE,
+ * and pre-checking before inserting a new SPTE is advantageous as it
+ * avoids unnecessary work.
+ */
+ WARN_ON_ONCE(iter->yielded || is_frozen_spte(iter->old_spte));
+
+ /*
+ * Note, fast_pf_fix_direct_spte() can also modify TDP MMU SPTEs and
+ * does not hold the mmu_lock. On failure, i.e. if a different logical
+ * CPU modified the SPTE, try_cmpxchg64() updates iter->old_spte with
+ * the current value, so the caller operates on fresh data, e.g. if it
+ * retries tdp_mmu_set_spte_atomic()
+ */
+ if (!try_cmpxchg64(sptep, &iter->old_spte, new_spte))
+ return -EBUSY;
+
+ return 0;
+}
+
/*
* tdp_mmu_set_spte_atomic - Set a TDP MMU SPTE atomically
* and handle the associated bookkeeping. Do not mark the page dirty
@@ -547,31 +573,17 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
* no side-effects other than setting iter->old_spte to the last
* known value of the spte.
*/
-static inline int tdp_mmu_set_spte_atomic(struct kvm *kvm,
- struct tdp_iter *iter,
- u64 new_spte)
+static inline int __must_check tdp_mmu_set_spte_atomic(struct kvm *kvm,
+ struct tdp_iter *iter,
+ u64 new_spte)
{
- u64 *sptep = rcu_dereference(iter->sptep);
-
- /*
- * The caller is responsible for ensuring the old SPTE is not a REMOVED
- * SPTE. KVM should never attempt to zap or manipulate a REMOVED SPTE,
- * and pre-checking before inserting a new SPTE is advantageous as it
- * avoids unnecessary work.
- */
- WARN_ON_ONCE(iter->yielded || is_removed_spte(iter->old_spte));
+ int ret;
lockdep_assert_held_read(&kvm->mmu_lock);
- /*
- * Note, fast_pf_fix_direct_spte() can also modify TDP MMU SPTEs and
- * does not hold the mmu_lock. On failure, i.e. if a different logical
- * CPU modified the SPTE, try_cmpxchg64() updates iter->old_spte with
- * the current value, so the caller operates on fresh data, e.g. if it
- * retries tdp_mmu_set_spte_atomic()
- */
- if (!try_cmpxchg64(sptep, &iter->old_spte, new_spte))
- return -EBUSY;
+ ret = __tdp_mmu_set_spte_atomic(iter, new_spte);
+ if (ret)
+ return ret;
handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte,
new_spte, iter->level, true);
@@ -579,31 +591,43 @@ static inline int tdp_mmu_set_spte_atomic(struct kvm *kvm,
return 0;
}
-static inline int tdp_mmu_zap_spte_atomic(struct kvm *kvm,
- struct tdp_iter *iter)
+static inline int __must_check tdp_mmu_zap_spte_atomic(struct kvm *kvm,
+ struct tdp_iter *iter)
{
int ret;
+ lockdep_assert_held_read(&kvm->mmu_lock);
+
/*
- * Freeze the SPTE by setting it to a special,
- * non-present value. This will stop other threads from
- * immediately installing a present entry in its place
- * before the TLBs are flushed.
+ * Freeze the SPTE by setting it to a special, non-present value. This
+ * will stop other threads from immediately installing a present entry
+ * in its place before the TLBs are flushed.
+ *
+ * Delay processing of the zapped SPTE until after TLBs are flushed and
+ * the FROZEN_SPTE is replaced (see below).
*/
- ret = tdp_mmu_set_spte_atomic(kvm, iter, REMOVED_SPTE);
+ ret = __tdp_mmu_set_spte_atomic(iter, FROZEN_SPTE);
if (ret)
return ret;
kvm_flush_remote_tlbs_gfn(kvm, iter->gfn, iter->level);
/*
- * No other thread can overwrite the removed SPTE as they must either
+ * No other thread can overwrite the frozen SPTE as they must either
* wait on the MMU lock or use tdp_mmu_set_spte_atomic() which will not
- * overwrite the special removed SPTE value. No bookkeeping is needed
- * here since the SPTE is going from non-present to non-present. Use
- * the raw write helper to avoid an unnecessary check on volatile bits.
+ * overwrite the special frozen SPTE value. Use the raw write helper to
+ * avoid an unnecessary check on volatile bits.
+ */
+ __kvm_tdp_mmu_write_spte(iter->sptep, SHADOW_NONPRESENT_VALUE);
+
+ /*
+ * Process the zapped SPTE after flushing TLBs, and after replacing
+ * FROZEN_SPTE with 0. This minimizes the amount of time vCPUs are
+ * blocked by the FROZEN_SPTE and reduces contention on the child
+ * SPTEs.
*/
- __kvm_tdp_mmu_write_spte(iter->sptep, 0);
+ handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte,
+ SHADOW_NONPRESENT_VALUE, iter->level, true);
return 0;
}
@@ -629,12 +653,12 @@ static u64 tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep,
/*
* No thread should be using this function to set SPTEs to or from the
- * temporary removed SPTE value.
+ * temporary frozen SPTE value.
* If operating under the MMU lock in read mode, tdp_mmu_set_spte_atomic
* should be used. If operating under the MMU lock in write mode, the
- * use of the removed SPTE should not be necessary.
+ * use of the frozen SPTE should not be necessary.
*/
- WARN_ON_ONCE(is_removed_spte(old_spte) || is_removed_spte(new_spte));
+ WARN_ON_ONCE(is_frozen_spte(old_spte) || is_frozen_spte(new_spte));
old_spte = kvm_tdp_mmu_write_spte(sptep, old_spte, new_spte, level);
@@ -740,8 +764,8 @@ retry:
continue;
if (!shared)
- tdp_mmu_iter_set_spte(kvm, &iter, 0);
- else if (tdp_mmu_set_spte_atomic(kvm, &iter, 0))
+ tdp_mmu_iter_set_spte(kvm, &iter, SHADOW_NONPRESENT_VALUE);
+ else if (tdp_mmu_set_spte_atomic(kvm, &iter, SHADOW_NONPRESENT_VALUE))
goto retry;
}
}
@@ -808,8 +832,8 @@ bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
if (WARN_ON_ONCE(!is_shadow_present_pte(old_spte)))
return false;
- tdp_mmu_set_spte(kvm, kvm_mmu_page_as_id(sp), sp->ptep, old_spte, 0,
- sp->gfn, sp->role.level + 1);
+ tdp_mmu_set_spte(kvm, kvm_mmu_page_as_id(sp), sp->ptep, old_spte,
+ SHADOW_NONPRESENT_VALUE, sp->gfn, sp->role.level + 1);
return true;
}
@@ -843,7 +867,7 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root,
!is_last_spte(iter.old_spte, iter.level))
continue;
- tdp_mmu_iter_set_spte(kvm, &iter, 0);
+ tdp_mmu_iter_set_spte(kvm, &iter, SHADOW_NONPRESENT_VALUE);
/*
* Zappings SPTEs in invalid roots doesn't require a TLB flush,
@@ -1028,7 +1052,7 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu,
}
/* If a MMIO SPTE is installed, the MMIO will need to be emulated. */
- if (unlikely(is_mmio_spte(new_spte))) {
+ if (unlikely(is_mmio_spte(vcpu->kvm, new_spte))) {
vcpu->stat.pf_mmio_spte_created++;
trace_mark_mmio_spte(rcu_dereference(iter->sptep), iter->gfn,
new_spte);
@@ -1103,7 +1127,7 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
* If SPTE has been frozen by another thread, just give up and
* retry, avoiding unnecessary page table allocation and free.
*/
- if (is_removed_spte(iter.old_spte))
+ if (is_frozen_spte(iter.old_spte))
goto retry;
if (iter.level == fault->goal_level)
@@ -1258,52 +1282,6 @@ bool kvm_tdp_mmu_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
return kvm_tdp_mmu_handle_gfn(kvm, range, test_age_gfn);
}
-static bool set_spte_gfn(struct kvm *kvm, struct tdp_iter *iter,
- struct kvm_gfn_range *range)
-{
- u64 new_spte;
-
- /* Huge pages aren't expected to be modified without first being zapped. */
- WARN_ON_ONCE(pte_huge(range->arg.pte) || range->start + 1 != range->end);
-
- if (iter->level != PG_LEVEL_4K ||
- !is_shadow_present_pte(iter->old_spte))
- return false;
-
- /*
- * Note, when changing a read-only SPTE, it's not strictly necessary to
- * zero the SPTE before setting the new PFN, but doing so preserves the
- * invariant that the PFN of a present * leaf SPTE can never change.
- * See handle_changed_spte().
- */
- tdp_mmu_iter_set_spte(kvm, iter, 0);
-
- if (!pte_write(range->arg.pte)) {
- new_spte = kvm_mmu_changed_pte_notifier_make_spte(iter->old_spte,
- pte_pfn(range->arg.pte));
-
- tdp_mmu_iter_set_spte(kvm, iter, new_spte);
- }
-
- return true;
-}
-
-/*
- * 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.
- */
-bool kvm_tdp_mmu_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
-{
- /*
- * No need to handle the remote TLB flush under RCU protection, the
- * target SPTE _must_ be a leaf SPTE, i.e. cannot result in freeing a
- * shadow page. See the WARN on pfn_changed in handle_changed_spte().
- */
- return kvm_tdp_mmu_handle_gfn(kvm, range, set_spte_gfn);
-}
-
/*
* Remove write access from all SPTEs at or above min_level that map GFNs
* [start, end). Returns true if an SPTE has been changed and the TLBs need to
@@ -1362,17 +1340,15 @@ bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm,
return spte_set;
}
-static struct kvm_mmu_page *__tdp_mmu_alloc_sp_for_split(gfp_t gfp)
+static struct kvm_mmu_page *tdp_mmu_alloc_sp_for_split(void)
{
struct kvm_mmu_page *sp;
- gfp |= __GFP_ZERO;
-
- sp = kmem_cache_alloc(mmu_page_header_cache, gfp);
+ sp = kmem_cache_zalloc(mmu_page_header_cache, GFP_KERNEL_ACCOUNT);
if (!sp)
return NULL;
- sp->spt = (void *)__get_free_page(gfp);
+ sp->spt = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT);
if (!sp->spt) {
kmem_cache_free(mmu_page_header_cache, sp);
return NULL;
@@ -1381,47 +1357,6 @@ static struct kvm_mmu_page *__tdp_mmu_alloc_sp_for_split(gfp_t gfp)
return sp;
}
-static struct kvm_mmu_page *tdp_mmu_alloc_sp_for_split(struct kvm *kvm,
- struct tdp_iter *iter,
- bool shared)
-{
- struct kvm_mmu_page *sp;
-
- kvm_lockdep_assert_mmu_lock_held(kvm, shared);
-
- /*
- * Since we are allocating while under the MMU lock we have to be
- * careful about GFP flags. Use GFP_NOWAIT to avoid blocking on direct
- * reclaim and to avoid making any filesystem callbacks (which can end
- * up invoking KVM MMU notifiers, resulting in a deadlock).
- *
- * If this allocation fails we drop the lock and retry with reclaim
- * allowed.
- */
- sp = __tdp_mmu_alloc_sp_for_split(GFP_NOWAIT | __GFP_ACCOUNT);
- if (sp)
- return sp;
-
- rcu_read_unlock();
-
- if (shared)
- read_unlock(&kvm->mmu_lock);
- else
- write_unlock(&kvm->mmu_lock);
-
- iter->yielded = true;
- sp = __tdp_mmu_alloc_sp_for_split(GFP_KERNEL_ACCOUNT);
-
- if (shared)
- read_lock(&kvm->mmu_lock);
- else
- write_lock(&kvm->mmu_lock);
-
- rcu_read_lock();
-
- return sp;
-}
-
/* Note, the caller is responsible for initializing @sp. */
static int tdp_mmu_split_huge_page(struct kvm *kvm, struct tdp_iter *iter,
struct kvm_mmu_page *sp, bool shared)
@@ -1468,7 +1403,6 @@ static int tdp_mmu_split_huge_pages_root(struct kvm *kvm,
{
struct kvm_mmu_page *sp = NULL;
struct tdp_iter iter;
- int ret = 0;
rcu_read_lock();
@@ -1492,17 +1426,31 @@ retry:
continue;
if (!sp) {
- sp = tdp_mmu_alloc_sp_for_split(kvm, &iter, shared);
+ rcu_read_unlock();
+
+ if (shared)
+ read_unlock(&kvm->mmu_lock);
+ else
+ write_unlock(&kvm->mmu_lock);
+
+ sp = tdp_mmu_alloc_sp_for_split();
+
+ if (shared)
+ read_lock(&kvm->mmu_lock);
+ else
+ write_lock(&kvm->mmu_lock);
+
if (!sp) {
- ret = -ENOMEM;
trace_kvm_mmu_split_huge_page(iter.gfn,
iter.old_spte,
- iter.level, ret);
- break;
+ iter.level, -ENOMEM);
+ return -ENOMEM;
}
- if (iter.yielded)
- continue;
+ rcu_read_lock();
+
+ iter.yielded = true;
+ continue;
}
tdp_mmu_init_child_sp(sp, &iter);
@@ -1523,7 +1471,7 @@ retry:
if (sp)
tdp_mmu_free_sp(sp);
- return ret;
+ return 0;
}
@@ -1824,12 +1772,11 @@ int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes,
*
* WARNING: This function is only intended to be called during fast_page_fault.
*/
-u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, u64 addr,
+u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, gfn_t gfn,
u64 *spte)
{
struct tdp_iter iter;
struct kvm_mmu *mmu = vcpu->arch.mmu;
- gfn_t gfn = addr >> PAGE_SHIFT;
tdp_ptep_t sptep = NULL;
tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) {
diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h
index 6e1ea04ca885..1b74e058a81c 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.h
+++ b/arch/x86/kvm/mmu/tdp_mmu.h
@@ -31,7 +31,6 @@ bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range,
bool flush);
bool kvm_tdp_mmu_age_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range);
bool kvm_tdp_mmu_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
-bool kvm_tdp_mmu_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm,
const struct kvm_memory_slot *slot, int min_level);
@@ -65,7 +64,7 @@ static inline void kvm_tdp_mmu_walk_lockless_end(void)
int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes,
int *root_level);
-u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, u64 addr,
+u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, gfn_t gfn,
u64 *spte);
#ifdef CONFIG_X86_64
diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
index a67c28a56417..05490b9d8a43 100644
--- a/arch/x86/kvm/mtrr.c
+++ b/arch/x86/kvm/mtrr.c
@@ -19,33 +19,21 @@
#include <asm/mtrr.h>
#include "cpuid.h"
-#include "mmu.h"
-#define IA32_MTRR_DEF_TYPE_E (1ULL << 11)
-#define IA32_MTRR_DEF_TYPE_FE (1ULL << 10)
-#define IA32_MTRR_DEF_TYPE_TYPE_MASK (0xff)
-
-static bool is_mtrr_base_msr(unsigned int msr)
-{
- /* MTRR base MSRs use even numbers, masks use odd numbers. */
- return !(msr & 0x1);
-}
-
-static struct kvm_mtrr_range *var_mtrr_msr_to_range(struct kvm_vcpu *vcpu,
- unsigned int msr)
+static u64 *find_mtrr(struct kvm_vcpu *vcpu, unsigned int msr)
{
- int index = (msr - MTRRphysBase_MSR(0)) / 2;
-
- return &vcpu->arch.mtrr_state.var_ranges[index];
-}
+ int index;
-static bool msr_mtrr_valid(unsigned msr)
-{
switch (msr) {
case MTRRphysBase_MSR(0) ... MTRRphysMask_MSR(KVM_NR_VAR_MTRR - 1):
+ index = msr - MTRRphysBase_MSR(0);
+ return &vcpu->arch.mtrr_state.var[index];
case MSR_MTRRfix64K_00000:
+ return &vcpu->arch.mtrr_state.fixed_64k;
case MSR_MTRRfix16K_80000:
case MSR_MTRRfix16K_A0000:
+ index = msr - MSR_MTRRfix16K_80000;
+ return &vcpu->arch.mtrr_state.fixed_16k[index];
case MSR_MTRRfix4K_C0000:
case MSR_MTRRfix4K_C8000:
case MSR_MTRRfix4K_D0000:
@@ -54,10 +42,14 @@ static bool msr_mtrr_valid(unsigned msr)
case MSR_MTRRfix4K_E8000:
case MSR_MTRRfix4K_F0000:
case MSR_MTRRfix4K_F8000:
+ index = msr - MSR_MTRRfix4K_C0000;
+ return &vcpu->arch.mtrr_state.fixed_4k[index];
case MSR_MTRRdefType:
- return true;
+ return &vcpu->arch.mtrr_state.deftype;
+ default:
+ break;
}
- return false;
+ return NULL;
}
static bool valid_mtrr_type(unsigned t)
@@ -70,9 +62,6 @@ static bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
int i;
u64 mask;
- if (!msr_mtrr_valid(msr))
- return false;
-
if (msr == MSR_MTRRdefType) {
if (data & ~0xcff)
return false;
@@ -85,8 +74,9 @@ static bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
}
/* variable MTRRs */
- WARN_ON(!(msr >= MTRRphysBase_MSR(0) &&
- msr <= MTRRphysMask_MSR(KVM_NR_VAR_MTRR - 1)));
+ if (WARN_ON_ONCE(!(msr >= MTRRphysBase_MSR(0) &&
+ msr <= MTRRphysMask_MSR(KVM_NR_VAR_MTRR - 1))))
+ return false;
mask = kvm_vcpu_reserved_gpa_bits_raw(vcpu);
if ((msr & 1) == 0) {
@@ -94,309 +84,32 @@ static bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
if (!valid_mtrr_type(data & 0xff))
return false;
mask |= 0xf00;
- } else
+ } else {
/* MTRR mask */
mask |= 0x7ff;
-
- return (data & mask) == 0;
-}
-
-static bool mtrr_is_enabled(struct kvm_mtrr *mtrr_state)
-{
- return !!(mtrr_state->deftype & IA32_MTRR_DEF_TYPE_E);
-}
-
-static bool fixed_mtrr_is_enabled(struct kvm_mtrr *mtrr_state)
-{
- return !!(mtrr_state->deftype & IA32_MTRR_DEF_TYPE_FE);
-}
-
-static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
-{
- return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
-}
-
-static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu)
-{
- /*
- * Intel SDM 11.11.2.2: all MTRRs are disabled when
- * IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
- * memory type is applied to all of physical memory.
- *
- * However, virtual machines can be run with CPUID such that
- * there are no MTRRs. In that case, the firmware will never
- * enable MTRRs and it is obviously undesirable to run the
- * guest entirely with UC memory and we use WB.
- */
- if (guest_cpuid_has(vcpu, X86_FEATURE_MTRR))
- return MTRR_TYPE_UNCACHABLE;
- else
- return MTRR_TYPE_WRBACK;
-}
-
-/*
-* Three terms are used in the following code:
-* - segment, it indicates the address segments covered by fixed MTRRs.
-* - unit, it corresponds to the MSR entry in the segment.
-* - range, a range is covered in one memory cache type.
-*/
-struct fixed_mtrr_segment {
- u64 start;
- u64 end;
-
- int range_shift;
-
- /* the start position in kvm_mtrr.fixed_ranges[]. */
- int range_start;
-};
-
-static struct fixed_mtrr_segment fixed_seg_table[] = {
- /* MSR_MTRRfix64K_00000, 1 unit. 64K fixed mtrr. */
- {
- .start = 0x0,
- .end = 0x80000,
- .range_shift = 16, /* 64K */
- .range_start = 0,
- },
-
- /*
- * MSR_MTRRfix16K_80000 ... MSR_MTRRfix16K_A0000, 2 units,
- * 16K fixed mtrr.
- */
- {
- .start = 0x80000,
- .end = 0xc0000,
- .range_shift = 14, /* 16K */
- .range_start = 8,
- },
-
- /*
- * MSR_MTRRfix4K_C0000 ... MSR_MTRRfix4K_F8000, 8 units,
- * 4K fixed mtrr.
- */
- {
- .start = 0xc0000,
- .end = 0x100000,
- .range_shift = 12, /* 12K */
- .range_start = 24,
- }
-};
-
-/*
- * The size of unit is covered in one MSR, one MSR entry contains
- * 8 ranges so that unit size is always 8 * 2^range_shift.
- */
-static u64 fixed_mtrr_seg_unit_size(int seg)
-{
- return 8 << fixed_seg_table[seg].range_shift;
-}
-
-static bool fixed_msr_to_seg_unit(u32 msr, int *seg, int *unit)
-{
- switch (msr) {
- case MSR_MTRRfix64K_00000:
- *seg = 0;
- *unit = 0;
- break;
- case MSR_MTRRfix16K_80000 ... MSR_MTRRfix16K_A0000:
- *seg = 1;
- *unit = array_index_nospec(
- msr - MSR_MTRRfix16K_80000,
- MSR_MTRRfix16K_A0000 - MSR_MTRRfix16K_80000 + 1);
- break;
- case MSR_MTRRfix4K_C0000 ... MSR_MTRRfix4K_F8000:
- *seg = 2;
- *unit = array_index_nospec(
- msr - MSR_MTRRfix4K_C0000,
- MSR_MTRRfix4K_F8000 - MSR_MTRRfix4K_C0000 + 1);
- break;
- default:
- return false;
}
- return true;
-}
-
-static void fixed_mtrr_seg_unit_range(int seg, int unit, u64 *start, u64 *end)
-{
- struct fixed_mtrr_segment *mtrr_seg = &fixed_seg_table[seg];
- u64 unit_size = fixed_mtrr_seg_unit_size(seg);
-
- *start = mtrr_seg->start + unit * unit_size;
- *end = *start + unit_size;
- WARN_ON(*end > mtrr_seg->end);
-}
-
-static int fixed_mtrr_seg_unit_range_index(int seg, int unit)
-{
- struct fixed_mtrr_segment *mtrr_seg = &fixed_seg_table[seg];
-
- WARN_ON(mtrr_seg->start + unit * fixed_mtrr_seg_unit_size(seg)
- > mtrr_seg->end);
-
- /* each unit has 8 ranges. */
- return mtrr_seg->range_start + 8 * unit;
-}
-
-static int fixed_mtrr_seg_end_range_index(int seg)
-{
- struct fixed_mtrr_segment *mtrr_seg = &fixed_seg_table[seg];
- int n;
-
- n = (mtrr_seg->end - mtrr_seg->start) >> mtrr_seg->range_shift;
- return mtrr_seg->range_start + n - 1;
-}
-
-static bool fixed_msr_to_range(u32 msr, u64 *start, u64 *end)
-{
- int seg, unit;
-
- if (!fixed_msr_to_seg_unit(msr, &seg, &unit))
- return false;
-
- fixed_mtrr_seg_unit_range(seg, unit, start, end);
- return true;
-}
-
-static int fixed_msr_to_range_index(u32 msr)
-{
- int seg, unit;
-
- if (!fixed_msr_to_seg_unit(msr, &seg, &unit))
- return -1;
-
- return fixed_mtrr_seg_unit_range_index(seg, unit);
-}
-
-static int fixed_mtrr_addr_to_seg(u64 addr)
-{
- struct fixed_mtrr_segment *mtrr_seg;
- int seg, seg_num = ARRAY_SIZE(fixed_seg_table);
-
- for (seg = 0; seg < seg_num; seg++) {
- mtrr_seg = &fixed_seg_table[seg];
- if (mtrr_seg->start <= addr && addr < mtrr_seg->end)
- return seg;
- }
-
- return -1;
-}
-
-static int fixed_mtrr_addr_seg_to_range_index(u64 addr, int seg)
-{
- struct fixed_mtrr_segment *mtrr_seg;
- int index;
-
- mtrr_seg = &fixed_seg_table[seg];
- index = mtrr_seg->range_start;
- index += (addr - mtrr_seg->start) >> mtrr_seg->range_shift;
- return index;
-}
-
-static u64 fixed_mtrr_range_end_addr(int seg, int index)
-{
- struct fixed_mtrr_segment *mtrr_seg = &fixed_seg_table[seg];
- int pos = index - mtrr_seg->range_start;
-
- return mtrr_seg->start + ((pos + 1) << mtrr_seg->range_shift);
-}
-
-static void var_mtrr_range(struct kvm_mtrr_range *range, u64 *start, u64 *end)
-{
- u64 mask;
-
- *start = range->base & PAGE_MASK;
-
- mask = range->mask & PAGE_MASK;
-
- /* This cannot overflow because writing to the reserved bits of
- * variable MTRRs causes a #GP.
- */
- *end = (*start | ~mask) + 1;
-}
-
-static void update_mtrr(struct kvm_vcpu *vcpu, u32 msr)
-{
- struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
- gfn_t start, end;
-
- if (!kvm_mmu_honors_guest_mtrrs(vcpu->kvm))
- return;
-
- if (!mtrr_is_enabled(mtrr_state) && msr != MSR_MTRRdefType)
- return;
-
- /* fixed MTRRs. */
- if (fixed_msr_to_range(msr, &start, &end)) {
- if (!fixed_mtrr_is_enabled(mtrr_state))
- return;
- } else if (msr == MSR_MTRRdefType) {
- start = 0x0;
- end = ~0ULL;
- } else {
- /* variable range MTRRs. */
- var_mtrr_range(var_mtrr_msr_to_range(vcpu, msr), &start, &end);
- }
-
- kvm_zap_gfn_range(vcpu->kvm, gpa_to_gfn(start), gpa_to_gfn(end));
-}
-
-static bool var_mtrr_range_is_valid(struct kvm_mtrr_range *range)
-{
- return (range->mask & (1 << 11)) != 0;
-}
-
-static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
-{
- struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
- struct kvm_mtrr_range *tmp, *cur;
-
- cur = var_mtrr_msr_to_range(vcpu, msr);
-
- /* remove the entry if it's in the list. */
- if (var_mtrr_range_is_valid(cur))
- list_del(&cur->node);
-
- /*
- * Set all illegal GPA bits in the mask, since those bits must
- * implicitly be 0. The bits are then cleared when reading them.
- */
- if (is_mtrr_base_msr(msr))
- cur->base = data;
- else
- cur->mask = data | kvm_vcpu_reserved_gpa_bits_raw(vcpu);
-
- /* add it to the list if it's enabled. */
- if (var_mtrr_range_is_valid(cur)) {
- list_for_each_entry(tmp, &mtrr_state->head, node)
- if (cur->base >= tmp->base)
- break;
- list_add_tail(&cur->node, &tmp->node);
- }
+ return (data & mask) == 0;
}
int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
- int index;
+ u64 *mtrr;
- if (!kvm_mtrr_valid(vcpu, msr, data))
+ mtrr = find_mtrr(vcpu, msr);
+ if (!mtrr)
return 1;
- index = fixed_msr_to_range_index(msr);
- if (index >= 0)
- *(u64 *)&vcpu->arch.mtrr_state.fixed_ranges[index] = data;
- else if (msr == MSR_MTRRdefType)
- vcpu->arch.mtrr_state.deftype = data;
- else
- set_var_mtrr_msr(vcpu, msr, data);
+ if (!kvm_mtrr_valid(vcpu, msr, data))
+ return 1;
- update_mtrr(vcpu, msr);
+ *mtrr = data;
return 0;
}
int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
{
- int index;
+ u64 *mtrr;
/* MSR_MTRRcap is a readonly MSR. */
if (msr == MSR_MTRRcap) {
@@ -410,311 +123,10 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
return 0;
}
- if (!msr_mtrr_valid(msr))
+ mtrr = find_mtrr(vcpu, msr);
+ if (!mtrr)
return 1;
- index = fixed_msr_to_range_index(msr);
- if (index >= 0) {
- *pdata = *(u64 *)&vcpu->arch.mtrr_state.fixed_ranges[index];
- } else if (msr == MSR_MTRRdefType) {
- *pdata = vcpu->arch.mtrr_state.deftype;
- } else {
- /* Variable MTRRs */
- if (is_mtrr_base_msr(msr))
- *pdata = var_mtrr_msr_to_range(vcpu, msr)->base;
- else
- *pdata = var_mtrr_msr_to_range(vcpu, msr)->mask;
-
- *pdata &= ~kvm_vcpu_reserved_gpa_bits_raw(vcpu);
- }
-
+ *pdata = *mtrr;
return 0;
}
-
-void kvm_vcpu_mtrr_init(struct kvm_vcpu *vcpu)
-{
- INIT_LIST_HEAD(&vcpu->arch.mtrr_state.head);
-}
-
-struct mtrr_iter {
- /* input fields. */
- struct kvm_mtrr *mtrr_state;
- u64 start;
- u64 end;
-
- /* output fields. */
- int mem_type;
- /* mtrr is completely disabled? */
- bool mtrr_disabled;
- /* [start, end) is not fully covered in MTRRs? */
- bool partial_map;
-
- /* private fields. */
- union {
- /* used for fixed MTRRs. */
- struct {
- int index;
- int seg;
- };
-
- /* used for var MTRRs. */
- struct {
- struct kvm_mtrr_range *range;
- /* max address has been covered in var MTRRs. */
- u64 start_max;
- };
- };
-
- bool fixed;
-};
-
-static bool mtrr_lookup_fixed_start(struct mtrr_iter *iter)
-{
- int seg, index;
-
- if (!fixed_mtrr_is_enabled(iter->mtrr_state))
- return false;
-
- seg = fixed_mtrr_addr_to_seg(iter->start);
- if (seg < 0)
- return false;
-
- iter->fixed = true;
- index = fixed_mtrr_addr_seg_to_range_index(iter->start, seg);
- iter->index = index;
- iter->seg = seg;
- return true;
-}
-
-static bool match_var_range(struct mtrr_iter *iter,
- struct kvm_mtrr_range *range)
-{
- u64 start, end;
-
- var_mtrr_range(range, &start, &end);
- if (!(start >= iter->end || end <= iter->start)) {
- iter->range = range;
-
- /*
- * the function is called when we do kvm_mtrr.head walking.
- * Range has the minimum base address which interleaves
- * [looker->start_max, looker->end).
- */
- iter->partial_map |= iter->start_max < start;
-
- /* update the max address has been covered. */
- iter->start_max = max(iter->start_max, end);
- return true;
- }
-
- return false;
-}
-
-static void __mtrr_lookup_var_next(struct mtrr_iter *iter)
-{
- struct kvm_mtrr *mtrr_state = iter->mtrr_state;
-
- list_for_each_entry_continue(iter->range, &mtrr_state->head, node)
- if (match_var_range(iter, iter->range))
- return;
-
- iter->range = NULL;
- iter->partial_map |= iter->start_max < iter->end;
-}
-
-static void mtrr_lookup_var_start(struct mtrr_iter *iter)
-{
- struct kvm_mtrr *mtrr_state = iter->mtrr_state;
-
- iter->fixed = false;
- iter->start_max = iter->start;
- iter->range = NULL;
- iter->range = list_prepare_entry(iter->range, &mtrr_state->head, node);
-
- __mtrr_lookup_var_next(iter);
-}
-
-static void mtrr_lookup_fixed_next(struct mtrr_iter *iter)
-{
- /* terminate the lookup. */
- if (fixed_mtrr_range_end_addr(iter->seg, iter->index) >= iter->end) {
- iter->fixed = false;
- iter->range = NULL;
- return;
- }
-
- iter->index++;
-
- /* have looked up for all fixed MTRRs. */
- if (iter->index >= ARRAY_SIZE(iter->mtrr_state->fixed_ranges))
- return mtrr_lookup_var_start(iter);
-
- /* switch to next segment. */
- if (iter->index > fixed_mtrr_seg_end_range_index(iter->seg))
- iter->seg++;
-}
-
-static void mtrr_lookup_var_next(struct mtrr_iter *iter)
-{
- __mtrr_lookup_var_next(iter);
-}
-
-static void mtrr_lookup_start(struct mtrr_iter *iter)
-{
- if (!mtrr_is_enabled(iter->mtrr_state)) {
- iter->mtrr_disabled = true;
- return;
- }
-
- if (!mtrr_lookup_fixed_start(iter))
- mtrr_lookup_var_start(iter);
-}
-
-static void mtrr_lookup_init(struct mtrr_iter *iter,
- struct kvm_mtrr *mtrr_state, u64 start, u64 end)
-{
- iter->mtrr_state = mtrr_state;
- iter->start = start;
- iter->end = end;
- iter->mtrr_disabled = false;
- iter->partial_map = false;
- iter->fixed = false;
- iter->range = NULL;
-
- mtrr_lookup_start(iter);
-}
-
-static bool mtrr_lookup_okay(struct mtrr_iter *iter)
-{
- if (iter->fixed) {
- iter->mem_type = iter->mtrr_state->fixed_ranges[iter->index];
- return true;
- }
-
- if (iter->range) {
- iter->mem_type = iter->range->base & 0xff;
- return true;
- }
-
- return false;
-}
-
-static void mtrr_lookup_next(struct mtrr_iter *iter)
-{
- if (iter->fixed)
- mtrr_lookup_fixed_next(iter);
- else
- mtrr_lookup_var_next(iter);
-}
-
-#define mtrr_for_each_mem_type(_iter_, _mtrr_, _gpa_start_, _gpa_end_) \
- for (mtrr_lookup_init(_iter_, _mtrr_, _gpa_start_, _gpa_end_); \
- mtrr_lookup_okay(_iter_); mtrr_lookup_next(_iter_))
-
-u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
-{
- struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
- struct mtrr_iter iter;
- u64 start, end;
- int type = -1;
- const int wt_wb_mask = (1 << MTRR_TYPE_WRBACK)
- | (1 << MTRR_TYPE_WRTHROUGH);
-
- start = gfn_to_gpa(gfn);
- end = start + PAGE_SIZE;
-
- mtrr_for_each_mem_type(&iter, mtrr_state, start, end) {
- int curr_type = iter.mem_type;
-
- /*
- * Please refer to Intel SDM Volume 3: 11.11.4.1 MTRR
- * Precedences.
- */
-
- if (type == -1) {
- type = curr_type;
- continue;
- }
-
- /*
- * If two or more variable memory ranges match and the
- * memory types are identical, then that memory type is
- * used.
- */
- if (type == curr_type)
- continue;
-
- /*
- * If two or more variable memory ranges match and one of
- * the memory types is UC, the UC memory type used.
- */
- if (curr_type == MTRR_TYPE_UNCACHABLE)
- return MTRR_TYPE_UNCACHABLE;
-
- /*
- * If two or more variable memory ranges match and the
- * memory types are WT and WB, the WT memory type is used.
- */
- if (((1 << type) & wt_wb_mask) &&
- ((1 << curr_type) & wt_wb_mask)) {
- type = MTRR_TYPE_WRTHROUGH;
- continue;
- }
-
- /*
- * For overlaps not defined by the above rules, processor
- * behavior is undefined.
- */
-
- /* We use WB for this undefined behavior. :( */
- return MTRR_TYPE_WRBACK;
- }
-
- if (iter.mtrr_disabled)
- return mtrr_disabled_type(vcpu);
-
- /* not contained in any MTRRs. */
- if (type == -1)
- return mtrr_default_type(mtrr_state);
-
- /*
- * We just check one page, partially covered by MTRRs is
- * impossible.
- */
- WARN_ON(iter.partial_map);
-
- return type;
-}
-EXPORT_SYMBOL_GPL(kvm_mtrr_get_guest_memory_type);
-
-bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
- int page_num)
-{
- struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
- struct mtrr_iter iter;
- u64 start, end;
- int type = -1;
-
- start = gfn_to_gpa(gfn);
- end = gfn_to_gpa(gfn + page_num);
- mtrr_for_each_mem_type(&iter, mtrr_state, start, end) {
- if (type == -1) {
- type = iter.mem_type;
- continue;
- }
-
- if (type != iter.mem_type)
- return false;
- }
-
- if (iter.mtrr_disabled)
- return true;
-
- if (!iter.partial_map)
- return true;
-
- if (type == -1)
- return true;
-
- return type == mtrr_default_type(mtrr_state);
-}
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index a593b03c9aed..47a46283c866 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -34,16 +34,16 @@ EXPORT_SYMBOL_GPL(kvm_pmu_eventsel);
/* Precise Distribution of Instructions Retired (PDIR) */
static const struct x86_cpu_id vmx_pebs_pdir_cpu[] = {
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, NULL),
- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, NULL),
+ X86_MATCH_VFM(INTEL_ICELAKE_D, NULL),
+ X86_MATCH_VFM(INTEL_ICELAKE_X, NULL),
/* Instruction-Accurate PDIR (PDIR++) */
- X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, NULL),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, NULL),
{}
};
/* Precise Distribution (PDist) */
static const struct x86_cpu_id vmx_pebs_pdist_cpu[] = {
- X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, NULL),
+ X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, NULL),
{}
};
@@ -69,7 +69,7 @@ static const struct x86_cpu_id vmx_pebs_pdist_cpu[] = {
* code. Each pmc, stored in kvm_pmc.idx field, is unique across
* all perf counters (both gp and fixed). The mapping relationship
* between pmc and perf counters is as the following:
- * * Intel: [0 .. KVM_INTEL_PMC_MAX_GENERIC-1] <=> gp counters
+ * * Intel: [0 .. KVM_MAX_NR_INTEL_GP_COUNTERS-1] <=> gp counters
* [KVM_FIXED_PMC_BASE_IDX .. KVM_FIXED_PMC_BASE_IDX + 2] <=> fixed
* * AMD: [0 .. AMD64_NUM_COUNTERS-1] and, for families 15H
* and later, [0 .. AMD64_NUM_COUNTERS_CORE-1] <=> gp counters
@@ -194,7 +194,7 @@ static int pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type, u64 config,
attr.sample_period = get_sample_period(pmc, pmc->counter);
if ((attr.config & HSW_IN_TX_CHECKPOINTED) &&
- guest_cpuid_is_intel(pmc->vcpu)) {
+ (boot_cpu_has(X86_FEATURE_RTM) || boot_cpu_has(X86_FEATURE_HLE))) {
/*
* HSW_IN_TX_CHECKPOINTED is not supported with nonzero
* period. Just clear the sample period so at least
@@ -469,11 +469,11 @@ static int reprogram_counter(struct kvm_pmc *pmc)
if (pmc_is_fixed(pmc)) {
fixed_ctr_ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl,
pmc->idx - KVM_FIXED_PMC_BASE_IDX);
- if (fixed_ctr_ctrl & 0x1)
+ if (fixed_ctr_ctrl & INTEL_FIXED_0_KERNEL)
eventsel |= ARCH_PERFMON_EVENTSEL_OS;
- if (fixed_ctr_ctrl & 0x2)
+ if (fixed_ctr_ctrl & INTEL_FIXED_0_USER)
eventsel |= ARCH_PERFMON_EVENTSEL_USR;
- if (fixed_ctr_ctrl & 0x8)
+ if (fixed_ctr_ctrl & INTEL_FIXED_0_ENABLE_PMI)
eventsel |= ARCH_PERFMON_EVENTSEL_INT;
new_config = (u64)fixed_ctr_ctrl;
}
@@ -521,9 +521,9 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
}
/*
- * Unused perf_events are only released if the corresponding MSRs
- * weren't accessed during the last vCPU time slice. kvm_arch_sched_in
- * triggers KVM_REQ_PMU if cleanup is needed.
+ * Release unused perf_events if the corresponding guest MSRs weren't
+ * accessed during the last vCPU time slice (need_cleanup is set when
+ * the vCPU is scheduled back in).
*/
if (unlikely(pmu->need_cleanup))
kvm_pmu_cleanup(vcpu);
@@ -542,7 +542,7 @@ int kvm_pmu_check_rdpmc_early(struct kvm_vcpu *vcpu, unsigned int idx)
if (!kvm_pmu_ops.check_rdpmc_early)
return 0;
- return static_call(kvm_x86_pmu_check_rdpmc_early)(vcpu, idx);
+ return kvm_pmu_call(check_rdpmc_early)(vcpu, idx);
}
bool is_vmware_backdoor_pmc(u32 pmc_idx)
@@ -591,12 +591,12 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
if (is_vmware_backdoor_pmc(idx))
return kvm_pmu_rdpmc_vmware(vcpu, idx, data);
- pmc = static_call(kvm_x86_pmu_rdpmc_ecx_to_pmc)(vcpu, idx, &mask);
+ pmc = kvm_pmu_call(rdpmc_ecx_to_pmc)(vcpu, idx, &mask);
if (!pmc)
return 1;
if (!kvm_is_cr4_bit_set(vcpu, X86_CR4_PCE) &&
- (static_call(kvm_x86_get_cpl)(vcpu) != 0) &&
+ (kvm_x86_call(get_cpl)(vcpu) != 0) &&
kvm_is_cr0_bit_set(vcpu, X86_CR0_PE))
return 1;
@@ -607,7 +607,7 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
{
if (lapic_in_kernel(vcpu)) {
- static_call_cond(kvm_x86_pmu_deliver_pmi)(vcpu);
+ kvm_pmu_call(deliver_pmi)(vcpu);
kvm_apic_local_deliver(vcpu->arch.apic, APIC_LVTPC);
}
}
@@ -622,14 +622,14 @@ bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
default:
break;
}
- return static_call(kvm_x86_pmu_msr_idx_to_pmc)(vcpu, msr) ||
- static_call(kvm_x86_pmu_is_valid_msr)(vcpu, msr);
+ return kvm_pmu_call(msr_idx_to_pmc)(vcpu, msr) ||
+ kvm_pmu_call(is_valid_msr)(vcpu, msr);
}
static void kvm_pmu_mark_pmc_in_use(struct kvm_vcpu *vcpu, u32 msr)
{
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
- struct kvm_pmc *pmc = static_call(kvm_x86_pmu_msr_idx_to_pmc)(vcpu, msr);
+ struct kvm_pmc *pmc = kvm_pmu_call(msr_idx_to_pmc)(vcpu, msr);
if (pmc)
__set_bit(pmc->idx, pmu->pmc_in_use);
@@ -654,7 +654,7 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
msr_info->data = 0;
break;
default:
- return static_call(kvm_x86_pmu_get_msr)(vcpu, msr_info);
+ return kvm_pmu_call(get_msr)(vcpu, msr_info);
}
return 0;
@@ -681,13 +681,13 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
if (!msr_info->host_initiated)
break;
- if (data & pmu->global_status_mask)
+ if (data & pmu->global_status_rsvd)
return 1;
pmu->global_status = data;
break;
case MSR_AMD64_PERF_CNTR_GLOBAL_CTL:
- data &= ~pmu->global_ctrl_mask;
+ data &= ~pmu->global_ctrl_rsvd;
fallthrough;
case MSR_CORE_PERF_GLOBAL_CTRL:
if (!kvm_valid_perf_global_ctrl(pmu, data))
@@ -704,7 +704,7 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
* GLOBAL_OVF_CTRL, a.k.a. GLOBAL STATUS_RESET, clears bits in
* GLOBAL_STATUS, and so the set of reserved bits is the same.
*/
- if (data & pmu->global_status_mask)
+ if (data & pmu->global_status_rsvd)
return 1;
fallthrough;
case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR:
@@ -713,7 +713,7 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
break;
default:
kvm_pmu_mark_pmc_in_use(vcpu, msr_info->index);
- return static_call(kvm_x86_pmu_set_msr)(vcpu, msr_info);
+ return kvm_pmu_call(set_msr)(vcpu, msr_info);
}
return 0;
@@ -740,7 +740,7 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0;
- static_call_cond(kvm_x86_pmu_reset)(vcpu);
+ kvm_pmu_call(reset)(vcpu);
}
@@ -768,17 +768,17 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
pmu->reserved_bits = 0xffffffff00200000ull;
pmu->raw_event_mask = X86_RAW_EVENT_MASK;
- pmu->global_ctrl_mask = ~0ull;
- pmu->global_status_mask = ~0ull;
- pmu->fixed_ctr_ctrl_mask = ~0ull;
- pmu->pebs_enable_mask = ~0ull;
- pmu->pebs_data_cfg_mask = ~0ull;
+ pmu->global_ctrl_rsvd = ~0ull;
+ pmu->global_status_rsvd = ~0ull;
+ pmu->fixed_ctr_ctrl_rsvd = ~0ull;
+ pmu->pebs_enable_rsvd = ~0ull;
+ pmu->pebs_data_cfg_rsvd = ~0ull;
bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
if (!vcpu->kvm->arch.enable_pmu)
return;
- static_call(kvm_x86_pmu_refresh)(vcpu);
+ kvm_pmu_call(refresh)(vcpu);
/*
* At RESET, both Intel and AMD CPUs set all enable bits for general
@@ -796,7 +796,7 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu)
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
memset(pmu, 0, sizeof(*pmu));
- static_call(kvm_x86_pmu_init)(vcpu);
+ kvm_pmu_call(init)(vcpu);
kvm_pmu_refresh(vcpu);
}
@@ -818,7 +818,7 @@ void kvm_pmu_cleanup(struct kvm_vcpu *vcpu)
pmc_stop_counter(pmc);
}
- static_call_cond(kvm_x86_pmu_cleanup)(vcpu);
+ kvm_pmu_call(cleanup)(vcpu);
bitmap_zero(pmu->pmc_in_use, X86_PMC_IDX_MAX);
}
@@ -846,8 +846,8 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
} else {
config = fixed_ctrl_field(pmc_to_pmu(pmc)->fixed_ctr_ctrl,
pmc->idx - KVM_FIXED_PMC_BASE_IDX);
- select_os = config & 0x1;
- select_user = config & 0x2;
+ select_os = config & INTEL_FIXED_0_KERNEL;
+ select_user = config & INTEL_FIXED_0_USER;
}
/*
@@ -857,7 +857,8 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
if (select_os == select_user)
return select_os;
- return (static_call(kvm_x86_get_cpl)(pmc->vcpu) == 0) ? select_os : select_user;
+ return (kvm_x86_call(get_cpl)(pmc->vcpu) == 0) ? select_os :
+ select_user;
}
void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel)
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 4d52b0b539ba..ad89d0bd6005 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -14,7 +14,8 @@
MSR_IA32_MISC_ENABLE_BTS_UNAVAIL)
/* retrieve the 4 bits for EN and PMI out of IA32_FIXED_CTR_CTRL */
-#define fixed_ctrl_field(ctrl_reg, idx) (((ctrl_reg) >> ((idx)*4)) & 0xf)
+#define fixed_ctrl_field(ctrl_reg, idx) \
+ (((ctrl_reg) >> ((idx) * INTEL_FIXED_BITS_STRIDE)) & INTEL_FIXED_BITS_MASK)
#define VMWARE_BACKDOOR_PMC_HOST_TSC 0x10000
#define VMWARE_BACKDOOR_PMC_REAL_TIME 0x10001
@@ -129,7 +130,7 @@ static inline bool pmc_is_fixed(struct kvm_pmc *pmc)
static inline bool kvm_valid_perf_global_ctrl(struct kvm_pmu *pmu,
u64 data)
{
- return !(pmu->global_ctrl_mask & data);
+ return !(pmu->global_ctrl_rsvd & data);
}
/* returns general purpose PMC with the specified MSR. Note that it can be
@@ -170,7 +171,8 @@ static inline bool pmc_speculative_in_use(struct kvm_pmc *pmc)
if (pmc_is_fixed(pmc))
return fixed_ctrl_field(pmu->fixed_ctr_ctrl,
- pmc->idx - KVM_FIXED_PMC_BASE_IDX) & 0x3;
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX) &
+ (INTEL_FIXED_0_KERNEL | INTEL_FIXED_0_USER);
return pmc->eventsel & ARCH_PERFMON_EVENTSEL_ENABLE;
}
@@ -217,7 +219,7 @@ static inline void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
kvm_pmu_cap.num_counters_gp = min(kvm_pmu_cap.num_counters_gp,
pmu_ops->MAX_NR_GP_COUNTERS);
kvm_pmu_cap.num_counters_fixed = min(kvm_pmu_cap.num_counters_fixed,
- KVM_PMC_MAX_FIXED);
+ KVM_MAX_NR_FIXED_COUNTERS);
kvm_pmu_eventsel.INSTRUCTIONS_RETIRED =
perf_get_hw_event_config(PERF_COUNT_HW_INSTRUCTIONS);
diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c
index d06d43d8d2aa..00e3c27d2a87 100644
--- a/arch/x86/kvm/smm.c
+++ b/arch/x86/kvm/smm.c
@@ -200,11 +200,11 @@ static void enter_smm_save_state_32(struct kvm_vcpu *vcpu,
enter_smm_save_seg_32(vcpu, &smram->tr, &smram->tr_sel, VCPU_SREG_TR);
enter_smm_save_seg_32(vcpu, &smram->ldtr, &smram->ldtr_sel, VCPU_SREG_LDTR);
- static_call(kvm_x86_get_gdt)(vcpu, &dt);
+ kvm_x86_call(get_gdt)(vcpu, &dt);
smram->gdtr.base = dt.address;
smram->gdtr.limit = dt.size;
- static_call(kvm_x86_get_idt)(vcpu, &dt);
+ kvm_x86_call(get_idt)(vcpu, &dt);
smram->idtr.base = dt.address;
smram->idtr.limit = dt.size;
@@ -220,7 +220,7 @@ static void enter_smm_save_state_32(struct kvm_vcpu *vcpu,
smram->smm_revision = 0x00020000;
smram->smbase = vcpu->arch.smbase;
- smram->int_shadow = static_call(kvm_x86_get_interrupt_shadow)(vcpu);
+ smram->int_shadow = kvm_x86_call(get_interrupt_shadow)(vcpu);
}
#ifdef CONFIG_X86_64
@@ -250,13 +250,13 @@ static void enter_smm_save_state_64(struct kvm_vcpu *vcpu,
enter_smm_save_seg_64(vcpu, &smram->tr, VCPU_SREG_TR);
- static_call(kvm_x86_get_idt)(vcpu, &dt);
+ kvm_x86_call(get_idt)(vcpu, &dt);
smram->idtr.limit = dt.size;
smram->idtr.base = dt.address;
enter_smm_save_seg_64(vcpu, &smram->ldtr, VCPU_SREG_LDTR);
- static_call(kvm_x86_get_gdt)(vcpu, &dt);
+ kvm_x86_call(get_gdt)(vcpu, &dt);
smram->gdtr.limit = dt.size;
smram->gdtr.base = dt.address;
@@ -267,7 +267,7 @@ static void enter_smm_save_state_64(struct kvm_vcpu *vcpu,
enter_smm_save_seg_64(vcpu, &smram->fs, VCPU_SREG_FS);
enter_smm_save_seg_64(vcpu, &smram->gs, VCPU_SREG_GS);
- smram->int_shadow = static_call(kvm_x86_get_interrupt_shadow)(vcpu);
+ smram->int_shadow = kvm_x86_call(get_interrupt_shadow)(vcpu);
}
#endif
@@ -297,7 +297,7 @@ void enter_smm(struct kvm_vcpu *vcpu)
* Kill the VM in the unlikely case of failure, because the VM
* can be in undefined state in this case.
*/
- if (static_call(kvm_x86_enter_smm)(vcpu, &smram))
+ if (kvm_x86_call(enter_smm)(vcpu, &smram))
goto error;
kvm_smm_changed(vcpu, true);
@@ -305,24 +305,24 @@ void enter_smm(struct kvm_vcpu *vcpu)
if (kvm_vcpu_write_guest(vcpu, vcpu->arch.smbase + 0xfe00, &smram, sizeof(smram)))
goto error;
- if (static_call(kvm_x86_get_nmi_mask)(vcpu))
+ if (kvm_x86_call(get_nmi_mask)(vcpu))
vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK;
else
- static_call(kvm_x86_set_nmi_mask)(vcpu, true);
+ kvm_x86_call(set_nmi_mask)(vcpu, true);
kvm_set_rflags(vcpu, X86_EFLAGS_FIXED);
kvm_rip_write(vcpu, 0x8000);
- static_call(kvm_x86_set_interrupt_shadow)(vcpu, 0);
+ kvm_x86_call(set_interrupt_shadow)(vcpu, 0);
cr0 = vcpu->arch.cr0 & ~(X86_CR0_PE | X86_CR0_EM | X86_CR0_TS | X86_CR0_PG);
- static_call(kvm_x86_set_cr0)(vcpu, cr0);
+ kvm_x86_call(set_cr0)(vcpu, cr0);
- static_call(kvm_x86_set_cr4)(vcpu, 0);
+ kvm_x86_call(set_cr4)(vcpu, 0);
/* Undocumented: IDT limit is set to zero on entry to SMM. */
dt.address = dt.size = 0;
- static_call(kvm_x86_set_idt)(vcpu, &dt);
+ kvm_x86_call(set_idt)(vcpu, &dt);
if (WARN_ON_ONCE(kvm_set_dr(vcpu, 7, DR7_FIXED_1)))
goto error;
@@ -354,7 +354,7 @@ void enter_smm(struct kvm_vcpu *vcpu)
#ifdef CONFIG_X86_64
if (guest_cpuid_has(vcpu, X86_FEATURE_LM))
- if (static_call(kvm_x86_set_efer)(vcpu, 0))
+ if (kvm_x86_call(set_efer)(vcpu, 0))
goto error;
#endif
@@ -479,11 +479,11 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt,
dt.address = smstate->gdtr.base;
dt.size = smstate->gdtr.limit;
- static_call(kvm_x86_set_gdt)(vcpu, &dt);
+ kvm_x86_call(set_gdt)(vcpu, &dt);
dt.address = smstate->idtr.base;
dt.size = smstate->idtr.limit;
- static_call(kvm_x86_set_idt)(vcpu, &dt);
+ kvm_x86_call(set_idt)(vcpu, &dt);
rsm_load_seg_32(vcpu, &smstate->es, smstate->es_sel, VCPU_SREG_ES);
rsm_load_seg_32(vcpu, &smstate->cs, smstate->cs_sel, VCPU_SREG_CS);
@@ -501,7 +501,7 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt,
if (r != X86EMUL_CONTINUE)
return r;
- static_call(kvm_x86_set_interrupt_shadow)(vcpu, 0);
+ kvm_x86_call(set_interrupt_shadow)(vcpu, 0);
ctxt->interruptibility = (u8)smstate->int_shadow;
return r;
@@ -535,13 +535,13 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt,
dt.size = smstate->idtr.limit;
dt.address = smstate->idtr.base;
- static_call(kvm_x86_set_idt)(vcpu, &dt);
+ kvm_x86_call(set_idt)(vcpu, &dt);
rsm_load_seg_64(vcpu, &smstate->ldtr, VCPU_SREG_LDTR);
dt.size = smstate->gdtr.limit;
dt.address = smstate->gdtr.base;
- static_call(kvm_x86_set_gdt)(vcpu, &dt);
+ kvm_x86_call(set_gdt)(vcpu, &dt);
r = rsm_enter_protected_mode(vcpu, smstate->cr0, smstate->cr3, smstate->cr4);
if (r != X86EMUL_CONTINUE)
@@ -554,7 +554,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt,
rsm_load_seg_64(vcpu, &smstate->fs, VCPU_SREG_FS);
rsm_load_seg_64(vcpu, &smstate->gs, VCPU_SREG_GS);
- static_call(kvm_x86_set_interrupt_shadow)(vcpu, 0);
+ kvm_x86_call(set_interrupt_shadow)(vcpu, 0);
ctxt->interruptibility = (u8)smstate->int_shadow;
return X86EMUL_CONTINUE;
@@ -576,7 +576,7 @@ int emulator_leave_smm(struct x86_emulate_ctxt *ctxt)
return X86EMUL_UNHANDLEABLE;
if ((vcpu->arch.hflags & HF_SMM_INSIDE_NMI_MASK) == 0)
- static_call(kvm_x86_set_nmi_mask)(vcpu, false);
+ kvm_x86_call(set_nmi_mask)(vcpu, false);
kvm_smm_changed(vcpu, false);
@@ -628,7 +628,7 @@ int emulator_leave_smm(struct x86_emulate_ctxt *ctxt)
* state (e.g. enter guest mode) before loading state from the SMM
* state-save area.
*/
- if (static_call(kvm_x86_leave_smm)(vcpu, &smram))
+ if (kvm_x86_call(leave_smm)(vcpu, &smram))
return X86EMUL_UNHANDLEABLE;
#ifdef CONFIG_X86_64
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index 55b9a6d96bcf..6f704c1037e5 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1181,7 +1181,7 @@ int svm_allocate_nested(struct vcpu_svm *svm)
if (svm->nested.initialized)
return 0;
- vmcb02_page = snp_safe_alloc_page(&svm->vcpu);
+ vmcb02_page = snp_safe_alloc_page();
if (!vmcb02_page)
return -ENOMEM;
svm->nested.vmcb02.ptr = page_address(vmcb02_page);
diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
index dfcc38bd97d3..22d5a65b410c 100644
--- a/arch/x86/kvm/svm/pmu.c
+++ b/arch/x86/kvm/svm/pmu.c
@@ -199,8 +199,8 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
kvm_pmu_cap.num_counters_gp);
if (pmu->version > 1) {
- pmu->global_ctrl_mask = ~((1ull << pmu->nr_arch_gp_counters) - 1);
- pmu->global_status_mask = pmu->global_ctrl_mask;
+ pmu->global_ctrl_rsvd = ~((1ull << pmu->nr_arch_gp_counters) - 1);
+ pmu->global_status_rsvd = pmu->global_ctrl_rsvd;
}
pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
@@ -217,10 +217,9 @@ static void amd_pmu_init(struct kvm_vcpu *vcpu)
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
int i;
- BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > AMD64_NUM_COUNTERS_CORE);
- BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > INTEL_PMC_MAX_GENERIC);
+ BUILD_BUG_ON(KVM_MAX_NR_AMD_GP_COUNTERS > AMD64_NUM_COUNTERS_CORE);
- for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC ; i++) {
+ for (i = 0; i < KVM_MAX_NR_AMD_GP_COUNTERS; i++) {
pmu->gp_counters[i].type = KVM_PMC_GP;
pmu->gp_counters[i].vcpu = vcpu;
pmu->gp_counters[i].idx = i;
@@ -238,6 +237,6 @@ struct kvm_pmu_ops amd_pmu_ops __initdata = {
.refresh = amd_pmu_refresh,
.init = amd_pmu_init,
.EVENTSEL_EVENT = AMD64_EVENTSEL_EVENT,
- .MAX_NR_GP_COUNTERS = KVM_AMD_PMC_MAX_GENERIC,
+ .MAX_NR_GP_COUNTERS = KVM_MAX_NR_AMD_GP_COUNTERS,
.MIN_NR_GP_COUNTERS = AMD64_NUM_COUNTERS,
};
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 759581bb2128..a16c873b3232 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -19,11 +19,14 @@
#include <linux/misc_cgroup.h>
#include <linux/processor.h>
#include <linux/trace_events.h>
+#include <uapi/linux/sev-guest.h>
#include <asm/pkru.h>
#include <asm/trapnr.h>
#include <asm/fpu/xcr.h>
+#include <asm/fpu/xstate.h>
#include <asm/debugreg.h>
+#include <asm/sev.h>
#include "mmu.h"
#include "x86.h"
@@ -32,22 +35,12 @@
#include "cpuid.h"
#include "trace.h"
-#ifndef CONFIG_KVM_AMD_SEV
-/*
- * When this config is not defined, SEV feature is not supported and APIs in
- * this file are not used but this file still gets compiled into the KVM AMD
- * module.
- *
- * We will not have MISC_CG_RES_SEV and MISC_CG_RES_SEV_ES entries in the enum
- * misc_res_type {} defined in linux/misc_cgroup.h.
- *
- * Below macros allow compilation to succeed.
- */
-#define MISC_CG_RES_SEV MISC_CG_RES_TYPES
-#define MISC_CG_RES_SEV_ES MISC_CG_RES_TYPES
-#endif
+#define GHCB_VERSION_MAX 2ULL
+#define GHCB_VERSION_DEFAULT 2ULL
+#define GHCB_VERSION_MIN 1ULL
+
+#define GHCB_HV_FT_SUPPORTED (GHCB_HV_FT_SNP | GHCB_HV_FT_SNP_AP_CREATION)
-#ifdef CONFIG_KVM_AMD_SEV
/* enable/disable SEV support */
static bool sev_enabled = true;
module_param_named(sev, sev_enabled, bool, 0444);
@@ -56,14 +49,35 @@ module_param_named(sev, sev_enabled, bool, 0444);
static bool sev_es_enabled = true;
module_param_named(sev_es, sev_es_enabled, bool, 0444);
+/* enable/disable SEV-SNP support */
+static bool sev_snp_enabled = true;
+module_param_named(sev_snp, sev_snp_enabled, bool, 0444);
+
/* enable/disable SEV-ES DebugSwap support */
-static bool sev_es_debug_swap_enabled = false;
+static bool sev_es_debug_swap_enabled = true;
module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444);
-#else
-#define sev_enabled false
-#define sev_es_enabled false
-#define sev_es_debug_swap_enabled false
-#endif /* CONFIG_KVM_AMD_SEV */
+static u64 sev_supported_vmsa_features;
+
+#define AP_RESET_HOLD_NONE 0
+#define AP_RESET_HOLD_NAE_EVENT 1
+#define AP_RESET_HOLD_MSR_PROTO 2
+
+/* As defined by SEV-SNP Firmware ABI, under "Guest Policy". */
+#define SNP_POLICY_MASK_API_MINOR GENMASK_ULL(7, 0)
+#define SNP_POLICY_MASK_API_MAJOR GENMASK_ULL(15, 8)
+#define SNP_POLICY_MASK_SMT BIT_ULL(16)
+#define SNP_POLICY_MASK_RSVD_MBO BIT_ULL(17)
+#define SNP_POLICY_MASK_DEBUG BIT_ULL(19)
+#define SNP_POLICY_MASK_SINGLE_SOCKET BIT_ULL(20)
+
+#define SNP_POLICY_MASK_VALID (SNP_POLICY_MASK_API_MINOR | \
+ SNP_POLICY_MASK_API_MAJOR | \
+ SNP_POLICY_MASK_SMT | \
+ SNP_POLICY_MASK_RSVD_MBO | \
+ SNP_POLICY_MASK_DEBUG | \
+ SNP_POLICY_MASK_SINGLE_SOCKET)
+
+#define INITIAL_VMSA_GPA 0xFFFFFFFFF000
static u8 sev_enc_bit;
static DECLARE_RWSEM(sev_deactivate_lock);
@@ -75,6 +89,8 @@ static unsigned int nr_asids;
static unsigned long *sev_asid_bitmap;
static unsigned long *sev_reclaim_asid_bitmap;
+static int snp_decommission_context(struct kvm *kvm);
+
struct enc_region {
struct list_head list;
unsigned long npages;
@@ -101,19 +117,32 @@ static int sev_flush_asids(unsigned int min_asid, unsigned int max_asid)
down_write(&sev_deactivate_lock);
wbinvd_on_all_cpus();
- ret = sev_guest_df_flush(&error);
+
+ if (sev_snp_enabled)
+ ret = sev_do_cmd(SEV_CMD_SNP_DF_FLUSH, NULL, &error);
+ else
+ ret = sev_guest_df_flush(&error);
up_write(&sev_deactivate_lock);
if (ret)
- pr_err("SEV: DF_FLUSH failed, ret=%d, error=%#x\n", ret, error);
+ pr_err("SEV%s: DF_FLUSH failed, ret=%d, error=%#x\n",
+ sev_snp_enabled ? "-SNP" : "", ret, error);
return ret;
}
static inline bool is_mirroring_enc_context(struct kvm *kvm)
{
- return !!to_kvm_svm(kvm)->sev_info.enc_context_owner;
+ return !!to_kvm_sev_info(kvm)->enc_context_owner;
+}
+
+static bool sev_vcpu_has_debug_swap(struct vcpu_svm *svm)
+{
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info;
+
+ return sev->vmsa_features & SVM_SEV_FEAT_DEBUG_SWAP;
}
/* Must be called with the sev_bitmap_lock held */
@@ -234,6 +263,53 @@ static void sev_decommission(unsigned int handle)
sev_guest_decommission(&decommission, NULL);
}
+/*
+ * Transition a page to hypervisor-owned/shared state in the RMP table. This
+ * should not fail under normal conditions, but leak the page should that
+ * happen since it will no longer be usable by the host due to RMP protections.
+ */
+static int kvm_rmp_make_shared(struct kvm *kvm, u64 pfn, enum pg_level level)
+{
+ if (KVM_BUG_ON(rmp_make_shared(pfn, level), kvm)) {
+ snp_leak_pages(pfn, page_level_size(level) >> PAGE_SHIFT);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * Certain page-states, such as Pre-Guest and Firmware pages (as documented
+ * in Chapter 5 of the SEV-SNP Firmware ABI under "Page States") cannot be
+ * directly transitioned back to normal/hypervisor-owned state via RMPUPDATE
+ * unless they are reclaimed first.
+ *
+ * Until they are reclaimed and subsequently transitioned via RMPUPDATE, they
+ * might not be usable by the host due to being set as immutable or still
+ * being associated with a guest ASID.
+ *
+ * Bug the VM and leak the page if reclaim fails, or if the RMP entry can't be
+ * converted back to shared, as the page is no longer usable due to RMP
+ * protections, and it's infeasible for the guest to continue on.
+ */
+static int snp_page_reclaim(struct kvm *kvm, u64 pfn)
+{
+ struct sev_data_snp_page_reclaim data = {0};
+ int fw_err, rc;
+
+ data.paddr = __sme_set(pfn << PAGE_SHIFT);
+ rc = sev_do_cmd(SEV_CMD_SNP_PAGE_RECLAIM, &data, &fw_err);
+ if (KVM_BUG(rc, kvm, "Failed to reclaim PFN %llx, rc %d fw_err %d", pfn, rc, fw_err)) {
+ snp_leak_pages(pfn, 1);
+ return -EIO;
+ }
+
+ if (kvm_rmp_make_shared(kvm, pfn, PG_LEVEL_4K))
+ return -EIO;
+
+ return rc;
+}
+
static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
{
struct sev_data_deactivate deactivate;
@@ -251,20 +327,119 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
sev_decommission(handle);
}
-static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
+/*
+ * This sets up bounce buffers/firmware pages to handle SNP Guest Request
+ * messages (e.g. attestation requests). See "SNP Guest Request" in the GHCB
+ * 2.0 specification for more details.
+ *
+ * Technically, when an SNP Guest Request is issued, the guest will provide its
+ * own request/response pages, which could in theory be passed along directly
+ * to firmware rather than using bounce pages. However, these pages would need
+ * special care:
+ *
+ * - Both pages are from shared guest memory, so they need to be protected
+ * from migration/etc. occurring while firmware reads/writes to them. At a
+ * minimum, this requires elevating the ref counts and potentially needing
+ * an explicit pinning of the memory. This places additional restrictions
+ * on what type of memory backends userspace can use for shared guest
+ * memory since there is some reliance on using refcounted pages.
+ *
+ * - The response page needs to be switched to Firmware-owned[1] state
+ * before the firmware can write to it, which can lead to potential
+ * host RMP #PFs if the guest is misbehaved and hands the host a
+ * guest page that KVM might write to for other reasons (e.g. virtio
+ * buffers/etc.).
+ *
+ * Both of these issues can be avoided completely by using separately-allocated
+ * bounce pages for both the request/response pages and passing those to
+ * firmware instead. So that's what is being set up here.
+ *
+ * Guest requests rely on message sequence numbers to ensure requests are
+ * issued to firmware in the order the guest issues them, so concurrent guest
+ * requests generally shouldn't happen. But a misbehaved guest could issue
+ * concurrent guest requests in theory, so a mutex is used to serialize
+ * access to the bounce buffers.
+ *
+ * [1] See the "Page States" section of the SEV-SNP Firmware ABI for more
+ * details on Firmware-owned pages, along with "RMP and VMPL Access Checks"
+ * in the APM for details on the related RMP restrictions.
+ */
+static int snp_guest_req_init(struct kvm *kvm)
+{
+ struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
+ struct page *req_page;
+
+ req_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ if (!req_page)
+ return -ENOMEM;
+
+ sev->guest_resp_buf = snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ if (!sev->guest_resp_buf) {
+ __free_page(req_page);
+ return -EIO;
+ }
+
+ sev->guest_req_buf = page_address(req_page);
+ mutex_init(&sev->guest_req_mutex);
+
+ return 0;
+}
+
+static void snp_guest_req_cleanup(struct kvm *kvm)
+{
+ struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
+
+ if (sev->guest_resp_buf)
+ snp_free_firmware_page(sev->guest_resp_buf);
+
+ if (sev->guest_req_buf)
+ __free_page(virt_to_page(sev->guest_req_buf));
+
+ sev->guest_req_buf = NULL;
+ sev->guest_resp_buf = NULL;
+}
+
+static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
+ struct kvm_sev_init *data,
+ unsigned long vm_type)
{
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
struct sev_platform_init_args init_args = {0};
+ bool es_active = vm_type != KVM_X86_SEV_VM;
+ u64 valid_vmsa_features = es_active ? sev_supported_vmsa_features : 0;
int ret;
if (kvm->created_vcpus)
return -EINVAL;
+ if (data->flags)
+ return -EINVAL;
+
+ if (data->vmsa_features & ~valid_vmsa_features)
+ return -EINVAL;
+
+ if (data->ghcb_version > GHCB_VERSION_MAX || (!es_active && data->ghcb_version))
+ return -EINVAL;
+
if (unlikely(sev->active))
return -EINVAL;
sev->active = true;
- sev->es_active = argp->id == KVM_SEV_ES_INIT;
+ sev->es_active = es_active;
+ sev->vmsa_features = data->vmsa_features;
+ sev->ghcb_version = data->ghcb_version;
+
+ /*
+ * Currently KVM supports the full range of mandatory features defined
+ * by version 2 of the GHCB protocol, so default to that for SEV-ES
+ * guests created via KVM_SEV_INIT2.
+ */
+ if (sev->es_active && !sev->ghcb_version)
+ sev->ghcb_version = GHCB_VERSION_DEFAULT;
+
+ if (vm_type == KVM_X86_SNP_VM)
+ sev->vmsa_features |= SVM_SEV_FEAT_SNP_ACTIVE;
+
ret = sev_asid_new(sev);
if (ret)
goto e_no_asid;
@@ -274,8 +449,13 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (ret)
goto e_free;
+ /* This needs to happen after SEV/SNP firmware initialization. */
+ if (vm_type == KVM_X86_SNP_VM && snp_guest_req_init(kvm))
+ goto e_free;
+
INIT_LIST_HEAD(&sev->regions_list);
INIT_LIST_HEAD(&sev->mirror_vms);
+ sev->need_init = false;
kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_SEV);
@@ -286,11 +466,54 @@ e_free:
sev_asid_free(sev);
sev->asid = 0;
e_no_asid:
+ sev->vmsa_features = 0;
sev->es_active = false;
sev->active = false;
return ret;
}
+static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_init data = {
+ .vmsa_features = 0,
+ .ghcb_version = 0,
+ };
+ unsigned long vm_type;
+
+ if (kvm->arch.vm_type != KVM_X86_DEFAULT_VM)
+ return -EINVAL;
+
+ vm_type = (argp->id == KVM_SEV_INIT ? KVM_X86_SEV_VM : KVM_X86_SEV_ES_VM);
+
+ /*
+ * KVM_SEV_ES_INIT has been deprecated by KVM_SEV_INIT2, so it will
+ * continue to only ever support the minimal GHCB protocol version.
+ */
+ if (vm_type == KVM_X86_SEV_ES_VM)
+ data.ghcb_version = GHCB_VERSION_MIN;
+
+ return __sev_guest_init(kvm, argp, &data, vm_type);
+}
+
+static int sev_guest_init2(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct kvm_sev_init data;
+
+ if (!sev->need_init)
+ return -EINVAL;
+
+ if (kvm->arch.vm_type != KVM_X86_SEV_VM &&
+ kvm->arch.vm_type != KVM_X86_SEV_ES_VM &&
+ kvm->arch.vm_type != KVM_X86_SNP_VM)
+ return -EINVAL;
+
+ if (copy_from_user(&data, u64_to_user_ptr(argp->data), sizeof(data)))
+ return -EFAULT;
+
+ return __sev_guest_init(kvm, argp, &data, kvm->arch.vm_type);
+}
+
static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error)
{
unsigned int asid = sev_get_asid(kvm);
@@ -339,7 +562,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
return -EFAULT;
memset(&start, 0, sizeof(start));
@@ -383,7 +606,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
/* return handle to userspace */
params.handle = start.handle;
- if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params))) {
+ if (copy_to_user(u64_to_user_ptr(argp->data), &params, sizeof(params))) {
sev_unbind_asid(kvm, start.handle);
ret = -EFAULT;
goto e_free_session;
@@ -522,7 +745,7 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
return -EFAULT;
vaddr = params.uaddr;
@@ -580,7 +803,13 @@ e_unpin:
static int sev_es_sync_vmsa(struct vcpu_svm *svm)
{
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info;
struct sev_es_save_area *save = svm->sev_es.vmsa;
+ struct xregs_state *xsave;
+ const u8 *s;
+ u8 *d;
+ int i;
/* Check some debug related fields before encrypting the VMSA */
if (svm->vcpu.guest_debug || (svm->vmcb->save.dr7 & ~DR7_FIXED_1))
@@ -621,10 +850,44 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
save->xss = svm->vcpu.arch.ia32_xss;
save->dr6 = svm->vcpu.arch.dr6;
- if (sev_es_debug_swap_enabled) {
- save->sev_features |= SVM_SEV_FEAT_DEBUG_SWAP;
- pr_warn_once("Enabling DebugSwap with KVM_SEV_ES_INIT. "
- "This will not work starting with Linux 6.10\n");
+ save->sev_features = sev->vmsa_features;
+
+ /*
+ * Skip FPU and AVX setup with KVM_SEV_ES_INIT to avoid
+ * breaking older measurements.
+ */
+ if (vcpu->kvm->arch.vm_type != KVM_X86_DEFAULT_VM) {
+ xsave = &vcpu->arch.guest_fpu.fpstate->regs.xsave;
+ save->x87_dp = xsave->i387.rdp;
+ save->mxcsr = xsave->i387.mxcsr;
+ save->x87_ftw = xsave->i387.twd;
+ save->x87_fsw = xsave->i387.swd;
+ save->x87_fcw = xsave->i387.cwd;
+ save->x87_fop = xsave->i387.fop;
+ save->x87_ds = 0;
+ save->x87_cs = 0;
+ save->x87_rip = xsave->i387.rip;
+
+ for (i = 0; i < 8; i++) {
+ /*
+ * The format of the x87 save area is undocumented and
+ * definitely not what you would expect. It consists of
+ * an 8*8 bytes area with bytes 0-7, and an 8*2 bytes
+ * area with bytes 8-9 of each register.
+ */
+ d = save->fpreg_x87 + i * 8;
+ s = ((u8 *)xsave->i387.st_space) + i * 16;
+ memcpy(d, s, 8);
+ save->fpreg_x87[64 + i * 2] = s[8];
+ save->fpreg_x87[64 + i * 2 + 1] = s[9];
+ }
+ memcpy(save->fpreg_xmm, xsave->i387.xmm_space, 256);
+
+ s = get_xsave_addr(xsave, XFEATURE_YMM);
+ if (s)
+ memcpy(save->fpreg_ymm, s, 256);
+ else
+ memset(save->fpreg_ymm, 0, 256);
}
pr_debug("Virtual Machine Save Area (VMSA):\n");
@@ -658,14 +921,29 @@ static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
clflush_cache_range(svm->sev_es.vmsa, PAGE_SIZE);
vmsa.reserved = 0;
- vmsa.handle = to_kvm_svm(kvm)->sev_info.handle;
+ vmsa.handle = to_kvm_sev_info(kvm)->handle;
vmsa.address = __sme_pa(svm->sev_es.vmsa);
vmsa.len = PAGE_SIZE;
ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_VMSA, &vmsa, error);
if (ret)
return ret;
+ /*
+ * SEV-ES guests maintain an encrypted version of their FPU
+ * state which is restored and saved on VMRUN and VMEXIT.
+ * Mark vcpu->arch.guest_fpu->fpstate as scratch so it won't
+ * do xsave/xrstor on it.
+ */
+ fpstate_set_confidential(&vcpu->arch.guest_fpu);
vcpu->arch.guest_state_protected = true;
+
+ /*
+ * SEV-ES guest mandates LBR Virtualization to be _always_ ON. Enable it
+ * only after setting guest_state_protected because KVM_SET_MSRS allows
+ * dynamic toggling of LBRV (for performance reason) on write access to
+ * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
+ */
+ svm_enable_lbrv(vcpu);
return 0;
}
@@ -695,7 +973,7 @@ static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
{
- void __user *measure = (void __user *)(uintptr_t)argp->data;
+ void __user *measure = u64_to_user_ptr(argp->data);
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
struct sev_data_launch_measure data;
struct kvm_sev_launch_measure params;
@@ -715,7 +993,7 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!params.len)
goto cmd;
- p = (void __user *)(uintptr_t)params.uaddr;
+ p = u64_to_user_ptr(params.uaddr);
if (p) {
if (params.len > SEV_FW_BLOB_MAX_SIZE)
return -EINVAL;
@@ -788,7 +1066,7 @@ static int sev_guest_status(struct kvm *kvm, struct kvm_sev_cmd *argp)
params.state = data.state;
params.handle = data.handle;
- if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
+ if (copy_to_user(u64_to_user_ptr(argp->data), &params, sizeof(params)))
ret = -EFAULT;
return ret;
@@ -953,7 +1231,7 @@ static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&debug, (void __user *)(uintptr_t)argp->data, sizeof(debug)))
+ if (copy_from_user(&debug, u64_to_user_ptr(argp->data), sizeof(debug)))
return -EFAULT;
if (!debug.len || debug.src_uaddr + debug.len < debug.src_uaddr)
@@ -1037,7 +1315,7 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
return -EFAULT;
pages = sev_pin_memory(kvm, params.guest_uaddr, params.guest_len, &n, 1);
@@ -1101,7 +1379,7 @@ e_unpin_memory:
static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp)
{
- void __user *report = (void __user *)(uintptr_t)argp->data;
+ void __user *report = u64_to_user_ptr(argp->data);
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
struct sev_data_attestation_report data;
struct kvm_sev_attestation_report params;
@@ -1112,7 +1390,7 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
return -EFAULT;
memset(&data, 0, sizeof(data));
@@ -1121,7 +1399,7 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!params.len)
goto cmd;
- p = (void __user *)(uintptr_t)params.uaddr;
+ p = u64_to_user_ptr(params.uaddr);
if (p) {
if (params.len > SEV_FW_BLOB_MAX_SIZE)
return -EINVAL;
@@ -1174,7 +1452,7 @@ __sev_send_start_query_session_length(struct kvm *kvm, struct kvm_sev_cmd *argp,
ret = sev_issue_cmd(kvm, SEV_CMD_SEND_START, &data, &argp->error);
params->session_len = data.session_len;
- if (copy_to_user((void __user *)(uintptr_t)argp->data, params,
+ if (copy_to_user(u64_to_user_ptr(argp->data), params,
sizeof(struct kvm_sev_send_start)))
ret = -EFAULT;
@@ -1193,7 +1471,7 @@ static int sev_send_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data,
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data),
sizeof(struct kvm_sev_send_start)))
return -EFAULT;
@@ -1248,7 +1526,7 @@ static int sev_send_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
ret = sev_issue_cmd(kvm, SEV_CMD_SEND_START, &data, &argp->error);
- if (!ret && copy_to_user((void __user *)(uintptr_t)params.session_uaddr,
+ if (!ret && copy_to_user(u64_to_user_ptr(params.session_uaddr),
session_data, params.session_len)) {
ret = -EFAULT;
goto e_free_amd_cert;
@@ -1256,7 +1534,7 @@ static int sev_send_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
params.policy = data.policy;
params.session_len = data.session_len;
- if (copy_to_user((void __user *)(uintptr_t)argp->data, &params,
+ if (copy_to_user(u64_to_user_ptr(argp->data), &params,
sizeof(struct kvm_sev_send_start)))
ret = -EFAULT;
@@ -1287,7 +1565,7 @@ __sev_send_update_data_query_lengths(struct kvm *kvm, struct kvm_sev_cmd *argp,
params->hdr_len = data.hdr_len;
params->trans_len = data.trans_len;
- if (copy_to_user((void __user *)(uintptr_t)argp->data, params,
+ if (copy_to_user(u64_to_user_ptr(argp->data), params,
sizeof(struct kvm_sev_send_update_data)))
ret = -EFAULT;
@@ -1307,7 +1585,7 @@ static int sev_send_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data,
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data),
sizeof(struct kvm_sev_send_update_data)))
return -EFAULT;
@@ -1358,14 +1636,14 @@ static int sev_send_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
goto e_free_trans_data;
/* copy transport buffer to user space */
- if (copy_to_user((void __user *)(uintptr_t)params.trans_uaddr,
+ if (copy_to_user(u64_to_user_ptr(params.trans_uaddr),
trans_data, params.trans_len)) {
ret = -EFAULT;
goto e_free_trans_data;
}
/* Copy packet header to userspace. */
- if (copy_to_user((void __user *)(uintptr_t)params.hdr_uaddr, hdr,
+ if (copy_to_user(u64_to_user_ptr(params.hdr_uaddr), hdr,
params.hdr_len))
ret = -EFAULT;
@@ -1417,7 +1695,7 @@ static int sev_receive_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
return -ENOTTY;
/* Get parameter from the userspace */
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data,
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data),
sizeof(struct kvm_sev_receive_start)))
return -EFAULT;
@@ -1459,7 +1737,7 @@ static int sev_receive_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
}
params.handle = start.handle;
- if (copy_to_user((void __user *)(uintptr_t)argp->data,
+ if (copy_to_user(u64_to_user_ptr(argp->data),
&params, sizeof(struct kvm_sev_receive_start))) {
ret = -EFAULT;
sev_unbind_asid(kvm, start.handle);
@@ -1490,7 +1768,7 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -EINVAL;
- if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data,
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data),
sizeof(struct kvm_sev_receive_update_data)))
return -EFAULT;
@@ -1705,6 +1983,7 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
dst->pages_locked = src->pages_locked;
dst->enc_context_owner = src->enc_context_owner;
dst->es_active = src->es_active;
+ dst->vmsa_features = src->vmsa_features;
src->asid = 0;
src->active = false;
@@ -1812,7 +2091,8 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
if (ret)
goto out_fput;
- if (sev_guest(kvm) || !sev_guest(source_kvm)) {
+ if (kvm->arch.vm_type != source_kvm->arch.vm_type ||
+ sev_guest(kvm) || !sev_guest(source_kvm)) {
ret = -EINVAL;
goto out_unlock;
}
@@ -1861,6 +2141,425 @@ out_fput:
return ret;
}
+int sev_dev_get_attr(u32 group, u64 attr, u64 *val)
+{
+ if (group != KVM_X86_GRP_SEV)
+ return -ENXIO;
+
+ switch (attr) {
+ case KVM_X86_SEV_VMSA_FEATURES:
+ *val = sev_supported_vmsa_features;
+ return 0;
+
+ default:
+ return -ENXIO;
+ }
+}
+
+/*
+ * The guest context contains all the information, keys and metadata
+ * associated with the guest that the firmware tracks to implement SEV
+ * and SNP features. The firmware stores the guest context in hypervisor
+ * provide page via the SNP_GCTX_CREATE command.
+ */
+static void *snp_context_create(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct sev_data_snp_addr data = {};
+ void *context;
+ int rc;
+
+ /* Allocate memory for context page */
+ context = snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT);
+ if (!context)
+ return NULL;
+
+ data.address = __psp_pa(context);
+ rc = __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_GCTX_CREATE, &data, &argp->error);
+ if (rc) {
+ pr_warn("Failed to create SEV-SNP context, rc %d fw_error %d",
+ rc, argp->error);
+ snp_free_firmware_page(context);
+ return NULL;
+ }
+
+ return context;
+}
+
+static int snp_bind_asid(struct kvm *kvm, int *error)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct sev_data_snp_activate data = {0};
+
+ data.gctx_paddr = __psp_pa(sev->snp_context);
+ data.asid = sev_get_asid(kvm);
+ return sev_issue_cmd(kvm, SEV_CMD_SNP_ACTIVATE, &data, error);
+}
+
+static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct sev_data_snp_launch_start start = {0};
+ struct kvm_sev_snp_launch_start params;
+ int rc;
+
+ if (!sev_snp_guest(kvm))
+ return -ENOTTY;
+
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
+ return -EFAULT;
+
+ /* Don't allow userspace to allocate memory for more than 1 SNP context. */
+ if (sev->snp_context)
+ return -EINVAL;
+
+ sev->snp_context = snp_context_create(kvm, argp);
+ if (!sev->snp_context)
+ return -ENOTTY;
+
+ if (params.flags)
+ return -EINVAL;
+
+ if (params.policy & ~SNP_POLICY_MASK_VALID)
+ return -EINVAL;
+
+ /* Check for policy bits that must be set */
+ if (!(params.policy & SNP_POLICY_MASK_RSVD_MBO) ||
+ !(params.policy & SNP_POLICY_MASK_SMT))
+ return -EINVAL;
+
+ if (params.policy & SNP_POLICY_MASK_SINGLE_SOCKET)
+ return -EINVAL;
+
+ start.gctx_paddr = __psp_pa(sev->snp_context);
+ start.policy = params.policy;
+ memcpy(start.gosvw, params.gosvw, sizeof(params.gosvw));
+ rc = __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_LAUNCH_START, &start, &argp->error);
+ if (rc) {
+ pr_debug("%s: SEV_CMD_SNP_LAUNCH_START firmware command failed, rc %d\n",
+ __func__, rc);
+ goto e_free_context;
+ }
+
+ sev->fd = argp->sev_fd;
+ rc = snp_bind_asid(kvm, &argp->error);
+ if (rc) {
+ pr_debug("%s: Failed to bind ASID to SEV-SNP context, rc %d\n",
+ __func__, rc);
+ goto e_free_context;
+ }
+
+ return 0;
+
+e_free_context:
+ snp_decommission_context(kvm);
+
+ return rc;
+}
+
+struct sev_gmem_populate_args {
+ __u8 type;
+ int sev_fd;
+ int fw_error;
+};
+
+static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn_start, kvm_pfn_t pfn,
+ void __user *src, int order, void *opaque)
+{
+ struct sev_gmem_populate_args *sev_populate_args = opaque;
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ int n_private = 0, ret, i;
+ int npages = (1 << order);
+ gfn_t gfn;
+
+ if (WARN_ON_ONCE(sev_populate_args->type != KVM_SEV_SNP_PAGE_TYPE_ZERO && !src))
+ return -EINVAL;
+
+ for (gfn = gfn_start, i = 0; gfn < gfn_start + npages; gfn++, i++) {
+ struct sev_data_snp_launch_update fw_args = {0};
+ bool assigned;
+ int level;
+
+ if (!kvm_mem_is_private(kvm, gfn)) {
+ pr_debug("%s: Failed to ensure GFN 0x%llx has private memory attribute set\n",
+ __func__, gfn);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = snp_lookup_rmpentry((u64)pfn + i, &assigned, &level);
+ if (ret || assigned) {
+ pr_debug("%s: Failed to ensure GFN 0x%llx RMP entry is initial shared state, ret: %d assigned: %d\n",
+ __func__, gfn, ret, assigned);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (src) {
+ void *vaddr = kmap_local_pfn(pfn + i);
+
+ ret = copy_from_user(vaddr, src + i * PAGE_SIZE, PAGE_SIZE);
+ if (ret)
+ goto err;
+ kunmap_local(vaddr);
+ }
+
+ ret = rmp_make_private(pfn + i, gfn << PAGE_SHIFT, PG_LEVEL_4K,
+ sev_get_asid(kvm), true);
+ if (ret)
+ goto err;
+
+ n_private++;
+
+ fw_args.gctx_paddr = __psp_pa(sev->snp_context);
+ fw_args.address = __sme_set(pfn_to_hpa(pfn + i));
+ fw_args.page_size = PG_LEVEL_TO_RMP(PG_LEVEL_4K);
+ fw_args.page_type = sev_populate_args->type;
+
+ ret = __sev_issue_cmd(sev_populate_args->sev_fd, SEV_CMD_SNP_LAUNCH_UPDATE,
+ &fw_args, &sev_populate_args->fw_error);
+ if (ret)
+ goto fw_err;
+ }
+
+ return 0;
+
+fw_err:
+ /*
+ * If the firmware command failed handle the reclaim and cleanup of that
+ * PFN specially vs. prior pages which can be cleaned up below without
+ * needing to reclaim in advance.
+ *
+ * Additionally, when invalid CPUID function entries are detected,
+ * firmware writes the expected values into the page and leaves it
+ * unencrypted so it can be used for debugging and error-reporting.
+ *
+ * Copy this page back into the source buffer so userspace can use this
+ * information to provide information on which CPUID leaves/fields
+ * failed CPUID validation.
+ */
+ if (!snp_page_reclaim(kvm, pfn + i) &&
+ sev_populate_args->type == KVM_SEV_SNP_PAGE_TYPE_CPUID &&
+ sev_populate_args->fw_error == SEV_RET_INVALID_PARAM) {
+ void *vaddr = kmap_local_pfn(pfn + i);
+
+ if (copy_to_user(src + i * PAGE_SIZE, vaddr, PAGE_SIZE))
+ pr_debug("Failed to write CPUID page back to userspace\n");
+
+ kunmap_local(vaddr);
+ }
+
+ /* pfn + i is hypervisor-owned now, so skip below cleanup for it. */
+ n_private--;
+
+err:
+ pr_debug("%s: exiting with error ret %d (fw_error %d), restoring %d gmem PFNs to shared.\n",
+ __func__, ret, sev_populate_args->fw_error, n_private);
+ for (i = 0; i < n_private; i++)
+ kvm_rmp_make_shared(kvm, pfn + i, PG_LEVEL_4K);
+
+ return ret;
+}
+
+static int snp_launch_update(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct sev_gmem_populate_args sev_populate_args = {0};
+ struct kvm_sev_snp_launch_update params;
+ struct kvm_memory_slot *memslot;
+ long npages, count;
+ void __user *src;
+ int ret = 0;
+
+ if (!sev_snp_guest(kvm) || !sev->snp_context)
+ return -EINVAL;
+
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
+ return -EFAULT;
+
+ pr_debug("%s: GFN start 0x%llx length 0x%llx type %d flags %d\n", __func__,
+ params.gfn_start, params.len, params.type, params.flags);
+
+ if (!PAGE_ALIGNED(params.len) || params.flags ||
+ (params.type != KVM_SEV_SNP_PAGE_TYPE_NORMAL &&
+ params.type != KVM_SEV_SNP_PAGE_TYPE_ZERO &&
+ params.type != KVM_SEV_SNP_PAGE_TYPE_UNMEASURED &&
+ params.type != KVM_SEV_SNP_PAGE_TYPE_SECRETS &&
+ params.type != KVM_SEV_SNP_PAGE_TYPE_CPUID))
+ return -EINVAL;
+
+ npages = params.len / PAGE_SIZE;
+
+ /*
+ * For each GFN that's being prepared as part of the initial guest
+ * state, the following pre-conditions are verified:
+ *
+ * 1) The backing memslot is a valid private memslot.
+ * 2) The GFN has been set to private via KVM_SET_MEMORY_ATTRIBUTES
+ * beforehand.
+ * 3) The PFN of the guest_memfd has not already been set to private
+ * in the RMP table.
+ *
+ * The KVM MMU relies on kvm->mmu_invalidate_seq to retry nested page
+ * faults if there's a race between a fault and an attribute update via
+ * KVM_SET_MEMORY_ATTRIBUTES, and a similar approach could be utilized
+ * here. However, kvm->slots_lock guards against both this as well as
+ * concurrent memslot updates occurring while these checks are being
+ * performed, so use that here to make it easier to reason about the
+ * initial expected state and better guard against unexpected
+ * situations.
+ */
+ mutex_lock(&kvm->slots_lock);
+
+ memslot = gfn_to_memslot(kvm, params.gfn_start);
+ if (!kvm_slot_can_be_private(memslot)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ sev_populate_args.sev_fd = argp->sev_fd;
+ sev_populate_args.type = params.type;
+ src = params.type == KVM_SEV_SNP_PAGE_TYPE_ZERO ? NULL : u64_to_user_ptr(params.uaddr);
+
+ count = kvm_gmem_populate(kvm, params.gfn_start, src, npages,
+ sev_gmem_post_populate, &sev_populate_args);
+ if (count < 0) {
+ argp->error = sev_populate_args.fw_error;
+ pr_debug("%s: kvm_gmem_populate failed, ret %ld (fw_error %d)\n",
+ __func__, count, argp->error);
+ ret = -EIO;
+ } else {
+ params.gfn_start += count;
+ params.len -= count * PAGE_SIZE;
+ if (params.type != KVM_SEV_SNP_PAGE_TYPE_ZERO)
+ params.uaddr += count * PAGE_SIZE;
+
+ ret = 0;
+ if (copy_to_user(u64_to_user_ptr(argp->data), &params, sizeof(params)))
+ ret = -EFAULT;
+ }
+
+out:
+ mutex_unlock(&kvm->slots_lock);
+
+ return ret;
+}
+
+static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct sev_data_snp_launch_update data = {};
+ struct kvm_vcpu *vcpu;
+ unsigned long i;
+ int ret;
+
+ data.gctx_paddr = __psp_pa(sev->snp_context);
+ data.page_type = SNP_PAGE_TYPE_VMSA;
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ struct vcpu_svm *svm = to_svm(vcpu);
+ u64 pfn = __pa(svm->sev_es.vmsa) >> PAGE_SHIFT;
+
+ ret = sev_es_sync_vmsa(svm);
+ if (ret)
+ return ret;
+
+ /* Transition the VMSA page to a firmware state. */
+ ret = rmp_make_private(pfn, INITIAL_VMSA_GPA, PG_LEVEL_4K, sev->asid, true);
+ if (ret)
+ return ret;
+
+ /* Issue the SNP command to encrypt the VMSA */
+ data.address = __sme_pa(svm->sev_es.vmsa);
+ ret = __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_LAUNCH_UPDATE,
+ &data, &argp->error);
+ if (ret) {
+ snp_page_reclaim(kvm, pfn);
+
+ return ret;
+ }
+
+ svm->vcpu.arch.guest_state_protected = true;
+ /*
+ * SEV-ES (and thus SNP) guest mandates LBR Virtualization to
+ * be _always_ ON. Enable it only after setting
+ * guest_state_protected because KVM_SET_MSRS allows dynamic
+ * toggling of LBRV (for performance reason) on write access to
+ * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
+ */
+ svm_enable_lbrv(vcpu);
+ }
+
+ return 0;
+}
+
+static int snp_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct kvm_sev_snp_launch_finish params;
+ struct sev_data_snp_launch_finish *data;
+ void *id_block = NULL, *id_auth = NULL;
+ int ret;
+
+ if (!sev_snp_guest(kvm))
+ return -ENOTTY;
+
+ if (!sev->snp_context)
+ return -EINVAL;
+
+ if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
+ return -EFAULT;
+
+ if (params.flags)
+ return -EINVAL;
+
+ /* Measure all vCPUs using LAUNCH_UPDATE before finalizing the launch flow. */
+ ret = snp_launch_update_vmsa(kvm, argp);
+ if (ret)
+ return ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
+ if (!data)
+ return -ENOMEM;
+
+ if (params.id_block_en) {
+ id_block = psp_copy_user_blob(params.id_block_uaddr, KVM_SEV_SNP_ID_BLOCK_SIZE);
+ if (IS_ERR(id_block)) {
+ ret = PTR_ERR(id_block);
+ goto e_free;
+ }
+
+ data->id_block_en = 1;
+ data->id_block_paddr = __sme_pa(id_block);
+
+ id_auth = psp_copy_user_blob(params.id_auth_uaddr, KVM_SEV_SNP_ID_AUTH_SIZE);
+ if (IS_ERR(id_auth)) {
+ ret = PTR_ERR(id_auth);
+ goto e_free_id_block;
+ }
+
+ data->id_auth_paddr = __sme_pa(id_auth);
+
+ if (params.auth_key_en)
+ data->auth_key_en = 1;
+ }
+
+ data->vcek_disabled = params.vcek_disabled;
+
+ memcpy(data->host_data, params.host_data, KVM_SEV_SNP_FINISH_DATA_SIZE);
+ data->gctx_paddr = __psp_pa(sev->snp_context);
+ ret = sev_issue_cmd(kvm, SEV_CMD_SNP_LAUNCH_FINISH, data, &argp->error);
+
+ kfree(id_auth);
+
+e_free_id_block:
+ kfree(id_block);
+
+e_free:
+ kfree(data);
+
+ return ret;
+}
+
int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
{
struct kvm_sev_cmd sev_cmd;
@@ -1884,6 +2583,15 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
goto out;
}
+ /*
+ * Once KVM_SEV_INIT2 initializes a KVM instance as an SNP guest, only
+ * allow the use of SNP-specific commands.
+ */
+ if (sev_snp_guest(kvm) && sev_cmd.id < KVM_SEV_SNP_LAUNCH_START) {
+ r = -EPERM;
+ goto out;
+ }
+
switch (sev_cmd.id) {
case KVM_SEV_ES_INIT:
if (!sev_es_enabled) {
@@ -1894,6 +2602,9 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
case KVM_SEV_INIT:
r = sev_guest_init(kvm, &sev_cmd);
break;
+ case KVM_SEV_INIT2:
+ r = sev_guest_init2(kvm, &sev_cmd);
+ break;
case KVM_SEV_LAUNCH_START:
r = sev_launch_start(kvm, &sev_cmd);
break;
@@ -1945,6 +2656,15 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
case KVM_SEV_RECEIVE_FINISH:
r = sev_receive_finish(kvm, &sev_cmd);
break;
+ case KVM_SEV_SNP_LAUNCH_START:
+ r = snp_launch_start(kvm, &sev_cmd);
+ break;
+ case KVM_SEV_SNP_LAUNCH_UPDATE:
+ r = snp_launch_update(kvm, &sev_cmd);
+ break;
+ case KVM_SEV_SNP_LAUNCH_FINISH:
+ r = snp_launch_finish(kvm, &sev_cmd);
+ break;
default:
r = -EINVAL;
goto out;
@@ -2121,6 +2841,7 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
mirror_sev->asid = source_sev->asid;
mirror_sev->fd = source_sev->fd;
mirror_sev->es_active = source_sev->es_active;
+ mirror_sev->need_init = false;
mirror_sev->handle = source_sev->handle;
INIT_LIST_HEAD(&mirror_sev->regions_list);
INIT_LIST_HEAD(&mirror_sev->mirror_vms);
@@ -2139,6 +2860,31 @@ e_source_fput:
return ret;
}
+static int snp_decommission_context(struct kvm *kvm)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ struct sev_data_snp_addr data = {};
+ int ret;
+
+ /* If context is not created then do nothing */
+ if (!sev->snp_context)
+ return 0;
+
+ /* Do the decommision, which will unbind the ASID from the SNP context */
+ data.address = __sme_pa(sev->snp_context);
+ down_write(&sev_deactivate_lock);
+ ret = sev_do_cmd(SEV_CMD_SNP_DECOMMISSION, &data, NULL);
+ up_write(&sev_deactivate_lock);
+
+ if (WARN_ONCE(ret, "Failed to release guest context, ret %d", ret))
+ return ret;
+
+ snp_free_firmware_page(sev->snp_context);
+ sev->snp_context = NULL;
+
+ return 0;
+}
+
void sev_vm_destroy(struct kvm *kvm)
{
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
@@ -2180,22 +2926,42 @@ void sev_vm_destroy(struct kvm *kvm)
}
}
- sev_unbind_asid(kvm, sev->handle);
+ if (sev_snp_guest(kvm)) {
+ snp_guest_req_cleanup(kvm);
+
+ /*
+ * Decomission handles unbinding of the ASID. If it fails for
+ * some unexpected reason, just leak the ASID.
+ */
+ if (snp_decommission_context(kvm))
+ return;
+ } else {
+ sev_unbind_asid(kvm, sev->handle);
+ }
+
sev_asid_free(sev);
}
void __init sev_set_cpu_caps(void)
{
- if (!sev_enabled)
- kvm_cpu_cap_clear(X86_FEATURE_SEV);
- if (!sev_es_enabled)
- kvm_cpu_cap_clear(X86_FEATURE_SEV_ES);
+ if (sev_enabled) {
+ kvm_cpu_cap_set(X86_FEATURE_SEV);
+ kvm_caps.supported_vm_types |= BIT(KVM_X86_SEV_VM);
+ }
+ if (sev_es_enabled) {
+ kvm_cpu_cap_set(X86_FEATURE_SEV_ES);
+ kvm_caps.supported_vm_types |= BIT(KVM_X86_SEV_ES_VM);
+ }
+ if (sev_snp_enabled) {
+ kvm_cpu_cap_set(X86_FEATURE_SEV_SNP);
+ kvm_caps.supported_vm_types |= BIT(KVM_X86_SNP_VM);
+ }
}
void __init sev_hardware_setup(void)
{
-#ifdef CONFIG_KVM_AMD_SEV
unsigned int eax, ebx, ecx, edx, sev_asid_count, sev_es_asid_count;
+ bool sev_snp_supported = false;
bool sev_es_supported = false;
bool sev_supported = false;
@@ -2269,6 +3035,12 @@ void __init sev_hardware_setup(void)
if (!boot_cpu_has(X86_FEATURE_SEV_ES))
goto out;
+ if (!lbrv) {
+ WARN_ONCE(!boot_cpu_has(X86_FEATURE_LBRV),
+ "LBRV must be present for SEV-ES support");
+ goto out;
+ }
+
/* Has the system been allocated ASIDs for SEV-ES? */
if (min_sev_asid == 1)
goto out;
@@ -2276,6 +3048,7 @@ void __init sev_hardware_setup(void)
sev_es_asid_count = min_sev_asid - 1;
WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV_ES, sev_es_asid_count));
sev_es_supported = true;
+ sev_snp_supported = sev_snp_enabled && cc_platform_has(CC_ATTR_HOST_SEV_SNP);
out:
if (boot_cpu_has(X86_FEATURE_SEV))
@@ -2288,13 +3061,22 @@ out:
pr_info("SEV-ES %s (ASIDs %u - %u)\n",
sev_es_supported ? "enabled" : "disabled",
min_sev_asid > 1 ? 1 : 0, min_sev_asid - 1);
+ if (boot_cpu_has(X86_FEATURE_SEV_SNP))
+ pr_info("SEV-SNP %s (ASIDs %u - %u)\n",
+ sev_snp_supported ? "enabled" : "disabled",
+ min_sev_asid > 1 ? 1 : 0, min_sev_asid - 1);
sev_enabled = sev_supported;
sev_es_enabled = sev_es_supported;
+ sev_snp_enabled = sev_snp_supported;
+
if (!sev_es_enabled || !cpu_feature_enabled(X86_FEATURE_DEBUG_SWAP) ||
!cpu_feature_enabled(X86_FEATURE_NO_NESTED_DATA_BP))
sev_es_debug_swap_enabled = false;
-#endif
+
+ sev_supported_vmsa_features = 0;
+ if (sev_es_debug_swap_enabled)
+ sev_supported_vmsa_features |= SVM_SEV_FEAT_DEBUG_SWAP;
}
void sev_hardware_unsetup(void)
@@ -2366,7 +3148,13 @@ do_wbinvd:
void sev_guest_memory_reclaimed(struct kvm *kvm)
{
- if (!sev_guest(kvm))
+ /*
+ * With SNP+gmem, private/encrypted memory is unreachable via the
+ * hva-based mmu notifiers, so these events are only actually
+ * pertaining to shared pages where there is no need to perform
+ * the WBINVD to flush associated caches.
+ */
+ if (!sev_guest(kvm) || sev_snp_guest(kvm))
return;
wbinvd_on_all_cpus();
@@ -2381,11 +3169,24 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu)
svm = to_svm(vcpu);
+ /*
+ * If it's an SNP guest, then the VMSA was marked in the RMP table as
+ * a guest-owned page. Transition the page to hypervisor state before
+ * releasing it back to the system.
+ */
+ if (sev_snp_guest(vcpu->kvm)) {
+ u64 pfn = __pa(svm->sev_es.vmsa) >> PAGE_SHIFT;
+
+ if (kvm_rmp_make_shared(vcpu->kvm, pfn, PG_LEVEL_4K))
+ goto skip_vmsa_free;
+ }
+
if (vcpu->arch.guest_state_protected)
sev_flush_encrypted_page(vcpu, svm->sev_es.vmsa);
__free_page(virt_to_page(svm->sev_es.vmsa));
+skip_vmsa_free:
if (svm->sev_es.ghcb_sa_free)
kvfree(svm->sev_es.ghcb_sa);
}
@@ -2581,10 +3382,31 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
if (!kvm_ghcb_sw_scratch_is_valid(svm))
goto vmgexit_err;
break;
+ case SVM_VMGEXIT_AP_CREATION:
+ if (!sev_snp_guest(vcpu->kvm))
+ goto vmgexit_err;
+ if (lower_32_bits(control->exit_info_1) != SVM_VMGEXIT_AP_DESTROY)
+ if (!kvm_ghcb_rax_is_valid(svm))
+ goto vmgexit_err;
+ break;
case SVM_VMGEXIT_NMI_COMPLETE:
case SVM_VMGEXIT_AP_HLT_LOOP:
case SVM_VMGEXIT_AP_JUMP_TABLE:
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
+ case SVM_VMGEXIT_HV_FEATURES:
+ case SVM_VMGEXIT_TERM_REQUEST:
+ break;
+ case SVM_VMGEXIT_PSC:
+ if (!sev_snp_guest(vcpu->kvm) || !kvm_ghcb_sw_scratch_is_valid(svm))
+ goto vmgexit_err;
+ break;
+ case SVM_VMGEXIT_GUEST_REQUEST:
+ case SVM_VMGEXIT_EXT_GUEST_REQUEST:
+ if (!sev_snp_guest(vcpu->kvm) ||
+ !PAGE_ALIGNED(control->exit_info_1) ||
+ !PAGE_ALIGNED(control->exit_info_2) ||
+ control->exit_info_1 == control->exit_info_2)
+ goto vmgexit_err;
break;
default:
reason = GHCB_ERR_INVALID_EVENT;
@@ -2615,6 +3437,9 @@ vmgexit_err:
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
{
+ /* Clear any indication that the vCPU is in a type of AP Reset Hold */
+ svm->sev_es.ap_reset_hold_type = AP_RESET_HOLD_NONE;
+
if (!svm->sev_es.ghcb)
return;
@@ -2770,10 +3595,539 @@ static void set_ghcb_msr(struct vcpu_svm *svm, u64 value)
svm->vmcb->control.ghcb_gpa = value;
}
+static int snp_rmptable_psmash(kvm_pfn_t pfn)
+{
+ int ret;
+
+ pfn = pfn & ~(KVM_PAGES_PER_HPAGE(PG_LEVEL_2M) - 1);
+
+ /*
+ * PSMASH_FAIL_INUSE indicates another processor is modifying the
+ * entry, so retry until that's no longer the case.
+ */
+ do {
+ ret = psmash(pfn);
+ } while (ret == PSMASH_FAIL_INUSE);
+
+ return ret;
+}
+
+static int snp_complete_psc_msr(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ if (vcpu->run->hypercall.ret)
+ set_ghcb_msr(svm, GHCB_MSR_PSC_RESP_ERROR);
+ else
+ set_ghcb_msr(svm, GHCB_MSR_PSC_RESP);
+
+ return 1; /* resume guest */
+}
+
+static int snp_begin_psc_msr(struct vcpu_svm *svm, u64 ghcb_msr)
+{
+ u64 gpa = gfn_to_gpa(GHCB_MSR_PSC_REQ_TO_GFN(ghcb_msr));
+ u8 op = GHCB_MSR_PSC_REQ_TO_OP(ghcb_msr);
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+
+ if (op != SNP_PAGE_STATE_PRIVATE && op != SNP_PAGE_STATE_SHARED) {
+ set_ghcb_msr(svm, GHCB_MSR_PSC_RESP_ERROR);
+ return 1; /* resume guest */
+ }
+
+ if (!(vcpu->kvm->arch.hypercall_exit_enabled & (1 << KVM_HC_MAP_GPA_RANGE))) {
+ set_ghcb_msr(svm, GHCB_MSR_PSC_RESP_ERROR);
+ return 1; /* resume guest */
+ }
+
+ vcpu->run->exit_reason = KVM_EXIT_HYPERCALL;
+ vcpu->run->hypercall.nr = KVM_HC_MAP_GPA_RANGE;
+ vcpu->run->hypercall.args[0] = gpa;
+ vcpu->run->hypercall.args[1] = 1;
+ vcpu->run->hypercall.args[2] = (op == SNP_PAGE_STATE_PRIVATE)
+ ? KVM_MAP_GPA_RANGE_ENCRYPTED
+ : KVM_MAP_GPA_RANGE_DECRYPTED;
+ vcpu->run->hypercall.args[2] |= KVM_MAP_GPA_RANGE_PAGE_SZ_4K;
+
+ vcpu->arch.complete_userspace_io = snp_complete_psc_msr;
+
+ return 0; /* forward request to userspace */
+}
+
+struct psc_buffer {
+ struct psc_hdr hdr;
+ struct psc_entry entries[];
+} __packed;
+
+static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc);
+
+static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret)
+{
+ svm->sev_es.psc_inflight = 0;
+ svm->sev_es.psc_idx = 0;
+ svm->sev_es.psc_2m = false;
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, psc_ret);
+}
+
+static void __snp_complete_one_psc(struct vcpu_svm *svm)
+{
+ struct psc_buffer *psc = svm->sev_es.ghcb_sa;
+ struct psc_entry *entries = psc->entries;
+ struct psc_hdr *hdr = &psc->hdr;
+ __u16 idx;
+
+ /*
+ * Everything in-flight has been processed successfully. Update the
+ * corresponding entries in the guest's PSC buffer and zero out the
+ * count of in-flight PSC entries.
+ */
+ for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
+ svm->sev_es.psc_inflight--, idx++) {
+ struct psc_entry *entry = &entries[idx];
+
+ entry->cur_page = entry->pagesize ? 512 : 1;
+ }
+
+ hdr->cur_entry = idx;
+}
+
+static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+ struct psc_buffer *psc = svm->sev_es.ghcb_sa;
+
+ if (vcpu->run->hypercall.ret) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
+ return 1; /* resume guest */
+ }
+
+ __snp_complete_one_psc(svm);
+
+ /* Handle the next range (if any). */
+ return snp_begin_psc(svm, psc);
+}
+
+static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc)
+{
+ struct psc_entry *entries = psc->entries;
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct psc_hdr *hdr = &psc->hdr;
+ struct psc_entry entry_start;
+ u16 idx, idx_start, idx_end;
+ int npages;
+ bool huge;
+ u64 gfn;
+
+ if (!(vcpu->kvm->arch.hypercall_exit_enabled & (1 << KVM_HC_MAP_GPA_RANGE))) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
+ return 1;
+ }
+
+next_range:
+ /* There should be no other PSCs in-flight at this point. */
+ if (WARN_ON_ONCE(svm->sev_es.psc_inflight)) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
+ return 1;
+ }
+
+ /*
+ * The PSC descriptor buffer can be modified by a misbehaved guest after
+ * validation, so take care to only use validated copies of values used
+ * for things like array indexing.
+ */
+ idx_start = hdr->cur_entry;
+ idx_end = hdr->end_entry;
+
+ if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
+ return 1;
+ }
+
+ /* Find the start of the next range which needs processing. */
+ for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) {
+ entry_start = entries[idx];
+
+ gfn = entry_start.gfn;
+ huge = entry_start.pagesize;
+ npages = huge ? 512 : 1;
+
+ if (entry_start.cur_page > npages || !IS_ALIGNED(gfn, npages)) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_ENTRY);
+ return 1;
+ }
+
+ if (entry_start.cur_page) {
+ /*
+ * If this is a partially-completed 2M range, force 4K handling
+ * for the remaining pages since they're effectively split at
+ * this point. Subsequent code should ensure this doesn't get
+ * combined with adjacent PSC entries where 2M handling is still
+ * possible.
+ */
+ npages -= entry_start.cur_page;
+ gfn += entry_start.cur_page;
+ huge = false;
+ }
+
+ if (npages)
+ break;
+ }
+
+ if (idx > idx_end) {
+ /* Nothing more to process. */
+ snp_complete_psc(svm, 0);
+ return 1;
+ }
+
+ svm->sev_es.psc_2m = huge;
+ svm->sev_es.psc_idx = idx;
+ svm->sev_es.psc_inflight = 1;
+
+ /*
+ * Find all subsequent PSC entries that contain adjacent GPA
+ * ranges/operations and can be combined into a single
+ * KVM_HC_MAP_GPA_RANGE exit.
+ */
+ while (++idx <= idx_end) {
+ struct psc_entry entry = entries[idx];
+
+ if (entry.operation != entry_start.operation ||
+ entry.gfn != entry_start.gfn + npages ||
+ entry.cur_page || !!entry.pagesize != huge)
+ break;
+
+ svm->sev_es.psc_inflight++;
+ npages += huge ? 512 : 1;
+ }
+
+ switch (entry_start.operation) {
+ case VMGEXIT_PSC_OP_PRIVATE:
+ case VMGEXIT_PSC_OP_SHARED:
+ vcpu->run->exit_reason = KVM_EXIT_HYPERCALL;
+ vcpu->run->hypercall.nr = KVM_HC_MAP_GPA_RANGE;
+ vcpu->run->hypercall.args[0] = gfn_to_gpa(gfn);
+ vcpu->run->hypercall.args[1] = npages;
+ vcpu->run->hypercall.args[2] = entry_start.operation == VMGEXIT_PSC_OP_PRIVATE
+ ? KVM_MAP_GPA_RANGE_ENCRYPTED
+ : KVM_MAP_GPA_RANGE_DECRYPTED;
+ vcpu->run->hypercall.args[2] |= entry_start.pagesize
+ ? KVM_MAP_GPA_RANGE_PAGE_SZ_2M
+ : KVM_MAP_GPA_RANGE_PAGE_SZ_4K;
+ vcpu->arch.complete_userspace_io = snp_complete_one_psc;
+ return 0; /* forward request to userspace */
+ default:
+ /*
+ * Only shared/private PSC operations are currently supported, so if the
+ * entire range consists of unsupported operations (e.g. SMASH/UNSMASH),
+ * then consider the entire range completed and avoid exiting to
+ * userspace. In theory snp_complete_psc() can always be called directly
+ * at this point to complete the current range and start the next one,
+ * but that could lead to unexpected levels of recursion.
+ */
+ __snp_complete_one_psc(svm);
+ goto next_range;
+ }
+
+ unreachable();
+}
+
+static int __sev_snp_update_protected_guest_state(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ WARN_ON(!mutex_is_locked(&svm->sev_es.snp_vmsa_mutex));
+
+ /* Mark the vCPU as offline and not runnable */
+ vcpu->arch.pv.pv_unhalted = false;
+ vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
+
+ /* Clear use of the VMSA */
+ svm->vmcb->control.vmsa_pa = INVALID_PAGE;
+
+ if (VALID_PAGE(svm->sev_es.snp_vmsa_gpa)) {
+ gfn_t gfn = gpa_to_gfn(svm->sev_es.snp_vmsa_gpa);
+ struct kvm_memory_slot *slot;
+ kvm_pfn_t pfn;
+
+ slot = gfn_to_memslot(vcpu->kvm, gfn);
+ if (!slot)
+ return -EINVAL;
+
+ /*
+ * The new VMSA will be private memory guest memory, so
+ * retrieve the PFN from the gmem backend.
+ */
+ if (kvm_gmem_get_pfn(vcpu->kvm, slot, gfn, &pfn, NULL))
+ return -EINVAL;
+
+ /*
+ * From this point forward, the VMSA will always be a
+ * guest-mapped page rather than the initial one allocated
+ * by KVM in svm->sev_es.vmsa. In theory, svm->sev_es.vmsa
+ * could be free'd and cleaned up here, but that involves
+ * cleanups like wbinvd_on_all_cpus() which would ideally
+ * be handled during teardown rather than guest boot.
+ * Deferring that also allows the existing logic for SEV-ES
+ * VMSAs to be re-used with minimal SNP-specific changes.
+ */
+ svm->sev_es.snp_has_guest_vmsa = true;
+
+ /* Use the new VMSA */
+ svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
+
+ /* Mark the vCPU as runnable */
+ vcpu->arch.pv.pv_unhalted = false;
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+
+ svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
+
+ /*
+ * gmem pages aren't currently migratable, but if this ever
+ * changes then care should be taken to ensure
+ * svm->sev_es.vmsa is pinned through some other means.
+ */
+ kvm_release_pfn_clean(pfn);
+ }
+
+ /*
+ * When replacing the VMSA during SEV-SNP AP creation,
+ * mark the VMCB dirty so that full state is always reloaded.
+ */
+ vmcb_mark_all_dirty(svm->vmcb);
+
+ return 0;
+}
+
+/*
+ * Invoked as part of svm_vcpu_reset() processing of an init event.
+ */
+void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+ int ret;
+
+ if (!sev_snp_guest(vcpu->kvm))
+ return;
+
+ mutex_lock(&svm->sev_es.snp_vmsa_mutex);
+
+ if (!svm->sev_es.snp_ap_waiting_for_reset)
+ goto unlock;
+
+ svm->sev_es.snp_ap_waiting_for_reset = false;
+
+ ret = __sev_snp_update_protected_guest_state(vcpu);
+ if (ret)
+ vcpu_unimpl(vcpu, "snp: AP state update on init failed\n");
+
+unlock:
+ mutex_unlock(&svm->sev_es.snp_vmsa_mutex);
+}
+
+static int sev_snp_ap_creation(struct vcpu_svm *svm)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info;
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct kvm_vcpu *target_vcpu;
+ struct vcpu_svm *target_svm;
+ unsigned int request;
+ unsigned int apic_id;
+ bool kick;
+ int ret;
+
+ request = lower_32_bits(svm->vmcb->control.exit_info_1);
+ apic_id = upper_32_bits(svm->vmcb->control.exit_info_1);
+
+ /* Validate the APIC ID */
+ target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, apic_id);
+ if (!target_vcpu) {
+ vcpu_unimpl(vcpu, "vmgexit: invalid AP APIC ID [%#x] from guest\n",
+ apic_id);
+ return -EINVAL;
+ }
+
+ ret = 0;
+
+ target_svm = to_svm(target_vcpu);
+
+ /*
+ * The target vCPU is valid, so the vCPU will be kicked unless the
+ * request is for CREATE_ON_INIT. For any errors at this stage, the
+ * kick will place the vCPU in an non-runnable state.
+ */
+ kick = true;
+
+ mutex_lock(&target_svm->sev_es.snp_vmsa_mutex);
+
+ target_svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
+ target_svm->sev_es.snp_ap_waiting_for_reset = true;
+
+ /* Interrupt injection mode shouldn't change for AP creation */
+ if (request < SVM_VMGEXIT_AP_DESTROY) {
+ u64 sev_features;
+
+ sev_features = vcpu->arch.regs[VCPU_REGS_RAX];
+ sev_features ^= sev->vmsa_features;
+
+ if (sev_features & SVM_SEV_FEAT_INT_INJ_MODES) {
+ vcpu_unimpl(vcpu, "vmgexit: invalid AP injection mode [%#lx] from guest\n",
+ vcpu->arch.regs[VCPU_REGS_RAX]);
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ switch (request) {
+ case SVM_VMGEXIT_AP_CREATE_ON_INIT:
+ kick = false;
+ fallthrough;
+ case SVM_VMGEXIT_AP_CREATE:
+ if (!page_address_valid(vcpu, svm->vmcb->control.exit_info_2)) {
+ vcpu_unimpl(vcpu, "vmgexit: invalid AP VMSA address [%#llx] from guest\n",
+ svm->vmcb->control.exit_info_2);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Malicious guest can RMPADJUST a large page into VMSA which
+ * will hit the SNP erratum where the CPU will incorrectly signal
+ * an RMP violation #PF if a hugepage collides with the RMP entry
+ * of VMSA page, reject the AP CREATE request if VMSA address from
+ * guest is 2M aligned.
+ */
+ if (IS_ALIGNED(svm->vmcb->control.exit_info_2, PMD_SIZE)) {
+ vcpu_unimpl(vcpu,
+ "vmgexit: AP VMSA address [%llx] from guest is unsafe as it is 2M aligned\n",
+ svm->vmcb->control.exit_info_2);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ target_svm->sev_es.snp_vmsa_gpa = svm->vmcb->control.exit_info_2;
+ break;
+ case SVM_VMGEXIT_AP_DESTROY:
+ break;
+ default:
+ vcpu_unimpl(vcpu, "vmgexit: invalid AP creation request [%#x] from guest\n",
+ request);
+ ret = -EINVAL;
+ break;
+ }
+
+out:
+ if (kick) {
+ kvm_make_request(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, target_vcpu);
+ kvm_vcpu_kick(target_vcpu);
+ }
+
+ mutex_unlock(&target_svm->sev_es.snp_vmsa_mutex);
+
+ return ret;
+}
+
+static int snp_handle_guest_req(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_gpa)
+{
+ struct sev_data_snp_guest_request data = {0};
+ struct kvm *kvm = svm->vcpu.kvm;
+ struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
+ sev_ret_code fw_err = 0;
+ int ret;
+
+ if (!sev_snp_guest(kvm))
+ return -EINVAL;
+
+ mutex_lock(&sev->guest_req_mutex);
+
+ if (kvm_read_guest(kvm, req_gpa, sev->guest_req_buf, PAGE_SIZE)) {
+ ret = -EIO;
+ goto out_unlock;
+ }
+
+ data.gctx_paddr = __psp_pa(sev->snp_context);
+ data.req_paddr = __psp_pa(sev->guest_req_buf);
+ data.res_paddr = __psp_pa(sev->guest_resp_buf);
+
+ /*
+ * Firmware failures are propagated on to guest, but any other failure
+ * condition along the way should be reported to userspace. E.g. if
+ * the PSP is dead and commands are timing out.
+ */
+ ret = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &data, &fw_err);
+ if (ret && !fw_err)
+ goto out_unlock;
+
+ if (kvm_write_guest(kvm, resp_gpa, sev->guest_resp_buf, PAGE_SIZE)) {
+ ret = -EIO;
+ goto out_unlock;
+ }
+
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, SNP_GUEST_ERR(0, fw_err));
+
+ ret = 1; /* resume guest */
+
+out_unlock:
+ mutex_unlock(&sev->guest_req_mutex);
+ return ret;
+}
+
+static int snp_handle_ext_guest_req(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_gpa)
+{
+ struct kvm *kvm = svm->vcpu.kvm;
+ u8 msg_type;
+
+ if (!sev_snp_guest(kvm))
+ return -EINVAL;
+
+ if (kvm_read_guest(kvm, req_gpa + offsetof(struct snp_guest_msg_hdr, msg_type),
+ &msg_type, 1))
+ return -EIO;
+
+ /*
+ * As per GHCB spec, requests of type MSG_REPORT_REQ also allow for
+ * additional certificate data to be provided alongside the attestation
+ * report via the guest-provided data pages indicated by RAX/RBX. The
+ * certificate data is optional and requires additional KVM enablement
+ * to provide an interface for userspace to provide it, but KVM still
+ * needs to be able to handle extended guest requests either way. So
+ * provide a stub implementation that will always return an empty
+ * certificate table in the guest-provided data pages.
+ */
+ if (msg_type == SNP_MSG_REPORT_REQ) {
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ u64 data_npages;
+ gpa_t data_gpa;
+
+ if (!kvm_ghcb_rax_is_valid(svm) || !kvm_ghcb_rbx_is_valid(svm))
+ goto request_invalid;
+
+ data_gpa = vcpu->arch.regs[VCPU_REGS_RAX];
+ data_npages = vcpu->arch.regs[VCPU_REGS_RBX];
+
+ if (!PAGE_ALIGNED(data_gpa))
+ goto request_invalid;
+
+ /*
+ * As per GHCB spec (see "SNP Extended Guest Request"), the
+ * certificate table is terminated by 24-bytes of zeroes.
+ */
+ if (data_npages && kvm_clear_guest(kvm, data_gpa, 24))
+ return -EIO;
+ }
+
+ return snp_handle_guest_req(svm, req_gpa, resp_gpa);
+
+request_invalid:
+ ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT);
+ return 1; /* resume guest */
+}
+
static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
{
struct vmcb_control_area *control = &svm->vmcb->control;
struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info;
u64 ghcb_info;
int ret = 1;
@@ -2784,7 +4138,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
switch (ghcb_info) {
case GHCB_MSR_SEV_INFO_REQ:
- set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX,
+ set_ghcb_msr(svm, GHCB_MSR_SEV_INFO((__u64)sev->ghcb_version,
GHCB_VERSION_MIN,
sev_enc_bit));
break;
@@ -2826,6 +4180,60 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
GHCB_MSR_INFO_POS);
break;
}
+ case GHCB_MSR_AP_RESET_HOLD_REQ:
+ svm->sev_es.ap_reset_hold_type = AP_RESET_HOLD_MSR_PROTO;
+ ret = kvm_emulate_ap_reset_hold(&svm->vcpu);
+
+ /*
+ * Preset the result to a non-SIPI return and then only set
+ * the result to non-zero when delivering a SIPI.
+ */
+ set_ghcb_msr_bits(svm, 0,
+ GHCB_MSR_AP_RESET_HOLD_RESULT_MASK,
+ GHCB_MSR_AP_RESET_HOLD_RESULT_POS);
+
+ set_ghcb_msr_bits(svm, GHCB_MSR_AP_RESET_HOLD_RESP,
+ GHCB_MSR_INFO_MASK,
+ GHCB_MSR_INFO_POS);
+ break;
+ case GHCB_MSR_HV_FT_REQ:
+ set_ghcb_msr_bits(svm, GHCB_HV_FT_SUPPORTED,
+ GHCB_MSR_HV_FT_MASK, GHCB_MSR_HV_FT_POS);
+ set_ghcb_msr_bits(svm, GHCB_MSR_HV_FT_RESP,
+ GHCB_MSR_INFO_MASK, GHCB_MSR_INFO_POS);
+ break;
+ case GHCB_MSR_PREF_GPA_REQ:
+ if (!sev_snp_guest(vcpu->kvm))
+ goto out_terminate;
+
+ set_ghcb_msr_bits(svm, GHCB_MSR_PREF_GPA_NONE, GHCB_MSR_GPA_VALUE_MASK,
+ GHCB_MSR_GPA_VALUE_POS);
+ set_ghcb_msr_bits(svm, GHCB_MSR_PREF_GPA_RESP, GHCB_MSR_INFO_MASK,
+ GHCB_MSR_INFO_POS);
+ break;
+ case GHCB_MSR_REG_GPA_REQ: {
+ u64 gfn;
+
+ if (!sev_snp_guest(vcpu->kvm))
+ goto out_terminate;
+
+ gfn = get_ghcb_msr_bits(svm, GHCB_MSR_GPA_VALUE_MASK,
+ GHCB_MSR_GPA_VALUE_POS);
+
+ svm->sev_es.ghcb_registered_gpa = gfn_to_gpa(gfn);
+
+ set_ghcb_msr_bits(svm, gfn, GHCB_MSR_GPA_VALUE_MASK,
+ GHCB_MSR_GPA_VALUE_POS);
+ set_ghcb_msr_bits(svm, GHCB_MSR_REG_GPA_RESP, GHCB_MSR_INFO_MASK,
+ GHCB_MSR_INFO_POS);
+ break;
+ }
+ case GHCB_MSR_PSC_REQ:
+ if (!sev_snp_guest(vcpu->kvm))
+ goto out_terminate;
+
+ ret = snp_begin_psc_msr(svm, control->ghcb_gpa);
+ break;
case GHCB_MSR_TERM_REQ: {
u64 reason_set, reason_code;
@@ -2838,12 +4246,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
pr_info("SEV-ES guest requested termination: %#llx:%#llx\n",
reason_set, reason_code);
- vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
- vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM;
- vcpu->run->system_event.ndata = 1;
- vcpu->run->system_event.data[0] = control->ghcb_gpa;
-
- return 0;
+ goto out_terminate;
}
default:
/* Error, keep GHCB MSR value as-is */
@@ -2854,6 +4257,14 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
control->ghcb_gpa, ret);
return ret;
+
+out_terminate:
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+ vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM;
+ vcpu->run->system_event.ndata = 1;
+ vcpu->run->system_event.data[0] = control->ghcb_gpa;
+
+ return 0;
}
int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
@@ -2889,6 +4300,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
trace_kvm_vmgexit_enter(vcpu->vcpu_id, svm->sev_es.ghcb);
sev_es_sync_from_ghcb(svm);
+
+ /* SEV-SNP guest requires that the GHCB GPA must be registered */
+ if (sev_snp_guest(svm->vcpu.kvm) && !ghcb_gpa_is_registered(svm, ghcb_gpa)) {
+ vcpu_unimpl(&svm->vcpu, "vmgexit: GHCB GPA [%#llx] is not registered.\n", ghcb_gpa);
+ return -EINVAL;
+ }
+
ret = sev_es_validate_vmgexit(svm);
if (ret)
return ret;
@@ -2925,6 +4343,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
ret = 1;
break;
case SVM_VMGEXIT_AP_HLT_LOOP:
+ svm->sev_es.ap_reset_hold_type = AP_RESET_HOLD_NAE_EVENT;
ret = kvm_emulate_ap_reset_hold(vcpu);
break;
case SVM_VMGEXIT_AP_JUMP_TABLE: {
@@ -2949,6 +4368,41 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
ret = 1;
break;
}
+ case SVM_VMGEXIT_HV_FEATURES:
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_HV_FT_SUPPORTED);
+
+ ret = 1;
+ break;
+ case SVM_VMGEXIT_TERM_REQUEST:
+ pr_info("SEV-ES guest requested termination: reason %#llx info %#llx\n",
+ control->exit_info_1, control->exit_info_2);
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+ vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM;
+ vcpu->run->system_event.ndata = 1;
+ vcpu->run->system_event.data[0] = control->ghcb_gpa;
+ break;
+ case SVM_VMGEXIT_PSC:
+ ret = setup_vmgexit_scratch(svm, true, control->exit_info_2);
+ if (ret)
+ break;
+
+ ret = snp_begin_psc(svm, svm->sev_es.ghcb_sa);
+ break;
+ case SVM_VMGEXIT_AP_CREATION:
+ ret = sev_snp_ap_creation(svm);
+ if (ret) {
+ ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT);
+ }
+
+ ret = 1;
+ break;
+ case SVM_VMGEXIT_GUEST_REQUEST:
+ ret = snp_handle_guest_req(svm, control->exit_info_1, control->exit_info_2);
+ break;
+ case SVM_VMGEXIT_EXT_GUEST_REQUEST:
+ ret = snp_handle_ext_guest_req(svm, control->exit_info_1, control->exit_info_2);
+ break;
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
vcpu_unimpl(vcpu,
"vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n",
@@ -3034,7 +4488,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
struct kvm_vcpu *vcpu = &svm->vcpu;
svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE;
- svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK;
/*
* An SEV-ES guest requires a VMSA area that is a separate from the
@@ -3043,7 +4496,7 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
* the VMSA will be NULL if this vCPU is the destination for intrahost
* migration, and will be copied later.
*/
- if (svm->sev_es.vmsa)
+ if (svm->sev_es.vmsa && !svm->sev_es.snp_has_guest_vmsa)
svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa);
/* Can't intercept CR register access, HV can't modify CR registers */
@@ -3063,7 +4516,7 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
svm_set_intercept(svm, TRAP_CR8_WRITE);
vmcb->control.intercepts[INTERCEPT_DR] = 0;
- if (!sev_es_debug_swap_enabled) {
+ if (!sev_vcpu_has_debug_swap(svm)) {
vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
recalc_intercepts(svm);
@@ -3086,10 +4539,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
/* Clear intercepts on selected MSRs */
set_msr_interception(vcpu, svm->msrpm, MSR_EFER, 1, 1);
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_CR_PAT, 1, 1);
- set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1);
- set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1);
- set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
- set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
}
void sev_init_vmcb(struct vcpu_svm *svm)
@@ -3109,16 +4558,21 @@ void sev_init_vmcb(struct vcpu_svm *svm)
void sev_es_vcpu_reset(struct vcpu_svm *svm)
{
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info;
+
/*
* Set the GHCB MSR value as per the GHCB specification when emulating
* vCPU RESET for an SEV-ES guest.
*/
- set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX,
+ set_ghcb_msr(svm, GHCB_MSR_SEV_INFO((__u64)sev->ghcb_version,
GHCB_VERSION_MIN,
sev_enc_bit));
+
+ mutex_init(&svm->sev_es.snp_vmsa_mutex);
}
-void sev_es_prepare_switch_to_guest(struct sev_es_save_area *hostsa)
+void sev_es_prepare_switch_to_guest(struct vcpu_svm *svm, struct sev_es_save_area *hostsa)
{
/*
* All host state for SEV-ES guests is categorized into three swap types
@@ -3137,16 +4591,16 @@ void sev_es_prepare_switch_to_guest(struct sev_es_save_area *hostsa)
* isn't saved by VMRUN, that isn't already saved by VMSAVE (performed
* by common SVM code).
*/
- hostsa->xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
+ hostsa->xcr0 = kvm_host.xcr0;
hostsa->pkru = read_pkru();
- hostsa->xss = host_xss;
+ hostsa->xss = kvm_host.xss;
/*
* If DebugSwap is enabled, debug registers are loaded but NOT saved by
* the CPU (Type-B). If DebugSwap is disabled/unsupported, the CPU both
* saves and loads debug registers (Type-A).
*/
- if (sev_es_debug_swap_enabled) {
+ if (sev_vcpu_has_debug_swap(svm)) {
hostsa->dr0 = native_get_debugreg(0);
hostsa->dr1 = native_get_debugreg(1);
hostsa->dr2 = native_get_debugreg(2);
@@ -3168,24 +4622,40 @@ void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
return;
}
- /*
- * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where
- * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a
- * non-zero value.
- */
- if (!svm->sev_es.ghcb)
- return;
+ /* Subsequent SIPI */
+ switch (svm->sev_es.ap_reset_hold_type) {
+ case AP_RESET_HOLD_NAE_EVENT:
+ /*
+ * Return from an AP Reset Hold VMGEXIT, where the guest will
+ * set the CS and RIP. Set SW_EXIT_INFO_2 to a non-zero value.
+ */
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 1);
+ break;
+ case AP_RESET_HOLD_MSR_PROTO:
+ /*
+ * Return from an AP Reset Hold VMGEXIT, where the guest will
+ * set the CS and RIP. Set GHCB data field to a non-zero value.
+ */
+ set_ghcb_msr_bits(svm, 1,
+ GHCB_MSR_AP_RESET_HOLD_RESULT_MASK,
+ GHCB_MSR_AP_RESET_HOLD_RESULT_POS);
- ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 1);
+ set_ghcb_msr_bits(svm, GHCB_MSR_AP_RESET_HOLD_RESP,
+ GHCB_MSR_INFO_MASK,
+ GHCB_MSR_INFO_POS);
+ break;
+ default:
+ break;
+ }
}
-struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
+struct page *snp_safe_alloc_page_node(int node, gfp_t gfp)
{
unsigned long pfn;
struct page *p;
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
- return alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ return alloc_pages_node(node, gfp | __GFP_ZERO, 0);
/*
* Allocate an SNP-safe page to workaround the SNP erratum where
@@ -3196,7 +4666,7 @@ struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
* Allocate one extra page, choose a page which is not
* 2MB-aligned, and free the other.
*/
- p = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO, 1);
+ p = alloc_pages_node(node, gfp | __GFP_ZERO, 1);
if (!p)
return NULL;
@@ -3210,3 +4680,271 @@ struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
return p;
}
+
+void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code)
+{
+ struct kvm_memory_slot *slot;
+ struct kvm *kvm = vcpu->kvm;
+ int order, rmp_level, ret;
+ bool assigned;
+ kvm_pfn_t pfn;
+ gfn_t gfn;
+
+ gfn = gpa >> PAGE_SHIFT;
+
+ /*
+ * The only time RMP faults occur for shared pages is when the guest is
+ * triggering an RMP fault for an implicit page-state change from
+ * shared->private. Implicit page-state changes are forwarded to
+ * userspace via KVM_EXIT_MEMORY_FAULT events, however, so RMP faults
+ * for shared pages should not end up here.
+ */
+ if (!kvm_mem_is_private(kvm, gfn)) {
+ pr_warn_ratelimited("SEV: Unexpected RMP fault for non-private GPA 0x%llx\n",
+ gpa);
+ return;
+ }
+
+ slot = gfn_to_memslot(kvm, gfn);
+ if (!kvm_slot_can_be_private(slot)) {
+ pr_warn_ratelimited("SEV: Unexpected RMP fault, non-private slot for GPA 0x%llx\n",
+ gpa);
+ return;
+ }
+
+ ret = kvm_gmem_get_pfn(kvm, slot, gfn, &pfn, &order);
+ if (ret) {
+ pr_warn_ratelimited("SEV: Unexpected RMP fault, no backing page for private GPA 0x%llx\n",
+ gpa);
+ return;
+ }
+
+ ret = snp_lookup_rmpentry(pfn, &assigned, &rmp_level);
+ if (ret || !assigned) {
+ pr_warn_ratelimited("SEV: Unexpected RMP fault, no assigned RMP entry found for GPA 0x%llx PFN 0x%llx error %d\n",
+ gpa, pfn, ret);
+ goto out_no_trace;
+ }
+
+ /*
+ * There are 2 cases where a PSMASH may be needed to resolve an #NPF
+ * with PFERR_GUEST_RMP_BIT set:
+ *
+ * 1) RMPADJUST/PVALIDATE can trigger an #NPF with PFERR_GUEST_SIZEM
+ * bit set if the guest issues them with a smaller granularity than
+ * what is indicated by the page-size bit in the 2MB RMP entry for
+ * the PFN that backs the GPA.
+ *
+ * 2) Guest access via NPT can trigger an #NPF if the NPT mapping is
+ * smaller than what is indicated by the 2MB RMP entry for the PFN
+ * that backs the GPA.
+ *
+ * In both these cases, the corresponding 2M RMP entry needs to
+ * be PSMASH'd to 512 4K RMP entries. If the RMP entry is already
+ * split into 4K RMP entries, then this is likely a spurious case which
+ * can occur when there are concurrent accesses by the guest to a 2MB
+ * GPA range that is backed by a 2MB-aligned PFN who's RMP entry is in
+ * the process of being PMASH'd into 4K entries. These cases should
+ * resolve automatically on subsequent accesses, so just ignore them
+ * here.
+ */
+ if (rmp_level == PG_LEVEL_4K)
+ goto out;
+
+ ret = snp_rmptable_psmash(pfn);
+ if (ret) {
+ /*
+ * Look it up again. If it's 4K now then the PSMASH may have
+ * raced with another process and the issue has already resolved
+ * itself.
+ */
+ if (!snp_lookup_rmpentry(pfn, &assigned, &rmp_level) &&
+ assigned && rmp_level == PG_LEVEL_4K)
+ goto out;
+
+ pr_warn_ratelimited("SEV: Unable to split RMP entry for GPA 0x%llx PFN 0x%llx ret %d\n",
+ gpa, pfn, ret);
+ }
+
+ kvm_zap_gfn_range(kvm, gfn, gfn + PTRS_PER_PMD);
+out:
+ trace_kvm_rmp_fault(vcpu, gpa, pfn, error_code, rmp_level, ret);
+out_no_trace:
+ put_page(pfn_to_page(pfn));
+}
+
+static bool is_pfn_range_shared(kvm_pfn_t start, kvm_pfn_t end)
+{
+ kvm_pfn_t pfn = start;
+
+ while (pfn < end) {
+ int ret, rmp_level;
+ bool assigned;
+
+ ret = snp_lookup_rmpentry(pfn, &assigned, &rmp_level);
+ if (ret) {
+ pr_warn_ratelimited("SEV: Failed to retrieve RMP entry: PFN 0x%llx GFN start 0x%llx GFN end 0x%llx RMP level %d error %d\n",
+ pfn, start, end, rmp_level, ret);
+ return false;
+ }
+
+ if (assigned) {
+ pr_debug("%s: overlap detected, PFN 0x%llx start 0x%llx end 0x%llx RMP level %d\n",
+ __func__, pfn, start, end, rmp_level);
+ return false;
+ }
+
+ pfn++;
+ }
+
+ return true;
+}
+
+static u8 max_level_for_order(int order)
+{
+ if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M))
+ return PG_LEVEL_2M;
+
+ return PG_LEVEL_4K;
+}
+
+static bool is_large_rmp_possible(struct kvm *kvm, kvm_pfn_t pfn, int order)
+{
+ kvm_pfn_t pfn_aligned = ALIGN_DOWN(pfn, PTRS_PER_PMD);
+
+ /*
+ * If this is a large folio, and the entire 2M range containing the
+ * PFN is currently shared, then the entire 2M-aligned range can be
+ * set to private via a single 2M RMP entry.
+ */
+ if (max_level_for_order(order) > PG_LEVEL_4K &&
+ is_pfn_range_shared(pfn_aligned, pfn_aligned + PTRS_PER_PMD))
+ return true;
+
+ return false;
+}
+
+int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order)
+{
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+ kvm_pfn_t pfn_aligned;
+ gfn_t gfn_aligned;
+ int level, rc;
+ bool assigned;
+
+ if (!sev_snp_guest(kvm))
+ return 0;
+
+ rc = snp_lookup_rmpentry(pfn, &assigned, &level);
+ if (rc) {
+ pr_err_ratelimited("SEV: Failed to look up RMP entry: GFN %llx PFN %llx error %d\n",
+ gfn, pfn, rc);
+ return -ENOENT;
+ }
+
+ if (assigned) {
+ pr_debug("%s: already assigned: gfn %llx pfn %llx max_order %d level %d\n",
+ __func__, gfn, pfn, max_order, level);
+ return 0;
+ }
+
+ if (is_large_rmp_possible(kvm, pfn, max_order)) {
+ level = PG_LEVEL_2M;
+ pfn_aligned = ALIGN_DOWN(pfn, PTRS_PER_PMD);
+ gfn_aligned = ALIGN_DOWN(gfn, PTRS_PER_PMD);
+ } else {
+ level = PG_LEVEL_4K;
+ pfn_aligned = pfn;
+ gfn_aligned = gfn;
+ }
+
+ rc = rmp_make_private(pfn_aligned, gfn_to_gpa(gfn_aligned), level, sev->asid, false);
+ if (rc) {
+ pr_err_ratelimited("SEV: Failed to update RMP entry: GFN %llx PFN %llx level %d error %d\n",
+ gfn, pfn, level, rc);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: updated: gfn %llx pfn %llx pfn_aligned %llx max_order %d level %d\n",
+ __func__, gfn, pfn, pfn_aligned, max_order, level);
+
+ return 0;
+}
+
+void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
+{
+ kvm_pfn_t pfn;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return;
+
+ pr_debug("%s: PFN start 0x%llx PFN end 0x%llx\n", __func__, start, end);
+
+ for (pfn = start; pfn < end;) {
+ bool use_2m_update = false;
+ int rc, rmp_level;
+ bool assigned;
+
+ rc = snp_lookup_rmpentry(pfn, &assigned, &rmp_level);
+ if (rc || !assigned)
+ goto next_pfn;
+
+ use_2m_update = IS_ALIGNED(pfn, PTRS_PER_PMD) &&
+ end >= (pfn + PTRS_PER_PMD) &&
+ rmp_level > PG_LEVEL_4K;
+
+ /*
+ * If an unaligned PFN corresponds to a 2M region assigned as a
+ * large page in the RMP table, PSMASH the region into individual
+ * 4K RMP entries before attempting to convert a 4K sub-page.
+ */
+ if (!use_2m_update && rmp_level > PG_LEVEL_4K) {
+ /*
+ * This shouldn't fail, but if it does, report it, but
+ * still try to update RMP entry to shared and pray this
+ * was a spurious error that can be addressed later.
+ */
+ rc = snp_rmptable_psmash(pfn);
+ WARN_ONCE(rc, "SEV: Failed to PSMASH RMP entry for PFN 0x%llx error %d\n",
+ pfn, rc);
+ }
+
+ rc = rmp_make_shared(pfn, use_2m_update ? PG_LEVEL_2M : PG_LEVEL_4K);
+ if (WARN_ONCE(rc, "SEV: Failed to update RMP entry for PFN 0x%llx error %d\n",
+ pfn, rc))
+ goto next_pfn;
+
+ /*
+ * SEV-ES avoids host/guest cache coherency issues through
+ * WBINVD hooks issued via MMU notifiers during run-time, and
+ * KVM's VM destroy path at shutdown. Those MMU notifier events
+ * don't cover gmem since there is no requirement to map pages
+ * to a HVA in order to use them for a running guest. While the
+ * shutdown path would still likely cover things for SNP guests,
+ * userspace may also free gmem pages during run-time via
+ * hole-punching operations on the guest_memfd, so flush the
+ * cache entries for these pages before free'ing them back to
+ * the host.
+ */
+ clflush_cache_range(__va(pfn_to_hpa(pfn)),
+ use_2m_update ? PMD_SIZE : PAGE_SIZE);
+next_pfn:
+ pfn += use_2m_update ? PTRS_PER_PMD : 1;
+ cond_resched();
+ }
+}
+
+int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
+{
+ int level, rc;
+ bool assigned;
+
+ if (!sev_snp_guest(kvm))
+ return 0;
+
+ rc = snp_lookup_rmpentry(pfn, &assigned, &level);
+ if (rc || !assigned)
+ return PG_LEVEL_4K;
+
+ return level;
+}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 9aaf83c8d57d..c115d26844f7 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -53,6 +53,7 @@
#include "svm_onhyperv.h"
MODULE_AUTHOR("Qumranet");
+MODULE_DESCRIPTION("KVM support for SVM (AMD-V) extensions");
MODULE_LICENSE("GPL");
#ifdef MODULE
@@ -99,6 +100,7 @@ static const struct svm_direct_access_msrs {
{ .index = MSR_IA32_SPEC_CTRL, .always = false },
{ .index = MSR_IA32_PRED_CMD, .always = false },
{ .index = MSR_IA32_FLUSH_CMD, .always = false },
+ { .index = MSR_IA32_DEBUGCTLMSR, .always = false },
{ .index = MSR_IA32_LASTBRANCHFROMIP, .always = false },
{ .index = MSR_IA32_LASTBRANCHTOIP, .always = false },
{ .index = MSR_IA32_LASTINTFROMIP, .always = false },
@@ -215,7 +217,7 @@ int vgif = true;
module_param(vgif, int, 0444);
/* enable/disable LBR virtualization */
-static int lbrv = true;
+int lbrv = true;
module_param(lbrv, int, 0444);
static int tsc_scaling = true;
@@ -569,6 +571,11 @@ static void __svm_write_tsc_multiplier(u64 multiplier)
__this_cpu_write(current_tsc_ratio, multiplier);
}
+static __always_inline struct sev_es_save_area *sev_es_host_save_area(struct svm_cpu_data *sd)
+{
+ return page_address(sd->save_area) + 0x400;
+}
+
static inline void kvm_cpu_svm_disable(void)
{
uint64_t efer;
@@ -673,12 +680,9 @@ static int svm_hardware_enable(void)
* TSC_AUX field now to avoid a RDMSR on every vCPU run.
*/
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) {
- struct sev_es_save_area *hostsa;
u32 __maybe_unused msr_hi;
- hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400);
-
- rdmsr(MSR_TSC_AUX, hostsa->tsc_aux, msr_hi);
+ rdmsr(MSR_TSC_AUX, sev_es_host_save_area(sd)->tsc_aux, msr_hi);
}
return 0;
@@ -703,7 +707,7 @@ static int svm_cpu_init(int cpu)
int ret = -ENOMEM;
memset(sd, 0, sizeof(struct svm_cpu_data));
- sd->save_area = snp_safe_alloc_page(NULL);
+ sd->save_area = snp_safe_alloc_page_node(cpu_to_node(cpu), GFP_KERNEL);
if (!sd->save_area)
return ret;
@@ -990,7 +994,7 @@ void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb)
vmcb_mark_dirty(to_vmcb, VMCB_LBR);
}
-static void svm_enable_lbrv(struct kvm_vcpu *vcpu)
+void svm_enable_lbrv(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1000,6 +1004,9 @@ static void svm_enable_lbrv(struct kvm_vcpu *vcpu)
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
+ if (sev_es_guest(vcpu->kvm))
+ set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, 1, 1);
+
/* Move the LBR msrs to the vmcb02 so that the guest can see them. */
if (is_guest_mode(vcpu))
svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr);
@@ -1009,6 +1016,8 @@ static void svm_disable_lbrv(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm);
+
svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK;
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0);
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0);
@@ -1196,7 +1205,7 @@ static inline void init_vmcb_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (guest_cpuid_is_intel(vcpu)) {
+ if (guest_cpuid_is_intel_compatible(vcpu)) {
/*
* We must intercept SYSENTER_EIP and SYSENTER_ESP
* accesses because the processor only stores 32 bits.
@@ -1398,6 +1407,9 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
svm->spec_ctrl = 0;
svm->virt_spec_ctrl = 0;
+ if (init_event)
+ sev_snp_init_protected_guest_state(vcpu);
+
init_vmcb(vcpu);
if (!init_event)
@@ -1421,7 +1433,7 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu)
svm = to_svm(vcpu);
err = -ENOMEM;
- vmcb01_page = snp_safe_alloc_page(vcpu);
+ vmcb01_page = snp_safe_alloc_page();
if (!vmcb01_page)
goto out;
@@ -1430,17 +1442,9 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu)
* SEV-ES guests require a separate VMSA page used to contain
* the encrypted register state of the guest.
*/
- vmsa_page = snp_safe_alloc_page(vcpu);
+ vmsa_page = snp_safe_alloc_page();
if (!vmsa_page)
goto error_free_vmcb_page;
-
- /*
- * SEV-ES guests maintain an encrypted version of their FPU
- * state which is restored and saved on VMRUN and VMEXIT.
- * Mark vcpu->arch.guest_fpu->fpstate as scratch so it won't
- * do xsave/xrstor on it.
- */
- fpstate_set_confidential(&vcpu->arch.guest_fpu);
}
err = avic_init_vcpu(svm);
@@ -1503,11 +1507,6 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
__free_pages(virt_to_page(svm->msrpm), get_order(MSRPM_SIZE));
}
-static struct sev_es_save_area *sev_es_host_save_area(struct svm_cpu_data *sd)
-{
- return page_address(sd->save_area) + 0x400;
-}
-
static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1525,7 +1524,7 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
*/
vmsave(sd->save_area_pa);
if (sev_es_guest(vcpu->kvm))
- sev_es_prepare_switch_to_guest(sev_es_host_save_area(sd));
+ sev_es_prepare_switch_to_guest(svm, sev_es_host_save_area(sd));
if (tsc_scaling)
__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
@@ -1553,6 +1552,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
struct vcpu_svm *svm = to_svm(vcpu);
struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ if (vcpu->scheduled_out && !kvm_pause_in_guest(vcpu->kvm))
+ shrink_ple_window(vcpu);
+
if (sd->current_vmcb != svm->vmcb) {
sd->current_vmcb = svm->vmcb;
@@ -2052,15 +2054,33 @@ static int pf_interception(struct kvm_vcpu *vcpu)
static int npf_interception(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ int rc;
u64 fault_address = svm->vmcb->control.exit_info_2;
u64 error_code = svm->vmcb->control.exit_info_1;
+ /*
+ * WARN if hardware generates a fault with an error code that collides
+ * with KVM-defined sythentic flags. Clear the flags and continue on,
+ * i.e. don't terminate the VM, as KVM can't possibly be relying on a
+ * flag that KVM doesn't know about.
+ */
+ if (WARN_ON_ONCE(error_code & PFERR_SYNTHETIC_MASK))
+ error_code &= ~PFERR_SYNTHETIC_MASK;
+
+ if (sev_snp_guest(vcpu->kvm) && (error_code & PFERR_GUEST_ENC_MASK))
+ error_code |= PFERR_PRIVATE_ACCESS;
+
trace_kvm_page_fault(vcpu, fault_address, error_code);
- return kvm_mmu_page_fault(vcpu, fault_address, error_code,
- static_cpu_has(X86_FEATURE_DECODEASSISTS) ?
- svm->vmcb->control.insn_bytes : NULL,
- svm->vmcb->control.insn_len);
+ rc = kvm_mmu_page_fault(vcpu, fault_address, error_code,
+ static_cpu_has(X86_FEATURE_DECODEASSISTS) ?
+ svm->vmcb->control.insn_bytes : NULL,
+ svm->vmcb->control.insn_len);
+
+ if (rc > 0 && error_code & PFERR_GUEST_RMP_MASK)
+ sev_handle_rmp_fault(vcpu, fault_address, error_code);
+
+ return rc;
}
static int db_interception(struct kvm_vcpu *vcpu)
@@ -2821,10 +2841,24 @@ static int svm_get_msr_feature(struct kvm_msr_entry *msr)
return 0;
}
+static bool
+sev_es_prevent_msr_access(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+{
+ return sev_es_guest(vcpu->kvm) &&
+ vcpu->arch.guest_state_protected &&
+ svm_msrpm_offset(msr_info->index) != MSR_INVALID &&
+ !msr_write_intercepted(vcpu, msr_info->index);
+}
+
static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ if (sev_es_prevent_msr_access(vcpu, msr_info)) {
+ msr_info->data = 0;
+ return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0;
+ }
+
switch (msr_info->index) {
case MSR_AMD64_TSC_RATIO:
if (!msr_info->host_initiated &&
@@ -2854,12 +2888,12 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
break;
case MSR_IA32_SYSENTER_EIP:
msr_info->data = (u32)svm->vmcb01.ptr->save.sysenter_eip;
- if (guest_cpuid_is_intel(vcpu))
+ if (guest_cpuid_is_intel_compatible(vcpu))
msr_info->data |= (u64)svm->sysenter_eip_hi << 32;
break;
case MSR_IA32_SYSENTER_ESP:
msr_info->data = svm->vmcb01.ptr->save.sysenter_esp;
- if (guest_cpuid_is_intel(vcpu))
+ if (guest_cpuid_is_intel_compatible(vcpu))
msr_info->data |= (u64)svm->sysenter_esp_hi << 32;
break;
case MSR_TSC_AUX:
@@ -2975,6 +3009,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
u32 ecx = msr->index;
u64 data = msr->data;
+
+ if (sev_es_prevent_msr_access(vcpu, msr))
+ return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0;
+
switch (ecx) {
case MSR_AMD64_TSC_RATIO:
@@ -3082,11 +3120,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
* 32 bit part of these msrs to support Intel's
* implementation of SYSENTER/SYSEXIT.
*/
- svm->sysenter_eip_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0;
+ svm->sysenter_eip_hi = guest_cpuid_is_intel_compatible(vcpu) ? (data >> 32) : 0;
break;
case MSR_IA32_SYSENTER_ESP:
svm->vmcb01.ptr->save.sysenter_esp = (u32)data;
- svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0;
+ svm->sysenter_esp_hi = guest_cpuid_is_intel_compatible(vcpu) ? (data >> 32) : 0;
break;
case MSR_TSC_AUX:
/*
@@ -3304,7 +3342,9 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[SVM_EXIT_RSM] = rsm_interception,
[SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception,
[SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception,
+#ifdef CONFIG_KVM_AMD_SEV
[SVM_EXIT_VMGEXIT] = sev_handle_vmgexit,
+#endif
};
static void dump_vmcb(struct kvm_vcpu *vcpu)
@@ -3843,16 +3883,27 @@ static void svm_enable_nmi_window(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu);
/*
- * KVM should never request an NMI window when vNMI is enabled, as KVM
- * allows at most one to-be-injected NMI and one pending NMI, i.e. if
- * two NMIs arrive simultaneously, KVM will inject one and set
- * V_NMI_PENDING for the other. WARN, but continue with the standard
- * single-step approach to try and salvage the pending NMI.
+ * If NMIs are outright masked, i.e. the vCPU is already handling an
+ * NMI, and KVM has not yet intercepted an IRET, then there is nothing
+ * more to do at this time as KVM has already enabled IRET intercepts.
+ * If KVM has already intercepted IRET, then single-step over the IRET,
+ * as NMIs aren't architecturally unmasked until the IRET completes.
+ *
+ * If vNMI is enabled, KVM should never request an NMI window if NMIs
+ * are masked, as KVM allows at most one to-be-injected NMI and one
+ * pending NMI. If two NMIs arrive simultaneously, KVM will inject one
+ * NMI and set V_NMI_PENDING for the other, but if and only if NMIs are
+ * unmasked. KVM _will_ request an NMI window in some situations, e.g.
+ * if the vCPU is in an STI shadow or if GIF=0, KVM can't immediately
+ * inject the NMI. In those situations, KVM needs to single-step over
+ * the STI shadow or intercept STGI.
*/
- WARN_ON_ONCE(is_vnmi_enabled(svm));
+ if (svm_get_nmi_mask(vcpu)) {
+ WARN_ON_ONCE(is_vnmi_enabled(svm));
- if (svm_get_nmi_mask(vcpu) && !svm->awaiting_iret_completion)
- return; /* IRET will cause a vm exit */
+ if (!svm->awaiting_iret_completion)
+ return; /* IRET will cause a vm exit */
+ }
/*
* SEV-ES guests are responsible for signaling when a vCPU is ready to
@@ -4085,6 +4136,9 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu)
static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu)
{
+ if (to_kvm_sev_info(vcpu->kvm)->need_init)
+ return -EINVAL;
+
return 1;
}
@@ -4331,11 +4385,11 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_LBRV);
/*
- * Intercept VMLOAD if the vCPU mode is Intel in order to emulate that
+ * Intercept VMLOAD if the vCPU model is Intel in order to emulate that
* VMLOAD drops bits 63:32 of SYSENTER (ignoring the fact that exposing
* SVM on Intel is bonkers and extremely unlikely to work).
*/
- if (!guest_cpuid_is_intel(vcpu))
+ if (!guest_cpuid_is_intel_compatible(vcpu))
kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_V_VMSAVE_VMLOAD);
kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_PAUSEFILTER);
@@ -4554,12 +4608,6 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu)
vcpu->arch.at_instruction_boundary = true;
}
-static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu)
-{
- if (!kvm_pause_in_guest(vcpu->kvm))
- shrink_ple_window(vcpu);
-}
-
static void svm_setup_mce(struct kvm_vcpu *vcpu)
{
/* [63:9] are reserved. */
@@ -4892,6 +4940,17 @@ static void svm_vm_destroy(struct kvm *kvm)
static int svm_vm_init(struct kvm *kvm)
{
+ int type = kvm->arch.vm_type;
+
+ if (type != KVM_X86_DEFAULT_VM &&
+ type != KVM_X86_SW_PROTECTED_VM) {
+ kvm->arch.has_protected_state =
+ (type == KVM_X86_SEV_ES_VM || type == KVM_X86_SNP_VM);
+ to_kvm_sev_info(kvm)->need_init = true;
+
+ kvm->arch.has_private_mem = (type == KVM_X86_SNP_VM);
+ }
+
if (!pause_filter_count || !pause_filter_thresh)
kvm->arch.pause_in_guest = true;
@@ -4906,7 +4965,7 @@ static int svm_vm_init(struct kvm *kvm)
static void *svm_alloc_apic_backing_page(struct kvm_vcpu *vcpu)
{
- struct page *page = snp_safe_alloc_page(vcpu);
+ struct page *page = snp_safe_alloc_page();
if (!page)
return NULL;
@@ -5011,8 +5070,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.check_intercept = svm_check_intercept,
.handle_exit_irqoff = svm_handle_exit_irqoff,
- .sched_in = svm_sched_in,
-
.nested_ops = &svm_nested_ops,
.deliver_interrupt = svm_deliver_interrupt,
@@ -5026,6 +5083,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.enable_smi_window = svm_enable_smi_window,
#endif
+#ifdef CONFIG_KVM_AMD_SEV
+ .dev_get_attr = sev_dev_get_attr,
.mem_enc_ioctl = sev_mem_enc_ioctl,
.mem_enc_register_region = sev_mem_enc_register_region,
.mem_enc_unregister_region = sev_mem_enc_unregister_region,
@@ -5033,7 +5092,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.vm_copy_enc_context_from = sev_vm_copy_enc_context_from,
.vm_move_enc_context_from = sev_vm_move_enc_context_from,
-
+#endif
.check_emulate_instruction = svm_check_emulate_instruction,
.apic_init_signal_blocked = svm_apic_init_signal_blocked,
@@ -5044,6 +5103,10 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.vcpu_deliver_sipi_vector = svm_vcpu_deliver_sipi_vector,
.vcpu_get_apicv_inhibit_reasons = avic_vcpu_get_apicv_inhibit_reasons,
.alloc_apic_backing_page = svm_alloc_apic_backing_page,
+
+ .gmem_prepare = sev_gmem_prepare,
+ .gmem_invalidate = sev_gmem_invalidate,
+ .private_max_mapping_level = sev_private_max_mapping_level,
};
/*
@@ -5249,6 +5312,12 @@ static __init int svm_hardware_setup(void)
nrips = nrips && boot_cpu_has(X86_FEATURE_NRIPS);
+ if (lbrv) {
+ if (!boot_cpu_has(X86_FEATURE_LBRV))
+ lbrv = false;
+ else
+ pr_info("LBR virtualization supported\n");
+ }
/*
* Note, SEV setup consumes npt_enabled and enable_mmio_caching (which
* may be modified by svm_adjust_mmio_mask()), as well as nrips.
@@ -5302,14 +5371,6 @@ static __init int svm_hardware_setup(void)
svm_x86_ops.set_vnmi_pending = NULL;
}
-
- if (lbrv) {
- if (!boot_cpu_has(X86_FEATURE_LBRV))
- lbrv = false;
- else
- pr_info("LBR virtualization supported\n");
- }
-
if (!enable_pmu)
pr_info("PMU virtualization is disabled\n");
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 33878efdebc8..76107c7d0595 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -30,7 +30,7 @@
#define IOPM_SIZE PAGE_SIZE * 3
#define MSRPM_SIZE PAGE_SIZE * 2
-#define MAX_DIRECT_ACCESS_MSRS 47
+#define MAX_DIRECT_ACCESS_MSRS 48
#define MSRPM_OFFSETS 32
extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
extern bool npt_enabled;
@@ -39,6 +39,7 @@ extern int vgif;
extern bool intercept_smi;
extern bool x2avic_enabled;
extern bool vnmi;
+extern int lbrv;
/*
* Clean bits in VMCB.
@@ -79,17 +80,24 @@ enum {
struct kvm_sev_info {
bool active; /* SEV enabled guest */
bool es_active; /* SEV-ES enabled guest */
+ bool need_init; /* waiting for SEV_INIT2 */
unsigned int asid; /* ASID used for this guest */
unsigned int handle; /* SEV firmware handle */
int fd; /* SEV device fd */
unsigned long pages_locked; /* Number of pages locked */
struct list_head regions_list; /* List of registered regions */
u64 ap_jump_table; /* SEV-ES AP Jump Table address */
+ u64 vmsa_features;
+ u16 ghcb_version; /* Highest guest GHCB protocol version allowed */
struct kvm *enc_context_owner; /* Owner of copied encryption context */
struct list_head mirror_vms; /* List of VMs mirroring */
struct list_head mirror_entry; /* Use as a list entry of mirrors */
struct misc_cg *misc_cg; /* For misc cgroup accounting */
atomic_t migration_in_progress;
+ void *snp_context; /* SNP guest context page */
+ void *guest_req_buf; /* Bounce buffer for SNP Guest Request input */
+ void *guest_resp_buf; /* Bounce buffer for SNP Guest Request output */
+ struct mutex guest_req_mutex; /* Must acquire before using bounce buffers */
};
struct kvm_svm {
@@ -197,6 +205,7 @@ struct vcpu_sev_es_state {
u8 valid_bitmap[16];
struct kvm_host_map ghcb_map;
bool received_first_sipi;
+ unsigned int ap_reset_hold_type;
/* SEV-ES scratch area support */
u64 sw_scratch;
@@ -204,6 +213,18 @@ struct vcpu_sev_es_state {
u32 ghcb_sa_len;
bool ghcb_sa_sync;
bool ghcb_sa_free;
+
+ /* SNP Page-State-Change buffer entries currently being processed */
+ u16 psc_idx;
+ u16 psc_inflight;
+ bool psc_2m;
+
+ u64 ghcb_registered_gpa;
+
+ struct mutex snp_vmsa_mutex; /* Used to handle concurrent updates of VMSA. */
+ gpa_t snp_vmsa_gpa;
+ bool snp_ap_waiting_for_reset;
+ bool snp_has_guest_vmsa;
};
struct vcpu_svm {
@@ -318,6 +339,11 @@ static __always_inline struct kvm_svm *to_kvm_svm(struct kvm *kvm)
return container_of(kvm, struct kvm_svm, kvm);
}
+static __always_inline struct kvm_sev_info *to_kvm_sev_info(struct kvm *kvm)
+{
+ return &to_kvm_svm(kvm)->sev_info;
+}
+
static __always_inline bool sev_guest(struct kvm *kvm)
{
#ifdef CONFIG_KVM_AMD_SEV
@@ -340,6 +366,23 @@ static __always_inline bool sev_es_guest(struct kvm *kvm)
#endif
}
+static __always_inline bool sev_snp_guest(struct kvm *kvm)
+{
+#ifdef CONFIG_KVM_AMD_SEV
+ struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+
+ return (sev->vmsa_features & SVM_SEV_FEAT_SNP_ACTIVE) &&
+ !WARN_ON_ONCE(!sev_es_guest(kvm));
+#else
+ return false;
+#endif
+}
+
+static inline bool ghcb_gpa_is_registered(struct vcpu_svm *svm, u64 val)
+{
+ return svm->sev_es.ghcb_registered_gpa == val;
+}
+
static inline void vmcb_mark_all_dirty(struct vmcb *vmcb)
{
vmcb->control.clean = 0;
@@ -543,6 +586,7 @@ u32 *svm_vcpu_alloc_msrpm(void);
void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm);
void svm_vcpu_free_msrpm(u32 *msrpm);
void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb);
+void svm_enable_lbrv(struct kvm_vcpu *vcpu);
void svm_update_lbrv(struct kvm_vcpu *vcpu);
int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer);
@@ -627,7 +671,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
/* avic.c */
#define AVIC_REQUIRED_APICV_INHIBITS \
( \
- BIT(APICV_INHIBIT_REASON_DISABLE) | \
+ BIT(APICV_INHIBIT_REASON_DISABLED) | \
BIT(APICV_INHIBIT_REASON_ABSENT) | \
BIT(APICV_INHIBIT_REASON_HYPERV) | \
BIT(APICV_INHIBIT_REASON_NESTED) | \
@@ -664,13 +708,16 @@ void avic_refresh_virtual_apic_mode(struct kvm_vcpu *vcpu);
/* sev.c */
-#define GHCB_VERSION_MAX 1ULL
-#define GHCB_VERSION_MIN 1ULL
-
-
-extern unsigned int max_sev_asid;
+void pre_sev_run(struct vcpu_svm *svm, int cpu);
+void sev_init_vmcb(struct vcpu_svm *svm);
+void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm);
+int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in);
+void sev_es_vcpu_reset(struct vcpu_svm *svm);
+void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector);
+void sev_es_prepare_switch_to_guest(struct vcpu_svm *svm, struct sev_es_save_area *hostsa);
+void sev_es_unmap_ghcb(struct vcpu_svm *svm);
-void sev_vm_destroy(struct kvm *kvm);
+#ifdef CONFIG_KVM_AMD_SEV
int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp);
int sev_mem_enc_register_region(struct kvm *kvm,
struct kvm_enc_region *range);
@@ -679,22 +726,61 @@ int sev_mem_enc_unregister_region(struct kvm *kvm,
int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd);
int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd);
void sev_guest_memory_reclaimed(struct kvm *kvm);
+int sev_handle_vmgexit(struct kvm_vcpu *vcpu);
-void pre_sev_run(struct vcpu_svm *svm, int cpu);
+/* These symbols are used in common code and are stubbed below. */
+
+struct page *snp_safe_alloc_page_node(int node, gfp_t gfp);
+static inline struct page *snp_safe_alloc_page(void)
+{
+ return snp_safe_alloc_page_node(numa_node_id(), GFP_KERNEL_ACCOUNT);
+}
+
+void sev_free_vcpu(struct kvm_vcpu *vcpu);
+void sev_vm_destroy(struct kvm *kvm);
void __init sev_set_cpu_caps(void);
void __init sev_hardware_setup(void);
void sev_hardware_unsetup(void);
int sev_cpu_init(struct svm_cpu_data *sd);
-void sev_init_vmcb(struct vcpu_svm *svm);
-void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm);
-void sev_free_vcpu(struct kvm_vcpu *vcpu);
-int sev_handle_vmgexit(struct kvm_vcpu *vcpu);
-int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in);
-void sev_es_vcpu_reset(struct vcpu_svm *svm);
-void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector);
-void sev_es_prepare_switch_to_guest(struct sev_es_save_area *hostsa);
-void sev_es_unmap_ghcb(struct vcpu_svm *svm);
-struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu);
+int sev_dev_get_attr(u32 group, u64 attr, u64 *val);
+extern unsigned int max_sev_asid;
+void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code);
+void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu);
+int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
+void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
+int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn);
+#else
+static inline struct page *snp_safe_alloc_page_node(int node, gfp_t gfp)
+{
+ return alloc_pages_node(node, gfp | __GFP_ZERO, 0);
+}
+
+static inline struct page *snp_safe_alloc_page(void)
+{
+ return snp_safe_alloc_page_node(numa_node_id(), GFP_KERNEL_ACCOUNT);
+}
+
+static inline void sev_free_vcpu(struct kvm_vcpu *vcpu) {}
+static inline void sev_vm_destroy(struct kvm *kvm) {}
+static inline void __init sev_set_cpu_caps(void) {}
+static inline void __init sev_hardware_setup(void) {}
+static inline void sev_hardware_unsetup(void) {}
+static inline int sev_cpu_init(struct svm_cpu_data *sd) { return 0; }
+static inline int sev_dev_get_attr(u32 group, u64 attr, u64 *val) { return -ENXIO; }
+#define max_sev_asid 0
+static inline void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code) {}
+static inline void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu) {}
+static inline int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order)
+{
+ return 0;
+}
+static inline void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) {}
+static inline int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
+{
+ return 0;
+}
+
+#endif
/* vmenter.S */
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index c6b4b1728006..d3aeffd6ae75 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -314,12 +314,12 @@ TRACE_EVENT(name, \
__entry->guest_rip = kvm_rip_read(vcpu); \
__entry->isa = isa; \
__entry->vcpu_id = vcpu->vcpu_id; \
- static_call(kvm_x86_get_exit_info)(vcpu, \
- &__entry->exit_reason, \
- &__entry->info1, \
- &__entry->info2, \
- &__entry->intr_info, \
- &__entry->error_code); \
+ kvm_x86_call(get_exit_info)(vcpu, \
+ &__entry->exit_reason, \
+ &__entry->info1, \
+ &__entry->info2, \
+ &__entry->intr_info, \
+ &__entry->error_code); \
), \
\
TP_printk("vcpu %u reason %s%s%s rip 0x%lx info1 0x%016llx " \
@@ -828,7 +828,8 @@ TRACE_EVENT(kvm_emulate_insn,
),
TP_fast_assign(
- __entry->csbase = static_call(kvm_x86_get_segment_base)(vcpu, VCPU_SREG_CS);
+ __entry->csbase = kvm_x86_call(get_segment_base)(vcpu,
+ VCPU_SREG_CS);
__entry->len = vcpu->arch.emulate_ctxt->fetch.ptr
- vcpu->arch.emulate_ctxt->fetch.data;
__entry->rip = vcpu->arch.emulate_ctxt->_eip - __entry->len;
@@ -1074,7 +1075,7 @@ TRACE_EVENT(kvm_smm_transition,
);
/*
- * Tracepoint for VT-d posted-interrupts.
+ * Tracepoint for VT-d posted-interrupts and AMD-Vi Guest Virtual APIC.
*/
TRACE_EVENT(kvm_pi_irte_update,
TP_PROTO(unsigned int host_irq, unsigned int vcpu_id,
@@ -1100,7 +1101,7 @@ TRACE_EVENT(kvm_pi_irte_update,
__entry->set = set;
),
- TP_printk("VT-d PI is %s for irq %u, vcpu %u, gsi: 0x%x, "
+ TP_printk("PI is %s for irq %u, vcpu %u, gsi: 0x%x, "
"gvec: 0x%x, pi_desc_addr: 0x%llx",
__entry->set ? "enabled and being updated" : "disabled",
__entry->host_irq,
@@ -1375,6 +1376,10 @@ TRACE_EVENT(kvm_hv_stimer_cleanup,
__entry->vcpu_id, __entry->timer_index)
);
+#define kvm_print_apicv_inhibit_reasons(inhibits) \
+ (inhibits), (inhibits) ? " " : "", \
+ (inhibits) ? __print_flags(inhibits, "|", APICV_INHIBIT_REASONS) : ""
+
TRACE_EVENT(kvm_apicv_inhibit_changed,
TP_PROTO(int reason, bool set, unsigned long inhibits),
TP_ARGS(reason, set, inhibits),
@@ -1391,9 +1396,10 @@ TRACE_EVENT(kvm_apicv_inhibit_changed,
__entry->inhibits = inhibits;
),
- TP_printk("%s reason=%u, inhibits=0x%lx",
+ TP_printk("%s reason=%u, inhibits=0x%lx%s%s",
__entry->set ? "set" : "cleared",
- __entry->reason, __entry->inhibits)
+ __entry->reason,
+ kvm_print_apicv_inhibit_reasons(__entry->inhibits))
);
TRACE_EVENT(kvm_apicv_accept_irq,
@@ -1678,7 +1684,7 @@ TRACE_EVENT(kvm_nested_vmenter_failed,
),
TP_fast_assign(
- __assign_str(msg, msg);
+ __assign_str(msg);
__entry->err = err;
),
@@ -1834,6 +1840,37 @@ TRACE_EVENT(kvm_vmgexit_msr_protocol_exit,
__entry->vcpu_id, __entry->ghcb_gpa, __entry->result)
);
+/*
+ * Tracepoint for #NPFs due to RMP faults.
+ */
+TRACE_EVENT(kvm_rmp_fault,
+ TP_PROTO(struct kvm_vcpu *vcpu, u64 gpa, u64 pfn, u64 error_code,
+ int rmp_level, int psmash_ret),
+ TP_ARGS(vcpu, gpa, pfn, error_code, rmp_level, psmash_ret),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, vcpu_id)
+ __field(u64, gpa)
+ __field(u64, pfn)
+ __field(u64, error_code)
+ __field(int, rmp_level)
+ __field(int, psmash_ret)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu->vcpu_id;
+ __entry->gpa = gpa;
+ __entry->pfn = pfn;
+ __entry->error_code = error_code;
+ __entry->rmp_level = rmp_level;
+ __entry->psmash_ret = psmash_ret;
+ ),
+
+ TP_printk("vcpu %u gpa %016llx pfn 0x%llx error_code 0x%llx rmp_level %d psmash_ret %d",
+ __entry->vcpu_id, __entry->gpa, __entry->pfn,
+ __entry->error_code, __entry->rmp_level, __entry->psmash_ret)
+);
+
#endif /* _TRACE_KVM_H */
#undef TRACE_INCLUDE_PATH
diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c
new file mode 100644
index 000000000000..0bf35ebe8a1b
--- /dev/null
+++ b/arch/x86/kvm/vmx/main.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/moduleparam.h>
+
+#include "x86_ops.h"
+#include "vmx.h"
+#include "nested.h"
+#include "pmu.h"
+#include "posted_intr.h"
+
+#define VMX_REQUIRED_APICV_INHIBITS \
+ (BIT(APICV_INHIBIT_REASON_DISABLED) | \
+ BIT(APICV_INHIBIT_REASON_ABSENT) | \
+ BIT(APICV_INHIBIT_REASON_HYPERV) | \
+ BIT(APICV_INHIBIT_REASON_BLOCKIRQ) | \
+ BIT(APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED) | \
+ BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) | \
+ BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED))
+
+struct kvm_x86_ops vt_x86_ops __initdata = {
+ .name = KBUILD_MODNAME,
+
+ .check_processor_compatibility = vmx_check_processor_compat,
+
+ .hardware_unsetup = vmx_hardware_unsetup,
+
+ .hardware_enable = vmx_hardware_enable,
+ .hardware_disable = vmx_hardware_disable,
+ .has_emulated_msr = vmx_has_emulated_msr,
+
+ .vm_size = sizeof(struct kvm_vmx),
+ .vm_init = vmx_vm_init,
+ .vm_destroy = vmx_vm_destroy,
+
+ .vcpu_precreate = vmx_vcpu_precreate,
+ .vcpu_create = vmx_vcpu_create,
+ .vcpu_free = vmx_vcpu_free,
+ .vcpu_reset = vmx_vcpu_reset,
+
+ .prepare_switch_to_guest = vmx_prepare_switch_to_guest,
+ .vcpu_load = vmx_vcpu_load,
+ .vcpu_put = vmx_vcpu_put,
+
+ .update_exception_bitmap = vmx_update_exception_bitmap,
+ .get_msr_feature = vmx_get_msr_feature,
+ .get_msr = vmx_get_msr,
+ .set_msr = vmx_set_msr,
+ .get_segment_base = vmx_get_segment_base,
+ .get_segment = vmx_get_segment,
+ .set_segment = vmx_set_segment,
+ .get_cpl = vmx_get_cpl,
+ .get_cs_db_l_bits = vmx_get_cs_db_l_bits,
+ .is_valid_cr0 = vmx_is_valid_cr0,
+ .set_cr0 = vmx_set_cr0,
+ .is_valid_cr4 = vmx_is_valid_cr4,
+ .set_cr4 = vmx_set_cr4,
+ .set_efer = vmx_set_efer,
+ .get_idt = vmx_get_idt,
+ .set_idt = vmx_set_idt,
+ .get_gdt = vmx_get_gdt,
+ .set_gdt = vmx_set_gdt,
+ .set_dr7 = vmx_set_dr7,
+ .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs,
+ .cache_reg = vmx_cache_reg,
+ .get_rflags = vmx_get_rflags,
+ .set_rflags = vmx_set_rflags,
+ .get_if_flag = vmx_get_if_flag,
+
+ .flush_tlb_all = vmx_flush_tlb_all,
+ .flush_tlb_current = vmx_flush_tlb_current,
+ .flush_tlb_gva = vmx_flush_tlb_gva,
+ .flush_tlb_guest = vmx_flush_tlb_guest,
+
+ .vcpu_pre_run = vmx_vcpu_pre_run,
+ .vcpu_run = vmx_vcpu_run,
+ .handle_exit = vmx_handle_exit,
+ .skip_emulated_instruction = vmx_skip_emulated_instruction,
+ .update_emulated_instruction = vmx_update_emulated_instruction,
+ .set_interrupt_shadow = vmx_set_interrupt_shadow,
+ .get_interrupt_shadow = vmx_get_interrupt_shadow,
+ .patch_hypercall = vmx_patch_hypercall,
+ .inject_irq = vmx_inject_irq,
+ .inject_nmi = vmx_inject_nmi,
+ .inject_exception = vmx_inject_exception,
+ .cancel_injection = vmx_cancel_injection,
+ .interrupt_allowed = vmx_interrupt_allowed,
+ .nmi_allowed = vmx_nmi_allowed,
+ .get_nmi_mask = vmx_get_nmi_mask,
+ .set_nmi_mask = vmx_set_nmi_mask,
+ .enable_nmi_window = vmx_enable_nmi_window,
+ .enable_irq_window = vmx_enable_irq_window,
+ .update_cr8_intercept = vmx_update_cr8_intercept,
+ .set_virtual_apic_mode = vmx_set_virtual_apic_mode,
+ .set_apic_access_page_addr = vmx_set_apic_access_page_addr,
+ .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
+ .load_eoi_exitmap = vmx_load_eoi_exitmap,
+ .apicv_pre_state_restore = vmx_apicv_pre_state_restore,
+ .required_apicv_inhibits = VMX_REQUIRED_APICV_INHIBITS,
+ .hwapic_irr_update = vmx_hwapic_irr_update,
+ .hwapic_isr_update = vmx_hwapic_isr_update,
+ .sync_pir_to_irr = vmx_sync_pir_to_irr,
+ .deliver_interrupt = vmx_deliver_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,
+ .get_mt_mask = vmx_get_mt_mask,
+
+ .get_exit_info = vmx_get_exit_info,
+
+ .vcpu_after_set_cpuid = vmx_vcpu_after_set_cpuid,
+
+ .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
+
+ .get_l2_tsc_offset = vmx_get_l2_tsc_offset,
+ .get_l2_tsc_multiplier = vmx_get_l2_tsc_multiplier,
+ .write_tsc_offset = vmx_write_tsc_offset,
+ .write_tsc_multiplier = vmx_write_tsc_multiplier,
+
+ .load_mmu_pgd = vmx_load_mmu_pgd,
+
+ .check_intercept = vmx_check_intercept,
+ .handle_exit_irqoff = vmx_handle_exit_irqoff,
+
+ .cpu_dirty_log_size = PML_ENTITY_NUM,
+ .update_cpu_dirty_logging = vmx_update_cpu_dirty_logging,
+
+ .nested_ops = &vmx_nested_ops,
+
+ .pi_update_irte = vmx_pi_update_irte,
+ .pi_start_assignment = vmx_pi_start_assignment,
+
+#ifdef CONFIG_X86_64
+ .set_hv_timer = vmx_set_hv_timer,
+ .cancel_hv_timer = vmx_cancel_hv_timer,
+#endif
+
+ .setup_mce = vmx_setup_mce,
+
+#ifdef CONFIG_KVM_SMM
+ .smi_allowed = vmx_smi_allowed,
+ .enter_smm = vmx_enter_smm,
+ .leave_smm = vmx_leave_smm,
+ .enable_smi_window = vmx_enable_smi_window,
+#endif
+
+ .check_emulate_instruction = vmx_check_emulate_instruction,
+ .apic_init_signal_blocked = vmx_apic_init_signal_blocked,
+ .migrate_timers = vmx_migrate_timers,
+
+ .msr_filter_changed = vmx_msr_filter_changed,
+ .complete_emulated_msr = kvm_complete_insn_gp,
+
+ .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
+
+ .get_untagged_addr = vmx_get_untagged_addr,
+};
+
+struct kvm_x86_init_ops vt_init_ops __initdata = {
+ .hardware_setup = vmx_hardware_setup,
+ .handle_intel_pt_intr = NULL,
+
+ .runtime_ops = &vt_x86_ops,
+ .pmu_ops = &intel_pmu_ops,
+};
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index d05ddf751491..2392a7ef254d 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -12,6 +12,7 @@
#include "mmu.h"
#include "nested.h"
#include "pmu.h"
+#include "posted_intr.h"
#include "sgx.h"
#include "trace.h"
#include "vmx.h"
@@ -409,18 +410,40 @@ static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ unsigned long exit_qualification;
u32 vm_exit_reason;
- unsigned long exit_qualification = vcpu->arch.exit_qualification;
if (vmx->nested.pml_full) {
vm_exit_reason = EXIT_REASON_PML_FULL;
vmx->nested.pml_full = false;
- exit_qualification &= INTR_INFO_UNBLOCK_NMI;
+
+ /*
+ * It should be impossible to trigger a nested PML Full VM-Exit
+ * for anything other than an EPT Violation from L2. KVM *can*
+ * trigger nEPT page fault injection in response to an EPT
+ * Misconfig, e.g. if the MMIO SPTE was stale and L1's EPT
+ * tables also changed, but KVM should not treat EPT Misconfig
+ * VM-Exits as writes.
+ */
+ WARN_ON_ONCE(vmx->exit_reason.basic != EXIT_REASON_EPT_VIOLATION);
+
+ /*
+ * PML Full and EPT Violation VM-Exits both use bit 12 to report
+ * "NMI unblocking due to IRET", i.e. the bit can be propagated
+ * as-is from the original EXIT_QUALIFICATION.
+ */
+ exit_qualification = vmx_get_exit_qual(vcpu) & INTR_INFO_UNBLOCK_NMI;
} else {
- if (fault->error_code & PFERR_RSVD_MASK)
+ if (fault->error_code & PFERR_RSVD_MASK) {
vm_exit_reason = EXIT_REASON_EPT_MISCONFIG;
- else
+ exit_qualification = 0;
+ } else {
+ exit_qualification = fault->exit_qualification;
+ exit_qualification |= vmx_get_exit_qual(vcpu) &
+ (EPT_VIOLATION_GVA_IS_VALID |
+ EPT_VIOLATION_GVA_TRANSLATED);
vm_exit_reason = EXIT_REASON_EPT_VIOLATION;
+ }
/*
* Although the caller (kvm_inject_emulated_page_fault) would
@@ -2220,6 +2243,9 @@ static void prepare_vmcs02_constant_state(struct vcpu_vmx *vmx)
vmcs_write64(EPT_POINTER,
construct_eptp(&vmx->vcpu, 0, PT64_ROOT_4LEVEL));
+ if (vmx->ve_info)
+ vmcs_write64(VE_INFORMATION_ADDRESS, __pa(vmx->ve_info));
+
/* All VMFUNCs are currently emulated through L0 vmexits. */
if (cpu_has_vmx_vmfunc())
vmcs_write64(VM_FUNCTION_CONTROL, 0);
@@ -2400,7 +2426,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
if (cpu_has_load_ia32_efer()) {
if (guest_efer & EFER_LMA)
exec_control |= VM_ENTRY_IA32E_MODE;
- if (guest_efer != host_efer)
+ if (guest_efer != kvm_host.efer)
exec_control |= VM_ENTRY_LOAD_IA32_EFER;
}
vm_entry_controls_set(vmx, exec_control);
@@ -2413,7 +2439,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
* bits may be modified by vmx_set_efer() in prepare_vmcs02().
*/
exec_control = __vm_exit_controls_get(vmcs01);
- if (cpu_has_load_ia32_efer() && guest_efer != host_efer)
+ if (cpu_has_load_ia32_efer() && guest_efer != kvm_host.efer)
exec_control |= VM_EXIT_LOAD_IA32_EFER;
else
exec_control &= ~VM_EXIT_LOAD_IA32_EFER;
@@ -3874,8 +3900,8 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
if (!pi_test_and_clear_on(vmx->nested.pi_desc))
return 0;
- max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
- if (max_irr != 256) {
+ max_irr = pi_find_highest_vector(vmx->nested.pi_desc);
+ if (max_irr > 0) {
vapic_page = vmx->nested.virtual_apic_map.hva;
if (!vapic_page)
goto mmio_needed;
@@ -4006,10 +4032,46 @@ static bool nested_vmx_preemption_timer_pending(struct kvm_vcpu *vcpu)
to_vmx(vcpu)->nested.preemption_timer_expired;
}
-static bool vmx_has_nested_events(struct kvm_vcpu *vcpu)
+static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection)
{
- return nested_vmx_preemption_timer_pending(vcpu) ||
- to_vmx(vcpu)->nested.mtf_pending;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ void *vapic = vmx->nested.virtual_apic_map.hva;
+ int max_irr, vppr;
+
+ if (nested_vmx_preemption_timer_pending(vcpu) ||
+ vmx->nested.mtf_pending)
+ return true;
+
+ /*
+ * Virtual Interrupt Delivery doesn't require manual injection. Either
+ * the interrupt is already in GUEST_RVI and will be recognized by CPU
+ * at VM-Entry, or there is a KVM_REQ_EVENT pending and KVM will move
+ * the interrupt from the PIR to RVI prior to entering the guest.
+ */
+ if (for_injection)
+ return false;
+
+ if (!nested_cpu_has_vid(get_vmcs12(vcpu)) ||
+ __vmx_interrupt_blocked(vcpu))
+ return false;
+
+ if (!vapic)
+ return false;
+
+ vppr = *((u32 *)(vapic + APIC_PROCPRI));
+
+ max_irr = vmx_get_rvi();
+ if ((max_irr & 0xf0) > (vppr & 0xf0))
+ return true;
+
+ if (vmx->nested.pi_pending && vmx->nested.pi_desc &&
+ pi_test_on(vmx->nested.pi_desc)) {
+ max_irr = pi_find_highest_vector(vmx->nested.pi_desc);
+ if (max_irr > 0 && (max_irr & 0xf0) > (vppr & 0xf0))
+ return true;
+ }
+
+ return false;
}
/*
@@ -4640,7 +4702,7 @@ static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx)
return vmcs_read64(GUEST_IA32_EFER);
if (cpu_has_load_ia32_efer())
- return host_efer;
+ return kvm_host.efer;
for (i = 0; i < vmx->msr_autoload.guest.nr; ++i) {
if (vmx->msr_autoload.guest.val[i].index == MSR_EFER)
@@ -4651,7 +4713,7 @@ static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx)
if (efer_msr)
return efer_msr->data;
- return host_efer;
+ return kvm_host.efer;
}
static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu)
@@ -6208,6 +6270,8 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu,
else if (is_alignment_check(intr_info) &&
!vmx_guest_inject_ac(vcpu))
return true;
+ else if (is_ve_fault(intr_info))
+ return true;
return false;
case EXIT_REASON_EXTERNAL_INTERRUPT:
return true;
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index be40474de6e4..83382a4d1d66 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -348,14 +348,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
switch (msr) {
case MSR_CORE_PERF_FIXED_CTR_CTRL:
- if (data & pmu->fixed_ctr_ctrl_mask)
+ if (data & pmu->fixed_ctr_ctrl_rsvd)
return 1;
if (pmu->fixed_ctr_ctrl != data)
reprogram_fixed_counters(pmu, data);
break;
case MSR_IA32_PEBS_ENABLE:
- if (data & pmu->pebs_enable_mask)
+ if (data & pmu->pebs_enable_rsvd)
return 1;
if (pmu->pebs_enable != data) {
@@ -371,7 +371,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
pmu->ds_area = data;
break;
case MSR_PEBS_DATA_CFG:
- if (data & pmu->pebs_data_cfg_mask)
+ if (data & pmu->pebs_data_cfg_rsvd)
return 1;
pmu->pebs_data_cfg = data;
@@ -436,8 +436,8 @@ static __always_inline u64 intel_get_fixed_pmc_eventsel(unsigned int index)
};
u64 eventsel;
- BUILD_BUG_ON(ARRAY_SIZE(fixed_pmc_perf_ids) != KVM_PMC_MAX_FIXED);
- BUILD_BUG_ON(index >= KVM_PMC_MAX_FIXED);
+ BUILD_BUG_ON(ARRAY_SIZE(fixed_pmc_perf_ids) != KVM_MAX_NR_INTEL_FIXED_COUTNERS);
+ BUILD_BUG_ON(index >= KVM_MAX_NR_INTEL_FIXED_COUTNERS);
/*
* Yell if perf reports support for a fixed counter but perf doesn't
@@ -448,6 +448,14 @@ static __always_inline u64 intel_get_fixed_pmc_eventsel(unsigned int index)
return eventsel;
}
+static void intel_pmu_enable_fixed_counter_bits(struct kvm_pmu *pmu, u64 bits)
+{
+ int i;
+
+ for (i = 0; i < pmu->nr_arch_fixed_counters; i++)
+ pmu->fixed_ctr_ctrl_rsvd &= ~intel_fixed_bits_by_idx(i, bits);
+}
+
static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
{
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
@@ -456,8 +464,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
union cpuid10_eax eax;
union cpuid10_edx edx;
u64 perf_capabilities;
- u64 counter_mask;
- int i;
+ u64 counter_rsvd;
memset(&lbr_desc->records, 0, sizeof(lbr_desc->records));
@@ -501,22 +508,24 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
((u64)1 << edx.split.bit_width_fixed) - 1;
}
- for (i = 0; i < pmu->nr_arch_fixed_counters; i++)
- pmu->fixed_ctr_ctrl_mask &= ~(0xbull << (i * 4));
- counter_mask = ~(((1ull << pmu->nr_arch_gp_counters) - 1) |
+ intel_pmu_enable_fixed_counter_bits(pmu, INTEL_FIXED_0_KERNEL |
+ INTEL_FIXED_0_USER |
+ INTEL_FIXED_0_ENABLE_PMI);
+
+ counter_rsvd = ~(((1ull << pmu->nr_arch_gp_counters) - 1) |
(((1ull << pmu->nr_arch_fixed_counters) - 1) << KVM_FIXED_PMC_BASE_IDX));
- pmu->global_ctrl_mask = counter_mask;
+ pmu->global_ctrl_rsvd = counter_rsvd;
/*
* GLOBAL_STATUS and GLOBAL_OVF_CONTROL (a.k.a. GLOBAL_STATUS_RESET)
* share reserved bit definitions. The kernel just happens to use
* OVF_CTRL for the names.
*/
- pmu->global_status_mask = pmu->global_ctrl_mask
+ pmu->global_status_rsvd = pmu->global_ctrl_rsvd
& ~(MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF |
MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD);
if (vmx_pt_mode_is_host_guest())
- pmu->global_status_mask &=
+ pmu->global_status_rsvd &=
~MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI;
entry = kvm_find_cpuid_entry_index(vcpu, 7, 0);
@@ -544,15 +553,12 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
if (perf_capabilities & PERF_CAP_PEBS_FORMAT) {
if (perf_capabilities & PERF_CAP_PEBS_BASELINE) {
- pmu->pebs_enable_mask = counter_mask;
+ pmu->pebs_enable_rsvd = counter_rsvd;
pmu->reserved_bits &= ~ICL_EVENTSEL_ADAPTIVE;
- for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
- pmu->fixed_ctr_ctrl_mask &=
- ~(1ULL << (KVM_FIXED_PMC_BASE_IDX + i * 4));
- }
- pmu->pebs_data_cfg_mask = ~0xff00000full;
+ pmu->pebs_data_cfg_rsvd = ~0xff00000full;
+ intel_pmu_enable_fixed_counter_bits(pmu, ICL_FIXED_0_ADAPTIVE);
} else {
- pmu->pebs_enable_mask =
+ pmu->pebs_enable_rsvd =
~((1ull << pmu->nr_arch_gp_counters) - 1);
}
}
@@ -564,14 +570,14 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu)
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
- for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) {
+ for (i = 0; i < KVM_MAX_NR_INTEL_GP_COUNTERS; i++) {
pmu->gp_counters[i].type = KVM_PMC_GP;
pmu->gp_counters[i].vcpu = vcpu;
pmu->gp_counters[i].idx = i;
pmu->gp_counters[i].current_config = 0;
}
- for (i = 0; i < KVM_PMC_MAX_FIXED; i++) {
+ for (i = 0; i < KVM_MAX_NR_INTEL_FIXED_COUTNERS; i++) {
pmu->fixed_counters[i].type = KVM_PMC_FIXED;
pmu->fixed_counters[i].vcpu = vcpu;
pmu->fixed_counters[i].idx = i + KVM_FIXED_PMC_BASE_IDX;
@@ -731,6 +737,6 @@ struct kvm_pmu_ops intel_pmu_ops __initdata = {
.deliver_pmi = intel_pmu_deliver_pmi,
.cleanup = intel_pmu_cleanup,
.EVENTSEL_EVENT = ARCH_PERFMON_EVENTSEL_EVENT,
- .MAX_NR_GP_COUNTERS = KVM_INTEL_PMC_MAX_GENERIC,
+ .MAX_NR_GP_COUNTERS = KVM_MAX_NR_INTEL_GP_COUNTERS,
.MIN_NR_GP_COUNTERS = 1,
};
diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c
index af662312fd07..ec08fa3caf43 100644
--- a/arch/x86/kvm/vmx/posted_intr.c
+++ b/arch/x86/kvm/vmx/posted_intr.c
@@ -107,7 +107,7 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
* handle task migration (@cpu != vcpu->cpu).
*/
new.ndst = dest;
- new.sn = 0;
+ __pi_clear_sn(&new);
/*
* Restore the notification vector; in the blocking case, the
@@ -157,7 +157,7 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu)
&per_cpu(wakeup_vcpus_on_cpu, vcpu->cpu));
raw_spin_unlock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu));
- WARN(pi_desc->sn, "PI descriptor SN field set before blocking");
+ WARN(pi_test_sn(pi_desc), "PI descriptor SN field set before blocking");
old.control = READ_ONCE(pi_desc->control);
do {
diff --git a/arch/x86/kvm/vmx/posted_intr.h b/arch/x86/kvm/vmx/posted_intr.h
index 26992076552e..1715d2ab07be 100644
--- a/arch/x86/kvm/vmx/posted_intr.h
+++ b/arch/x86/kvm/vmx/posted_intr.h
@@ -2,97 +2,8 @@
#ifndef __KVM_X86_VMX_POSTED_INTR_H
#define __KVM_X86_VMX_POSTED_INTR_H
-#define POSTED_INTR_ON 0
-#define POSTED_INTR_SN 1
-
-#define PID_TABLE_ENTRY_VALID 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 bool pi_test_and_clear_sn(struct pi_desc *pi_desc)
-{
- return test_and_clear_bit(POSTED_INTR_SN,
- (unsigned long *)&pi_desc->control);
-}
-
-static inline bool 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 bool pi_test_on(struct pi_desc *pi_desc)
-{
- return test_bit(POSTED_INTR_ON,
- (unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_sn(struct pi_desc *pi_desc)
-{
- return test_bit(POSTED_INTR_SN,
- (unsigned long *)&pi_desc->control);
-}
+#include <linux/find.h>
+#include <asm/posted_intr.h>
void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu);
void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu);
@@ -103,4 +14,12 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
uint32_t guest_irq, bool set);
void vmx_pi_start_assignment(struct kvm *kvm);
+static inline int pi_find_highest_vector(struct pi_desc *pi_desc)
+{
+ int vec;
+
+ vec = find_last_bit((unsigned long *)pi_desc->pir, 256);
+ return vec < 256 ? vec : -1;
+}
+
#endif /* __KVM_X86_VMX_POSTED_INTR_H */
diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h
index 7c1996b433e2..b25625314658 100644
--- a/arch/x86/kvm/vmx/vmcs.h
+++ b/arch/x86/kvm/vmx/vmcs.h
@@ -140,6 +140,11 @@ static inline bool is_nm_fault(u32 intr_info)
return is_exception_n(intr_info, NM_VECTOR);
}
+static inline bool is_ve_fault(u32 intr_info)
+{
+ return is_exception_n(intr_info, VE_VECTOR);
+}
+
/* Undocumented: icebp/int1 */
static inline bool is_icebp(u32 intr_info)
{
diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h
index 01936013428b..56fd150a6f24 100644
--- a/arch/x86/kvm/vmx/vmcs12.h
+++ b/arch/x86/kvm/vmx/vmcs12.h
@@ -188,12 +188,13 @@ struct __packed vmcs12 {
};
/*
- * VMCS12_REVISION is an arbitrary id that should be changed if the content or
- * layout of struct vmcs12 is changed. MSR_IA32_VMX_BASIC returns this id, and
- * VMPTRLD verifies that the VMCS region that L1 is loading contains this id.
+ * VMCS12_REVISION is KVM's arbitrary ID for the layout of struct vmcs12. KVM
+ * enumerates this value to L1 via MSR_IA32_VMX_BASIC, and checks the revision
+ * ID during nested VMPTRLD to verify that L1 is loading a VMCS that adhere's
+ * to KVM's virtual CPU definition.
*
- * IMPORTANT: Changing this value will break save/restore compatibility with
- * older kvm releases.
+ * DO NOT change this value, as it will break save/restore compatibility with
+ * older KVM releases.
*/
#define VMCS12_REVISION 0x11e57ed0
@@ -206,7 +207,8 @@ struct __packed vmcs12 {
#define VMCS12_SIZE KVM_STATE_NESTED_VMX_VMCS_SIZE
/*
- * For save/restore compatibility, the vmcs12 field offsets must not change.
+ * For save/restore compatibility, the vmcs12 field offsets must not change,
+ * although appending fields and/or filling gaps is obviously allowed.
*/
#define CHECK_OFFSET(field, loc) \
ASSERT_STRUCT_OFFSET(struct vmcs12, field, loc)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 22411f4aff53..f18c2d8c7476 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -68,10 +68,13 @@
#include "vmcs12.h"
#include "vmx.h"
#include "x86.h"
+#include "x86_ops.h"
#include "smm.h"
#include "vmx_onhyperv.h"
+#include "posted_intr.h"
MODULE_AUTHOR("Qumranet");
+MODULE_DESCRIPTION("KVM support for VMX (Intel VT-x) extensions");
MODULE_LICENSE("GPL");
#ifdef MODULE
@@ -257,7 +260,7 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
return 0;
}
- if (host_arch_capabilities & ARCH_CAP_SKIP_VMENTRY_L1DFLUSH) {
+ if (kvm_host.arch_capabilities & ARCH_CAP_SKIP_VMENTRY_L1DFLUSH) {
l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED;
return 0;
}
@@ -402,7 +405,7 @@ static void vmx_update_fb_clear_dis(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx)
* and VM-Exit.
*/
vmx->disable_fb_clear = !cpu_feature_enabled(X86_FEATURE_CLEAR_CPU_BUF) &&
- (host_arch_capabilities & ARCH_CAP_FB_CLEAR_CTRL) &&
+ (kvm_host.arch_capabilities & ARCH_CAP_FB_CLEAR_CTRL) &&
!boot_cpu_has_bug(X86_BUG_MDS) &&
!boot_cpu_has_bug(X86_BUG_TAA);
@@ -530,8 +533,6 @@ static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx)
static unsigned long host_idt_base;
#if IS_ENABLED(CONFIG_HYPERV)
-static struct kvm_x86_ops vmx_x86_ops __initdata;
-
static bool __read_mostly enlightened_vmcs = true;
module_param(enlightened_vmcs, bool, 0444);
@@ -581,9 +582,8 @@ static __init void hv_init_evmcs(void)
}
if (ms_hyperv.nested_features & HV_X64_NESTED_DIRECT_FLUSH)
- vmx_x86_ops.enable_l2_tlb_flush
+ vt_x86_ops.enable_l2_tlb_flush
= hv_enable_l2_tlb_flush;
-
} else {
enlightened_vmcs = false;
}
@@ -874,6 +874,12 @@ void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu)
eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
(1u << DB_VECTOR) | (1u << AC_VECTOR);
/*
+ * #VE isn't used for VMX. To test against unexpected changes
+ * related to #VE for VMX, intercept unexpected #VE and warn on it.
+ */
+ if (IS_ENABLED(CONFIG_KVM_INTEL_PROVE_VE))
+ eb |= 1u << VE_VECTOR;
+ /*
* Guest access to VMware backdoor ports could legitimately
* trigger #GP because of TSS I/O permission bitmap.
* We intercept those #GP and allow access to them anyway
@@ -1118,12 +1124,12 @@ static bool update_transition_efer(struct vcpu_vmx *vmx)
* atomically, since it's faster than switching it manually.
*/
if (cpu_has_load_ia32_efer() ||
- (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) {
+ (enable_ept && ((vmx->vcpu.arch.efer ^ kvm_host.efer) & EFER_NX))) {
if (!(guest_efer & EFER_LMA))
guest_efer &= ~EFER_LME;
- if (guest_efer != host_efer)
+ if (guest_efer != kvm_host.efer)
add_atomic_switch_msr(vmx, MSR_EFER,
- guest_efer, host_efer, false);
+ guest_efer, kvm_host.efer, false);
else
clear_atomic_switch_msr(vmx, MSR_EFER);
return false;
@@ -1136,7 +1142,7 @@ static bool update_transition_efer(struct vcpu_vmx *vmx)
clear_atomic_switch_msr(vmx, MSR_EFER);
guest_efer &= ~ignore_bits;
- guest_efer |= host_efer & ignore_bits;
+ guest_efer |= kvm_host.efer & ignore_bits;
vmx->guest_uret_msrs[i].data = guest_efer;
vmx->guest_uret_msrs[i].mask = ~ignore_bits;
@@ -1406,6 +1412,38 @@ static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data)
}
#endif
+static void grow_ple_window(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ unsigned int old = vmx->ple_window;
+
+ vmx->ple_window = __grow_ple_window(old, ple_window,
+ ple_window_grow,
+ ple_window_max);
+
+ if (vmx->ple_window != old) {
+ vmx->ple_window_dirty = true;
+ trace_kvm_ple_window_update(vcpu->vcpu_id,
+ vmx->ple_window, old);
+ }
+}
+
+static void shrink_ple_window(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ unsigned int old = vmx->ple_window;
+
+ vmx->ple_window = __shrink_ple_window(old, ple_window,
+ ple_window_shrink,
+ ple_window);
+
+ if (vmx->ple_window != old) {
+ vmx->ple_window_dirty = true;
+ trace_kvm_ple_window_update(vcpu->vcpu_id,
+ vmx->ple_window, old);
+ }
+}
+
void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu,
struct loaded_vmcs *buddy)
{
@@ -1477,10 +1515,13 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu,
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
* vcpu mutex is already taken.
*/
-static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ if (vcpu->scheduled_out && !kvm_pause_in_guest(vcpu->kvm))
+ shrink_ple_window(vcpu);
+
vmx_vcpu_load_vmcs(vcpu, cpu, NULL);
vmx_vcpu_pi_load(vcpu, cpu);
@@ -1488,7 +1529,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
vmx->host_debugctlmsr = get_debugctlmsr();
}
-static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
+void vmx_vcpu_put(struct kvm_vcpu *vcpu)
{
vmx_vcpu_pi_put(vcpu);
@@ -1547,7 +1588,7 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
vmx->emulation_required = vmx_emulation_required(vcpu);
}
-static bool vmx_get_if_flag(struct kvm_vcpu *vcpu)
+bool vmx_get_if_flag(struct kvm_vcpu *vcpu)
{
return vmx_get_rflags(vcpu) & X86_EFLAGS_IF;
}
@@ -1653,8 +1694,8 @@ static int vmx_rtit_ctl_check(struct kvm_vcpu *vcpu, u64 data)
return 0;
}
-static int vmx_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type,
- void *insn, int insn_len)
+int vmx_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type,
+ void *insn, int insn_len)
{
/*
* Emulation of instructions in SGX enclaves is impossible as RIP does
@@ -1738,7 +1779,7 @@ rip_updated:
* Recognizes a pending MTF VM-exit and records the nested state for later
* delivery.
*/
-static void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu)
+void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu)
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1769,7 +1810,7 @@ static void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu)
}
}
-static int vmx_skip_emulated_instruction(struct kvm_vcpu *vcpu)
+int vmx_skip_emulated_instruction(struct kvm_vcpu *vcpu)
{
vmx_update_emulated_instruction(vcpu);
return skip_emulated_instruction(vcpu);
@@ -1788,7 +1829,7 @@ static void vmx_clear_hlt(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
}
-static void vmx_inject_exception(struct kvm_vcpu *vcpu)
+void vmx_inject_exception(struct kvm_vcpu *vcpu)
{
struct kvm_queued_exception *ex = &vcpu->arch.exception;
u32 intr_info = ex->vector | INTR_INFO_VALID_MASK;
@@ -1909,12 +1950,12 @@ u64 vmx_get_l2_tsc_multiplier(struct kvm_vcpu *vcpu)
return kvm_caps.default_tsc_scaling_ratio;
}
-static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu)
+void vmx_write_tsc_offset(struct kvm_vcpu *vcpu)
{
vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
}
-static void vmx_write_tsc_multiplier(struct kvm_vcpu *vcpu)
+void vmx_write_tsc_multiplier(struct kvm_vcpu *vcpu)
{
vmcs_write64(TSC_MULTIPLIER, vcpu->arch.tsc_scaling_ratio);
}
@@ -1957,7 +1998,7 @@ static inline bool is_vmx_feature_control_msr_valid(struct vcpu_vmx *vmx,
return !(msr->data & ~valid_bits);
}
-static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
+int vmx_get_msr_feature(struct kvm_msr_entry *msr)
{
switch (msr->index) {
case KVM_FIRST_EMULATED_VMX_MSR ... KVM_LAST_EMULATED_VMX_MSR:
@@ -1974,7 +2015,7 @@ static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
* Returns 0 on success, non-0 otherwise.
* Assumes vcpu_load() was already called.
*/
-static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
struct vmx_uret_msr *msr;
@@ -2155,7 +2196,7 @@ static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated
* Returns 0 on success, non-0 otherwise.
* Assumes vcpu_load() was already called.
*/
-static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
struct vmx_uret_msr *msr;
@@ -2458,7 +2499,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
return ret;
}
-static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
+void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
{
unsigned long guest_owned_bits;
@@ -2520,17 +2561,15 @@ static bool cpu_has_sgx(void)
*/
static bool cpu_has_perf_global_ctrl_bug(void)
{
- if (boot_cpu_data.x86 == 0x6) {
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_NEHALEM_EP: /* AAK155 */
- case INTEL_FAM6_NEHALEM: /* AAP115 */
- case INTEL_FAM6_WESTMERE: /* AAT100 */
- case INTEL_FAM6_WESTMERE_EP: /* BC86,AAY89,BD102 */
- case INTEL_FAM6_NEHALEM_EX: /* BA97 */
- return true;
- default:
- break;
- }
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_NEHALEM_EP: /* AAK155 */
+ case INTEL_NEHALEM: /* AAP115 */
+ case INTEL_WESTMERE: /* AAT100 */
+ case INTEL_WESTMERE_EP: /* BC86,AAY89,BD102 */
+ case INTEL_NEHALEM_EX: /* BA97 */
+ return true;
+ default:
+ break;
}
return false;
@@ -2606,6 +2645,9 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
&_cpu_based_2nd_exec_control))
return -EIO;
}
+ if (!IS_ENABLED(CONFIG_KVM_INTEL_PROVE_VE))
+ _cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_EPT_VIOLATION_VE;
+
#ifndef CONFIG_X86_64
if (!(_cpu_based_2nd_exec_control &
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
@@ -2630,6 +2672,7 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
return -EIO;
vmx_cap->ept = 0;
+ _cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_EPT_VIOLATION_VE;
}
if (!(_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_VPID) &&
vmx_cap->vpid) {
@@ -2759,7 +2802,7 @@ static bool kvm_is_vmx_supported(void)
return supported;
}
-static int vmx_check_processor_compat(void)
+int vmx_check_processor_compat(void)
{
int cpu = raw_smp_processor_id();
struct vmcs_config vmcs_conf;
@@ -2801,7 +2844,7 @@ fault:
return -EFAULT;
}
-static int vmx_hardware_enable(void)
+int vmx_hardware_enable(void)
{
int cpu = raw_smp_processor_id();
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
@@ -2825,9 +2868,6 @@ static int vmx_hardware_enable(void)
return r;
}
- if (enable_ept)
- ept_sync_global();
-
return 0;
}
@@ -2841,7 +2881,7 @@ static void vmclear_local_loaded_vmcss(void)
__loaded_vmcs_clear(v);
}
-static void vmx_hardware_disable(void)
+void vmx_hardware_disable(void)
{
vmclear_local_loaded_vmcss();
@@ -3155,7 +3195,7 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
#endif
-static void vmx_flush_tlb_all(struct kvm_vcpu *vcpu)
+void vmx_flush_tlb_all(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -3185,7 +3225,7 @@ static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu)
return to_vmx(vcpu)->vpid;
}
-static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu)
+void vmx_flush_tlb_current(struct kvm_vcpu *vcpu)
{
struct kvm_mmu *mmu = vcpu->arch.mmu;
u64 root_hpa = mmu->root.hpa;
@@ -3201,7 +3241,7 @@ static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu)
vpid_sync_context(vmx_get_current_vpid(vcpu));
}
-static void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr)
+void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr)
{
/*
* vpid_sync_vcpu_addr() is a nop if vpid==0, see the comment in
@@ -3210,7 +3250,7 @@ static void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr)
vpid_sync_vcpu_addr(vmx_get_current_vpid(vcpu), addr);
}
-static void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu)
+void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu)
{
/*
* vpid_sync_context() is a nop if vpid==0, e.g. if enable_vpid==0 or a
@@ -3255,7 +3295,7 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu)
#define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \
CPU_BASED_CR3_STORE_EXITING)
-static bool vmx_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
+bool vmx_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
if (is_guest_mode(vcpu))
return nested_guest_cr0_valid(vcpu, cr0);
@@ -3376,8 +3416,7 @@ u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level)
return eptp;
}
-static void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa,
- int root_level)
+void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level)
{
struct kvm *kvm = vcpu->kvm;
bool update_guest_cr3 = true;
@@ -3406,8 +3445,7 @@ static void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa,
vmcs_writel(GUEST_CR3, guest_cr3);
}
-
-static bool vmx_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
+bool vmx_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
{
/*
* We operate under the default treatment of SMM, so VMX cannot be
@@ -3523,7 +3561,7 @@ void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg)
var->g = (ar >> 15) & 1;
}
-static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
+u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
{
struct kvm_segment s;
@@ -3600,14 +3638,14 @@ void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg)
vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(var));
}
-static void vmx_set_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)
{
__vmx_set_segment(vcpu, var, seg);
to_vmx(vcpu)->emulation_required = vmx_emulation_required(vcpu);
}
-static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
+void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
{
u32 ar = vmx_read_guest_seg_ar(to_vmx(vcpu), VCPU_SREG_CS);
@@ -3615,25 +3653,25 @@ static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
*l = (ar >> 13) & 1;
}
-static void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
+void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
{
dt->size = vmcs_read32(GUEST_IDTR_LIMIT);
dt->address = vmcs_readl(GUEST_IDTR_BASE);
}
-static void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
+void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
{
vmcs_write32(GUEST_IDTR_LIMIT, dt->size);
vmcs_writel(GUEST_IDTR_BASE, dt->address);
}
-static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
+void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
{
dt->size = vmcs_read32(GUEST_GDTR_LIMIT);
dt->address = vmcs_readl(GUEST_GDTR_BASE);
}
-static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
+void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
{
vmcs_write32(GUEST_GDTR_LIMIT, dt->size);
vmcs_writel(GUEST_GDTR_BASE, dt->address);
@@ -4101,27 +4139,7 @@ void pt_update_intercept_for_msr(struct kvm_vcpu *vcpu)
}
}
-static bool vmx_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
-{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
- void *vapic_page;
- u32 vppr;
- int rvi;
-
- if (WARN_ON_ONCE(!is_guest_mode(vcpu)) ||
- !nested_cpu_has_vid(get_vmcs12(vcpu)) ||
- WARN_ON_ONCE(!vmx->nested.virtual_apic_map.gfn))
- return false;
-
- rvi = vmx_get_rvi();
-
- vapic_page = vmx->nested.virtual_apic_map.hva;
- vppr = *((u32 *)(vapic_page + APIC_PROCPRI));
-
- return ((rvi & 0xf0) > (vppr & 0xf0));
-}
-
-static void vmx_msr_filter_changed(struct kvm_vcpu *vcpu)
+void vmx_msr_filter_changed(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
u32 i;
@@ -4265,8 +4283,8 @@ static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
return 0;
}
-static void vmx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
- int trig_mode, int vector)
+void vmx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
+ int trig_mode, int vector)
{
struct kvm_vcpu *vcpu = apic->vcpu;
@@ -4350,7 +4368,7 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
}
if (cpu_has_load_ia32_efer())
- vmcs_write64(HOST_IA32_EFER, host_efer);
+ vmcs_write64(HOST_IA32_EFER, kvm_host.efer);
}
void set_cr4_guest_host_mask(struct vcpu_vmx *vmx)
@@ -4428,7 +4446,7 @@ static u32 vmx_vmexit_ctrl(void)
~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | VM_EXIT_LOAD_IA32_EFER);
}
-static void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
+void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -4594,6 +4612,7 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
if (!enable_ept) {
exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
+ exec_control &= ~SECONDARY_EXEC_EPT_VIOLATION_VE;
enable_unrestricted_guest = 0;
}
if (!enable_unrestricted_guest)
@@ -4692,7 +4711,7 @@ static int vmx_alloc_ipiv_pid_table(struct kvm *kvm)
return 0;
}
-static int vmx_vcpu_precreate(struct kvm *kvm)
+int vmx_vcpu_precreate(struct kvm *kvm)
{
return vmx_alloc_ipiv_pid_table(kvm);
}
@@ -4717,8 +4736,12 @@ static void init_vmcs(struct vcpu_vmx *vmx)
exec_controls_set(vmx, vmx_exec_control(vmx));
- if (cpu_has_secondary_exec_ctrls())
+ if (cpu_has_secondary_exec_ctrls()) {
secondary_exec_controls_set(vmx, vmx_secondary_exec_control(vmx));
+ if (vmx->ve_info)
+ vmcs_write64(VE_INFORMATION_ADDRESS,
+ __pa(vmx->ve_info));
+ }
if (cpu_has_tertiary_exec_ctrls())
tertiary_exec_controls_set(vmx, vmx_tertiary_exec_control(vmx));
@@ -4844,10 +4867,10 @@ static void __vmx_vcpu_reset(struct kvm_vcpu *vcpu)
* or POSTED_INTR_WAKEUP_VECTOR.
*/
vmx->pi_desc.nv = POSTED_INTR_VECTOR;
- vmx->pi_desc.sn = 1;
+ __pi_set_sn(&vmx->pi_desc);
}
-static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -4906,12 +4929,12 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
vmx_update_fb_clear_dis(vcpu, vmx);
}
-static void vmx_enable_irq_window(struct kvm_vcpu *vcpu)
+void vmx_enable_irq_window(struct kvm_vcpu *vcpu)
{
exec_controls_setbit(to_vmx(vcpu), CPU_BASED_INTR_WINDOW_EXITING);
}
-static void vmx_enable_nmi_window(struct kvm_vcpu *vcpu)
+void vmx_enable_nmi_window(struct kvm_vcpu *vcpu)
{
if (!enable_vnmi ||
vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_STI) {
@@ -4922,7 +4945,7 @@ static void vmx_enable_nmi_window(struct kvm_vcpu *vcpu)
exec_controls_setbit(to_vmx(vcpu), CPU_BASED_NMI_WINDOW_EXITING);
}
-static void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinjected)
+void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinjected)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
uint32_t intr;
@@ -4950,7 +4973,7 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinjected)
vmx_clear_hlt(vcpu);
}
-static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
+void vmx_inject_nmi(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -5028,7 +5051,7 @@ bool vmx_nmi_blocked(struct kvm_vcpu *vcpu)
GUEST_INTR_STATE_NMI));
}
-static int vmx_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
+int vmx_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
{
if (to_vmx(vcpu)->nested.nested_run_pending)
return -EBUSY;
@@ -5040,17 +5063,22 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
return !vmx_nmi_blocked(vcpu);
}
+bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
+{
+ return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) ||
+ (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
+}
+
bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
{
if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
return false;
- return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) ||
- (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
- (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
+ return __vmx_interrupt_blocked(vcpu);
}
-static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
+int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
{
if (to_vmx(vcpu)->nested.nested_run_pending)
return -EBUSY;
@@ -5065,7 +5093,7 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
return !vmx_interrupt_blocked(vcpu);
}
-static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
+int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
{
void __user *ret;
@@ -5085,7 +5113,7 @@ static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
return init_rmode_tss(kvm, ret);
}
-static int vmx_set_identity_map_addr(struct kvm *kvm, u64 ident_addr)
+int vmx_set_identity_map_addr(struct kvm *kvm, u64 ident_addr)
{
to_kvm_vmx(kvm)->ept_identity_map_addr = ident_addr;
return 0;
@@ -5206,6 +5234,16 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
if (is_invalid_opcode(intr_info))
return handle_ud(vcpu);
+ if (WARN_ON_ONCE(is_ve_fault(intr_info))) {
+ struct vmx_ve_information *ve_info = vmx->ve_info;
+
+ WARN_ONCE(ve_info->exit_reason != EXIT_REASON_EPT_VIOLATION,
+ "Unexpected #VE on VM-Exit reason 0x%x", ve_info->exit_reason);
+ dump_vmcs(vcpu);
+ kvm_mmu_print_sptes(vcpu, ve_info->guest_physical_address, "#VE");
+ return 1;
+ }
+
error_code = 0;
if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
@@ -5371,8 +5409,7 @@ static int handle_io(struct kvm_vcpu *vcpu)
return kvm_fast_pio(vcpu, size, port, in);
}
-static void
-vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
+void vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
{
/*
* Patch in the VMCALL instruction:
@@ -5578,7 +5615,7 @@ out:
return kvm_complete_insn_gp(vcpu, err);
}
-static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
+void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
{
get_debugreg(vcpu->arch.db[0], 0);
get_debugreg(vcpu->arch.db[1], 1);
@@ -5597,7 +5634,7 @@ static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
set_debugreg(DR6_RESERVED, 6);
}
-static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
+void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
{
vmcs_writel(GUEST_DR7, val);
}
@@ -5770,8 +5807,6 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) != 0 ?
PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK;
- vcpu->arch.exit_qualification = exit_qualification;
-
/*
* Check that the GPA doesn't exceed physical memory limits, as that is
* a guest page fault. We have to emulate the instruction here, because
@@ -5868,7 +5903,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
return 1;
}
-static int vmx_vcpu_pre_run(struct kvm_vcpu *vcpu)
+int vmx_vcpu_pre_run(struct kvm_vcpu *vcpu)
{
if (vmx_emulation_required_with_pending_exception(vcpu)) {
kvm_prepare_emulation_failure_exit(vcpu);
@@ -5878,38 +5913,6 @@ static int vmx_vcpu_pre_run(struct kvm_vcpu *vcpu)
return 1;
}
-static void grow_ple_window(struct kvm_vcpu *vcpu)
-{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
- unsigned int old = vmx->ple_window;
-
- vmx->ple_window = __grow_ple_window(old, ple_window,
- ple_window_grow,
- ple_window_max);
-
- if (vmx->ple_window != old) {
- vmx->ple_window_dirty = true;
- trace_kvm_ple_window_update(vcpu->vcpu_id,
- vmx->ple_window, old);
- }
-}
-
-static void shrink_ple_window(struct kvm_vcpu *vcpu)
-{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
- unsigned int old = vmx->ple_window;
-
- vmx->ple_window = __shrink_ple_window(old, ple_window,
- ple_window_shrink,
- ple_window);
-
- if (vmx->ple_window != old) {
- vmx->ple_window_dirty = true;
- trace_kvm_ple_window_update(vcpu->vcpu_id,
- vmx->ple_window, old);
- }
-}
-
/*
* Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE
* exiting, so only get here on cpu with PAUSE-Loop-Exiting.
@@ -6156,9 +6159,8 @@ 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, u32 *reason,
- u64 *info1, u64 *info2,
- u32 *intr_info, u32 *error_code)
+void vmx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
+ u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -6416,6 +6418,24 @@ void dump_vmcs(struct kvm_vcpu *vcpu)
if (secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
pr_err("Virtual processor ID = 0x%04x\n",
vmcs_read16(VIRTUAL_PROCESSOR_ID));
+ if (secondary_exec_control & SECONDARY_EXEC_EPT_VIOLATION_VE) {
+ struct vmx_ve_information *ve_info = vmx->ve_info;
+ u64 ve_info_pa = vmcs_read64(VE_INFORMATION_ADDRESS);
+
+ /*
+ * If KVM is dumping the VMCS, then something has gone wrong
+ * already. Derefencing an address from the VMCS, which could
+ * very well be corrupted, is a terrible idea. The virtual
+ * address is known so use it.
+ */
+ pr_err("VE info address = 0x%016llx%s\n", ve_info_pa,
+ ve_info_pa == __pa(ve_info) ? "" : "(corrupted!)");
+ pr_err("ve_info: 0x%08x 0x%08x 0x%016llx 0x%016llx 0x%016llx 0x%04x\n",
+ ve_info->exit_reason, ve_info->delivery,
+ ve_info->exit_qualification,
+ ve_info->guest_linear_address,
+ ve_info->guest_physical_address, ve_info->eptp_index);
+ }
}
/*
@@ -6601,7 +6621,7 @@ unexpected_vmexit:
return 0;
}
-static int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
{
int ret = __vmx_handle_exit(vcpu, exit_fastpath);
@@ -6641,9 +6661,10 @@ static noinstr void vmx_l1d_flush(struct kvm_vcpu *vcpu)
bool flush_l1d;
/*
- * Clear the per-vcpu flush bit, it gets set again
- * either from vcpu_run() or from one of the unsafe
- * VMEXIT handlers.
+ * Clear the per-vcpu flush bit, it gets set again if the vCPU
+ * is reloaded, i.e. if the vCPU is scheduled out or if KVM
+ * exits to userspace, or if KVM reaches one of the unsafe
+ * VMEXIT handlers, e.g. if KVM calls into the emulator.
*/
flush_l1d = vcpu->arch.l1tf_flush_l1d;
vcpu->arch.l1tf_flush_l1d = false;
@@ -6689,7 +6710,7 @@ static noinstr void vmx_l1d_flush(struct kvm_vcpu *vcpu)
: "eax", "ebx", "ecx", "edx");
}
-static void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
+void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
int tpr_threshold;
@@ -6759,7 +6780,7 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
vmx_update_msr_bitmap_x2apic(vcpu);
}
-static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu)
+void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu)
{
const gfn_t gfn = APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT;
struct kvm *kvm = vcpu->kvm;
@@ -6828,7 +6849,7 @@ out:
kvm_release_pfn_clean(pfn);
}
-static void vmx_hwapic_isr_update(int max_isr)
+void vmx_hwapic_isr_update(int max_isr)
{
u16 status;
u8 old;
@@ -6862,7 +6883,7 @@ static void vmx_set_rvi(int vector)
}
}
-static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
+void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
{
/*
* When running L2, updating RVI is only relevant when
@@ -6876,7 +6897,7 @@ static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
vmx_set_rvi(max_irr);
}
-static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
+int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
int max_irr;
@@ -6922,7 +6943,7 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
return max_irr;
}
-static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
+void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
{
if (!kvm_vcpu_apicv_active(vcpu))
return;
@@ -6933,7 +6954,7 @@ static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
vmcs_write64(EOI_EXIT_BITMAP3, eoi_exit_bitmap[3]);
}
-static void vmx_apicv_pre_state_restore(struct kvm_vcpu *vcpu)
+void vmx_apicv_pre_state_restore(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -6964,24 +6985,22 @@ static void handle_nm_fault_irqoff(struct kvm_vcpu *vcpu)
rdmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
}
-static void handle_exception_irqoff(struct vcpu_vmx *vmx)
+static void handle_exception_irqoff(struct kvm_vcpu *vcpu, u32 intr_info)
{
- u32 intr_info = vmx_get_intr_info(&vmx->vcpu);
-
/* if exit due to PF check for async PF */
if (is_page_fault(intr_info))
- vmx->vcpu.arch.apf.host_apf_flags = kvm_read_and_reset_apf_flags();
+ vcpu->arch.apf.host_apf_flags = kvm_read_and_reset_apf_flags();
/* if exit due to NM, handle before interrupts are enabled */
else if (is_nm_fault(intr_info))
- handle_nm_fault_irqoff(&vmx->vcpu);
+ handle_nm_fault_irqoff(vcpu);
/* Handle machine checks before interrupts are enabled */
else if (is_machine_check(intr_info))
kvm_machine_check();
}
-static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu)
+static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu,
+ u32 intr_info)
{
- u32 intr_info = vmx_get_intr_info(vcpu);
unsigned int vector = intr_info & INTR_INFO_VECTOR_MASK;
if (KVM_BUG(!is_external_intr(intr_info), vcpu->kvm,
@@ -6998,7 +7017,7 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu)
vcpu->arch.at_instruction_boundary = true;
}
-static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu)
+void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -7006,16 +7025,16 @@ static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu)
return;
if (vmx->exit_reason.basic == EXIT_REASON_EXTERNAL_INTERRUPT)
- handle_external_interrupt_irqoff(vcpu);
+ handle_external_interrupt_irqoff(vcpu, vmx_get_intr_info(vcpu));
else if (vmx->exit_reason.basic == EXIT_REASON_EXCEPTION_NMI)
- handle_exception_irqoff(vmx);
+ handle_exception_irqoff(vcpu, vmx_get_intr_info(vcpu));
}
/*
* The kvm parameter can be NULL (module initialization, or invocation before
* VM creation). Be sure to check the kvm parameter before using it.
*/
-static bool vmx_has_emulated_msr(struct kvm *kvm, u32 index)
+bool vmx_has_emulated_msr(struct kvm *kvm, u32 index)
{
switch (index) {
case MSR_IA32_SMBASE:
@@ -7138,7 +7157,7 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
IDT_VECTORING_ERROR_CODE);
}
-static void vmx_cancel_injection(struct kvm_vcpu *vcpu)
+void vmx_cancel_injection(struct kvm_vcpu *vcpu)
{
__vmx_complete_interrupts(vcpu,
vmcs_read32(VM_ENTRY_INTR_INFO_FIELD),
@@ -7308,7 +7327,7 @@ out:
guest_state_exit_irqoff();
}
-static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
+fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long cr3, cr4;
@@ -7463,7 +7482,7 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
return vmx_exit_handlers_fastpath(vcpu, force_immediate_exit);
}
-static void vmx_vcpu_free(struct kvm_vcpu *vcpu)
+void vmx_vcpu_free(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -7472,9 +7491,10 @@ static void vmx_vcpu_free(struct kvm_vcpu *vcpu)
free_vpid(vmx->vpid);
nested_vmx_free_vcpu(vcpu);
free_loaded_vmcs(vmx->loaded_vmcs);
+ free_page((unsigned long)vmx->ve_info);
}
-static int vmx_vcpu_create(struct kvm_vcpu *vcpu)
+int vmx_vcpu_create(struct kvm_vcpu *vcpu)
{
struct vmx_uret_msr *tsx_ctrl;
struct vcpu_vmx *vmx;
@@ -7565,6 +7585,20 @@ static int vmx_vcpu_create(struct kvm_vcpu *vcpu)
goto free_vmcs;
}
+ err = -ENOMEM;
+ if (vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_EPT_VIOLATION_VE) {
+ struct page *page;
+
+ BUILD_BUG_ON(sizeof(*vmx->ve_info) > PAGE_SIZE);
+
+ /* ve_info must be page aligned. */
+ page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ if (!page)
+ goto free_vmcs;
+
+ vmx->ve_info = page_to_virt(page);
+ }
+
if (vmx_can_use_ipiv(vcpu))
WRITE_ONCE(to_kvm_vmx(vcpu->kvm)->pid_table[vcpu->vcpu_id],
__pa(&vmx->pi_desc) | PID_TABLE_ENTRY_VALID);
@@ -7583,7 +7617,7 @@ free_vpid:
#define L1TF_MSG_SMT "L1TF CPU bug present and SMT on, data leak possible. See CVE-2018-3646 and https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/l1tf.html for details.\n"
#define L1TF_MSG_L1D "L1TF CPU bug present and virtualization mitigation disabled, data leak possible. See CVE-2018-3646 and https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/l1tf.html for details.\n"
-static int vmx_vm_init(struct kvm *kvm)
+int vmx_vm_init(struct kvm *kvm)
{
if (!ple_gap)
kvm->arch.pause_in_guest = true;
@@ -7614,41 +7648,27 @@ static int vmx_vm_init(struct kvm *kvm)
return 0;
}
-static u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
+u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
{
- /* We wanted to honor guest CD/MTRR/PAT, but doing so could result in
- * memory aliases with conflicting memory types and sometimes MCEs.
- * We have to be careful as to what are honored and when.
- *
- * For MMIO, guest CD/MTRR are ignored. The EPT memory type is set to
- * UC. The effective memory type is UC or WC depending on guest PAT.
- * This was historically the source of MCEs and we want to be
- * conservative.
- *
- * When there is no need to deal with noncoherent DMA (e.g., no VT-d
- * or VT-d has snoop control), guest CD/MTRR/PAT are all ignored. The
- * EPT memory type is set to WB. The effective memory type is forced
- * WB.
- *
- * Otherwise, we trust guest. Guest CD/MTRR/PAT are all honored. The
- * EPT memory type is used to emulate guest CD/MTRR.
+ /*
+ * Force UC for host MMIO regions, as allowing the guest to access MMIO
+ * with cacheable accesses will result in Machine Checks.
*/
-
if (is_mmio)
return MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT;
- if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
+ /*
+ * Force WB and ignore guest PAT if the VM does NOT have a non-coherent
+ * device attached and the CPU doesn't support self-snoop. Letting the
+ * guest control memory types on Intel CPUs without self-snoop may
+ * result in unexpected behavior, and so KVM's (historical) ABI is to
+ * trust the guest to behave only as a last resort.
+ */
+ if (!static_cpu_has(X86_FEATURE_SELFSNOOP) &&
+ !kvm_arch_has_noncoherent_dma(vcpu->kvm))
return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
- if (kvm_read_cr0_bits(vcpu, X86_CR0_CD)) {
- if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
- return MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT;
- else
- return (MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT) |
- VMX_EPT_IPAT_BIT;
- }
-
- return kvm_mtrr_get_guest_memory_type(vcpu, gfn) << VMX_EPT_MT_EPTE_SHIFT;
+ return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT);
}
static void vmcs_set_secondary_exec_control(struct vcpu_vmx *vmx, u32 new_ctl)
@@ -7786,7 +7806,7 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu)
vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4));
}
-static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
+void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -8001,10 +8021,10 @@ static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE;
}
-static int vmx_check_intercept(struct kvm_vcpu *vcpu,
- struct x86_instruction_info *info,
- enum x86_intercept_stage stage,
- struct x86_exception *exception)
+int vmx_check_intercept(struct kvm_vcpu *vcpu,
+ struct x86_instruction_info *info,
+ enum x86_intercept_stage stage,
+ struct x86_exception *exception)
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
@@ -8084,8 +8104,8 @@ static inline int u64_shl_div_u64(u64 a, unsigned int shift,
return 0;
}
-static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc,
- bool *expired)
+int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc,
+ bool *expired)
{
struct vcpu_vmx *vmx;
u64 tscl, guest_tscl, delta_tsc, lapic_timer_advance_cycles;
@@ -8124,18 +8144,12 @@ static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc,
return 0;
}
-static void vmx_cancel_hv_timer(struct kvm_vcpu *vcpu)
+void vmx_cancel_hv_timer(struct kvm_vcpu *vcpu)
{
to_vmx(vcpu)->hv_deadline_tsc = -1;
}
#endif
-static void vmx_sched_in(struct kvm_vcpu *vcpu, int cpu)
-{
- if (!kvm_pause_in_guest(vcpu->kvm))
- shrink_ple_window(vcpu);
-}
-
void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -8159,7 +8173,7 @@ void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu)
secondary_exec_controls_clearbit(vmx, SECONDARY_EXEC_ENABLE_PML);
}
-static void vmx_setup_mce(struct kvm_vcpu *vcpu)
+void vmx_setup_mce(struct kvm_vcpu *vcpu)
{
if (vcpu->arch.mcg_cap & MCG_LMCE_P)
to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
@@ -8170,7 +8184,7 @@ static void vmx_setup_mce(struct kvm_vcpu *vcpu)
}
#ifdef CONFIG_KVM_SMM
-static int vmx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
+int vmx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
{
/* we need a nested vmexit to enter SMM, postpone if run is pending */
if (to_vmx(vcpu)->nested.nested_run_pending)
@@ -8178,7 +8192,7 @@ static int vmx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
return !is_smm(vcpu);
}
-static int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)
+int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -8199,7 +8213,7 @@ static int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)
return 0;
}
-static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
+int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
int ret;
@@ -8220,18 +8234,18 @@ static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
return 0;
}
-static void vmx_enable_smi_window(struct kvm_vcpu *vcpu)
+void vmx_enable_smi_window(struct kvm_vcpu *vcpu)
{
/* RSM will cause a vmexit anyway. */
}
#endif
-static bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu)
+bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu)
{
return to_vmx(vcpu)->nested.vmxon && !is_guest_mode(vcpu);
}
-static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
+void vmx_migrate_timers(struct kvm_vcpu *vcpu)
{
if (is_guest_mode(vcpu)) {
struct hrtimer *timer = &to_vmx(vcpu)->nested.preemption_timer;
@@ -8241,7 +8255,7 @@ static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
}
}
-static void vmx_hardware_unsetup(void)
+void vmx_hardware_unsetup(void)
{
kvm_set_posted_intr_wakeup_handler(NULL);
@@ -8251,18 +8265,7 @@ static void vmx_hardware_unsetup(void)
free_kvm_area();
}
-#define VMX_REQUIRED_APICV_INHIBITS \
-( \
- BIT(APICV_INHIBIT_REASON_DISABLE)| \
- BIT(APICV_INHIBIT_REASON_ABSENT) | \
- BIT(APICV_INHIBIT_REASON_HYPERV) | \
- BIT(APICV_INHIBIT_REASON_BLOCKIRQ) | \
- BIT(APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED) | \
- BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) | \
- BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED) \
-)
-
-static void vmx_vm_destroy(struct kvm *kvm)
+void vmx_vm_destroy(struct kvm *kvm)
{
struct kvm_vmx *kvm_vmx = to_kvm_vmx(kvm);
@@ -8313,148 +8316,6 @@ gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags
return (sign_extend64(gva, lam_bit) & ~BIT_ULL(63)) | (gva & BIT_ULL(63));
}
-static struct kvm_x86_ops vmx_x86_ops __initdata = {
- .name = KBUILD_MODNAME,
-
- .check_processor_compatibility = vmx_check_processor_compat,
-
- .hardware_unsetup = vmx_hardware_unsetup,
-
- .hardware_enable = vmx_hardware_enable,
- .hardware_disable = vmx_hardware_disable,
- .has_emulated_msr = vmx_has_emulated_msr,
-
- .vm_size = sizeof(struct kvm_vmx),
- .vm_init = vmx_vm_init,
- .vm_destroy = vmx_vm_destroy,
-
- .vcpu_precreate = vmx_vcpu_precreate,
- .vcpu_create = vmx_vcpu_create,
- .vcpu_free = vmx_vcpu_free,
- .vcpu_reset = vmx_vcpu_reset,
-
- .prepare_switch_to_guest = vmx_prepare_switch_to_guest,
- .vcpu_load = vmx_vcpu_load,
- .vcpu_put = vmx_vcpu_put,
-
- .update_exception_bitmap = vmx_update_exception_bitmap,
- .get_msr_feature = vmx_get_msr_feature,
- .get_msr = vmx_get_msr,
- .set_msr = vmx_set_msr,
- .get_segment_base = vmx_get_segment_base,
- .get_segment = vmx_get_segment,
- .set_segment = vmx_set_segment,
- .get_cpl = vmx_get_cpl,
- .get_cs_db_l_bits = vmx_get_cs_db_l_bits,
- .is_valid_cr0 = vmx_is_valid_cr0,
- .set_cr0 = vmx_set_cr0,
- .is_valid_cr4 = vmx_is_valid_cr4,
- .set_cr4 = vmx_set_cr4,
- .set_efer = vmx_set_efer,
- .get_idt = vmx_get_idt,
- .set_idt = vmx_set_idt,
- .get_gdt = vmx_get_gdt,
- .set_gdt = vmx_set_gdt,
- .set_dr7 = vmx_set_dr7,
- .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs,
- .cache_reg = vmx_cache_reg,
- .get_rflags = vmx_get_rflags,
- .set_rflags = vmx_set_rflags,
- .get_if_flag = vmx_get_if_flag,
-
- .flush_tlb_all = vmx_flush_tlb_all,
- .flush_tlb_current = vmx_flush_tlb_current,
- .flush_tlb_gva = vmx_flush_tlb_gva,
- .flush_tlb_guest = vmx_flush_tlb_guest,
-
- .vcpu_pre_run = vmx_vcpu_pre_run,
- .vcpu_run = vmx_vcpu_run,
- .handle_exit = vmx_handle_exit,
- .skip_emulated_instruction = vmx_skip_emulated_instruction,
- .update_emulated_instruction = vmx_update_emulated_instruction,
- .set_interrupt_shadow = vmx_set_interrupt_shadow,
- .get_interrupt_shadow = vmx_get_interrupt_shadow,
- .patch_hypercall = vmx_patch_hypercall,
- .inject_irq = vmx_inject_irq,
- .inject_nmi = vmx_inject_nmi,
- .inject_exception = vmx_inject_exception,
- .cancel_injection = vmx_cancel_injection,
- .interrupt_allowed = vmx_interrupt_allowed,
- .nmi_allowed = vmx_nmi_allowed,
- .get_nmi_mask = vmx_get_nmi_mask,
- .set_nmi_mask = vmx_set_nmi_mask,
- .enable_nmi_window = vmx_enable_nmi_window,
- .enable_irq_window = vmx_enable_irq_window,
- .update_cr8_intercept = vmx_update_cr8_intercept,
- .set_virtual_apic_mode = vmx_set_virtual_apic_mode,
- .set_apic_access_page_addr = vmx_set_apic_access_page_addr,
- .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
- .load_eoi_exitmap = vmx_load_eoi_exitmap,
- .apicv_pre_state_restore = vmx_apicv_pre_state_restore,
- .required_apicv_inhibits = VMX_REQUIRED_APICV_INHIBITS,
- .hwapic_irr_update = vmx_hwapic_irr_update,
- .hwapic_isr_update = vmx_hwapic_isr_update,
- .guest_apic_has_interrupt = vmx_guest_apic_has_interrupt,
- .sync_pir_to_irr = vmx_sync_pir_to_irr,
- .deliver_interrupt = vmx_deliver_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,
- .get_mt_mask = vmx_get_mt_mask,
-
- .get_exit_info = vmx_get_exit_info,
-
- .vcpu_after_set_cpuid = vmx_vcpu_after_set_cpuid,
-
- .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
-
- .get_l2_tsc_offset = vmx_get_l2_tsc_offset,
- .get_l2_tsc_multiplier = vmx_get_l2_tsc_multiplier,
- .write_tsc_offset = vmx_write_tsc_offset,
- .write_tsc_multiplier = vmx_write_tsc_multiplier,
-
- .load_mmu_pgd = vmx_load_mmu_pgd,
-
- .check_intercept = vmx_check_intercept,
- .handle_exit_irqoff = vmx_handle_exit_irqoff,
-
- .sched_in = vmx_sched_in,
-
- .cpu_dirty_log_size = PML_ENTITY_NUM,
- .update_cpu_dirty_logging = vmx_update_cpu_dirty_logging,
-
- .nested_ops = &vmx_nested_ops,
-
- .pi_update_irte = vmx_pi_update_irte,
- .pi_start_assignment = vmx_pi_start_assignment,
-
-#ifdef CONFIG_X86_64
- .set_hv_timer = vmx_set_hv_timer,
- .cancel_hv_timer = vmx_cancel_hv_timer,
-#endif
-
- .setup_mce = vmx_setup_mce,
-
-#ifdef CONFIG_KVM_SMM
- .smi_allowed = vmx_smi_allowed,
- .enter_smm = vmx_enter_smm,
- .leave_smm = vmx_leave_smm,
- .enable_smi_window = vmx_enable_smi_window,
-#endif
-
- .check_emulate_instruction = vmx_check_emulate_instruction,
- .apic_init_signal_blocked = vmx_apic_init_signal_blocked,
- .migrate_timers = vmx_migrate_timers,
-
- .msr_filter_changed = vmx_msr_filter_changed,
- .complete_emulated_msr = kvm_complete_insn_gp,
-
- .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
-
- .get_untagged_addr = vmx_get_untagged_addr,
-};
-
static unsigned int vmx_handle_intel_pt_intr(void)
{
struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
@@ -8500,18 +8361,16 @@ static void __init vmx_setup_me_spte_mask(void)
u64 me_mask = 0;
/*
- * kvm_get_shadow_phys_bits() returns shadow_phys_bits. Use
- * the former to avoid exposing shadow_phys_bits.
- *
* On pre-MKTME system, boot_cpu_data.x86_phys_bits equals to
- * shadow_phys_bits. On MKTME and/or TDX capable systems,
+ * kvm_host.maxphyaddr. On MKTME and/or TDX capable systems,
* boot_cpu_data.x86_phys_bits holds the actual physical address
- * w/o the KeyID bits, and shadow_phys_bits equals to MAXPHYADDR
- * reported by CPUID. Those bits between are KeyID bits.
+ * w/o the KeyID bits, and kvm_host.maxphyaddr equals to
+ * MAXPHYADDR reported by CPUID. Those bits between are KeyID bits.
*/
- if (boot_cpu_data.x86_phys_bits != kvm_get_shadow_phys_bits())
+ if (boot_cpu_data.x86_phys_bits != kvm_host.maxphyaddr)
me_mask = rsvd_bits(boot_cpu_data.x86_phys_bits,
- kvm_get_shadow_phys_bits() - 1);
+ kvm_host.maxphyaddr - 1);
+
/*
* Unlike SME, host kernel doesn't support setting up any
* MKTME KeyID on Intel platforms. No memory encryption
@@ -8520,9 +8379,7 @@ static void __init vmx_setup_me_spte_mask(void)
kvm_mmu_set_me_spte_mask(0, me_mask);
}
-static struct kvm_x86_init_ops vmx_init_ops __initdata;
-
-static __init int hardware_setup(void)
+__init int vmx_hardware_setup(void)
{
unsigned long host_bndcfgs;
struct desc_ptr dt;
@@ -8591,16 +8448,16 @@ static __init int hardware_setup(void)
* using the APIC_ACCESS_ADDR VMCS field.
*/
if (!flexpriority_enabled)
- vmx_x86_ops.set_apic_access_page_addr = NULL;
+ vt_x86_ops.set_apic_access_page_addr = NULL;
if (!cpu_has_vmx_tpr_shadow())
- vmx_x86_ops.update_cr8_intercept = NULL;
+ vt_x86_ops.update_cr8_intercept = NULL;
#if IS_ENABLED(CONFIG_HYPERV)
if (ms_hyperv.nested_features & HV_X64_NESTED_GUEST_MAPPING_FLUSH
&& enable_ept) {
- vmx_x86_ops.flush_remote_tlbs = hv_flush_remote_tlbs;
- vmx_x86_ops.flush_remote_tlbs_range = hv_flush_remote_tlbs_range;
+ vt_x86_ops.flush_remote_tlbs = hv_flush_remote_tlbs;
+ vt_x86_ops.flush_remote_tlbs_range = hv_flush_remote_tlbs_range;
}
#endif
@@ -8615,7 +8472,7 @@ static __init int hardware_setup(void)
if (!cpu_has_vmx_apicv())
enable_apicv = 0;
if (!enable_apicv)
- vmx_x86_ops.sync_pir_to_irr = NULL;
+ vt_x86_ops.sync_pir_to_irr = NULL;
if (!enable_apicv || !cpu_has_vmx_ipiv())
enable_ipiv = false;
@@ -8651,7 +8508,7 @@ static __init int hardware_setup(void)
enable_pml = 0;
if (!enable_pml)
- vmx_x86_ops.cpu_dirty_log_size = 0;
+ vt_x86_ops.cpu_dirty_log_size = 0;
if (!cpu_has_vmx_preemption_timer())
enable_preemption_timer = false;
@@ -8676,8 +8533,8 @@ static __init int hardware_setup(void)
}
if (!enable_preemption_timer) {
- vmx_x86_ops.set_hv_timer = NULL;
- vmx_x86_ops.cancel_hv_timer = NULL;
+ vt_x86_ops.set_hv_timer = NULL;
+ vt_x86_ops.cancel_hv_timer = NULL;
}
kvm_caps.supported_mce_cap |= MCG_LMCE_P;
@@ -8688,9 +8545,9 @@ static __init int hardware_setup(void)
if (!enable_ept || !enable_pmu || !cpu_has_vmx_intel_pt())
pt_mode = PT_MODE_SYSTEM;
if (pt_mode == PT_MODE_HOST_GUEST)
- vmx_init_ops.handle_intel_pt_intr = vmx_handle_intel_pt_intr;
+ vt_init_ops.handle_intel_pt_intr = vmx_handle_intel_pt_intr;
else
- vmx_init_ops.handle_intel_pt_intr = NULL;
+ vt_init_ops.handle_intel_pt_intr = NULL;
setup_default_sgx_lepubkeyhash();
@@ -8713,14 +8570,6 @@ static __init int hardware_setup(void)
return r;
}
-static struct kvm_x86_init_ops vmx_init_ops __initdata = {
- .hardware_setup = hardware_setup,
- .handle_intel_pt_intr = NULL,
-
- .runtime_ops = &vmx_x86_ops,
- .pmu_ops = &intel_pmu_ops,
-};
-
static void vmx_cleanup_l1d_flush(void)
{
if (vmx_l1d_flush_pages) {
@@ -8743,9 +8592,9 @@ static void __vmx_exit(void)
static void vmx_exit(void)
{
kvm_exit();
+ __vmx_exit();
kvm_x86_vendor_exit();
- __vmx_exit();
}
module_exit(vmx_exit);
@@ -8762,7 +8611,7 @@ static int __init vmx_init(void)
*/
hv_init_evmcs();
- r = kvm_x86_vendor_init(&vmx_init_ops);
+ r = kvm_x86_vendor_init(&vt_init_ops);
if (r)
return r;
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 90f9e4434646..42498fa63abb 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -7,10 +7,10 @@
#include <asm/kvm.h>
#include <asm/intel_pt.h>
#include <asm/perf_event.h>
+#include <asm/posted_intr.h>
#include "capabilities.h"
#include "../kvm_cache_regs.h"
-#include "posted_intr.h"
#include "vmcs.h"
#include "vmx_ops.h"
#include "../cpuid.h"
@@ -365,6 +365,9 @@ struct vcpu_vmx {
DECLARE_BITMAP(read, MAX_POSSIBLE_PASSTHROUGH_MSRS);
DECLARE_BITMAP(write, MAX_POSSIBLE_PASSTHROUGH_MSRS);
} shadow_msr_intercept;
+
+ /* ve_info must be page aligned. */
+ struct vmx_ve_information *ve_info;
};
struct kvm_vmx {
@@ -403,6 +406,7 @@ u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level);
bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu);
void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu);
bool vmx_nmi_blocked(struct kvm_vcpu *vcpu);
+bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu);
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);
@@ -577,7 +581,8 @@ static inline u8 vmx_get_rvi(void)
SECONDARY_EXEC_ENABLE_VMFUNC | \
SECONDARY_EXEC_BUS_LOCK_DETECTION | \
SECONDARY_EXEC_NOTIFY_VM_EXITING | \
- SECONDARY_EXEC_ENCLS_EXITING)
+ SECONDARY_EXEC_ENCLS_EXITING | \
+ SECONDARY_EXEC_EPT_VIOLATION_VE)
#define KVM_REQUIRED_VMX_TERTIARY_VM_EXEC_CONTROL 0
#define KVM_OPTIONAL_VMX_TERTIARY_VM_EXEC_CONTROL \
@@ -723,7 +728,7 @@ static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
return true;
return allow_smaller_maxphyaddr &&
- cpuid_maxphyaddr(vcpu) < kvm_get_shadow_phys_bits();
+ cpuid_maxphyaddr(vcpu) < kvm_host.maxphyaddr;
}
static inline bool is_unrestricted_guest(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h
new file mode 100644
index 000000000000..ce3221cd1d01
--- /dev/null
+++ b/arch/x86/kvm/vmx/x86_ops.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __KVM_X86_VMX_X86_OPS_H
+#define __KVM_X86_VMX_X86_OPS_H
+
+#include <linux/kvm_host.h>
+
+#include "x86.h"
+
+__init int vmx_hardware_setup(void);
+
+extern struct kvm_x86_ops vt_x86_ops __initdata;
+extern struct kvm_x86_init_ops vt_init_ops __initdata;
+
+void vmx_hardware_unsetup(void);
+int vmx_check_processor_compat(void);
+int vmx_hardware_enable(void);
+void vmx_hardware_disable(void);
+int vmx_vm_init(struct kvm *kvm);
+void vmx_vm_destroy(struct kvm *kvm);
+int vmx_vcpu_precreate(struct kvm *kvm);
+int vmx_vcpu_create(struct kvm_vcpu *vcpu);
+int vmx_vcpu_pre_run(struct kvm_vcpu *vcpu);
+fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit);
+void vmx_vcpu_free(struct kvm_vcpu *vcpu);
+void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
+void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
+void vmx_vcpu_put(struct kvm_vcpu *vcpu);
+int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath);
+void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu);
+int vmx_skip_emulated_instruction(struct kvm_vcpu *vcpu);
+void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu);
+int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
+#ifdef CONFIG_KVM_SMM
+int vmx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection);
+int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram);
+int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram);
+void vmx_enable_smi_window(struct kvm_vcpu *vcpu);
+#endif
+int vmx_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type,
+ void *insn, int insn_len);
+int vmx_check_intercept(struct kvm_vcpu *vcpu,
+ struct x86_instruction_info *info,
+ enum x86_intercept_stage stage,
+ struct x86_exception *exception);
+bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu);
+void vmx_migrate_timers(struct kvm_vcpu *vcpu);
+void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
+void vmx_apicv_pre_state_restore(struct kvm_vcpu *vcpu);
+void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr);
+void vmx_hwapic_isr_update(int max_isr);
+int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu);
+void vmx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
+ int trig_mode, int vector);
+void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu);
+bool vmx_has_emulated_msr(struct kvm *kvm, u32 index);
+void vmx_msr_filter_changed(struct kvm_vcpu *vcpu);
+void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
+void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu);
+int vmx_get_msr_feature(struct kvm_msr_entry *msr);
+int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
+u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg);
+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);
+int vmx_get_cpl(struct kvm_vcpu *vcpu);
+void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l);
+bool vmx_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
+void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
+void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level);
+void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
+bool vmx_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
+int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer);
+void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
+void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
+void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
+void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
+void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val);
+void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu);
+void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg);
+unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
+void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
+bool vmx_get_if_flag(struct kvm_vcpu *vcpu);
+void vmx_flush_tlb_all(struct kvm_vcpu *vcpu);
+void vmx_flush_tlb_current(struct kvm_vcpu *vcpu);
+void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr);
+void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu);
+void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask);
+u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu);
+void vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall);
+void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinjected);
+void vmx_inject_nmi(struct kvm_vcpu *vcpu);
+void vmx_inject_exception(struct kvm_vcpu *vcpu);
+void vmx_cancel_injection(struct kvm_vcpu *vcpu);
+int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection);
+int vmx_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection);
+bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
+void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
+void vmx_enable_nmi_window(struct kvm_vcpu *vcpu);
+void vmx_enable_irq_window(struct kvm_vcpu *vcpu);
+void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr);
+void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu);
+void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu);
+void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
+int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
+int vmx_set_identity_map_addr(struct kvm *kvm, u64 ident_addr);
+u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
+void vmx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
+ u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code);
+u64 vmx_get_l2_tsc_offset(struct kvm_vcpu *vcpu);
+u64 vmx_get_l2_tsc_multiplier(struct kvm_vcpu *vcpu);
+void vmx_write_tsc_offset(struct kvm_vcpu *vcpu);
+void vmx_write_tsc_multiplier(struct kvm_vcpu *vcpu);
+void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu);
+#ifdef CONFIG_X86_64
+int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc,
+ bool *expired);
+void vmx_cancel_hv_timer(struct kvm_vcpu *vcpu);
+#endif
+void vmx_setup_mce(struct kvm_vcpu *vcpu);
+
+#endif /* __KVM_X86_VMX_X86_OPS_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 91478b769af0..af6c8cf6a37a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -92,11 +92,17 @@
#define MAX_IO_MSRS 256
#define KVM_MAX_MCE_BANKS 32
-struct kvm_caps kvm_caps __read_mostly = {
- .supported_mce_cap = MCG_CTL_P | MCG_SER_P,
-};
+/*
+ * Note, kvm_caps fields should *never* have default values, all fields must be
+ * recomputed from scratch during vendor module load, e.g. to account for a
+ * vendor module being reloaded with different module parameters.
+ */
+struct kvm_caps kvm_caps __read_mostly;
EXPORT_SYMBOL_GPL(kvm_caps);
+struct kvm_host_values kvm_host __read_mostly;
+EXPORT_SYMBOL_GPL(kvm_host);
+
#define ERR_PTR_USR(e) ((void __user *)ERR_PTR(e))
#define emul_to_vcpu(ctxt) \
@@ -161,15 +167,6 @@ module_param(kvmclock_periodic_sync, bool, 0444);
static u32 __read_mostly tsc_tolerance_ppm = 250;
module_param(tsc_tolerance_ppm, uint, 0644);
-/*
- * lapic timer advance (tscdeadline mode only) in nanoseconds. '-1' enables
- * adaptive tuning starting from default advancement of 1000ns. '0' disables
- * advancement entirely. Any other value is used as-is and disables adaptive
- * tuning, i.e. allows privileged userspace to set an exact advancement time.
- */
-static int __read_mostly lapic_timer_advance_ns = -1;
-module_param(lapic_timer_advance_ns, int, 0644);
-
static bool __read_mostly vector_hashing = true;
module_param(vector_hashing, bool, 0444);
@@ -226,21 +223,12 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
-u64 __read_mostly host_efer;
-EXPORT_SYMBOL_GPL(host_efer);
-
bool __read_mostly allow_smaller_maxphyaddr = 0;
EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr);
bool __read_mostly enable_apicv = true;
EXPORT_SYMBOL_GPL(enable_apicv);
-u64 __read_mostly host_xss;
-EXPORT_SYMBOL_GPL(host_xss);
-
-u64 __read_mostly host_arch_capabilities;
-EXPORT_SYMBOL_GPL(host_arch_capabilities);
-
const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
KVM_GENERIC_VM_STATS(),
STATS_DESC_COUNTER(VM, mmu_shadow_zapped),
@@ -314,8 +302,6 @@ const struct kvm_stats_header kvm_vcpu_stats_header = {
sizeof(kvm_vcpu_stats_desc),
};
-u64 __read_mostly host_xcr0;
-
static struct kmem_cache *x86_emulator_cache;
/*
@@ -839,7 +825,7 @@ EXPORT_SYMBOL_GPL(kvm_requeue_exception_e);
*/
bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
{
- if (static_call(kvm_x86_get_cpl)(vcpu) <= required_cpl)
+ if (kvm_x86_call(get_cpl)(vcpu) <= required_cpl)
return true;
kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
return false;
@@ -923,7 +909,7 @@ static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
return false;
- return static_call(kvm_x86_is_valid_cr0)(vcpu, cr0);
+ return kvm_x86_call(is_valid_cr0)(vcpu, cr0);
}
void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0)
@@ -960,11 +946,6 @@ void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned lon
if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS)
kvm_mmu_reset_context(vcpu);
-
- if (((cr0 ^ old_cr0) & X86_CR0_CD) &&
- kvm_mmu_honors_guest_mtrrs(vcpu->kvm) &&
- !kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
- kvm_zap_gfn_range(vcpu->kvm, 0, ~0ULL);
}
EXPORT_SYMBOL_GPL(kvm_post_set_cr0);
@@ -987,7 +968,7 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
if (!is_pae(vcpu))
return 1;
- static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
+ kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
if (cs_l)
return 1;
}
@@ -1001,7 +982,7 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
(is_64_bit_mode(vcpu) || kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)))
return 1;
- static_call(kvm_x86_set_cr0)(vcpu, cr0);
+ kvm_x86_call(set_cr0)(vcpu, cr0);
kvm_post_set_cr0(vcpu, old_cr0, cr0);
@@ -1022,11 +1003,11 @@ void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu)
if (kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) {
- if (vcpu->arch.xcr0 != host_xcr0)
+ if (vcpu->arch.xcr0 != kvm_host.xcr0)
xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0);
if (guest_can_use(vcpu, X86_FEATURE_XSAVES) &&
- vcpu->arch.ia32_xss != host_xss)
+ vcpu->arch.ia32_xss != kvm_host.xss)
wrmsrl(MSR_IA32_XSS, vcpu->arch.ia32_xss);
}
@@ -1053,12 +1034,12 @@ void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu)
if (kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) {
- if (vcpu->arch.xcr0 != host_xcr0)
- xsetbv(XCR_XFEATURE_ENABLED_MASK, host_xcr0);
+ if (vcpu->arch.xcr0 != kvm_host.xcr0)
+ xsetbv(XCR_XFEATURE_ENABLED_MASK, kvm_host.xcr0);
if (guest_can_use(vcpu, X86_FEATURE_XSAVES) &&
- vcpu->arch.ia32_xss != host_xss)
- wrmsrl(MSR_IA32_XSS, host_xss);
+ vcpu->arch.ia32_xss != kvm_host.xss)
+ wrmsrl(MSR_IA32_XSS, kvm_host.xss);
}
}
@@ -1119,7 +1100,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu)
{
/* Note, #UD due to CR4.OSXSAVE=0 has priority over the intercept. */
- if (static_call(kvm_x86_get_cpl)(vcpu) != 0 ||
+ if (kvm_x86_call(get_cpl)(vcpu) != 0 ||
__kvm_set_xcr(vcpu, kvm_rcx_read(vcpu), kvm_read_edx_eax(vcpu))) {
kvm_inject_gp(vcpu, 0);
return 1;
@@ -1144,7 +1125,7 @@ EXPORT_SYMBOL_GPL(__kvm_is_valid_cr4);
static bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
{
return __kvm_is_valid_cr4(vcpu, cr4) &&
- static_call(kvm_x86_is_valid_cr4)(vcpu, cr4);
+ kvm_x86_call(is_valid_cr4)(vcpu, cr4);
}
void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4)
@@ -1212,7 +1193,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
return 1;
}
- static_call(kvm_x86_set_cr4)(vcpu, cr4);
+ kvm_x86_call(set_cr4)(vcpu, cr4);
kvm_post_set_cr4(vcpu, old_cr4, cr4);
@@ -1351,7 +1332,7 @@ void kvm_update_dr7(struct kvm_vcpu *vcpu)
dr7 = vcpu->arch.guest_debug_dr7;
else
dr7 = vcpu->arch.dr7;
- static_call(kvm_x86_set_dr7)(vcpu, dr7);
+ kvm_x86_call(set_dr7)(vcpu, dr7);
vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_BP_ENABLED;
if (dr7 & DR7_BP_EN_MASK)
vcpu->arch.switch_db_regs |= KVM_DEBUGREG_BP_ENABLED;
@@ -1467,10 +1448,10 @@ static const u32 msrs_to_save_pmu[] = {
MSR_ARCH_PERFMON_FIXED_CTR0, MSR_ARCH_PERFMON_FIXED_CTR1,
MSR_ARCH_PERFMON_FIXED_CTR0 + 2,
MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS,
- MSR_CORE_PERF_GLOBAL_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
+ MSR_CORE_PERF_GLOBAL_CTRL,
MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
- /* This part of MSRs should match KVM_INTEL_PMC_MAX_GENERIC. */
+ /* This part of MSRs should match KVM_MAX_NR_INTEL_GP_COUNTERS. */
MSR_ARCH_PERFMON_PERFCTR0, MSR_ARCH_PERFMON_PERFCTR1,
MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3,
MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5,
@@ -1483,7 +1464,7 @@ static const u32 msrs_to_save_pmu[] = {
MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3,
MSR_K7_PERFCTR0, MSR_K7_PERFCTR1, MSR_K7_PERFCTR2, MSR_K7_PERFCTR3,
- /* This part of MSRs should match KVM_AMD_PMC_MAX_GENERIC. */
+ /* This part of MSRs should match KVM_MAX_NR_AMD_GP_COUNTERS. */
MSR_F15H_PERF_CTL0, MSR_F15H_PERF_CTL1, MSR_F15H_PERF_CTL2,
MSR_F15H_PERF_CTL3, MSR_F15H_PERF_CTL4, MSR_F15H_PERF_CTL5,
MSR_F15H_PERF_CTR0, MSR_F15H_PERF_CTR1, MSR_F15H_PERF_CTR2,
@@ -1625,7 +1606,7 @@ static bool kvm_is_immutable_feature_msr(u32 msr)
static u64 kvm_get_arch_capabilities(void)
{
- u64 data = host_arch_capabilities & KVM_SUPPORTED_ARCH_CAP;
+ u64 data = kvm_host.arch_capabilities & KVM_SUPPORTED_ARCH_CAP;
/*
* If nx_huge_pages is enabled, KVM's shadow paging will ensure that
@@ -1694,7 +1675,7 @@ static int kvm_get_msr_feature(struct kvm_msr_entry *msr)
rdmsrl_safe(msr->index, &msr->data);
break;
default:
- return static_call(kvm_x86_get_msr_feature)(msr);
+ return kvm_x86_call(get_msr_feature)(msr);
}
return 0;
}
@@ -1768,7 +1749,7 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
efer &= ~EFER_LMA;
efer |= vcpu->arch.efer & EFER_LMA;
- r = static_call(kvm_x86_set_efer)(vcpu, efer);
+ r = kvm_x86_call(set_efer)(vcpu, efer);
if (r) {
WARN_ON(r > 0);
return r;
@@ -1883,11 +1864,11 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data,
* incomplete and conflicting architectural behavior. Current
* AMD CPUs completely ignore bits 63:32, i.e. they aren't
* reserved and always read as zeros. Enforce Intel's reserved
- * bits check if and only if the guest CPU is Intel, and clear
- * the bits in all other cases. This ensures cross-vendor
- * migration will provide consistent behavior for the guest.
+ * bits check if the guest CPU is Intel compatible, otherwise
+ * clear the bits. This ensures cross-vendor migration will
+ * provide consistent behavior for the guest.
*/
- if (guest_cpuid_is_intel(vcpu) && (data >> 32) != 0)
+ if (guest_cpuid_is_intel_compatible(vcpu) && (data >> 32) != 0)
return 1;
data = (u32)data;
@@ -1898,7 +1879,7 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data,
msr.index = index;
msr.host_initiated = host_initiated;
- return static_call(kvm_x86_set_msr)(vcpu, &msr);
+ return kvm_x86_call(set_msr)(vcpu, &msr);
}
static int kvm_set_msr_ignored_check(struct kvm_vcpu *vcpu,
@@ -1940,7 +1921,7 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data,
msr.index = index;
msr.host_initiated = host_initiated;
- ret = static_call(kvm_x86_get_msr)(vcpu, &msr);
+ ret = kvm_x86_call(get_msr)(vcpu, &msr);
if (!ret)
*data = msr.data;
return ret;
@@ -2008,7 +1989,7 @@ static int complete_emulated_rdmsr(struct kvm_vcpu *vcpu)
static int complete_fast_msr_access(struct kvm_vcpu *vcpu)
{
- return static_call(kvm_x86_complete_emulated_msr)(vcpu, vcpu->run->msr.error);
+ return kvm_x86_call(complete_emulated_msr)(vcpu, vcpu->run->msr.error);
}
static int complete_fast_rdmsr(struct kvm_vcpu *vcpu)
@@ -2072,7 +2053,7 @@ int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu)
trace_kvm_msr_read_ex(ecx);
}
- return static_call(kvm_x86_complete_emulated_msr)(vcpu, r);
+ return kvm_x86_call(complete_emulated_msr)(vcpu, r);
}
EXPORT_SYMBOL_GPL(kvm_emulate_rdmsr);
@@ -2097,7 +2078,7 @@ int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu)
trace_kvm_msr_write_ex(ecx, data);
}
- return static_call(kvm_x86_complete_emulated_msr)(vcpu, r);
+ return kvm_x86_call(complete_emulated_msr)(vcpu, r);
}
EXPORT_SYMBOL_GPL(kvm_emulate_wrmsr);
@@ -2230,16 +2211,13 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
/*
* Disallow writes to immutable feature MSRs after KVM_RUN. KVM does
* not support modifying the guest vCPU model on the fly, e.g. changing
- * the nVMX capabilities while L2 is running is nonsensical. Ignore
+ * the nVMX capabilities while L2 is running is nonsensical. Allow
* writes of the same value, e.g. to allow userspace to blindly stuff
* all MSRs when emulating RESET.
*/
- if (kvm_vcpu_has_run(vcpu) && kvm_is_immutable_feature_msr(index)) {
- if (do_get_msr(vcpu, index, &val) || *data != val)
- return -EINVAL;
-
- return 0;
- }
+ if (kvm_vcpu_has_run(vcpu) && kvm_is_immutable_feature_msr(index) &&
+ (do_get_msr(vcpu, index, &val) || *data != val))
+ return -EINVAL;
return kvm_set_msr_ignored_check(vcpu, index, *data, true);
}
@@ -2625,12 +2603,12 @@ static void kvm_vcpu_write_tsc_offset(struct kvm_vcpu *vcpu, u64 l1_offset)
if (is_guest_mode(vcpu))
vcpu->arch.tsc_offset = kvm_calc_nested_tsc_offset(
l1_offset,
- static_call(kvm_x86_get_l2_tsc_offset)(vcpu),
- static_call(kvm_x86_get_l2_tsc_multiplier)(vcpu));
+ kvm_x86_call(get_l2_tsc_offset)(vcpu),
+ kvm_x86_call(get_l2_tsc_multiplier)(vcpu));
else
vcpu->arch.tsc_offset = l1_offset;
- static_call(kvm_x86_write_tsc_offset)(vcpu);
+ kvm_x86_call(write_tsc_offset)(vcpu);
}
static void kvm_vcpu_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 l1_multiplier)
@@ -2641,12 +2619,12 @@ static void kvm_vcpu_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 l1_multipli
if (is_guest_mode(vcpu))
vcpu->arch.tsc_scaling_ratio = kvm_calc_nested_tsc_multiplier(
l1_multiplier,
- static_call(kvm_x86_get_l2_tsc_multiplier)(vcpu));
+ kvm_x86_call(get_l2_tsc_multiplier)(vcpu));
else
vcpu->arch.tsc_scaling_ratio = l1_multiplier;
if (kvm_caps.has_tsc_control)
- static_call(kvm_x86_write_tsc_multiplier)(vcpu);
+ kvm_x86_call(write_tsc_multiplier)(vcpu);
}
static inline bool kvm_check_tsc_unstable(void)
@@ -3619,7 +3597,7 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu)
static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu)
{
++vcpu->stat.tlb_flush;
- static_call(kvm_x86_flush_tlb_all)(vcpu);
+ kvm_x86_call(flush_tlb_all)(vcpu);
/* Flushing all ASIDs flushes the current ASID... */
kvm_clear_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
@@ -3640,7 +3618,7 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
kvm_mmu_sync_prev_roots(vcpu);
}
- static_call(kvm_x86_flush_tlb_guest)(vcpu);
+ kvm_x86_call(flush_tlb_guest)(vcpu);
/*
* Flushing all "guest" TLB is always a superset of Hyper-V's fine
@@ -3653,7 +3631,7 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu)
{
++vcpu->stat.tlb_flush;
- static_call(kvm_x86_flush_tlb_current)(vcpu);
+ kvm_x86_call(flush_tlb_current)(vcpu);
}
/*
@@ -4629,9 +4607,7 @@ static int kvm_ioctl_get_supported_hv_cpuid(struct kvm_vcpu *vcpu,
static bool kvm_is_vm_type_supported(unsigned long type)
{
- return type == KVM_X86_DEFAULT_VM ||
- (type == KVM_X86_SW_PROTECTED_VM &&
- IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) && tdp_mmu_enabled);
+ return type < 32 && (kvm_caps.supported_vm_types & BIT(type));
}
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
@@ -4714,8 +4690,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES:
case KVM_CAP_IRQFD_RESAMPLE:
case KVM_CAP_MEMORY_FAULT_INFO:
+ case KVM_CAP_X86_GUEST_MODE:
r = 1;
break;
+ case KVM_CAP_PRE_FAULT_MEMORY:
+ r = tdp_enabled;
+ break;
+ case KVM_CAP_X86_APIC_BUS_CYCLES_NS:
+ r = APIC_BUS_CYCLE_NS_DEFAULT;
+ break;
case KVM_CAP_EXIT_HYPERCALL:
r = KVM_EXIT_HYPERCALL_VALID_MASK;
break;
@@ -4764,7 +4747,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
* fringe case that is not enabled except via specific settings
* of the module parameters.
*/
- r = static_call(kvm_x86_has_emulated_msr)(kvm, MSR_IA32_SMBASE);
+ r = kvm_x86_call(has_emulated_msr)(kvm, MSR_IA32_SMBASE);
break;
case KVM_CAP_NR_VCPUS:
r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
@@ -4832,9 +4815,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = kvm_caps.has_notify_vmexit;
break;
case KVM_CAP_VM_TYPES:
- r = BIT(KVM_X86_DEFAULT_VM);
- if (kvm_is_vm_type_supported(KVM_X86_SW_PROTECTED_VM))
- r |= BIT(KVM_X86_SW_PROTECTED_VM);
+ r = kvm_caps.supported_vm_types;
break;
default:
break;
@@ -4842,46 +4823,44 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
return r;
}
-static inline void __user *kvm_get_attr_addr(struct kvm_device_attr *attr)
-{
- void __user *uaddr = (void __user*)(unsigned long)attr->addr;
-
- if ((u64)(unsigned long)uaddr != attr->addr)
- return ERR_PTR_USR(-EFAULT);
- return uaddr;
-}
-
-static int kvm_x86_dev_get_attr(struct kvm_device_attr *attr)
+static int __kvm_x86_dev_get_attr(struct kvm_device_attr *attr, u64 *val)
{
- u64 __user *uaddr = kvm_get_attr_addr(attr);
-
- if (attr->group)
+ if (attr->group) {
+ if (kvm_x86_ops.dev_get_attr)
+ return kvm_x86_call(dev_get_attr)(attr->group, attr->attr, val);
return -ENXIO;
-
- if (IS_ERR(uaddr))
- return PTR_ERR(uaddr);
+ }
switch (attr->attr) {
case KVM_X86_XCOMP_GUEST_SUPP:
- if (put_user(kvm_caps.supported_xcr0, uaddr))
- return -EFAULT;
+ *val = kvm_caps.supported_xcr0;
return 0;
default:
return -ENXIO;
}
}
+static int kvm_x86_dev_get_attr(struct kvm_device_attr *attr)
+{
+ u64 __user *uaddr = u64_to_user_ptr(attr->addr);
+ int r;
+ u64 val;
+
+ r = __kvm_x86_dev_get_attr(attr, &val);
+ if (r < 0)
+ return r;
+
+ if (put_user(val, uaddr))
+ return -EFAULT;
+
+ return 0;
+}
+
static int kvm_x86_dev_has_attr(struct kvm_device_attr *attr)
{
- if (attr->group)
- return -ENXIO;
+ u64 val;
- switch (attr->attr) {
- case KVM_X86_XCOMP_GUEST_SUPP:
- return 0;
- default:
- return -ENXIO;
- }
+ return __kvm_x86_dev_get_attr(attr, &val);
}
long kvm_arch_dev_ioctl(struct file *filp,
@@ -5010,16 +4989,25 @@ static bool need_emulate_wbinvd(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
+ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
+ vcpu->arch.l1tf_flush_l1d = true;
+
+ if (vcpu->scheduled_out && pmu->version && pmu->event_count) {
+ pmu->need_cleanup = true;
+ kvm_make_request(KVM_REQ_PMU, vcpu);
+ }
+
/* Address WBINVD may be executed by guest */
if (need_emulate_wbinvd(vcpu)) {
- if (static_call(kvm_x86_has_wbinvd_exit)())
+ if (kvm_x86_call(has_wbinvd_exit)())
cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);
else if (vcpu->cpu != -1 && vcpu->cpu != cpu)
smp_call_function_single(vcpu->cpu,
wbinvd_ipi, NULL, 1);
}
- static_call(kvm_x86_vcpu_load)(vcpu, cpu);
+ kvm_x86_call(vcpu_load)(vcpu, cpu);
/* Save host pkru register if supported */
vcpu->arch.host_pkru = read_pkru();
@@ -5127,14 +5115,14 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
srcu_read_unlock(&vcpu->kvm->srcu, idx);
}
- static_call(kvm_x86_vcpu_put)(vcpu);
+ kvm_x86_call(vcpu_put)(vcpu);
vcpu->arch.last_host_tsc = rdtsc();
}
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s)
{
- static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
+ kvm_x86_call(sync_pir_to_irr)(vcpu);
return kvm_apic_get_state(vcpu, s);
}
@@ -5251,7 +5239,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
kvm_apic_after_set_mcg_cap(vcpu);
- static_call(kvm_x86_setup_mce)(vcpu);
+ kvm_x86_call(setup_mce)(vcpu);
out:
return r;
}
@@ -5411,11 +5399,11 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
events->interrupt.injected =
vcpu->arch.interrupt.injected && !vcpu->arch.interrupt.soft;
events->interrupt.nr = vcpu->arch.interrupt.nr;
- events->interrupt.shadow = static_call(kvm_x86_get_interrupt_shadow)(vcpu);
+ events->interrupt.shadow = kvm_x86_call(get_interrupt_shadow)(vcpu);
events->nmi.injected = vcpu->arch.nmi_injected;
events->nmi.pending = kvm_get_nr_pending_nmis(vcpu);
- events->nmi.masked = static_call(kvm_x86_get_nmi_mask)(vcpu);
+ events->nmi.masked = kvm_x86_call(get_nmi_mask)(vcpu);
/* events->sipi_vector is never valid when reporting to user space */
@@ -5497,8 +5485,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
vcpu->arch.interrupt.nr = events->interrupt.nr;
vcpu->arch.interrupt.soft = events->interrupt.soft;
if (events->flags & KVM_VCPUEVENT_VALID_SHADOW)
- static_call(kvm_x86_set_interrupt_shadow)(vcpu,
- events->interrupt.shadow);
+ kvm_x86_call(set_interrupt_shadow)(vcpu,
+ events->interrupt.shadow);
vcpu->arch.nmi_injected = events->nmi.injected;
if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) {
@@ -5507,7 +5495,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
if (events->nmi.pending)
kvm_make_request(KVM_REQ_NMI, vcpu);
}
- static_call(kvm_x86_set_nmi_mask)(vcpu, events->nmi.masked);
+ kvm_x86_call(set_nmi_mask)(vcpu, events->nmi.masked);
if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR &&
lapic_in_kernel(vcpu))
@@ -5557,11 +5545,15 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
return 0;
}
-static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
- struct kvm_debugregs *dbgregs)
+static int kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
+ struct kvm_debugregs *dbgregs)
{
unsigned int i;
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
memset(dbgregs, 0, sizeof(*dbgregs));
BUILD_BUG_ON(ARRAY_SIZE(vcpu->arch.db) != ARRAY_SIZE(dbgregs->db));
@@ -5570,6 +5562,7 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
dbgregs->dr6 = vcpu->arch.dr6;
dbgregs->dr7 = vcpu->arch.dr7;
+ return 0;
}
static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
@@ -5577,6 +5570,10 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
{
unsigned int i;
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
if (dbgregs->flags)
return -EINVAL;
@@ -5597,8 +5594,8 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
}
-static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu,
- u8 *state, unsigned int size)
+static int kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu,
+ u8 *state, unsigned int size)
{
/*
* Only copy state for features that are enabled for the guest. The
@@ -5616,24 +5613,25 @@ static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu,
XFEATURE_MASK_FPSSE;
if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
- return;
+ return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0;
fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, state, size,
supported_xcr0, vcpu->arch.pkru);
+ return 0;
}
-static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
- struct kvm_xsave *guest_xsave)
+static int kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
+ struct kvm_xsave *guest_xsave)
{
- kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region,
- sizeof(guest_xsave->region));
+ return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region,
+ sizeof(guest_xsave->region));
}
static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
struct kvm_xsave *guest_xsave)
{
if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
- return 0;
+ return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0;
return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu,
guest_xsave->region,
@@ -5641,18 +5639,23 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
&vcpu->arch.pkru);
}
-static void kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu,
- struct kvm_xcrs *guest_xcrs)
+static int kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu,
+ struct kvm_xcrs *guest_xcrs)
{
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
if (!boot_cpu_has(X86_FEATURE_XSAVE)) {
guest_xcrs->nr_xcrs = 0;
- return;
+ return 0;
}
guest_xcrs->nr_xcrs = 1;
guest_xcrs->flags = 0;
guest_xcrs->xcrs[0].xcr = XCR_XFEATURE_ENABLED_MASK;
guest_xcrs->xcrs[0].value = vcpu->arch.xcr0;
+ return 0;
}
static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
@@ -5660,6 +5663,10 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
{
int i, r = 0;
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
if (!boot_cpu_has(X86_FEATURE_XSAVE))
return -EINVAL;
@@ -5712,12 +5719,9 @@ static int kvm_arch_tsc_has_attr(struct kvm_vcpu *vcpu,
static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
- u64 __user *uaddr = kvm_get_attr_addr(attr);
+ u64 __user *uaddr = u64_to_user_ptr(attr->addr);
int r;
- if (IS_ERR(uaddr))
- return PTR_ERR(uaddr);
-
switch (attr->attr) {
case KVM_VCPU_TSC_OFFSET:
r = -EFAULT;
@@ -5735,13 +5739,10 @@ static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu,
static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
- u64 __user *uaddr = kvm_get_attr_addr(attr);
+ u64 __user *uaddr = u64_to_user_ptr(attr->addr);
struct kvm *kvm = vcpu->kvm;
int r;
- if (IS_ERR(uaddr))
- return PTR_ERR(uaddr);
-
switch (attr->attr) {
case KVM_VCPU_TSC_OFFSET: {
u64 offset, tsc, ns;
@@ -5842,7 +5843,7 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
if (!kvm_x86_ops.enable_l2_tlb_flush)
return -ENOTTY;
- return static_call(kvm_x86_enable_l2_tlb_flush)(vcpu);
+ return kvm_x86_call(enable_l2_tlb_flush)(vcpu);
case KVM_CAP_HYPERV_ENFORCE_CPUID:
return kvm_hv_set_enforce_cpuid(vcpu, cap->args[0]);
@@ -5881,8 +5882,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EINVAL;
if (!lapic_in_kernel(vcpu))
goto out;
- u.lapic = kzalloc(sizeof(struct kvm_lapic_state),
- GFP_KERNEL_ACCOUNT);
+ u.lapic = kzalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL);
r = -ENOMEM;
if (!u.lapic)
@@ -6048,7 +6048,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
case KVM_GET_DEBUGREGS: {
struct kvm_debugregs dbgregs;
- kvm_vcpu_ioctl_x86_get_debugregs(vcpu, &dbgregs);
+ r = kvm_vcpu_ioctl_x86_get_debugregs(vcpu, &dbgregs);
+ if (r < 0)
+ break;
r = -EFAULT;
if (copy_to_user(argp, &dbgregs,
@@ -6073,12 +6075,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (vcpu->arch.guest_fpu.uabi_size > sizeof(struct kvm_xsave))
break;
- u.xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL_ACCOUNT);
+ u.xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL);
r = -ENOMEM;
if (!u.xsave)
break;
- kvm_vcpu_ioctl_x86_get_xsave(vcpu, u.xsave);
+ r = kvm_vcpu_ioctl_x86_get_xsave(vcpu, u.xsave);
+ if (r < 0)
+ break;
r = -EFAULT;
if (copy_to_user(argp, u.xsave, sizeof(struct kvm_xsave)))
@@ -6102,12 +6106,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
case KVM_GET_XSAVE2: {
int size = vcpu->arch.guest_fpu.uabi_size;
- u.xsave = kzalloc(size, GFP_KERNEL_ACCOUNT);
+ u.xsave = kzalloc(size, GFP_KERNEL);
r = -ENOMEM;
if (!u.xsave)
break;
- kvm_vcpu_ioctl_x86_get_xsave2(vcpu, u.buffer, size);
+ r = kvm_vcpu_ioctl_x86_get_xsave2(vcpu, u.buffer, size);
+ if (r < 0)
+ break;
r = -EFAULT;
if (copy_to_user(argp, u.xsave, size))
@@ -6118,12 +6124,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
}
case KVM_GET_XCRS: {
- u.xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL_ACCOUNT);
+ u.xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL);
r = -ENOMEM;
if (!u.xcrs)
break;
- kvm_vcpu_ioctl_x86_get_xcrs(vcpu, u.xcrs);
+ r = kvm_vcpu_ioctl_x86_get_xcrs(vcpu, u.xcrs);
+ if (r < 0)
+ break;
r = -EFAULT;
if (copy_to_user(argp, u.xcrs,
@@ -6267,6 +6275,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
}
#endif
case KVM_GET_SREGS2: {
+ r = -EINVAL;
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ goto out;
+
u.sregs2 = kzalloc(sizeof(struct kvm_sregs2), GFP_KERNEL);
r = -ENOMEM;
if (!u.sregs2)
@@ -6279,6 +6292,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
break;
}
case KVM_SET_SREGS2: {
+ r = -EINVAL;
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ goto out;
+
u.sregs2 = memdup_user(argp, sizeof(struct kvm_sregs2));
if (IS_ERR(u.sregs2)) {
r = PTR_ERR(u.sregs2);
@@ -6314,14 +6332,14 @@ static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
if (addr > (unsigned int)(-3 * PAGE_SIZE))
return -EINVAL;
- ret = static_call(kvm_x86_set_tss_addr)(kvm, addr);
+ ret = kvm_x86_call(set_tss_addr)(kvm, addr);
return ret;
}
static int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm,
u64 ident_addr)
{
- return static_call(kvm_x86_set_identity_map_addr)(kvm, ident_addr);
+ return kvm_x86_call(set_identity_map_addr)(kvm, ident_addr);
}
static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
@@ -6527,9 +6545,6 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
goto split_irqchip_unlock;
if (kvm->created_vcpus)
goto split_irqchip_unlock;
- r = kvm_setup_empty_irq_routing(kvm);
- if (r)
- goto split_irqchip_unlock;
/* Pairs with irqchip_in_kernel. */
smp_wmb();
kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
@@ -6634,14 +6649,14 @@ split_irqchip_unlock:
if (!kvm_x86_ops.vm_copy_enc_context_from)
break;
- r = static_call(kvm_x86_vm_copy_enc_context_from)(kvm, cap->args[0]);
+ r = kvm_x86_call(vm_copy_enc_context_from)(kvm, cap->args[0]);
break;
case KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM:
r = -EINVAL;
if (!kvm_x86_ops.vm_move_enc_context_from)
break;
- r = static_call(kvm_x86_vm_move_enc_context_from)(kvm, cap->args[0]);
+ r = kvm_x86_call(vm_move_enc_context_from)(kvm, cap->args[0]);
break;
case KVM_CAP_EXIT_HYPERCALL:
if (cap->args[0] & ~KVM_EXIT_HYPERCALL_VALID_MASK) {
@@ -6676,7 +6691,9 @@ split_irqchip_unlock:
break;
mutex_lock(&kvm->lock);
- if (kvm->arch.max_vcpu_ids == cap->args[0]) {
+ if (kvm->arch.bsp_vcpu_id > cap->args[0]) {
+ ;
+ } else if (kvm->arch.max_vcpu_ids == cap->args[0]) {
r = 0;
} else if (!kvm->arch.max_vcpu_ids) {
kvm->arch.max_vcpu_ids = cap->args[0];
@@ -6729,6 +6746,30 @@ split_irqchip_unlock:
}
mutex_unlock(&kvm->lock);
break;
+ case KVM_CAP_X86_APIC_BUS_CYCLES_NS: {
+ u64 bus_cycle_ns = cap->args[0];
+ u64 unused;
+
+ /*
+ * Guard against overflow in tmict_to_ns(). 128 is the highest
+ * divide value that can be programmed in APIC_TDCR.
+ */
+ r = -EINVAL;
+ if (!bus_cycle_ns ||
+ check_mul_overflow((u64)U32_MAX * 128, bus_cycle_ns, &unused))
+ break;
+
+ r = 0;
+ mutex_lock(&kvm->lock);
+ if (!irqchip_in_kernel(kvm))
+ r = -ENXIO;
+ else if (kvm->created_vcpus)
+ r = -EINVAL;
+ else
+ kvm->arch.apic_bus_cycle_ns = bus_cycle_ns;
+ mutex_unlock(&kvm->lock);
+ break;
+ }
default:
r = -EINVAL;
break;
@@ -7197,6 +7238,9 @@ set_pit2_out:
mutex_lock(&kvm->lock);
if (kvm->created_vcpus)
r = -EBUSY;
+ else if (arg > KVM_MAX_VCPU_IDS ||
+ (kvm->arch.max_vcpu_ids && arg > kvm->arch.max_vcpu_ids))
+ r = -EINVAL;
else
kvm->arch.bsp_vcpu_id = arg;
mutex_unlock(&kvm->lock);
@@ -7273,7 +7317,7 @@ set_pit2_out:
if (!kvm_x86_ops.mem_enc_ioctl)
goto out;
- r = static_call(kvm_x86_mem_enc_ioctl)(kvm, argp);
+ r = kvm_x86_call(mem_enc_ioctl)(kvm, argp);
break;
}
case KVM_MEMORY_ENCRYPT_REG_REGION: {
@@ -7287,7 +7331,7 @@ set_pit2_out:
if (!kvm_x86_ops.mem_enc_register_region)
goto out;
- r = static_call(kvm_x86_mem_enc_register_region)(kvm, &region);
+ r = kvm_x86_call(mem_enc_register_region)(kvm, &region);
break;
}
case KVM_MEMORY_ENCRYPT_UNREG_REGION: {
@@ -7301,7 +7345,7 @@ set_pit2_out:
if (!kvm_x86_ops.mem_enc_unregister_region)
goto out;
- r = static_call(kvm_x86_mem_enc_unregister_region)(kvm, &region);
+ r = kvm_x86_call(mem_enc_unregister_region)(kvm, &region);
break;
}
#ifdef CONFIG_KVM_HYPERV
@@ -7395,17 +7439,20 @@ static void kvm_probe_msr_to_save(u32 msr_index)
intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2))
return;
break;
- case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR_MAX:
+ case MSR_ARCH_PERFMON_PERFCTR0 ...
+ MSR_ARCH_PERFMON_PERFCTR0 + KVM_MAX_NR_GP_COUNTERS - 1:
if (msr_index - MSR_ARCH_PERFMON_PERFCTR0 >=
kvm_pmu_cap.num_counters_gp)
return;
break;
- case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL_MAX:
+ case MSR_ARCH_PERFMON_EVENTSEL0 ...
+ MSR_ARCH_PERFMON_EVENTSEL0 + KVM_MAX_NR_GP_COUNTERS - 1:
if (msr_index - MSR_ARCH_PERFMON_EVENTSEL0 >=
kvm_pmu_cap.num_counters_gp)
return;
break;
- case MSR_ARCH_PERFMON_FIXED_CTR0 ... MSR_ARCH_PERFMON_FIXED_CTR_MAX:
+ case MSR_ARCH_PERFMON_FIXED_CTR0 ...
+ MSR_ARCH_PERFMON_FIXED_CTR0 + KVM_MAX_NR_FIXED_COUNTERS - 1:
if (msr_index - MSR_ARCH_PERFMON_FIXED_CTR0 >=
kvm_pmu_cap.num_counters_fixed)
return;
@@ -7436,7 +7483,7 @@ static void kvm_init_msr_lists(void)
{
unsigned i;
- BUILD_BUG_ON_MSG(KVM_PMC_MAX_FIXED != 3,
+ BUILD_BUG_ON_MSG(KVM_MAX_NR_FIXED_COUNTERS != 3,
"Please update the fixed PMCs in msrs_to_save_pmu[]");
num_msrs_to_save = 0;
@@ -7452,7 +7499,8 @@ static void kvm_init_msr_lists(void)
}
for (i = 0; i < ARRAY_SIZE(emulated_msrs_all); i++) {
- if (!static_call(kvm_x86_has_emulated_msr)(NULL, emulated_msrs_all[i]))
+ if (!kvm_x86_call(has_emulated_msr)(NULL,
+ emulated_msrs_all[i]))
continue;
emulated_msrs[num_emulated_msrs++] = emulated_msrs_all[i];
@@ -7511,13 +7559,13 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
void kvm_set_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg)
{
- static_call(kvm_x86_set_segment)(vcpu, var, seg);
+ kvm_x86_call(set_segment)(vcpu, var, seg);
}
void kvm_get_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg)
{
- static_call(kvm_x86_get_segment)(vcpu, var, seg);
+ kvm_x86_call(get_segment)(vcpu, var, seg);
}
gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access,
@@ -7540,7 +7588,7 @@ gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
{
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
- u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception);
}
EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_read);
@@ -7550,7 +7598,7 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
{
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
- u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
access |= PFERR_WRITE_MASK;
return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception);
}
@@ -7603,7 +7651,7 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt,
{
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
- u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
unsigned offset;
int ret;
@@ -7628,7 +7676,7 @@ int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
gva_t addr, void *val, unsigned int bytes,
struct x86_exception *exception)
{
- u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
/*
* FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED
@@ -7651,7 +7699,7 @@ static int emulator_read_std(struct x86_emulate_ctxt *ctxt,
if (system)
access |= PFERR_IMPLICIT_ACCESS;
- else if (static_call(kvm_x86_get_cpl)(vcpu) == 3)
+ else if (kvm_x86_call(get_cpl)(vcpu) == 3)
access |= PFERR_USER_MASK;
return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception);
@@ -7696,7 +7744,7 @@ static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *v
if (system)
access |= PFERR_IMPLICIT_ACCESS;
- else if (static_call(kvm_x86_get_cpl)(vcpu) == 3)
+ else if (kvm_x86_call(get_cpl)(vcpu) == 3)
access |= PFERR_USER_MASK;
return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
@@ -7717,8 +7765,8 @@ EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system);
static int kvm_check_emulate_insn(struct kvm_vcpu *vcpu, int emul_type,
void *insn, int insn_len)
{
- return static_call(kvm_x86_check_emulate_instruction)(vcpu, emul_type,
- insn, insn_len);
+ return kvm_x86_call(check_emulate_instruction)(vcpu, emul_type,
+ insn, insn_len);
}
int handle_ud(struct kvm_vcpu *vcpu)
@@ -7768,8 +7816,8 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
bool write)
{
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
- u64 access = ((static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0)
- | (write ? PFERR_WRITE_MASK : 0);
+ u64 access = ((kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0)
+ | (write ? PFERR_WRITE_MASK : 0);
/*
* currently PKRU is only applied to ept enabled guest so
@@ -8195,7 +8243,7 @@ static int emulator_pio_out_emulated(struct x86_emulate_ctxt *ctxt,
static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
{
- return static_call(kvm_x86_get_segment_base)(vcpu, seg);
+ return kvm_x86_call(get_segment_base)(vcpu, seg);
}
static void emulator_invlpg(struct x86_emulate_ctxt *ctxt, ulong address)
@@ -8208,7 +8256,7 @@ static int kvm_emulate_wbinvd_noskip(struct kvm_vcpu *vcpu)
if (!need_emulate_wbinvd(vcpu))
return X86EMUL_CONTINUE;
- if (static_call(kvm_x86_has_wbinvd_exit)()) {
+ if (kvm_x86_call(has_wbinvd_exit)()) {
int cpu = get_cpu();
cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);
@@ -8312,27 +8360,27 @@ static int emulator_set_cr(struct x86_emulate_ctxt *ctxt, int cr, ulong val)
static int emulator_get_cpl(struct x86_emulate_ctxt *ctxt)
{
- return static_call(kvm_x86_get_cpl)(emul_to_vcpu(ctxt));
+ return kvm_x86_call(get_cpl)(emul_to_vcpu(ctxt));
}
static void emulator_get_gdt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
{
- static_call(kvm_x86_get_gdt)(emul_to_vcpu(ctxt), dt);
+ kvm_x86_call(get_gdt)(emul_to_vcpu(ctxt), dt);
}
static void emulator_get_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
{
- static_call(kvm_x86_get_idt)(emul_to_vcpu(ctxt), dt);
+ kvm_x86_call(get_idt)(emul_to_vcpu(ctxt), dt);
}
static void emulator_set_gdt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
{
- static_call(kvm_x86_set_gdt)(emul_to_vcpu(ctxt), dt);
+ kvm_x86_call(set_gdt)(emul_to_vcpu(ctxt), dt);
}
static void emulator_set_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
{
- static_call(kvm_x86_set_idt)(emul_to_vcpu(ctxt), dt);
+ kvm_x86_call(set_idt)(emul_to_vcpu(ctxt), dt);
}
static unsigned long emulator_get_cached_segment_base(
@@ -8479,8 +8527,8 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
struct x86_instruction_info *info,
enum x86_intercept_stage stage)
{
- return static_call(kvm_x86_check_intercept)(emul_to_vcpu(ctxt), info, stage,
- &ctxt->exception);
+ return kvm_x86_call(check_intercept)(emul_to_vcpu(ctxt), info, stage,
+ &ctxt->exception);
}
static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
@@ -8505,6 +8553,11 @@ static bool emulator_guest_has_rdpid(struct x86_emulate_ctxt *ctxt)
return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID);
}
+static bool emulator_guest_cpuid_is_intel_compatible(struct x86_emulate_ctxt *ctxt)
+{
+ return guest_cpuid_is_intel_compatible(emul_to_vcpu(ctxt));
+}
+
static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
{
return kvm_register_read_raw(emul_to_vcpu(ctxt), reg);
@@ -8517,7 +8570,7 @@ static void emulator_write_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg, ulon
static void emulator_set_nmi_mask(struct x86_emulate_ctxt *ctxt, bool masked)
{
- static_call(kvm_x86_set_nmi_mask)(emul_to_vcpu(ctxt), masked);
+ kvm_x86_call(set_nmi_mask)(emul_to_vcpu(ctxt), masked);
}
static bool emulator_is_smm(struct x86_emulate_ctxt *ctxt)
@@ -8562,7 +8615,8 @@ static gva_t emulator_get_untagged_addr(struct x86_emulate_ctxt *ctxt,
if (!kvm_x86_ops.get_untagged_addr)
return addr;
- return static_call(kvm_x86_get_untagged_addr)(emul_to_vcpu(ctxt), addr, flags);
+ return kvm_x86_call(get_untagged_addr)(emul_to_vcpu(ctxt),
+ addr, flags);
}
static const struct x86_emulate_ops emulate_ops = {
@@ -8603,6 +8657,7 @@ static const struct x86_emulate_ops emulate_ops = {
.guest_has_movbe = emulator_guest_has_movbe,
.guest_has_fxsr = emulator_guest_has_fxsr,
.guest_has_rdpid = emulator_guest_has_rdpid,
+ .guest_cpuid_is_intel_compatible = emulator_guest_cpuid_is_intel_compatible,
.set_nmi_mask = emulator_set_nmi_mask,
.is_smm = emulator_is_smm,
.is_guest_mode = emulator_is_guest_mode,
@@ -8614,7 +8669,7 @@ static const struct x86_emulate_ops emulate_ops = {
static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
{
- u32 int_shadow = static_call(kvm_x86_get_interrupt_shadow)(vcpu);
+ u32 int_shadow = kvm_x86_call(get_interrupt_shadow)(vcpu);
/*
* an sti; sti; sequence only disable interrupts for the first
* instruction. So, if the last instruction, be it emulated or
@@ -8625,7 +8680,7 @@ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
if (int_shadow & mask)
mask = 0;
if (unlikely(int_shadow || mask)) {
- static_call(kvm_x86_set_interrupt_shadow)(vcpu, mask);
+ kvm_x86_call(set_interrupt_shadow)(vcpu, mask);
if (!mask)
kvm_make_request(KVM_REQ_EVENT, vcpu);
}
@@ -8666,7 +8721,7 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt;
int cs_db, cs_l;
- static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
+ kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
ctxt->gpa_available = false;
ctxt->eflags = kvm_get_rflags(vcpu);
@@ -8722,9 +8777,8 @@ static void prepare_emulation_failure_exit(struct kvm_vcpu *vcpu, u64 *data,
*/
memset(&info, 0, sizeof(info));
- static_call(kvm_x86_get_exit_info)(vcpu, (u32 *)&info[0], &info[1],
- &info[2], (u32 *)&info[3],
- (u32 *)&info[4]);
+ kvm_x86_call(get_exit_info)(vcpu, (u32 *)&info[0], &info[1], &info[2],
+ (u32 *)&info[3], (u32 *)&info[4]);
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
run->emulation_failure.suberror = KVM_INTERNAL_ERROR_EMULATION;
@@ -8801,7 +8855,7 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
kvm_queue_exception(vcpu, UD_VECTOR);
- if (!is_guest_mode(vcpu) && static_call(kvm_x86_get_cpl)(vcpu) == 0) {
+ if (!is_guest_mode(vcpu) && kvm_x86_call(get_cpl)(vcpu) == 0) {
prepare_emulation_ctxt_failure_exit(vcpu);
return 0;
}
@@ -8959,10 +9013,10 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu)
int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
{
- unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
+ unsigned long rflags = kvm_x86_call(get_rflags)(vcpu);
int r;
- r = static_call(kvm_x86_skip_emulated_instruction)(vcpu);
+ r = kvm_x86_call(skip_emulated_instruction)(vcpu);
if (unlikely(!r))
return 0;
@@ -8984,19 +9038,17 @@ EXPORT_SYMBOL_GPL(kvm_skip_emulated_instruction);
static bool kvm_is_code_breakpoint_inhibited(struct kvm_vcpu *vcpu)
{
- u32 shadow;
-
if (kvm_get_rflags(vcpu) & X86_EFLAGS_RF)
return true;
/*
- * Intel CPUs inhibit code #DBs when MOV/POP SS blocking is active,
- * but AMD CPUs do not. MOV/POP SS blocking is rare, check that first
- * to avoid the relatively expensive CPUID lookup.
+ * Intel compatible CPUs inhibit code #DBs when MOV/POP SS blocking is
+ * active, but AMD compatible CPUs do not.
*/
- shadow = static_call(kvm_x86_get_interrupt_shadow)(vcpu);
- return (shadow & KVM_X86_SHADOW_INT_MOV_SS) &&
- guest_cpuid_is_intel(vcpu);
+ if (!guest_cpuid_is_intel_compatible(vcpu))
+ return false;
+
+ return kvm_x86_call(get_interrupt_shadow)(vcpu) & KVM_X86_SHADOW_INT_MOV_SS;
}
static bool kvm_vcpu_check_code_breakpoint(struct kvm_vcpu *vcpu,
@@ -9268,7 +9320,7 @@ restart:
writeback:
if (writeback) {
- unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
+ unsigned long rflags = kvm_x86_call(get_rflags)(vcpu);
toggle_interruptibility(vcpu, ctxt->interruptibility);
vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
@@ -9285,7 +9337,7 @@ writeback:
kvm_rip_write(vcpu, ctxt->eip);
if (r && (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
r = kvm_vcpu_do_singlestep(vcpu);
- static_call_cond(kvm_x86_update_emulated_instruction)(vcpu);
+ kvm_x86_call(update_emulated_instruction)(vcpu);
__kvm_set_rflags(vcpu, ctxt->eflags);
}
@@ -9684,7 +9736,7 @@ static int kvm_x86_check_processor_compatibility(void)
__cr4_reserved_bits(cpu_has, &boot_cpu_data))
return -EIO;
- return static_call(kvm_x86_check_processor_compatibility)();
+ return kvm_x86_call(check_processor_compatibility)();
}
static void kvm_x86_check_cpu_compat(void *ret)
@@ -9732,6 +9784,8 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
return -EIO;
}
+ memset(&kvm_caps, 0, sizeof(kvm_caps));
+
x86_emulator_cache = kvm_alloc_emulator_cache();
if (!x86_emulator_cache) {
pr_err("failed to allocate cache for x86 emulator\n");
@@ -9750,20 +9804,23 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
if (r)
goto out_free_percpu;
+ kvm_caps.supported_vm_types = BIT(KVM_X86_DEFAULT_VM);
+ kvm_caps.supported_mce_cap = MCG_CTL_P | MCG_SER_P;
+
if (boot_cpu_has(X86_FEATURE_XSAVE)) {
- host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
- kvm_caps.supported_xcr0 = host_xcr0 & KVM_SUPPORTED_XCR0;
+ kvm_host.xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
+ kvm_caps.supported_xcr0 = kvm_host.xcr0 & KVM_SUPPORTED_XCR0;
}
- rdmsrl_safe(MSR_EFER, &host_efer);
+ rdmsrl_safe(MSR_EFER, &kvm_host.efer);
if (boot_cpu_has(X86_FEATURE_XSAVES))
- rdmsrl(MSR_IA32_XSS, host_xss);
+ rdmsrl(MSR_IA32_XSS, kvm_host.xss);
kvm_init_pmu_capability(ops->pmu_ops);
if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
- rdmsrl(MSR_IA32_ARCH_CAPABILITIES, host_arch_capabilities);
+ rdmsrl(MSR_IA32_ARCH_CAPABILITIES, kvm_host.arch_capabilities);
r = ops->hardware_setup();
if (r != 0)
@@ -9795,6 +9852,9 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
kvm_register_perf_callbacks(ops->handle_intel_pt_intr);
+ if (IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) && tdp_mmu_enabled)
+ kvm_caps.supported_vm_types |= BIT(KVM_X86_SW_PROTECTED_VM);
+
if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
kvm_caps.supported_xss = 0;
@@ -9819,7 +9879,7 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
out_unwind_ops:
kvm_x86_ops.hardware_enable = NULL;
- static_call(kvm_x86_hardware_unsetup)();
+ kvm_x86_call(hardware_unsetup)();
out_mmu_exit:
kvm_mmu_vendor_module_exit();
out_free_percpu:
@@ -9850,7 +9910,7 @@ void kvm_x86_vendor_exit(void)
irq_work_sync(&pvclock_irq_work);
cancel_work_sync(&pvclock_gtod_work);
#endif
- static_call(kvm_x86_hardware_unsetup)();
+ kvm_x86_call(hardware_unsetup)();
kvm_mmu_vendor_module_exit();
free_percpu(user_return_msrs);
kmem_cache_destroy(x86_emulator_cache);
@@ -9976,7 +10036,8 @@ EXPORT_SYMBOL_GPL(kvm_apicv_activated);
bool kvm_vcpu_apicv_activated(struct kvm_vcpu *vcpu)
{
ulong vm_reasons = READ_ONCE(vcpu->kvm->arch.apicv_inhibit_reasons);
- ulong vcpu_reasons = static_call(kvm_x86_vcpu_get_apicv_inhibit_reasons)(vcpu);
+ ulong vcpu_reasons =
+ kvm_x86_call(vcpu_get_apicv_inhibit_reasons)(vcpu);
return (vm_reasons | vcpu_reasons) == 0;
}
@@ -9985,6 +10046,10 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_apicv_activated);
static void set_or_clear_apicv_inhibit(unsigned long *inhibits,
enum kvm_apicv_inhibit reason, bool set)
{
+ const struct trace_print_flags apicv_inhibits[] = { APICV_INHIBIT_REASONS };
+
+ BUILD_BUG_ON(ARRAY_SIZE(apicv_inhibits) != NR_APICV_INHIBIT_REASONS);
+
if (set)
__set_bit(reason, inhibits);
else
@@ -9995,15 +10060,12 @@ static void set_or_clear_apicv_inhibit(unsigned long *inhibits,
static void kvm_apicv_init(struct kvm *kvm)
{
- unsigned long *inhibits = &kvm->arch.apicv_inhibit_reasons;
-
- init_rwsem(&kvm->arch.apicv_update_lock);
+ enum kvm_apicv_inhibit reason = enable_apicv ? APICV_INHIBIT_REASON_ABSENT :
+ APICV_INHIBIT_REASON_DISABLED;
- set_or_clear_apicv_inhibit(inhibits, APICV_INHIBIT_REASON_ABSENT, true);
+ set_or_clear_apicv_inhibit(&kvm->arch.apicv_inhibit_reasons, reason, true);
- if (!enable_apicv)
- set_or_clear_apicv_inhibit(inhibits,
- APICV_INHIBIT_REASON_DISABLE, true);
+ init_rwsem(&kvm->arch.apicv_update_lock);
}
static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id)
@@ -10051,26 +10113,15 @@ static int complete_hypercall_exit(struct kvm_vcpu *vcpu)
return kvm_skip_emulated_instruction(vcpu);
}
-int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
+unsigned long __kvm_emulate_hypercall(struct kvm_vcpu *vcpu, unsigned long nr,
+ unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ int op_64_bit, int cpl)
{
- unsigned long nr, a0, a1, a2, a3, ret;
- int op_64_bit;
-
- if (kvm_xen_hypercall_enabled(vcpu->kvm))
- return kvm_xen_hypercall(vcpu);
-
- if (kvm_hv_hypercall_enabled(vcpu))
- return kvm_hv_hypercall(vcpu);
-
- nr = kvm_rax_read(vcpu);
- a0 = kvm_rbx_read(vcpu);
- a1 = kvm_rcx_read(vcpu);
- a2 = kvm_rdx_read(vcpu);
- a3 = kvm_rsi_read(vcpu);
+ unsigned long ret;
trace_kvm_hypercall(nr, a0, a1, a2, a3);
- op_64_bit = is_64_bit_hypercall(vcpu);
if (!op_64_bit) {
nr &= 0xFFFFFFFF;
a0 &= 0xFFFFFFFF;
@@ -10079,7 +10130,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
a3 &= 0xFFFFFFFF;
}
- if (static_call(kvm_x86_get_cpl)(vcpu) != 0) {
+ if (cpl) {
ret = -KVM_EPERM;
goto out;
}
@@ -10140,18 +10191,49 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
WARN_ON_ONCE(vcpu->run->hypercall.flags & KVM_EXIT_HYPERCALL_MBZ);
vcpu->arch.complete_userspace_io = complete_hypercall_exit;
+ /* stat is incremented on completion. */
return 0;
}
default:
ret = -KVM_ENOSYS;
break;
}
+
out:
+ ++vcpu->stat.hypercalls;
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__kvm_emulate_hypercall);
+
+int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
+{
+ unsigned long nr, a0, a1, a2, a3, ret;
+ int op_64_bit;
+ int cpl;
+
+ if (kvm_xen_hypercall_enabled(vcpu->kvm))
+ return kvm_xen_hypercall(vcpu);
+
+ if (kvm_hv_hypercall_enabled(vcpu))
+ return kvm_hv_hypercall(vcpu);
+
+ nr = kvm_rax_read(vcpu);
+ a0 = kvm_rbx_read(vcpu);
+ a1 = kvm_rcx_read(vcpu);
+ a2 = kvm_rdx_read(vcpu);
+ a3 = kvm_rsi_read(vcpu);
+ op_64_bit = is_64_bit_hypercall(vcpu);
+ cpl = kvm_x86_call(get_cpl)(vcpu);
+
+ ret = __kvm_emulate_hypercall(vcpu, nr, a0, a1, a2, a3, op_64_bit, cpl);
+ if (nr == KVM_HC_MAP_GPA_RANGE && !ret)
+ /* MAP_GPA tosses the request to the user space. */
+ return 0;
+
if (!op_64_bit)
ret = (u32)ret;
kvm_rax_write(vcpu, ret);
- ++vcpu->stat.hypercalls;
return kvm_skip_emulated_instruction(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
@@ -10173,7 +10255,7 @@ static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
return X86EMUL_PROPAGATE_FAULT;
}
- static_call(kvm_x86_patch_hypercall)(vcpu, instruction);
+ kvm_x86_call(patch_hypercall)(vcpu, instruction);
return emulator_write_emulated(ctxt, rip, instruction, 3,
&ctxt->exception);
@@ -10190,7 +10272,7 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
{
struct kvm_run *kvm_run = vcpu->run;
- kvm_run->if_flag = static_call(kvm_x86_get_if_flag)(vcpu);
+ kvm_run->if_flag = kvm_x86_call(get_if_flag)(vcpu);
kvm_run->cr8 = kvm_get_cr8(vcpu);
kvm_run->apic_base = kvm_get_apic_base(vcpu);
@@ -10200,6 +10282,8 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
if (is_smm(vcpu))
kvm_run->flags |= KVM_RUN_X86_SMM;
+ if (is_guest_mode(vcpu))
+ kvm_run->flags |= KVM_RUN_X86_GUEST_MODE;
}
static void update_cr8_intercept(struct kvm_vcpu *vcpu)
@@ -10225,7 +10309,7 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
tpr = kvm_lapic_get_cr8(vcpu);
- static_call(kvm_x86_update_cr8_intercept)(vcpu, tpr, max_irr);
+ kvm_x86_call(update_cr8_intercept)(vcpu, tpr, max_irr);
}
@@ -10255,7 +10339,7 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
vcpu->arch.exception.error_code,
vcpu->arch.exception.injected);
- static_call(kvm_x86_inject_exception)(vcpu);
+ kvm_x86_call(inject_exception)(vcpu);
}
/*
@@ -10341,9 +10425,9 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
else if (kvm_is_exception_pending(vcpu))
; /* see above */
else if (vcpu->arch.nmi_injected)
- static_call(kvm_x86_inject_nmi)(vcpu);
+ kvm_x86_call(inject_nmi)(vcpu);
else if (vcpu->arch.interrupt.injected)
- static_call(kvm_x86_inject_irq)(vcpu, true);
+ kvm_x86_call(inject_irq)(vcpu, true);
/*
* Exceptions that morph to VM-Exits are handled above, and pending
@@ -10428,7 +10512,8 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
*/
#ifdef CONFIG_KVM_SMM
if (vcpu->arch.smi_pending) {
- r = can_inject ? static_call(kvm_x86_smi_allowed)(vcpu, true) : -EBUSY;
+ r = can_inject ? kvm_x86_call(smi_allowed)(vcpu, true) :
+ -EBUSY;
if (r < 0)
goto out;
if (r) {
@@ -10437,27 +10522,29 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
enter_smm(vcpu);
can_inject = false;
} else
- static_call(kvm_x86_enable_smi_window)(vcpu);
+ kvm_x86_call(enable_smi_window)(vcpu);
}
#endif
if (vcpu->arch.nmi_pending) {
- r = can_inject ? static_call(kvm_x86_nmi_allowed)(vcpu, true) : -EBUSY;
+ r = can_inject ? kvm_x86_call(nmi_allowed)(vcpu, true) :
+ -EBUSY;
if (r < 0)
goto out;
if (r) {
--vcpu->arch.nmi_pending;
vcpu->arch.nmi_injected = true;
- static_call(kvm_x86_inject_nmi)(vcpu);
+ kvm_x86_call(inject_nmi)(vcpu);
can_inject = false;
- WARN_ON(static_call(kvm_x86_nmi_allowed)(vcpu, true) < 0);
+ WARN_ON(kvm_x86_call(nmi_allowed)(vcpu, true) < 0);
}
if (vcpu->arch.nmi_pending)
- static_call(kvm_x86_enable_nmi_window)(vcpu);
+ kvm_x86_call(enable_nmi_window)(vcpu);
}
if (kvm_cpu_has_injectable_intr(vcpu)) {
- r = can_inject ? static_call(kvm_x86_interrupt_allowed)(vcpu, true) : -EBUSY;
+ r = can_inject ? kvm_x86_call(interrupt_allowed)(vcpu, true) :
+ -EBUSY;
if (r < 0)
goto out;
if (r) {
@@ -10465,17 +10552,17 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
if (!WARN_ON_ONCE(irq == -1)) {
kvm_queue_interrupt(vcpu, irq, false);
- static_call(kvm_x86_inject_irq)(vcpu, false);
- WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0);
+ kvm_x86_call(inject_irq)(vcpu, false);
+ WARN_ON(kvm_x86_call(interrupt_allowed)(vcpu, true) < 0);
}
}
if (kvm_cpu_has_injectable_intr(vcpu))
- static_call(kvm_x86_enable_irq_window)(vcpu);
+ kvm_x86_call(enable_irq_window)(vcpu);
}
if (is_guest_mode(vcpu) &&
kvm_x86_ops.nested_ops->has_events &&
- kvm_x86_ops.nested_ops->has_events(vcpu))
+ kvm_x86_ops.nested_ops->has_events(vcpu, true))
*req_immediate_exit = true;
/*
@@ -10516,7 +10603,7 @@ static void process_nmi(struct kvm_vcpu *vcpu)
* blocks NMIs). KVM will immediately inject one of the two NMIs, and
* will request an NMI window to handle the second NMI.
*/
- if (static_call(kvm_x86_get_nmi_mask)(vcpu) || vcpu->arch.nmi_injected)
+ if (kvm_x86_call(get_nmi_mask)(vcpu) || vcpu->arch.nmi_injected)
limit = 1;
else
limit = 2;
@@ -10525,14 +10612,14 @@ static void process_nmi(struct kvm_vcpu *vcpu)
* Adjust the limit to account for pending virtual NMIs, which aren't
* tracked in vcpu->arch.nmi_pending.
*/
- if (static_call(kvm_x86_is_vnmi_pending)(vcpu))
+ if (kvm_x86_call(is_vnmi_pending)(vcpu))
limit--;
vcpu->arch.nmi_pending += atomic_xchg(&vcpu->arch.nmi_queued, 0);
vcpu->arch.nmi_pending = min(vcpu->arch.nmi_pending, limit);
if (vcpu->arch.nmi_pending &&
- (static_call(kvm_x86_set_vnmi_pending)(vcpu)))
+ (kvm_x86_call(set_vnmi_pending)(vcpu)))
vcpu->arch.nmi_pending--;
if (vcpu->arch.nmi_pending)
@@ -10543,7 +10630,7 @@ static void process_nmi(struct kvm_vcpu *vcpu)
int kvm_get_nr_pending_nmis(struct kvm_vcpu *vcpu)
{
return vcpu->arch.nmi_pending +
- static_call(kvm_x86_is_vnmi_pending)(vcpu);
+ kvm_x86_call(is_vnmi_pending)(vcpu);
}
void kvm_make_scan_ioapic_request_mask(struct kvm *kvm,
@@ -10577,7 +10664,7 @@ void __kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
apic->apicv_active = activate;
kvm_apic_update_apicv(vcpu);
- static_call(kvm_x86_refresh_apicv_exec_ctrl)(vcpu);
+ kvm_x86_call(refresh_apicv_exec_ctrl)(vcpu);
/*
* When APICv gets disabled, we may still have injected interrupts
@@ -10677,13 +10764,12 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
+ kvm_x86_call(sync_pir_to_irr)(vcpu);
+
if (irqchip_split(vcpu->kvm))
kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
- else {
- static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
- if (ioapic_in_kernel(vcpu->kvm))
- kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
- }
+ else if (ioapic_in_kernel(vcpu->kvm))
+ kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
if (is_guest_mode(vcpu))
vcpu->arch.load_eoi_exitmap_pending = true;
@@ -10703,17 +10789,17 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
bitmap_or((ulong *)eoi_exit_bitmap,
vcpu->arch.ioapic_handled_vectors,
to_hv_synic(vcpu)->vec_bitmap, 256);
- static_call_cond(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
+ kvm_x86_call(load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
return;
}
#endif
- static_call_cond(kvm_x86_load_eoi_exitmap)(
+ kvm_x86_call(load_eoi_exitmap)(
vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
}
void kvm_arch_guest_memory_reclaimed(struct kvm *kvm)
{
- static_call_cond(kvm_x86_guest_memory_reclaimed)(kvm);
+ kvm_x86_call(guest_memory_reclaimed)(kvm);
}
static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
@@ -10721,7 +10807,7 @@ static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
if (!lapic_in_kernel(vcpu))
return;
- static_call_cond(kvm_x86_set_apic_access_page_addr)(vcpu);
+ kvm_x86_call(set_apic_access_page_addr)(vcpu);
}
/*
@@ -10885,10 +10971,18 @@ static int vcpu_enter_guest(struct kvm_vcpu *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))
- static_call(kvm_x86_msr_filter_changed)(vcpu);
+ kvm_x86_call(msr_filter_changed)(vcpu);
if (kvm_check_request(KVM_REQ_UPDATE_CPU_DIRTY_LOGGING, vcpu))
- static_call(kvm_x86_update_cpu_dirty_logging)(vcpu);
+ kvm_x86_call(update_cpu_dirty_logging)(vcpu);
+
+ if (kvm_check_request(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, vcpu)) {
+ kvm_vcpu_reset(vcpu, true);
+ if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) {
+ r = 1;
+ goto out;
+ }
+ }
}
if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win ||
@@ -10910,7 +11004,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
goto out;
}
if (req_int_win)
- static_call(kvm_x86_enable_irq_window)(vcpu);
+ kvm_x86_call(enable_irq_window)(vcpu);
if (kvm_lapic_enabled(vcpu)) {
update_cr8_intercept(vcpu);
@@ -10925,7 +11019,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
preempt_disable();
- static_call(kvm_x86_prepare_switch_to_guest)(vcpu);
+ kvm_x86_call(prepare_switch_to_guest)(vcpu);
/*
* Disable IRQs before setting IN_GUEST_MODE. Posted interrupt
@@ -10961,7 +11055,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
* i.e. they can post interrupts even if APICv is temporarily disabled.
*/
if (kvm_lapic_enabled(vcpu))
- static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
+ kvm_x86_call(sync_pir_to_irr)(vcpu);
if (kvm_vcpu_exit_request(vcpu)) {
vcpu->mode = OUTSIDE_GUEST_MODE;
@@ -11005,12 +11099,13 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
WARN_ON_ONCE((kvm_vcpu_apicv_activated(vcpu) != kvm_vcpu_apicv_active(vcpu)) &&
(kvm_get_apic_mode(vcpu) != LAPIC_MODE_DISABLED));
- exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu, req_immediate_exit);
+ exit_fastpath = kvm_x86_call(vcpu_run)(vcpu,
+ req_immediate_exit);
if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST))
break;
if (kvm_lapic_enabled(vcpu))
- static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
+ kvm_x86_call(sync_pir_to_irr)(vcpu);
if (unlikely(kvm_vcpu_exit_request(vcpu))) {
exit_fastpath = EXIT_FASTPATH_EXIT_HANDLED;
@@ -11029,7 +11124,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
*/
if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) {
WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP);
- static_call(kvm_x86_sync_dirty_debug_regs)(vcpu);
+ kvm_x86_call(sync_dirty_debug_regs)(vcpu);
kvm_update_dr0123(vcpu);
kvm_update_dr7(vcpu);
}
@@ -11058,7 +11153,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (vcpu->arch.xfd_no_write_intercept)
fpu_sync_guest_vmexit_xfd_state();
- static_call(kvm_x86_handle_exit_irqoff)(vcpu);
+ kvm_x86_call(handle_exit_irqoff)(vcpu);
if (vcpu->arch.guest_fpu.xfd_err)
wrmsrl(MSR_IA32_XFD_ERR, 0);
@@ -11091,6 +11186,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_vcpu_srcu_read_lock(vcpu);
/*
+ * Call this to ensure WC buffers in guest are evicted after each VM
+ * Exit, so that the evicted WC writes can be snooped across all cpus
+ */
+ smp_mb__after_srcu_read_lock();
+
+ /*
* Profile KVM exit RIPs:
*/
if (unlikely(prof_on == KVM_PROFILING)) {
@@ -11104,13 +11205,13 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (vcpu->arch.apic_attention)
kvm_lapic_sync_from_vapic(vcpu);
- r = static_call(kvm_x86_handle_exit)(vcpu, exit_fastpath);
+ r = kvm_x86_call(handle_exit)(vcpu, exit_fastpath);
return r;
cancel_injection:
if (req_immediate_exit)
kvm_make_request(KVM_REQ_EVENT, vcpu);
- static_call(kvm_x86_cancel_injection)(vcpu);
+ kvm_x86_call(cancel_injection)(vcpu);
if (unlikely(vcpu->arch.apic_attention))
kvm_lapic_sync_from_vapic(vcpu);
out:
@@ -11160,7 +11261,10 @@ static inline int vcpu_block(struct kvm_vcpu *vcpu)
* causes a spurious wakeup from HLT).
*/
if (is_guest_mode(vcpu)) {
- if (kvm_check_nested_events(vcpu) < 0)
+ int r = kvm_check_nested_events(vcpu);
+
+ WARN_ON_ONCE(r == -EBUSY);
+ if (r < 0)
return 0;
}
@@ -11197,7 +11301,6 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
int r;
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
- vcpu->arch.l1tf_flush_l1d = true;
for (;;) {
/*
@@ -11347,7 +11450,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_vcpu_srcu_read_lock(vcpu);
if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
- if (kvm_run->immediate_exit) {
+ if (!vcpu->wants_to_run) {
r = -EINTR;
goto out;
}
@@ -11425,12 +11528,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
WARN_ON_ONCE(vcpu->mmio_needed);
}
- if (kvm_run->immediate_exit) {
+ if (!vcpu->wants_to_run) {
r = -EINTR;
goto out;
}
- r = static_call(kvm_x86_vcpu_pre_run)(vcpu);
+ r = kvm_x86_call(vcpu_pre_run)(vcpu);
if (r <= 0)
goto out;
@@ -11486,6 +11589,10 @@ static void __get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
{
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
vcpu_load(vcpu);
__get_regs(vcpu, regs);
vcpu_put(vcpu);
@@ -11527,6 +11634,10 @@ static void __set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
{
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
vcpu_load(vcpu);
__set_regs(vcpu, regs);
vcpu_put(vcpu);
@@ -11550,10 +11661,10 @@ static void __get_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
kvm_get_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
- static_call(kvm_x86_get_idt)(vcpu, &dt);
+ kvm_x86_call(get_idt)(vcpu, &dt);
sregs->idt.limit = dt.size;
sregs->idt.base = dt.address;
- static_call(kvm_x86_get_gdt)(vcpu, &dt);
+ kvm_x86_call(get_gdt)(vcpu, &dt);
sregs->gdt.limit = dt.size;
sregs->gdt.base = dt.address;
@@ -11599,6 +11710,10 @@ static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2)
int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
struct kvm_sregs *sregs)
{
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
vcpu_load(vcpu);
__get_sregs(vcpu, sregs);
vcpu_put(vcpu);
@@ -11691,7 +11806,13 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
ret = emulator_task_switch(ctxt, tss_selector, idt_index, reason,
has_error_code, error_code);
- if (ret) {
+
+ /*
+ * Report an error userspace if MMIO is needed, as KVM doesn't support
+ * MMIO during a task switch (or any other complex operation).
+ */
+ if (ret || vcpu->mmio_needed) {
+ vcpu->mmio_needed = false;
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
vcpu->run->internal.ndata = 0;
@@ -11749,27 +11870,27 @@ static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
dt.size = sregs->idt.limit;
dt.address = sregs->idt.base;
- static_call(kvm_x86_set_idt)(vcpu, &dt);
+ kvm_x86_call(set_idt)(vcpu, &dt);
dt.size = sregs->gdt.limit;
dt.address = sregs->gdt.base;
- static_call(kvm_x86_set_gdt)(vcpu, &dt);
+ kvm_x86_call(set_gdt)(vcpu, &dt);
vcpu->arch.cr2 = sregs->cr2;
*mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3;
vcpu->arch.cr3 = sregs->cr3;
kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
- static_call_cond(kvm_x86_post_set_cr3)(vcpu, sregs->cr3);
+ kvm_x86_call(post_set_cr3)(vcpu, sregs->cr3);
kvm_set_cr8(vcpu, sregs->cr8);
*mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
- static_call(kvm_x86_set_efer)(vcpu, sregs->efer);
+ kvm_x86_call(set_efer)(vcpu, sregs->efer);
*mmu_reset_needed |= kvm_read_cr0(vcpu) != sregs->cr0;
- static_call(kvm_x86_set_cr0)(vcpu, sregs->cr0);
+ kvm_x86_call(set_cr0)(vcpu, sregs->cr0);
*mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
- static_call(kvm_x86_set_cr4)(vcpu, sregs->cr4);
+ kvm_x86_call(set_cr4)(vcpu, sregs->cr4);
if (update_pdptrs) {
idx = srcu_read_lock(&vcpu->kvm->srcu);
@@ -11866,6 +11987,10 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
{
int ret;
+ if (vcpu->kvm->arch.has_protected_state &&
+ vcpu->arch.guest_state_protected)
+ return -EINVAL;
+
vcpu_load(vcpu);
ret = __set_sregs(vcpu, sregs);
vcpu_put(vcpu);
@@ -11943,7 +12068,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
*/
kvm_set_rflags(vcpu, rflags);
- static_call(kvm_x86_update_exception_bitmap)(vcpu);
+ kvm_x86_call(update_exception_bitmap)(vcpu);
kvm_arch_vcpu_guestdbg_update_apicv_inhibit(vcpu->kvm);
@@ -11983,7 +12108,7 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
struct fxregs_state *fxsave;
if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
- return 0;
+ return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0;
vcpu_load(vcpu);
@@ -12006,7 +12131,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
struct fxregs_state *fxsave;
if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
- return 0;
+ return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0;
vcpu_load(vcpu);
@@ -12080,7 +12205,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
if (id >= kvm->arch.max_vcpu_ids)
return -EINVAL;
- return static_call(kvm_x86_vcpu_precreate)(kvm);
+ return kvm_x86_call(vcpu_precreate)(kvm);
}
int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
@@ -12103,7 +12228,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
if (r < 0)
return r;
- r = kvm_create_lapic(vcpu, lapic_timer_advance_ns);
+ r = kvm_create_lapic(vcpu);
if (r < 0)
goto fail_mmu_destroy;
@@ -12151,14 +12276,13 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
vcpu->arch.hv_root_tdp = INVALID_PAGE;
#endif
- r = static_call(kvm_x86_vcpu_create)(vcpu);
+ r = kvm_x86_call(vcpu_create)(vcpu);
if (r)
goto free_guest_fpu;
vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
kvm_xen_init_vcpu(vcpu);
- kvm_vcpu_mtrr_init(vcpu);
vcpu_load(vcpu);
kvm_set_tsc_khz(vcpu, vcpu->kvm->arch.default_tsc_khz);
kvm_vcpu_reset(vcpu, false);
@@ -12209,7 +12333,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
kvmclock_reset(vcpu);
- static_call(kvm_x86_vcpu_free)(vcpu);
+ kvm_x86_call(vcpu_free)(vcpu);
kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt);
free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
@@ -12327,7 +12451,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
cpuid_0x1 = kvm_find_cpuid_entry(vcpu, 1);
kvm_rdx_write(vcpu, cpuid_0x1 ? cpuid_0x1->eax : 0x600);
- static_call(kvm_x86_vcpu_reset)(vcpu, init_event);
+ kvm_x86_call(vcpu_reset)(vcpu, init_event);
kvm_set_rflags(vcpu, X86_EFLAGS_FIXED);
kvm_rip_write(vcpu, 0xfff0);
@@ -12346,10 +12470,10 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
else
new_cr0 |= X86_CR0_NW | X86_CR0_CD;
- static_call(kvm_x86_set_cr0)(vcpu, new_cr0);
- static_call(kvm_x86_set_cr4)(vcpu, 0);
- static_call(kvm_x86_set_efer)(vcpu, 0);
- static_call(kvm_x86_update_exception_bitmap)(vcpu);
+ kvm_x86_call(set_cr0)(vcpu, new_cr0);
+ kvm_x86_call(set_cr4)(vcpu, 0);
+ kvm_x86_call(set_efer)(vcpu, 0);
+ kvm_x86_call(update_exception_bitmap)(vcpu);
/*
* On the standard CR0/CR4/EFER modification paths, there are several
@@ -12406,7 +12530,7 @@ int kvm_arch_hardware_enable(void)
if (ret)
return ret;
- ret = static_call(kvm_x86_hardware_enable)();
+ ret = kvm_x86_call(hardware_enable)();
if (ret != 0)
return ret;
@@ -12488,7 +12612,7 @@ int kvm_arch_hardware_enable(void)
void kvm_arch_hardware_disable(void)
{
- static_call(kvm_x86_hardware_disable)();
+ kvm_x86_call(hardware_disable)();
drop_user_return_notifiers();
}
@@ -12502,18 +12626,6 @@ bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu)
return (vcpu->arch.apic_base & MSR_IA32_APICBASE_BSP) != 0;
}
-void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
-{
- struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
-
- vcpu->arch.l1tf_flush_l1d = true;
- if (pmu->version && unlikely(pmu->event_count)) {
- pmu->need_cleanup = true;
- kvm_make_request(KVM_REQ_PMU, vcpu);
- }
- static_call(kvm_x86_sched_in)(vcpu, cpu);
-}
-
void kvm_arch_free_vm(struct kvm *kvm)
{
#if IS_ENABLED(CONFIG_HYPERV)
@@ -12532,6 +12644,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
return -EINVAL;
kvm->arch.vm_type = type;
+ kvm->arch.has_private_mem =
+ (type == KVM_X86_SW_PROTECTED_VM);
ret = kvm_page_track_init(kvm);
if (ret)
@@ -12539,7 +12653,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm_mmu_init_vm(kvm);
- ret = static_call(kvm_x86_vm_init)(kvm);
+ ret = kvm_x86_call(vm_init)(kvm);
if (ret)
goto out_uninit_mmu;
@@ -12562,6 +12676,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
kvm->arch.default_tsc_khz = max_tsc_khz ? : tsc_khz;
+ kvm->arch.apic_bus_cycle_ns = APIC_BUS_CYCLE_NS_DEFAULT;
kvm->arch.guest_can_read_msr_platform_info = true;
kvm->arch.enable_pmu = enable_pmu;
@@ -12713,7 +12828,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
mutex_unlock(&kvm->slots_lock);
}
kvm_unload_vcpu_mmus(kvm);
- static_call_cond(kvm_x86_vm_destroy)(kvm);
+ kvm_x86_call(vm_destroy)(kvm);
kvm_free_msr_filter(srcu_dereference_check(kvm->arch.msr_filter, &kvm->srcu, 1));
kvm_pic_destroy(kvm);
kvm_ioapic_destroy(kvm);
@@ -12731,7 +12846,7 @@ static void memslot_rmap_free(struct kvm_memory_slot *slot)
int i;
for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
- kvfree(slot->arch.rmap[i]);
+ vfree(slot->arch.rmap[i]);
slot->arch.rmap[i] = NULL;
}
}
@@ -12743,7 +12858,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot)
memslot_rmap_free(slot);
for (i = 1; i < KVM_NR_PAGE_SIZES; ++i) {
- kvfree(slot->arch.lpage_info[i - 1]);
+ vfree(slot->arch.lpage_info[i - 1]);
slot->arch.lpage_info[i - 1] = NULL;
}
@@ -12835,7 +12950,7 @@ out_free:
memslot_rmap_free(slot);
for (i = 1; i < KVM_NR_PAGE_SIZES; ++i) {
- kvfree(slot->arch.lpage_info[i - 1]);
+ vfree(slot->arch.lpage_info[i - 1]);
slot->arch.lpage_info[i - 1] = NULL;
}
return -ENOMEM;
@@ -13042,12 +13157,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
kvm_arch_free_memslot(kvm, old);
}
-static inline bool kvm_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
-{
- return (is_guest_mode(vcpu) &&
- static_call(kvm_x86_guest_apic_has_interrupt)(vcpu));
-}
-
static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
{
if (!list_empty_careful(&vcpu->async_pf.done))
@@ -13065,22 +13174,23 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
if (kvm_test_request(KVM_REQ_NMI, vcpu) ||
(vcpu->arch.nmi_pending &&
- static_call(kvm_x86_nmi_allowed)(vcpu, false)))
+ kvm_x86_call(nmi_allowed)(vcpu, false)))
return true;
#ifdef CONFIG_KVM_SMM
if (kvm_test_request(KVM_REQ_SMI, vcpu) ||
(vcpu->arch.smi_pending &&
- static_call(kvm_x86_smi_allowed)(vcpu, false)))
+ kvm_x86_call(smi_allowed)(vcpu, false)))
return true;
#endif
if (kvm_test_request(KVM_REQ_PMI, vcpu))
return true;
- if (kvm_arch_interrupt_allowed(vcpu) &&
- (kvm_cpu_has_interrupt(vcpu) ||
- kvm_guest_apic_has_interrupt(vcpu)))
+ if (kvm_test_request(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, vcpu))
+ return true;
+
+ if (kvm_arch_interrupt_allowed(vcpu) && kvm_cpu_has_interrupt(vcpu))
return true;
if (kvm_hv_has_stimer_pending(vcpu))
@@ -13088,7 +13198,7 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
if (is_guest_mode(vcpu) &&
kvm_x86_ops.nested_ops->has_events &&
- kvm_x86_ops.nested_ops->has_events(vcpu))
+ kvm_x86_ops.nested_ops->has_events(vcpu, false))
return true;
if (kvm_xen_has_pending_events(vcpu))
@@ -13105,7 +13215,7 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
bool kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu *vcpu)
{
return kvm_vcpu_apicv_active(vcpu) &&
- static_call(kvm_x86_dy_apicv_has_pending_interrupt)(vcpu);
+ kvm_x86_call(dy_apicv_has_pending_interrupt)(vcpu);
}
bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu)
@@ -13133,7 +13243,7 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
if (vcpu->arch.guest_state_protected)
return true;
- return static_call(kvm_x86_get_cpl)(vcpu) == 0;
+ return kvm_x86_call(get_cpl)(vcpu) == 0;
}
unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
@@ -13148,7 +13258,7 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
{
- return static_call(kvm_x86_interrupt_allowed)(vcpu, false);
+ return kvm_x86_call(interrupt_allowed)(vcpu, false);
}
unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu)
@@ -13174,7 +13284,7 @@ unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu)
{
unsigned long rflags;
- rflags = static_call(kvm_x86_get_rflags)(vcpu);
+ rflags = kvm_x86_call(get_rflags)(vcpu);
if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
rflags &= ~X86_EFLAGS_TF;
return rflags;
@@ -13186,7 +13296,7 @@ static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP &&
kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip))
rflags |= X86_EFLAGS_TF;
- static_call(kvm_x86_set_rflags)(vcpu, rflags);
+ kvm_x86_call(set_rflags)(vcpu, rflags);
}
void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
@@ -13298,7 +13408,7 @@ static bool kvm_can_deliver_async_pf(struct kvm_vcpu *vcpu)
return false;
if (vcpu->arch.apf.send_user_only &&
- static_call(kvm_x86_get_cpl)(vcpu) == 0)
+ kvm_x86_call(get_cpl)(vcpu) == 0)
return false;
if (is_guest_mode(vcpu)) {
@@ -13409,7 +13519,7 @@ bool kvm_arch_can_dequeue_async_page_present(struct kvm_vcpu *vcpu)
void kvm_arch_start_assignment(struct kvm *kvm)
{
if (atomic_inc_return(&kvm->arch.assigned_device_count) == 1)
- static_call_cond(kvm_x86_pi_start_assignment)(kvm);
+ kvm_x86_call(pi_start_assignment)(kvm);
}
EXPORT_SYMBOL_GPL(kvm_arch_start_assignment);
@@ -13428,13 +13538,13 @@ EXPORT_SYMBOL_GPL(kvm_arch_has_assigned_device);
static void kvm_noncoherent_dma_assignment_start_or_stop(struct kvm *kvm)
{
/*
- * Non-coherent DMA assignment and de-assignment will affect
- * whether KVM honors guest MTRRs and cause changes in memtypes
- * in TDP.
- * So, pass %true unconditionally to indicate non-coherent DMA was,
- * or will be involved, and that zapping SPTEs might be necessary.
+ * Non-coherent DMA assignment and de-assignment may affect whether or
+ * not KVM honors guest PAT, and thus may cause changes in EPT SPTEs
+ * due to toggling the "ignore PAT" bit. Zap all SPTEs when the first
+ * (or last) non-coherent device is (un)registered to so that new SPTEs
+ * with the correct "ignore guest PAT" setting are created.
*/
- if (__kvm_mmu_honors_guest_mtrrs(true))
+ if (kvm_mmu_may_ignore_guest_pat())
kvm_zap_gfn_range(kvm, gpa_to_gfn(0), gpa_to_gfn(~0ULL));
}
@@ -13472,9 +13582,8 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
irqfd->producer = prod;
kvm_arch_start_assignment(irqfd->kvm);
- ret = static_call(kvm_x86_pi_update_irte)(irqfd->kvm,
- prod->irq, irqfd->gsi, 1);
-
+ ret = kvm_x86_call(pi_update_irte)(irqfd->kvm,
+ prod->irq, irqfd->gsi, 1);
if (ret)
kvm_arch_end_assignment(irqfd->kvm);
@@ -13497,7 +13606,8 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
* when the irq is masked/disabled or the consumer side (KVM
* int this case doesn't want to receive the interrupts.
*/
- ret = static_call(kvm_x86_pi_update_irte)(irqfd->kvm, prod->irq, irqfd->gsi, 0);
+ ret = kvm_x86_call(pi_update_irte)(irqfd->kvm,
+ prod->irq, irqfd->gsi, 0);
if (ret)
printk(KERN_INFO "irq bypass consumer (token %p) unregistration"
" fails: %d\n", irqfd->consumer.token, ret);
@@ -13508,7 +13618,7 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
uint32_t guest_irq, bool set)
{
- return static_call(kvm_x86_pi_update_irte)(kvm, host_irq, guest_irq, set);
+ return kvm_x86_call(pi_update_irte)(kvm, host_irq, guest_irq, set);
}
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
@@ -13531,6 +13641,24 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_arch_no_poll);
+#ifdef CONFIG_HAVE_KVM_GMEM_PREPARE
+bool kvm_arch_gmem_prepare_needed(struct kvm *kvm)
+{
+ return kvm->arch.vm_type == KVM_X86_SNP_VM;
+}
+
+int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_order)
+{
+ return kvm_x86_call(gmem_prepare)(kvm, pfn, gfn, max_order);
+}
+#endif
+
+#ifdef CONFIG_HAVE_KVM_GMEM_INVALIDATE
+void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
+{
+ kvm_x86_call(gmem_invalidate)(start, end);
+}
+#endif
int kvm_spec_ctrl_test_value(u64 value)
{
@@ -13916,6 +14044,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_enter);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_enter);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_rmp_fault);
static int __init kvm_x86_init(void)
{
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index a8b71803777b..50596f6f8320 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -24,6 +24,8 @@ struct kvm_caps {
bool has_bus_lock_exit;
/* notify VM exit supported? */
bool has_notify_vmexit;
+ /* bit mask of VM types */
+ u32 supported_vm_types;
u64 supported_mce_cap;
u64 supported_xcr0;
@@ -31,6 +33,20 @@ struct kvm_caps {
u64 supported_perf_cap;
};
+struct kvm_host_values {
+ /*
+ * The host's raw MAXPHYADDR, i.e. the number of non-reserved physical
+ * address bits irrespective of features that repurpose legal bits,
+ * e.g. MKTME.
+ */
+ u8 maxphyaddr;
+
+ u64 efer;
+ u64 xcr0;
+ u64 xss;
+ u64 arch_capabilities;
+};
+
void kvm_spurious_fault(void);
#define KVM_NESTED_VMENTER_CONSISTENCY_CHECK(consistency_check) \
@@ -157,7 +173,7 @@ static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
if (!is_long_mode(vcpu))
return false;
- static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
+ kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
return cs_l;
}
@@ -309,12 +325,8 @@ int handle_ud(struct kvm_vcpu *vcpu);
void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu,
struct kvm_queued_exception *ex);
-void kvm_vcpu_mtrr_init(struct kvm_vcpu *vcpu);
-u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn);
int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
-bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
- int page_num);
bool kvm_vector_hashing_enabled(void);
void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_code);
int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
@@ -323,11 +335,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
int emulation_type, void *insn, int insn_len);
fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu);
-extern u64 host_xcr0;
-extern u64 host_xss;
-extern u64 host_arch_capabilities;
-
extern struct kvm_caps kvm_caps;
+extern struct kvm_host_values kvm_host;
extern bool enable_pmu;
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index f65b35a05d91..622fe24da910 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -741,7 +741,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
} else {
void __user * hva = u64_to_user_ptr(data->u.shared_info.hva);
- if (!PAGE_ALIGNED(hva) || !access_ok(hva, PAGE_SIZE)) {
+ if (!PAGE_ALIGNED(hva)) {
r = -EINVAL;
} else if (!hva) {
kvm_gpc_deactivate(&kvm->arch.xen.shinfo_cache);
@@ -1270,7 +1270,7 @@ int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
instructions[0] = 0xb8;
/* vmcall / vmmcall */
- static_call(kvm_x86_patch_hypercall)(vcpu, instructions + 5);
+ kvm_x86_call(patch_hypercall)(vcpu, instructions + 5);
/* ret */
instructions[8] = 0xc3;
@@ -1650,7 +1650,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
params[5] = (u64)kvm_r9_read(vcpu);
}
#endif
- cpl = static_call(kvm_x86_get_cpl)(vcpu);
+ cpl = kvm_x86_call(get_cpl)(vcpu);
trace_kvm_xen_hypercall(cpl, input, params[0], params[1], params[2],
params[3], params[4], params[5]);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 6da73513f026..98583a9dbab3 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -53,7 +53,6 @@ ifneq ($(CONFIG_X86_CMPXCHG64),y)
lib-y += atomic64_386_32.o
endif
else
- obj-y += iomap_copy_64.o
ifneq ($(CONFIG_GENERIC_CSUM),y)
lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
endif
diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c
index 80570eb3c89b..384da1fdd5c6 100644
--- a/arch/x86/lib/cmdline.c
+++ b/arch/x86/lib/cmdline.c
@@ -6,8 +6,10 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ctype.h>
+
#include <asm/setup.h>
#include <asm/cmdline.h>
+#include <asm/bug.h>
static inline int myisspace(u8 c)
{
@@ -205,12 +207,18 @@ __cmdline_find_option(const char *cmdline, int max_cmdline_size,
int cmdline_find_option_bool(const char *cmdline, const char *option)
{
+ if (IS_ENABLED(CONFIG_CMDLINE_BOOL))
+ WARN_ON_ONCE(!builtin_cmdline_added);
+
return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option);
}
int cmdline_find_option(const char *cmdline, const char *option, char *buffer,
int bufsize)
{
+ if (IS_ENABLED(CONFIG_CMDLINE_BOOL))
+ WARN_ON_ONCE(!builtin_cmdline_added);
+
return __cmdline_find_option(cmdline, COMMAND_LINE_SIZE, option,
buffer, bufsize);
}
diff --git a/arch/x86/lib/copy_mc.c b/arch/x86/lib/copy_mc.c
index 6e8b7e600def..97e88e58567b 100644
--- a/arch/x86/lib/copy_mc.c
+++ b/arch/x86/lib/copy_mc.c
@@ -4,6 +4,7 @@
#include <linux/jump_label.h>
#include <linux/uaccess.h>
#include <linux/export.h>
+#include <linux/instrumented.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -61,10 +62,20 @@ unsigned long copy_mc_enhanced_fast_string(void *dst, const void *src, unsigned
*/
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);
+ unsigned long ret;
+
+ if (copy_mc_fragile_enabled) {
+ instrument_memcpy_before(dst, src, len);
+ ret = copy_mc_fragile(dst, src, len);
+ instrument_memcpy_after(dst, src, len, ret);
+ return ret;
+ }
+ if (static_cpu_has(X86_FEATURE_ERMS)) {
+ instrument_memcpy_before(dst, src, len);
+ ret = copy_mc_enhanced_fast_string(dst, src, len);
+ instrument_memcpy_after(dst, src, len, ret);
+ return ret;
+ }
memcpy(dst, src, len);
return 0;
}
@@ -75,6 +86,7 @@ unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, un
unsigned long ret;
if (copy_mc_fragile_enabled) {
+ instrument_copy_to_user(dst, src, len);
__uaccess_begin();
ret = copy_mc_fragile((__force void *)dst, src, len);
__uaccess_end();
@@ -82,6 +94,7 @@ unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, un
}
if (static_cpu_has(X86_FEATURE_ERMS)) {
+ instrument_copy_to_user(dst, src, len);
__uaccess_begin();
ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len);
__uaccess_end();
diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S
index 10d5ed8b5990..a314622aa093 100644
--- a/arch/x86/lib/getuser.S
+++ b/arch/x86/lib/getuser.S
@@ -50,11 +50,17 @@
.endif
.endm
+.macro UACCESS op src dst
+1: \op \src,\dst
+ _ASM_EXTABLE_UA(1b, __get_user_handle_exception)
+.endm
+
+
.text
SYM_FUNC_START(__get_user_1)
check_range size=1
ASM_STAC
-1: movzbl (%_ASM_AX),%edx
+ UACCESS movzbl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
RET
@@ -64,7 +70,7 @@ EXPORT_SYMBOL(__get_user_1)
SYM_FUNC_START(__get_user_2)
check_range size=2
ASM_STAC
-2: movzwl (%_ASM_AX),%edx
+ UACCESS movzwl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
RET
@@ -74,7 +80,7 @@ EXPORT_SYMBOL(__get_user_2)
SYM_FUNC_START(__get_user_4)
check_range size=4
ASM_STAC
-3: movl (%_ASM_AX),%edx
+ UACCESS movl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
RET
@@ -85,10 +91,11 @@ SYM_FUNC_START(__get_user_8)
check_range size=8
ASM_STAC
#ifdef CONFIG_X86_64
-4: movq (%_ASM_AX),%rdx
+ UACCESS movq (%_ASM_AX),%rdx
#else
-4: movl (%_ASM_AX),%edx
-5: movl 4(%_ASM_AX),%ecx
+ xor %ecx,%ecx
+ UACCESS movl (%_ASM_AX),%edx
+ UACCESS movl 4(%_ASM_AX),%ecx
#endif
xor %eax,%eax
ASM_CLAC
@@ -100,7 +107,7 @@ EXPORT_SYMBOL(__get_user_8)
SYM_FUNC_START(__get_user_nocheck_1)
ASM_STAC
ASM_BARRIER_NOSPEC
-6: movzbl (%_ASM_AX),%edx
+ UACCESS movzbl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
RET
@@ -110,7 +117,7 @@ EXPORT_SYMBOL(__get_user_nocheck_1)
SYM_FUNC_START(__get_user_nocheck_2)
ASM_STAC
ASM_BARRIER_NOSPEC
-7: movzwl (%_ASM_AX),%edx
+ UACCESS movzwl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
RET
@@ -120,7 +127,7 @@ EXPORT_SYMBOL(__get_user_nocheck_2)
SYM_FUNC_START(__get_user_nocheck_4)
ASM_STAC
ASM_BARRIER_NOSPEC
-8: movl (%_ASM_AX),%edx
+ UACCESS movl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
RET
@@ -131,10 +138,11 @@ SYM_FUNC_START(__get_user_nocheck_8)
ASM_STAC
ASM_BARRIER_NOSPEC
#ifdef CONFIG_X86_64
-9: movq (%_ASM_AX),%rdx
+ UACCESS movq (%_ASM_AX),%rdx
#else
-9: movl (%_ASM_AX),%edx
-10: movl 4(%_ASM_AX),%ecx
+ xor %ecx,%ecx
+ UACCESS movl (%_ASM_AX),%edx
+ UACCESS movl 4(%_ASM_AX),%ecx
#endif
xor %eax,%eax
ASM_CLAC
@@ -150,36 +158,3 @@ SYM_CODE_START_LOCAL(__get_user_handle_exception)
mov $(-EFAULT),%_ASM_AX
RET
SYM_CODE_END(__get_user_handle_exception)
-
-#ifdef CONFIG_X86_32
-SYM_CODE_START_LOCAL(__get_user_8_handle_exception)
- ASM_CLAC
-bad_get_user_8:
- xor %edx,%edx
- xor %ecx,%ecx
- mov $(-EFAULT),%_ASM_AX
- RET
-SYM_CODE_END(__get_user_8_handle_exception)
-#endif
-
-/* get_user */
- _ASM_EXTABLE_UA(1b, __get_user_handle_exception)
- _ASM_EXTABLE_UA(2b, __get_user_handle_exception)
- _ASM_EXTABLE_UA(3b, __get_user_handle_exception)
-#ifdef CONFIG_X86_64
- _ASM_EXTABLE_UA(4b, __get_user_handle_exception)
-#else
- _ASM_EXTABLE_UA(4b, __get_user_8_handle_exception)
- _ASM_EXTABLE_UA(5b, __get_user_8_handle_exception)
-#endif
-
-/* __get_user */
- _ASM_EXTABLE_UA(6b, __get_user_handle_exception)
- _ASM_EXTABLE_UA(7b, __get_user_handle_exception)
- _ASM_EXTABLE_UA(8b, __get_user_handle_exception)
-#ifdef CONFIG_X86_64
- _ASM_EXTABLE_UA(9b, __get_user_handle_exception)
-#else
- _ASM_EXTABLE_UA(9b, __get_user_8_handle_exception)
- _ASM_EXTABLE_UA(10b, __get_user_8_handle_exception)
-#endif
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 1bb155a0955b..5952ab41c60f 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -185,6 +185,17 @@ found:
if (X86_REX_W(b))
/* REX.W overrides opnd_size */
insn->opnd_bytes = 8;
+ } else if (inat_is_rex2_prefix(attr)) {
+ insn_set_byte(&insn->rex_prefix, 0, b);
+ b = peek_nbyte_next(insn_byte_t, insn, 1);
+ insn_set_byte(&insn->rex_prefix, 1, b);
+ insn->rex_prefix.nbytes = 2;
+ insn->next_byte += 2;
+ if (X86_REX_W(b))
+ /* REX.W overrides opnd_size */
+ insn->opnd_bytes = 8;
+ insn->rex_prefix.got = 1;
+ goto vex_end;
}
}
insn->rex_prefix.got = 1;
@@ -283,6 +294,10 @@ int insn_get_opcode(struct insn *insn)
m = insn_vex_m_bits(insn);
p = insn_vex_p_bits(insn);
insn->attr = inat_get_avx_attribute(op, m, p);
+ /* SCALABLE EVEX uses p bits to encode operand size */
+ if (inat_evex_scalable(insn->attr) && !insn_vex_w_bit(insn) &&
+ p == INAT_PFX_OPNDSZ)
+ insn->opnd_bytes = 2;
if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
(!inat_accept_vex(insn->attr) &&
!inat_is_group(insn->attr))) {
@@ -294,6 +309,20 @@ int insn_get_opcode(struct insn *insn)
goto end;
}
+ /* Check if there is REX2 prefix or not */
+ if (insn_is_rex2(insn)) {
+ if (insn_rex2_m_bit(insn)) {
+ /* map 1 is escape 0x0f */
+ insn_attr_t esc_attr = inat_get_opcode_attribute(0x0f);
+
+ pfx_id = insn_last_prefix_id(insn);
+ insn->attr = inat_get_escape_attribute(op, pfx_id, esc_attr);
+ } else {
+ insn->attr = inat_get_opcode_attribute(op);
+ }
+ goto end;
+ }
+
insn->attr = inat_get_opcode_attribute(op);
while (inat_is_escape(insn->attr)) {
/* Get escaped opcode */
diff --git a/arch/x86/lib/iomap_copy_64.S b/arch/x86/lib/iomap_copy_64.S
deleted file mode 100644
index 6ff2f56cb0f7..000000000000
--- a/arch/x86/lib/iomap_copy_64.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright 2006 PathScale, Inc. All Rights Reserved.
- */
-
-#include <linux/linkage.h>
-
-/*
- * override generic version in lib/iomap_copy.c
- */
-SYM_FUNC_START(__iowrite32_copy)
- movl %edx,%ecx
- rep movsl
- RET
-SYM_FUNC_END(__iowrite32_copy)
diff --git a/arch/x86/lib/iomem.c b/arch/x86/lib/iomem.c
index e0411a3774d4..5eecb45d05d5 100644
--- a/arch/x86/lib/iomem.c
+++ b/arch/x86/lib/iomem.c
@@ -25,6 +25,9 @@ static __always_inline void rep_movs(void *to, const void *from, size_t n)
static void string_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
{
+ const void *orig_to = to;
+ const size_t orig_n = n;
+
if (unlikely(!n))
return;
@@ -39,7 +42,7 @@ static void string_memcpy_fromio(void *to, const volatile void __iomem *from, si
}
rep_movs(to, (const void *)from, n);
/* KMSAN must treat values read from devices as initialized. */
- kmsan_unpoison_memory(to, n);
+ kmsan_unpoison_memory(orig_to, orig_n);
}
static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 12af572201a2..caedb3ef6688 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -23,6 +23,7 @@
#
# AVX Superscripts
# (ev): this opcode requires EVEX prefix.
+# (es): this opcode requires EVEX prefix and is SCALABALE.
# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
# (v): this opcode requires VEX prefix.
# (v1): this opcode only supports 128bit VEX.
@@ -33,6 +34,10 @@
# - (F2): the last prefix is 0xF2
# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
# - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
+#
+# REX2 Prefix
+# - (!REX2): REX2 is not allowed
+# - (REX2): REX2 variant e.g. JMPABS
Table: one byte opcode
Referrer:
@@ -148,7 +153,7 @@ AVXcode:
65: SEG=GS (Prefix)
66: Operand-Size (Prefix)
67: Address-Size (Prefix)
-68: PUSH Iz (d64)
+68: PUSH Iz
69: IMUL Gv,Ev,Iz
6a: PUSH Ib (d64)
6b: IMUL Gv,Ev,Ib
@@ -157,22 +162,22 @@ AVXcode:
6e: OUTS/OUTSB DX,Xb
6f: OUTS/OUTSW/OUTSD DX,Xz
# 0x70 - 0x7f
-70: JO Jb
-71: JNO Jb
-72: JB/JNAE/JC Jb
-73: JNB/JAE/JNC Jb
-74: JZ/JE Jb
-75: JNZ/JNE Jb
-76: JBE/JNA Jb
-77: JNBE/JA Jb
-78: JS Jb
-79: JNS Jb
-7a: JP/JPE Jb
-7b: JNP/JPO Jb
-7c: JL/JNGE Jb
-7d: JNL/JGE Jb
-7e: JLE/JNG Jb
-7f: JNLE/JG Jb
+70: JO Jb (!REX2)
+71: JNO Jb (!REX2)
+72: JB/JNAE/JC Jb (!REX2)
+73: JNB/JAE/JNC Jb (!REX2)
+74: JZ/JE Jb (!REX2)
+75: JNZ/JNE Jb (!REX2)
+76: JBE/JNA Jb (!REX2)
+77: JNBE/JA Jb (!REX2)
+78: JS Jb (!REX2)
+79: JNS Jb (!REX2)
+7a: JP/JPE Jb (!REX2)
+7b: JNP/JPO Jb (!REX2)
+7c: JL/JNGE Jb (!REX2)
+7d: JNL/JGE Jb (!REX2)
+7e: JLE/JNG Jb (!REX2)
+7f: JNLE/JG Jb (!REX2)
# 0x80 - 0x8f
80: Grp1 Eb,Ib (1A)
81: Grp1 Ev,Iz (1A)
@@ -208,24 +213,24 @@ AVXcode:
9e: SAHF
9f: LAHF
# 0xa0 - 0xaf
-a0: MOV AL,Ob
-a1: MOV rAX,Ov
-a2: MOV Ob,AL
-a3: MOV Ov,rAX
-a4: MOVS/B Yb,Xb
-a5: MOVS/W/D/Q Yv,Xv
-a6: CMPS/B Xb,Yb
-a7: CMPS/W/D Xv,Yv
-a8: TEST AL,Ib
-a9: TEST rAX,Iz
-aa: STOS/B Yb,AL
-ab: STOS/W/D/Q Yv,rAX
-ac: LODS/B AL,Xb
-ad: LODS/W/D/Q rAX,Xv
-ae: SCAS/B AL,Yb
+a0: MOV AL,Ob (!REX2)
+a1: MOV rAX,Ov (!REX2) | JMPABS O (REX2),(o64)
+a2: MOV Ob,AL (!REX2)
+a3: MOV Ov,rAX (!REX2)
+a4: MOVS/B Yb,Xb (!REX2)
+a5: MOVS/W/D/Q Yv,Xv (!REX2)
+a6: CMPS/B Xb,Yb (!REX2)
+a7: CMPS/W/D Xv,Yv (!REX2)
+a8: TEST AL,Ib (!REX2)
+a9: TEST rAX,Iz (!REX2)
+aa: STOS/B Yb,AL (!REX2)
+ab: STOS/W/D/Q Yv,rAX (!REX2)
+ac: LODS/B AL,Xb (!REX2)
+ad: LODS/W/D/Q rAX,Xv (!REX2)
+ae: SCAS/B AL,Yb (!REX2)
# Note: The May 2011 Intel manual shows Xv for the second parameter of the
# next instruction but Yv is correct
-af: SCAS/W/D/Q rAX,Yv
+af: SCAS/W/D/Q rAX,Yv (!REX2)
# 0xb0 - 0xbf
b0: MOV AL/R8L,Ib
b1: MOV CL/R9L,Ib
@@ -266,7 +271,7 @@ d1: Grp2 Ev,1 (1A)
d2: Grp2 Eb,CL (1A)
d3: Grp2 Ev,CL (1A)
d4: AAM Ib (i64)
-d5: AAD Ib (i64)
+d5: AAD Ib (i64) | REX2 (Prefix),(o64)
d6:
d7: XLAT/XLATB
d8: ESC
@@ -281,26 +286,26 @@ df: ESC
# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
-e0: LOOPNE/LOOPNZ Jb (f64)
-e1: LOOPE/LOOPZ Jb (f64)
-e2: LOOP Jb (f64)
-e3: JrCXZ Jb (f64)
-e4: IN AL,Ib
-e5: IN eAX,Ib
-e6: OUT Ib,AL
-e7: OUT Ib,eAX
+e0: LOOPNE/LOOPNZ Jb (f64) (!REX2)
+e1: LOOPE/LOOPZ Jb (f64) (!REX2)
+e2: LOOP Jb (f64) (!REX2)
+e3: JrCXZ Jb (f64) (!REX2)
+e4: IN AL,Ib (!REX2)
+e5: IN eAX,Ib (!REX2)
+e6: OUT Ib,AL (!REX2)
+e7: OUT Ib,eAX (!REX2)
# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset
# in "near" jumps and calls is 16-bit. For CALL,
# push of return address is 16-bit wide, RSP is decremented by 2
# but is not truncated to 16 bits, unlike RIP.
-e8: CALL Jz (f64)
-e9: JMP-near Jz (f64)
-ea: JMP-far Ap (i64)
-eb: JMP-short Jb (f64)
-ec: IN AL,DX
-ed: IN eAX,DX
-ee: OUT DX,AL
-ef: OUT DX,eAX
+e8: CALL Jz (f64) (!REX2)
+e9: JMP-near Jz (f64) (!REX2)
+ea: JMP-far Ap (i64) (!REX2)
+eb: JMP-short Jb (f64) (!REX2)
+ec: IN AL,DX (!REX2)
+ed: IN eAX,DX (!REX2)
+ee: OUT DX,AL (!REX2)
+ef: OUT DX,eAX (!REX2)
# 0xf0 - 0xff
f0: LOCK (Prefix)
f1:
@@ -386,14 +391,14 @@ AVXcode: 1
2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1)
2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1)
# 0x0f 0x30-0x3f
-30: WRMSR
-31: RDTSC
-32: RDMSR
-33: RDPMC
-34: SYSENTER
-35: SYSEXIT
+30: WRMSR (!REX2)
+31: RDTSC (!REX2)
+32: RDMSR (!REX2)
+33: RDPMC (!REX2)
+34: SYSENTER (!REX2)
+35: SYSEXIT (!REX2)
36:
-37: GETSEC
+37: GETSEC (!REX2)
38: escape # 3-byte escape 1
39:
3a: escape # 3-byte escape 2
@@ -473,22 +478,22 @@ AVXcode: 1
7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
# 0x0f 0x80-0x8f
# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
-80: JO Jz (f64)
-81: JNO Jz (f64)
-82: JB/JC/JNAE Jz (f64)
-83: JAE/JNB/JNC Jz (f64)
-84: JE/JZ Jz (f64)
-85: JNE/JNZ Jz (f64)
-86: JBE/JNA Jz (f64)
-87: JA/JNBE Jz (f64)
-88: JS Jz (f64)
-89: JNS Jz (f64)
-8a: JP/JPE Jz (f64)
-8b: JNP/JPO Jz (f64)
-8c: JL/JNGE Jz (f64)
-8d: JNL/JGE Jz (f64)
-8e: JLE/JNG Jz (f64)
-8f: JNLE/JG Jz (f64)
+80: JO Jz (f64) (!REX2)
+81: JNO Jz (f64) (!REX2)
+82: JB/JC/JNAE Jz (f64) (!REX2)
+83: JAE/JNB/JNC Jz (f64) (!REX2)
+84: JE/JZ Jz (f64) (!REX2)
+85: JNE/JNZ Jz (f64) (!REX2)
+86: JBE/JNA Jz (f64) (!REX2)
+87: JA/JNBE Jz (f64) (!REX2)
+88: JS Jz (f64) (!REX2)
+89: JNS Jz (f64) (!REX2)
+8a: JP/JPE Jz (f64) (!REX2)
+8b: JNP/JPO Jz (f64) (!REX2)
+8c: JL/JNGE Jz (f64) (!REX2)
+8d: JNL/JGE Jz (f64) (!REX2)
+8e: JLE/JNG Jz (f64) (!REX2)
+8f: JNLE/JG Jz (f64) (!REX2)
# 0x0f 0x90-0x9f
90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
@@ -698,17 +703,17 @@ AVXcode: 2
4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
-50: vpdpbusd Vx,Hx,Wx (66),(ev)
-51: vpdpbusds Vx,Hx,Wx (66),(ev)
-52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev)
-53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev)
+50: vpdpbusd Vx,Hx,Wx (66) | vpdpbssd Vx,Hx,Wx (F2),(v) | vpdpbsud Vx,Hx,Wx (F3),(v) | vpdpbuud Vx,Hx,Wx (v)
+51: vpdpbusds Vx,Hx,Wx (66) | vpdpbssds Vx,Hx,Wx (F2),(v) | vpdpbsuds Vx,Hx,Wx (F3),(v) | vpdpbuuds Vx,Hx,Wx (v)
+52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev)
+53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev)
54: vpopcntb/w Vx,Wx (66),(ev)
55: vpopcntd/q Vx,Wx (66),(ev)
58: vpbroadcastd Vx,Wx (66),(v)
59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
-5c: TDPBF16PS Vt,Wt,Ht (F3),(v1)
+5c: TDPBF16PS Vt,Wt,Ht (F3),(v1) | TDPFP16PS Vt,Wt,Ht (F2),(v1),(o64)
# Skip 0x5d
5e: TDPBSSD Vt,Wt,Ht (F2),(v1) | TDPBSUD Vt,Wt,Ht (F3),(v1) | TDPBUSD Vt,Wt,Ht (66),(v1) | TDPBUUD Vt,Wt,Ht (v1)
# Skip 0x5f-0x61
@@ -718,10 +723,12 @@ AVXcode: 2
65: vblendmps/d Vx,Hx,Wx (66),(ev)
66: vpblendmb/w Vx,Hx,Wx (66),(ev)
68: vp2intersectd/q Kx,Hx,Wx (F2),(ev)
-# Skip 0x69-0x6f
+# Skip 0x69-0x6b
+6c: TCMMIMFP16PS Vt,Wt,Ht (66),(v1),(o64) | TCMMRLFP16PS Vt,Wt,Ht (v1),(o64)
+# Skip 0x6d-0x6f
70: vpshldvw Vx,Hx,Wx (66),(ev)
71: vpshldvd/q Vx,Hx,Wx (66),(ev)
-72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3),(ev) | vpshrdvw Vx,Hx,Wx (66),(ev)
+72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3) | vpshrdvw Vx,Hx,Wx (66),(ev)
73: vpshrdvd/q Vx,Hx,Wx (66),(ev)
75: vpermi2b/w Vx,Hx,Wx (66),(ev)
76: vpermi2d/q Vx,Hx,Wx (66),(ev)
@@ -777,8 +784,10 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
-b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
-b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
+b0: vcvtneebf162ps Vx,Mx (F3),(!11B),(v) | vcvtneeph2ps Vx,Mx (66),(!11B),(v) | vcvtneobf162ps Vx,Mx (F2),(!11B),(v) | vcvtneoph2ps Vx,Mx (!11B),(v)
+b1: vbcstnebf162ps Vx,Mw (F3),(!11B),(v) | vbcstnesh2ps Vx,Mw (66),(!11B),(v)
+b4: vpmadd52luq Vx,Hx,Wx (66)
+b5: vpmadd52huq Vx,Hx,Wx (66)
b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -796,15 +805,35 @@ c7: Grp19 (1A)
c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
c9: sha1msg1 Vdq,Wdq
ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
-cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
-cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
-cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
+cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) | vsha512rnds2 Vqq,Hqq,Udq (F2),(11B),(v)
+cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) | vsha512msg1 Vqq,Udq (F2),(11B),(v)
+cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) | vsha512msg2 Vqq,Uqq (F2),(11B),(v)
cf: vgf2p8mulb Vx,Wx (66)
+d2: vpdpwsud Vx,Hx,Wx (F3),(v) | vpdpwusd Vx,Hx,Wx (66),(v) | vpdpwuud Vx,Hx,Wx (v)
+d3: vpdpwsuds Vx,Hx,Wx (F3),(v) | vpdpwusds Vx,Hx,Wx (66),(v) | vpdpwuuds Vx,Hx,Wx (v)
+d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B)
+da: vsm3msg1 Vdq,Hdq,Udq (v1) | vsm3msg2 Vdq,Hdq,Udq (66),(v1) | vsm4key4 Vx,Hx,Wx (F3),(v) | vsm4rnds4 Vx,Hx,Wx (F2),(v)
db: VAESIMC Vdq,Wdq (66),(v1)
-dc: vaesenc Vx,Hx,Wx (66)
-dd: vaesenclast Vx,Hx,Wx (66)
-de: vaesdec Vx,Hx,Wx (66)
-df: vaesdeclast Vx,Hx,Wx (66)
+dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3)
+dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3)
+de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3)
+df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3)
+e0: CMPOXADD My,Gy,By (66),(v1),(o64)
+e1: CMPNOXADD My,Gy,By (66),(v1),(o64)
+e2: CMPBXADD My,Gy,By (66),(v1),(o64)
+e3: CMPNBXADD My,Gy,By (66),(v1),(o64)
+e4: CMPZXADD My,Gy,By (66),(v1),(o64)
+e5: CMPNZXADD My,Gy,By (66),(v1),(o64)
+e6: CMPBEXADD My,Gy,By (66),(v1),(o64)
+e7: CMPNBEXADD My,Gy,By (66),(v1),(o64)
+e8: CMPSXADD My,Gy,By (66),(v1),(o64)
+e9: CMPNSXADD My,Gy,By (66),(v1),(o64)
+ea: CMPPXADD My,Gy,By (66),(v1),(o64)
+eb: CMPNPXADD My,Gy,By (66),(v1),(o64)
+ec: CMPLXADD My,Gy,By (66),(v1),(o64)
+ed: CMPNLXADD My,Gy,By (66),(v1),(o64)
+ee: CMPLEXADD My,Gy,By (66),(v1),(o64)
+ef: CMPNLEXADD My,Gy,By (66),(v1),(o64)
f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2)
f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2)
f2: ANDN Gy,By,Ey (v)
@@ -812,8 +841,11 @@ f3: Grp17 (1A)
f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | WRUSSD/Q My,Gy (66)
f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My,Gy
f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
-f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3)
+f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) | URDMSR Rq,Gq (F2),(11B) | UWRMSR Gq,Rq (F3),(11B)
f9: MOVDIRI My,Gy
+fa: ENCODEKEY128 Ew,Ew (F3)
+fb: ENCODEKEY256 Ew,Ew (F3)
+fc: AADD My,Gy | AAND My,Gy (66) | AOR My,Gy (F2) | AXOR My,Gy (F3)
EndTable
Table: 3-byte opcode 2 (0x0f 0x3a)
@@ -893,10 +925,103 @@ c2: vcmpph Vx,Hx,Wx,Ib (ev) | vcmpsh Vx,Hx,Wx,Ib (F3),(ev)
cc: sha1rnds4 Vdq,Wdq,Ib
ce: vgf2p8affineqb Vx,Wx,Ib (66)
cf: vgf2p8affineinvqb Vx,Wx,Ib (66)
+de: vsm3rnds2 Vdq,Hdq,Wdq,Ib (66),(v1)
df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B)
EndTable
+Table: EVEX map 4
+Referrer:
+AVXcode: 4
+00: ADD Eb,Gb (ev)
+01: ADD Ev,Gv (es) | ADD Ev,Gv (66),(es)
+02: ADD Gb,Eb (ev)
+03: ADD Gv,Ev (es) | ADD Gv,Ev (66),(es)
+08: OR Eb,Gb (ev)
+09: OR Ev,Gv (es) | OR Ev,Gv (66),(es)
+0a: OR Gb,Eb (ev)
+0b: OR Gv,Ev (es) | OR Gv,Ev (66),(es)
+10: ADC Eb,Gb (ev)
+11: ADC Ev,Gv (es) | ADC Ev,Gv (66),(es)
+12: ADC Gb,Eb (ev)
+13: ADC Gv,Ev (es) | ADC Gv,Ev (66),(es)
+18: SBB Eb,Gb (ev)
+19: SBB Ev,Gv (es) | SBB Ev,Gv (66),(es)
+1a: SBB Gb,Eb (ev)
+1b: SBB Gv,Ev (es) | SBB Gv,Ev (66),(es)
+20: AND Eb,Gb (ev)
+21: AND Ev,Gv (es) | AND Ev,Gv (66),(es)
+22: AND Gb,Eb (ev)
+23: AND Gv,Ev (es) | AND Gv,Ev (66),(es)
+24: SHLD Ev,Gv,Ib (es) | SHLD Ev,Gv,Ib (66),(es)
+28: SUB Eb,Gb (ev)
+29: SUB Ev,Gv (es) | SUB Ev,Gv (66),(es)
+2a: SUB Gb,Eb (ev)
+2b: SUB Gv,Ev (es) | SUB Gv,Ev (66),(es)
+2c: SHRD Ev,Gv,Ib (es) | SHRD Ev,Gv,Ib (66),(es)
+30: XOR Eb,Gb (ev)
+31: XOR Ev,Gv (es) | XOR Ev,Gv (66),(es)
+32: XOR Gb,Eb (ev)
+33: XOR Gv,Ev (es) | XOR Gv,Ev (66),(es)
+# CCMPSCC instructions are: CCOMB, CCOMBE, CCOMF, CCOML, CCOMLE, CCOMNB, CCOMNBE, CCOMNL, CCOMNLE,
+# CCOMNO, CCOMNS, CCOMNZ, CCOMO, CCOMS, CCOMT, CCOMZ
+38: CCMPSCC Eb,Gb (ev)
+39: CCMPSCC Ev,Gv (es) | CCMPSCC Ev,Gv (66),(es)
+3a: CCMPSCC Gv,Ev (ev)
+3b: CCMPSCC Gv,Ev (es) | CCMPSCC Gv,Ev (66),(es)
+40: CMOVO Gv,Ev (es) | CMOVO Gv,Ev (66),(es) | CFCMOVO Ev,Ev (es) | CFCMOVO Ev,Ev (66),(es) | SETO Eb (F2),(ev)
+41: CMOVNO Gv,Ev (es) | CMOVNO Gv,Ev (66),(es) | CFCMOVNO Ev,Ev (es) | CFCMOVNO Ev,Ev (66),(es) | SETNO Eb (F2),(ev)
+42: CMOVB Gv,Ev (es) | CMOVB Gv,Ev (66),(es) | CFCMOVB Ev,Ev (es) | CFCMOVB Ev,Ev (66),(es) | SETB Eb (F2),(ev)
+43: CMOVNB Gv,Ev (es) | CMOVNB Gv,Ev (66),(es) | CFCMOVNB Ev,Ev (es) | CFCMOVNB Ev,Ev (66),(es) | SETNB Eb (F2),(ev)
+44: CMOVZ Gv,Ev (es) | CMOVZ Gv,Ev (66),(es) | CFCMOVZ Ev,Ev (es) | CFCMOVZ Ev,Ev (66),(es) | SETZ Eb (F2),(ev)
+45: CMOVNZ Gv,Ev (es) | CMOVNZ Gv,Ev (66),(es) | CFCMOVNZ Ev,Ev (es) | CFCMOVNZ Ev,Ev (66),(es) | SETNZ Eb (F2),(ev)
+46: CMOVBE Gv,Ev (es) | CMOVBE Gv,Ev (66),(es) | CFCMOVBE Ev,Ev (es) | CFCMOVBE Ev,Ev (66),(es) | SETBE Eb (F2),(ev)
+47: CMOVNBE Gv,Ev (es) | CMOVNBE Gv,Ev (66),(es) | CFCMOVNBE Ev,Ev (es) | CFCMOVNBE Ev,Ev (66),(es) | SETNBE Eb (F2),(ev)
+48: CMOVS Gv,Ev (es) | CMOVS Gv,Ev (66),(es) | CFCMOVS Ev,Ev (es) | CFCMOVS Ev,Ev (66),(es) | SETS Eb (F2),(ev)
+49: CMOVNS Gv,Ev (es) | CMOVNS Gv,Ev (66),(es) | CFCMOVNS Ev,Ev (es) | CFCMOVNS Ev,Ev (66),(es) | SETNS Eb (F2),(ev)
+4a: CMOVP Gv,Ev (es) | CMOVP Gv,Ev (66),(es) | CFCMOVP Ev,Ev (es) | CFCMOVP Ev,Ev (66),(es) | SETP Eb (F2),(ev)
+4b: CMOVNP Gv,Ev (es) | CMOVNP Gv,Ev (66),(es) | CFCMOVNP Ev,Ev (es) | CFCMOVNP Ev,Ev (66),(es) | SETNP Eb (F2),(ev)
+4c: CMOVL Gv,Ev (es) | CMOVL Gv,Ev (66),(es) | CFCMOVL Ev,Ev (es) | CFCMOVL Ev,Ev (66),(es) | SETL Eb (F2),(ev)
+4d: CMOVNL Gv,Ev (es) | CMOVNL Gv,Ev (66),(es) | CFCMOVNL Ev,Ev (es) | CFCMOVNL Ev,Ev (66),(es) | SETNL Eb (F2),(ev)
+4e: CMOVLE Gv,Ev (es) | CMOVLE Gv,Ev (66),(es) | CFCMOVLE Ev,Ev (es) | CFCMOVLE Ev,Ev (66),(es) | SETLE Eb (F2),(ev)
+4f: CMOVNLE Gv,Ev (es) | CMOVNLE Gv,Ev (66),(es) | CFCMOVNLE Ev,Ev (es) | CFCMOVNLE Ev,Ev (66),(es) | SETNLE Eb (F2),(ev)
+60: MOVBE Gv,Ev (es) | MOVBE Gv,Ev (66),(es)
+61: MOVBE Ev,Gv (es) | MOVBE Ev,Gv (66),(es)
+65: WRUSSD Md,Gd (66),(ev) | WRUSSQ Mq,Gq (66),(ev)
+66: ADCX Gy,Ey (66),(ev) | ADOX Gy,Ey (F3),(ev) | WRSSD Md,Gd (ev) | WRSSQ Mq,Gq (66),(ev)
+69: IMUL Gv,Ev,Iz (es) | IMUL Gv,Ev,Iz (66),(es)
+6b: IMUL Gv,Ev,Ib (es) | IMUL Gv,Ev,Ib (66),(es)
+80: Grp1 Eb,Ib (1A),(ev)
+81: Grp1 Ev,Iz (1A),(es)
+83: Grp1 Ev,Ib (1A),(es)
+# CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL,
+# CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ
+84: CTESTSCC (ev)
+85: CTESTSCC (es) | CTESTSCC (66),(es)
+88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es)
+8f: POP2 Bq,Rq (000),(11B),(ev)
+a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es)
+ad: SHRD Ev,Gv,CL (es) | SHRD Ev,Gv,CL (66),(es)
+af: IMUL Gv,Ev (es) | IMUL Gv,Ev (66),(es)
+c0: Grp2 Eb,Ib (1A),(ev)
+c1: Grp2 Ev,Ib (1A),(es)
+d0: Grp2 Eb,1 (1A),(ev)
+d1: Grp2 Ev,1 (1A),(es)
+d2: Grp2 Eb,CL (1A),(ev)
+d3: Grp2 Ev,CL (1A),(es)
+f0: CRC32 Gy,Eb (es) | INVEPT Gq,Mdq (F3),(ev)
+f1: CRC32 Gy,Ey (es) | CRC32 Gy,Ey (66),(es) | INVVPID Gy,Mdq (F3),(ev)
+f2: INVPCID Gy,Mdq (F3),(ev)
+f4: TZCNT Gv,Ev (es) | TZCNT Gv,Ev (66),(es)
+f5: LZCNT Gv,Ev (es) | LZCNT Gv,Ev (66),(es)
+f6: Grp3_1 Eb (1A),(ev)
+f7: Grp3_2 Ev (1A),(es)
+f8: MOVDIR64B Gv,Mdqq (66),(ev) | ENQCMD Gv,Mdqq (F2),(ev) | ENQCMDS Gv,Mdqq (F3),(ev) | URDMSR Rq,Gq (F2),(11B),(ev) | UWRMSR Gq,Rq (F3),(11B),(ev)
+f9: MOVDIRI My,Gy (ev)
+fe: Grp4 (1A),(ev)
+ff: Grp5 (1A),(es) | PUSH2 Bq,Rq (110),(11B),(ev)
+EndTable
+
Table: EVEX map 5
Referrer:
AVXcode: 5
@@ -975,6 +1100,12 @@ d6: vfcmulcph Vx,Hx,Wx (F2),(ev) | vfmulcph Vx,Hx,Wx (F3),(ev)
d7: vfcmulcsh Vx,Hx,Wx (F2),(ev) | vfmulcsh Vx,Hx,Wx (F3),(ev)
EndTable
+Table: VEX map 7
+Referrer:
+AVXcode: 7
+f8: URDMSR Rq,Id (F2),(v1),(11B) | UWRMSR Id,Rq (F3),(v1),(11B)
+EndTable
+
GrpTable: Grp1
0: ADD
1: OR
@@ -1051,7 +1182,7 @@ GrpTable: Grp6
EndTable
GrpTable: Grp7
-0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B) | WRMSRNS (110),(11B)
+0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B) | WRMSRNS (110),(11B) | RDMSRLIST (F2),(110),(11B) | WRMSRLIST (F3),(110),(11B) | PBNDKB (111),(11B)
1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) | ENCLS (111),(11B) | ERETU (F3),(010),(11B) | ERETS (F2),(010),(11B)
2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B)
3: LIDT Ms
@@ -1137,6 +1268,8 @@ GrpTable: Grp16
1: prefetch T0
2: prefetch T1
3: prefetch T2
+6: prefetch IT1
+7: prefetch IT0
EndTable
GrpTable: Grp17
diff --git a/arch/x86/math-emu/fpu_etc.c b/arch/x86/math-emu/fpu_etc.c
index 1b118fd93140..39423ec409e1 100644
--- a/arch/x86/math-emu/fpu_etc.c
+++ b/arch/x86/math-emu/fpu_etc.c
@@ -120,9 +120,14 @@ static void fxam(FPU_REG *st0_ptr, u_char st0tag)
setcc(c);
}
+static void FPU_ST0_illegal(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_illegal();
+}
+
static FUNC_ST0 const fp_etc_table[] = {
- fchs, fabs, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal,
- ftst_, fxam, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal
+ fchs, fabs, FPU_ST0_illegal, FPU_ST0_illegal,
+ ftst_, fxam, FPU_ST0_illegal, FPU_ST0_illegal,
};
void FPU_etc(void)
diff --git a/arch/x86/math-emu/fpu_trig.c b/arch/x86/math-emu/fpu_trig.c
index 990d847ae902..85daf98c81c3 100644
--- a/arch/x86/math-emu/fpu_trig.c
+++ b/arch/x86/math-emu/fpu_trig.c
@@ -433,13 +433,13 @@ static void fxtract(FPU_REG *st0_ptr, u_char st0_tag)
#endif /* PARANOID */
}
-static void fdecstp(void)
+static void fdecstp(FPU_REG *st0_ptr, u_char st0_tag)
{
clear_C1();
top--;
}
-static void fincstp(void)
+static void fincstp(FPU_REG *st0_ptr, u_char st0_tag)
{
clear_C1();
top++;
@@ -1631,7 +1631,7 @@ static void fscale(FPU_REG *st0_ptr, u_char st0_tag)
static FUNC_ST0 const trig_table_a[] = {
f2xm1, fyl2x, fptan, fpatan,
- fxtract, fprem1, (FUNC_ST0) fdecstp, (FUNC_ST0) fincstp
+ fxtract, fprem1, fdecstp, fincstp,
};
void FPU_triga(void)
diff --git a/arch/x86/math-emu/reg_constant.c b/arch/x86/math-emu/reg_constant.c
index 742619e94bdf..003a0b2753e6 100644
--- a/arch/x86/math-emu/reg_constant.c
+++ b/arch/x86/math-emu/reg_constant.c
@@ -108,8 +108,13 @@ static void fldz(int rc)
typedef void (*FUNC_RC) (int);
+static void FPU_RC_illegal(int unused)
+{
+ FPU_illegal();
+}
+
static FUNC_RC constants_table[] = {
- fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC) FPU_illegal
+ fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, FPU_RC_illegal
};
void fconst(void)
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 428048e73bd2..8d3a00e5c528 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -34,7 +34,7 @@ obj-y += pat/
CFLAGS_physaddr.o := -fno-stack-protector
CFLAGS_mem_encrypt_identity.o := -fno-stack-protector
-CFLAGS_fault.o := -I $(srctree)/$(src)/../include/asm/trace
+CFLAGS_fault.o := -I $(src)/../include/asm/trace
obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index b522933bfa56..51986e8a9d35 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -164,13 +164,6 @@ static bool ex_handler_uaccess(const struct exception_table_entry *fixup,
return ex_handler_default(fixup, regs);
}
-static bool ex_handler_copy(const struct exception_table_entry *fixup,
- struct pt_regs *regs, int trapnr)
-{
- WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?");
- return ex_handler_fault(fixup, regs, trapnr);
-}
-
static bool ex_handler_msr(const struct exception_table_entry *fixup,
struct pt_regs *regs, bool wrmsr, bool safe, int reg)
{
@@ -341,8 +334,6 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
return ex_handler_fault(e, regs, trapnr);
case EX_TYPE_UACCESS:
return ex_handler_uaccess(e, regs, trapnr, fault_addr);
- case EX_TYPE_COPY:
- return ex_handler_copy(e, regs, trapnr);
case EX_TYPE_CLEAR_FS:
return ex_handler_clear_fs(e, regs);
case EX_TYPE_FPU_RESTORE:
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index bba4e020dd64..e6c469b323cc 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -20,6 +20,7 @@
#include <linux/efi.h> /* efi_crash_gracefully_on_page_fault()*/
#include <linux/mm_types.h>
#include <linux/mm.h> /* find_and_lock_vma() */
+#include <linux/vmalloc.h>
#include <asm/cpufeature.h> /* boot_cpu_has, ... */
#include <asm/traps.h> /* dotraplinkage, ... */
@@ -514,18 +515,19 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long ad
if (error_code & X86_PF_INSTR) {
unsigned int level;
+ bool nx, rw;
pgd_t *pgd;
pte_t *pte;
pgd = __va(read_cr3_pa());
pgd += pgd_index(address);
- pte = lookup_address_in_pgd(pgd, address, &level);
+ pte = lookup_address_in_pgd_attr(pgd, address, &level, &nx, &rw);
- if (pte && pte_present(*pte) && !pte_exec(*pte))
+ if (pte && pte_present(*pte) && (!pte_exec(*pte) || nx))
pr_crit("kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n",
from_kuid(&init_user_ns, current_uid()));
- if (pte && pte_present(*pte) && pte_exec(*pte) &&
+ if (pte && pte_present(*pte) && pte_exec(*pte) && !nx &&
(pgd_flags(*pgd) & _PAGE_USER) &&
(__read_cr4() & X86_CR4_SMEP))
pr_crit("unable to execute userspace code (SMEP?) (uid: %d)\n",
@@ -834,14 +836,17 @@ bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
static void
__bad_area(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, u32 pkey, int si_code)
+ unsigned long address, struct mm_struct *mm,
+ struct vm_area_struct *vma, u32 pkey, int si_code)
{
- struct mm_struct *mm = current->mm;
/*
* 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);
+ if (mm)
+ mmap_read_unlock(mm);
+ else
+ vma_end_read(vma);
__bad_area_nosemaphore(regs, error_code, address, pkey, si_code);
}
@@ -865,7 +870,8 @@ static inline bool bad_area_access_from_pkeys(unsigned long error_code,
static noinline void
bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, struct vm_area_struct *vma)
+ unsigned long address, struct mm_struct *mm,
+ struct vm_area_struct *vma)
{
/*
* This OSPKE check is not strictly necessary at runtime.
@@ -895,9 +901,9 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
*/
u32 pkey = vma_pkey(vma);
- __bad_area(regs, error_code, address, pkey, SEGV_PKUERR);
+ __bad_area(regs, error_code, address, mm, vma, pkey, SEGV_PKUERR);
} else {
- __bad_area(regs, error_code, address, 0, SEGV_ACCERR);
+ __bad_area(regs, error_code, address, mm, vma, 0, SEGV_ACCERR);
}
}
@@ -1325,8 +1331,9 @@ void do_user_addr_fault(struct pt_regs *regs,
goto lock_mmap;
if (unlikely(access_error(error_code, vma))) {
- vma_end_read(vma);
- goto lock_mmap;
+ bad_area_access_error(regs, error_code, address, NULL, vma);
+ count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
+ return;
}
fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs);
if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
@@ -1362,7 +1369,7 @@ retry:
* we can handle it..
*/
if (unlikely(access_error(error_code, vma))) {
- bad_area_access_error(regs, error_code, address, vma);
+ bad_area_access_error(regs, error_code, address, mm, vma);
return;
}
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 5804bbae4f01..807a5859a3c4 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -19,41 +19,14 @@
#include <asm/tlbflush.h>
#include <asm/elf.h>
-/*
- * pmd_huge() returns 1 if @pmd is hugetlb related entry, that is normal
- * hugetlb entry or non-present (migration or hwpoisoned) hugetlb entry.
- * Otherwise, returns 0.
- */
-int pmd_huge(pmd_t pmd)
-{
- return !pmd_none(pmd) &&
- (pmd_val(pmd) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;
-}
-
-/*
- * pud_huge() returns 1 if @pud is hugetlb related entry, that is normal
- * hugetlb entry or non-present (migration or hwpoisoned) hugetlb entry.
- * Otherwise, returns 0.
- */
-int pud_huge(pud_t pud)
-{
-#if CONFIG_PGTABLE_LEVELS > 2
- return !pud_none(pud) &&
- (pud_val(pud) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;
-#else
- return 0;
-#endif
-}
-
#ifdef CONFIG_HUGETLB_PAGE
static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
- info.flags = 0;
info.length = len;
info.low_limit = get_mmap_base(1);
@@ -65,7 +38,6 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
task_size_32bit() : task_size_64bit(addr > DEFAULT_MAP_WINDOW);
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- info.align_offset = 0;
return vm_unmapped_area(&info);
}
@@ -74,7 +46,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info;
+ struct vm_unmapped_area_info info = {};
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.length = len;
@@ -89,7 +61,6 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- info.align_offset = 0;
addr = vm_unmapped_area(&info);
/*
@@ -141,7 +112,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
}
get_unmapped_area:
- if (mm->get_unmapped_area == arch_get_unmapped_area)
+ if (!test_bit(MMF_TOPDOWN, &mm->flags))
return hugetlb_get_unmapped_area_bottomup(file, addr, len,
pgoff, flags);
else
diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c
index 968d7005f4a7..c45127265f2f 100644
--- a/arch/x86/mm/ident_map.c
+++ b/arch/x86/mm/ident_map.c
@@ -4,6 +4,79 @@
* included by both the compressed kernel and the regular kernel.
*/
+static void free_pte(struct x86_mapping_info *info, pmd_t *pmd)
+{
+ pte_t *pte = pte_offset_kernel(pmd, 0);
+
+ info->free_pgt_page(pte, info->context);
+}
+
+static void free_pmd(struct x86_mapping_info *info, pud_t *pud)
+{
+ pmd_t *pmd = pmd_offset(pud, 0);
+ int i;
+
+ for (i = 0; i < PTRS_PER_PMD; i++) {
+ if (!pmd_present(pmd[i]))
+ continue;
+
+ if (pmd_leaf(pmd[i]))
+ continue;
+
+ free_pte(info, &pmd[i]);
+ }
+
+ info->free_pgt_page(pmd, info->context);
+}
+
+static void free_pud(struct x86_mapping_info *info, p4d_t *p4d)
+{
+ pud_t *pud = pud_offset(p4d, 0);
+ int i;
+
+ for (i = 0; i < PTRS_PER_PUD; i++) {
+ if (!pud_present(pud[i]))
+ continue;
+
+ if (pud_leaf(pud[i]))
+ continue;
+
+ free_pmd(info, &pud[i]);
+ }
+
+ info->free_pgt_page(pud, info->context);
+}
+
+static void free_p4d(struct x86_mapping_info *info, pgd_t *pgd)
+{
+ p4d_t *p4d = p4d_offset(pgd, 0);
+ int i;
+
+ for (i = 0; i < PTRS_PER_P4D; i++) {
+ if (!p4d_present(p4d[i]))
+ continue;
+
+ free_pud(info, &p4d[i]);
+ }
+
+ if (pgtable_l5_enabled())
+ info->free_pgt_page(p4d, info->context);
+}
+
+void kernel_ident_mapping_free(struct x86_mapping_info *info, pgd_t *pgd)
+{
+ int i;
+
+ for (i = 0; i < PTRS_PER_PGD; i++) {
+ if (!pgd_present(pgd[i]))
+ continue;
+
+ free_p4d(info, &pgd[i]);
+ }
+
+ info->free_pgt_page(pgd, info->context);
+}
+
static void ident_pmd_init(struct x86_mapping_info *info, pmd_t *pmd_page,
unsigned long addr, unsigned long end)
{
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 679893ea5e68..eb503f53c319 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -7,6 +7,7 @@
#include <linux/swapops.h>
#include <linux/kmemleak.h>
#include <linux/sched/task.h>
+#include <linux/execmem.h>
#include <asm/set_memory.h>
#include <asm/cpu_device_id.h>
@@ -261,21 +262,17 @@ static void __init probe_page_size_mask(void)
}
}
-#define INTEL_MATCH(_model) { .vendor = X86_VENDOR_INTEL, \
- .family = 6, \
- .model = _model, \
- }
/*
* INVLPG may not properly flush Global entries
* on these CPUs when PCIDs are enabled.
*/
static const struct x86_cpu_id invlpg_miss_ids[] = {
- INTEL_MATCH(INTEL_FAM6_ALDERLAKE ),
- INTEL_MATCH(INTEL_FAM6_ALDERLAKE_L ),
- INTEL_MATCH(INTEL_FAM6_ATOM_GRACEMONT ),
- INTEL_MATCH(INTEL_FAM6_RAPTORLAKE ),
- INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_P),
- INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_S),
+ X86_MATCH_VFM(INTEL_ALDERLAKE, 0),
+ X86_MATCH_VFM(INTEL_ALDERLAKE_L, 0),
+ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, 0),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE, 0),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_P, 0),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_S, 0),
{}
};
@@ -990,53 +987,6 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
}
#endif
-/*
- * Calculate the precise size of the DMA zone (first 16 MB of RAM),
- * and pass it to the MM layer - to help it set zone watermarks more
- * accurately.
- *
- * Done on 64-bit systems only for the time being, although 32-bit systems
- * might benefit from this as well.
- */
-void __init memblock_find_dma_reserve(void)
-{
-#ifdef CONFIG_X86_64
- u64 nr_pages = 0, nr_free_pages = 0;
- unsigned long start_pfn, end_pfn;
- phys_addr_t start_addr, end_addr;
- int i;
- u64 u;
-
- /*
- * Iterate over all memory ranges (free and reserved ones alike),
- * to calculate the total number of pages in the first 16 MB of RAM:
- */
- nr_pages = 0;
- for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) {
- start_pfn = min(start_pfn, MAX_DMA_PFN);
- end_pfn = min(end_pfn, MAX_DMA_PFN);
-
- nr_pages += end_pfn - start_pfn;
- }
-
- /*
- * Iterate over free memory ranges to calculate the number of free
- * pages in the DMA zone, while not counting potential partial
- * pages at the beginning or the end of the range:
- */
- nr_free_pages = 0;
- for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start_addr, &end_addr, NULL) {
- start_pfn = min_t(unsigned long, PFN_UP(start_addr), MAX_DMA_PFN);
- end_pfn = min_t(unsigned long, PFN_DOWN(end_addr), MAX_DMA_PFN);
-
- if (start_pfn < end_pfn)
- nr_free_pages += end_pfn - start_pfn;
- }
-
- set_dma_reserve(nr_pages - nr_free_pages);
-#endif
-}
-
void __init zone_sizes_init(void)
{
unsigned long max_zone_pfns[MAX_NR_ZONES];
@@ -1099,3 +1049,31 @@ unsigned long arch_max_swapfile_size(void)
return pages;
}
#endif
+
+#ifdef CONFIG_EXECMEM
+static struct execmem_info execmem_info __ro_after_init;
+
+struct execmem_info __init *execmem_arch_setup(void)
+{
+ unsigned long start, offset = 0;
+
+ if (kaslr_enabled())
+ offset = get_random_u32_inclusive(1, 1024) * PAGE_SIZE;
+
+ start = MODULES_VADDR + offset;
+
+ execmem_info = (struct execmem_info){
+ .ranges = {
+ [EXECMEM_DEFAULT] = {
+ .flags = EXECMEM_KASAN_SHADOW,
+ .start = start,
+ .end = MODULES_END,
+ .pgprot = PAGE_KERNEL,
+ .alignment = MODULE_ALIGN,
+ },
+ },
+ };
+
+ return &execmem_info;
+}
+#endif /* CONFIG_EXECMEM */
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 7e177856ee4f..d8dbeac8b206 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -469,7 +469,9 @@ phys_pte_init(pte_t *pte_page, unsigned long paddr, unsigned long paddr_end,
!e820__mapped_any(paddr & PAGE_MASK, paddr_next,
E820_TYPE_RAM) &&
!e820__mapped_any(paddr & PAGE_MASK, paddr_next,
- E820_TYPE_RESERVED_KERN))
+ E820_TYPE_RESERVED_KERN) &&
+ !e820__mapped_any(paddr & PAGE_MASK, paddr_next,
+ E820_TYPE_ACPI))
set_pte_init(pte, __pte(0), init);
continue;
}
@@ -524,7 +526,9 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end,
!e820__mapped_any(paddr & PMD_MASK, paddr_next,
E820_TYPE_RAM) &&
!e820__mapped_any(paddr & PMD_MASK, paddr_next,
- E820_TYPE_RESERVED_KERN))
+ E820_TYPE_RESERVED_KERN) &&
+ !e820__mapped_any(paddr & PMD_MASK, paddr_next,
+ E820_TYPE_ACPI))
set_pmd_init(pmd, __pmd(0), init);
continue;
}
@@ -611,7 +615,9 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end,
!e820__mapped_any(paddr & PUD_MASK, paddr_next,
E820_TYPE_RAM) &&
!e820__mapped_any(paddr & PUD_MASK, paddr_next,
- E820_TYPE_RESERVED_KERN))
+ E820_TYPE_RESERVED_KERN) &&
+ !e820__mapped_any(paddr & PUD_MASK, paddr_next,
+ E820_TYPE_ACPI))
set_pud_init(pud, __pud(0), init);
continue;
}
@@ -698,7 +704,9 @@ phys_p4d_init(p4d_t *p4d_page, unsigned long paddr, unsigned long paddr_end,
!e820__mapped_any(paddr & P4D_MASK, paddr_next,
E820_TYPE_RAM) &&
!e820__mapped_any(paddr & P4D_MASK, paddr_next,
- E820_TYPE_RESERVED_KERN))
+ E820_TYPE_RESERVED_KERN) &&
+ !e820__mapped_any(paddr & P4D_MASK, paddr_next,
+ E820_TYPE_ACPI))
set_p4d_init(p4d, __p4d(0), init);
continue;
}
@@ -980,8 +988,6 @@ static void __meminit free_pagetable(struct page *page, int order)
/* bootmem page has reserved flag */
if (PageReserved(page)) {
- __ClearPageReserved(page);
-
magic = page->index;
if (magic == SECTION_INFO || magic == MIX_SECTION_INFO) {
while (nr_pages--)
@@ -1354,18 +1360,6 @@ void __init mem_init(void)
preallocate_vmalloc_pages();
}
-#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
-int __init deferred_page_init_max_threads(const struct cpumask *node_cpumask)
-{
- /*
- * More CPUs always led to greater speedups on tested systems, up to
- * all the nodes' CPUs. Use all since the system is otherwise idle
- * now.
- */
- return max_t(int, cpumask_weight(node_cpumask), 1);
-}
-#endif
-
int kernel_set_to_readonly;
void mark_rodata_ro(void)
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 422602f6039b..86a476a426c2 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -2,7 +2,7 @@
/*
* AMD Memory Encryption Support
*
- * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2016-2024 Advanced Micro Devices, Inc.
*
* Author: Tom Lendacky <thomas.lendacky@amd.com>
*/
@@ -283,7 +283,7 @@ static void enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc)
#endif
}
-static bool amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+static int amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
{
/*
* To maintain the security guarantees of SEV-SNP guests, make sure
@@ -292,11 +292,11 @@ static bool amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool
if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && !enc)
snp_set_memory_shared(vaddr, npages);
- return true;
+ return 0;
}
/* Return true unconditionally: return value doesn't matter for the SEV side */
-static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+static int amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
{
/*
* After memory is mapped encrypted in the page table, validate it
@@ -308,7 +308,7 @@ static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool e
if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
enc_dec_hypercall(vaddr, npages << PAGE_SHIFT, enc);
- return true;
+ return 0;
}
static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
@@ -510,6 +510,12 @@ void __init sme_early_init(void)
*/
x86_init.resources.dmi_setup = snp_dmi_setup;
}
+
+ /*
+ * Switch the SVSM CA mapping (if active) from identity mapped to
+ * kernel mapped.
+ */
+ snp_update_svsm_ca();
}
void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index c90c20904a60..a2cabb1c81e1 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -129,9 +129,9 @@ static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base,
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
{
if (mmap_is_legacy())
- mm->get_unmapped_area = arch_get_unmapped_area;
+ clear_bit(MMF_TOPDOWN, &mm->flags);
else
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ set_bit(MMF_TOPDOWN, &mm->flags);
arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base,
arch_rnd(mmap64_rnd_bits), task_size_64bit(0),
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 65e9a6e391c0..6ce10e3c6228 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -493,7 +493,7 @@ static void __init numa_clear_kernel_node_hotplug(void)
for_each_reserved_mem_region(mb_region) {
int nid = memblock_get_region_node(mb_region);
- if (nid != MAX_NUMNODES)
+ if (nid != NUMA_NO_NODE)
node_set(nid, reserved_nodemask);
}
@@ -614,9 +614,9 @@ static int __init numa_init(int (*init_func)(void))
nodes_clear(node_online_map);
memset(&numa_meminfo, 0, sizeof(numa_meminfo));
WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory,
- MAX_NUMNODES));
+ NUMA_NO_NODE));
WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved,
- MAX_NUMNODES));
+ NUMA_NO_NODE));
/* In case that parsing SRAT failed. */
WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX));
numa_reset_distance();
@@ -929,6 +929,8 @@ int memory_add_physaddr_to_nid(u64 start)
}
EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
+
static int __init cmp_memblk(const void *a, const void *b)
{
const struct numa_memblk *ma = *(const struct numa_memblk **)a;
@@ -1001,5 +1003,3 @@ int __init numa_fill_memblks(u64 start, u64 end)
}
return 0;
}
-
-#endif
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index 025fd7ea5d69..65fda406e6f2 100644
--- a/arch/x86/mm/numa_32.c
+++ b/arch/x86/mm/numa_32.c
@@ -24,6 +24,7 @@
#include <linux/memblock.h>
#include <linux/init.h>
+#include <linux/vmalloc.h>
#include <asm/pgtable_areas.h>
#include "numa_internal.h"
diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
index 36b603d0cdde..bdc2a240c2aa 100644
--- a/arch/x86/mm/pat/memtype.c
+++ b/arch/x86/mm/pat/memtype.c
@@ -39,6 +39,7 @@
#include <linux/pfn_t.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <linux/fs.h>
#include <linux/rbtree.h>
@@ -947,6 +948,29 @@ static void free_pfn_range(u64 paddr, unsigned long size)
memtype_free(paddr, paddr + size);
}
+static int follow_phys(struct vm_area_struct *vma, unsigned long *prot,
+ resource_size_t *phys)
+{
+ pte_t *ptep, pte;
+ spinlock_t *ptl;
+
+ if (follow_pte(vma, vma->vm_start, &ptep, &ptl))
+ return -EINVAL;
+
+ pte = ptep_get(ptep);
+
+ /* Never return PFNs of anon folios in COW mappings. */
+ if (vm_normal_folio(vma, vma->vm_start, pte)) {
+ pte_unmap_unlock(ptep, ptl);
+ return -EINVAL;
+ }
+
+ *prot = pgprot_val(pte_pgprot(pte));
+ *phys = (resource_size_t)pte_pfn(pte) << PAGE_SHIFT;
+ pte_unmap_unlock(ptep, ptl);
+ return 0;
+}
+
static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
pgprot_t *pgprot)
{
@@ -964,7 +988,7 @@ static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
* detect the PFN. If we need the cachemode as well, we're out of luck
* for now and have to fail fork().
*/
- if (!follow_phys(vma, vma->vm_start, 0, &prot, paddr)) {
+ if (!follow_phys(vma, &prot, paddr)) {
if (pgprot)
*pgprot = __pgprot(prot);
return 0;
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 80c9037ffadf..44f7b2ea6a07 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -619,7 +619,8 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long start,
* Validate strict W^X semantics.
*/
static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long start,
- unsigned long pfn, unsigned long npg)
+ unsigned long pfn, unsigned long npg,
+ bool nx, bool rw)
{
unsigned long end;
@@ -641,6 +642,10 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star
if ((pgprot_val(new) & (_PAGE_RW | _PAGE_NX)) != _PAGE_RW)
return new;
+ /* Non-leaf translation entries can disable writing or execution. */
+ if (!rw || nx)
+ return new;
+
end = start + npg * PAGE_SIZE - 1;
WARN_ONCE(1, "CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n",
(unsigned long long)pgprot_val(old),
@@ -657,56 +662,82 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star
/*
* Lookup the page table entry for a virtual address in a specific pgd.
- * Return a pointer to the entry and the level of the mapping.
+ * Return a pointer to the entry (or NULL if the entry does not exist),
+ * the level of the entry, and the effective NX and RW bits of all
+ * page table levels.
*/
-pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
- unsigned int *level)
+pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
+ unsigned int *level, bool *nx, bool *rw)
{
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
- *level = PG_LEVEL_NONE;
+ *level = PG_LEVEL_256T;
+ *nx = false;
+ *rw = true;
if (pgd_none(*pgd))
return NULL;
+ *level = PG_LEVEL_512G;
+ *nx |= pgd_flags(*pgd) & _PAGE_NX;
+ *rw &= pgd_flags(*pgd) & _PAGE_RW;
+
p4d = p4d_offset(pgd, address);
if (p4d_none(*p4d))
return NULL;
- *level = PG_LEVEL_512G;
if (p4d_leaf(*p4d) || !p4d_present(*p4d))
return (pte_t *)p4d;
+ *level = PG_LEVEL_1G;
+ *nx |= p4d_flags(*p4d) & _PAGE_NX;
+ *rw &= p4d_flags(*p4d) & _PAGE_RW;
+
pud = pud_offset(p4d, address);
if (pud_none(*pud))
return NULL;
- *level = PG_LEVEL_1G;
if (pud_leaf(*pud) || !pud_present(*pud))
return (pte_t *)pud;
+ *level = PG_LEVEL_2M;
+ *nx |= pud_flags(*pud) & _PAGE_NX;
+ *rw &= pud_flags(*pud) & _PAGE_RW;
+
pmd = pmd_offset(pud, address);
if (pmd_none(*pmd))
return NULL;
- *level = PG_LEVEL_2M;
if (pmd_leaf(*pmd) || !pmd_present(*pmd))
return (pte_t *)pmd;
*level = PG_LEVEL_4K;
+ *nx |= pmd_flags(*pmd) & _PAGE_NX;
+ *rw &= pmd_flags(*pmd) & _PAGE_RW;
return pte_offset_kernel(pmd, address);
}
/*
+ * Lookup the page table entry for a virtual address in a specific pgd.
+ * Return a pointer to the entry and the level of the mapping.
+ */
+pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
+ unsigned int *level)
+{
+ bool nx, rw;
+
+ return lookup_address_in_pgd_attr(pgd, address, level, &nx, &rw);
+}
+
+/*
* Lookup the page table entry for a virtual address. Return a pointer
* to the entry and the level of the mapping.
*
- * Note: We return pud and pmd either when the entry is marked large
- * or when the present bit is not set. Otherwise we would return a
- * pointer to a nonexisting mapping.
+ * Note: the function returns p4d, pud or pmd either when the entry is marked
+ * large or when the present bit is not set. Otherwise it returns NULL.
*/
pte_t *lookup_address(unsigned long address, unsigned int *level)
{
@@ -715,13 +746,16 @@ pte_t *lookup_address(unsigned long address, unsigned int *level)
EXPORT_SYMBOL_GPL(lookup_address);
static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address,
- unsigned int *level)
+ unsigned int *level, bool *nx, bool *rw)
{
- if (cpa->pgd)
- return lookup_address_in_pgd(cpa->pgd + pgd_index(address),
- address, level);
+ pgd_t *pgd;
+
+ if (!cpa->pgd)
+ pgd = pgd_offset_k(address);
+ else
+ pgd = cpa->pgd + pgd_index(address);
- return lookup_address(address, level);
+ return lookup_address_in_pgd_attr(pgd, address, level, nx, rw);
}
/*
@@ -849,12 +883,13 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address,
pgprot_t old_prot, new_prot, req_prot, chk_prot;
pte_t new_pte, *tmp;
enum pg_level level;
+ bool nx, rw;
/*
* Check for races, another CPU might have split this page
* up already:
*/
- tmp = _lookup_address_cpa(cpa, address, &level);
+ tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw);
if (tmp != kpte)
return 1;
@@ -965,7 +1000,8 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address,
new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages,
psize, CPA_DETECT);
- new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages);
+ new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages,
+ nx, rw);
/*
* If there is a conflict, split the large page.
@@ -1046,6 +1082,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
pte_t *pbase = (pte_t *)page_address(base);
unsigned int i, level;
pgprot_t ref_prot;
+ bool nx, rw;
pte_t *tmp;
spin_lock(&pgd_lock);
@@ -1053,7 +1090,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
* Check for races, another CPU might have split this page
* up for us already:
*/
- tmp = _lookup_address_cpa(cpa, address, &level);
+ tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw);
if (tmp != kpte) {
spin_unlock(&pgd_lock);
return 1;
@@ -1082,8 +1119,8 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
lpinc = PMD_SIZE;
/*
* Clear the PSE flags if the PRESENT flag is not set
- * otherwise pmd_present/pmd_huge will return true
- * even on a non present pmd.
+ * otherwise pmd_present() will return true even on a non
+ * present pmd.
*/
if (!(pgprot_val(ref_prot) & _PAGE_PRESENT))
pgprot_val(ref_prot) &= ~_PAGE_PSE;
@@ -1594,10 +1631,11 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
int do_split, err;
unsigned int level;
pte_t *kpte, old_pte;
+ bool nx, rw;
address = __cpa_addr(cpa, cpa->curpage);
repeat:
- kpte = _lookup_address_cpa(cpa, address, &level);
+ kpte = _lookup_address_cpa(cpa, address, &level, &nx, &rw);
if (!kpte)
return __cpa_process_fault(cpa, address, primary);
@@ -1619,7 +1657,8 @@ repeat:
new_prot = static_protections(new_prot, address, pfn, 1, 0,
CPA_PROTECT);
- new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1);
+ new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1,
+ nx, rw);
new_prot = pgprot_clear_protnone_bits(new_prot);
@@ -2156,7 +2195,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
/* Notify hypervisor that we are about to set/clr encryption attribute. */
- if (!x86_platform.guest.enc_status_change_prepare(addr, numpages, enc))
+ ret = x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
+ if (ret)
goto vmm_fail;
ret = __change_page_attr_set_clr(&cpa, 1);
@@ -2174,24 +2214,61 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
return ret;
/* Notify hypervisor that we have successfully set/clr encryption attribute. */
- if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
+ ret = x86_platform.guest.enc_status_change_finish(addr, numpages, enc);
+ if (ret)
goto vmm_fail;
return 0;
vmm_fail:
- WARN_ONCE(1, "CPA VMM failure to convert memory (addr=%p, numpages=%d) to %s.\n",
- (void *)addr, numpages, enc ? "private" : "shared");
+ WARN_ONCE(1, "CPA VMM failure to convert memory (addr=%p, numpages=%d) to %s: %d\n",
+ (void *)addr, numpages, enc ? "private" : "shared", ret);
+
+ return ret;
+}
+
+/*
+ * The lock serializes conversions between private and shared memory.
+ *
+ * It is taken for read on conversion. A write lock guarantees that no
+ * concurrent conversions are in progress.
+ */
+static DECLARE_RWSEM(mem_enc_lock);
+
+/*
+ * Stop new private<->shared conversions.
+ *
+ * Taking the exclusive mem_enc_lock waits for in-flight conversions to complete.
+ * The lock is not released to prevent new conversions from being started.
+ */
+bool set_memory_enc_stop_conversion(void)
+{
+ /*
+ * In a crash scenario, sleep is not allowed. Try to take the lock.
+ * Failure indicates that there is a race with the conversion.
+ */
+ if (oops_in_progress)
+ return down_write_trylock(&mem_enc_lock);
- return -EIO;
+ down_write(&mem_enc_lock);
+
+ return true;
}
static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
{
- if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
- return __set_memory_enc_pgtable(addr, numpages, enc);
+ int ret = 0;
- return 0;
+ if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
+ if (!down_read_trylock(&mem_enc_lock))
+ return -EBUSY;
+
+ ret = __set_memory_enc_pgtable(addr, numpages, enc);
+
+ up_read(&mem_enc_lock);
+ }
+
+ return ret;
}
int set_memory_encrypted(unsigned long addr, int numpages)
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index d007591b8059..93e54ba91fbf 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -631,6 +631,8 @@ int pmdp_clear_flush_young(struct vm_area_struct *vma,
pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address,
pmd_t *pmdp)
{
+ VM_WARN_ON_ONCE(!pmd_present(*pmdp));
+
/*
* No flush is necessary. Once an invalid PTE is established, the PTE's
* access and dirty bits cannot be updated.
@@ -731,7 +733,7 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
return 0;
/* Bail out if we are we on a populated non-leaf entry: */
- if (pud_present(*pud) && !pud_huge(*pud))
+ if (pud_present(*pud) && !pud_leaf(*pud))
return 0;
set_pte((pte_t *)pud, pfn_pte(
@@ -760,7 +762,7 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
}
/* Bail out if we are we on a populated non-leaf entry: */
- if (pmd_present(*pmd) && !pmd_huge(*pmd))
+ if (pmd_present(*pmd) && !pmd_leaf(*pmd))
return 0;
set_pte((pte_t *)pmd, pfn_pte(
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 59cbc94b6e69..d25d81c8ecc0 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -816,9 +816,10 @@ done:
static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
const u32 imm32_hi, const u32 imm32_lo)
{
+ u64 imm64 = ((u64)imm32_hi << 32) | (u32)imm32_lo;
u8 *prog = *pprog;
- if (is_uimm32(((u64)imm32_hi << 32) | (u32)imm32_lo)) {
+ if (is_uimm32(imm64)) {
/*
* For emitting plain u32, where sign bit must not be
* propagated LLVM tends to load imm64 over mov32
@@ -826,6 +827,8 @@ static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
* 'mov %eax, imm32' instead.
*/
emit_mov_imm32(&prog, false, dst_reg, imm32_lo);
+ } else if (is_simm32(imm64)) {
+ emit_mov_imm32(&prog, true, dst_reg, imm32_lo);
} else {
/* movabsq rax, imm64 */
EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
@@ -1169,6 +1172,54 @@ static int emit_atomic(u8 **pprog, u8 atomic_op,
return 0;
}
+static int emit_atomic_index(u8 **pprog, u8 atomic_op, u32 size,
+ u32 dst_reg, u32 src_reg, u32 index_reg, int off)
+{
+ u8 *prog = *pprog;
+
+ EMIT1(0xF0); /* lock prefix */
+ switch (size) {
+ case BPF_W:
+ EMIT1(add_3mod(0x40, dst_reg, src_reg, index_reg));
+ break;
+ case BPF_DW:
+ EMIT1(add_3mod(0x48, dst_reg, src_reg, index_reg));
+ break;
+ default:
+ pr_err("bpf_jit: 1 and 2 byte atomics are not supported\n");
+ return -EFAULT;
+ }
+
+ /* emit opcode */
+ switch (atomic_op) {
+ case BPF_ADD:
+ case BPF_AND:
+ case BPF_OR:
+ case BPF_XOR:
+ /* lock *(u32/u64*)(dst_reg + idx_reg + off) <op>= src_reg */
+ EMIT1(simple_alu_opcodes[atomic_op]);
+ break;
+ case BPF_ADD | BPF_FETCH:
+ /* src_reg = atomic_fetch_add(dst_reg + idx_reg + off, src_reg); */
+ EMIT2(0x0F, 0xC1);
+ break;
+ case BPF_XCHG:
+ /* src_reg = atomic_xchg(dst_reg + idx_reg + off, src_reg); */
+ EMIT1(0x87);
+ break;
+ case BPF_CMPXCHG:
+ /* r0 = atomic_cmpxchg(dst_reg + idx_reg + off, r0, src_reg); */
+ EMIT2(0x0F, 0xB1);
+ break;
+ default:
+ pr_err("bpf_jit: unknown atomic opcode %02x\n", atomic_op);
+ return -EFAULT;
+ }
+ emit_insn_suffix_SIB(&prog, dst_reg, src_reg, index_reg, off);
+ *pprog = prog;
+ return 0;
+}
+
#define DONT_CLEAR 1
bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs)
@@ -1183,13 +1234,11 @@ bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs)
}
static void detect_reg_usage(struct bpf_insn *insn, int insn_cnt,
- bool *regs_used, bool *tail_call_seen)
+ bool *regs_used)
{
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)
@@ -1273,7 +1322,6 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
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];
u64 arena_vm_start, user_vm_start;
@@ -1285,11 +1333,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
arena_vm_start = bpf_arena_get_kern_vm_start(bpf_prog->aux->arena);
user_vm_start = bpf_arena_get_user_vm_start(bpf_prog->aux->arena);
- 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;
+ detect_reg_usage(insn, insn_cnt, callee_regs_used);
emit_prologue(&prog, bpf_prog->aux->stack_depth,
bpf_prog_was_classic(bpf_prog), tail_call_reachable,
@@ -1351,8 +1395,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
break;
case BPF_ALU64 | BPF_MOV | BPF_X:
- if (insn->off == BPF_ADDR_SPACE_CAST &&
- insn->imm == 1U << 16) {
+ if (insn_is_cast_user(insn)) {
if (dst_reg != src_reg)
/* 32-bit mov */
emit_mov_reg(&prog, false, dst_reg, src_reg);
@@ -1383,6 +1426,16 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
maybe_emit_mod(&prog, AUX_REG, dst_reg, true);
EMIT3(0x0F, 0x44, add_2reg(0xC0, AUX_REG, dst_reg));
break;
+ } else if (insn_is_mov_percpu_addr(insn)) {
+ /* mov <dst>, <src> (if necessary) */
+ EMIT_mov(dst_reg, src_reg);
+#ifdef CONFIG_SMP
+ /* add <dst>, gs:[<off>] */
+ EMIT2(0x65, add_1mod(0x48, dst_reg));
+ EMIT3(0x03, add_2reg(0x04, 0, dst_reg), 0x25);
+ EMIT((u32)(unsigned long)&this_cpu_off, 4);
+#endif
+ break;
}
fallthrough;
case BPF_ALU | BPF_MOV | BPF_X:
@@ -1963,6 +2016,15 @@ populate_extable:
return err;
break;
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_W:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_DW:
+ start_of_ldx = prog;
+ err = emit_atomic_index(&prog, insn->imm, BPF_SIZE(insn->code),
+ dst_reg, src_reg, X86_REG_R12, insn->off);
+ if (err)
+ return err;
+ goto populate_extable;
+
/* call */
case BPF_JMP | BPF_CALL: {
u8 *ip = image + addrs[i - 1];
@@ -2994,12 +3056,9 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
bpf_prog_pack_free(image, size);
}
-void arch_protect_bpf_trampoline(void *image, unsigned int size)
-{
-}
-
-void arch_unprotect_bpf_trampoline(void *image, unsigned int size)
+int arch_protect_bpf_trampoline(void *image, unsigned int size)
{
+ return 0;
}
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end,
@@ -3297,7 +3356,7 @@ out_image:
*
* Both cases are serious bugs and justify WARN_ON.
*/
- if (WARN_ON(bpf_jit_binary_pack_finalize(prog, header, rw_header))) {
+ if (WARN_ON(bpf_jit_binary_pack_finalize(header, rw_header))) {
/* header has been freed */
header = NULL;
goto out_image;
@@ -3359,6 +3418,11 @@ bool bpf_jit_supports_subprog_tailcalls(void)
return true;
}
+bool bpf_jit_supports_percpu_insn(void)
+{
+ return true;
+}
+
void bpf_jit_free(struct bpf_prog *prog)
{
if (prog->jited) {
@@ -3371,7 +3435,7 @@ void bpf_jit_free(struct bpf_prog *prog)
* before freeing it.
*/
if (jit_data) {
- bpf_jit_binary_pack_finalize(prog, jit_data->header,
+ bpf_jit_binary_pack_finalize(jit_data->header,
jit_data->rw_header);
kvfree(jit_data->addrs);
kfree(jit_data);
@@ -3462,6 +3526,21 @@ bool bpf_jit_supports_arena(void)
return true;
}
+bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
+{
+ if (!in_arena)
+ return true;
+ switch (insn->code) {
+ case BPF_STX | BPF_ATOMIC | BPF_W:
+ case BPF_STX | BPF_ATOMIC | BPF_DW:
+ if (insn->imm == (BPF_AND | BPF_FETCH) ||
+ insn->imm == (BPF_OR | BPF_FETCH) ||
+ insn->imm == (BPF_XOR | BPF_FETCH))
+ return false;
+ }
+ return true;
+}
+
bool bpf_jit_supports_ptr_xchg(void)
{
return true;
diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c
index c10083a8e68e..de0f9e5f9f73 100644
--- a/arch/x86/net/bpf_jit_comp32.c
+++ b/arch/x86/net/bpf_jit_comp32.c
@@ -2600,8 +2600,7 @@ out_image:
if (bpf_jit_enable > 1)
bpf_jit_dump(prog->len, proglen, pass + 1, image);
- if (image) {
- bpf_jit_binary_lock_ro(header);
+ if (image && !bpf_jit_binary_lock_ro(header)) {
prog->bpf_func = (void *)image;
prog->jited = 1;
prog->jited_len = proglen;
diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 87313701f069..f5dbd25651e0 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -35,12 +35,6 @@ struct sim_dev_reg {
struct sim_reg sim_reg;
};
-struct sim_reg_op {
- void (*init)(struct sim_dev_reg *reg);
- void (*read)(struct sim_dev_reg *reg, u32 value);
- void (*write)(struct sim_dev_reg *reg, u32 value);
-};
-
#define MB (1024 * 1024)
#define KB (1024)
#define SIZE_TO_MASK(size) (~(size - 1))
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c
index 8edd62206604..b433b1753016 100644
--- a/arch/x86/pci/intel_mid_pci.c
+++ b/arch/x86/pci/intel_mid_pci.c
@@ -216,7 +216,7 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
}
static const struct x86_cpu_id intel_mid_cpu_ids[] = {
- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, NULL),
+ X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, NULL),
{}
};
@@ -233,9 +233,9 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
return 0;
ret = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
- if (ret < 0) {
+ if (ret) {
dev_warn(&dev->dev, "Failed to read interrupt line: %d\n", ret);
- return ret;
+ return pcibios_err_to_errno(ret);
}
id = x86_match_cpu(intel_mid_cpu_ids);
@@ -243,7 +243,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
model = id->model;
switch (model) {
- case INTEL_FAM6_ATOM_SILVERMONT_MID:
+ case VFM_MODEL(INTEL_ATOM_SILVERMONT_MID):
polarity_low = false;
/* Special treatment for IRQ0 */
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 0cc9520666ef..39255f0eb14d 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -518,7 +518,34 @@ static bool __ref pci_mmcfg_reserved(struct device *dev,
{
struct resource *conflict;
- if (!early && !acpi_disabled) {
+ if (early) {
+
+ /*
+ * Don't try to do this check unless configuration type 1
+ * is available. How about type 2?
+ */
+
+ /*
+ * 946f2ee5c731 ("Check that MCFG points to an e820
+ * reserved area") added this E820 check in 2006 to work
+ * around BIOS defects.
+ *
+ * Per PCI Firmware r3.3, sec 4.1.2, ECAM space must be
+ * reserved by a PNP0C02 resource, but it need not be
+ * mentioned in E820. Before the ACPI interpreter is
+ * available, we can't check for PNP0C02 resources, so
+ * there's no reliable way to verify the region in this
+ * early check. Keep it only for the old machines that
+ * motivated 946f2ee5c731.
+ */
+ if (dmi_get_bios_year() < 2016 && raw_pci_ops)
+ return is_mmconf_reserved(e820__mapped_all, cfg, dev,
+ "E820 entry");
+
+ return true;
+ }
+
+ if (!acpi_disabled) {
if (is_mmconf_reserved(is_acpi_reserved, cfg, dev,
"ACPI motherboard resource"))
return true;
@@ -551,16 +578,7 @@ static bool __ref pci_mmcfg_reserved(struct device *dev,
* For MCFG information constructed from hotpluggable host bridge's
* _CBA method, just assume it's reserved.
*/
- if (pci_mmcfg_running_state)
- return true;
-
- /* Don't try to do this check unless configuration
- type 1 is available. how about type 2 ?*/
- if (raw_pci_ops)
- return is_mmconf_reserved(e820__mapped_all, cfg, dev,
- "E820 entry");
-
- return false;
+ return pci_mmcfg_running_state;
}
static void __init pci_mmcfg_reject_broken(int early)
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c
index f3aab76e357a..4b18c6404363 100644
--- a/arch/x86/pci/olpc.c
+++ b/arch/x86/pci/olpc.c
@@ -154,9 +154,6 @@ static const uint32_t ehci_hdr[] = { /* dev f function 4 - devfn = 7d */
0x0, 0x40, 0x0, 0x40a, /* CapPtr INT-D, IRQA */
0xc8020001, 0x0, 0x0, 0x0, /* Capabilities - 40 is R/O, 44 is
mask 8103 (power control) */
-#if 0
- 0x1, 0x40080000, 0x0, 0x0, /* EECP - see EHCI spec section 2.1.7 */
-#endif
0x01000001, 0x0, 0x0, 0x0, /* EECP - see EHCI spec section 2.1.7 */
0x2020, 0x0, 0x0, 0x0, /* (EHCI page 8) 60 SBRN (R/O),
61 FLADJ (R/W), PORTWAKECAP */
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 652cd53e77f6..0f2fe524f60d 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -38,10 +38,10 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev)
u8 gsi;
rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
- if (rc < 0) {
+ if (rc) {
dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n",
rc);
- return rc;
+ return pcibios_err_to_errno(rc);
}
/* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/
pirq = gsi;
diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c
index 6b9c6deca8ba..44c30ce6360a 100644
--- a/arch/x86/platform/atom/punit_atom_debug.c
+++ b/arch/x86/platform/atom/punit_atom_debug.c
@@ -165,14 +165,13 @@ static void punit_s2idle_check_register(struct punit_device *punit_device) {}
static void punit_s2idle_check_unregister(void) {}
#endif
-#define X86_MATCH(model, data) \
- X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
- X86_FEATURE_MWAIT, data)
+#define X86_MATCH(vfm, data) \
+ X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_MWAIT, data)
static const struct x86_cpu_id intel_punit_cpu_ids[] = {
- X86_MATCH(ATOM_SILVERMONT, &punit_device_byt),
- X86_MATCH(ATOM_SILVERMONT_MID, &punit_device_tng),
- X86_MATCH(ATOM_AIRMONT, &punit_device_cht),
+ X86_MATCH(INTEL_ATOM_SILVERMONT, &punit_device_byt),
+ X86_MATCH(INTEL_ATOM_SILVERMONT_MID, &punit_device_tng),
+ X86_MATCH(INTEL_ATOM_AIRMONT, &punit_device_cht),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_punit_cpu_ids);
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index f32451bdcfdd..f8126821a94d 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -139,7 +139,6 @@ void __init x86_ce4100_early_setup(void)
x86_init.resources.probe_roms = x86_init_noop;
x86_init.mpparse.find_mptable = x86_init_noop;
x86_init.mpparse.early_parse_smp_cfg = x86_init_noop;
- x86_init.mpparse.parse_smp_cfg = x86_dtb_parse_smp_config;
x86_init.pci.init = ce4100_pci_init;
x86_init.pci.init_irq = sdv_pci_init;
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
index 543df9a1379d..500cab4a7f7c 100644
--- a/arch/x86/platform/efi/Makefile
+++ b/arch/x86/platform/efi/Makefile
@@ -5,5 +5,4 @@ GCOV_PROFILE := n
obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \
efi_stub_$(BITS).o
obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o
-obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f090ec972d7b..88a96816de9a 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -226,8 +226,6 @@ int __init efi_memblock_x86_reserve_range(void)
if (add_efi_memmap || do_efi_soft_reserve())
do_add_efi_memmap();
- efi_fake_memmap_early();
-
WARN(efi.memmap.desc_version != 1,
"Unexpected EFI_MEMORY_DESCRIPTOR version %ld",
efi.memmap.desc_version);
diff --git a/arch/x86/platform/efi/fake_mem.c b/arch/x86/platform/efi/fake_mem.c
deleted file mode 100644
index 41d57cad3d84..000000000000
--- a/arch/x86/platform/efi/fake_mem.c
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * fake_mem.c
- *
- * Copyright (C) 2015 FUJITSU LIMITED
- * Author: Taku Izumi <izumi.taku@jp.fujitsu.com>
- *
- * This code introduces new boot option named "efi_fake_mem"
- * By specifying this parameter, you can add arbitrary attribute to
- * specific memory range by updating original (firmware provided) EFI
- * memmap.
- */
-
-#include <linux/kernel.h>
-#include <linux/efi.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/types.h>
-#include <linux/sort.h>
-#include <asm/e820/api.h>
-#include <asm/efi.h>
-
-#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM
-
-static struct efi_mem_range efi_fake_mems[EFI_MAX_FAKEMEM];
-static int nr_fake_mem;
-
-static int __init cmp_fake_mem(const void *x1, const void *x2)
-{
- const struct efi_mem_range *m1 = x1;
- const struct efi_mem_range *m2 = x2;
-
- if (m1->range.start < m2->range.start)
- return -1;
- if (m1->range.start > m2->range.start)
- return 1;
- return 0;
-}
-
-static void __init efi_fake_range(struct efi_mem_range *efi_range)
-{
- struct efi_memory_map_data data = { 0 };
- int new_nr_map = efi.memmap.nr_map;
- efi_memory_desc_t *md;
- void *new_memmap;
-
- /* count up the number of EFI memory descriptor */
- for_each_efi_memory_desc(md)
- new_nr_map += efi_memmap_split_count(md, &efi_range->range);
-
- /* allocate memory for new EFI memmap */
- if (efi_memmap_alloc(new_nr_map, &data) != 0)
- return;
-
- /* create new EFI memmap */
- new_memmap = early_memremap(data.phys_map, data.size);
- if (!new_memmap) {
- __efi_memmap_free(data.phys_map, data.size, data.flags);
- return;
- }
-
- efi_memmap_insert(&efi.memmap, new_memmap, efi_range);
-
- /* swap into new EFI memmap */
- early_memunmap(new_memmap, data.size);
-
- efi_memmap_install(&data);
-}
-
-void __init efi_fake_memmap(void)
-{
- int i;
-
- if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem)
- return;
-
- for (i = 0; i < nr_fake_mem; i++)
- efi_fake_range(&efi_fake_mems[i]);
-
- /* print new EFI memmap */
- efi_print_memmap();
-}
-
-static int __init setup_fake_mem(char *p)
-{
- u64 start = 0, mem_size = 0, attribute = 0;
- int i;
-
- if (!p)
- return -EINVAL;
-
- while (*p != '\0') {
- mem_size = memparse(p, &p);
- if (*p == '@')
- start = memparse(p+1, &p);
- else
- break;
-
- if (*p == ':')
- attribute = simple_strtoull(p+1, &p, 0);
- else
- break;
-
- if (nr_fake_mem >= EFI_MAX_FAKEMEM)
- break;
-
- efi_fake_mems[nr_fake_mem].range.start = start;
- efi_fake_mems[nr_fake_mem].range.end = start + mem_size - 1;
- efi_fake_mems[nr_fake_mem].attribute = attribute;
- nr_fake_mem++;
-
- if (*p == ',')
- p++;
- }
-
- sort(efi_fake_mems, nr_fake_mem, sizeof(struct efi_mem_range),
- cmp_fake_mem, NULL);
-
- for (i = 0; i < nr_fake_mem; i++)
- pr_info("efi_fake_mem: add attr=0x%016llx to [mem 0x%016llx-0x%016llx]",
- efi_fake_mems[i].attribute, efi_fake_mems[i].range.start,
- efi_fake_mems[i].range.end);
-
- return *p == '\0' ? 0 : -EINVAL;
-}
-
-early_param("efi_fake_mem", setup_fake_mem);
-
-void __init efi_fake_memmap_early(void)
-{
- int i;
-
- /*
- * The late efi_fake_mem() call can handle all requests if
- * EFI_MEMORY_SP support is disabled.
- */
- if (!efi_soft_reserve_enabled())
- return;
-
- if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem)
- return;
-
- /*
- * Given that efi_fake_memmap() needs to perform memblock
- * allocations it needs to run after e820__memblock_setup().
- * However, if efi_fake_mem specifies EFI_MEMORY_SP for a given
- * address range that potentially needs to mark the memory as
- * reserved prior to e820__memblock_setup(). Update e820
- * directly if EFI_MEMORY_SP is specified for an
- * EFI_CONVENTIONAL_MEMORY descriptor.
- */
- for (i = 0; i < nr_fake_mem; i++) {
- struct efi_mem_range *mem = &efi_fake_mems[i];
- efi_memory_desc_t *md;
- u64 m_start, m_end;
-
- if ((mem->attribute & EFI_MEMORY_SP) == 0)
- continue;
-
- m_start = mem->range.start;
- m_end = mem->range.end;
- for_each_efi_memory_desc(md) {
- u64 start, end, size;
-
- if (md->type != EFI_CONVENTIONAL_MEMORY)
- continue;
-
- start = md->phys_addr;
- end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
-
- if (m_start <= end && m_end >= start)
- /* fake range overlaps descriptor */;
- else
- continue;
-
- /*
- * Trim the boundary of the e820 update to the
- * descriptor in case the fake range overlaps
- * !EFI_CONVENTIONAL_MEMORY
- */
- start = max(start, m_start);
- end = min(end, m_end);
- size = end - start + 1;
-
- if (end <= start)
- continue;
-
- /*
- * Ensure each efi_fake_mem instance results in
- * a unique e820 resource
- */
- e820__range_remove(start, size, E820_TYPE_RAM, 1);
- e820__range_add(start, size, E820_TYPE_SOFT_RESERVED);
- e820__update_table(e820_table);
- }
- }
-}
diff --git a/arch/x86/platform/efi/memmap.c b/arch/x86/platform/efi/memmap.c
index 4ef20b49eb5e..061b8ecc71a1 100644
--- a/arch/x86/platform/efi/memmap.c
+++ b/arch/x86/platform/efi/memmap.c
@@ -30,6 +30,7 @@ static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
return PFN_PHYS(page_to_pfn(p));
}
+static
void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags)
{
if (flags & EFI_MEMMAP_MEMBLOCK) {
@@ -92,12 +93,22 @@ int __init efi_memmap_alloc(unsigned int num_entries,
*/
int __init efi_memmap_install(struct efi_memory_map_data *data)
{
+ unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map;
+ unsigned long flags = efi.memmap.flags;
+ u64 phys = efi.memmap.phys_map;
+ int ret;
+
efi_memmap_unmap();
if (efi_enabled(EFI_PARAVIRT))
return 0;
- return __efi_memmap_init(data);
+ ret = __efi_memmap_init(data);
+ if (ret)
+ return ret;
+
+ __efi_memmap_free(phys, size, flags);
+ return 0;
}
/**
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 7be71c2cdc83..f83bbe0acd4a 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -22,6 +22,7 @@
#include <asm/mpspec_def.h>
#include <asm/hw_irq.h>
#include <asm/apic.h>
+#include <asm/cpu_device_id.h>
#include <asm/io_apic.h>
#include <asm/intel-mid.h>
#include <asm/io.h>
@@ -55,9 +56,8 @@ static void __init intel_mid_time_init(void)
static void intel_mid_arch_setup(void)
{
- switch (boot_cpu_data.x86_model) {
- case 0x3C:
- case 0x4A:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_ATOM_SILVERMONT_MID:
x86_platform.legacy.rtc = 1;
break;
default:
diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c
index fdd49d70b437..c81cea208c2c 100644
--- a/arch/x86/platform/intel/iosf_mbi.c
+++ b/arch/x86/platform/intel/iosf_mbi.c
@@ -62,7 +62,7 @@ static int iosf_mbi_pci_read_mdr(u32 mcrx, u32 mcr, u32 *mdr)
fail_read:
dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
- return result;
+ return pcibios_err_to_errno(result);
}
static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
@@ -91,7 +91,7 @@ static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
fail_write:
dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
- return result;
+ return pcibios_err_to_errno(result);
}
int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)
diff --git a/arch/x86/platform/iris/iris.c b/arch/x86/platform/iris/iris.c
index b42bfdab01a9..c5f3bbdbdcfe 100644
--- a/arch/x86/platform/iris/iris.c
+++ b/arch/x86/platform/iris/iris.c
@@ -62,11 +62,10 @@ static int iris_probe(struct platform_device *pdev)
return 0;
}
-static int iris_remove(struct platform_device *pdev)
+static void iris_remove(struct platform_device *pdev)
{
pm_power_off = old_pm_power_off;
printk(KERN_INFO "Iris power_off handler uninstalled.\n");
- return 0;
}
static struct platform_driver iris_driver = {
@@ -74,7 +73,7 @@ static struct platform_driver iris_driver = {
.name = "iris",
},
.probe = iris_probe,
- .remove = iris_remove,
+ .remove_new = iris_remove,
};
static struct resource iris_resources[] = {
diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c
index f067ac780ba7..6a9c42de74e7 100644
--- a/arch/x86/platform/olpc/olpc-xo1-pm.c
+++ b/arch/x86/platform/olpc/olpc-xo1-pm.c
@@ -144,7 +144,7 @@ static int xo1_pm_probe(struct platform_device *pdev)
return 0;
}
-static int xo1_pm_remove(struct platform_device *pdev)
+static void xo1_pm_remove(struct platform_device *pdev)
{
if (strcmp(pdev->name, "cs5535-pms") == 0)
pms_base = 0;
@@ -152,7 +152,6 @@ static int xo1_pm_remove(struct platform_device *pdev)
acpi_base = 0;
pm_power_off = NULL;
- return 0;
}
static struct platform_driver cs5535_pms_driver = {
@@ -160,7 +159,7 @@ static struct platform_driver cs5535_pms_driver = {
.name = "cs5535-pms",
},
.probe = xo1_pm_probe,
- .remove = xo1_pm_remove,
+ .remove_new = xo1_pm_remove,
};
static struct platform_driver cs5535_acpi_driver = {
@@ -168,7 +167,7 @@ static struct platform_driver cs5535_acpi_driver = {
.name = "olpc-xo1-pm-acpi",
},
.probe = xo1_pm_probe,
- .remove = xo1_pm_remove,
+ .remove_new = xo1_pm_remove,
};
static int __init xo1_pm_init(void)
diff --git a/arch/x86/platform/olpc/olpc-xo1-sci.c b/arch/x86/platform/olpc/olpc-xo1-sci.c
index 89f25af4b3c3..46d42ff6e18a 100644
--- a/arch/x86/platform/olpc/olpc-xo1-sci.c
+++ b/arch/x86/platform/olpc/olpc-xo1-sci.c
@@ -598,7 +598,7 @@ err_ebook:
return r;
}
-static int xo1_sci_remove(struct platform_device *pdev)
+static void xo1_sci_remove(struct platform_device *pdev)
{
free_irq(sci_irq, pdev);
cancel_work_sync(&sci_work);
@@ -608,7 +608,6 @@ static int xo1_sci_remove(struct platform_device *pdev)
free_ebook_switch();
free_power_button();
acpi_base = 0;
- return 0;
}
static struct platform_driver xo1_sci_driver = {
@@ -617,7 +616,7 @@ static struct platform_driver xo1_sci_driver = {
.dev_groups = lid_groups,
},
.probe = xo1_sci_probe,
- .remove = xo1_sci_remove,
+ .remove_new = xo1_sci_remove,
.suspend = xo1_sci_suspend,
.resume = xo1_sci_resume,
};
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index bc31863c5ee6..ebdfd7b84feb 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-OBJECT_FILES_NON_STANDARD := y
purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string.o
@@ -30,19 +29,12 @@ LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
targets += purgatory.ro purgatory.chk
-# Sanitizer, etc. runtimes are unavailable and cannot be linked here.
-GCOV_PROFILE := n
-KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
-KCSAN_SANITIZE := n
-KMSAN_SANITIZE := n
-KCOV_INSTRUMENT := n
-
# These are adjustments to the compiler flags used for objects that
# make up the standalone purgatory.ro
PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
-PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0
+PURGATORY_CFLAGS := -mcmodel=small -ffreestanding -fno-zero-initialized-in-bss -g0
+PURGATORY_CFLAGS += -fpic -fvisibility=hidden
PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
PURGATORY_CFLAGS += -fno-stack-protector
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile
index f614009d3e4e..a0fb39abc5c8 100644
--- a/arch/x86/realmode/rm/Makefile
+++ b/arch/x86/realmode/rm/Makefile
@@ -7,15 +7,6 @@
#
#
-# Sanitizer runtimes are unavailable and cannot be linked here.
-KASAN_SANITIZE := n
-KCSAN_SANITIZE := n
-KMSAN_SANITIZE := n
-OBJECT_FILES_NON_STANDARD := y
-
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-
always-y := realmode.bin realmode.relocs
wakeup-objs := wakeup_asm.o wakemain.o video-mode.o
@@ -76,5 +67,3 @@ KBUILD_CFLAGS := $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \
-I$(srctree)/arch/x86/boot
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
-GCOV_PROFILE := n
-UBSAN_SANITIZE := n
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
index af38469afd14..5770c8097f32 100644
--- a/arch/x86/tools/gen-insn-attr-x86.awk
+++ b/arch/x86/tools/gen-insn-attr-x86.awk
@@ -64,7 +64,9 @@ BEGIN {
modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
force64_expr = "\\([df]64\\)"
- rex_expr = "^REX(\\.[XRWB]+)*"
+ rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))"
+ rex2_expr = "\\(REX2\\)"
+ no_rex2_expr = "\\(!REX2\\)"
fpu_expr = "^ESC" # TODO
lprefix1_expr = "\\((66|!F3)\\)"
@@ -81,6 +83,8 @@ BEGIN {
vexonly_expr = "\\(v\\)"
# All opcodes with (ev) superscript supports *only* EVEX prefix
evexonly_expr = "\\(ev\\)"
+ # (es) is the same as (ev) but also "SCALABLE" i.e. W and pp determine operand size
+ evex_scalable_expr = "\\(es\\)"
prefix_expr = "\\(Prefix\\)"
prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -99,6 +103,7 @@ BEGIN {
prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
prefix_num["EVEX"] = "INAT_PFX_EVEX"
+ prefix_num["REX2"] = "INAT_PFX_REX2"
clear_vars()
}
@@ -314,6 +319,10 @@ function convert_operands(count,opnd, i,j,imm,mod)
if (match(ext, force64_expr))
flags = add_flags(flags, "INAT_FORCE64")
+ # check REX2 not allowed
+ if (match(ext, no_rex2_expr))
+ flags = add_flags(flags, "INAT_NO_REX2")
+
# check REX prefix
if (match(opcode, rex_expr))
flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
@@ -325,6 +334,8 @@ function convert_operands(count,opnd, i,j,imm,mod)
# check VEX codes
if (match(ext, evexonly_expr))
flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
+ else if (match(ext, evex_scalable_expr))
+ flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY | INAT_EVEX_SCALABLE")
else if (match(ext, vexonly_expr))
flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
@@ -351,6 +362,8 @@ function convert_operands(count,opnd, i,j,imm,mod)
lptable3[idx] = add_flags(lptable3[idx],flags)
variant = "INAT_VARIANT"
}
+ if (match(ext, rex2_expr))
+ table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT")
if (!match(ext, lprefix_expr)){
table[idx] = add_flags(table[idx],flags)
}
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index b029fb81ebee..c101bed61940 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -11,41 +11,42 @@
#define Elf_Shdr ElfW(Shdr)
#define Elf_Sym ElfW(Sym)
-static Elf_Ehdr ehdr;
-static unsigned long shnum;
-static unsigned int shstrndx;
-static unsigned int shsymtabndx;
-static unsigned int shxsymtabndx;
+static Elf_Ehdr ehdr;
+static unsigned long shnum;
+static unsigned int shstrndx;
+static unsigned int shsymtabndx;
+static unsigned int shxsymtabndx;
static int sym_index(Elf_Sym *sym);
struct relocs {
- uint32_t *offset;
- unsigned long count;
- unsigned long size;
+ uint32_t *offset;
+ unsigned long count;
+ unsigned long size;
};
-static struct relocs relocs16;
-static struct relocs relocs32;
+static struct relocs relocs16;
+static struct relocs relocs32;
+
#if ELF_BITS == 64
-static struct relocs relocs32neg;
-static struct relocs relocs64;
-#define FMT PRIu64
+static struct relocs relocs32neg;
+static struct relocs relocs64;
+# define FMT PRIu64
#else
-#define FMT PRIu32
+# define FMT PRIu32
#endif
struct section {
- Elf_Shdr shdr;
- struct section *link;
- Elf_Sym *symtab;
- Elf32_Word *xsymtab;
- Elf_Rel *reltab;
- char *strtab;
+ Elf_Shdr shdr;
+ struct section *link;
+ Elf_Sym *symtab;
+ Elf32_Word *xsymtab;
+ Elf_Rel *reltab;
+ char *strtab;
};
-static struct section *secs;
+static struct section *secs;
-static const char * const sym_regex_kernel[S_NSYMTYPES] = {
+static const char * const sym_regex_kernel[S_NSYMTYPES] = {
/*
* Following symbols have been audited. There values are constant and do
* not change if bzImage is loaded at a different physical address than
@@ -115,13 +116,13 @@ static const char * const sym_regex_realmode[S_NSYMTYPES] = {
"^pa_",
};
-static const char * const *sym_regex;
+static const char * const *sym_regex;
+
+static regex_t sym_regex_c[S_NSYMTYPES];
-static regex_t sym_regex_c[S_NSYMTYPES];
static int is_reloc(enum symtype type, const char *sym_name)
{
- return sym_regex[type] &&
- !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
+ return sym_regex[type] && !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
}
static void regex_init(int use_real_mode)
@@ -139,8 +140,7 @@ static void regex_init(int use_real_mode)
if (!sym_regex[i])
continue;
- err = regcomp(&sym_regex_c[i], sym_regex[i],
- REG_EXTENDED|REG_NOSUB);
+ err = regcomp(&sym_regex_c[i], sym_regex[i], REG_EXTENDED|REG_NOSUB);
if (err) {
regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
@@ -163,9 +163,10 @@ static const char *sym_type(unsigned type)
#undef SYM_TYPE
};
const char *name = "unknown sym type name";
- if (type < ARRAY_SIZE(type_name)) {
+
+ if (type < ARRAY_SIZE(type_name))
name = type_name[type];
- }
+
return name;
}
@@ -179,9 +180,10 @@ static const char *sym_bind(unsigned bind)
#undef SYM_BIND
};
const char *name = "unknown sym bind name";
- if (bind < ARRAY_SIZE(bind_name)) {
+
+ if (bind < ARRAY_SIZE(bind_name))
name = bind_name[bind];
- }
+
return name;
}
@@ -196,9 +198,10 @@ static const char *sym_visibility(unsigned visibility)
#undef SYM_VISIBILITY
};
const char *name = "unknown sym visibility name";
- if (visibility < ARRAY_SIZE(visibility_name)) {
+
+ if (visibility < ARRAY_SIZE(visibility_name))
name = visibility_name[visibility];
- }
+
return name;
}
@@ -244,9 +247,10 @@ static const char *rel_type(unsigned type)
#undef REL_TYPE
};
const char *name = "unknown type rel type name";
- if (type < ARRAY_SIZE(type_name) && type_name[type]) {
+
+ if (type < ARRAY_SIZE(type_name) && type_name[type])
name = type_name[type];
- }
+
return name;
}
@@ -256,15 +260,14 @@ static const char *sec_name(unsigned shndx)
const char *name;
sec_strtab = secs[shstrndx].strtab;
name = "<noname>";
- if (shndx < shnum) {
+
+ if (shndx < shnum)
name = sec_strtab + secs[shndx].shdr.sh_name;
- }
- else if (shndx == SHN_ABS) {
+ else if (shndx == SHN_ABS)
name = "ABSOLUTE";
- }
- else if (shndx == SHN_COMMON) {
+ else if (shndx == SHN_COMMON)
name = "COMMON";
- }
+
return name;
}
@@ -272,18 +275,19 @@ static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
{
const char *name;
name = "<noname>";
- if (sym->st_name) {
+
+ if (sym->st_name)
name = sym_strtab + sym->st_name;
- }
- else {
+ else
name = sec_name(sym_index(sym));
- }
+
return name;
}
static Elf_Sym *sym_lookup(const char *symname)
{
int i;
+
for (i = 0; i < shnum; i++) {
struct section *sec = &secs[i];
long nsyms;
@@ -309,14 +313,15 @@ static Elf_Sym *sym_lookup(const char *symname)
}
#if BYTE_ORDER == LITTLE_ENDIAN
-#define le16_to_cpu(val) (val)
-#define le32_to_cpu(val) (val)
-#define le64_to_cpu(val) (val)
+# define le16_to_cpu(val) (val)
+# define le32_to_cpu(val) (val)
+# define le64_to_cpu(val) (val)
#endif
+
#if BYTE_ORDER == BIG_ENDIAN
-#define le16_to_cpu(val) bswap_16(val)
-#define le32_to_cpu(val) bswap_32(val)
-#define le64_to_cpu(val) bswap_64(val)
+# define le16_to_cpu(val) bswap_16(val)
+# define le32_to_cpu(val) bswap_32(val)
+# define le64_to_cpu(val) bswap_64(val)
#endif
static uint16_t elf16_to_cpu(uint16_t val)
@@ -337,13 +342,13 @@ static uint64_t elf64_to_cpu(uint64_t val)
{
return le64_to_cpu(val);
}
-#define elf_addr_to_cpu(x) elf64_to_cpu(x)
-#define elf_off_to_cpu(x) elf64_to_cpu(x)
-#define elf_xword_to_cpu(x) elf64_to_cpu(x)
+# define elf_addr_to_cpu(x) elf64_to_cpu(x)
+# define elf_off_to_cpu(x) elf64_to_cpu(x)
+# define elf_xword_to_cpu(x) elf64_to_cpu(x)
#else
-#define elf_addr_to_cpu(x) elf32_to_cpu(x)
-#define elf_off_to_cpu(x) elf32_to_cpu(x)
-#define elf_xword_to_cpu(x) elf32_to_cpu(x)
+# define elf_addr_to_cpu(x) elf32_to_cpu(x)
+# define elf_off_to_cpu(x) elf32_to_cpu(x)
+# define elf_xword_to_cpu(x) elf32_to_cpu(x)
#endif
static int sym_index(Elf_Sym *sym)
@@ -365,22 +370,17 @@ static int sym_index(Elf_Sym *sym)
static void read_ehdr(FILE *fp)
{
- if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
- die("Cannot read ELF header: %s\n",
- strerror(errno));
- }
- if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
+ if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
+ die("Cannot read ELF header: %s\n", strerror(errno));
+ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
die("No ELF magic\n");
- }
- if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) {
+ if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
die("Not a %d bit executable\n", ELF_BITS);
- }
- if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
+ if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
die("Not a LSB ELF executable\n");
- }
- if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
+ if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
die("Unknown ELF version\n");
- }
+
/* Convert the fields to native endian */
ehdr.e_type = elf_half_to_cpu(ehdr.e_type);
ehdr.e_machine = elf_half_to_cpu(ehdr.e_machine);
@@ -439,19 +439,18 @@ static void read_shdrs(FILE *fp)
Elf_Shdr shdr;
secs = calloc(shnum, sizeof(struct section));
- if (!secs) {
- die("Unable to allocate %ld section headers\n",
- shnum);
- }
- if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
- die("Seek to %" FMT " failed: %s\n",
- ehdr.e_shoff, strerror(errno));
- }
+ if (!secs)
+ die("Unable to allocate %ld section headers\n", shnum);
+
+ if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
+ die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));
+
for (i = 0; i < shnum; i++) {
struct section *sec = &secs[i];
+
if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
- die("Cannot read ELF section headers %d/%ld: %s\n",
- i, shnum, strerror(errno));
+ die("Cannot read ELF section headers %d/%ld: %s\n", i, shnum, strerror(errno));
+
sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name);
sec->shdr.sh_type = elf_word_to_cpu(shdr.sh_type);
sec->shdr.sh_flags = elf_xword_to_cpu(shdr.sh_flags);
@@ -471,31 +470,28 @@ static void read_shdrs(FILE *fp)
static void read_strtabs(FILE *fp)
{
int i;
+
for (i = 0; i < shnum; i++) {
struct section *sec = &secs[i];
- if (sec->shdr.sh_type != SHT_STRTAB) {
+
+ if (sec->shdr.sh_type != SHT_STRTAB)
continue;
- }
+
sec->strtab = malloc(sec->shdr.sh_size);
- if (!sec->strtab) {
- die("malloc of %" FMT " bytes for strtab failed\n",
- sec->shdr.sh_size);
- }
- if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
- die("Seek to %" FMT " failed: %s\n",
- sec->shdr.sh_offset, strerror(errno));
- }
- if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
- != sec->shdr.sh_size) {
- die("Cannot read symbol table: %s\n",
- strerror(errno));
- }
+ if (!sec->strtab)
+ die("malloc of %" FMT " bytes for strtab failed\n", sec->shdr.sh_size);
+
+ if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
+ die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
+
+ if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
+ die("Cannot read symbol table: %s\n", strerror(errno));
}
}
static void read_symtabs(FILE *fp)
{
- int i,j;
+ int i, j;
for (i = 0; i < shnum; i++) {
struct section *sec = &secs[i];
@@ -504,19 +500,15 @@ static void read_symtabs(FILE *fp)
switch (sec->shdr.sh_type) {
case SHT_SYMTAB_SHNDX:
sec->xsymtab = malloc(sec->shdr.sh_size);
- if (!sec->xsymtab) {
- die("malloc of %" FMT " bytes for xsymtab failed\n",
- sec->shdr.sh_size);
- }
- if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
- die("Seek to %" FMT " failed: %s\n",
- sec->shdr.sh_offset, strerror(errno));
- }
- if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp)
- != sec->shdr.sh_size) {
- die("Cannot read extended symbol table: %s\n",
- strerror(errno));
- }
+ if (!sec->xsymtab)
+ die("malloc of %" FMT " bytes for xsymtab failed\n", sec->shdr.sh_size);
+
+ if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
+ die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
+
+ if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
+ die("Cannot read extended symbol table: %s\n", strerror(errno));
+
shxsymtabndx = i;
continue;
@@ -524,19 +516,15 @@ static void read_symtabs(FILE *fp)
num_syms = sec->shdr.sh_size / sizeof(Elf_Sym);
sec->symtab = malloc(sec->shdr.sh_size);
- if (!sec->symtab) {
- die("malloc of %" FMT " bytes for symtab failed\n",
- sec->shdr.sh_size);
- }
- if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
- die("Seek to %" FMT " failed: %s\n",
- sec->shdr.sh_offset, strerror(errno));
- }
- if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
- != sec->shdr.sh_size) {
- die("Cannot read symbol table: %s\n",
- strerror(errno));
- }
+ if (!sec->symtab)
+ die("malloc of %" FMT " bytes for symtab failed\n", sec->shdr.sh_size);
+
+ if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
+ die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
+
+ if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
+ die("Cannot read symbol table: %s\n", strerror(errno));
+
for (j = 0; j < num_syms; j++) {
Elf_Sym *sym = &sec->symtab[j];
@@ -557,28 +545,27 @@ static void read_symtabs(FILE *fp)
static void read_relocs(FILE *fp)
{
- int i,j;
+ int i, j;
+
for (i = 0; i < shnum; i++) {
struct section *sec = &secs[i];
- if (sec->shdr.sh_type != SHT_REL_TYPE) {
+
+ if (sec->shdr.sh_type != SHT_REL_TYPE)
continue;
- }
+
sec->reltab = malloc(sec->shdr.sh_size);
- if (!sec->reltab) {
- die("malloc of %" FMT " bytes for relocs failed\n",
- sec->shdr.sh_size);
- }
- if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
- die("Seek to %" FMT " failed: %s\n",
- sec->shdr.sh_offset, strerror(errno));
- }
- if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
- != sec->shdr.sh_size) {
- die("Cannot read symbol table: %s\n",
- strerror(errno));
- }
+ if (!sec->reltab)
+ die("malloc of %" FMT " bytes for relocs failed\n", sec->shdr.sh_size);
+
+ if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
+ die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
+
+ if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
+ die("Cannot read symbol table: %s\n", strerror(errno));
+
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
Elf_Rel *rel = &sec->reltab[j];
+
rel->r_offset = elf_addr_to_cpu(rel->r_offset);
rel->r_info = elf_xword_to_cpu(rel->r_info);
#if (SHT_REL_TYPE == SHT_RELA)
@@ -601,23 +588,27 @@ static void print_absolute_symbols(void)
printf("Absolute symbols\n");
printf(" Num: Value Size Type Bind Visibility Name\n");
+
for (i = 0; i < shnum; i++) {
struct section *sec = &secs[i];
char *sym_strtab;
int j;
- if (sec->shdr.sh_type != SHT_SYMTAB) {
+ if (sec->shdr.sh_type != SHT_SYMTAB)
continue;
- }
+
sym_strtab = sec->link->strtab;
+
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
Elf_Sym *sym;
const char *name;
+
sym = &sec->symtab[j];
name = sym_name(sym_strtab, sym);
- if (sym->st_shndx != SHN_ABS) {
+
+ if (sym->st_shndx != SHN_ABS)
continue;
- }
+
printf(format,
j, sym->st_value, sym->st_size,
sym_type(ELF_ST_TYPE(sym->st_info)),
@@ -645,34 +636,37 @@ static void print_absolute_relocs(void)
char *sym_strtab;
Elf_Sym *sh_symtab;
int j;
- if (sec->shdr.sh_type != SHT_REL_TYPE) {
+
+ if (sec->shdr.sh_type != SHT_REL_TYPE)
continue;
- }
+
sec_symtab = sec->link;
sec_applies = &secs[sec->shdr.sh_info];
- if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+ if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
continue;
- }
+
/*
* Do not perform relocations in .notes section; any
* values there are meant for pre-boot consumption (e.g.
* startup_xen).
*/
- if (sec_applies->shdr.sh_type == SHT_NOTE) {
+ if (sec_applies->shdr.sh_type == SHT_NOTE)
continue;
- }
+
sh_symtab = sec_symtab->symtab;
sym_strtab = sec_symtab->link->strtab;
+
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
Elf_Rel *rel;
Elf_Sym *sym;
const char *name;
+
rel = &sec->reltab[j];
sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
name = sym_name(sym_strtab, sym);
- if (sym->st_shndx != SHN_ABS) {
+
+ if (sym->st_shndx != SHN_ABS)
continue;
- }
/* Absolute symbols are not relocated if bzImage is
* loaded at a non-compiled address. Display a warning
@@ -691,10 +685,8 @@ static void print_absolute_relocs(void)
continue;
if (!printed) {
- printf("WARNING: Absolute relocations"
- " present\n");
- printf("Offset Info Type Sym.Value "
- "Sym.Name\n");
+ printf("WARNING: Absolute relocations present\n");
+ printf("Offset Info Type Sym.Value Sym.Name\n");
printed = 1;
}
@@ -718,8 +710,8 @@ static void add_reloc(struct relocs *r, uint32_t offset)
void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
if (!mem)
- die("realloc of %ld entries for relocs failed\n",
- newsize);
+ die("realloc of %ld entries for relocs failed\n", newsize);
+
r->offset = mem;
r->size = newsize;
}
@@ -730,6 +722,7 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
Elf_Sym *sym, const char *symname))
{
int i;
+
/* Walk through the relocations */
for (i = 0; i < shnum; i++) {
char *sym_strtab;
@@ -738,16 +731,25 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
int j;
struct section *sec = &secs[i];
- if (sec->shdr.sh_type != SHT_REL_TYPE) {
+ if (sec->shdr.sh_type != SHT_REL_TYPE)
continue;
- }
+
sec_symtab = sec->link;
sec_applies = &secs[sec->shdr.sh_info];
- if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+ if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
continue;
- }
+
+ /*
+ * Do not perform relocations in .notes sections; any
+ * values there are meant for pre-boot consumption (e.g.
+ * startup_xen).
+ */
+ if (sec_applies->shdr.sh_type == SHT_NOTE)
+ continue;
+
sh_symtab = sec_symtab->symtab;
sym_strtab = sec_symtab->link->strtab;
+
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
Elf_Rel *rel = &sec->reltab[j];
Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
@@ -781,14 +783,16 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
* kernel data and does not require special treatment.
*
*/
-static int per_cpu_shndx = -1;
+static int per_cpu_shndx = -1;
static Elf_Addr per_cpu_load_addr;
static void percpu_init(void)
{
int i;
+
for (i = 0; i < shnum; i++) {
ElfW(Sym) *sym;
+
if (strcmp(sec_name(i), ".data..percpu"))
continue;
@@ -801,6 +805,7 @@ static void percpu_init(void)
per_cpu_shndx = i;
per_cpu_load_addr = sym->st_value;
+
return;
}
}
@@ -871,8 +876,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
* Only used by jump labels
*/
if (is_percpu_sym(sym, symname))
- die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
- symname);
+ die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n", symname);
break;
case R_X86_64_32:
@@ -892,8 +896,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
if (is_reloc(S_ABS, symname))
break;
- die("Invalid absolute %s relocation: %s\n",
- rel_type(r_type), symname);
+ die("Invalid absolute %s relocation: %s\n", rel_type(r_type), symname);
break;
}
@@ -913,8 +916,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
break;
default:
- die("Unsupported relocation type: %s (%d)\n",
- rel_type(r_type), r_type);
+ die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
break;
}
@@ -951,8 +953,7 @@ static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
if (is_reloc(S_ABS, symname))
break;
- die("Invalid absolute %s relocation: %s\n",
- rel_type(r_type), symname);
+ die("Invalid absolute %s relocation: %s\n", rel_type(r_type), symname);
break;
}
@@ -960,16 +961,14 @@ static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
break;
default:
- die("Unsupported relocation type: %s (%d)\n",
- rel_type(r_type), r_type);
+ die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
break;
}
return 0;
}
-static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
- const char *symname)
+static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname)
{
unsigned r_type = ELF32_R_TYPE(rel->r_info);
int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
@@ -1004,9 +1003,7 @@ static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
if (!is_reloc(S_LIN, symname))
break;
}
- die("Invalid %s %s relocation: %s\n",
- shn_abs ? "absolute" : "relative",
- rel_type(r_type), symname);
+ die("Invalid %s %s relocation: %s\n", shn_abs ? "absolute" : "relative", rel_type(r_type), symname);
break;
case R_386_32:
@@ -1027,14 +1024,11 @@ static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
add_reloc(&relocs32, rel->r_offset);
break;
}
- die("Invalid %s %s relocation: %s\n",
- shn_abs ? "absolute" : "relative",
- rel_type(r_type), symname);
+ die("Invalid %s %s relocation: %s\n", shn_abs ? "absolute" : "relative", rel_type(r_type), symname);
break;
default:
- die("Unsupported relocation type: %s (%d)\n",
- rel_type(r_type), r_type);
+ die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
break;
}
@@ -1046,7 +1040,10 @@ static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
static int cmp_relocs(const void *va, const void *vb)
{
const uint32_t *a, *b;
- a = va; b = vb;
+
+ a = va;
+ b = vb;
+
return (*a == *b)? 0 : (*a > *b)? 1 : -1;
}
@@ -1060,6 +1057,7 @@ static int write32(uint32_t v, FILE *f)
unsigned char buf[4];
put_unaligned_le32(v, buf);
+
return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
}
@@ -1072,8 +1070,7 @@ static void emit_relocs(int as_text, int use_real_mode)
{
int i;
int (*write_reloc)(uint32_t, FILE *) = write32;
- int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
- const char *symname);
+ int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname);
#if ELF_BITS == 64
if (!use_real_mode)
@@ -1160,6 +1157,7 @@ static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
rel_type(ELF_R_TYPE(rel->r_info)),
symname,
sec_name(sym_index(sym)));
+
return 0;
}
@@ -1185,19 +1183,24 @@ void process(FILE *fp, int use_real_mode, int as_text,
read_strtabs(fp);
read_symtabs(fp);
read_relocs(fp);
+
if (ELF_BITS == 64)
percpu_init();
+
if (show_absolute_syms) {
print_absolute_symbols();
return;
}
+
if (show_absolute_relocs) {
print_absolute_relocs();
return;
}
+
if (show_reloc_info) {
print_reloc_info();
return;
}
+
emit_relocs(as_text, use_real_mode);
}
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
index 8bc72a51b257..36e67fc97c22 100644
--- a/arch/x86/um/Makefile
+++ b/arch/x86/um/Makefile
@@ -9,9 +9,9 @@ else
BITS := 64
endif
-obj-y = bugs_$(BITS).o delay.o fault.o ldt.o \
+obj-y = bugs_$(BITS).o delay.o fault.o \
ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \
- stub_$(BITS).o stub_segv.o \
+ stub_segv.o \
sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \
mem_$(BITS).o subarch.o os-Linux/
@@ -31,7 +31,6 @@ obj-y += syscalls_64.o vdso/
subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o \
../lib/memmove_64.o ../lib/memset_64.o
-subarch-$(CONFIG_PREEMPTION) += ../entry/thunk_64.o
endif
diff --git a/arch/x86/um/asm/mm_context.h b/arch/x86/um/asm/mm_context.h
deleted file mode 100644
index dc32dc023c2f..000000000000
--- a/arch/x86/um/asm/mm_context.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
- * Licensed under the GPL
- *
- * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
- */
-
-#ifndef __ASM_LDT_H
-#define __ASM_LDT_H
-
-#include <linux/mutex.h>
-#include <asm/ldt.h>
-
-#define LDT_PAGES_MAX \
- ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
-#define LDT_ENTRIES_PER_PAGE \
- (PAGE_SIZE/LDT_ENTRY_SIZE)
-#define LDT_DIRECT_ENTRIES \
- ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
-
-struct ldt_entry {
- __u32 a;
- __u32 b;
-};
-
-typedef struct uml_ldt {
- int entry_count;
- struct mutex lock;
- union {
- struct ldt_entry * pages[LDT_PAGES_MAX];
- struct ldt_entry entries[LDT_DIRECT_ENTRIES];
- } u;
-} uml_ldt_t;
-
-#define LDT_entry_a(info) \
- ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
-
-#define LDT_entry_b(info) \
- (((info)->base_addr & 0xff000000) | \
- (((info)->base_addr & 0x00ff0000) >> 16) | \
- ((info)->limit & 0xf0000) | \
- (((info)->read_exec_only ^ 1) << 9) | \
- ((info)->contents << 10) | \
- (((info)->seg_not_present ^ 1) << 15) | \
- ((info)->seg_32bit << 22) | \
- ((info)->limit_in_pages << 23) | \
- ((info)->useable << 20) | \
- 0x7000)
-
-#define _LDT_empty(info) (\
- (info)->base_addr == 0 && \
- (info)->limit == 0 && \
- (info)->contents == 0 && \
- (info)->read_exec_only == 1 && \
- (info)->seg_32bit == 0 && \
- (info)->limit_in_pages == 0 && \
- (info)->seg_not_present == 1 && \
- (info)->useable == 0 )
-
-#ifdef CONFIG_X86_64
-#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0))
-#else
-#define LDT_empty(info) (_LDT_empty(info))
-#endif
-
-struct uml_arch_mm_context {
- uml_ldt_t ldt;
-};
-
-#endif
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index 83822fd42204..2fef3da55533 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -54,6 +54,8 @@ extern int ptrace_get_thread_area(struct task_struct *child, int idx,
extern int ptrace_set_thread_area(struct task_struct *child, int idx,
struct user_desc __user *user_desc);
+extern int arch_switch_tls(struct task_struct *to);
+
#else
#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
@@ -83,5 +85,9 @@ extern long arch_prctl(struct task_struct *task, int option,
unsigned long __user *addr);
#endif
+
#define user_stack_pointer(regs) PT_REGS_SP(regs)
+
+extern void arch_switch_to(struct task_struct *to);
+
#endif /* __UM_X86_PTRACE_H */
diff --git a/arch/x86/um/bugs_32.c b/arch/x86/um/bugs_32.c
index 33daff4dade4..d29929efcc07 100644
--- a/arch/x86/um/bugs_32.c
+++ b/arch/x86/um/bugs_32.c
@@ -3,6 +3,7 @@
* Licensed under the GPL
*/
+#include <arch.h>
#include <signal.h>
#include <kern_util.h>
#include <longjmp.h>
diff --git a/arch/x86/um/bugs_64.c b/arch/x86/um/bugs_64.c
index 8cc8256c698d..b01295e8a676 100644
--- a/arch/x86/um/bugs_64.c
+++ b/arch/x86/um/bugs_64.c
@@ -4,6 +4,7 @@
* Licensed under the GPL
*/
+#include <arch.h>
#include <sysdep/ptrace.h>
void arch_check_bugs(void)
diff --git a/arch/x86/um/elfcore.c b/arch/x86/um/elfcore.c
index 650cdbbdaf45..ef50662fc40d 100644
--- a/arch/x86/um/elfcore.c
+++ b/arch/x86/um/elfcore.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/elf.h>
+#include <linux/elfcore.h>
#include <linux/coredump.h>
#include <linux/fs.h>
#include <linux/mm.h>
diff --git a/arch/x86/um/fault.c b/arch/x86/um/fault.c
index 84ac7f7b0257..0dde4d613a87 100644
--- a/arch/x86/um/fault.c
+++ b/arch/x86/um/fault.c
@@ -3,6 +3,7 @@
* Licensed under the GPL
*/
+#include <arch.h>
#include <sysdep/ptrace.h>
/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c
deleted file mode 100644
index 255a44dd415a..000000000000
--- a/arch/x86/um/ldt.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/uaccess.h>
-#include <asm/unistd.h>
-#include <os.h>
-#include <skas.h>
-#include <sysdep/tls.h>
-
-static inline int modify_ldt (int func, void *ptr, unsigned long bytecount)
-{
- return syscall(__NR_modify_ldt, func, ptr, bytecount);
-}
-
-static long write_ldt_entry(struct mm_id *mm_idp, int func,
- struct user_desc *desc, void **addr, int done)
-{
- long res;
- void *stub_addr;
-
- BUILD_BUG_ON(sizeof(*desc) % sizeof(long));
-
- res = syscall_stub_data(mm_idp, (unsigned long *)desc,
- sizeof(*desc) / sizeof(long),
- addr, &stub_addr);
- if (!res) {
- unsigned long args[] = { func,
- (unsigned long)stub_addr,
- sizeof(*desc),
- 0, 0, 0 };
- res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
- 0, addr, done);
- }
-
- return res;
-}
-
-/*
- * In skas mode, we hold our own ldt data in UML.
- * Thus, the code implementing sys_modify_ldt_skas
- * is very similar to (and mostly stolen from) sys_modify_ldt
- * for arch/i386/kernel/ldt.c
- * The routines copied and modified in part are:
- * - read_ldt
- * - read_default_ldt
- * - write_ldt
- * - sys_modify_ldt_skas
- */
-
-static int read_ldt(void __user * ptr, unsigned long bytecount)
-{
- int i, err = 0;
- unsigned long size;
- uml_ldt_t *ldt = &current->mm->context.arch.ldt;
-
- if (!ldt->entry_count)
- goto out;
- if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
- bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
- err = bytecount;
-
- mutex_lock(&ldt->lock);
- if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
- size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
- if (size > bytecount)
- size = bytecount;
- if (copy_to_user(ptr, ldt->u.entries, size))
- err = -EFAULT;
- bytecount -= size;
- ptr += size;
- }
- else {
- for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
- i++) {
- size = PAGE_SIZE;
- if (size > bytecount)
- size = bytecount;
- if (copy_to_user(ptr, ldt->u.pages[i], size)) {
- err = -EFAULT;
- break;
- }
- bytecount -= size;
- ptr += size;
- }
- }
- mutex_unlock(&ldt->lock);
-
- if (bytecount == 0 || err == -EFAULT)
- goto out;
-
- if (clear_user(ptr, bytecount))
- err = -EFAULT;
-
-out:
- return err;
-}
-
-static int read_default_ldt(void __user * ptr, unsigned long bytecount)
-{
- int err;
-
- if (bytecount > 5*LDT_ENTRY_SIZE)
- bytecount = 5*LDT_ENTRY_SIZE;
-
- err = bytecount;
- /*
- * UML doesn't support lcall7 and lcall27.
- * So, we don't really have a default ldt, but emulate
- * an empty ldt of common host default ldt size.
- */
- if (clear_user(ptr, bytecount))
- err = -EFAULT;
-
- return err;
-}
-
-static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
-{
- uml_ldt_t *ldt = &current->mm->context.arch.ldt;
- struct mm_id * mm_idp = &current->mm->context.id;
- int i, err;
- struct user_desc ldt_info;
- struct ldt_entry entry0, *ldt_p;
- void *addr = NULL;
-
- err = -EINVAL;
- if (bytecount != sizeof(ldt_info))
- goto out;
- err = -EFAULT;
- if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
- goto out;
-
- err = -EINVAL;
- if (ldt_info.entry_number >= LDT_ENTRIES)
- goto out;
- if (ldt_info.contents == 3) {
- if (func == 1)
- goto out;
- if (ldt_info.seg_not_present == 0)
- goto out;
- }
-
- mutex_lock(&ldt->lock);
-
- err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
- if (err)
- goto out_unlock;
-
- if (ldt_info.entry_number >= ldt->entry_count &&
- ldt_info.entry_number >= LDT_DIRECT_ENTRIES) {
- for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
- i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
- i++) {
- if (i == 0)
- memcpy(&entry0, ldt->u.entries,
- sizeof(entry0));
- ldt->u.pages[i] = (struct ldt_entry *)
- __get_free_page(GFP_KERNEL|__GFP_ZERO);
- if (!ldt->u.pages[i]) {
- err = -ENOMEM;
- /* Undo the change in host */
- memset(&ldt_info, 0, sizeof(ldt_info));
- write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
- goto out_unlock;
- }
- if (i == 0) {
- memcpy(ldt->u.pages[0], &entry0,
- sizeof(entry0));
- memcpy(ldt->u.pages[0]+1, ldt->u.entries+1,
- sizeof(entry0)*(LDT_DIRECT_ENTRIES-1));
- }
- ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
- }
- }
- if (ldt->entry_count <= ldt_info.entry_number)
- ldt->entry_count = ldt_info.entry_number + 1;
-
- if (ldt->entry_count <= LDT_DIRECT_ENTRIES)
- ldt_p = ldt->u.entries + ldt_info.entry_number;
- else
- ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
- ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
-
- if (ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
- (func == 1 || LDT_empty(&ldt_info))) {
- ldt_p->a = 0;
- ldt_p->b = 0;
- }
- else{
- if (func == 1)
- ldt_info.useable = 0;
- ldt_p->a = LDT_entry_a(&ldt_info);
- ldt_p->b = LDT_entry_b(&ldt_info);
- }
- err = 0;
-
-out_unlock:
- mutex_unlock(&ldt->lock);
-out:
- return err;
-}
-
-static long do_modify_ldt_skas(int func, void __user *ptr,
- unsigned long bytecount)
-{
- int ret = -ENOSYS;
-
- switch (func) {
- case 0:
- ret = read_ldt(ptr, bytecount);
- break;
- case 1:
- case 0x11:
- ret = write_ldt(ptr, bytecount, func);
- break;
- case 2:
- ret = read_default_ldt(ptr, bytecount);
- break;
- }
- return ret;
-}
-
-static DEFINE_SPINLOCK(host_ldt_lock);
-static short dummy_list[9] = {0, -1};
-static short * host_ldt_entries = NULL;
-
-static void ldt_get_host_info(void)
-{
- long ret;
- struct ldt_entry * ldt;
- short *tmp;
- int i, size, k, order;
-
- spin_lock(&host_ldt_lock);
-
- if (host_ldt_entries != NULL) {
- spin_unlock(&host_ldt_lock);
- return;
- }
- host_ldt_entries = dummy_list+1;
-
- spin_unlock(&host_ldt_lock);
-
- for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++)
- ;
-
- ldt = (struct ldt_entry *)
- __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
- if (ldt == NULL) {
- printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer "
- "for host ldt\n");
- return;
- }
-
- ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
- if (ret < 0) {
- printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n");
- goto out_free;
- }
- if (ret == 0) {
- /* default_ldt is active, simply write an empty entry 0 */
- host_ldt_entries = dummy_list;
- goto out_free;
- }
-
- for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) {
- if (ldt[i].a != 0 || ldt[i].b != 0)
- size++;
- }
-
- if (size < ARRAY_SIZE(dummy_list))
- host_ldt_entries = dummy_list;
- else {
- size = (size + 1) * sizeof(dummy_list[0]);
- tmp = kmalloc(size, GFP_KERNEL);
- if (tmp == NULL) {
- printk(KERN_ERR "ldt_get_host_info: couldn't allocate "
- "host ldt list\n");
- goto out_free;
- }
- host_ldt_entries = tmp;
- }
-
- for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) {
- if (ldt[i].a != 0 || ldt[i].b != 0)
- host_ldt_entries[k++] = i;
- }
- host_ldt_entries[k] = -1;
-
-out_free:
- free_pages((unsigned long)ldt, order);
-}
-
-long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
-{
- struct user_desc desc;
- short * num_p;
- int i;
- long page, err=0;
- void *addr = NULL;
-
-
- mutex_init(&new_mm->arch.ldt.lock);
-
- if (!from_mm) {
- memset(&desc, 0, sizeof(desc));
- /*
- * Now we try to retrieve info about the ldt, we
- * inherited from the host. All ldt-entries found
- * will be reset in the following loop
- */
- ldt_get_host_info();
- for (num_p=host_ldt_entries; *num_p != -1; num_p++) {
- desc.entry_number = *num_p;
- err = write_ldt_entry(&new_mm->id, 1, &desc,
- &addr, *(num_p + 1) == -1);
- if (err)
- break;
- }
- new_mm->arch.ldt.entry_count = 0;
-
- goto out;
- }
-
- /*
- * Our local LDT is used to supply the data for
- * modify_ldt(READLDT), if PTRACE_LDT isn't available,
- * i.e., we have to use the stub for modify_ldt, which
- * can't handle the big read buffer of up to 64kB.
- */
- mutex_lock(&from_mm->arch.ldt.lock);
- if (from_mm->arch.ldt.entry_count <= LDT_DIRECT_ENTRIES)
- memcpy(new_mm->arch.ldt.u.entries, from_mm->arch.ldt.u.entries,
- sizeof(new_mm->arch.ldt.u.entries));
- else {
- i = from_mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE;
- while (i-->0) {
- page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
- if (!page) {
- err = -ENOMEM;
- break;
- }
- new_mm->arch.ldt.u.pages[i] =
- (struct ldt_entry *) page;
- memcpy(new_mm->arch.ldt.u.pages[i],
- from_mm->arch.ldt.u.pages[i], PAGE_SIZE);
- }
- }
- new_mm->arch.ldt.entry_count = from_mm->arch.ldt.entry_count;
- mutex_unlock(&from_mm->arch.ldt.lock);
-
- out:
- return err;
-}
-
-
-void free_ldt(struct mm_context *mm)
-{
- int i;
-
- if (mm->arch.ldt.entry_count > LDT_DIRECT_ENTRIES) {
- i = mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE;
- while (i-- > 0)
- free_page((long) mm->arch.ldt.u.pages[i]);
- }
- mm->arch.ldt.entry_count = 0;
-}
-
-SYSCALL_DEFINE3(modify_ldt, int , func , void __user * , ptr ,
- unsigned long , bytecount)
-{
- /* See non-um modify_ldt() for why we do this cast */
- return (unsigned int)do_modify_ldt_skas(func, ptr, bytecount);
-}
diff --git a/arch/x86/um/os-Linux/mcontext.c b/arch/x86/um/os-Linux/mcontext.c
index 49c3744cac37..e80ab7d28117 100644
--- a/arch/x86/um/os-Linux/mcontext.c
+++ b/arch/x86/um/os-Linux/mcontext.c
@@ -3,6 +3,7 @@
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <sysdep/ptrace.h>
+#include <sysdep/mcontext.h>
void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
{
diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c
index df8f4b4bf98b..f3638dd09cec 100644
--- a/arch/x86/um/os-Linux/registers.c
+++ b/arch/x86/um/os-Linux/registers.c
@@ -17,7 +17,7 @@
#include <linux/elf.h>
#include <registers.h>
-int have_xstate_support;
+static int have_xstate_support;
int save_i387_registers(int pid, unsigned long *fp_regs)
{
diff --git a/arch/x86/um/os-Linux/tls.c b/arch/x86/um/os-Linux/tls.c
index 3e1b1bf6acbc..eed9efe29ade 100644
--- a/arch/x86/um/os-Linux/tls.c
+++ b/arch/x86/um/os-Linux/tls.c
@@ -6,6 +6,7 @@
#include <sys/syscall.h>
#include <unistd.h>
+#include <os.h>
#include <sysdep/tls.h>
#ifndef PTRACE_GET_THREAD_AREA
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index 7f1abde2c84b..b0a71c6cdc6e 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -10,8 +10,6 @@
#include <registers.h>
#include <skas.h>
-extern int arch_switch_tls(struct task_struct *to);
-
void arch_switch_to(struct task_struct *to)
{
int err = arch_switch_tls(to);
diff --git a/arch/x86/um/shared/sysdep/archsetjmp.h b/arch/x86/um/shared/sysdep/archsetjmp.h
index 166cedbab926..8c81d1a604a9 100644
--- a/arch/x86/um/shared/sysdep/archsetjmp.h
+++ b/arch/x86/um/shared/sysdep/archsetjmp.h
@@ -1,6 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __X86_UM_SYSDEP_ARCHSETJMP_H
+#define __X86_UM_SYSDEP_ARCHSETJMP_H
+
#ifdef __i386__
#include "archsetjmp_32.h"
#else
#include "archsetjmp_64.h"
#endif
+
+unsigned long get_thread_reg(int reg, jmp_buf *buf);
+
+#endif /* __X86_UM_SYSDEP_ARCHSETJMP_H */
diff --git a/arch/x86/um/shared/sysdep/kernel-offsets.h b/arch/x86/um/shared/sysdep/kernel-offsets.h
index a004bffb7b8d..48de3a71f845 100644
--- a/arch/x86/um/shared/sysdep/kernel-offsets.h
+++ b/arch/x86/um/shared/sysdep/kernel-offsets.h
@@ -6,6 +6,9 @@
#include <linux/kbuild.h>
#include <asm/mman.h>
+/* workaround for a warning with -Wmissing-prototypes */
+void foo(void);
+
void foo(void)
{
#include <common-offsets.h>
diff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h
index ce0ca46ad383..dc89f4423454 100644
--- a/arch/x86/um/shared/sysdep/stub.h
+++ b/arch/x86/um/shared/sysdep/stub.h
@@ -12,4 +12,4 @@
#endif
extern void stub_segv_handler(int, siginfo_t *, void *);
-extern void stub_clone_handler(void);
+extern void stub_syscall_handler(void);
diff --git a/arch/x86/um/shared/sysdep/stub_32.h b/arch/x86/um/shared/sysdep/stub_32.h
index ea8b5a2d67af..0b44a86dd346 100644
--- a/arch/x86/um/shared/sysdep/stub_32.h
+++ b/arch/x86/um/shared/sysdep/stub_32.h
@@ -6,6 +6,7 @@
#ifndef __SYSDEP_STUB_H
#define __SYSDEP_STUB_H
+#include <stddef.h>
#include <asm/ptrace.h>
#include <generated/asm-offsets.h>
@@ -79,33 +80,31 @@ static __always_inline long stub_syscall5(long syscall, long arg1, long arg2,
return ret;
}
-static __always_inline void trap_myself(void)
+static __always_inline long stub_syscall6(long syscall, long arg1, long arg2,
+ long arg3, long arg4, long arg5,
+ long arg6)
{
- __asm("int3");
+ struct syscall_args {
+ int ebx, ebp;
+ } args = { arg1, arg6 };
+ long ret;
+
+ __asm__ volatile ("pushl %%ebp;"
+ "movl 0x4(%%ebx),%%ebp;"
+ "movl (%%ebx),%%ebx;"
+ "int $0x80;"
+ "popl %%ebp"
+ : "=a" (ret)
+ : "0" (syscall), "b" (&args),
+ "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+ : "memory");
+
+ return ret;
}
-static __always_inline void remap_stack_and_trap(void)
+static __always_inline void trap_myself(void)
{
- __asm__ volatile (
- "movl %%esp,%%ebx ;"
- "andl %0,%%ebx ;"
- "movl %1,%%eax ;"
- "movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;"
- "movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;"
- "int $0x80 ;"
- "addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
- "int $3"
- : :
- "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
- "g" (STUB_MMAP_NR),
- "g" (UML_STUB_FIELD_FD),
- "g" (UML_STUB_FIELD_OFFSET),
- "g" (UML_STUB_FIELD_CHILD_ERR),
- "c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
- "d" (PROT_READ | PROT_WRITE),
- "S" (MAP_FIXED | MAP_SHARED)
- :
- "memory");
+ __asm("int3");
}
static __always_inline void *get_stub_data(void)
diff --git a/arch/x86/um/shared/sysdep/stub_64.h b/arch/x86/um/shared/sysdep/stub_64.h
index b24168ef0ac4..67f44284f1aa 100644
--- a/arch/x86/um/shared/sysdep/stub_64.h
+++ b/arch/x86/um/shared/sysdep/stub_64.h
@@ -6,6 +6,7 @@
#ifndef __SYSDEP_STUB_H
#define __SYSDEP_STUB_H
+#include <stddef.h>
#include <sysdep/ptrace_user.h>
#include <generated/asm-offsets.h>
#include <linux/stddef.h>
@@ -79,35 +80,25 @@ static __always_inline long stub_syscall5(long syscall, long arg1, long arg2,
return ret;
}
-static __always_inline void trap_myself(void)
+static __always_inline long stub_syscall6(long syscall, long arg1, long arg2,
+ long arg3, long arg4, long arg5,
+ long arg6)
{
- __asm("int3");
+ long ret;
+
+ __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; "
+ __syscall
+ : "=a" (ret)
+ : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+ "g" (arg4), "g" (arg5), "g" (arg6)
+ : __syscall_clobber, "r10", "r8", "r9");
+
+ return ret;
}
-static __always_inline void remap_stack_and_trap(void)
+static __always_inline void trap_myself(void)
{
- __asm__ volatile (
- "movq %0,%%rax ;"
- "movq %%rsp,%%rdi ;"
- "andq %1,%%rdi ;"
- "movq %2,%%r10 ;"
- "movq %%rdi,%%r8 ; addq %3,%%r8 ; movq (%%r8),%%r8 ;"
- "movq %%rdi,%%r9 ; addq %4,%%r9 ; movq (%%r9),%%r9 ;"
- __syscall ";"
- "movq %%rsp,%%rdi ; andq %1,%%rdi ;"
- "addq %5,%%rdi ; movq %%rax, (%%rdi) ;"
- "int3"
- : :
- "g" (STUB_MMAP_NR),
- "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
- "g" (MAP_FIXED | MAP_SHARED),
- "g" (UML_STUB_FIELD_FD),
- "g" (UML_STUB_FIELD_OFFSET),
- "g" (UML_STUB_FIELD_CHILD_ERR),
- "S" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
- "d" (PROT_READ | PROT_WRITE)
- :
- __syscall_clobber, "r10", "r8", "r9");
+ __asm("int3");
}
static __always_inline void *get_stub_data(void)
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index 263e1d08f216..2cc8c2309022 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -8,6 +8,7 @@
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/kernel.h>
+#include <linux/syscalls.h>
#include <asm/unistd.h>
#include <linux/uaccess.h>
#include <asm/ucontext.h>
@@ -155,7 +156,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
struct sigcontext __user *from)
{
struct sigcontext sc;
- int err, pid;
+ int err;
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
@@ -201,10 +202,10 @@ static int copy_sc_from_user(struct pt_regs *regs,
#undef GETREG
- pid = userspace_pid[current_thread_info()->cpu];
#ifdef CONFIG_X86_32
if (have_fpx_regs) {
struct user_fxsr_struct fpx;
+ int pid = userspace_pid[current_thread_info()->cpu];
err = copy_from_user(&fpx,
&((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0],
@@ -240,7 +241,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
{
struct sigcontext sc;
struct faultinfo * fi = &current->thread.arch.faultinfo;
- int err, pid;
+ int err;
memset(&sc, 0, sizeof(struct sigcontext));
#define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno]
@@ -288,10 +289,9 @@ static int copy_sc_to_user(struct sigcontext __user *to,
if (err)
return 1;
- pid = userspace_pid[current_thread_info()->cpu];
-
#ifdef CONFIG_X86_32
if (have_fpx_regs) {
+ int pid = userspace_pid[current_thread_info()->cpu];
struct user_fxsr_struct fpx;
err = save_fpx_registers(pid, (unsigned long *) &fpx);
@@ -450,7 +450,7 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
return 0;
}
-long sys_sigreturn(void)
+SYSCALL_DEFINE0(sigreturn)
{
unsigned long sp = PT_REGS_SP(&current->thread.regs);
struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
@@ -557,7 +557,7 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
}
#endif
-long sys_rt_sigreturn(void)
+SYSCALL_DEFINE0(rt_sigreturn)
{
unsigned long sp = PT_REGS_SP(&current->thread.regs);
struct rt_sigframe __user *frame =
diff --git a/arch/x86/um/stub_32.S b/arch/x86/um/stub_32.S
deleted file mode 100644
index 8291899e6aaf..000000000000
--- a/arch/x86/um/stub_32.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <as-layout.h>
-
-.section .__syscall_stub, "ax"
-
- .globl batch_syscall_stub
-batch_syscall_stub:
- /* %esp comes in as "top of page" */
- mov %esp, %ecx
- /* %esp has pointer to first operation */
- add $8, %esp
-again:
- /* load length of additional data */
- mov 0x0(%esp), %eax
-
- /* if(length == 0) : end of list */
- /* write possible 0 to header */
- mov %eax, 0x4(%ecx)
- cmpl $0, %eax
- jz done
-
- /* save current pointer */
- mov %esp, 0x4(%ecx)
-
- /* skip additional data */
- add %eax, %esp
-
- /* load syscall-# */
- pop %eax
-
- /* load syscall params */
- pop %ebx
- pop %ecx
- pop %edx
- pop %esi
- pop %edi
- pop %ebp
-
- /* execute syscall */
- int $0x80
-
- /* restore top of page pointer in %ecx */
- mov %esp, %ecx
- andl $(~UM_KERN_PAGE_SIZE) + 1, %ecx
-
- /* check return value */
- pop %ebx
- cmp %ebx, %eax
- je again
-
-done:
- /* save return value */
- mov %eax, (%ecx)
-
- /* stop */
- int3
diff --git a/arch/x86/um/stub_64.S b/arch/x86/um/stub_64.S
deleted file mode 100644
index f3404640197a..000000000000
--- a/arch/x86/um/stub_64.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <as-layout.h>
-
-.section .__syscall_stub, "ax"
- .globl batch_syscall_stub
-batch_syscall_stub:
- /* %rsp has the pointer to first operation */
- mov %rsp, %rbx
- add $0x10, %rsp
-again:
- /* load length of additional data */
- mov 0x0(%rsp), %rax
-
- /* if(length == 0) : end of list */
- /* write possible 0 to header */
- mov %rax, 8(%rbx)
- cmp $0, %rax
- jz done
-
- /* save current pointer */
- mov %rsp, 8(%rbx)
-
- /* skip additional data */
- add %rax, %rsp
-
- /* load syscall-# */
- pop %rax
-
- /* load syscall params */
- pop %rdi
- pop %rsi
- pop %rdx
- pop %r10
- pop %r8
- pop %r9
-
- /* execute syscall */
- syscall
-
- /* check return value */
- pop %rcx
- cmp %rcx, %rax
- je again
-
-done:
- /* save return value */
- mov %rax, (%rbx)
-
- /* stop */
- int3
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index 89df5d89d664..51655133eee3 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -9,6 +9,10 @@
#include <linux/cache.h>
#include <asm/syscall.h>
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
+
/*
* Below you can see, in terms of #define's, the differences between the x86-64
* and the UML syscall table.
@@ -22,15 +26,13 @@
#define sys_vm86 sys_ni_syscall
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+#define __SYSCALL_NORETURN __SYSCALL
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#include <asm/syscalls_32.h>
+#undef __SYSCALL
-#undef __SYSCALL
#define __SYSCALL(nr, sym) sym,
-
-extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
-
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
#include <asm/syscalls_32.h>
};
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
index b0b4cfd2308c..943d414f2109 100644
--- a/arch/x86/um/sys_call_table_64.c
+++ b/arch/x86/um/sys_call_table_64.c
@@ -9,6 +9,10 @@
#include <linux/cache.h>
#include <asm/syscall.h>
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
+
/*
* Below you can see, in terms of #define's, the differences between the x86-64
* and the UML syscall table.
@@ -18,14 +22,13 @@
#define sys_iopl sys_ni_syscall
#define sys_ioperm sys_ni_syscall
+#define __SYSCALL_NORETURN __SYSCALL
+
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#include <asm/syscalls_64.h>
+#undef __SYSCALL
-#undef __SYSCALL
#define __SYSCALL(nr, sym) sym,
-
-extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
-
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
#include <asm/syscalls_64.h>
};
diff --git a/arch/x86/um/tls_32.c b/arch/x86/um/tls_32.c
index 66162eafd8e8..fbb129023080 100644
--- a/arch/x86/um/tls_32.c
+++ b/arch/x86/um/tls_32.c
@@ -11,6 +11,7 @@
#include <os.h>
#include <skas.h>
#include <sysdep/tls.h>
+#include <asm/desc.h>
/*
* If needed we can detect when it's uninitialized.
@@ -20,7 +21,7 @@
static int host_supports_tls = -1;
int host_gdt_entry_tls_min;
-int do_set_thread_area(struct user_desc *info)
+static int do_set_thread_area(struct user_desc *info)
{
int ret;
u32 cpu;
@@ -36,22 +37,6 @@ int do_set_thread_area(struct user_desc *info)
return ret;
}
-int do_get_thread_area(struct user_desc *info)
-{
- int ret;
- u32 cpu;
-
- cpu = get_cpu();
- ret = os_get_thread_area(info, userspace_pid[cpu]);
- put_cpu();
-
- if (ret)
- printk(KERN_ERR "PTRACE_GET_THREAD_AREA failed, err = %d, "
- "index = %d\n", ret, info->entry_number);
-
- return ret;
-}
-
/*
* sys_get_thread_area: get a yet unused TLS descriptor index.
* XXX: Consider leaving one free slot for glibc usage at first place. This must
@@ -231,7 +216,6 @@ out:
return ret;
}
-/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */
static int get_tls_entry(struct task_struct *task, struct user_desc *info,
int idx)
{
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index e54a9814ccf1..1c77d9946199 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -14,6 +14,9 @@
COMMENT(#val " / sizeof(unsigned long)"); \
DEFINE(sym, val / sizeof(unsigned long))
+/* workaround for a warning with -Wmissing-prototypes */
+void foo(void);
+
void foo(void)
{
#ifdef __i386__
diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile
index b86d634730b2..6a77ea6434ff 100644
--- a/arch/x86/um/vdso/Makefile
+++ b/arch/x86/um/vdso/Makefile
@@ -3,12 +3,6 @@
# Building vDSO images for x86.
#
-# do not instrument on vdso because KASAN is not compatible with user mode
-KASAN_SANITIZE := n
-
-# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
-KCOV_INSTRUMENT := n
-
VDSO64-y := y
vdso-install-$(VDSO64-y) += vdso.so
@@ -63,7 +57,6 @@ quiet_cmd_vdso = VDSO $@
cmd_vdso = $(CC) -nostdlib -o $@ \
$(CC_FLAGS_LTO) $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
- sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
+ sh $(src)/checkundef.sh '$(NM)' '$@'
VDSO_LDFLAGS = -fPIC -shared -Wl,--hash-style=sysv -z noexecstack
-GCOV_PROFILE := n
diff --git a/arch/x86/um/vdso/um_vdso.c b/arch/x86/um/vdso/um_vdso.c
index ff0f3b4b6c45..cbae2584124f 100644
--- a/arch/x86/um/vdso/um_vdso.c
+++ b/arch/x86/um/vdso/um_vdso.c
@@ -13,6 +13,12 @@
#include <linux/getcpu.h>
#include <asm/unistd.h>
+/* workaround for -Wmissing-prototypes warnings */
+int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts);
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
+__kernel_old_time_t __vdso_time(__kernel_old_time_t *t);
+long __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused);
+
int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
{
long ret;
@@ -54,7 +60,7 @@ __kernel_old_time_t __vdso_time(__kernel_old_time_t *t)
__kernel_old_time_t time(__kernel_old_time_t *t) __attribute__((weak, alias("__vdso_time")));
long
-__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
+__vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused)
{
/*
* UML does not support SMP, we can cheat here. :)
@@ -68,5 +74,5 @@ __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
return 0;
}
-long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
+long getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *tcache)
__attribute__((weak, alias("__vdso_getcpu")));
diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile
index 5ebe48752ffc..dcfbe7a5912c 100644
--- a/arch/x86/video/Makefile
+++ b/arch/x86/video/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_FB_CORE) += fbdev.o
+
+obj-y += video-common.o
diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/video-common.c
index 1dd6528cc947..81fc97a2a837 100644
--- a/arch/x86/video/fbdev.c
+++ b/arch/x86/video/video-common.c
@@ -7,11 +7,11 @@
*
*/
-#include <linux/fb.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/vgaarb.h>
-#include <asm/fb.h>
+
+#include <asm/video.h>
pgprot_t pgprot_framebuffer(pgprot_t prot,
unsigned long vm_start, unsigned long vm_end,
@@ -25,20 +25,17 @@ pgprot_t pgprot_framebuffer(pgprot_t prot,
}
EXPORT_SYMBOL(pgprot_framebuffer);
-int fb_is_primary_device(struct fb_info *info)
+bool video_is_primary_device(struct device *dev)
{
- struct device *device = info->device;
- struct pci_dev *pci_dev;
+ struct pci_dev *pdev;
- if (!device || !dev_is_pci(device))
- return 0;
+ if (!dev_is_pci(dev))
+ return false;
- pci_dev = to_pci_dev(device);
+ pdev = to_pci_dev(dev);
- if (pci_dev == vga_default_device())
- return 1;
- return 0;
+ return (pdev == vga_default_device());
}
-EXPORT_SYMBOL(fb_is_primary_device);
+EXPORT_SYMBOL(video_is_primary_device);
MODULE_LICENSE("GPL");
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index 0ae10535c699..0ce17766c0e5 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -120,7 +120,7 @@ static __init void snp_enable(void *arg)
bool snp_probe_rmptable_info(void)
{
- u64 max_rmp_pfn, calc_rmp_sz, rmp_sz, rmp_base, rmp_end;
+ u64 rmp_sz, rmp_base, rmp_end;
rdmsrl(MSR_AMD64_RMP_BASE, rmp_base);
rdmsrl(MSR_AMD64_RMP_END, rmp_end);
@@ -137,28 +137,11 @@ bool snp_probe_rmptable_info(void)
rmp_sz = rmp_end - rmp_base + 1;
- /*
- * Calculate the amount the memory that must be reserved by the BIOS to
- * address the whole RAM, including the bookkeeping area. The RMP itself
- * must also be covered.
- */
- max_rmp_pfn = max_pfn;
- if (PHYS_PFN(rmp_end) > max_pfn)
- max_rmp_pfn = PHYS_PFN(rmp_end);
-
- calc_rmp_sz = (max_rmp_pfn << 4) + RMPTABLE_CPU_BOOKKEEPING_SZ;
-
- if (calc_rmp_sz > rmp_sz) {
- pr_err("Memory reserved for the RMP table does not cover full system RAM (expected 0x%llx got 0x%llx)\n",
- calc_rmp_sz, rmp_sz);
- return false;
- }
-
probed_rmp_base = rmp_base;
probed_rmp_size = rmp_sz;
pr_info("RMP table physical range [0x%016llx - 0x%016llx]\n",
- probed_rmp_base, probed_rmp_base + probed_rmp_size - 1);
+ rmp_base, rmp_end);
return true;
}
@@ -206,9 +189,8 @@ void __init snp_fixup_e820_tables(void)
*/
static int __init snp_rmptable_init(void)
{
+ u64 max_rmp_pfn, calc_rmp_sz, rmptable_size, rmp_end, val;
void *rmptable_start;
- u64 rmptable_size;
- u64 val;
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
return 0;
@@ -219,10 +201,28 @@ static int __init snp_rmptable_init(void)
if (!probed_rmp_size)
goto nosnp;
+ rmp_end = probed_rmp_base + probed_rmp_size - 1;
+
+ /*
+ * Calculate the amount the memory that must be reserved by the BIOS to
+ * address the whole RAM, including the bookkeeping area. The RMP itself
+ * must also be covered.
+ */
+ max_rmp_pfn = max_pfn;
+ if (PFN_UP(rmp_end) > max_pfn)
+ max_rmp_pfn = PFN_UP(rmp_end);
+
+ calc_rmp_sz = (max_rmp_pfn << 4) + RMPTABLE_CPU_BOOKKEEPING_SZ;
+ if (calc_rmp_sz > probed_rmp_size) {
+ pr_err("Memory reserved for the RMP table does not cover full system RAM (expected 0x%llx got 0x%llx)\n",
+ calc_rmp_sz, probed_rmp_size);
+ goto nosnp;
+ }
+
rmptable_start = memremap(probed_rmp_base, probed_rmp_size, MEMREMAP_WB);
if (!rmptable_start) {
pr_err("Failed to map RMP table\n");
- return 1;
+ goto nosnp;
}
/*
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 4d6826a76f78..4e2b2e2ac9f9 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -27,14 +27,13 @@
#include <linux/log2.h>
#include <linux/acpi.h>
#include <linux/suspend.h>
-#include <linux/acpi.h>
#include <asm/page.h>
#include <asm/special_insns.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
#include <asm/cpufeature.h>
#include <asm/tdx.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include <asm/processor.h>
#include <asm/mce.h>
#include "tdx.h"
@@ -1427,9 +1426,9 @@ static void __init check_tdx_erratum(void)
* private memory poisons that memory, and a subsequent read of
* that memory triggers #MC.
*/
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_SAPPHIRERAPIDS_X:
- case INTEL_FAM6_EMERALDRAPIDS_X:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_SAPPHIRERAPIDS_X:
+ case INTEL_EMERALDRAPIDS_X:
setup_force_cpu_bug(X86_BUG_TDX_PW_MCE);
}
}
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
index 8b045dd25196..bb0f3f368446 100644
--- a/arch/x86/xen/apic.c
+++ b/arch/x86/xen/apic.c
@@ -10,8 +10,6 @@
#include <xen/xen.h>
#include <xen/interface/physdev.h>
#include "xen-ops.h"
-#include "pmu.h"
-#include "smp.h"
static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
{
diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c
index 532410998684..b8c9f2a7d9b6 100644
--- a/arch/x86/xen/debugfs.c
+++ b/arch/x86/xen/debugfs.c
@@ -3,7 +3,7 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
-#include "debugfs.h"
+#include "xen-ops.h"
static struct dentry *d_xen_debug;
diff --git a/arch/x86/xen/debugfs.h b/arch/x86/xen/debugfs.h
deleted file mode 100644
index 6b813ad1091c..000000000000
--- a/arch/x86/xen/debugfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _XEN_DEBUGFS_H
-#define _XEN_DEBUGFS_H
-
-struct dentry * __init xen_init_debugfs(void);
-
-#endif /* _XEN_DEBUGFS_H */
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index a01ca255b0c6..84e5adbd0925 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1,8 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
-#include <linux/memblock.h>
-#endif
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/kexec.h>
@@ -23,8 +20,6 @@
#include <asm/setup.h>
#include "xen-ops.h"
-#include "smp.h"
-#include "pmu.h"
EXPORT_SYMBOL_GPL(hypercall_page);
@@ -382,3 +377,36 @@ void __init xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns)
memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
}
+
+#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
+int __init arch_xen_unpopulated_init(struct resource **res)
+{
+ unsigned int i;
+
+ if (!xen_domain())
+ return -ENODEV;
+
+ /* Must be set strictly before calling xen_free_unpopulated_pages(). */
+ *res = &iomem_resource;
+
+ /*
+ * Initialize with pages from the extra memory regions (see
+ * arch/x86/xen/setup.c).
+ */
+ for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
+ unsigned int j;
+
+ for (j = 0; j < xen_extra_mem[i].n_pfns; j++) {
+ struct page *pg =
+ pfn_to_page(xen_extra_mem[i].start_pfn + j);
+
+ xen_free_unpopulated_pages(1, &pg);
+ }
+
+ /* Zero so region is not also added to the balloon driver. */
+ xen_extra_mem[i].n_pfns = 0;
+ }
+
+ return 0;
+}
+#endif
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index c001a2296582..24d2957a4726 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -28,8 +28,6 @@
#include <asm/xen/page.h>
#include "xen-ops.h"
-#include "mmu.h"
-#include "smp.h"
static unsigned long shared_info_pfn;
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 9ba53814ed6a..2c12ae42dc8b 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -85,10 +85,6 @@
#endif
#include "xen-ops.h"
-#include "mmu.h"
-#include "smp.h"
-#include "multicalls.h"
-#include "pmu.h"
#include "../kernel/cpu/cpu.h" /* get_cpu_cap() */
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 60e9c37fd79f..c4c479373249 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -5,8 +5,7 @@
#include <asm/xen/hypercall.h>
#include <xen/interface/memory.h>
-#include "multicalls.h"
-#include "mmu.h"
+#include "xen-ops.h"
unsigned long arbitrary_virt_to_mfn(void *vaddr)
{
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
deleted file mode 100644
index 6e4c6bd62203..000000000000
--- a/arch/x86/xen/mmu.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _XEN_MMU_H
-
-#include <linux/linkage.h>
-#include <asm/page.h>
-
-enum pt_level {
- PT_PGD,
- PT_P4D,
- PT_PUD,
- PT_PMD,
- PT_PTE
-};
-
-
-bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
-
-void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
-
-pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
-void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
- pte_t *ptep, pte_t pte);
-
-unsigned long xen_read_cr2_direct(void);
-
-extern void xen_init_mmu_ops(void);
-extern void xen_hvm_init_mmu_ops(void);
-#endif /* _XEN_MMU_H */
diff --git a/arch/x86/xen/mmu_hvm.c b/arch/x86/xen/mmu_hvm.c
index 509bdee3ab90..337955652202 100644
--- a/arch/x86/xen/mmu_hvm.c
+++ b/arch/x86/xen/mmu_hvm.c
@@ -5,7 +5,7 @@
#include <xen/interface/xen.h>
#include <xen/hvm.h>
-#include "mmu.h"
+#include "xen-ops.h"
#ifdef CONFIG_PROC_VMCORE
/*
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 54e0d311dcc9..f1ce39d6d32c 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -82,9 +82,7 @@
#include <xen/hvc-console.h>
#include <xen/swiotlb-xen.h>
-#include "multicalls.h"
-#include "mmu.h"
-#include "debugfs.h"
+#include "xen-ops.h"
/*
* Prototypes for functions called via PV_CALLEE_SAVE_REGS_THUNK() in order
@@ -128,7 +126,7 @@ static DEFINE_SPINLOCK(xen_reservation_lock);
* looking at another vcpu's cr3 value, it should use this variable.
*/
DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */
-DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
+static DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
static phys_addr_t xen_pt_base, xen_pt_size __initdata;
@@ -305,16 +303,17 @@ static void xen_set_pte(pte_t *ptep, pte_t pteval)
__xen_set_pte(ptep, pteval);
}
-pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep)
+static pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
{
/* Just return the pte as-is. We preserve the bits on commit */
trace_xen_mmu_ptep_modify_prot_start(vma->vm_mm, addr, ptep, *ptep);
return *ptep;
}
-void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
- pte_t *ptep, pte_t pte)
+static void xen_ptep_modify_prot_commit(struct vm_area_struct *vma,
+ unsigned long addr,
+ pte_t *ptep, pte_t pte)
{
struct mmu_update u;
diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c
index 07054572297f..d4cefd8a9af4 100644
--- a/arch/x86/xen/multicalls.c
+++ b/arch/x86/xen/multicalls.c
@@ -23,26 +23,21 @@
#include <linux/percpu.h>
#include <linux/hardirq.h>
#include <linux/debugfs.h>
+#include <linux/jump_label.h>
+#include <linux/printk.h>
#include <asm/xen/hypercall.h>
-#include "multicalls.h"
-#include "debugfs.h"
+#include "xen-ops.h"
#define MC_BATCH 32
-#define MC_DEBUG 0
-
#define MC_ARGS (MC_BATCH * 16)
struct mc_buffer {
unsigned mcidx, argidx, cbidx;
struct multicall_entry entries[MC_BATCH];
-#if MC_DEBUG
- struct multicall_entry debug[MC_BATCH];
- void *caller[MC_BATCH];
-#endif
unsigned char args[MC_ARGS];
struct callback {
void (*fn)(void *);
@@ -50,13 +45,98 @@ struct mc_buffer {
} callbacks[MC_BATCH];
};
+struct mc_debug_data {
+ struct multicall_entry entries[MC_BATCH];
+ void *caller[MC_BATCH];
+ size_t argsz[MC_BATCH];
+ unsigned long *args[MC_BATCH];
+};
+
static DEFINE_PER_CPU(struct mc_buffer, mc_buffer);
+static struct mc_debug_data mc_debug_data_early __initdata;
+static struct mc_debug_data __percpu *mc_debug_data __refdata =
+ &mc_debug_data_early;
DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags);
+static struct static_key mc_debug __ro_after_init;
+static bool mc_debug_enabled __initdata;
+
+static int __init xen_parse_mc_debug(char *arg)
+{
+ mc_debug_enabled = true;
+ static_key_slow_inc(&mc_debug);
+
+ return 0;
+}
+early_param("xen_mc_debug", xen_parse_mc_debug);
+
+static int __init mc_debug_enable(void)
+{
+ struct mc_debug_data __percpu *mcdb;
+ unsigned long flags;
+
+ if (!mc_debug_enabled)
+ return 0;
+
+ mcdb = alloc_percpu(struct mc_debug_data);
+ if (!mcdb) {
+ pr_err("xen_mc_debug inactive\n");
+ static_key_slow_dec(&mc_debug);
+ return -ENOMEM;
+ }
+
+ /* Be careful when switching to percpu debug data. */
+ local_irq_save(flags);
+ xen_mc_flush();
+ mc_debug_data = mcdb;
+ local_irq_restore(flags);
+
+ pr_info("xen_mc_debug active\n");
+
+ return 0;
+}
+early_initcall(mc_debug_enable);
+
+/* Number of parameters of hypercalls used via multicalls. */
+static const uint8_t hpcpars[] = {
+ [__HYPERVISOR_mmu_update] = 4,
+ [__HYPERVISOR_stack_switch] = 2,
+ [__HYPERVISOR_fpu_taskswitch] = 1,
+ [__HYPERVISOR_update_descriptor] = 2,
+ [__HYPERVISOR_update_va_mapping] = 3,
+ [__HYPERVISOR_mmuext_op] = 4,
+};
+
+static void print_debug_data(struct mc_buffer *b, struct mc_debug_data *mcdb,
+ int idx)
+{
+ unsigned int arg;
+ unsigned int opidx = mcdb->entries[idx].op & 0xff;
+ unsigned int pars = 0;
+
+ pr_err(" call %2d: op=%lu result=%ld caller=%pS ", idx + 1,
+ mcdb->entries[idx].op, b->entries[idx].result,
+ mcdb->caller[idx]);
+ if (opidx < ARRAY_SIZE(hpcpars))
+ pars = hpcpars[opidx];
+ if (pars) {
+ pr_cont("pars=");
+ for (arg = 0; arg < pars; arg++)
+ pr_cont("%lx ", mcdb->entries[idx].args[arg]);
+ }
+ if (mcdb->argsz[idx]) {
+ pr_cont("args=");
+ for (arg = 0; arg < mcdb->argsz[idx] / 8; arg++)
+ pr_cont("%lx ", mcdb->args[idx][arg]);
+ }
+ pr_cont("\n");
+}
+
void xen_mc_flush(void)
{
struct mc_buffer *b = this_cpu_ptr(&mc_buffer);
struct multicall_entry *mc;
+ struct mc_debug_data *mcdb = NULL;
int ret = 0;
unsigned long flags;
int i;
@@ -69,10 +149,11 @@ void xen_mc_flush(void)
trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
-#if MC_DEBUG
- memcpy(b->debug, b->entries,
- b->mcidx * sizeof(struct multicall_entry));
-#endif
+ if (static_key_false(&mc_debug)) {
+ mcdb = this_cpu_ptr(mc_debug_data);
+ memcpy(mcdb->entries, b->entries,
+ b->mcidx * sizeof(struct multicall_entry));
+ }
switch (b->mcidx) {
case 0:
@@ -103,21 +184,14 @@ void xen_mc_flush(void)
pr_err("%d of %d multicall(s) failed: cpu %d\n",
ret, b->mcidx, smp_processor_id());
for (i = 0; i < b->mcidx; i++) {
- if (b->entries[i].result < 0) {
-#if MC_DEBUG
- pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\t%pS\n",
- i + 1,
- b->debug[i].op,
- b->debug[i].args[0],
- b->entries[i].result,
- b->caller[i]);
-#else
+ if (static_key_false(&mc_debug)) {
+ print_debug_data(b, mcdb, i);
+ } else if (b->entries[i].result < 0) {
pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n",
i + 1,
b->entries[i].op,
b->entries[i].args[0],
b->entries[i].result);
-#endif
}
}
}
@@ -155,9 +229,13 @@ struct multicall_space __xen_mc_entry(size_t args)
}
ret.mc = &b->entries[b->mcidx];
-#if MC_DEBUG
- b->caller[b->mcidx] = __builtin_return_address(0);
-#endif
+ if (static_key_false(&mc_debug)) {
+ struct mc_debug_data *mcdb = this_cpu_ptr(mc_debug_data);
+
+ mcdb->caller[b->mcidx] = __builtin_return_address(0);
+ mcdb->argsz[b->mcidx] = args;
+ mcdb->args[b->mcidx] = (unsigned long *)(&b->args[argidx]);
+ }
b->mcidx++;
ret.args = &b->args[argidx];
b->argidx = argidx + args;
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h
deleted file mode 100644
index c3867b585e0d..000000000000
--- a/arch/x86/xen/multicalls.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _XEN_MULTICALLS_H
-#define _XEN_MULTICALLS_H
-
-#include <trace/events/xen.h>
-
-#include "xen-ops.h"
-
-/* Multicalls */
-struct multicall_space
-{
- struct multicall_entry *mc;
- void *args;
-};
-
-/* Allocate room for a multicall and its args */
-struct multicall_space __xen_mc_entry(size_t args);
-
-DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags);
-
-/* Call to start a batch of multiple __xen_mc_entry()s. Must be
- paired with xen_mc_issue() */
-static inline void xen_mc_batch(void)
-{
- unsigned long flags;
-
- /* need to disable interrupts until this entry is complete */
- local_irq_save(flags);
- trace_xen_mc_batch(xen_get_lazy_mode());
- __this_cpu_write(xen_mc_irq_flags, flags);
-}
-
-static inline struct multicall_space xen_mc_entry(size_t args)
-{
- xen_mc_batch();
- return __xen_mc_entry(args);
-}
-
-/* Flush all pending multicalls */
-void xen_mc_flush(void);
-
-/* Issue a multicall if we're not in a lazy mode */
-static inline void xen_mc_issue(unsigned mode)
-{
- trace_xen_mc_issue(mode);
-
- if ((xen_get_lazy_mode() & mode) == 0)
- xen_mc_flush();
-
- /* restore flags saved in xen_mc_batch */
- local_irq_restore(this_cpu_read(xen_mc_irq_flags));
-}
-
-/* Set up a callback to be called when the current batch is flushed */
-void xen_mc_callback(void (*fn)(void *), void *data);
-
-/*
- * Try to extend the arguments of the previous multicall command. The
- * previous command's op must match. If it does, then it attempts to
- * extend the argument space allocated to the multicall entry by
- * arg_size bytes.
- *
- * The returned multicall_space will return with mc pointing to the
- * command on success, or NULL on failure, and args pointing to the
- * newly allocated space.
- */
-struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size);
-
-#endif /* _XEN_MULTICALLS_H */
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 9bdc3b656b2c..7c735b730acd 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -81,7 +81,6 @@
#include <xen/balloon.h>
#include <xen/grant_table.h>
-#include "multicalls.h"
#include "xen-ops.h"
#define P2M_MID_PER_PAGE (PAGE_SIZE / sizeof(unsigned long *))
@@ -555,7 +554,6 @@ int xen_alloc_p2m_entry(unsigned long pfn)
/* Separately check the mid mfn level */
unsigned long missing_mfn;
unsigned long mid_mfn_mfn;
- unsigned long old_mfn;
mid_mfn = alloc_p2m_page();
if (!mid_mfn)
@@ -565,12 +563,12 @@ int xen_alloc_p2m_entry(unsigned long pfn)
missing_mfn = virt_to_mfn(p2m_mid_missing_mfn);
mid_mfn_mfn = virt_to_mfn(mid_mfn);
- old_mfn = cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn);
- if (old_mfn != missing_mfn) {
- free_p2m_page(mid_mfn);
- mid_mfn = mfn_to_virt(old_mfn);
- } else {
+ /* try_cmpxchg() updates missing_mfn on failure. */
+ if (try_cmpxchg(top_mfn_p, &missing_mfn, mid_mfn_mfn)) {
p2m_top_mfn_p[topidx] = mid_mfn;
+ } else {
+ free_p2m_page(mid_mfn);
+ mid_mfn = mfn_to_virt(missing_mfn);
}
}
} else {
@@ -731,7 +729,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
* immediate unmapping.
*/
map_ops[i].status = GNTST_general_error;
- unmap[0].host_addr = map_ops[i].host_addr,
+ unmap[0].host_addr = map_ops[i].host_addr;
unmap[0].handle = map_ops[i].handle;
map_ops[i].handle = INVALID_GRANT_HANDLE;
if (map_ops[i].flags & GNTMAP_device_map)
@@ -741,7 +739,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
if (kmap_ops) {
kmap_ops[i].status = GNTST_general_error;
- unmap[1].host_addr = kmap_ops[i].host_addr,
+ unmap[1].host_addr = kmap_ops[i].host_addr;
unmap[1].handle = kmap_ops[i].handle;
kmap_ops[i].handle = INVALID_GRANT_HANDLE;
if (kmap_ops[i].flags & GNTMAP_device_map)
@@ -796,7 +794,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
#ifdef CONFIG_XEN_DEBUG_FS
#include <linux/debugfs.h>
-#include "debugfs.h"
static int p2m_dump_show(struct seq_file *m, void *v)
{
static const char * const type_name[] = {
diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index 246d67dab510..f06987b0efc3 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -10,7 +10,6 @@
#include <xen/interface/xenpmu.h>
#include "xen-ops.h"
-#include "pmu.h"
/* x86_pmu.handle_irq definition */
#include "../events/perf_event.h"
diff --git a/arch/x86/xen/pmu.h b/arch/x86/xen/pmu.h
deleted file mode 100644
index 65c58894fc79..000000000000
--- a/arch/x86/xen/pmu.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __XEN_PMU_H
-#define __XEN_PMU_H
-
-#include <xen/interface/xenpmu.h>
-
-extern bool is_xen_pmu;
-
-irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
-#ifdef CONFIG_XEN_HAVE_VPMU
-void xen_pmu_init(int cpu);
-void xen_pmu_finish(int cpu);
-#else
-static inline void xen_pmu_init(int cpu) {}
-static inline void xen_pmu_finish(int cpu) {}
-#endif
-bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
-bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
-int pmu_apic_update(uint32_t reg);
-unsigned long long xen_read_pmc(int counter);
-
-#endif /* __XEN_PMU_H */
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 380591028cb8..806ddb2391d9 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -34,7 +34,6 @@
#include <xen/features.h>
#include <xen/hvc-console.h>
#include "xen-ops.h"
-#include "mmu.h"
#define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)
@@ -691,6 +690,7 @@ char * __init xen_memory_setup(void)
struct xen_memory_map memmap;
unsigned long max_pages;
unsigned long extra_pages = 0;
+ unsigned long maxmem_pages;
int i;
int op;
@@ -762,8 +762,8 @@ char * __init xen_memory_setup(void)
* Make sure we have no memory above max_pages, as this area
* isn't handled by the p2m management.
*/
- extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
- extra_pages, max_pages - max_pfn);
+ maxmem_pages = EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM));
+ extra_pages = min3(maxmem_pages, extra_pages, max_pages - max_pfn);
i = 0;
addr = xen_e820_table.entries[0].addr;
size = xen_e820_table.entries[0].size;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 935771726f9c..05f92c812ac8 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -9,7 +9,6 @@
#include <xen/hvc-console.h>
#include "xen-ops.h"
-#include "smp.h"
static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 };
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h
deleted file mode 100644
index b8efdbc693f7..000000000000
--- a/arch/x86/xen/smp.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _XEN_SMP_H
-
-#ifdef CONFIG_SMP
-
-void asm_cpu_bringup_and_idle(void);
-asmlinkage void cpu_bringup_and_idle(void);
-
-extern void xen_send_IPI_mask(const struct cpumask *mask,
- int vector);
-extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
- int vector);
-extern void xen_send_IPI_allbutself(int vector);
-extern void xen_send_IPI_all(int vector);
-extern void xen_send_IPI_self(int vector);
-
-extern int xen_smp_intr_init(unsigned int cpu);
-extern void xen_smp_intr_free(unsigned int cpu);
-int xen_smp_intr_init_pv(unsigned int cpu);
-void xen_smp_intr_free_pv(unsigned int cpu);
-
-void xen_smp_count_cpus(void);
-void xen_smp_cpus_done(unsigned int max_cpus);
-
-void xen_smp_send_reschedule(int cpu);
-void xen_smp_send_call_function_ipi(const struct cpumask *mask);
-void xen_smp_send_call_function_single_ipi(int cpu);
-
-void __noreturn xen_cpu_bringup_again(unsigned long stack);
-
-struct xen_common_irq {
- int irq;
- char *name;
-};
-#else /* CONFIG_SMP */
-
-static inline int xen_smp_intr_init(unsigned int cpu)
-{
- return 0;
-}
-static inline void xen_smp_intr_free(unsigned int cpu) {}
-
-static inline int xen_smp_intr_init_pv(unsigned int cpu)
-{
- return 0;
-}
-static inline void xen_smp_intr_free_pv(unsigned int cpu) {}
-static inline void xen_smp_count_cpus(void) { }
-#endif /* CONFIG_SMP */
-
-#endif
diff --git a/arch/x86/xen/smp_hvm.c b/arch/x86/xen/smp_hvm.c
index ac95d1981cc0..485c1d8804f7 100644
--- a/arch/x86/xen/smp_hvm.c
+++ b/arch/x86/xen/smp_hvm.c
@@ -5,8 +5,6 @@
#include <xen/events.h>
#include "xen-ops.h"
-#include "smp.h"
-
static void __init xen_hvm_smp_prepare_boot_cpu(void)
{
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
index ac41d83b38d3..7ea57f728b89 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -46,9 +46,6 @@
#include <xen/hvc-console.h>
#include "xen-ops.h"
-#include "mmu.h"
-#include "smp.h"
-#include "pmu.h"
cpumask_var_t xen_cpu_initialized_map;
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 5c6fc16e4b92..8e4efe0fb6f9 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -18,7 +18,6 @@
static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
static DEFINE_PER_CPU(char *, irq_name);
static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);
-static bool xen_pvspin = true;
static void xen_qlock_kick(int cpu)
{
@@ -68,7 +67,7 @@ void xen_init_lock_cpu(int cpu)
int irq;
char *name;
- if (!xen_pvspin)
+ if (nopvspin)
return;
WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",
@@ -95,7 +94,7 @@ void xen_uninit_lock_cpu(int cpu)
{
int irq;
- if (!xen_pvspin)
+ if (nopvspin)
return;
kfree(per_cpu(irq_name, cpu));
@@ -125,10 +124,10 @@ PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen);
void __init xen_init_spinlocks(void)
{
/* Don't need to use pvqspinlock code if there is only 1 vCPU. */
- if (num_possible_cpus() == 1 || nopvspin)
- xen_pvspin = false;
+ if (num_possible_cpus() == 1)
+ nopvspin = true;
- if (!xen_pvspin) {
+ if (nopvspin) {
printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
static_branch_disable(&virt_spin_lock_key);
return;
@@ -143,12 +142,3 @@ void __init xen_init_spinlocks(void)
pv_ops.lock.kick = xen_qlock_kick;
pv_ops.lock.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen);
}
-
-static __init int xen_parse_nopvspin(char *arg)
-{
- pr_notice("\"xen_nopvspin\" is deprecated, please use \"nopvspin\" instead\n");
- xen_pvspin = false;
- return 0;
-}
-early_param("xen_nopvspin", xen_parse_nopvspin);
-
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 1d83152c761b..77a6ea1c60e4 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -15,8 +15,6 @@
#include <asm/fixmap.h>
#include "xen-ops.h"
-#include "mmu.h"
-#include "pmu.h"
static DEFINE_PER_CPU(u64, spec_ctrl);
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 52fa5609b7f6..96521b1874ac 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -30,7 +30,7 @@
#include "xen-ops.h"
/* Minimum amount of time until next clock event fires */
-#define TIMER_SLOP 100000
+#define TIMER_SLOP 1
static u64 xen_sched_clock_offset __read_mostly;
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index 04101b984f24..758bcd47b72d 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -49,7 +49,7 @@ SYM_CODE_START(startup_xen)
ANNOTATE_NOENDBR
cld
- leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
+ leaq __top_init_kernel_stack(%rip), %rsp
/* Set up %gs.
*
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 79cf93f2c92f..e7775dff9452 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -5,8 +5,15 @@
#include <linux/init.h>
#include <linux/clocksource.h>
#include <linux/irqreturn.h>
+#include <linux/linkage.h>
+
+#include <xen/interface/xenpmu.h>
#include <xen/xen-ops.h>
+#include <asm/page.h>
+
+#include <trace/events/xen.h>
+
/* These are code, but not functions. Defined in entry.S */
extern const char xen_failsafe_callback[];
@@ -23,14 +30,11 @@ void xen_copy_trap_info(struct trap_info *traps);
DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info);
DECLARE_PER_CPU(unsigned long, xen_cr3);
-DECLARE_PER_CPU(unsigned long, xen_current_cr3);
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);
@@ -177,4 +181,142 @@ static inline void xen_hvm_post_suspend(int suspend_cancelled) {}
void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns);
+struct dentry * __init xen_init_debugfs(void);
+
+enum pt_level {
+ PT_PGD,
+ PT_P4D,
+ PT_PUD,
+ PT_PMD,
+ PT_PTE
+};
+
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
+unsigned long xen_read_cr2_direct(void);
+void xen_init_mmu_ops(void);
+void xen_hvm_init_mmu_ops(void);
+
+/* Multicalls */
+struct multicall_space
+{
+ struct multicall_entry *mc;
+ void *args;
+};
+
+/* Allocate room for a multicall and its args */
+struct multicall_space __xen_mc_entry(size_t args);
+
+DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags);
+
+/* Call to start a batch of multiple __xen_mc_entry()s. Must be
+ paired with xen_mc_issue() */
+static inline void xen_mc_batch(void)
+{
+ unsigned long flags;
+
+ /* need to disable interrupts until this entry is complete */
+ local_irq_save(flags);
+ trace_xen_mc_batch(xen_get_lazy_mode());
+ __this_cpu_write(xen_mc_irq_flags, flags);
+}
+
+static inline struct multicall_space xen_mc_entry(size_t args)
+{
+ xen_mc_batch();
+ return __xen_mc_entry(args);
+}
+
+/* Flush all pending multicalls */
+void xen_mc_flush(void);
+
+/* Issue a multicall if we're not in a lazy mode */
+static inline void xen_mc_issue(unsigned mode)
+{
+ trace_xen_mc_issue(mode);
+
+ if ((xen_get_lazy_mode() & mode) == 0)
+ xen_mc_flush();
+
+ /* restore flags saved in xen_mc_batch */
+ local_irq_restore(this_cpu_read(xen_mc_irq_flags));
+}
+
+/* Set up a callback to be called when the current batch is flushed */
+void xen_mc_callback(void (*fn)(void *), void *data);
+
+/*
+ * Try to extend the arguments of the previous multicall command. The
+ * previous command's op must match. If it does, then it attempts to
+ * extend the argument space allocated to the multicall entry by
+ * arg_size bytes.
+ *
+ * The returned multicall_space will return with mc pointing to the
+ * command on success, or NULL on failure, and args pointing to the
+ * newly allocated space.
+ */
+struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size);
+
+extern bool is_xen_pmu;
+
+irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
+#ifdef CONFIG_XEN_HAVE_VPMU
+void xen_pmu_init(int cpu);
+void xen_pmu_finish(int cpu);
+#else
+static inline void xen_pmu_init(int cpu) {}
+static inline void xen_pmu_finish(int cpu) {}
+#endif
+bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
+bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
+int pmu_apic_update(uint32_t reg);
+unsigned long long xen_read_pmc(int counter);
+
+#ifdef CONFIG_SMP
+
+void asm_cpu_bringup_and_idle(void);
+asmlinkage void cpu_bringup_and_idle(void);
+
+extern void xen_send_IPI_mask(const struct cpumask *mask,
+ int vector);
+extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
+ int vector);
+extern void xen_send_IPI_allbutself(int vector);
+extern void xen_send_IPI_all(int vector);
+extern void xen_send_IPI_self(int vector);
+
+extern int xen_smp_intr_init(unsigned int cpu);
+extern void xen_smp_intr_free(unsigned int cpu);
+int xen_smp_intr_init_pv(unsigned int cpu);
+void xen_smp_intr_free_pv(unsigned int cpu);
+
+void xen_smp_count_cpus(void);
+void xen_smp_cpus_done(unsigned int max_cpus);
+
+void xen_smp_send_reschedule(int cpu);
+void xen_smp_send_call_function_ipi(const struct cpumask *mask);
+void xen_smp_send_call_function_single_ipi(int cpu);
+
+void __noreturn xen_cpu_bringup_again(unsigned long stack);
+
+struct xen_common_irq {
+ int irq;
+ char *name;
+};
+#else /* CONFIG_SMP */
+
+static inline int xen_smp_intr_init(unsigned int cpu)
+{
+ return 0;
+}
+static inline void xen_smp_intr_free(unsigned int cpu) {}
+
+static inline int xen_smp_intr_init_pv(unsigned int cpu)
+{
+ return 0;
+}
+static inline void xen_smp_intr_free_pv(unsigned int cpu) {}
+static inline void xen_smp_count_cpus(void) { }
+#endif /* CONFIG_SMP */
+
#endif /* XEN_OPS_H */
diff --git a/arch/xtensa/boot/dts/Makefile b/arch/xtensa/boot/dts/Makefile
index 720628c0d8b9..d6408c16d74e 100644
--- a/arch/xtensa/boot/dts/Makefile
+++ b/arch/xtensa/boot/dts/Makefile
@@ -10,5 +10,4 @@
obj-$(CONFIG_OF) += $(addsuffix .dtb.o, $(CONFIG_BUILTIN_DTB_SOURCE))
# for CONFIG_OF_ALL_DTBS test
-dtstree := $(srctree)/$(src)
-dtb- := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+dtb- := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts))
diff --git a/arch/xtensa/include/asm/current.h b/arch/xtensa/include/asm/current.h
index 08010dbf5e09..df275d554788 100644
--- a/arch/xtensa/include/asm/current.h
+++ b/arch/xtensa/include/asm/current.h
@@ -19,7 +19,7 @@
struct task_struct;
-static inline struct task_struct *get_current(void)
+static __always_inline struct task_struct *get_current(void)
{
return current_thread_info()->task;
}
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 9a7e5e57ee9a..1647a7cc3fbf 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -410,9 +410,9 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
typedef pte_t *pte_addr_t;
-void update_mmu_tlb(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep);
-#define __HAVE_ARCH_UPDATE_MMU_TLB
+void update_mmu_tlb_range(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep, unsigned int nr);
+#define update_mmu_tlb_range update_mmu_tlb_range
#endif /* !defined (__ASSEMBLY__) */
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 326db1c1d5d8..e0dffcc43b9e 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -91,7 +91,7 @@ struct thread_info {
}
/* how to get the thread information struct from C */
-static inline struct thread_info *current_thread_info(void)
+static __always_inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
__asm__("extui %0, a1, 0, "__stringify(CURRENT_SHIFT)"\n\t"
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
index b52236245e51..30af4dc3ce7b 100644
--- a/arch/xtensa/include/asm/unistd.h
+++ b/arch/xtensa/include/asm/unistd.h
@@ -3,7 +3,6 @@
#define _XTENSA_UNISTD_H
#define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
#include <uapi/asm/unistd.h>
#define __ARCH_WANT_NEW_STAT
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index dd116598fb25..67083fc1b2f5 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -432,3 +432,4 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common mseal sys_mseal
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 7ec66a79f472..23be0e7516ce 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -87,12 +87,13 @@ static inline void *coherent_kvaddr(struct page *page, unsigned long base,
void clear_user_highpage(struct page *page, unsigned long vaddr)
{
+ struct folio *folio = page_folio(page);
unsigned long paddr;
void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr);
preempt_disable();
kmap_invalidate_coherent(page, vaddr);
- set_bit(PG_arch_1, &page->flags);
+ set_bit(PG_arch_1, folio_flags(folio, 0));
clear_page_alias(kvaddr, paddr);
preempt_enable();
}
@@ -101,6 +102,7 @@ EXPORT_SYMBOL(clear_user_highpage);
void copy_user_highpage(struct page *dst, struct page *src,
unsigned long vaddr, struct vm_area_struct *vma)
{
+ struct folio *folio = page_folio(dst);
unsigned long dst_paddr, src_paddr;
void *dst_vaddr = coherent_kvaddr(dst, TLBTEMP_BASE_1, vaddr,
&dst_paddr);
@@ -109,7 +111,7 @@ void copy_user_highpage(struct page *dst, struct page *src,
preempt_disable();
kmap_invalidate_coherent(dst, vaddr);
- set_bit(PG_arch_1, &dst->flags);
+ set_bit(PG_arch_1, folio_flags(folio, 0));
copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr);
preempt_enable();
}
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c
index 4f974b74883c..0a1a815dc796 100644
--- a/arch/xtensa/mm/tlb.c
+++ b/arch/xtensa/mm/tlb.c
@@ -163,10 +163,10 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
}
}
-void update_mmu_tlb(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep)
+void update_mmu_tlb_range(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep, unsigned int nr)
{
- local_flush_tlb_page(vma, address);
+ local_flush_tlb_range(vma, address, address + PAGE_SIZE * nr);
}
#ifdef CONFIG_DEBUG_TLB_SANITY
@@ -256,12 +256,13 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb)
dtlb ? 'D' : 'I', w, e, r0, r1, pte);
if (pte == 0 || !pte_present(__pte(pte))) {
struct page *p = pfn_to_page(r1 >> PAGE_SHIFT);
- pr_err("page refcount: %d, mapcount: %d\n",
- page_count(p),
- page_mapcount(p));
- if (!page_count(p))
+ struct folio *f = page_folio(p);
+
+ pr_err("folio refcount: %d, mapcount: %d\n",
+ folio_ref_count(f), folio_mapcount(f));
+ if (!folio_ref_count(f))
rc |= TLB_INSANE;
- else if (page_mapcount(p))
+ else if (folio_mapped(f))
rc |= TLB_SUSPICIOUS;
} else {
rc |= TLB_INSANE;
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index defc67909a9c..d6d2b533a574 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -263,6 +263,9 @@ static const struct proc_ops simdisk_proc_ops = {
static int __init simdisk_setup(struct simdisk *dev, int which,
struct proc_dir_entry *procdir)
{
+ struct queue_limits lim = {
+ .features = BLK_FEAT_ROTATIONAL,
+ };
char tmp[2] = { '0' + which, 0 };
int err;
@@ -271,7 +274,7 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
spin_lock_init(&dev->lock);
dev->users = 0;
- dev->gd = blk_alloc_disk(NULL, NUMA_NO_NODE);
+ dev->gd = blk_alloc_disk(&lim, NUMA_NO_NODE);
if (IS_ERR(dev->gd)) {
err = PTR_ERR(dev->gd);
goto out;